'u1', 'clientip' => '10.0.0.10', 'locationid' => 2], ['machineuuid' => 'u2', 'clientip' => '10.0.0.11', 'locationid' => 2], ]; $task = RebootControl::execute($list, RebootControl::REBOOT, 0); $this->assertIsArray($task); $this->assertArrayHasKey('id', $task); // Property list should contain a JSON object with our task id and clients $listEntries = Property::getList(RebootControl::KEY_TASKLIST); $this->assertNotEmpty($listEntries); $found = false; foreach ($listEntries as $entry) { $p = json_decode($entry, true); if (is_array($p) && ($p['id'] ?? '') === $task['id']) { $found = true; $this->assertSame(RebootControl::TASK_REBOOTCTL, $p['type']); $this->assertSame([2], $p['locations']); break; } } $this->assertTrue($found, 'Expected task to be recorded via Property::addToList'); // EventLog::applyFilterRules should have been called for each client $this->assertCount(2, EventLog::$applied); $this->assertSame('#action-power', EventLog::$applied[0]['category']); } public function testRebootDelegatesToExecuteUsingRebootUtils(): void { $task = RebootControl::reboot(['m2'], false); $this->assertIsArray($task); $this->assertArrayHasKey('id', $task); // Ensure Taskmanager recorded a RemoteReboot submission $this->assertNotEmpty(Taskmanager::$submissions); $this->assertSame('RemoteReboot', Taskmanager::$submissions[0]['task']); } public function testRunScriptResolvesUuidToClientAndSubmitsRemoteExec(): void { // Seed a machine in DB (no extra tables needed) Database::exec("INSERT INTO machine (machineuuid, subnetlocationid, locationid, hostname, clientip, state) VALUES (:u, 1, 1, 'h', '10.0.0.55', 'IDLE')", ['u' => 'RES-1']); $clients = [ ['machineuuid' => 'RES-1'], // missing clientip -> should be looked up ['clientip' => '192.168.1.22'], ]; $task = RebootControl::runScript($clients, 'echo hi', 3, 'KEY'); $this->assertIsArray($task); $this->assertArrayHasKey('id', $task); // Verify Taskmanager submission name and arguments $this->assertNotEmpty(Taskmanager::$submissions); $sub = end(Taskmanager::$submissions); $this->assertSame('RemoteExec', $sub['task']); $this->assertArrayHasKey('clients', $sub['data']); $optClients = $sub['data']['clients']; $this->assertContains('10.0.0.55', array_column($optClients, 'clientip')); } public function testWakeDirectlySubmitsDirectClients(): void { $task = RebootControl::wakeDirectly(['aa:bb:cc:dd:ee:ff', '11:22:33:44:55:66'], '10.0.0.255', null); $this->assertIsArray($task); $sub = end(Taskmanager::$submissions); $this->assertSame('WakeOnLan', $sub['task']); $this->assertArrayHasKey('clients', $sub['data']); $this->assertCount(2, $sub['data']['clients']); $this->assertSame('DIRECT', $sub['data']['clients'][0]['methods'][0]); } public function testWakeViaClientBuildsJawolLoop(): void { $clients = [['clientip' => '10.0.0.50']]; $task = RebootControl::wakeViaClient($clients, 'aa-bb-cc-dd-ee-ff', '10.0.0.255', 'ffff'); $this->assertIsArray($task); $sub = end(Taskmanager::$submissions); $this->assertSame('RemoteExec', $sub['task']); $cmd = $sub['data']['command'] ?? ''; $this->assertStringContainsString('jawol', $cmd); $this->assertStringContainsString("-d '10.0.0.255'", $cmd); $this->assertStringContainsString("-p 'ffff'", $cmd); } public function testWakeViaJumpHostAddsCallback(): void { $jh = ['hostid' => 7, 'host' => '10.0.0.77', 'port' => 9922, 'username' => 'root', 'sshkey' => 'KEY', 'script' => 'echo wake %MACS% %IP%']; $task = RebootControl::wakeViaJumpHost($jh, '10.0.0.255', [['macaddr' => 'aa:bb:cc:dd:ee:ff']]); $this->assertIsArray($task); $this->assertNotEmpty(TaskmanagerCallback::$callbacks); $cb = end(TaskmanagerCallback::$callbacks); $this->assertSame('rbcConnCheck', $cb['name']); $this->assertSame(7, $cb['arg']); $sub = end(Taskmanager::$submissions); $this->assertSame('RemoteExec', $sub['task']); $cmd = $sub['data']['command'] ?? ''; $this->assertStringContainsString('aa:bb:cc:dd:ee:ff', $cmd); } public function testGetActiveTasksFiltersByLocationsAndId(): void { // Create two dummy task entries $entry1 = json_encode(['id' => 'A', 'locations' => [1, 2], 'tasks' => ['t1']]); $entry2 = json_encode(['id' => 'B', 'locations' => [5], 'tasks' => ['t2']]); Property::addToList(RebootControl::KEY_TASKLIST, $entry1, 20); Property::addToList(RebootControl::KEY_TASKLIST, $entry2, 20); // Mark t1 as valid and t2 as invalid Taskmanager::$statusById['t1'] = ['id' => 't1', 'statusCode' => 'RUNNING']; Taskmanager::$statusById['t2'] = ['id' => 't2', 'statusCode' => 'UNKNOWN']; // treated as invalid by isTask() // Filter by locations $out = RebootControl::getActiveTasks([1], null); $this->assertNotEmpty($out); $this->assertSame('A', $out[0]['id']); // Query by id returns the item $one = RebootControl::getActiveTasks(null, 'A'); $this->assertIsArray($one); $this->assertSame('A', $one['id']); } }