mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
Split save-test-data.php into two scripts, allow mass update (#8115)
* Add mass update to save-test-data. Fail when snmpsim doesn't start and try to give a hint. * Split save-test-data.php into two scripts One for updating snmprec files. One for updating db dump files.
This commit is contained in:
@@ -101,6 +101,16 @@ class ModuleTestHelper
|
||||
$this->quiet = $quiet;
|
||||
}
|
||||
|
||||
public function setSnmprecSavePath($path)
|
||||
{
|
||||
$this->snmprec_file = $path;
|
||||
}
|
||||
|
||||
public function setJsonSavePath($path)
|
||||
{
|
||||
$this->json_file = $path;
|
||||
}
|
||||
|
||||
public function captureFromDevice($device_id, $write = true, $prefer_new = false)
|
||||
{
|
||||
$snmp_oids = $this->collectOids($device_id);
|
||||
@@ -184,6 +194,66 @@ class ModuleTestHelper
|
||||
return $snmp_oids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a list of os containing test data for $modules (an empty array means all)
|
||||
*
|
||||
* Returns an array indexed by the basename ($os or $os_$variant)
|
||||
* Each entry contains [$os, $variant, $valid_modules]
|
||||
* $valid_modules is an array of selected modules this os has test data for
|
||||
*
|
||||
* @param array $modules
|
||||
* @return array
|
||||
*/
|
||||
public static function findOsWithData($modules = array())
|
||||
{
|
||||
$os_list = array();
|
||||
|
||||
foreach (glob(Config::get('install_dir') . "/tests/data/*.json") as $file) {
|
||||
$base_name = basename($file, '.json');
|
||||
list($os, $variant) = self::extractVariant($file);
|
||||
|
||||
// calculate valid modules
|
||||
$data_modules = array_keys(json_decode(file_get_contents($file), true));
|
||||
|
||||
if (empty($modules)) {
|
||||
$valid_modules = $data_modules;
|
||||
} else {
|
||||
$valid_modules = array_intersect($modules, $data_modules);
|
||||
}
|
||||
|
||||
if (empty($valid_modules)) {
|
||||
continue; // no test data for selected modules
|
||||
}
|
||||
|
||||
$os_list[$base_name] = array(
|
||||
$os,
|
||||
$variant,
|
||||
$valid_modules,
|
||||
);
|
||||
}
|
||||
|
||||
return $os_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a json filename or basename, extract os and variant
|
||||
*
|
||||
* @param string $os_file Either a filename or the basename
|
||||
* @return array [$os, $variant]
|
||||
*/
|
||||
public static function extractVariant($os_file)
|
||||
{
|
||||
$full_name = basename($os_file, '.json');
|
||||
|
||||
if (!str_contains($full_name, '_')) {
|
||||
return [$full_name, ''];
|
||||
} elseif (is_file(Config::get('install_dir') . "/includes/definitions/$full_name.yaml")) {
|
||||
return [$full_name, ''];
|
||||
} else {
|
||||
list($rvar, $ros) = explode('_', strrev($full_name), 2);
|
||||
return [strrev($ros), strrev($rvar)];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a module list. Try to take dependencies into account.
|
||||
@@ -581,8 +651,16 @@ class ModuleTestHelper
|
||||
return empty($this->modules) ? $this->getSupportedModules() : $this->modules;
|
||||
}
|
||||
|
||||
public function fetchTestData()
|
||||
public function getTestData()
|
||||
{
|
||||
return json_decode(file_get_contents($this->json_file), true);
|
||||
}
|
||||
|
||||
public function getJsonFilepath($short = false)
|
||||
{
|
||||
if ($short) {
|
||||
return ltrim(str_replace(Config::get('install_dir'), '', $this->json_file), '/');
|
||||
}
|
||||
return $this->json_file;
|
||||
}
|
||||
}
|
||||
|
@@ -15,12 +15,15 @@ consistent manner.
|
||||
|
||||
## Capturing test data
|
||||
|
||||
`./scripts/save-test-data.php` is provided to make it easy to collect data for tests. Running save-test-data.php with
|
||||
the --hostname (-h) allows you to capture all data used to discover and poll a device already added to LibreNMS. Make sure to
|
||||
re-run the script if you add additional support. Check the command-line help for more options.
|
||||
`./scripts/collect-snmp-data.php` is provided to make it easy to collect data for tests. Running collect-snmp-data.php
|
||||
with the --hostname (-h) allows you to capture all data used to discover and poll a device already added to LibreNMS.
|
||||
Make sure to re-run the script if you add additional support. Check the command-line help for more options.
|
||||
|
||||
Generally, you will only need to capture data (-h) once. After you have the data you need in the snmprec file, you can
|
||||
update the json using -o (and -v if using a variant) after that.
|
||||
After you have collected snmp data, run `./scripts/save-test-data.php` with the --os (-o) option to dump the post discovery
|
||||
and post poll database entries to json files.
|
||||
|
||||
Generally, you will only need to capture data once. After you have the data you need in the snmprec file, you can
|
||||
just use save-test-data.php to update the database dump (json) after that.
|
||||
|
||||
### OS Variants
|
||||
|
||||
@@ -44,7 +47,11 @@ To run the full suite of tests enable database and snmpsim reliant tests: `./scr
|
||||
|
||||
## Using snmpsim for testing
|
||||
|
||||
<<<<<<< HEAD
|
||||
You can run snmpsim to access test data by running `./scripts/save-test-data.php --snmpsim`
|
||||
=======
|
||||
You can run snmpsim to access test data by running `./scripts/collct-snmp-data.php --snmpsim`
|
||||
>>>>>>> Split save-test-data.php into two scripts
|
||||
|
||||
You may then run snmp queries against it using the os (and variant) as the community and 127.1.6.1:1161 as the host.
|
||||
```
|
||||
@@ -98,18 +105,19 @@ data, you must use a variant to store your test data (-v).
|
||||
|
||||
### Add initial detection
|
||||
1. Add device to LibreNMS. It is generic and device_id = 42
|
||||
2. Run `./scripts/save-test-data.php -h 42 -m os`, initial snmprec will be created
|
||||
2. Run `./scripts/collect-snmp-data.php -h 42 -m os`, initial snmprec will be created
|
||||
3. [Add initial detection](Initial-Detection.md) for `example-os`
|
||||
4. Run discovery to make sure it detects properly `./discovery.php -h 42`
|
||||
5. Add any additional os items like version, hardware, features, or serial.
|
||||
6. If there is additional snmp data required, run `./scripts/save-test-data.php -h 42 -m os` otherwise, run `./scripts/save-test-data.php -o example-os -m os`
|
||||
7. Review data. If you modified the snmprec (don't modify json manually) run `./scripts/save-test-data.php -o example-os -m os`
|
||||
6. If there is additional snmp data required, run `./scripts/collect-snmp-data.php -h 42 -m os`
|
||||
7. Run `./scripts/save-test-data.php -o example-os -m os` to update the dumped database data.
|
||||
7. Review data. If you modified the snmprec or code (don't modify json manually) run `./scripts/save-test-data.php -o example-os -m os`
|
||||
8. Run `./scripts/pre-commit.php --db --snmpsim`
|
||||
9. If the tests succeed submit a pull request
|
||||
|
||||
### Additional module support or test data
|
||||
1. Add code to support module or support already exists.
|
||||
2. `./scripts/save-test-data.php -h 42 -m <module>`, this will add more data to the snmprec file
|
||||
2. `./scripts/collect-snmp-data.php -h 42 -m <module>`, this will add more data to the snmprec file
|
||||
3. Review data. If you modified the snmprec (don't modify json manually) run `./scripts/save-test-data.php -o example-os -m <module>`
|
||||
4. Run `./scripts/pre-commit.php --db --snmpsim`
|
||||
5. If the tests succeed submit a pull request
|
||||
|
116
scripts/collect-snmp-data.php
Executable file
116
scripts/collect-snmp-data.php
Executable file
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
use LibreNMS\Util\ModuleTestHelper;
|
||||
use LibreNMS\Util\Snmpsim;
|
||||
|
||||
$install_dir = realpath(__DIR__ . '/..');
|
||||
chdir($install_dir);
|
||||
|
||||
$init_modules = array('discovery', 'polling');
|
||||
require $install_dir . '/includes/init.php';
|
||||
|
||||
$options = getopt(
|
||||
'h:m:no:v:f:d',
|
||||
array(
|
||||
'hostname:',
|
||||
'modules:',
|
||||
'prefer-new',
|
||||
'os:',
|
||||
'variant:',
|
||||
'file:',
|
||||
'debug',
|
||||
'snmpsim',
|
||||
'help',
|
||||
)
|
||||
);
|
||||
|
||||
if (isset($options['snmpsim'])) {
|
||||
$snmpsim = new Snmpsim();
|
||||
$snmpsim->run();
|
||||
exit;
|
||||
}
|
||||
|
||||
// check for hostname
|
||||
if (isset($options['h'])) {
|
||||
$hostname = $options['h'];
|
||||
} elseif (isset($options['hostname'])) {
|
||||
$hostname = $options['hostname'];
|
||||
}
|
||||
|
||||
if (isset($hostname)) {
|
||||
if (is_numeric($hostname)) {
|
||||
$device = device_by_id_cache($hostname);
|
||||
} elseif (!empty($hostname)) {
|
||||
$device = device_by_name($hostname);
|
||||
}
|
||||
|
||||
if (isset($device['os']) && $device['os'] != 'generic') {
|
||||
$target_os = $device['os'];
|
||||
} else {
|
||||
echo "OS (-o, --os) required because device is generic.\n";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($options['help']) || empty($target_os)) {
|
||||
echo "Script to collect snmp data from devices to be used for testing.
|
||||
Snmp data is saved in tests/snmpsim.
|
||||
|
||||
Usage:
|
||||
You must specify an existing device to collect data from.
|
||||
Required
|
||||
-h, --hostname ID, IP, or hostname of the device to collect data from
|
||||
Optional:
|
||||
-m, --modules The discovery/poller module(s) to collect data for, comma delimited
|
||||
-n, --prefer-new Prefer new snmprec data over existing data
|
||||
-o, --os Name of the OS to save test data for (only used if device is generic)
|
||||
-v, --variant The variant of the OS to use, usually the device model
|
||||
-f, --file Save data to file instead of the standard location
|
||||
-d, --debug Enable debug output
|
||||
--snmpsim Run snmpsimd.py using the collected data for manual testing.
|
||||
";
|
||||
exit;
|
||||
}
|
||||
|
||||
$debug = (isset($options['d']) || isset($options['debug']));
|
||||
|
||||
if (isset($options['m'])) {
|
||||
$modules_input = $options['m'];
|
||||
$modules = explode(',', $modules_input);
|
||||
} elseif (isset($options['modules'])) {
|
||||
$modules_input = $options['modules'];
|
||||
$modules = explode(',', $modules_input);
|
||||
} else {
|
||||
$modules_input = 'all';
|
||||
$modules = array();
|
||||
}
|
||||
|
||||
$variant = '';
|
||||
if (isset($options['v'])) {
|
||||
$variant = $options['v'];
|
||||
} elseif (isset($options['variant'])) {
|
||||
$variant = $options['variant'];
|
||||
}
|
||||
|
||||
echo "OS: $target_os\n";
|
||||
echo "Module(s): $modules_input\n";
|
||||
if ($variant) {
|
||||
echo "Variant: $variant\n";
|
||||
}
|
||||
echo PHP_EOL;
|
||||
|
||||
$capture = new ModuleTestHelper($modules, $target_os, $variant);
|
||||
|
||||
|
||||
if (isset($options['f'])) {
|
||||
$capture->setSnmprecSavePath($options['f']);
|
||||
} elseif (isset($options['file'])) {
|
||||
$capture->setSnmprecSavePath($options['file']);
|
||||
}
|
||||
|
||||
$prefer_new_snmprec = isset($options['n']) || isset($options['prefer-new']);
|
||||
|
||||
|
||||
echo "Capturing Data: ";
|
||||
$capture->captureFromDevice($device['device_id'], true, $prefer_new_snmprec);
|
@@ -12,19 +12,16 @@ $install_dir = realpath(__DIR__ . '/..');
|
||||
chdir($install_dir);
|
||||
|
||||
$options = getopt(
|
||||
'h:dncm:o:v:f:',
|
||||
'o:v:m:nf:dh',
|
||||
array(
|
||||
'debug',
|
||||
'collect-only',
|
||||
'no-save',
|
||||
'prefer-new',
|
||||
'hostname:',
|
||||
'help',
|
||||
'module:',
|
||||
'os:',
|
||||
'variant:',
|
||||
'modules:',
|
||||
'no-save',
|
||||
'file:',
|
||||
'debug',
|
||||
'snmpsim',
|
||||
'help',
|
||||
)
|
||||
);
|
||||
|
||||
@@ -41,54 +38,34 @@ if (isset($options['snmpsim'])) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($options['h'])) {
|
||||
$hostname = $options['h'];
|
||||
} elseif (isset($options['hostname'])) {
|
||||
$hostname = $options['hostname'];
|
||||
}
|
||||
|
||||
$target_os = '';
|
||||
if (isset($options['o'])) {
|
||||
$target_os = $options['o'];
|
||||
} elseif (isset($options['os'])) {
|
||||
$target_os = $options['os'];
|
||||
}
|
||||
|
||||
if (isset($hostname)) {
|
||||
if (is_numeric($hostname)) {
|
||||
$device = device_by_id_cache($hostname);
|
||||
} elseif (!empty($hostname)) {
|
||||
$device = device_by_name($hostname);
|
||||
}
|
||||
|
||||
if (isset($device['os']) && $device['os'] != 'generic') {
|
||||
$target_os = $device['os'];
|
||||
} else {
|
||||
echo "OS (-o, --os) required because device is generic.\n";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($options['help']) || empty($target_os)) {
|
||||
echo "Script to extract test data from devices or update test data.
|
||||
Snmp data is saved in tests/snmpsim and database data is saved in tests/data.
|
||||
if (isset($options['h'])
|
||||
|| isset($options['help'])
|
||||
|| !(isset($options['o']) || isset($options['os']) || isset($options['m']) || isset($options['modules']))
|
||||
) {
|
||||
echo "Script to update test data. Database data is saved in tests/data.
|
||||
|
||||
Usage:
|
||||
You must specify a valid hostname or os.
|
||||
-h, --hostname ID, IP, or hostname of the device to extract data from
|
||||
If this is not given, the existing snmp data will be used
|
||||
You must specify a valid OS and/or module(s).
|
||||
|
||||
-o, --os Name of the OS to save test data for
|
||||
-v, --variant The variant of the OS to use, usually the device model
|
||||
-m, --modules The discovery/poller module(s) to collect data for, comma delimited
|
||||
-c, --collect-only Only collect snmpsim data (does not require snmpsim)
|
||||
-n, --no-save Don't save database entries, print them out instead
|
||||
-f, --file Save data to file instead of the standard location
|
||||
-d, --debug Enable debug output
|
||||
-n, --prefer-new Prefer new snmprec data over existing data
|
||||
--no-save Don't save database entries, print them out instead
|
||||
--snmpsim Just run snmpsimd.py for manual testing.
|
||||
--snmpsim Run snmpsimd.py using the collected data for manual testing.
|
||||
";
|
||||
exit;
|
||||
}
|
||||
|
||||
$os_name = false;
|
||||
if (isset($options['o'])) {
|
||||
$os_name = $options['o'];
|
||||
} elseif (isset($os_list['os'])) {
|
||||
$os_name = $options['os'];
|
||||
}
|
||||
|
||||
if (isset($options['m'])) {
|
||||
$modules_input = $options['m'];
|
||||
$modules = explode(',', $modules_input);
|
||||
@@ -100,35 +77,22 @@ if (isset($options['m'])) {
|
||||
$modules = array();
|
||||
}
|
||||
|
||||
$full_os_name = $os_name;
|
||||
$variant = '';
|
||||
if (isset($options['v'])) {
|
||||
$variant = $options['v'];
|
||||
$full_os_name = $os_name . '_' . $variant;
|
||||
} elseif (isset($options['variant'])) {
|
||||
$variant = $options['variant'];
|
||||
$full_os_name = $os_name . '_' . $variant;
|
||||
}
|
||||
|
||||
echo "OS: $target_os\n";
|
||||
echo "Module: $modules_input\n";
|
||||
if ($variant) {
|
||||
echo "Variant: $variant\n";
|
||||
}
|
||||
echo PHP_EOL;
|
||||
$os_list = array();
|
||||
|
||||
$tester = new ModuleTestHelper($modules, $target_os, $variant);
|
||||
|
||||
|
||||
// Capture snmp data
|
||||
if ($device) {
|
||||
echo "Capturing Data: ";
|
||||
$prefer_new_snmprec = isset($options['n']) || isset($options['prefer-new']);
|
||||
$tester->captureFromDevice($device['device_id'], true, $prefer_new_snmprec);
|
||||
|
||||
if (isset($options['c']) || isset($options['collect-only'])) {
|
||||
// just capture, don't generate json
|
||||
exit;
|
||||
}
|
||||
|
||||
echo PHP_EOL;
|
||||
if ($os_name) {
|
||||
$os_list = [$full_os_name => [$os_name, $variant]];
|
||||
} else {
|
||||
$os_list = ModuleTestHelper::findOsWithData($modules);
|
||||
}
|
||||
|
||||
|
||||
@@ -138,10 +102,27 @@ $snmpsim->fork();
|
||||
$snmpsim_ip = $snmpsim->getIp();
|
||||
$snmpsim_port = $snmpsim->getPort();
|
||||
|
||||
|
||||
$no_save = isset($options['no-save']);
|
||||
$test_data = $tester->generateTestData($snmpsim, $no_save);
|
||||
|
||||
if ($no_save) {
|
||||
print_r($test_data);
|
||||
if (!$snmpsim->isRunning()) {
|
||||
echo "Failed to start snmpsim, make sure it is installed, working, and there are no bad snmprec files.\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
$no_save = isset($options['n']) || isset($options['no-save']);
|
||||
foreach ($os_list as $full_os_name => $parts) {
|
||||
list($target_os, $target_variant) = $parts;
|
||||
echo "OS: $target_os\n";
|
||||
echo "Module: $modules_input\n";
|
||||
if ($target_variant) {
|
||||
echo "Variant: $target_variant\n";
|
||||
}
|
||||
echo PHP_EOL;
|
||||
|
||||
$tester = new ModuleTestHelper($modules, $target_os, $target_variant);
|
||||
|
||||
$test_data = $tester->generateTestData($snmpsim, $no_save);
|
||||
|
||||
if ($no_save) {
|
||||
print_r($test_data);
|
||||
}
|
||||
}
|
||||
|
@@ -40,40 +40,37 @@ class OSModulesTest extends DBTestCase
|
||||
* @param string $filename file name of the json data
|
||||
* @param array $modules modules to test for this os
|
||||
*/
|
||||
public function testOS($target_os, $filename, $modules)
|
||||
public function testOS($os, $variant, $modules)
|
||||
{
|
||||
$this->requreSnmpsim(); // require snmpsim for tests
|
||||
global $snmpsim;
|
||||
|
||||
$file = Config::get('install_dir') . '/' . $filename;
|
||||
$expected_data = json_decode(file_get_contents($file), true);
|
||||
|
||||
list($os, $variant) = explode('_', $target_os, 2);
|
||||
|
||||
$helper = new ModuleTestHelper($modules, $os, $variant);
|
||||
$helper->setQuiet();
|
||||
$filename = $helper->getJsonFilepath(true);
|
||||
|
||||
$expected_data = $helper->getTestData();
|
||||
$results = $helper->generateTestData($snmpsim, true);
|
||||
|
||||
if (is_null($results)) {
|
||||
$this->fail("$target_os: Failed to collect data.");
|
||||
$this->fail("$os: Failed to collect data.");
|
||||
}
|
||||
|
||||
foreach ($modules as $module) {
|
||||
$this->assertEquals(
|
||||
$expected_data[$module]['discovery'],
|
||||
$results[$module]['discovery'],
|
||||
"OS $target_os: Discovered $module data does not match that found in $filename\n"
|
||||
"OS $os: Discovered $module data does not match that found in $filename\n"
|
||||
. $helper->getLastDiscoveryOutput()
|
||||
. "\nOS $target_os: Polled $module data does not match that found in $filename"
|
||||
. "\nOS $os: Polled $module data does not match that found in $filename"
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$expected_data[$module]['poller'] == 'matches discovery' ? $expected_data[$module]['discovery'] : $expected_data[$module]['poller'],
|
||||
$results[$module]['poller'],
|
||||
"OS $target_os: Polled $module data does not match that found in $filename\n"
|
||||
"OS $os: Polled $module data does not match that found in $filename\n"
|
||||
. $helper->getLastPollerOutput()
|
||||
. "\nOS $target_os: Polled $module data does not match that found in $filename"
|
||||
. "\nOS $os: Polled $module data does not match that found in $filename"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -81,29 +78,12 @@ class OSModulesTest extends DBTestCase
|
||||
|
||||
public function dumpedDataProvider()
|
||||
{
|
||||
$install_dir = Config::get('install_dir');
|
||||
$dump_files = glob("$install_dir/tests/data/*.json");
|
||||
$data = array();
|
||||
$modules = getenv('TEST_MODULES') ? explode(',', getenv('TEST_MODULES')) : array();
|
||||
$modules = array();
|
||||
|
||||
foreach ($dump_files as $file) {
|
||||
$os = basename($file, '.json');
|
||||
$short_file = str_replace($install_dir.'/', '', $file);
|
||||
$data_modules = array_keys(json_decode(file_get_contents($file), true));
|
||||
|
||||
if (count(array_diff($modules, $data_modules)) !== 0) {
|
||||
continue; // no test data for selected modules
|
||||
}
|
||||
|
||||
$test_modules = empty($modules) ? $data_modules : array_intersect($modules, $data_modules);
|
||||
|
||||
$data[$os] = array(
|
||||
$os,
|
||||
$short_file,
|
||||
$test_modules,
|
||||
);
|
||||
if (getenv('TEST_MODULES')) {
|
||||
$modules = explode(',', getenv('TEST_MODULES'));
|
||||
}
|
||||
|
||||
return $data;
|
||||
return ModuleTestHelper::findOsWithData($modules);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user