From 5819978bb2ff25f8617d8edbb8e2d39b399a3a38 Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Thu, 23 Jul 2015 18:35:55 -0700 Subject: [PATCH 01/20] unholy effort to wedge the previous test suite into unittest. --- setup.py | 4 +- test/run_tests.py | 47 ------------------- test/setup.py | 14 ------ test/t0.py | 34 -------------- test/t0_c_test.py | 40 ---------------- tests/__init__.py | 1 + {test => tests/coverage}/Makefile | 0 {test => tests/coverage}/README.md | 0 tests/coverage/__init__.py | 2 + {test => tests/coverage}/handwritten.c | 0 tests/coverage/old/t0.py | 39 +++++++++++++++ .../coverage/old}/t0_python_test.py | 2 +- {test => tests/coverage/old}/tint.c | 0 tests/coverage/setup.py | 21 +++++++++ {test => tests/coverage}/t0.asn | 0 tests/coverage/t0_c_driver.py | 37 +++++++++++++++ .../coverage/t0_gen_cases.py | 1 - .../t0_test.pyx => tests/coverage/t0_wrap.pyx | 0 tests/coverage/test_coverage.py | 42 +++++++++++++++++ tests/utils.py | 26 ++++++++++ tinyber/c_nodes.py | 2 +- 21 files changed, 172 insertions(+), 140 deletions(-) delete mode 100644 test/run_tests.py delete mode 100644 test/setup.py delete mode 100644 test/t0.py delete mode 100644 test/t0_c_test.py rename {test => tests/coverage}/Makefile (100%) rename {test => tests/coverage}/README.md (100%) create mode 100644 tests/coverage/__init__.py rename {test => tests/coverage}/handwritten.c (100%) create mode 100644 tests/coverage/old/t0.py rename {test => tests/coverage/old}/t0_python_test.py (96%) rename {test => tests/coverage/old}/tint.c (100%) create mode 100644 tests/coverage/setup.py rename {test => tests/coverage}/t0.asn (100%) create mode 100644 tests/coverage/t0_c_driver.py rename test/t0_gen_test.py => tests/coverage/t0_gen_cases.py (99%) rename test/t0_test.pyx => tests/coverage/t0_wrap.pyx (100%) create mode 100644 tests/coverage/test_coverage.py diff --git a/setup.py b/setup.py index f31c97c..7ce8082 100644 --- a/setup.py +++ b/setup.py @@ -17,8 +17,8 @@ description = 'ASN.1 code generator for Python and C', scripts = ['scripts/tinyber_gen', 'scripts/dax'], package_data = { - 'tinyber': ['data/*.[ch]', 'tinyber/codec.py'], - 'tests': ['*.asn1'], + 'tinyber': ['data/*.[ch]', 'tinyber/codec.py',], + 'tests': ['*.asn1', 'coverage/t0_wrap.pyx'], }, ext_modules = exts, test_suite = "tests", diff --git a/test/run_tests.py b/test/run_tests.py deleted file mode 100644 index 730aff6..0000000 --- a/test/run_tests.py +++ /dev/null @@ -1,47 +0,0 @@ - -# this is a first step toward moving this test suite into the 'tests' -# directory where it can be run with unittest. - -# 1) generate t0.[ch] - -# this is based on ../tests/utils.py - -from asn1ate import parser -from asn1ate.sema import * -from tinyber.walker import Walker - -from tinyber.c_nodes import CBackend -from tinyber import c_nodes as nodes - -def generate(infilename, outfilename): - class FakeArgs(object): - no_standalone = False - - import os - with open(infilename) as f: - asn1def = f.read() - - parse_tree = parser.parse_asn1(asn1def) - modules = build_semantic_model(parse_tree) - assert (len(modules) == 1) - - module_name = outfilename - path = "." - args = FakeArgs() - - # pull in the python-specific node implementations - walker = Walker(modules[0], nodes) - walker.walk() - - backend = CBackend(args, walker, module_name, path) - backend.generate_code() - - -generate ('t0.asn', 't0') - -# 2) build the cython extension in place. -from distutils.core import run_setup -run_setup ('setup.py', ['build_ext', '--inplace']) - -# 3) run the test -execfile ("t0_c_test.py") diff --git a/test/setup.py b/test/setup.py deleted file mode 100644 index 54cf34e..0000000 --- a/test/setup.py +++ /dev/null @@ -1,14 +0,0 @@ -from setuptools import setup, find_packages -from distutils.extension import Extension -from Cython.Build import cythonize - -ext = [ - Extension ("t0_test", ['t0_test.pyx', 't0.c', 'tinyber.c']) - ] - -setup ( - name = 'tinyber_test', - version = '0.1', - packages = find_packages(), - ext_modules = cythonize (ext) - ) diff --git a/test/t0.py b/test/t0.py deleted file mode 100644 index a121738..0000000 --- a/test/t0.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- Mode: Python; indent-tabs-mode: nil -*- - -from t0_ber import * - -def HD(s): - return s.decode ('hex') - -data = HD('300602016302016e') -p = Pair() -p.decode (data) -print p.encode().encode('hex') - -tests = [ - HD('6110300e020203e90101ff30003003020101'), - HD('611230100204400000000101ff30003003020101'), - HD('6110300e020203e901010030003003020101'), - HD('61133011020203e901010030003006020101020102'), - HD('61133011020203e901010030030101ff3003020101'), - HD('61163014020203e901010030060101ff0101003003020101'), - HD('603c303a040361626302013202022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101000a0100'), - HD('603c303a040361626302013302022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101000a0100'), - HD('603c303a040361626302013402022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101ff0a0100'), - HD('603c303a040361626302013202022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101000a0101'), - HD('603c303a040361626302013302022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101000a0101'), - HD('603c303a040361626302013402022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101ff0a0101'), - HD('603c303a040361626302013202022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101000a0102'), - HD('603c303a040361626302013302022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101000a0102'), - HD('603c303a040361626302013402022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101ff0a0102'), -] - -for data in tests: - m = ThingMsg() - m.decode (data) - print m.value diff --git a/test/t0_c_test.py b/test/t0_c_test.py deleted file mode 100644 index 406d538..0000000 --- a/test/t0_c_test.py +++ /dev/null @@ -1,40 +0,0 @@ -# -*- Mode: Python -*- - -# run the auto-generated tests on the C codec. - -from coro.asn1.ber import * -from t0_test import try_decode -from t0_gen_test import gen_thingmsg - -class ExpectedGood (Exception): - pass -class ExpectedBad (Exception): - pass -class BadEncoding (Exception): - pass - -# XXX use the unittest framework - -def go(): - n = 0 - for tval, good in gen_thingmsg(): - print tval.encode ('hex'), good - r = try_decode (tval) - if not good: - if r != -1: - # it should have been bad, but wasn't. - raise ExpectedBad - elif r == -1: - # it should have been good, but wasn't. - raise ExpectedGood - elif r != tval: - # it was a good decode, but the encoding wasn't identical. - raise BadEncoding - else: - # it's all good. - pass - n += 1 - print 'passed %d tests' % (n,) - -go() - diff --git a/tests/__init__.py b/tests/__init__.py index e69de29..72ca088 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -0,0 +1 @@ +import coverage diff --git a/test/Makefile b/tests/coverage/Makefile similarity index 100% rename from test/Makefile rename to tests/coverage/Makefile diff --git a/test/README.md b/tests/coverage/README.md similarity index 100% rename from test/README.md rename to tests/coverage/README.md diff --git a/tests/coverage/__init__.py b/tests/coverage/__init__.py new file mode 100644 index 0000000..97994ac --- /dev/null +++ b/tests/coverage/__init__.py @@ -0,0 +1,2 @@ +#import t0_python_test +import t0_gen_cases diff --git a/test/handwritten.c b/tests/coverage/handwritten.c similarity index 100% rename from test/handwritten.c rename to tests/coverage/handwritten.c diff --git a/tests/coverage/old/t0.py b/tests/coverage/old/t0.py new file mode 100644 index 0000000..1604943 --- /dev/null +++ b/tests/coverage/old/t0.py @@ -0,0 +1,39 @@ +# -*- Mode: Python; indent-tabs-mode: nil -*- + +def test(): + + from t0_ber import * + + def HD(s): + return s.decode ('hex') + + data = HD('300602016302016e') + p = Pair() + p.decode (data) + print p.encode().encode('hex') + + tests = [ + HD('6110300e020203e90101ff30003003020101'), + HD('611230100204400000000101ff30003003020101'), + HD('6110300e020203e901010030003003020101'), + HD('61133011020203e901010030003006020101020102'), + HD('61133011020203e901010030030101ff3003020101'), + HD('61163014020203e901010030060101ff0101003003020101'), + HD('603c303a040361626302013202022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101000a0100'), + HD('603c303a040361626302013302022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101000a0100'), + HD('603c303a040361626302013402022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101ff0a0100'), + HD('603c303a040361626302013202022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101000a0101'), + HD('603c303a040361626302013302022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101000a0101'), + HD('603c303a040361626302013402022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101ff0a0101'), + HD('603c303a040361626302013202022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101000a0102'), + HD('603c303a040361626302013302022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101000a0102'), + HD('603c303a040361626302013402022711020417bc927a3020300602010a020165300602010a020165300602010a020165300602010a0201650101ff0a0102'), + ] + + for data in tests: + m = ThingMsg() + m.decode (data) + print m.value + +if __name__ == '__main__': + test() diff --git a/test/t0_python_test.py b/tests/coverage/old/t0_python_test.py similarity index 96% rename from test/t0_python_test.py rename to tests/coverage/old/t0_python_test.py index 1d3d799..47ab483 100644 --- a/test/t0_python_test.py +++ b/tests/coverage/old/t0_python_test.py @@ -4,7 +4,7 @@ from coro.asn1.ber import * from t0_ber import ThingMsg -from t0_gen_test import gen_thingmsg +from t0_gen_cases import gen_thingmsg def try_decode (val): try: diff --git a/test/tint.c b/tests/coverage/old/tint.c similarity index 100% rename from test/tint.c rename to tests/coverage/old/tint.c diff --git a/tests/coverage/setup.py b/tests/coverage/setup.py new file mode 100644 index 0000000..65bdec2 --- /dev/null +++ b/tests/coverage/setup.py @@ -0,0 +1,21 @@ +from distutils.core import setup +from distutils.extension import Extension +from Cython.Build import cythonize + +exts = [ + Extension ("t0_wrap", ['t0_wrap.pyx', 't0.c', 'tinyber.c']) + ] + +# this is a complete hack to try to get unittest to work with this +# generated module. +import os +here = os.getcwd() +src, _ = os.path.split (__file__) +os.chdir (src) +try: + setup ( + ext_modules = cythonize (exts), + ) +finally: + os.chdir (here) + diff --git a/test/t0.asn b/tests/coverage/t0.asn similarity index 100% rename from test/t0.asn rename to tests/coverage/t0.asn diff --git a/tests/coverage/t0_c_driver.py b/tests/coverage/t0_c_driver.py new file mode 100644 index 0000000..abefde1 --- /dev/null +++ b/tests/coverage/t0_c_driver.py @@ -0,0 +1,37 @@ +# -*- Mode: Python -*- + +# run the auto-generated tests on the C codec. + +import unittest + +from coro.asn1.ber import * +from tests.coverage.t0_gen_cases import gen_thingmsg + +class ExpectedGood (Exception): + pass +class ExpectedBad (Exception): + pass +class BadEncoding (Exception): + pass + +class TestBasic(unittest.TestCase): + + def test_c_coverage (self): + # this is disgusting, but "from tests.coverage.t0_wrap" does not work here. + import sys + sys.path.append ('tests/coverage') + from t0_wrap import try_decode + for tval, good in gen_thingmsg(): + #print tval.encode ('hex'), good + r = try_decode (tval) + if not good: + # it should have been bad, but wasn't. + self.assertEqual (r, -1) + else: + self.assertNotEqual (r, -1) + self.assertEqual (r, tval) + +if __name__ == '__main__': + unittest.main() + + diff --git a/test/t0_gen_test.py b/tests/coverage/t0_gen_cases.py similarity index 99% rename from test/t0_gen_test.py rename to tests/coverage/t0_gen_cases.py index 2feb85e..96335ac 100644 --- a/test/t0_gen_test.py +++ b/tests/coverage/t0_gen_cases.py @@ -1,6 +1,5 @@ from coro.asn1.ber import * -from t0_test import try_decode # this will auto-generate test cases - both good and bad ones - to exhaustively # cover the tinyber codec generated for t0.asn. diff --git a/test/t0_test.pyx b/tests/coverage/t0_wrap.pyx similarity index 100% rename from test/t0_test.pyx rename to tests/coverage/t0_wrap.pyx diff --git a/tests/coverage/test_coverage.py b/tests/coverage/test_coverage.py new file mode 100644 index 0000000..21a61c2 --- /dev/null +++ b/tests/coverage/test_coverage.py @@ -0,0 +1,42 @@ + +# this is a first step toward moving this test suite into the 'tests' +# directory where it can be run with unittest. + +# 1) generate t0.[ch] + +# this is based on ../tests/utils.py + +from asn1ate import parser +from asn1ate.sema import * +from tinyber.walker import Walker + +from tinyber.c_nodes import CBackend +from tinyber import c_nodes as nodes + +import unittest +import os + +from tests.utils import generate_c + +class TestCoverage (unittest.TestCase): + + @classmethod + def setUpClass(cls): + import os + generate_c ('tests/coverage/t0.asn', 'tests/coverage/t0', '.') + from distutils.core import run_setup + run_setup ('tests/coverage/setup.py', ['build_ext', '--inplace']) + # ARRGGGHGHGHHHHHHHHHH + #import pdb; pdb.set_trace() + #os.rename ('t0_wrap.so', 'test/coverage/t0_wrap.so') + + @classmethod + def tearDownClass(cls): + pass + + def test_build_extension(self): + # dummy + pass + +if __name__ == '__main__': + unittest.main() diff --git a/tests/utils.py b/tests/utils.py index 8276210..84c29e9 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -29,6 +29,32 @@ class FakeArgs(object): backend = Backend(args, walker, module_name, path) backend.generate_code() +from tinyber.c_nodes import CBackend +from tinyber import c_nodes + +def generate_c(infilename, outfilename, path): + class FakeArgs(object): + no_standalone = False + + import os + with open(infilename) as f: + asn1def = f.read() + + parse_tree = parser.parse_asn1(asn1def) + modules = build_semantic_model(parse_tree) + assert (len(modules) == 1) + + module_name = outfilename + args = FakeArgs() + + # pull in the python-specific node implementations + walker = Walker(modules[0], c_nodes) + walker.walk() + + backend = CBackend(args, walker, module_name, path) + backend.generate_code() + + def test_reload(): import sys sys.path[:0] = '.' diff --git a/tinyber/c_nodes.py b/tinyber/c_nodes.py index 9acf50c..d469a0f 100644 --- a/tinyber/c_nodes.py +++ b/tinyber/c_nodes.py @@ -365,7 +365,7 @@ class CBackend: def __init__ (self, args, walker, module_name, path): self.args = args self.walker = walker - self.module_name = module_name + _, self.module_name = os.path.split (module_name) self.path = path self.base_path = os.path.join(path, module_name) From bfffe0067551b7f535f0d3092c6f68b4d0a2acbc Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Thu, 23 Jul 2015 18:45:20 -0700 Subject: [PATCH 02/20] hopefully the last tweak needed. --- tests/coverage/test_coverage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/coverage/test_coverage.py b/tests/coverage/test_coverage.py index 21a61c2..ab18ef7 100644 --- a/tests/coverage/test_coverage.py +++ b/tests/coverage/test_coverage.py @@ -23,7 +23,7 @@ class TestCoverage (unittest.TestCase): @classmethod def setUpClass(cls): import os - generate_c ('tests/coverage/t0.asn', 'tests/coverage/t0', '.') + generate_c ('tests/coverage/t0.asn', 't0', 'tests/coverage') from distutils.core import run_setup run_setup ('tests/coverage/setup.py', ['build_ext', '--inplace']) # ARRGGGHGHGHHHHHHHHHH From 17ce1d97850812c12eefe15e7db25a8170f73408 Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Thu, 23 Jul 2015 18:55:36 -0700 Subject: [PATCH 03/20] try test_reload() --- tests/coverage/t0_c_driver.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/coverage/t0_c_driver.py b/tests/coverage/t0_c_driver.py index abefde1..6287c41 100644 --- a/tests/coverage/t0_c_driver.py +++ b/tests/coverage/t0_c_driver.py @@ -6,6 +6,7 @@ from coro.asn1.ber import * from tests.coverage.t0_gen_cases import gen_thingmsg +from tests.utils import test_reload class ExpectedGood (Exception): pass @@ -18,6 +19,7 @@ class TestBasic(unittest.TestCase): def test_c_coverage (self): # this is disgusting, but "from tests.coverage.t0_wrap" does not work here. + test_reload() import sys sys.path.append ('tests/coverage') from t0_wrap import try_decode From dcca8ecf80789be500950841b60aaecb7c939f9a Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Thu, 23 Jul 2015 19:00:59 -0700 Subject: [PATCH 04/20] and yet another tweak. --- tests/coverage/t0_c_driver.py | 12 ++++++++++ tests/coverage/test_coverage.py | 42 --------------------------------- 2 files changed, 12 insertions(+), 42 deletions(-) delete mode 100644 tests/coverage/test_coverage.py diff --git a/tests/coverage/t0_c_driver.py b/tests/coverage/t0_c_driver.py index 6287c41..b76faa7 100644 --- a/tests/coverage/t0_c_driver.py +++ b/tests/coverage/t0_c_driver.py @@ -7,6 +7,7 @@ from coro.asn1.ber import * from tests.coverage.t0_gen_cases import gen_thingmsg from tests.utils import test_reload +from tests.utils import generate_c class ExpectedGood (Exception): pass @@ -17,6 +18,17 @@ class BadEncoding (Exception): class TestBasic(unittest.TestCase): + @classmethod + def setUpClass(cls): + import os + generate_c ('tests/coverage/t0.asn', 't0', 'tests/coverage') + from distutils.core import run_setup + run_setup ('tests/coverage/setup.py', ['build_ext', '--inplace']) + + @classmethod + def tearDownClass(cls): + pass + def test_c_coverage (self): # this is disgusting, but "from tests.coverage.t0_wrap" does not work here. test_reload() diff --git a/tests/coverage/test_coverage.py b/tests/coverage/test_coverage.py deleted file mode 100644 index ab18ef7..0000000 --- a/tests/coverage/test_coverage.py +++ /dev/null @@ -1,42 +0,0 @@ - -# this is a first step toward moving this test suite into the 'tests' -# directory where it can be run with unittest. - -# 1) generate t0.[ch] - -# this is based on ../tests/utils.py - -from asn1ate import parser -from asn1ate.sema import * -from tinyber.walker import Walker - -from tinyber.c_nodes import CBackend -from tinyber import c_nodes as nodes - -import unittest -import os - -from tests.utils import generate_c - -class TestCoverage (unittest.TestCase): - - @classmethod - def setUpClass(cls): - import os - generate_c ('tests/coverage/t0.asn', 't0', 'tests/coverage') - from distutils.core import run_setup - run_setup ('tests/coverage/setup.py', ['build_ext', '--inplace']) - # ARRGGGHGHGHHHHHHHHHH - #import pdb; pdb.set_trace() - #os.rename ('t0_wrap.so', 'test/coverage/t0_wrap.so') - - @classmethod - def tearDownClass(cls): - pass - - def test_build_extension(self): - # dummy - pass - -if __name__ == '__main__': - unittest.main() From bb1f0c0ac8bd7e810d1b60e322e8302ef42ca7a6 Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Fri, 24 Jul 2015 16:24:32 -0700 Subject: [PATCH 05/20] #comment --- tests/coverage/t0.asn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/coverage/t0.asn b/tests/coverage/t0.asn index b26e1b7..6528216 100644 --- a/tests/coverage/t0.asn +++ b/tests/coverage/t0.asn @@ -1,6 +1,6 @@ -- -*- Mode: asn1; indent-tabs-mode: nil -*- --- test module meant to exercise all supported features of tinyber_gen.py +-- test module meant to exercise all supported features of tinyber's code generators. ThingModule DEFINITIONS ::= BEGIN From 38f540a896f53265867546f372e44b8f94b8bf63 Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Fri, 24 Jul 2015 16:28:37 -0700 Subject: [PATCH 06/20] several changes to facilitate testing. equality: introduce __eq__ & __ne__ so that ASN1 objects can be compared directly. ENUMERATED: catch KeyError and translate it to BadEnum. emit_OCTET_STRING: convert to bytearray before encoding. --- tinyber/_codec.pyx | 28 +++++++++++++++++++++++++--- tinyber/codec.py | 27 ++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/tinyber/_codec.pyx b/tinyber/_codec.pyx index 72fa3bc..727da6b 100644 --- a/tinyber/_codec.pyx +++ b/tinyber/_codec.pyx @@ -36,6 +36,9 @@ class BadChoice (DecodingError): class ExtraData (DecodingError): pass +class BadEnum (DecodingError): + pass + # flags for BER tags cdef enum FLAGS: FLAGS_UNIVERSAL = 0x00 @@ -332,7 +335,7 @@ cdef class Encoder: cpdef emit_OCTET_STRING (self, s): with self.TLV (TAGS_OCTET_STRING): - self.emit (s) + self.emit (bytearray(s)) cpdef emit_BOOLEAN (self, v): with self.TLV (TAGS_BOOLEAN): @@ -352,6 +355,10 @@ class ASN1: def decode (self, data): b = Decoder (data) self._decode (b) + def __eq__ (self, other): + return isinstance (other, self.__class__) and self.value == other.value + def __ne__ (self, other): + return not self.__eq__ (other) def __repr__ (self): return '<%s %r>' % (self.__class__.__name__, self.value) @@ -360,6 +367,15 @@ class SEQUENCE (ASN1): def __init__ (self, **args): for k, v in args.iteritems(): setattr (self, k, v) + def __eq__ (self, other): + if not isinstance (other, self.__class__): + return False + else: + for name in self.__slots__: + if getattr (self, name) != getattr (other, name): + print 'slot __eq__ issue', name, getattr (self, name), getattr (other, name) + return False + return True def __repr__ (self): r = [] for name in self.__slots__: @@ -389,9 +405,15 @@ class ENUMERATED (ASN1): value = 'NoValueDefined' def _decode (self, Decoder src): v = src.next_ENUMERATED() - self.value = self.tags_r[v] + try: + self.value = self.tags_r[v] + except KeyError: + raise BadEnum (v) def _encode (self, Encoder dst): with dst.TLV (TAGS_ENUMERATED): - dst.emit_integer (self.tags_f[self.value]) + try: + dst.emit_integer(self.tags_f[self.value]) + except KeyError: + raise BadEnum (self.value) def __repr__ (self): return '<%s %s>' % (self.__class__.__name__, self.value) diff --git a/tinyber/codec.py b/tinyber/codec.py index cd76e96..3d4a21f 100644 --- a/tinyber/codec.py +++ b/tinyber/codec.py @@ -41,6 +41,9 @@ class ExtraData(DecodingError): pass +class BadEnum(DecodingError): + pass + class FLAG: UNIVERSAL = 0x00 STRUCTURED = 0x20 @@ -295,7 +298,7 @@ def emit_INTEGER(self, n): def emit_OCTET_STRING(self, s): with self.TLV(TAG.OCTETSTRING): - self.emit(s) + self.emit(bytearray(s)) def emit_BOOLEAN(self, v): with self.TLV(TAG.BOOLEAN): @@ -320,6 +323,12 @@ def decode(self, data): b = Decoder(data) self._decode(b) + def __eq__ (self, other): + return self.value == other.value + + def __ne__ (self, other): + return not self.__eq__ (other) + def __repr__(self): return '<%s %r>' % (self.__class__.__name__, self.value) @@ -331,6 +340,12 @@ def __init__(self, **args): for k, v in args.iteritems(): setattr(self, k, v) + def __eq__ (self, other): + for name in self.__slots__: + if getattr (self, name) != getattr (other, name): + return False + return True + def __repr__(self): r = [] for name in self.__slots__: @@ -363,11 +378,17 @@ class ENUMERATED(ASN1): def _decode(self, src): v = src.next_ENUMERATED() - self.value = self.tags_r[v] + try: + self.value = self.tags_r[v] + except KeyError: + raise BadEnum (v) def _encode(self, dst): with dst.TLV(TAG.ENUMERATED): - dst.emit_integer(self.tags_f[self.value]) + try: + dst.emit_integer(self.tags_f[self.value]) + except KeyError: + raise BadEnum (self.value) def __repr__(self): return '<%s %s>' % (self.__class__.__name__, self.value) From 097554cdc1031943d1c1904ee397d0c50fc6e8ba Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Fri, 24 Jul 2015 16:29:55 -0700 Subject: [PATCH 07/20] test the encoder. Note: the encoder does not [yet] check constraints, so we make a round-trip test. --- tests/coverage/t0_test_encoder.py | 120 ++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 tests/coverage/t0_test_encoder.py diff --git a/tests/coverage/t0_test_encoder.py b/tests/coverage/t0_test_encoder.py new file mode 100644 index 0000000..3f2f645 --- /dev/null +++ b/tests/coverage/t0_test_encoder.py @@ -0,0 +1,120 @@ +# -*- Mode: Python -*- + +# exhaustive test of the encoder, using t0.asn + +# Note: the encoder does not [yet] check constraints, only the decoder. +# this test suite will need slight tweaking once that is added. + +import unittest +from t0_ber import * + +class NoError (Exception): + pass + +def union_error (*errors): + r = NoError + # return the most specific error when possible + for e in errors: + if e is not NoError: + if r is NoError: + r = e + else: + # more than one specific error, use the base class + return DecodingError + return r + +def gen_pair(): + return [ + # good + (NoError, Pair (a=10, b=101)), + # out of range integer + (ConstraintViolation, Pair (a=10, b=10)), + (ConstraintViolation, Pair (a=1001, b=10)), + # unwanted negative integer + (ConstraintViolation, Pair (a=-5, b=-6)), + ] + +def gen_color(): + return [ + (NoError, Color ('red')), + (NoError, Color ('blue')), + (NoError, Color ('green')), + (BadEnum, Color ('orange')), + ] + +def gen_msgc(): + return [ + (NoError, MsgC (lstr = b'testing', tbool=False)), + (NoError, MsgC (lstr = b'x' * 499, tbool=False)), + (ConstraintViolation, MsgC (lstr = b'x' * 501, tbool=False)), + ] + +def gen_msgb(): + return [ + (NoError, MsgB (a=1001, b=True, x=[], y=[1])), + (NoError, MsgB (a=1<<30, b=True, x=[], y=[1])), + (NoError, MsgB (a=1001, b=False, x=[], y=[1])), + (NoError, MsgB (a=1001, b=False, x=[], y=[1, 2])), + # exactly one x + (NoError, MsgB (a=1001, b=False, x=[True], y=[1, 2])), + # exactly two x + (NoError, MsgB (a=1001, b=False, x=[True, False], y=[1, 2])), + # too many x + (ConstraintViolation, MsgB (a=1001, b=False, x=[True, False, True], y=[1, 2])), + # < 1 y + (ConstraintViolation, MsgB (a=1001, b=False, x=[], y=[])), + # out of range y + (ConstraintViolation, MsgB (a=1001, b=False, x=[], y=[1, 1001])), + ] + +def gen_msga(): + for error0, pair in gen_pair(): + for error1, color in gen_color(): + r0 = [ + # potentially good data + (NoError, MsgA (toctet=b'abc', t8int=50, t16int=10001, t32int=398234234, tarray=[pair, pair, pair, pair], tbool=False, tenum=color)), + (NoError, MsgA (toctet=b'abc', t8int=51, t16int=10001, t32int=398234234, tarray=[pair, pair, pair, pair], tbool=False, tenum=color)), + (NoError, MsgA (toctet=b'abc', t8int=52, t16int=10001, t32int=398234234, tarray=[pair, pair, pair, pair], tbool=False, tenum=color)), + (NoError, MsgA (toctet=b'abc', t8int=255, t16int=10001, t32int=398234234, tarray=[pair, pair, pair, pair], tbool=False, tenum=color)), + (ConstraintViolation, MsgA (toctet=b'abc', t8int=256, t16int=10001, t32int=398234234, tarray=[pair, pair, pair, pair], tbool=False, tenum=color)), + (ConstraintViolation, MsgA (toctet=b'abc', t8int=-1, t16int=10001, t32int=398234234, tarray=[pair, pair, pair, pair], tbool=False, tenum=color)), + # not enough entries + (ConstraintViolation, MsgA (toctet=b'abc', t8int=52, t16int=10001, t32int=398234234, tarray=[pair, pair, pair], tbool=False, tenum=color)), + # bad first type + (ConstraintViolation, MsgA (toctet=99, t8int=52, t16int=10001, t32int=398234234, tarray=[pair, pair, pair], tbool=False, tenum=color)), + ] + for error2, msg in r0: + yield union_error (error0, error1, error2), msg + +def gen_thingmsg(): + for error, msga in gen_msga(): + yield (error, ThingMsg (msga)) + for error, msgb in gen_msgb(): + yield (error, ThingMsg (msgb)) + for error, msgc in gen_msgc(): + yield (error, ThingMsg (msgc)) + +class TestEncoder(unittest.TestCase): + + # the codec does not currently check constraints in the *encoder*, + # so to verify contraint checking we do a round trip. + def round_trip (self, ob): + ob0 = ob.__class__() + encoded = ob.encode() + ob0.decode (encoded) + self.assertEqual (ob0, ob) + raise NoError + + def test_round_trip (self): + # all generators, simplest to the most complex + gens = [gen_pair, gen_color, gen_msgc, gen_msgb, gen_msga, gen_thingmsg] + n = 0 + for gen in gens: + for expected, ob in gen(): + with self.assertRaises (expected): + self.round_trip (ob) + n += 1 + # XXX would be nice if there was some way to report the total number of tests here. + +if __name__ == '__main__': + unittest.main() From 49b365bc27702004b3f4f3faf255fd9b4a095e47 Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Fri, 24 Jul 2015 16:34:13 -0700 Subject: [PATCH 08/20] include encoder test. --- tests/coverage/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/coverage/__init__.py b/tests/coverage/__init__.py index 97994ac..b60eaac 100644 --- a/tests/coverage/__init__.py +++ b/tests/coverage/__init__.py @@ -1,2 +1,4 @@ #import t0_python_test import t0_gen_cases +import t0_test_encoder + From 72d3d449815300ce03b36c26ab588e044f8d9f70 Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Fri, 24 Jul 2015 16:46:38 -0700 Subject: [PATCH 09/20] more desperate attempts to fix test ordering issues. --- tests/coverage/t0_c_driver.py | 3 +-- tests/coverage/t0_test_encoder.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/coverage/t0_c_driver.py b/tests/coverage/t0_c_driver.py index b76faa7..14d2f96 100644 --- a/tests/coverage/t0_c_driver.py +++ b/tests/coverage/t0_c_driver.py @@ -6,8 +6,7 @@ from coro.asn1.ber import * from tests.coverage.t0_gen_cases import gen_thingmsg -from tests.utils import test_reload -from tests.utils import generate_c +from tests.utils import test_reload, generate_c class ExpectedGood (Exception): pass diff --git a/tests/coverage/t0_test_encoder.py b/tests/coverage/t0_test_encoder.py index 3f2f645..85503c6 100644 --- a/tests/coverage/t0_test_encoder.py +++ b/tests/coverage/t0_test_encoder.py @@ -6,6 +6,7 @@ # this test suite will need slight tweaking once that is added. import unittest +from tests.utils import test_reload, generate_c from t0_ber import * class NoError (Exception): @@ -96,6 +97,17 @@ def gen_thingmsg(): class TestEncoder(unittest.TestCase): + @classmethod + def setUpClass(cls): + import os + generate_c ('tests/coverage/t0.asn', 't0', 'tests/coverage') + from distutils.core import run_setup + run_setup ('tests/coverage/setup.py', ['build_ext', '--inplace']) + + @classmethod + def tearDownClass(cls): + pass + # the codec does not currently check constraints in the *encoder*, # so to verify contraint checking we do a round trip. def round_trip (self, ob): From 31d40c20730c89bc525d498f4d2f848320faf5c7 Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Fri, 24 Jul 2015 16:51:12 -0700 Subject: [PATCH 10/20] use test_reload() --- tests/coverage/t0_test_encoder.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/coverage/t0_test_encoder.py b/tests/coverage/t0_test_encoder.py index 85503c6..1c777a6 100644 --- a/tests/coverage/t0_test_encoder.py +++ b/tests/coverage/t0_test_encoder.py @@ -118,6 +118,7 @@ def round_trip (self, ob): raise NoError def test_round_trip (self): + test_reload() # all generators, simplest to the most complex gens = [gen_pair, gen_color, gen_msgc, gen_msgb, gen_msga, gen_thingmsg] n = 0 From c7914ab40502fd1037f84b33e1abef0c18bf5d42 Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Fri, 24 Jul 2015 17:16:56 -0700 Subject: [PATCH 11/20] more insane attempts. --- tests/coverage/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/coverage/__init__.py b/tests/coverage/__init__.py index b60eaac..e6f0b41 100644 --- a/tests/coverage/__init__.py +++ b/tests/coverage/__init__.py @@ -1,4 +1,5 @@ -#import t0_python_test -import t0_gen_cases +# This is my attempt to get test_build to run first. It doesn't work. +import t0_test_build import t0_test_encoder +import t0_c_driver From 776d185b68c3eeb99223afb69fb2617c3755f1ac Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Fri, 24 Jul 2015 17:18:13 -0700 Subject: [PATCH 12/20] forgot to checkin. --- tests/coverage/t0_test_build.py | 37 +++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 tests/coverage/t0_test_build.py diff --git a/tests/coverage/t0_test_build.py b/tests/coverage/t0_test_build.py new file mode 100644 index 0000000..c7c5e05 --- /dev/null +++ b/tests/coverage/t0_test_build.py @@ -0,0 +1,37 @@ +# -*- Mode: Python -*- + +# run the auto-generated tests on the C codec. + +import unittest + +from coro.asn1.ber import * +from tests.coverage.t0_gen_cases import gen_thingmsg +from tests.utils import test_reload, generate_c + +class ExpectedGood (Exception): + pass +class ExpectedBad (Exception): + pass +class BadEncoding (Exception): + pass + +class TestBasic(unittest.TestCase): + + @classmethod + def setUpClass(cls): + import os + generate_c ('tests/coverage/t0.asn', 't0', 'tests/coverage') + from distutils.core import run_setup + run_setup ('tests/coverage/setup.py', ['build_ext', '--inplace']) + + @classmethod + def tearDownClass(cls): + pass + + def test_build (self): + pass + +if __name__ == '__main__': + unittest.main() + + From d9ec68c5117b4070f0a301785d82245bda2e680d Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Fri, 24 Jul 2015 17:41:47 -0700 Subject: [PATCH 13/20] trying to get the build happen from __init__.py --- tests/coverage/__init__.py | 13 ++++++++--- tests/coverage/setup.py | 26 +++++++++++++--------- tests/coverage/t0_c_driver.py | 11 --------- tests/coverage/t0_test_build.py | 37 ------------------------------- tests/coverage/t0_test_encoder.py | 11 --------- 5 files changed, 26 insertions(+), 72 deletions(-) delete mode 100644 tests/coverage/t0_test_build.py diff --git a/tests/coverage/__init__.py b/tests/coverage/__init__.py index e6f0b41..8806141 100644 --- a/tests/coverage/__init__.py +++ b/tests/coverage/__init__.py @@ -1,5 +1,12 @@ -# This is my attempt to get test_build to run first. It doesn't work. -import t0_test_build + +# build t0_wrap.pyx before doing any of the other tests. + +from tests.utils import generate_c + +print 'building from __init__ script...' +generate_c ('tests/coverage/t0.asn', 't0', 'tests/coverage') +from distutils.core import run_setup +run_setup ('tests/coverage/setup.py', ['build_ext', '--inplace']) + import t0_test_encoder import t0_c_driver - diff --git a/tests/coverage/setup.py b/tests/coverage/setup.py index 65bdec2..8136063 100644 --- a/tests/coverage/setup.py +++ b/tests/coverage/setup.py @@ -7,15 +7,21 @@ ] # this is a complete hack to try to get unittest to work with this -# generated module. +# generated module, and avoid trying to compile it more than once (in +# the wrong place). + import os -here = os.getcwd() -src, _ = os.path.split (__file__) -os.chdir (src) -try: - setup ( - ext_modules = cythonize (exts), - ) -finally: - os.chdir (here) +if 't0_wrap.so' in os.listdir ('tests/coverage'): + pass +else: + import os + here = os.getcwd() + src, _ = os.path.split (__file__) + os.chdir (src) + try: + setup ( + ext_modules = cythonize (exts), + ) + finally: + os.chdir (here) diff --git a/tests/coverage/t0_c_driver.py b/tests/coverage/t0_c_driver.py index 14d2f96..73fbeb1 100644 --- a/tests/coverage/t0_c_driver.py +++ b/tests/coverage/t0_c_driver.py @@ -17,17 +17,6 @@ class BadEncoding (Exception): class TestBasic(unittest.TestCase): - @classmethod - def setUpClass(cls): - import os - generate_c ('tests/coverage/t0.asn', 't0', 'tests/coverage') - from distutils.core import run_setup - run_setup ('tests/coverage/setup.py', ['build_ext', '--inplace']) - - @classmethod - def tearDownClass(cls): - pass - def test_c_coverage (self): # this is disgusting, but "from tests.coverage.t0_wrap" does not work here. test_reload() diff --git a/tests/coverage/t0_test_build.py b/tests/coverage/t0_test_build.py deleted file mode 100644 index c7c5e05..0000000 --- a/tests/coverage/t0_test_build.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- Mode: Python -*- - -# run the auto-generated tests on the C codec. - -import unittest - -from coro.asn1.ber import * -from tests.coverage.t0_gen_cases import gen_thingmsg -from tests.utils import test_reload, generate_c - -class ExpectedGood (Exception): - pass -class ExpectedBad (Exception): - pass -class BadEncoding (Exception): - pass - -class TestBasic(unittest.TestCase): - - @classmethod - def setUpClass(cls): - import os - generate_c ('tests/coverage/t0.asn', 't0', 'tests/coverage') - from distutils.core import run_setup - run_setup ('tests/coverage/setup.py', ['build_ext', '--inplace']) - - @classmethod - def tearDownClass(cls): - pass - - def test_build (self): - pass - -if __name__ == '__main__': - unittest.main() - - diff --git a/tests/coverage/t0_test_encoder.py b/tests/coverage/t0_test_encoder.py index 1c777a6..0f1d8c2 100644 --- a/tests/coverage/t0_test_encoder.py +++ b/tests/coverage/t0_test_encoder.py @@ -97,17 +97,6 @@ def gen_thingmsg(): class TestEncoder(unittest.TestCase): - @classmethod - def setUpClass(cls): - import os - generate_c ('tests/coverage/t0.asn', 't0', 'tests/coverage') - from distutils.core import run_setup - run_setup ('tests/coverage/setup.py', ['build_ext', '--inplace']) - - @classmethod - def tearDownClass(cls): - pass - # the codec does not currently check constraints in the *encoder*, # so to verify contraint checking we do a round trip. def round_trip (self, ob): From 53412ebd2fcca49d7f98ac9f08684f5f291a75e4 Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Fri, 24 Jul 2015 17:51:16 -0700 Subject: [PATCH 14/20] might be the shims... --- tests/coverage/t0_test_encoder.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/coverage/t0_test_encoder.py b/tests/coverage/t0_test_encoder.py index 0f1d8c2..22dfd52 100644 --- a/tests/coverage/t0_test_encoder.py +++ b/tests/coverage/t0_test_encoder.py @@ -7,6 +7,13 @@ import unittest from tests.utils import test_reload, generate_c + +import sys +sys.path.append ('tests/coverage') + +import t0_ber +print t0_ber.__file__ + from t0_ber import * class NoError (Exception): From c8732b3319c46a8a14290edb0c3418b6d7257e3f Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Fri, 24 Jul 2015 18:11:14 -0700 Subject: [PATCH 15/20] s/generate/generate_py: add output path to signature. --- tests/utils.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/utils.py b/tests/utils.py index 84c29e9..cb4adfd 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -6,7 +6,7 @@ from tinyber import py_nodes as nodes -def generate(infilename, outfilename): +def generate_py(infilename, outfilename, path): class FakeArgs(object): no_standalone = False @@ -19,7 +19,6 @@ class FakeArgs(object): assert (len(modules) == 1) module_name = outfilename - path = "tests" args = FakeArgs() # pull in the python-specific node implementations From 16a0ace060d6611e9e2a5994969a49dbd951c2dc Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Fri, 24 Jul 2015 18:11:28 -0700 Subject: [PATCH 16/20] s/generate/generate_py: add output path to signature. --- tests/test_choice.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_choice.py b/tests/test_choice.py index 0276e04..e0bb47a 100644 --- a/tests/test_choice.py +++ b/tests/test_choice.py @@ -7,13 +7,13 @@ from tinyber.py_nodes import PythonBackend as Backend from tinyber import py_nodes as nodes -from tests.utils import generate, test_reload +from tests.utils import generate_py, test_reload class TestBasic(unittest.TestCase): @classmethod def setUpClass(cls): - generate("tests/test_choice.asn1", "gen_choice") + generate_py("tests/test_choice.asn1", "gen_choice", 'tests') @classmethod def tearDownClass(cls): From f39c78318e93c8b99b9c1d8c3a40a5320766a8b2 Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Fri, 24 Jul 2015 18:11:44 -0700 Subject: [PATCH 17/20] generate t0_ber.py here, too. --- tests/coverage/__init__.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/coverage/__init__.py b/tests/coverage/__init__.py index 8806141..86c5dc0 100644 --- a/tests/coverage/__init__.py +++ b/tests/coverage/__init__.py @@ -1,12 +1,11 @@ # build t0_wrap.pyx before doing any of the other tests. -from tests.utils import generate_c +from tests.utils import generate_c, generate_py, test_reload print 'building from __init__ script...' generate_c ('tests/coverage/t0.asn', 't0', 'tests/coverage') from distutils.core import run_setup run_setup ('tests/coverage/setup.py', ['build_ext', '--inplace']) -import t0_test_encoder -import t0_c_driver +generate_py ('tests/coverage/t0.asn', 't0', 'tests/coverage') From c360425c830804bbd15b1b2deb9841eb665356f5 Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Mon, 27 Jul 2015 13:21:11 -0700 Subject: [PATCH 18/20] remove debug message. --- tinyber/_codec.pyx | 1 - 1 file changed, 1 deletion(-) diff --git a/tinyber/_codec.pyx b/tinyber/_codec.pyx index 727da6b..81daf9d 100644 --- a/tinyber/_codec.pyx +++ b/tinyber/_codec.pyx @@ -373,7 +373,6 @@ class SEQUENCE (ASN1): else: for name in self.__slots__: if getattr (self, name) != getattr (other, name): - print 'slot __eq__ issue', name, getattr (self, name), getattr (other, name) return False return True def __repr__ (self): From 280a32c9a6d1acd855765c5da06046be65cbde37 Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Mon, 27 Jul 2015 16:34:55 -0700 Subject: [PATCH 19/20] get_integer: frying-pan-to-the-face bug with negative integers. --- tinyber/_codec.pyx | 9 ++++----- tinyber/codec.py | 9 ++++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/tinyber/_codec.pyx b/tinyber/_codec.pyx index 81daf9d..56b4e73 100644 --- a/tinyber/_codec.pyx +++ b/tinyber/_codec.pyx @@ -174,11 +174,10 @@ cdef class Decoder: if n & 0x80: # negative n -= 0x100 - else: - while length: - n = n << 8 | self.pop_byte() - length -= 1 - return n + while length: + n = n << 8 | self.pop_byte() + length -= 1 + return n def next_INTEGER (self, min_val, max_val): self.check (TAGS_INTEGER) diff --git a/tinyber/codec.py b/tinyber/codec.py index 3d4a21f..8ba15a7 100644 --- a/tinyber/codec.py +++ b/tinyber/codec.py @@ -165,11 +165,10 @@ def get_integer(self, length): if n & 0x80: # negative n -= 0x100 - else: - while length: - n = n << 8 | self.pop_byte() - length -= 1 - return n + while length: + n = n << 8 | self.pop_byte() + length -= 1 + return n def next_INTEGER(self, min_val, max_val): self.check(TAG.INTEGER) From b194664274f1a8ba7a6de26a652a03ef205a1041 Mon Sep 17 00:00:00 2001 From: Sam Rushing Date: Mon, 27 Jul 2015 16:37:13 -0700 Subject: [PATCH 20/20] various changes to support python3. t0.asn: MsgD - a new PDU for testing negative integers & constraints. --- tests/__init__.py | 3 +- tests/coverage/t0.asn | 10 ++++-- tests/coverage/t0_c_driver.py | 3 +- tests/coverage/t0_gen_cases.py | 64 ++++++++++++++++++++-------------- 4 files changed, 49 insertions(+), 31 deletions(-) diff --git a/tests/__init__.py b/tests/__init__.py index 72ca088..62e58d5 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1 +1,2 @@ -import coverage +# -*- Mode: Python -*- + diff --git a/tests/coverage/t0.asn b/tests/coverage/t0.asn index 6528216..12b0899 100644 --- a/tests/coverage/t0.asn +++ b/tests/coverage/t0.asn @@ -8,8 +8,9 @@ ThingModule DEFINITIONS ::= BEGIN ThingMsg ::= CHOICE { msg-a [0] MsgA, - msg-b [1] MsgB, - msg-c [50] MsgC + msg-b [1] MsgB, + msg-c [50] MsgC, + msg-d [2] MsgD } Pair ::= SEQUENCE { @@ -46,5 +47,10 @@ ThingModule DEFINITIONS ::= BEGIN tbool BOOLEAN } + MsgD ::= SEQUENCE { + -- test negative ranges -- + x INTEGER (-10..10), + y INTEGER (-10..-5) + } END diff --git a/tests/coverage/t0_c_driver.py b/tests/coverage/t0_c_driver.py index 73fbeb1..ff7af69 100644 --- a/tests/coverage/t0_c_driver.py +++ b/tests/coverage/t0_c_driver.py @@ -4,7 +4,6 @@ import unittest -from coro.asn1.ber import * from tests.coverage.t0_gen_cases import gen_thingmsg from tests.utils import test_reload, generate_c @@ -30,7 +29,7 @@ def test_c_coverage (self): # it should have been bad, but wasn't. self.assertEqual (r, -1) else: - self.assertNotEqual (r, -1) + self.assertNotEqual (r, -1, msg=tval) self.assertEqual (r, tval) if __name__ == '__main__': diff --git a/tests/coverage/t0_gen_cases.py b/tests/coverage/t0_gen_cases.py index 96335ac..729c313 100644 --- a/tests/coverage/t0_gen_cases.py +++ b/tests/coverage/t0_gen_cases.py @@ -1,5 +1,6 @@ -from coro.asn1.ber import * +#from coro.asn1.ber import * +from cyber.ber import * # this will auto-generate test cases - both good and bad ones - to exhaustively # cover the tinyber codec generated for t0.asn. @@ -14,11 +15,11 @@ def gen_pair(): # unwanted negative integer (SEQUENCE (INTEGER (-5), INTEGER (-6)), False), # junk - ('asdfasdfasdf', False), - ('\xDE\xAD\xBE\xEF', False), - ('x', False), + (b'asdfasdfasdf', False), + (b'\xDE\xAD\xBE\xEF', False), + (b'x', False), # trailing junk - (SEQUENCE (INTEGER (10), INTEGER (101), 'asdfasdf'), False), + (SEQUENCE (INTEGER (10), INTEGER (101), b'asdfasdf'), False), (SEQUENCE (INTEGER (10), INTEGER (101), BOOLEAN(True)), False), ] @@ -32,8 +33,8 @@ def gen_color(): # bad type (INTEGER (99), False), # junk - ('wieuriuwiusdf', False), - ('x', False), + (b'wieuriuwiusdf', False), + (b'x', False), ] def gen_msgb(): @@ -55,12 +56,12 @@ def gen_msgb(): # out of range in y (SEQUENCE (INTEGER (1001), BOOLEAN(False), SEQUENCE(), SEQUENCE (INTEGER (1), INTEGER (1001))), False), # extra data - (SEQUENCE (INTEGER (1001), BOOLEAN(False), SEQUENCE(), BOOLEAN(True), OCTET_STRING ("asdfasdfasdfasdfasdfasdfasdfasdfasdf")), False), + (SEQUENCE (INTEGER (1001), BOOLEAN(False), SEQUENCE(), BOOLEAN(True), OCTET_STRING (b"asdfasdfasdfasdfasdfasdfasdfasdfasdf")), False), # not enough data (SEQUENCE (BOOLEAN(False), BOOLEAN(True)), False), (INTEGER (99), False), - ('ksdjfkjwekrjasdf', False), - ('x', False), + (b'ksdjfkjwekrjasdf', False), + (b'x', False), ] def gen_msga(): @@ -69,38 +70,47 @@ def gen_msga(): for color, good_color in gen_color(): result.extend ([ # -- potentially good data --- - (SEQUENCE (OCTET_STRING ('abc'), INTEGER (50), INTEGER (10001), INTEGER (398234234), SEQUENCE (pair,pair,pair,pair), BOOLEAN(False), color), good_pair and good_color), - (SEQUENCE (OCTET_STRING ('abc'), INTEGER (51), INTEGER (10001), INTEGER (398234234), SEQUENCE (pair,pair,pair,pair), BOOLEAN(False), color), good_pair and good_color), - (SEQUENCE (OCTET_STRING ('abc'), INTEGER (52), INTEGER (10001), INTEGER (398234234), SEQUENCE (pair,pair,pair,pair), BOOLEAN(True), color), good_pair and good_color), + (SEQUENCE (OCTET_STRING (b'abc'), INTEGER (50), INTEGER (10001), INTEGER (398234234), SEQUENCE (pair,pair,pair,pair), BOOLEAN(False), color), good_pair and good_color), + (SEQUENCE (OCTET_STRING (b'abc'), INTEGER (51), INTEGER (10001), INTEGER (398234234), SEQUENCE (pair,pair,pair,pair), BOOLEAN(False), color), good_pair and good_color), + (SEQUENCE (OCTET_STRING (b'abc'), INTEGER (52), INTEGER (10001), INTEGER (398234234), SEQUENCE (pair,pair,pair,pair), BOOLEAN(True), color), good_pair and good_color), # --- known to be bad data --- # not enough entries - (SEQUENCE (OCTET_STRING ('abc'), INTEGER (52), INTEGER (10001), INTEGER (398234234), SEQUENCE (pair,pair,pair), BOOLEAN(True), color), False), + (SEQUENCE (OCTET_STRING (b'abc'), INTEGER (52), INTEGER (10001), INTEGER (398234234), SEQUENCE (pair,pair,pair), BOOLEAN(True), color), False), # bad first type (SEQUENCE (INTEGER (99), INTEGER (50), INTEGER (10001), INTEGER (398234234), SEQUENCE (pair,pair,pair,pair), BOOLEAN(False), color), False), # out of range integers... - (SEQUENCE (OCTET_STRING ('abc'), INTEGER (410), INTEGER (10001), INTEGER (398234234), SEQUENCE (pair,pair,pair,pair), BOOLEAN(False), color), False), - (SEQUENCE (OCTET_STRING ('abc'), INTEGER (53), INTEGER (16555), INTEGER (398234234), SEQUENCE (pair,pair,pair,pair), BOOLEAN(False), color), False), - (SEQUENCE (OCTET_STRING ('abc'), INTEGER (54), INTEGER (10001), INTEGER (1<<33), SEQUENCE (pair,pair,pair,pair), BOOLEAN(False), color), False), + (SEQUENCE (OCTET_STRING (b'abc'), INTEGER (410), INTEGER (10001), INTEGER (398234234), SEQUENCE (pair,pair,pair,pair), BOOLEAN(False), color), False), + (SEQUENCE (OCTET_STRING (b'abc'), INTEGER (53), INTEGER (16555), INTEGER (398234234), SEQUENCE (pair,pair,pair,pair), BOOLEAN(False), color), False), + (SEQUENCE (OCTET_STRING (b'abc'), INTEGER (54), INTEGER (10001), INTEGER (1<<33), SEQUENCE (pair,pair,pair,pair), BOOLEAN(False), color), False), # bad type in SEQUENCE OF - (SEQUENCE (OCTET_STRING ('abc'), INTEGER (55), INTEGER (16555), INTEGER (99), SEQUENCE (INTEGER(99)), BOOLEAN(False), color), False), - (SEQUENCE (OCTET_STRING ('abc'), INTEGER (56), INTEGER (16555), INTEGER (99), INTEGER (99), BOOLEAN(False), color), False), + (SEQUENCE (OCTET_STRING (b'abc'), INTEGER (55), INTEGER (16555), INTEGER (99), SEQUENCE (INTEGER(99)), BOOLEAN(False), color), False), + (SEQUENCE (OCTET_STRING (b'abc'), INTEGER (56), INTEGER (16555), INTEGER (99), INTEGER (99), BOOLEAN(False), color), False), # bad type in place of BOOLEAN - (SEQUENCE (OCTET_STRING ('abc'), INTEGER (57), INTEGER (10001), INTEGER (398234234), SEQUENCE (pair,pair,pair,pair), INTEGER(-9), color), False), + (SEQUENCE (OCTET_STRING (b'abc'), INTEGER (57), INTEGER (10001), INTEGER (398234234), SEQUENCE (pair,pair,pair,pair), INTEGER(-9), color), False), # negative integers in unexpected places - (SEQUENCE (OCTET_STRING ('abc'), INTEGER (58), INTEGER (10001), INTEGER (-1000), SEQUENCE (pair,pair,pair), BOOLEAN(True), color), False), - (SEQUENCE (OCTET_STRING ('abc'), INTEGER (59), INTEGER (-100), INTEGER (-1000), SEQUENCE (pair,pair,pair), BOOLEAN(True), color), False), - (SEQUENCE (OCTET_STRING ('abc'), INTEGER (-20), INTEGER (-100), INTEGER (-1000), SEQUENCE (pair,pair,pair), BOOLEAN(True), color), False), + (SEQUENCE (OCTET_STRING (b'abc'), INTEGER (58), INTEGER (10001), INTEGER (-1000), SEQUENCE (pair,pair,pair), BOOLEAN(True), color), False), + (SEQUENCE (OCTET_STRING (b'abc'), INTEGER (59), INTEGER (-100), INTEGER (-1000), SEQUENCE (pair,pair,pair), BOOLEAN(True), color), False), + (SEQUENCE (OCTET_STRING (b'abc'), INTEGER (-20), INTEGER (-100), INTEGER (-1000), SEQUENCE (pair,pair,pair), BOOLEAN(True), color), False), ]) return result def gen_msgc(): return [ - (SEQUENCE (OCTET_STRING (''), BOOLEAN (True)), True), - (SEQUENCE (OCTET_STRING ('x' * 499), BOOLEAN (True)), True), - (SEQUENCE (OCTET_STRING ('x' * 501), BOOLEAN (True)), False), + (SEQUENCE (OCTET_STRING (b''), BOOLEAN (True)), True), + (SEQUENCE (OCTET_STRING (b'x' * 499), BOOLEAN (True)), True), + (SEQUENCE (OCTET_STRING (b'x' * 501), BOOLEAN (True)), False), ] +def gen_msgd(): + # x INTEGER (-10..10), + # y INTEGER (-10..-5) + # exhaustive test around the range + for i in range (-20, 20): + for j in range (-20, 20): + good = (-10 <= i <= 10) and (-10 <= j <= -5) + yield (SEQUENCE (INTEGER (i), INTEGER (j)), good) + def gen_thingmsg(): result = [] for msgb, good in gen_msgb(): @@ -115,4 +125,6 @@ def gen_thingmsg(): result.append ((APPLICATION (1, True, msga), False),) for msgc, good in gen_msgc(): result.append ((APPLICATION (50, True, msgc), good)) + for msgd, good in gen_msgd(): + result.append ((APPLICATION (2, True, msgd), good)) return result