. * * @package LibreNMS * @link http://librenms.org * @copyright 2017 Tony Murray * @author Tony Murray */ namespace LibreNMS\Tests; use DeviceCache; use Illuminate\Foundation\Testing\DatabaseTransactions; use LibreNMS\Config; use LibreNMS\Exceptions\FileNotFoundException; use LibreNMS\Exceptions\InvalidModuleException; use LibreNMS\Fping; use LibreNMS\Util\ModuleTestHelper; class OSModulesTest extends DBTestCase { use DatabaseTransactions; private $discoveryModules; private $pollerModules; protected function setUp(): void { parent::setUp(); // backup modules $this->discoveryModules = Config::get('discovery_modules'); $this->pollerModules = Config::get('poller_modules'); } protected function tearDown(): void { // restore modules Config::set('discovery_modules', $this->discoveryModules); Config::set('poller_modules', $this->pollerModules); parent::tearDown(); } /** * Test all modules for a particular OS * * @group os * @dataProvider dumpedDataProvider */ public function testDataIsValid($os, $variant, $modules) { // special case if data provider throws exception if ($os === false) { $this->fail($modules); } $this->assertNotEmpty($modules, "No modules to test for $os $variant"); } /** * Test all modules for a particular OS * * @group os * @dataProvider dumpedDataProvider * @param string $os base os * @param string $variant optional variant * @param array $modules modules to test for this os */ public function testOS($os, $variant, $modules) { $this->requireSnmpsim(); // require snmpsim for tests // stub out Log::event and Fping->ping, we don't need to store them for these tests $this->stubClasses(); try { set_debug(false); // avoid all undefined index errors in the legacy code $helper = new ModuleTestHelper($modules, $os, $variant); $helper->setQuiet(); $filename = $helper->getJsonFilepath(true); $expected_data = $helper->getTestData(); $results = $helper->generateTestData($this->getSnmpsim(), true); } catch (FileNotFoundException $e) { $this->fail($e->getMessage()); return; } catch (InvalidModuleException $e) { $this->fail($e->getMessage()); return; } if (is_null($results)) { $this->fail("$os: Failed to collect data."); } // output all discovery and poller output if debug mode is enabled for phpunit $debug = in_array('--debug', $_SERVER['argv'], true); foreach ($modules as $module) { $expected = $expected_data[$module]['discovery']; $actual = $results[$module]['discovery']; $this->assertEquals( $expected, $actual, "OS $os: Discovered $module data does not match that found in $filename\n" . print_r(array_diff($expected, $actual), true) . $helper->getDiscoveryOutput($debug ? null : $module) . "\nOS $os: Discovered $module data does not match that found in $filename" ); if ($module === 'route') { // no route poller module continue; } if ($expected_data[$module]['poller'] == 'matches discovery') { $expected = $expected_data[$module]['discovery']; } else { $expected = $expected_data[$module]['poller']; } $actual = $results[$module]['poller']; $this->assertEquals( $expected, $actual, "OS $os: Polled $module data does not match that found in $filename\n" . print_r(array_diff($expected, $actual), true) . $helper->getPollerOutput($debug ? null : $module) . "\nOS $os: Polled $module data does not match that found in $filename" ); } DeviceCache::flush(); // clear cached devices } public function dumpedDataProvider() { $modules = array(); if (getenv('TEST_MODULES')) { $modules = explode(',', getenv('TEST_MODULES')); } try { return ModuleTestHelper::findOsWithData($modules); } catch (InvalidModuleException $e) { // special case for exception return [[false, false, $e->getMessage()]]; } } private function stubClasses(): void { $this->app->bind('log', function ($app) { return \Mockery::mock('\App\Facades\LogManager[event]', [$app]) ->shouldReceive('event'); }); $this->app->bind(Fping::class, function ($app) { $mock = \Mockery::mock('\LibreNMS\Fping'); $mock->shouldReceive('ping')->andReturn([ "xmt" => 3, "rcv" => 3, "loss" => 0, "min" => 0.62, "max" => 0.93, "avg" => 0.71, "dup" => 0, "exitcode" => 0, ]); return $mock; }); } }