From 88d214c8f25c29576df89388c9570dc15fdea1d3 Mon Sep 17 00:00:00 2001 From: David van Moolenbroek Date: Fri, 23 Aug 2024 17:51:31 +0200 Subject: [PATCH] Allow tables to be used as table columns This fix is specifically for WIENER-CRATE-MIB, which uses a "SEQUENCE" declaration that includes a table object symbol. As a result, the corresponding object type is considered to be a table column, resulting in generated Python code that cannot be loaded. This commit adds an extra restriction for object types to be considered table columns, namely that they must not have a "SEQUENCE OF" type syntax. In other words, object types that are tables are no longer ever considered to be table columns. That restriction allows WIENER-CRATE-MIB to be loaded properly. The commit also adds a test case, which consists of a simplified version of the construction found in WIENER-CRATE-MIB. --- pysmi/codegen/intermediate.py | 8 ++-- tests/test_objecttype_smiv2_pysnmp.py | 63 +++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/pysmi/codegen/intermediate.py b/pysmi/codegen/intermediate.py index 5f1889f..d15b33d 100644 --- a/pysmi/codegen/intermediate.py +++ b/pysmi/codegen/intermediate.py @@ -478,11 +478,13 @@ def genObjectType(self, data): if syntax[0]: nodetype = syntax[0] == "Bits" and "scalar" or syntax[0] # Bits hack - nodetype = ( + # If this object type is used as a column, but it also has a + # "SEQUENCE OF" syntax, then it is really a table and not a column. + isColumn = ( pysmiName in self.symbolTable[self.moduleName[0]]["_symtable_cols"] - and "column" - or nodetype + and syntax[1] ) + nodetype = isColumn and "column" or nodetype outDict["nodetype"] = nodetype outDict["class"] = "objecttype" diff --git a/tests/test_objecttype_smiv2_pysnmp.py b/tests/test_objecttype_smiv2_pysnmp.py index 5033f88..fdec37e 100644 --- a/tests/test_objecttype_smiv2_pysnmp.py +++ b/tests/test_objecttype_smiv2_pysnmp.py @@ -1097,6 +1097,69 @@ def testObjectTypeTableRowIndex(self): ) +class ObjectTypeMibTableAndColumnTestCase(unittest.TestCase): + """ + TEST-MIB DEFINITIONS ::= BEGIN + IMPORTS + OBJECT-TYPE + FROM SNMPv2-SMI; + + Overview ::= SEQUENCE { + testTable TestEntry + } + + testTable OBJECT-TYPE + SYNTAX SEQUENCE OF TestEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION "Test table" + ::= { 1 3 } + + testEntry OBJECT-TYPE + SYNTAX TestEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION "Test row" + INDEX { testIndex } + ::= { testTable 1 } + + TestEntry ::= SEQUENCE { + testIndex INTEGER + } + + testIndex OBJECT-TYPE + SYNTAX INTEGER + MAX-ACCESS read-create + STATUS current + DESCRIPTION "Test column" + ::= { testEntry 1 } + + END + """ + + def setUp(self): + ast = parserFactory()().parse(self.__class__.__doc__)[0] + mibInfo, symtable = SymtableCodeGen().genCode(ast, {}) + self.mibInfo, pycode = PySnmpCodeGen().genCode(ast, {mibInfo.name: symtable}) + codeobj = compile(pycode, "test", "exec") + + self.ctx = {"mibBuilder": MibBuilder()} + + exec(codeobj, self.ctx, self.ctx) + + def testObjectTypeTableClass(self): + self.assertEqual( + self.ctx["testTable"].__class__.__name__, "MibTable", "bad table class" + ) + + def testObjectTypeTableRowClass(self): + self.assertEqual( + self.ctx["testEntry"].__class__.__name__, + "MibTableRow", + "bad table row class", + ) + + suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) if __name__ == "__main__":