librenms/tests/MibTest.php
Tony Murray fff66d3c00
Feature: Generic discovery and poller tests (#7873)
* Processor Tests!

* Capture data from live devices easily.

* fix up some stuff, remove powerconnect things as they seem to be just broken.

* formatting, fix missing assignment
add netonix processor data

* fix multi-line, always add sysDescr and sysObjectID
ios cpm test file

* revert composer change and fix whitespace issues

* add help text

* missed help text

* tighter debug output

* handle empty strings properly and mibs with numbers

* use keys for sorting as intended

* fix type with empty data

* oops :)

* whitespace fix

* try installing fping

* Fix TestCase collision + cleanup

* mark TestCase as abstract
don't run two instances of snmpsim

* better database dumps, improved capture

* style fixes

* fix quotes add a few more tables

* add --prefer-new, properly merge data

* Support separate discovery and poller data. But don't waste space if they aren't needed.

* refactor to use class
collects all code in one place for reusability

* reorganize

* Print out when not saving.

* Support for running multiple (or all) modules at once.

* tidy

* Change unit test to a generic name and test all modules we have data for.

* Add documentation and a few more tidies

* whitespace fixes

* Fix tests, add a couple more modules, more docs

* More docs updates

* Fix scrutinizer issues

* add bgp-peers
2017-12-20 08:36:49 -06:00

208 lines
5.9 KiB
PHP

<?php
/**
* MibTest.php
*
* Test Mib files for errors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2017 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace LibreNMS\Tests;
use Exception;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use SplFileInfo;
/**
* Class MibTest
* @package LibreNMS\Tests
*
* Tests mib files for errors.
* Will not be run by default, use --group=mibs to test.
* You may test specific directories or files by specifying them with filter. Example: --filter=@RFC1284-MIB
*/
class MibTest extends TestCase
{
/**
* Test mib file in a directory for errors
*
* @group mibs
* @dataProvider mibDirs
* @param $dir
*/
public function testMibDirectory($dir)
{
global $config;
$output = shell_exec("snmptranslate -M +{$config['mib_dir']}:$dir -m +ALL SNMPv2-MIB::system 2>&1");
$errors = str_replace("SNMPv2-MIB::system\n", '', $output);
$this->assertEmpty($errors, "MIBs in $dir have errors!\n$errors");
}
/**
* Test that each mib only exists once.
*
* @group mibs
* @dataProvider mibFiles
* @param $path
* @param $file
* @param $mib_name
*/
public function testDuplicateMibs($path, $file, $mib_name)
{
global $console_color;
$file_path = "$path/$file";
$highligted_mib = $console_color->convert("%r$mib_name%n");
static $existing_mibs;
if (is_null($existing_mibs)) {
$existing_mibs = array();
}
if (isset($existing_mibs[$mib_name])) {
$existing_mibs[$mib_name][] = $file_path;
$this->fail("$highligted_mib has duplicates: " . implode(', ', $existing_mibs[$mib_name]));
} else {
$existing_mibs[$mib_name] = array($file_path);
}
}
/**
* Test that the file name matches the mib name
*
* @group mibs
* @dataProvider mibFiles
* @param $path
* @param $file
* @param $mib_name
*/
public function testMibNameMatches($path, $file, $mib_name)
{
global $console_color;
$file_path = "$path/$file";
$highlighted_file = $console_color->convert("%r$file_path%n");
$this->assertEquals($mib_name, $file, "$highlighted_file should be named $mib_name");
}
/**
* Test each mib file for errors
*
* @group mibs
* @dataProvider mibFiles
* @param $path
* @param $file
* @param $mib_name
*/
public function testMibContents($path, $file, $mib_name)
{
global $config, $console_color;
$file_path = "$path/$file";
$highlighted_file = $console_color->convert("%r$file_path%n");
$output = shell_exec("snmptranslate -M +{$config['mib_dir']}:$path -m +$mib_name SNMPv2-MIB::system 2>&1");
$errors = str_replace("SNMPv2-MIB::system\n", '', $output);
$this->assertEmpty($errors, "$highlighted_file has errors!\n$errors");
}
/**
* Get a list of all mib files with the name of the mib.
* Called for each test that uses it before class setup.
* @return array path, filename, mib_name
*/
public function mibFiles()
{
global $config;
$file_list = array();
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($config['mib_dir'])) as $file) {
/** @var SplFileInfo $file */
if ($file->isDir()) {
continue;
}
$mib_path = str_replace($config['mib_dir'].'/', '', $file->getPathName());
$file_list[$mib_path] = array(
str_replace($config['install_dir'], '.', $file->getPath()),
$file->getFilename(),
$this->extractMibName($file->getPathname())
);
}
return $file_list;
}
/**
* List all directories inside the mib directory
* @return array
*/
public function mibDirs()
{
global $config;
$dirs = glob($config['mib_dir'] . '/*', GLOB_ONLYDIR);
array_unshift($dirs, $config['mib_dir']);
$final_list = array();
foreach ($dirs as $dir) {
$relative_dir = str_replace($config['mib_dir'].'/', '', $dir);
$final_list[$relative_dir] = array($dir);
}
return $final_list;
}
/**
* Extract the mib name from a file
*
* @param $file
* @return mixed
* @throws Exception
*/
private function extractMibName($file)
{
// extract the mib name (tried regex, but was too complex and I had to read the whole file)
$mib_name = null;
if ($handle = fopen($file, "r")) {
$header = '';
while (($line = fgets($handle)) !== false) {
$trimmed = trim($line);
if (empty($trimmed) || starts_with($trimmed, '--')) {
continue;
}
$header .= " $trimmed";
if (str_contains($trimmed, 'DEFINITIONS')) {
preg_match('/(\S+)\s+(?=DEFINITIONS)/', $header, $matches);
fclose($handle);
return $matches[1];
}
}
fclose($handle);
}
throw new Exception("Could not extract mib name from file ($file)");
}
}