1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
<?php
use PHPUnit\Framework\TestCase;
/**
* Tests for modules-available/locations/inc/locationutil.inc.php using SQLite DB and real Location.
*
*/
class LocationUtilTest extends TestCase
{
protected function setUp(): void
{
Database::resetSchema();
Message::reset();
$GLOBALS['__TEST_USE_REAL_CLASSES'] = ['Location'];
require_once __DIR__ . '/../../../modules-available/locations/inc/location.inc.php';
require_once __DIR__ . '/../../../modules-available/locations/inc/locationutil.inc.php';
}
public function testRangeToLongAndVerboseValidation(): void
{
list($s, $e) = LocationUtil::rangeToLong('10.0.0.1', '10.0.0.9');
$this->assertIsInt($s);
$this->assertIsInt($e);
$this->assertLessThan($s + 100, $e);
// Invalid addresses -> verbose returns null and records warnings
Message::reset();
$this->assertNull(LocationUtil::rangeToLongVerbose('bad-ip', '10.0.0.1'));
$this->assertContains('main.value-invalid', Message::$warnings);
Message::reset();
$this->assertNull(LocationUtil::rangeToLongVerbose('10.0.0.9', '10.0.0.1'));
$this->assertContains('main.value-invalid', Message::$warnings);
}
public function testGetOverlappingSubnetsSelfAndOther(): void
{
// Sanity: 2 and 3 are siblings under 1 in the canonical seed
$assoc = Location::getLocationsAssoc();
$this->assertSame(1, $assoc[2]['parentlocationid']);
$this->assertSame(1, $assoc[3]['parentlocationid']);
$this->assertNotContains(2, $assoc[3]['parents']);
$this->assertNotContains(3, $assoc[2]['parents']);
// Self-overlap in location 5: add overlapping ranges
$startA = sprintf('%u', ip2long('192.168.1.0'));
$endA = sprintf('%u', ip2long('192.168.1.127'));
$startB = sprintf('%u', ip2long('192.168.1.64'));
$endB = sprintf('%u', ip2long('192.168.1.200'));
Database::exec('INSERT INTO subnet (startaddr, endaddr, locationid) VALUES (:s, :e, 5)', ['s' => $startA, 'e' => $endA]);
Database::exec('INSERT INTO subnet (startaddr, endaddr, locationid) VALUES (:s, :e, 5)', ['s' => $startB, 'e' => $endB]);
// Other-overlap between unrelated siblings 2 and 3: make 3 overlap 2's 10.0.0.128/26 by adding a
// wider 10.0.0.0/24 in location 3.
$startC = sprintf('%u', ip2long('10.0.0.0'));
$endC = sprintf('%u', ip2long('10.0.0.255'));
Database::exec('INSERT INTO subnet (startaddr, endaddr, locationid) VALUES (:s, :e, 3)', ['s' => $startC, 'e' => $endC]);
$overSelf = [];
$overOther = [];
LocationUtil::getOverlappingSubnets($overSelf, $overOther);
// Self: expect one entry with location name 'Offsite' (id 5 in seed)
$this->assertNotEmpty($overSelf);
$names = array_column($overSelf, 'locationname');
$this->assertContains('Offsite', $names);
// Other: expect a pair 2|3 (order not guaranteed, check that both names present)
$this->assertNotEmpty($overOther);
$pairFound = false;
foreach ($overOther as $p) {
if ((isset($p['name1']) && isset($p['name2']))) {
$pair = [$p['name1'], $p['name2']]; sort($pair);
if ($pair === ['Building A', 'Building B']) { $pairFound = true; break; }
}
}
$this->assertTrue($pairFound, 'Expected overlap between Building A and Building B');
}
public function testGetMachinesWithLocationMismatchSummaryAndDetail(): void
{
// Summary across all locations
$summary = LocationUtil::getMachinesWithLocationMismatch(0, false);
// Expect entries for fixedlocationid 5 (m1 mismatch) and 2 (wrong2)
$byId = [];
foreach ($summary as $row) { $byId[$row['locationid']] = $row; }
$this->assertArrayHasKey(5, $byId);
$this->assertArrayHasKey(2, $byId);
$this->assertSame('Offsite', $byId[5]['locationname']);
$this->assertSame('Building A', $byId[2]['locationname']);
$this->assertGreaterThanOrEqual(1, $byId[5]['count']);
$this->assertGreaterThanOrEqual(1, $byId[2]['count']);
// Detail for location 5
$detail = LocationUtil::getMachinesWithLocationMismatch(5, false);
$this->assertSame(5, $detail['locationid']);
$this->assertSame('Offsite', $detail['locationname']);
$this->assertNotEmpty($detail['clients']);
$client = $detail['clients'][0];
$this->assertArrayHasKey('machineuuid', $client);
$this->assertArrayHasKey('iplocationid', $client);
$this->assertSame('Campus', $client['iplocationname']); // iplocationid 1 from seed
$this->assertFalse($client['ipisleaf']); // root has children
$this->assertFalse($client['canmove']); // not leaf -> cannot move
}
}
|