diff options
author | Ilya Etingof <etingof@gmail.com> | 2017-02-12 10:54:00 +0100 |
---|---|---|
committer | Ilya Etingof <etingof@gmail.com> | 2017-02-12 10:54:00 +0100 |
commit | 22e53a32753acfdc4101f6cb3f4d45397d72ce5c (patch) | |
tree | 574d16c8c1d71091db51798f1ec8c75a6494749e /tests | |
parent | 1bbefa9040dcd38195bb94bfeb85349b441659bd (diff) | |
download | pyasn1-22e53a32753acfdc4101f6cb3f4d45397d72ce5c.tar.gz |
test dir renamed into tests
Diffstat (limited to 'tests')
28 files changed, 3965 insertions, 0 deletions
diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..8c3066b --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/tests/__main__.py b/tests/__main__.py new file mode 100644 index 0000000..70bd9ea --- /dev/null +++ b/tests/__main__.py @@ -0,0 +1,21 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +try: + import unittest2 as unittest + +except ImportError: + import unittest + +suite = unittest.TestLoader().loadTestsFromNames( + ['tests.test_debug.suite', + 'tests.type.__main__.suite', + 'tests.codec.__main__.suite'] +) + + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/__init__.py b/tests/codec/__init__.py new file mode 100644 index 0000000..8c3066b --- /dev/null +++ b/tests/codec/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/tests/codec/__main__.py b/tests/codec/__main__.py new file mode 100644 index 0000000..bcfd96f --- /dev/null +++ b/tests/codec/__main__.py @@ -0,0 +1,22 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +try: + import unittest2 as unittest + +except ImportError: + import unittest + +suite = unittest.TestLoader().loadTestsFromNames( + ['tests.codec.ber.__main__.suite', + 'tests.codec.cer.__main__.suite', + 'tests.codec.der.__main__.suite', + 'tests.codec.native.__main__.suite'] +) + + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/ber/__init__.py b/tests/codec/ber/__init__.py new file mode 100644 index 0000000..8c3066b --- /dev/null +++ b/tests/codec/ber/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/tests/codec/ber/__main__.py b/tests/codec/ber/__main__.py new file mode 100644 index 0000000..2909628 --- /dev/null +++ b/tests/codec/ber/__main__.py @@ -0,0 +1,20 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +try: + import unittest2 as unittest + +except ImportError: + import unittest + +suite = unittest.TestLoader().loadTestsFromNames( + ['tests.codec.ber.test_encoder.suite', + 'tests.codec.ber.test_decoder.suite'] +) + + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/ber/test_decoder.py b/tests/codec/ber/test_decoder.py new file mode 100644 index 0000000..c1852c4 --- /dev/null +++ b/tests/codec/ber/test_decoder.py @@ -0,0 +1,817 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1.type import tag, namedtype, univ, char +from pyasn1.codec.ber import decoder, eoo +from pyasn1.compat.octets import ints2octs, str2octs, null +from pyasn1.error import PyAsn1Error + + +class BadAsn1SpecTestCase(unittest.TestCase): + def testBadSpec(self): + try: + decoder.decode(ints2octs((48, 2, 5, 0)), asn1Spec='not an Asn1Item') + except PyAsn1Error: + pass + else: + assert 0, 'Invalid asn1Spec accepted' + + +class LargeTagDecoderTestCase(unittest.TestCase): + def testLargeTag(self): + assert decoder.decode(ints2octs((127, 141, 245, 182, 253, 47, 3, 2, 1, 1))) == (1, null) + + def testLongTag(self): + assert decoder.decode(ints2octs((0x1f, 2, 1, 0)))[0].tagSet == univ.Integer.tagSet + + def testTagsEquivalence(self): + integer = univ.Integer(2, tag.TagSet((), tag.Tag(tag.tagClassContext, 0, 0))) + assert decoder.decode(ints2octs((0x9f, 0x80, 0x00, 0x02, 0x01, 0x02)), asn1Spec=integer) == decoder.decode( + ints2octs((0x9f, 0x00, 0x02, 0x01, 0x02)), asn1Spec=integer) + + +class DecoderCacheTestCase(unittest.TestCase): + def testCache(self): + assert decoder.decode(ints2octs((0x1f, 2, 1, 0))) == decoder.decode(ints2octs((0x1f, 2, 1, 0))) + + +class IntegerDecoderTestCase(unittest.TestCase): + def testPosInt(self): + assert decoder.decode(ints2octs((2, 1, 12))) == (12, null) + + def testNegInt(self): + assert decoder.decode(ints2octs((2, 1, 244))) == (-12, null) + + def testZero(self): + assert decoder.decode(ints2octs((2, 0))) == (0, null) + + def testZeroLong(self): + assert decoder.decode(ints2octs((2, 1, 0))) == (0, null) + + def testMinusOne(self): + assert decoder.decode(ints2octs((2, 1, 255))) == (-1, null) + + def testPosLong(self): + assert decoder.decode( + ints2octs((2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255)) + ) == (0xffffffffffffffff, null) + + def testNegLong(self): + assert decoder.decode( + ints2octs((2, 9, 255, 0, 0, 0, 0, 0, 0, 0, 1)) + ) == (-0xffffffffffffffff, null) + + def testSpec(self): + try: + decoder.decode( + ints2octs((2, 1, 12)), asn1Spec=univ.Null() + ) == (12, null) + except PyAsn1Error: + pass + else: + assert 0, 'wrong asn1Spec worked out' + assert decoder.decode( + ints2octs((2, 1, 12)), asn1Spec=univ.Integer() + ) == (12, null) + + def testTagFormat(self): + try: + decoder.decode(ints2octs((34, 1, 12))) + except PyAsn1Error: + pass + else: + assert 0, 'wrong tagFormat worked out' + + +class BooleanDecoderTestCase(unittest.TestCase): + def testTrue(self): + assert decoder.decode(ints2octs((1, 1, 1))) == (1, null) + + def testTrueNeg(self): + assert decoder.decode(ints2octs((1, 1, 255))) == (1, null) + + def testExtraTrue(self): + assert decoder.decode(ints2octs((1, 1, 1, 0, 120, 50, 50))) == (1, ints2octs((0, 120, 50, 50))) + + def testFalse(self): + assert decoder.decode(ints2octs((1, 1, 0))) == (0, null) + + def testTagFormat(self): + try: + decoder.decode(ints2octs((33, 1, 1))) + except PyAsn1Error: + pass + else: + assert 0, 'wrong tagFormat worked out' + + +class BitStringDecoderTestCase(unittest.TestCase): + def testDefMode(self): + assert decoder.decode( + ints2octs((3, 3, 1, 169, 138)) + ) == ((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1), null) + + def testIndefMode(self): + assert decoder.decode( + ints2octs((3, 3, 1, 169, 138)) + ) == ((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1), null) + + def testDefModeChunked(self): + assert decoder.decode( + ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138)) + ) == ((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1), null) + + def testIndefModeChunked(self): + assert decoder.decode( + ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0)) + ) == ((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1), null) + + def testDefModeChunkedSubst(self): + assert decoder.decode( + ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138)), + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs((3, 2, 0, 169, 3, 2, 1, 138)), 8) + + def testIndefModeChunkedSubst(self): + assert decoder.decode( + ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0)), + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs((3, 2, 0, 169, 3, 2, 1, 138, 0, 0)), -1) + + def testTypeChecking(self): + try: + decoder.decode(ints2octs((35, 4, 2, 2, 42, 42))) + except PyAsn1Error: + pass + else: + assert 0, 'accepted mis-encoded bit-string constructed out of an integer' + + +class OctetStringDecoderTestCase(unittest.TestCase): + def testDefMode(self): + assert decoder.decode( + ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)) + ) == (str2octs('Quick brown fox'), null) + + def testIndefMode(self): + assert decoder.decode( + ints2octs((36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0)) + ) == (str2octs('Quick brown fox'), null) + + def testDefModeChunked(self): + assert decoder.decode( + ints2octs( + (36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)) + ) == (str2octs('Quick brown fox'), null) + + def testIndefModeChunked(self): + assert decoder.decode( + ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, + 120, 0, 0)) + ) == (str2octs('Quick brown fox'), null) + + def testDefModeChunkedSubst(self): + assert decoder.decode( + ints2octs( + (36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)), + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs((4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)), + 23) + + def testIndefModeChunkedSubst(self): + assert decoder.decode( + ints2octs((36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, + 120, 0, 0)), + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs( + (4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120, 0, 0)), -1) + + +class ExpTaggedOctetStringDecoderTestCase(unittest.TestCase): + def setUp(self): + self.o = univ.OctetString( + 'Quick brown fox', + tagSet=univ.OctetString.tagSet.tagExplicitly( + tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 5) + )) + + def testDefMode(self): + assert self.o.isSameTypeWith(decoder.decode( + ints2octs((101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)) + )[0]) + + def testIndefMode(self): + v, s = decoder.decode(ints2octs(( + 101, 128, 36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, + 102, 111, 120, 0, 0, 0, 0))) + assert self.o.isSameTypeWith(v) + assert not s + + def testDefModeChunked(self): + v, s = decoder.decode(ints2octs(( + 101, 25, 36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, + 110, 32, 4, 3, 102, 111, 120))) + assert self.o.isSameTypeWith(v) + assert not s + + def testIndefModeChunked(self): + v, s = decoder.decode(ints2octs((101, 128, 36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, + 119, 110, 32, 4, 3, 102, 111, 120, 0, 0, 0, 0))) + assert self.o.isSameTypeWith(v) + assert not s + + def testDefModeSubst(self): + assert decoder.decode( + ints2octs((101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)), + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)), 17) + + def testIndefModeSubst(self): + assert decoder.decode( + ints2octs(( + 101, 128, 36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, + 0, 0, 0)), + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs( + (36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0, 0, 0)), -1) + + +class NullDecoderTestCase(unittest.TestCase): + def testNull(self): + assert decoder.decode(ints2octs((5, 0))) == (null, null) + + def testTagFormat(self): + try: + decoder.decode(ints2octs((37, 0))) + except PyAsn1Error: + pass + else: + assert 0, 'wrong tagFormat worked out' + + +# Useful analysis of OID encoding issues could be found here: +# http://www.viathinksoft.de/~daniel-marschall/asn.1/oid_facts.html +class ObjectIdentifierDecoderTestCase(unittest.TestCase): + def testOne(self): + assert decoder.decode( + ints2octs((6, 6, 43, 6, 0, 191, 255, 126)) + ) == ((1, 3, 6, 0, 0xffffe), null) + + def testEdge1(self): + assert decoder.decode( + ints2octs((6, 1, 39)) + ) == ((0, 39), null) + + def testEdge2(self): + assert decoder.decode( + ints2octs((6, 1, 79)) + ) == ((1, 39), null) + + def testEdge3(self): + assert decoder.decode( + ints2octs((6, 1, 120)) + ) == ((2, 40), null) + + def testEdge4(self): + assert decoder.decode( + ints2octs((6, 5, 0x90, 0x80, 0x80, 0x80, 0x4F)) + ) == ((2, 0xffffffff), null) + + def testEdge5(self): + assert decoder.decode( + ints2octs((6, 1, 0x7F)) + ) == ((2, 47), null) + + def testEdge6(self): + assert decoder.decode( + ints2octs((6, 2, 0x81, 0x00)) + ) == ((2, 48), null) + + def testEdge7(self): + assert decoder.decode( + ints2octs((6, 3, 0x81, 0x34, 0x03)) + ) == ((2, 100, 3), null) + + def testEdge8(self): + assert decoder.decode( + ints2octs((6, 2, 133, 0)) + ) == ((2, 560), null) + + def testEdge9(self): + assert decoder.decode( + ints2octs((6, 4, 0x88, 0x84, 0x87, 0x02)) + ) == ((2, 16843570), null) + + def testNonLeading0x80(self): + assert decoder.decode( + ints2octs((6, 5, 85, 4, 129, 128, 0)), + ) == ((2, 5, 4, 16384), null) + + def testLeading0x80Case1(self): + try: + decoder.decode( + ints2octs((6, 5, 85, 4, 128, 129, 0)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'Leading 0x80 tolarated' + + def testLeading0x80Case2(self): + try: + decoder.decode( + ints2octs((6, 7, 1, 0x80, 0x80, 0x80, 0x80, 0x80, 0x7F)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'Leading 0x80 tolarated' + + def testLeading0x80Case3(self): + try: + decoder.decode( + ints2octs((6, 2, 0x80, 1)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'Leading 0x80 tolarated' + + def testLeading0x80Case4(self): + try: + decoder.decode( + ints2octs((6, 2, 0x80, 0x7F)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'Leading 0x80 tolarated' + + def testTagFormat(self): + try: + decoder.decode(ints2octs((38, 1, 239))) + except PyAsn1Error: + pass + else: + assert 0, 'wrong tagFormat worked out' + + def testZeroLength(self): + try: + decoder.decode(ints2octs((6, 0, 0))) + except PyAsn1Error: + pass + else: + assert 0, 'zero length tolarated' + + def testIndefiniteLength(self): + try: + decoder.decode(ints2octs((6, 128, 0))) + except PyAsn1Error: + pass + else: + assert 0, 'indefinite length tolarated' + + def testReservedLength(self): + try: + decoder.decode(ints2octs((6, 255, 0))) + except PyAsn1Error: + pass + else: + assert 0, 'reserved length tolerated' + + def testLarge1(self): + assert decoder.decode( + ints2octs((0x06, 0x11, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6, 0xB8, 0xCB, + 0xE2, 0xB7, 0x17)) + ) == ((2, 18446744073709551535184467440737095), null) + + def testLarge2(self): + assert decoder.decode( + ints2octs((0x06, 0x13, 0x88, 0x37, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6, + 0xB8, 0xCB, 0xE2, 0xB6, 0x47)) + ) == ((2, 999, 18446744073709551535184467440737095), null) + + +class RealDecoderTestCase(unittest.TestCase): + def testChar(self): + assert decoder.decode( + ints2octs((9, 7, 3, 49, 50, 51, 69, 49, 49)) + ) == (univ.Real((123, 10, 11)), null) + + def testBin1(self): # check base = 2 + assert decoder.decode( # (0.5, 2, 0) encoded with base = 2 + ints2octs((9, 3, 128, 255, 1)) + ) == (univ.Real((1, 2, -1)), null) + + def testBin2(self): # check base = 2 and scale factor + assert decoder.decode( # (3.25, 2, 0) encoded with base = 8 + ints2octs((9, 3, 148, 255, 13)) + ) == (univ.Real((26, 2, -3)), null) + + def testBin3(self): # check base = 16 + assert decoder.decode( # (0.00390625, 2, 0) encoded with base = 16 + ints2octs((9, 3, 160, 254, 1)) + ) == (univ.Real((1, 2, -8)), null) + + def testBin4(self): # check exponenta = 0 + assert decoder.decode( # (1, 2, 0) encoded with base = 2 + ints2octs((9, 3, 128, 0, 1)) + ) == (univ.Real((1, 2, 0)), null) + + def testBin5(self): # case of 2 octs for exponenta and negative exponenta + assert decoder.decode( # (3, 2, -1020) encoded with base = 16 + ints2octs((9, 4, 161, 255, 1, 3)) + ) == (univ.Real((3, 2, -1020)), null) + + def testPlusInf(self): + assert decoder.decode( + ints2octs((9, 1, 64)) + ) == (univ.Real('inf'), null) + + def testMinusInf(self): + assert decoder.decode( + ints2octs((9, 1, 65)) + ) == (univ.Real('-inf'), null) + + def testEmpty(self): + assert decoder.decode( + ints2octs((9, 0)) + ) == (univ.Real(0.0), null) + + def testTagFormat(self): + try: + decoder.decode(ints2octs((41, 0))) + except PyAsn1Error: + pass + else: + assert 0, 'wrong tagFormat worked out' + + def testShortEncoding(self): + try: + decoder.decode(ints2octs((9, 1, 131))) + except PyAsn1Error: + pass + else: + assert 0, 'accepted too-short real' + + +if sys.version_info[0:2] > (2, 5): + class UniversalStringDecoderTestCase(unittest.TestCase): + def testDecoder(self): + assert decoder.decode(ints2octs((28, 12, 0, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99))) == (char.UniversalString(sys.version_info[0] == 3 and 'abc' or unicode('abc')), null) + + +class BMPStringDecoderTestCase(unittest.TestCase): + def testDecoder(self): + assert decoder.decode(ints2octs((30, 6, 0, 97, 0, 98, 0, 99))) == (char.BMPString(sys.version_info[0] == 3 and 'abc' or unicode('abc')), null) + + +class UTF8StringDecoderTestCase(unittest.TestCase): + def testDecoder(self): + assert decoder.decode(ints2octs((12, 3, 97, 98, 99))) == (char.UTF8String(sys.version_info[0] == 3 and 'abc' or unicode('abc')), null) + + +class SequenceDecoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Sequence(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null(null)), + namedtype.NamedType('first-name', univ.OctetString(null)), + namedtype.NamedType('age', univ.Integer(33))) + ) + self.s.setComponentByPosition(0, univ.Null(null)) + self.s.setComponentByPosition(1, univ.OctetString('quick brown')) + self.s.setComponentByPosition(2, univ.Integer(1)) + self.s.setDefaultComponents() + + def testWithOptionalAndDefaultedDefMode(self): + assert decoder.decode( + ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)) + ) == (self.s, null) + + def testWithOptionalAndDefaultedIndefMode(self): + assert decoder.decode( + ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, + 0, 0)) + ) == (self.s, null) + + def testWithOptionalAndDefaultedDefModeChunked(self): + assert decoder.decode( + ints2octs( + (48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1)) + ) == (self.s, null) + + def testWithOptionalAndDefaultedIndefModeChunked(self): + assert decoder.decode( + ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, + 0, 2, 1, 1, 0, 0)) + ) == (self.s, null) + + def testWithOptionalAndDefaultedDefModeSubst(self): + assert decoder.decode( + ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs((5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), 18) + + def testWithOptionalAndDefaultedIndefModeSubst(self): + assert decoder.decode( + ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, + 0, 0)), + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs( + (5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, 0, 0)), -1) + + def testTagFormat(self): + try: + decoder.decode( + ints2octs((16, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'wrong tagFormat worked out' + + +class GuidedSequenceDecoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Sequence(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null(null)), + namedtype.OptionalNamedType('first-name', univ.OctetString(null)), + namedtype.DefaultedNamedType('age', univ.Integer(33)), + )) + + def __init(self): + self.s.clear() + self.s.setComponentByPosition(0, univ.Null(null)) + self.s.setDefaultComponents() + + def __initWithOptional(self): + self.s.clear() + self.s.setComponentByPosition(0, univ.Null(null)) + self.s.setComponentByPosition(1, univ.OctetString('quick brown')) + self.s.setDefaultComponents() + + def __initWithDefaulted(self): + self.s.clear() + self.s.setComponentByPosition(0, univ.Null(null)) + self.s.setComponentByPosition(2, univ.Integer(1)) + self.s.setDefaultComponents() + + def __initWithOptionalAndDefaulted(self): + self.s.clear() + self.s.setComponentByPosition(0, univ.Null(null)) + self.s.setComponentByPosition(1, univ.OctetString('quick brown')) + self.s.setComponentByPosition(2, univ.Integer(1)) + self.s.setDefaultComponents() + + def testDefMode(self): + self.__init() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s + ) == (self.s, null) + + def testIndefMode(self): + self.__init() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s + ) == (self.s, null) + + def testDefModeChunked(self): + self.__init() + assert decoder.decode( + ints2octs((48, 2, 5, 0)), asn1Spec=self.s + ) == (self.s, null) + + def testIndefModeChunked(self): + self.__init() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 0, 0)), asn1Spec=self.s + ) == (self.s, null) + + def testWithOptionalDefMode(self): + self.__initWithOptional() + assert decoder.decode( + ints2octs((48, 15, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)), asn1Spec=self.s + ) == (self.s, null) + + def testWithOptionaIndefMode(self): + self.__initWithOptional() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 0, 0)), + asn1Spec=self.s + ) == (self.s, null) + + def testWithOptionalDefModeChunked(self): + self.__initWithOptional() + assert decoder.decode( + ints2octs((48, 21, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110)), + asn1Spec=self.s + ) == (self.s, null) + + def testWithOptionalIndefModeChunked(self): + self.__initWithOptional() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, + 0, 0, 0)), + asn1Spec=self.s + ) == (self.s, null) + + def testWithDefaultedDefMode(self): + self.__initWithDefaulted() + assert decoder.decode( + ints2octs((48, 5, 5, 0, 2, 1, 1)), asn1Spec=self.s + ) == (self.s, null) + + def testWithDefaultedIndefMode(self): + self.__initWithDefaulted() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s + ) == (self.s, null) + + def testWithDefaultedDefModeChunked(self): + self.__initWithDefaulted() + assert decoder.decode( + ints2octs((48, 5, 5, 0, 2, 1, 1)), asn1Spec=self.s + ) == (self.s, null) + + def testWithDefaultedIndefModeChunked(self): + self.__initWithDefaulted() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0)), asn1Spec=self.s + ) == (self.s, null) + + def testWithOptionalAndDefaultedDefMode(self): + self.__initWithOptionalAndDefaulted() + assert decoder.decode( + ints2octs((48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)), + asn1Spec=self.s + ) == (self.s, null) + + def testWithOptionalAndDefaultedIndefMode(self): + self.__initWithOptionalAndDefaulted() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 36, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0, 2, 1, 1, + 0, 0)), asn1Spec=self.s + ) == (self.s, null) + + def testWithOptionalAndDefaultedDefModeChunked(self): + self.__initWithOptionalAndDefaulted() + assert decoder.decode( + ints2octs( + (48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1)), + asn1Spec=self.s + ) == (self.s, null) + + def testWithOptionalAndDefaultedIndefModeChunked(self): + self.__initWithOptionalAndDefaulted() + assert decoder.decode( + ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, + 0, 2, 1, 1, 0, 0)), asn1Spec=self.s + ) == (self.s, null) + + +class ChoiceDecoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Choice(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null(null)), + namedtype.NamedType('number', univ.Integer(0)), + namedtype.NamedType('string', univ.OctetString()) + )) + + def testBySpec(self): + self.s.setComponentByPosition(0, univ.Null(null)) + assert decoder.decode( + ints2octs((5, 0)), asn1Spec=self.s + ) == (self.s, null) + + def testWithoutSpec(self): + self.s.setComponentByPosition(0, univ.Null(null)) + assert decoder.decode(ints2octs((5, 0))) == (self.s, null) + assert decoder.decode(ints2octs((5, 0))) == (univ.Null(null), null) + + def testUndefLength(self): + self.s.setComponentByPosition(2, univ.OctetString('abcdefgh')) + assert decoder.decode(ints2octs((36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0)), + asn1Spec=self.s) == (self.s, null) + + def testExplicitTag(self): + s = self.s.subtype(explicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatConstructed, 4)) + s.setComponentByPosition(0, univ.Null(null)) + assert decoder.decode(ints2octs((164, 2, 5, 0)), asn1Spec=s) == (s, null) + + def testExplicitTagUndefLength(self): + s = self.s.subtype(explicitTag=tag.Tag(tag.tagClassContext, + tag.tagFormatConstructed, 4)) + s.setComponentByPosition(0, univ.Null(null)) + assert decoder.decode(ints2octs((164, 128, 5, 0, 0, 0)), asn1Spec=s) == (s, null) + + +class AnyDecoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Any() + + def testByUntagged(self): + assert decoder.decode( + ints2octs((4, 3, 102, 111, 120)), asn1Spec=self.s + ) == (univ.Any('\004\003fox'), null) + + def testTaggedEx(self): + s = univ.Any('\004\003fox').subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)) + assert decoder.decode(ints2octs((164, 5, 4, 3, 102, 111, 120)), asn1Spec=s) == (s, null) + + def testTaggedIm(self): + s = univ.Any('\004\003fox').subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)) + assert decoder.decode(ints2octs((132, 5, 4, 3, 102, 111, 120)), asn1Spec=s) == (s, null) + + def testByUntaggedIndefMode(self): + assert decoder.decode( + ints2octs((4, 3, 102, 111, 120)), asn1Spec=self.s + ) == (univ.Any('\004\003fox'), null) + + def testTaggedExIndefMode(self): + s = univ.Any('\004\003fox').subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)) + assert decoder.decode(ints2octs((164, 128, 4, 3, 102, 111, 120, 0, 0)), asn1Spec=s) == (s, null) + + def testTaggedImIndefMode(self): + s = univ.Any('\004\003fox').subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)) + assert decoder.decode(ints2octs((164, 128, 4, 3, 102, 111, 120, 0, 0)), asn1Spec=s) == (s, null) + + def testByUntaggedSubst(self): + assert decoder.decode( + ints2octs((4, 3, 102, 111, 120)), + asn1Spec=self.s, + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs((4, 3, 102, 111, 120)), 5) + + def testTaggedExSubst(self): + assert decoder.decode( + ints2octs((164, 5, 4, 3, 102, 111, 120)), + asn1Spec=self.s, + substrateFun=lambda a, b, c: (b, c) + ) == (ints2octs((164, 5, 4, 3, 102, 111, 120)), 7) + + +class EndOfOctetsTestCase(unittest.TestCase): + def testUnexpectedEoo(self): + try: + decoder.decode(ints2octs((0, 0))) + except PyAsn1Error: + pass + else: + assert 0, 'end-of-contents octets accepted at top level' + + def testExpectedEoo(self): + result, remainder = decoder.decode(ints2octs((0, 0)), allowEoo=True) + assert eoo.endOfOctets.isSameTypeWith(result) and result == eoo.endOfOctets + assert remainder == null + + def testDefiniteNoEoo(self): + try: + decoder.decode(ints2octs((0x23, 0x02, 0x00, 0x00))) + except PyAsn1Error: + pass + else: + assert 0, 'end-of-contents octets accepted inside definite-length encoding' + + def testIndefiniteEoo(self): + result, remainder = decoder.decode(ints2octs((0x23, 0x80, 0x00, 0x00))) + assert result == () and remainder == null, 'incorrect decoding of indefinite length end-of-octets' + + def testNoLongFormEoo(self): + try: + decoder.decode(ints2octs((0x23, 0x80, 0x00, 0x81, 0x00))) + except PyAsn1Error: + pass + else: + assert 0, 'end-of-contents octets accepted with invalid long-form length' + + def testNoConstructedEoo(self): + try: + decoder.decode(ints2octs((0x23, 0x80, 0x20, 0x00))) + except PyAsn1Error: + pass + else: + assert 0, 'end-of-contents octets accepted with invalid constructed encoding' + + def testNoEooData(self): + try: + decoder.decode(ints2octs((0x23, 0x80, 0x00, 0x01, 0x00))) + except PyAsn1Error: + pass + else: + assert 0, 'end-of-contents octets accepted with unexpected data' + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/ber/test_encoder.py b/tests/codec/ber/test_encoder.py new file mode 100644 index 0000000..48a916b --- /dev/null +++ b/tests/codec/ber/test_encoder.py @@ -0,0 +1,536 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1.type import tag, namedtype, univ, char +from pyasn1.codec.ber import encoder +from pyasn1.compat.octets import ints2octs +from pyasn1.error import PyAsn1Error +from sys import version_info + + +class BadAsn1SpecTestCase(unittest.TestCase): + def testBadValueType(self): + try: + encoder.encode('not an Asn1Item') + except PyAsn1Error: + pass + else: + assert 0, 'Invalid value type accepted' + + +class LargeTagEncoderTestCase(unittest.TestCase): + def setUp(self): + self.o = univ.Integer().subtype( + value=1, explicitTag=tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 0xdeadbeaf) + ) + + def testEncoder(self): + assert encoder.encode(self.o) == ints2octs((127, 141, 245, 182, 253, 47, 3, 2, 1, 1)) + + +class IntegerEncoderTestCase(unittest.TestCase): + def testPosInt(self): + assert encoder.encode(univ.Integer(12)) == ints2octs((2, 1, 12)) + + def testNegInt(self): + assert encoder.encode(univ.Integer(-12)) == ints2octs((2, 1, 244)) + + def testZero(self): + assert encoder.encode(univ.Integer(0)) == ints2octs((2, 1, 0)) + + def testCompactZero(self): + encoder.IntegerEncoder.supportCompactZero = True + substrate = encoder.encode(univ.Integer(0)) + encoder.IntegerEncoder.supportCompactZero = False + assert substrate == ints2octs((2, 0)) + + def testMinusOne(self): + assert encoder.encode(univ.Integer(-1)) == ints2octs((2, 1, 255)) + + def testPosLong(self): + assert encoder.encode( + univ.Integer(0xffffffffffffffff) + ) == ints2octs((2, 9, 0, 255, 255, 255, 255, 255, 255, 255, 255)) + + def testNegLong(self): + assert encoder.encode( + univ.Integer(-0xffffffffffffffff) + ) == ints2octs((2, 9, 255, 0, 0, 0, 0, 0, 0, 0, 1)) + + +class BooleanEncoderTestCase(unittest.TestCase): + def testTrue(self): + assert encoder.encode(univ.Boolean(1)) == ints2octs((1, 1, 1)) + + def testFalse(self): + assert encoder.encode(univ.Boolean(0)) == ints2octs((1, 1, 0)) + + +class BitStringEncoderTestCase(unittest.TestCase): + def setUp(self): + self.b = univ.BitString((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1)) + + def testDefMode(self): + assert encoder.encode(self.b) == ints2octs((3, 3, 1, 169, 138)) + + def testIndefMode(self): + assert encoder.encode( + self.b, defMode=0 + ) == ints2octs((3, 3, 1, 169, 138)) + + def testDefModeChunked(self): + assert encoder.encode( + self.b, maxChunkSize=1 + ) == ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138)) + + def testIndefModeChunked(self): + assert encoder.encode( + self.b, defMode=0, maxChunkSize=1 + ) == ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0)) + + def testEmptyValue(self): + assert encoder.encode(univ.BitString(())) == ints2octs((3, 1, 0)) + + +class OctetStringEncoderTestCase(unittest.TestCase): + def setUp(self): + self.o = univ.OctetString('Quick brown fox') + + def testDefMode(self): + assert encoder.encode(self.o) == ints2octs( + (4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)) + + def testIndefMode(self): + assert encoder.encode( + self.o, defMode=0 + ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)) + + def testDefModeChunked(self): + assert encoder.encode( + self.o, maxChunkSize=4 + ) == ints2octs( + (36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, 120)) + + def testIndefModeChunked(self): + assert encoder.encode( + self.o, defMode=0, maxChunkSize=4 + ) == ints2octs(( + 36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, 102, 111, + 120, 0, 0)) + + +class ExpTaggedOctetStringEncoderTestCase(unittest.TestCase): + def setUp(self): + self.o = univ.OctetString().subtype( + value='Quick brown fox', + explicitTag=tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 5) + ) + + def testDefMode(self): + assert encoder.encode(self.o) == ints2octs( + (101, 17, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)) + + def testIndefMode(self): + assert encoder.encode( + self.o, defMode=0 + ) == ints2octs((101, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0)) + + def testDefModeChunked(self): + assert encoder.encode( + self.o, defMode=1, maxChunkSize=4 + ) == ints2octs((101, 25, 36, 23, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, + 102, 111, 120)) + + def testIndefModeChunked(self): + assert encoder.encode( + self.o, defMode=0, maxChunkSize=4 + ) == ints2octs(( + 101, 128, 36, 128, 4, 4, 81, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 4, 111, 119, 110, 32, 4, 3, + 102, 111, 120, 0, 0, 0, 0)) + + +class NullEncoderTestCase(unittest.TestCase): + def testNull(self): + assert encoder.encode(univ.Null('')) == ints2octs((5, 0)) + + +class ObjectIdentifierEncoderTestCase(unittest.TestCase): + def testOne(self): + assert encoder.encode( + univ.ObjectIdentifier((1, 3, 6, 0, 0xffffe)) + ) == ints2octs((6, 6, 43, 6, 0, 191, 255, 126)) + + def testEdge1(self): + assert encoder.encode( + univ.ObjectIdentifier((0, 39)) + ) == ints2octs((6, 1, 39)) + + def testEdge2(self): + assert encoder.encode( + univ.ObjectIdentifier((1, 39)) + ) == ints2octs((6, 1, 79)) + + def testEdge3(self): + # 01111111 + assert encoder.encode( + univ.ObjectIdentifier((2, 40)) + ) == ints2octs((6, 1, 120)) + + def testEdge4(self): + # 10010000|10000000|10000000|10000000|01001111 + assert encoder.encode( + univ.ObjectIdentifier((2, 0xffffffff)) + ) == ints2octs((6, 5, 0x90, 0x80, 0x80, 0x80, 0x4F)) + + def testEdge5(self): + # 01111111 + assert encoder.encode( + univ.ObjectIdentifier((2, 47)) + ) == ints2octs((6, 1, 0x7F)) + + def testEdge6(self): + # 10000001|00000000 + assert encoder.encode( + univ.ObjectIdentifier((2, 48)) + ) == ints2octs((6, 2, 0x81, 0x00)) + + def testEdge7(self): + # 10000001|00110100|00000003 + assert encoder.encode( + univ.ObjectIdentifier((2, 100, 3)) + ) == ints2octs((6, 3, 0x81, 0x34, 0x03)) + + def testEdge8(self): + # 10000101|00000000 + assert encoder.encode( + univ.ObjectIdentifier((2, 560)) + ) == ints2octs((6, 2, 133, 0)) + + def testEdge9(self): + # 10001000|10000100|10000111|0000010 + assert encoder.encode( + univ.ObjectIdentifier((2, 16843570)) + ) == ints2octs((6, 4, 0x88, 0x84, 0x87, 0x02)) + + def testImpossible1(self): + try: + encoder.encode(univ.ObjectIdentifier((3, 1, 2))) + except PyAsn1Error: + pass + else: + assert 0, 'impossible leading arc tolerated' + + def testImpossible2(self): + try: + encoder.encode(univ.ObjectIdentifier((0,))) + except PyAsn1Error: + pass + else: + assert 0, 'single arc OID tolerated' + + def testImpossible3(self): + try: + encoder.encode(univ.ObjectIdentifier((0, 40))) + except PyAsn1Error: + pass + else: + assert 0, 'second arc overflow tolerated' + + def testImpossible4(self): + try: + encoder.encode(univ.ObjectIdentifier((1, 40))) + except PyAsn1Error: + pass + else: + assert 0, 'second arc overflow tolerated' + + def testLarge1(self): + assert encoder.encode( + univ.ObjectIdentifier((2, 18446744073709551535184467440737095)) + ) == ints2octs((0x06, 0x11, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6, 0xB8, 0xCB, + 0xE2, 0xB7, 0x17)) + + def testLarge2(self): + assert encoder.encode( + univ.ObjectIdentifier((2, 999, 18446744073709551535184467440737095)) + ) == ints2octs((0x06, 0x13, 0x88, 0x37, 0x83, 0xC6, 0xDF, 0xD4, 0xCC, 0xB3, 0xFF, 0xFF, 0xFE, 0xF0, 0xB8, 0xD6, + 0xB8, 0xCB, 0xE2, 0xB6, 0x47)) + + +class RealEncoderTestCase(unittest.TestCase): + def testChar(self): + assert encoder.encode( + univ.Real((123, 10, 11)) + ) == ints2octs((9, 7, 3, 49, 50, 51, 69, 49, 49)) + + def testBin1(self): + assert encoder.encode( # default binEncBase = 2 + univ.Real((0.5, 2, 0)) # check encbase = 2 and exponenta = -1 + ) == ints2octs((9, 3, 128, 255, 1)) + + def testBin2(self): + r = univ.Real((3.25, 2, 0)) + r.binEncBase = 8 # change binEncBase only for this instance of Real + assert encoder.encode( + r # check encbase = 8 + ) == ints2octs((9, 3, 148, 255, 13)) + + def testBin3(self): + # change binEncBase in the RealEncoder instance => for all further Reals + encoder.tagMap[univ.Real.tagSet].binEncBase = 16 + assert encoder.encode( + univ.Real((0.00390625, 2, 0)) # check encbase = 16 + ) == ints2octs((9, 3, 160, 254, 1)) + + def testBin4(self): + # choose binEncBase automatically for all further Reals (testBin[4-7]) + encoder.tagMap[univ.Real.tagSet].binEncBase = None + assert encoder.encode( + univ.Real((1, 2, 0)) # check exponenta = 0 + ) == ints2octs((9, 3, 128, 0, 1)) + + def testBin5(self): + assert encoder.encode( + univ.Real((3, 2, -1020)) # case of 2 octs for exponenta and + # negative exponenta and abs(exponenta) is + # all 1's and fills the whole octet(s) + ) == ints2octs((9, 4, 161, 255, 1, 3)) + + def testBin6(self): + assert encoder.encode( + univ.Real((1, 2, 262140)) # case of 3 octs for exponenta and + # check that first 9 bits for exponenta + # are not all 1's + ) == ints2octs((9, 5, 162, 0, 255, 255, 1)) + + def testBin7(self): + assert encoder.encode( + univ.Real((-1, 2, 76354972)) # case of >3 octs for exponenta and + # mantissa < 0 + ) == ints2octs((9, 7, 227, 4, 1, 35, 69, 103, 1)) + + def testPlusInf(self): + assert encoder.encode(univ.Real('inf')) == ints2octs((9, 1, 64)) + + def testMinusInf(self): + assert encoder.encode(univ.Real('-inf')) == ints2octs((9, 1, 65)) + + def testZero(self): + assert encoder.encode(univ.Real(0)) == ints2octs((9, 0)) + + +if version_info[0:2] > (2, 5): + class UniversalStringEncoderTestCase(unittest.TestCase): + def testEncoding(self): + assert encoder.encode(char.UniversalString(version_info[0] == 3 and 'abc' or unicode('abc'))) == ints2octs( + (28, 12, 0, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99)), 'Incorrect encoding' + + +class BMPStringEncoderTestCase(unittest.TestCase): + def testEncoding(self): + assert encoder.encode(char.BMPString(version_info[0] == 3 and 'abc' or unicode('abc'))) == ints2octs( + (30, 6, 0, 97, 0, 98, 0, 99)), 'Incorrect encoding' + + +class UTF8StringEncoderTestCase(unittest.TestCase): + def testEncoding(self): + assert encoder.encode(char.UTF8String(version_info[0] == 3 and 'abc' or unicode('abc'))) == ints2octs( + (12, 3, 97, 98, 99)), 'Incorrect encoding' + + +class SequenceEncoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Sequence(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null('')), + namedtype.OptionalNamedType('first-name', univ.OctetString('')), + namedtype.DefaultedNamedType('age', univ.Integer(33)), + )) + + def __init(self): + self.s.clear() + self.s.setComponentByPosition(0) + + def __initWithOptional(self): + self.s.clear() + self.s.setComponentByPosition(0) + self.s.setComponentByPosition(1, 'quick brown') + + def __initWithDefaulted(self): + self.s.clear() + self.s.setComponentByPosition(0) + self.s.setComponentByPosition(2, 1) + + def __initWithOptionalAndDefaulted(self): + self.s.clear() + self.s.setComponentByPosition(0, univ.Null('')) + self.s.setComponentByPosition(1, univ.OctetString('quick brown')) + self.s.setComponentByPosition(2, univ.Integer(1)) + + def testDefMode(self): + self.__init() + assert encoder.encode(self.s) == ints2octs((48, 2, 5, 0)) + + def testIndefMode(self): + self.__init() + assert encoder.encode( + self.s, defMode=0 + ) == ints2octs((48, 128, 5, 0, 0, 0)) + + def testDefModeChunked(self): + self.__init() + assert encoder.encode( + self.s, defMode=1, maxChunkSize=4 + ) == ints2octs((48, 2, 5, 0)) + + def testIndefModeChunked(self): + self.__init() + assert encoder.encode( + self.s, defMode=0, maxChunkSize=4 + ) == ints2octs((48, 128, 5, 0, 0, 0)) + + def testWithOptionalDefMode(self): + self.__initWithOptional() + assert encoder.encode(self.s) == ints2octs( + (48, 15, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110)) + + def testWithOptionalIndefMode(self): + self.__initWithOptional() + assert encoder.encode( + self.s, defMode=0 + ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 0, 0)) + + def testWithOptionalDefModeChunked(self): + self.__initWithOptional() + assert encoder.encode( + self.s, defMode=1, maxChunkSize=4 + ) == ints2octs((48, 21, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110)) + + def testWithOptionalIndefModeChunked(self): + self.__initWithOptional() + assert encoder.encode( + self.s, defMode=0, maxChunkSize=4 + ) == ints2octs( + (48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, 0, 0, 0)) + + def testWithDefaultedDefMode(self): + self.__initWithDefaulted() + assert encoder.encode(self.s) == ints2octs((48, 5, 5, 0, 2, 1, 1)) + + def testWithDefaultedIndefMode(self): + self.__initWithDefaulted() + assert encoder.encode( + self.s, defMode=0 + ) == ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0)) + + def testWithDefaultedDefModeChunked(self): + self.__initWithDefaulted() + assert encoder.encode( + self.s, defMode=1, maxChunkSize=4 + ) == ints2octs((48, 5, 5, 0, 2, 1, 1)) + + def testWithDefaultedIndefModeChunked(self): + self.__initWithDefaulted() + assert encoder.encode( + self.s, defMode=0, maxChunkSize=4 + ) == ints2octs((48, 128, 5, 0, 2, 1, 1, 0, 0)) + + def testWithOptionalAndDefaultedDefMode(self): + self.__initWithOptionalAndDefaulted() + assert encoder.encode(self.s) == ints2octs( + (48, 18, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1)) + + def testWithOptionalAndDefaultedIndefMode(self): + self.__initWithOptionalAndDefaulted() + assert encoder.encode( + self.s, defMode=0 + ) == ints2octs((48, 128, 5, 0, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 2, 1, 1, 0, 0)) + + def testWithOptionalAndDefaultedDefModeChunked(self): + self.__initWithOptionalAndDefaulted() + assert encoder.encode( + self.s, defMode=1, maxChunkSize=4 + ) == ints2octs( + (48, 24, 5, 0, 36, 17, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 2, 1, 1)) + + def testWithOptionalAndDefaultedIndefModeChunked(self): + self.__initWithOptionalAndDefaulted() + assert encoder.encode( + self.s, defMode=0, maxChunkSize=4 + ) == ints2octs((48, 128, 5, 0, 36, 128, 4, 4, 113, 117, 105, 99, 4, 4, 107, 32, 98, 114, 4, 3, 111, 119, 110, 0, + 0, 2, 1, 1, 0, 0)) + + +class ChoiceEncoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Choice(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null('')), + namedtype.NamedType('number', univ.Integer(0)), + namedtype.NamedType('string', univ.OctetString()) + )) + + def testEmpty(self): + try: + encoder.encode(self.s) + except PyAsn1Error: + pass + else: + assert 0, 'encoded unset choice' + + def testFilled(self): + self.s.setComponentByPosition(0, univ.Null('')) + assert encoder.encode(self.s) == ints2octs((5, 0)) + + def testTagged(self): + s = self.s.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4) + ) + s.setComponentByPosition(0, univ.Null('')) + assert encoder.encode(s) == ints2octs((164, 2, 5, 0)) + + def testUndefLength(self): + self.s.setComponentByPosition(2, univ.OctetString('abcdefgh')) + assert encoder.encode(self.s, defMode=False, maxChunkSize=3) == ints2octs( + (36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0)) + + def testTaggedUndefLength(self): + s = self.s.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4) + ) + s.setComponentByPosition(2, univ.OctetString('abcdefgh')) + assert encoder.encode(s, defMode=False, maxChunkSize=3) == ints2octs( + (164, 128, 36, 128, 4, 3, 97, 98, 99, 4, 3, 100, 101, 102, 4, 2, 103, 104, 0, 0, 0, 0)) + + +class AnyEncoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Any(encoder.encode(univ.OctetString('fox'))) + + def testUntagged(self): + assert encoder.encode(self.s) == ints2octs((4, 3, 102, 111, 120)) + + def testTaggedEx(self): + s = self.s.subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4) + ) + assert encoder.encode(s) == ints2octs((164, 5, 4, 3, 102, 111, 120)) + + def testTaggedIm(self): + s = self.s.subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4) + ) + assert encoder.encode(s) == ints2octs((132, 5, 4, 3, 102, 111, 120)) + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/cer/__init__.py b/tests/codec/cer/__init__.py new file mode 100644 index 0000000..8c3066b --- /dev/null +++ b/tests/codec/cer/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/tests/codec/cer/__main__.py b/tests/codec/cer/__main__.py new file mode 100644 index 0000000..f641b82 --- /dev/null +++ b/tests/codec/cer/__main__.py @@ -0,0 +1,20 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +try: + import unittest2 as unittest + +except ImportError: + import unittest + +suite = unittest.TestLoader().loadTestsFromNames( + ['tests.codec.cer.test_encoder.suite', + 'tests.codec.cer.test_decoder.suite'] +) + + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/cer/test_decoder.py b/tests/codec/cer/test_decoder.py new file mode 100644 index 0000000..3ae1f99 --- /dev/null +++ b/tests/codec/cer/test_decoder.py @@ -0,0 +1,68 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1.codec.cer import decoder +from pyasn1.compat.octets import ints2octs, str2octs, null +from pyasn1.error import PyAsn1Error + + +class BooleanDecoderTestCase(unittest.TestCase): + def testTrue(self): + assert decoder.decode(ints2octs((1, 1, 255))) == (1, null) + + def testFalse(self): + assert decoder.decode(ints2octs((1, 1, 0))) == (0, null) + + def testEmpty(self): + try: + decoder.decode(ints2octs((1, 0))) + except PyAsn1Error: + pass + + def testOverflow(self): + try: + decoder.decode(ints2octs((1, 2, 0, 0))) + except PyAsn1Error: + pass + +class BitStringDecoderTestCase(unittest.TestCase): + def testShortMode(self): + assert decoder.decode( + ints2octs((3, 3, 6, 170, 128)) + ) == (((1, 0) * 5), null) + + def testLongMode(self): + assert decoder.decode( + ints2octs((3, 127, 6) + (170,) * 125 + (128,)) + ) == (((1, 0) * 501), null) + + # TODO: test failures on short chunked and long unchunked substrate samples + + +class OctetStringDecoderTestCase(unittest.TestCase): + def testShortMode(self): + assert decoder.decode( + ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)), + ) == (str2octs('Quick brown fox'), null) + + def testLongMode(self): + assert decoder.decode( + ints2octs((36, 128, 4, 130, 3, 232) + (81,) * 1000 + (4, 1, 81, 0, 0)) + ) == (str2octs('Q' * 1001), null) + + # TODO: test failures on short chunked and long unchunked substrate samples + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/cer/test_encoder.py b/tests/codec/cer/test_encoder.py new file mode 100644 index 0000000..0ced510 --- /dev/null +++ b/tests/codec/cer/test_encoder.py @@ -0,0 +1,193 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1.type import namedtype, univ, useful +from pyasn1.codec.cer import encoder +from pyasn1.compat.octets import ints2octs +from pyasn1.error import PyAsn1Error + + +class BooleanEncoderTestCase(unittest.TestCase): + def testTrue(self): + assert encoder.encode(univ.Boolean(1)) == ints2octs((1, 1, 255)) + + def testFalse(self): + assert encoder.encode(univ.Boolean(0)) == ints2octs((1, 1, 0)) + + +class BitStringEncoderTestCase(unittest.TestCase): + def testShortMode(self): + assert encoder.encode( + univ.BitString((1, 0) * 5) + ) == ints2octs((3, 3, 6, 170, 128)) + + def testLongMode(self): + assert encoder.encode( + univ.BitString((1, 0) * 501) + ) == ints2octs((3, 127, 6) + (170,) * 125 + (128,)) + + +class OctetStringEncoderTestCase(unittest.TestCase): + def testShortMode(self): + assert encoder.encode( + univ.OctetString('Quick brown fox') + ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)) + + def testLongMode(self): + assert encoder.encode( + univ.OctetString('Q' * 1001) + ) == ints2octs((36, 128, 4, 130, 3, 232) + (81,) * 1000 + (4, 1, 81, 0, 0)) + + +class SetEncoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Set(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null('')), + namedtype.OptionalNamedType('first-name', univ.OctetString('')), + namedtype.DefaultedNamedType('age', univ.Integer(33)) + )) + + def __init(self): + self.s.clear() + self.s.setComponentByPosition(0) + + def __initWithOptional(self): + self.s.clear() + self.s.setComponentByPosition(0) + self.s.setComponentByPosition(1, 'quick brown') + + def __initWithDefaulted(self): + self.s.clear() + self.s.setComponentByPosition(0) + self.s.setComponentByPosition(2, 1) + + def __initWithOptionalAndDefaulted(self): + self.s.clear() + self.s.setComponentByPosition(0, univ.Null('')) + self.s.setComponentByPosition(1, univ.OctetString('quick brown')) + self.s.setComponentByPosition(2, univ.Integer(1)) + + def testIndefMode(self): + self.__init() + assert encoder.encode(self.s) == ints2octs((49, 128, 5, 0, 0, 0)) + + def testWithOptionalIndefMode(self): + self.__initWithOptional() + assert encoder.encode( + self.s + ) == ints2octs((49, 128, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0)) + + def testWithDefaultedIndefMode(self): + self.__initWithDefaulted() + assert encoder.encode( + self.s + ) == ints2octs((49, 128, 2, 1, 1, 5, 0, 0, 0)) + + def testWithOptionalAndDefaultedIndefMode(self): + self.__initWithOptionalAndDefaulted() + assert encoder.encode( + self.s + ) == ints2octs((49, 128, 2, 1, 1, 4, 11, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 5, 0, 0, 0)) + + +class SetWithChoiceEncoderTestCase(unittest.TestCase): + def setUp(self): + c = univ.Choice(componentType=namedtype.NamedTypes( + namedtype.NamedType('actual', univ.Boolean(0)) + )) + self.s = univ.Set(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null('')), + namedtype.NamedType('status', c) + )) + + def testIndefMode(self): + self.s.setComponentByPosition(0) + self.s.setComponentByName('status') + self.s.getComponentByName('status').setComponentByPosition(0, 1) + assert encoder.encode(self.s) == ints2octs((49, 128, 1, 1, 255, 5, 0, 0, 0)) + + +class GeneralizedTimeEncoderTestCase(unittest.TestCase): + # def testExtraZeroInSeconds(self): + # try: + # assert encoder.encode( + # useful.GeneralizedTime('20150501120112.10Z') + # ) + # except PyAsn1Error: + # pass + # else: + # assert 0, 'Meaningless trailing zero in fraction part tolerated' + + def testLocalTimezone(self): + try: + assert encoder.encode( + useful.GeneralizedTime('20150501120112.1+0200') + ) + except PyAsn1Error: + pass + else: + assert 0, 'Local timezone tolerated' + + def testMissingTimezone(self): + try: + assert encoder.encode( + useful.GeneralizedTime('20150501120112.1') + ) + except PyAsn1Error: + pass + else: + assert 0, 'Missing timezone tolerated' + + +# When enabled, this breaks many existing encodings +# +# def testDecimalPoint(self): +# try: +# assert encoder.encode( +# useful.GeneralizedTime('20150501120112Z') +# ) +# except PyAsn1Error: +# pass +# else: +# assert 0, 'Missing decimal point tolerated' + +class UTCTimeEncoderTestCase(unittest.TestCase): + def testFractionOfSecond(self): + try: + assert encoder.encode( + useful.UTCTime('150501120112.10Z') + ) + except PyAsn1Error: + pass + else: + assert 0, 'Decimal point tolerated' + + def testMissingTimezone(self): + assert encoder.encode( + useful.UTCTime('150501120112') + ) == ints2octs((23, 13, 49, 53, 48, 53, 48, 49, 49, 50, 48, 49, 49, 50, 90)), 'Missing timezone not added' + + def testLocalTimezone(self): + try: + assert encoder.encode( + useful.UTCTime('150501120112+0200') + ) + except PyAsn1Error: + pass + else: + assert 0, 'Local timezone tolerated' + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/der/__init__.py b/tests/codec/der/__init__.py new file mode 100644 index 0000000..8c3066b --- /dev/null +++ b/tests/codec/der/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/tests/codec/der/__main__.py b/tests/codec/der/__main__.py new file mode 100644 index 0000000..0db3904 --- /dev/null +++ b/tests/codec/der/__main__.py @@ -0,0 +1,20 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +try: + import unittest2 as unittest + +except ImportError: + import unittest + +suite = unittest.TestLoader().loadTestsFromNames( + ['tests.codec.der.test_encoder.suite', + 'tests.codec.der.test_decoder.suite'] +) + + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/der/test_decoder.py b/tests/codec/der/test_decoder.py new file mode 100644 index 0000000..3fd55c3 --- /dev/null +++ b/tests/codec/der/test_decoder.py @@ -0,0 +1,75 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1.codec.der import decoder +from pyasn1.compat.octets import ints2octs, null +from pyasn1.error import PyAsn1Error + + +class BitStringDecoderTestCase(unittest.TestCase): + def testShortMode(self): + assert decoder.decode( + ints2octs((3, 127, 6) + (170,) * 125 + (128,)) + ) == (((1, 0) * 501), null) + + def testIndefMode(self): + try: + decoder.decode( + ints2octs((35, 128, 3, 2, 0, 169, 3, 2, 1, 138, 0, 0)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'indefinite length encoding tolerated' + + def testDefModeChunked(self): + try: + assert decoder.decode( + ints2octs((35, 8, 3, 2, 0, 169, 3, 2, 1, 138)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'chunked encoding tolerated' + + +class OctetStringDecoderTestCase(unittest.TestCase): + def testShortMode(self): + assert decoder.decode( + '\004\017Quick brown fox'.encode() + ) == ('Quick brown fox'.encode(), ''.encode()) + + def testIndefMode(self): + try: + decoder.decode( + ints2octs((36, 128, 4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120, 0, 0)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'indefinite length encoding tolerated' + + def testChunkedMode(self): + try: + decoder.decode( + ints2octs((36, 23, 4, 2, 81, 117, 4, 2, 105, 99, 4, 2, 107, 32, 4, 2, 98, 114, 4, 2, 111, 119, 4, 1, 110)) + ) + except PyAsn1Error: + pass + else: + assert 0, 'chunked encoding tolerated' + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/der/test_encoder.py b/tests/codec/der/test_encoder.py new file mode 100644 index 0000000..b514e3b --- /dev/null +++ b/tests/codec/der/test_encoder.py @@ -0,0 +1,70 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1.type import namedtype, univ +from pyasn1.codec.der import encoder +from pyasn1.compat.octets import ints2octs +from pyasn1.error import PyAsn1Error + + +class OctetStringEncoderTestCase(unittest.TestCase): + def testShortMode(self): + assert encoder.encode( + univ.OctetString('Quick brown fox') + ) == ints2octs((4, 15, 81, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120)) + + def testIndefMode(self): + try: + encoder.encode(univ.OctetString('Quick brown'), defMode=0) + except PyAsn1Error: + pass + else: + assert 0, 'Indefinite length encoding tolerated' + + def testChunkedMode(self): + try: + x = encoder.encode(univ.OctetString('Quick brown'), maxChunkSize=2) + except PyAsn1Error: + pass + else: + assert 0, 'Chunked encoding tolerated' + + +class BitStringEncoderTestCase(unittest.TestCase): + def testShortMode(self): + assert encoder.encode( + univ.BitString((1,)) + ) == ints2octs((3, 2, 7, 128)) + + +class SetWithChoiceEncoderTestCase(unittest.TestCase): + def setUp(self): + c = univ.Choice(componentType=namedtype.NamedTypes( + namedtype.NamedType('name', univ.OctetString('')), + namedtype.NamedType('amount', univ.Integer(0))) + ) + self.s = univ.Set(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null('')), + namedtype.NamedType('status', c)) + ) + + def testDefMode(self): + self.s.setComponentByPosition(0) + self.s.setComponentByName('status') + self.s.getComponentByName('status').setComponentByPosition(0, 'ann') + assert encoder.encode(self.s) == ints2octs((49, 7, 4, 3, 97, 110, 110, 5, 0)) + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/native/__init__.py b/tests/codec/native/__init__.py new file mode 100644 index 0000000..8c3066b --- /dev/null +++ b/tests/codec/native/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/tests/codec/native/__main__.py b/tests/codec/native/__main__.py new file mode 100644 index 0000000..89f0e06 --- /dev/null +++ b/tests/codec/native/__main__.py @@ -0,0 +1,19 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +try: + import unittest2 as unittest + +except ImportError: + import unittest + +suite = unittest.TestLoader().loadTestsFromNames( + ['tests.codec.native.test_encoder.suite', + 'tests.codec.native.test_decoder.suite'] +) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/native/test_decoder.py b/tests/codec/native/test_decoder.py new file mode 100644 index 0000000..16fddfc --- /dev/null +++ b/tests/codec/native/test_decoder.py @@ -0,0 +1,114 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1.type import tag, namedtype, univ, char +from pyasn1.codec.native import decoder +from pyasn1.error import PyAsn1Error + + +class BadAsn1SpecTestCase(unittest.TestCase): + def testBadSpec(self): + try: + decoder.decode('', asn1Spec='not an Asn1Item') + except PyAsn1Error: + pass + else: + assert 0, 'Invalid asn1Spec accepted' + + +class IntegerDecoderTestCase(unittest.TestCase): + def testPosInt(self): + assert decoder.decode(12, asn1Spec=univ.Integer()) == univ.Integer(12) + + def testNegInt(self): + assert decoder.decode(-12, asn1Spec=univ.Integer()) == univ.Integer(-12) + + +class BooleanDecoderTestCase(unittest.TestCase): + def testTrue(self): + assert decoder.decode(True, asn1Spec=univ.Boolean()) == univ.Boolean(True) + + def testTrueNeg(self): + assert decoder.decode(False, asn1Spec=univ.Boolean()) == univ.Boolean(False) + + +class BitStringDecoderTestCase(unittest.TestCase): + def testSimple(self): + assert decoder.decode('11111111', asn1Spec=univ.BitString()) == univ.BitString(hexValue='ff') + + +class OctetStringDecoderTestCase(unittest.TestCase): + def testSimple(self): + assert decoder.decode('Quick brown fox', asn1Spec=univ.OctetString()) == univ.OctetString('Quick brown fox') + + +class NullDecoderTestCase(unittest.TestCase): + def testNull(self): + assert decoder.decode(None, asn1Spec=univ.Null()) == univ.Null() + + +class ObjectIdentifierDecoderTestCase(unittest.TestCase): + def testOne(self): + assert decoder.decode('1.3.6.11', asn1Spec=univ.ObjectIdentifier()) == univ.ObjectIdentifier('1.3.6.11') + + +class RealDecoderTestCase(unittest.TestCase): + def testSimple(self): + assert decoder.decode(1.33, asn1Spec=univ.Real()) == univ.Real(1.33) + + +class SequenceDecoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Sequence( + componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null()), + namedtype.NamedType('first-name', univ.OctetString()), + namedtype.NamedType('age', univ.Integer(33)) + ) + ) + + def testSimple(self): + s = self.s.clone() + s[0] = univ.Null() + s[1] = univ.OctetString('xx') + s[2] = univ.Integer(33) + assert decoder.decode({'place-holder': None, 'first-name': 'xx', 'age': 33}, asn1Spec=self.s) == s + + +class ChoiceDecoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Choice( + componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null()), + namedtype.NamedType('first-name', univ.OctetString()), + namedtype.NamedType('age', univ.Integer(33)) + ) + ) + + def testSimple(self): + s = self.s.clone() + s[1] = univ.OctetString('xx') + assert decoder.decode({'first-name': 'xx'}, asn1Spec=self.s) == s + + +class AnyDecoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Any() + + def testSimple(self): + assert decoder.decode('fox', asn1Spec=univ.Any()) == univ.Any('fox') + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/codec/native/test_encoder.py b/tests/codec/native/test_encoder.py new file mode 100644 index 0000000..a1d9efc --- /dev/null +++ b/tests/codec/native/test_encoder.py @@ -0,0 +1,130 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1.type import tag, namedtype, univ +from pyasn1.codec.native import encoder +from pyasn1.compat.octets import str2octs +from pyasn1.error import PyAsn1Error + + +class BadAsn1SpecTestCase(unittest.TestCase): + def testBadValueType(self): + try: + encoder.encode('not an Asn1Item') + except PyAsn1Error: + pass + else: + assert 0, 'Invalid value type accepted' + + +class IntegerEncoderTestCase(unittest.TestCase): + def testPosInt(self): + assert encoder.encode(univ.Integer(12)) == 12 + + def testNegInt(self): + assert encoder.encode(univ.Integer(-12)) == -12 + + +class BooleanEncoderTestCase(unittest.TestCase): + def testTrue(self): + assert encoder.encode(univ.Boolean(1)) is True + + def testFalse(self): + assert encoder.encode(univ.Boolean(0)) is False + + +class BitStringEncoderTestCase(unittest.TestCase): + def setUp(self): + self.b = univ.BitString((1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1)) + + def testValue(self): + assert encoder.encode(self.b) == '101010011000101' + + +class OctetStringEncoderTestCase(unittest.TestCase): + def setUp(self): + self.o = univ.OctetString('Quick brown fox') + + def testValue(self): + assert encoder.encode(self.o) == str2octs('Quick brown fox') + + +class NullEncoderTestCase(unittest.TestCase): + def testNull(self): + assert encoder.encode(univ.Null('')) is None + + +class ObjectIdentifierEncoderTestCase(unittest.TestCase): + def testOne(self): + assert encoder.encode(univ.ObjectIdentifier((1, 3, 6, 0, 12345))) == '1.3.6.0.12345' + + +class RealEncoderTestCase(unittest.TestCase): + def testChar(self): + assert encoder.encode(univ.Real((123, 10, 11))) == 1.23e+13 + + def testPlusInf(self): + assert encoder.encode(univ.Real('inf')) == float('inf') + + def testMinusInf(self): + assert encoder.encode(univ.Real('-inf')) == float('-inf') + + +class SequenceEncoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Sequence(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null('')), + namedtype.OptionalNamedType('first-name', univ.OctetString('')), + namedtype.DefaultedNamedType('age', univ.Integer(33)), + )) + + def testSimple(self): + s = self.s.clone() + s[0] = univ.Null('') + s[1] = 'abc' + s[2] = 123 + assert encoder.encode(s) == {'place-holder': None, 'first-name': str2octs('abc'), 'age': 123} + + +class ChoiceEncoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Choice(componentType=namedtype.NamedTypes( + namedtype.NamedType('place-holder', univ.Null('')), + namedtype.NamedType('number', univ.Integer(0)), + namedtype.NamedType('string', univ.OctetString()) + )) + + def testEmpty(self): + try: + encoder.encode(self.s) + except PyAsn1Error: + pass + else: + assert False, 'encoded unset choice' + + def testFilled(self): + self.s.setComponentByPosition(0, univ.Null('')) + assert encoder.encode(self.s) == {'place-holder': None} + + +class AnyEncoderTestCase(unittest.TestCase): + def setUp(self): + self.s = univ.Any(encoder.encode(univ.OctetString('fox'))) + + def testSimple(self): + assert encoder.encode(self.s) == str2octs('fox') + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/test_debug.py b/tests/test_debug.py new file mode 100644 index 0000000..742f7f1 --- /dev/null +++ b/tests/test_debug.py @@ -0,0 +1,37 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1 import debug +from pyasn1 import error + +class DebugCaseBase(unittest.TestCase): + def testKnownFlags(self): + debug.setLogger(debug.Debug('all', 'encoder', 'decoder')) + debug.setLogger(0) + + def testUnknownFlags(self): + try: + debug.setLogger(debug.Debug('all', 'unknown', loggerName='xxx')) + + except error.PyAsn1Error: + debug.setLogger(0) + return + + else: + debug.setLogger(0) + assert 0, 'unknown debug flag tolerated' + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/type/__init__.py b/tests/type/__init__.py new file mode 100644 index 0000000..8c3066b --- /dev/null +++ b/tests/type/__init__.py @@ -0,0 +1 @@ +# This file is necessary to make this directory a package. diff --git a/tests/type/__main__.py b/tests/type/__main__.py new file mode 100644 index 0000000..bd89f8b --- /dev/null +++ b/tests/type/__main__.py @@ -0,0 +1,23 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +try: + import unittest2 as unittest + +except ImportError: + import unittest + +suite = unittest.TestLoader().loadTestsFromNames( + ['tests.type.test_constraint.suite', + 'tests.type.test_namedtype.suite', + 'tests.type.test_namedval.suite', + 'tests.type.test_tag.suite', + 'tests.type.test_univ.suite'] +) + + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/type/test_constraint.py b/tests/type/test_constraint.py new file mode 100644 index 0000000..0ea4ed4 --- /dev/null +++ b/tests/type/test_constraint.py @@ -0,0 +1,315 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest + +except ImportError: + import unittest + +from pyasn1.type import constraint, error + + +class SingleValueConstraintTestCase(unittest.TestCase): + def setUp(self): + self.c1 = constraint.SingleValueConstraint(1, 2) + self.c2 = constraint.SingleValueConstraint(3, 4) + + def testCmp(self): + assert self.c1 == self.c1, 'comparation fails' + + def testHash(self): + assert hash(self.c1) != hash(self.c2), 'hash() fails' + + def testGoodVal(self): + try: + self.c1(1) + except error.ValueConstraintError: + assert 0, 'constraint check fails' + + def testBadVal(self): + try: + self.c1(4) + except error.ValueConstraintError: + pass + else: + assert 0, 'constraint check fails' + + +class ContainedSubtypeConstraintTestCase(unittest.TestCase): + def setUp(self): + self.c1 = constraint.ContainedSubtypeConstraint( + constraint.SingleValueConstraint(12) + ) + + def testGoodVal(self): + try: + self.c1(12) + except error.ValueConstraintError: + assert 0, 'constraint check fails' + + def testBadVal(self): + try: + self.c1(4) + except error.ValueConstraintError: + pass + else: + assert 0, 'constraint check fails' + + +class ValueRangeConstraintTestCase(unittest.TestCase): + def setUp(self): + self.c1 = constraint.ValueRangeConstraint(1, 4) + + def testGoodVal(self): + try: + self.c1(1) + except error.ValueConstraintError: + assert 0, 'constraint check fails' + + def testBadVal(self): + try: + self.c1(-5) + except error.ValueConstraintError: + pass + else: + assert 0, 'constraint check fails' + + +class ValueSizeConstraintTestCase(unittest.TestCase): + def setUp(self): + self.c1 = constraint.ValueSizeConstraint(1, 2) + + def testGoodVal(self): + try: + self.c1('a') + except error.ValueConstraintError: + assert 0, 'constraint check fails' + + def testBadVal(self): + try: + self.c1('abc') + except error.ValueConstraintError: + pass + else: + assert 0, 'constraint check fails' + + +class PermittedAlphabetConstraintTestCase(SingleValueConstraintTestCase): + def setUp(self): + self.c1 = constraint.PermittedAlphabetConstraint('A', 'B', 'C') + self.c2 = constraint.PermittedAlphabetConstraint('DEF') + + def testGoodVal(self): + try: + self.c1('A') + except error.ValueConstraintError: + assert 0, 'constraint check fails' + + def testBadVal(self): + try: + self.c1('E') + except error.ValueConstraintError: + pass + else: + assert 0, 'constraint check fails' + + +class ConstraintsIntersectionTestCase(unittest.TestCase): + def setUp(self): + self.c1 = constraint.ConstraintsIntersection( + constraint.SingleValueConstraint(4), + constraint.ValueRangeConstraint(2, 4) + ) + + def testCmp1(self): + assert constraint.SingleValueConstraint(4) in self.c1, '__cmp__() fails' + + def testCmp2(self): + assert constraint.SingleValueConstraint(5) not in self.c1, \ + '__cmp__() fails' + + def testCmp3(self): + c = constraint.ConstraintsUnion(constraint.ConstraintsIntersection( + constraint.SingleValueConstraint(4), + constraint.ValueRangeConstraint(2, 4)) + ) + assert self.c1 in c, '__cmp__() fails' + + def testCmp4(self): + c = constraint.ConstraintsUnion( + constraint.ConstraintsIntersection(constraint.SingleValueConstraint(5)) + ) + assert self.c1 not in c, '__cmp__() fails' + + def testGoodVal(self): + try: + self.c1(4) + except error.ValueConstraintError: + assert 0, 'constraint check fails' + + def testBadVal(self): + try: + self.c1(-5) + except error.ValueConstraintError: + pass + else: + assert 0, 'constraint check fails' + + +class InnerTypeConstraintTestCase(unittest.TestCase): + def testConst1(self): + c = constraint.InnerTypeConstraint( + constraint.SingleValueConstraint(4) + ) + try: + c(4, 32) + except error.ValueConstraintError: + assert 0, 'constraint check fails' + try: + c(5, 32) + except error.ValueConstraintError: + pass + else: + assert 0, 'constraint check fails' + + def testConst2(self): + c = constraint.InnerTypeConstraint( + (0, constraint.SingleValueConstraint(4), 'PRESENT'), + (1, constraint.SingleValueConstraint(4), 'ABSENT') + ) + try: + c(4, 0) + except error.ValueConstraintError: + raise + assert 0, 'constraint check fails' + try: + c(4, 1) + except error.ValueConstraintError: + pass + else: + assert 0, 'constraint check fails' + try: + c(3, 0) + except error.ValueConstraintError: + pass + else: + assert 0, 'constraint check fails' + + # Constraints compositions + + +class ConstraintsIntersectionRangeTestCase(unittest.TestCase): + def setUp(self): + self.c1 = constraint.ConstraintsIntersection( + constraint.ValueRangeConstraint(1, 9), + constraint.ValueRangeConstraint(2, 5) + ) + + def testGoodVal(self): + try: + self.c1(3) + except error.ValueConstraintError: + assert 0, 'constraint check fails' + + def testBadVal(self): + try: + self.c1(0) + except error.ValueConstraintError: + pass + else: + assert 0, 'constraint check fails' + + +class ConstraintsUnionTestCase(unittest.TestCase): + def setUp(self): + self.c1 = constraint.ConstraintsUnion( + constraint.SingleValueConstraint(5), + constraint.ValueRangeConstraint(1, 3) + ) + + def testGoodVal(self): + try: + self.c1(2) + self.c1(5) + except error.ValueConstraintError: + assert 0, 'constraint check fails' + + def testBadVal(self): + try: + self.c1(-5) + except error.ValueConstraintError: + pass + else: + assert 0, 'constraint check fails' + + +class ConstraintsExclusionTestCase(unittest.TestCase): + def setUp(self): + self.c1 = constraint.ConstraintsExclusion( + constraint.ValueRangeConstraint(2, 4) + ) + + def testGoodVal(self): + try: + self.c1(6) + except error.ValueConstraintError: + assert 0, 'constraint check fails' + + def testBadVal(self): + try: + self.c1(2) + except error.ValueConstraintError: + pass + else: + assert 0, 'constraint check fails' + + +# Constraints derivations + +class DirectDerivationTestCase(unittest.TestCase): + def setUp(self): + self.c1 = constraint.SingleValueConstraint(5) + self.c2 = constraint.ConstraintsUnion( + self.c1, constraint.ValueRangeConstraint(1, 3) + ) + + def testGoodVal(self): + assert self.c1.isSuperTypeOf(self.c2), 'isSuperTypeOf failed' + assert not self.c1.isSubTypeOf(self.c2), 'isSubTypeOf failed' + + def testBadVal(self): + assert not self.c2.isSuperTypeOf(self.c1), 'isSuperTypeOf failed' + assert self.c2.isSubTypeOf(self.c1), 'isSubTypeOf failed' + + +class IndirectDerivationTestCase(unittest.TestCase): + def setUp(self): + self.c1 = constraint.ConstraintsIntersection( + constraint.ValueRangeConstraint(1, 30) + ) + self.c2 = constraint.ConstraintsIntersection( + self.c1, constraint.ValueRangeConstraint(1, 20) + ) + self.c2 = constraint.ConstraintsIntersection( + self.c2, constraint.ValueRangeConstraint(1, 10) + ) + + def testGoodVal(self): + assert self.c1.isSuperTypeOf(self.c2), 'isSuperTypeOf failed' + assert not self.c1.isSubTypeOf(self.c2), 'isSubTypeOf failed' + + def testBadVal(self): + assert not self.c2.isSuperTypeOf(self.c1), 'isSuperTypeOf failed' + assert self.c2.isSubTypeOf(self.c1), 'isSubTypeOf failed' + +# TODO: how to apply size constriants to constructed types? + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/type/test_namedtype.py b/tests/type/test_namedtype.py new file mode 100644 index 0000000..cbb9118 --- /dev/null +++ b/tests/type/test_namedtype.py @@ -0,0 +1,122 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest +except ImportError: + import unittest + +from pyasn1.type import namedtype, univ +from pyasn1.error import PyAsn1Error + + +class NamedTypeCaseBase(unittest.TestCase): + def setUp(self): + self.e = namedtype.NamedType('age', univ.Integer(0)) + + def testIter(self): + n, t = self.e + assert n == 'age' or t == univ.Integer(), 'unpack fails' + + def testRepr(self): + assert eval(repr(self.e), {'NamedType': namedtype.NamedType, 'Integer': univ.Integer}) == self.e, 'repr() fails' + + +class NamedTypesCaseBase(unittest.TestCase): + def setUp(self): + self.e = namedtype.NamedTypes( + namedtype.NamedType('first-name', univ.OctetString('')), + namedtype.OptionalNamedType('age', univ.Integer(0)), + namedtype.NamedType('family-name', univ.OctetString('')) + ) + + def testRepr(self): + assert eval(repr(self.e), {'NamedTypes': namedtype.NamedTypes, 'NamedType': namedtype.NamedType, + 'OptionalNamedType': namedtype.OptionalNamedType, 'Integer': univ.Integer, + 'OctetString': univ.OctetString}) == self.e, 'repr() fails' + + def testContains(self): + assert 'first-name' in self.e + assert '<missing>' not in self.e + + # noinspection PyUnusedLocal + def testGetItem(self): + assert self.e[0] == namedtype.NamedType('first-name', univ.OctetString('')) + + def testIter(self): + assert list(self.e) == ['first-name', 'age', 'family-name'] + + def testGetTypeByPosition(self): + assert self.e.getTypeByPosition(0) == univ.OctetString(''), \ + 'getTypeByPosition() fails' + + def testGetNameByPosition(self): + assert self.e.getNameByPosition(0) == 'first-name', \ + 'getNameByPosition() fails' + + def testGetPositionByName(self): + assert self.e.getPositionByName('first-name') == 0, \ + 'getPositionByName() fails' + + def testGetTypesNearPosition(self): + assert self.e.getTagMapNearPosition(0).getPosMap() == { + univ.OctetString.tagSet: univ.OctetString('') + } + assert self.e.getTagMapNearPosition(1).getPosMap() == { + univ.Integer.tagSet: univ.Integer(0), + univ.OctetString.tagSet: univ.OctetString('') + } + assert self.e.getTagMapNearPosition(2).getPosMap() == { + univ.OctetString.tagSet: univ.OctetString('') + } + + def testGetTagMap(self): + assert self.e.getTagMap().getPosMap() == { + univ.OctetString.tagSet: univ.OctetString(''), + univ.Integer.tagSet: univ.Integer(0) + } + + def testStrTagMap(self): + assert 'TagMap' in str(self.e.getTagMap()) + assert 'OctetString' in str(self.e.getTagMap()) + assert 'Integer' in str(self.e.getTagMap()) + + def testReprTagMap(self): + assert 'TagMap' in repr(self.e.getTagMap()) + assert 'OctetString' in repr(self.e.getTagMap()) + assert 'Integer' in repr(self.e.getTagMap()) + + def testGetTagMapWithDups(self): + try: + self.e.getTagMap(1) + except PyAsn1Error: + pass + else: + assert 0, 'Duped types not noticed' + + def testGetPositionNearType(self): + assert self.e.getPositionNearType(univ.OctetString.tagSet, 0) == 0 + assert self.e.getPositionNearType(univ.Integer.tagSet, 1) == 1 + assert self.e.getPositionNearType(univ.OctetString.tagSet, 2) == 2 + + +class OrderedNamedTypesCaseBase(unittest.TestCase): + def setUp(self): + self.e = namedtype.NamedTypes( + namedtype.NamedType('first-name', univ.OctetString('')), + namedtype.NamedType('age', univ.Integer(0)) + ) + + def testGetTypeByPosition(self): + assert self.e.getTypeByPosition(0) == univ.OctetString(''), \ + 'getTypeByPosition() fails' + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/type/test_namedval.py b/tests/type/test_namedval.py new file mode 100644 index 0000000..e52f724 --- /dev/null +++ b/tests/type/test_namedval.py @@ -0,0 +1,32 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest + +except ImportError: + import unittest + +from pyasn1.type import namedval + + +class NamedValuesCaseBase(unittest.TestCase): + def setUp(self): + self.e = namedval.NamedValues(('off', 0), ('on', 1)) + + def testIter(self): + off, on = self.e + assert off == ('off', 0) or on == ('on', 1), 'unpack fails' + + def testRepr(self): + assert eval(repr(self.e), {'NamedValues': namedval.NamedValues}) == self.e, 'repr() fails' + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/type/test_tag.py b/tests/type/test_tag.py new file mode 100644 index 0000000..fac9783 --- /dev/null +++ b/tests/type/test_tag.py @@ -0,0 +1,131 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +try: + import unittest2 as unittest + +except ImportError: + import unittest + +from pyasn1.type import tag + + +class TagTestCaseBase(unittest.TestCase): + def setUp(self): + self.t1 = tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 3) + self.t2 = tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 3) + + +class TagReprTestCase(TagTestCaseBase): + def testRepr(self): + assert eval(repr(self.t1), {'Tag': tag.Tag}) == self.t1, 'repr() fails' + + +class TagCmpTestCase(TagTestCaseBase): + def testCmp(self): + assert self.t1 == self.t2, 'tag comparation fails' + + def testHash(self): + assert hash(self.t1) == hash(self.t2), 'tag hash comparation fails' + + def testSequence(self): + assert self.t1[0] == self.t2[0] and \ + self.t1[1] == self.t2[1] and \ + self.t1[2] == self.t2[2], 'tag sequence protocol fails' + + +class TagSetTestCaseBase(unittest.TestCase): + def setUp(self): + self.ts1 = tag.initTagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12) + ) + self.ts2 = tag.initTagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12) + ) + + +class TagSetReprTestCase(TagSetTestCaseBase): + def testRepr(self): + assert eval(repr(self.ts1), {'TagSet': tag.TagSet, 'Tag': tag.Tag}) == self.ts1, 'repr() fails' + + +class TagSetCmpTestCase(TagSetTestCaseBase): + def testCmp(self): + assert self.ts1 == self.ts2, 'tag set comparation fails' + + def testHash(self): + assert hash(self.ts1) == hash(self.ts2), 'tag set hash comp. fails' + + def testLen(self): + assert len(self.ts1) == len(self.ts2), 'tag length comparation fails' + + +class TaggingTestSuite(TagSetTestCaseBase): + def testImplicitTag(self): + t = self.ts1.tagImplicitly( + tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 14) + ) + assert t == tag.TagSet( + tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 12), + tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 14) + ), 'implicit tagging went wrong' + + def testExplicitTag(self): + t = self.ts1.tagExplicitly( + tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 32) + ) + assert t == tag.TagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12), + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12), + tag.Tag(tag.tagClassPrivate, tag.tagFormatConstructed, 32) + ), 'explicit tagging went wrong' + + +class TagSetAddTestSuite(TagSetTestCaseBase): + def testAdd(self): + t = self.ts1 + tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2) + assert t == tag.TagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12), + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12), + tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2) + ), 'TagSet.__add__() fails' + + def testRadd(self): + t = tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2) + self.ts1 + assert t == tag.TagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12), + tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 2), + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12) + ), 'TagSet.__radd__() fails' + + +class SuperTagSetTestCase(TagSetTestCaseBase): + def testSuperTagCheck1(self): + assert self.ts1.isSuperTagSetOf( + tag.TagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12), + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12) + )), 'isSuperTagSetOf() fails' + + def testSuperTagCheck2(self): + assert not self.ts1.isSuperTagSetOf( + tag.TagSet( + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 12), + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 13) + )), 'isSuperTagSetOf() fails' + + def testSuperTagCheck3(self): + assert self.ts1.isSuperTagSetOf( + tag.TagSet((), tag.Tag(tag.tagClassUniversal, + tag.tagFormatSimple, 12)) + ), 'isSuperTagSetOf() fails' + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/type/test_univ.py b/tests/type/test_univ.py new file mode 100644 index 0000000..0d7e0ad --- /dev/null +++ b/tests/type/test_univ.py @@ -0,0 +1,1173 @@ +# +# This file is part of pyasn1 software. +# +# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com> +# License: http://pyasn1.sf.net/license.html +# +import sys +import math +from pyasn1.type import univ, tag, constraint, namedtype, namedval, error +from pyasn1.compat.octets import str2octs, ints2octs +from pyasn1.error import PyAsn1Error + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class NoValueTestCase(unittest.TestCase): + def testSingleton(self): + assert univ.NoValue() is univ.NoValue(), 'NoValue is not a singleton' + + def testRepr(self): + try: + repr(univ.noValue) + + except PyAsn1Error: + assert False, 'repr() on NoValue object fails' + + def testIsInstance(self): + try: + assert isinstance(univ.noValue, univ.NoValue), 'isinstance() on NoValue() object fails' + + except PyAsn1Error: + assert False, 'isinstance() on NoValue object fails' + + def testStr(self): + try: + str(univ.noValue) + + except PyAsn1Error: + pass + + else: + assert False, 'str() works for NoValue object' + + def testLen(self): + try: + len(univ.noValue) + + except PyAsn1Error: + pass + + else: + assert False, 'len() works for NoValue object' + + def testCmp(self): + try: + univ.noValue == 1 + + except PyAsn1Error: + pass + + else: + assert False, 'comparison works for NoValue object' + + def testSubs(self): + try: + univ.noValue[0] + + except PyAsn1Error: + pass + + else: + assert False, '__getitem__() works for NoValue object' + + def testKey(self): + try: + univ.noValue['key'] + + except PyAsn1Error: + pass + + else: + assert False, '__getitem__() works for NoValue object' + + def testKeyAssignment(self): + try: + univ.noValue['key'] = 123 + + except PyAsn1Error: + pass + + else: + assert False, '__setitem__() works for NoValue object' + + def testInt(self): + try: + int(univ.noValue) + + except PyAsn1Error: + pass + + else: + assert False, 'integer conversion works for NoValue object' + + def testAdd(self): + try: + univ.noValue + univ.noValue + + except PyAsn1Error: + pass + + else: + assert False, 'addition works for NoValue object' + + def testBitShift(self): + try: + univ.noValue << 1 + + except PyAsn1Error: + pass + + else: + assert False, 'bitshift works for NoValue object' + + def testBooleanEvaluation(self): + try: + if univ.noValue: + pass + + except PyAsn1Error: + pass + + else: + assert False, 'boolean evaluation works for NoValue object' + + def testSizeOf(self): + try: + if hasattr(sys, 'getsizeof'): + sys.getsizeof(univ.noValue) + + except PyAsn1Error: + assert False, 'sizeof failed for NoValue object' + + +class IntegerTestCase(unittest.TestCase): + def testStr(self): + assert str(univ.Integer(1)) in ('1', '1L'), 'str() fails' + + def testRepr(self): + assert eval(repr(univ.Integer(123)), {'Integer': univ.Integer}) == univ.Integer(123), 'repr() fails' + + def testAnd(self): + assert univ.Integer(1) & 0 == 0, '__and__() fails' + + def testOr(self): + assert univ.Integer(1) | 0 == 1, '__or__() fails' + + def testXor(self): + assert univ.Integer(1) ^ 0 == 1, '__xor__() fails' + + def testRand(self): + assert 0 & univ.Integer(1) == 0, '__rand__() fails' + + def testRor(self): + assert 0 | univ.Integer(1) == 1, '__ror__() fails' + + def testRxor(self): + assert 0 ^ univ.Integer(1) == 1, '__rxor__() fails' + + def testAdd(self): + assert univ.Integer(-4) + 6 == 2, '__add__() fails' + + def testRadd(self): + assert 4 + univ.Integer(5) == 9, '__radd__() fails' + + def testSub(self): + assert univ.Integer(3) - 6 == -3, '__sub__() fails' + + def testRsub(self): + assert 6 - univ.Integer(3) == 3, '__rsub__() fails' + + def testMul(self): + assert univ.Integer(3) * -3 == -9, '__mul__() fails' + + def testRmul(self): + assert 2 * univ.Integer(3) == 6, '__rmul__() fails' + + def testDivInt(self): + assert univ.Integer(4) / 2 == 2, '__div__() fails' + + if sys.version_info[0] > 2: + def testDivFloat(self): + assert univ.Integer(3) / 2 == 1.5, '__div__() fails' + + def testRdivFloat(self): + assert 3 / univ.Integer(2) == 1.5, '__rdiv__() fails' + else: + def testDivFloat(self): + assert univ.Integer(3) / 2 == 1, '__div__() fails' + + def testRdivFloat(self): + assert 3 / univ.Integer(2) == 1, '__rdiv__() fails' + + def testRdivInt(self): + assert 6 / univ.Integer(3) == 2, '__rdiv__() fails' + + if sys.version_info[0] > 2: + def testTrueDiv(self): + assert univ.Integer(3) / univ.Integer(2) == 1.5, '__truediv__() fails' + + def testFloorDiv(self): + assert univ.Integer(3) // univ.Integer(2) == 1, '__floordiv__() fails' + + def testMod(self): + assert univ.Integer(3) % 2 == 1, '__mod__() fails' + + def testRmod(self): + assert 4 % univ.Integer(3) == 1, '__rmod__() fails' + + def testPow(self): + assert univ.Integer(3) ** 2 == 9, '__pow__() fails' + + def testRpow(self): + assert 2 ** univ.Integer(2) == 4, '__rpow__() fails' + + def testLshift(self): + assert univ.Integer(1) << 1 == 2, '<< fails' + + def testRshift(self): + assert univ.Integer(2) >> 1 == 1, '>> fails' + + def testInt(self): + assert int(univ.Integer(3)) == 3, '__int__() fails' + + def testLong(self): + assert int(univ.Integer(8)) == 8, '__long__() fails' + + def testFloat(self): + assert float(univ.Integer(4)) == 4.0, '__float__() fails' + + def testPos(self): + assert +univ.Integer(1) == 1, '__pos__() fails' + + def testNeg(self): + assert -univ.Integer(1) == -1, '__neg__() fails' + + def testInvert(self): + assert ~univ.Integer(1) == -2, '__invert__() fails' + + def testRound(self): + assert round(univ.Integer(1), 3) == 1.0, '__round__() fails' + + def testFloor(self): + assert math.floor(univ.Integer(1)) == 1, '__floor__() fails' + + def testCeil(self): + assert math.ceil(univ.Integer(1)) == 1, '__ceil__() fails' + + if sys.version_info[0:2] > (2, 5): + def testTrunc(self): + assert math.trunc(univ.Integer(1)) == 1, '__trunc__() fails' + + def testPrettyIn(self): + assert univ.Integer('3') == 3, 'prettyIn() fails' + + def testTag(self): + assert univ.Integer().getTagSet() == tag.TagSet( + (), + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x02) + ) + + def testNamedVals(self): + i = univ.Integer( + 'asn1', namedValues=univ.Integer.namedValues.clone(('asn1', 1)) + ) + assert i == 1, 'named val fails' + assert str(i) != 'asn1', 'named val __str__() fails' + + +class BooleanTestCase(unittest.TestCase): + def testTruth(self): + assert univ.Boolean(True) and univ.Boolean(1), 'Truth initializer fails' + + def testFalse(self): + assert not univ.Boolean(False) and not univ.Boolean(0), 'False initializer fails' + + def testStr(self): + assert str(univ.Boolean(1)) in ('1', '1L'), 'str() fails' + + def testRepr(self): + assert eval(repr(univ.Boolean(1)), {'Boolean': univ.Boolean}) == univ.Boolean(1), 'repr() fails' + + def testTag(self): + assert univ.Boolean().getTagSet() == tag.TagSet( + (), + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x01) + ) + + def testConstraints(self): + try: + univ.Boolean(2) + except error.ValueConstraintError: + pass + else: + assert 0, 'constraint fail' + + def testSubtype(self): + assert univ.Integer().subtype( + value=1, + implicitTag=tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 2), + subtypeSpec=constraint.SingleValueConstraint(1, 3) + ) == univ.Integer( + value=1, + tagSet=tag.TagSet(tag.Tag(tag.tagClassPrivate, + tag.tagFormatSimple, 2)), + subtypeSpec=constraint.ConstraintsIntersection(constraint.SingleValueConstraint(1, 3)) + ) + + +class BitStringTestCase(unittest.TestCase): + def setUp(self): + self.b = univ.BitString( + namedValues=namedval.NamedValues(('Active', 0), ('Urgent', 1)) + ) + + def testBinDefault(self): + + class BinDefault(univ.BitString): + defaultBinValue = '1010100110001010' + + assert BinDefault() == univ.BitString(binValue='1010100110001010') + + def testHexDefault(self): + + class HexDefault(univ.BitString): + defaultHexValue = 'A98A' + + assert HexDefault() == univ.BitString(hexValue='A98A') + + def testSet(self): + assert self.b.clone('Active') == (1,) + assert self.b.clone("'1010100110001010'B") == (1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0) + assert self.b.clone("'A98A'H") == (1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0) + assert self.b.clone(binValue='1010100110001010') == (1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0) + assert self.b.clone(hexValue='A98A') == (1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0) + assert self.b.clone('1010100110001010') == (1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0) + assert self.b.clone((1, 0, 1)) == (1, 0, 1) + + def testStr(self): + assert str(self.b.clone('Urgent,Active')) == '11' + + def testRepr(self): + assert eval(repr(self.b.clone('Urgent,Active')), {'BitString': univ.BitString}) == self.b.clone( + 'Urgent,Active'), 'repr() fails' + + def testTag(self): + assert univ.BitString().getTagSet() == tag.TagSet( + (), + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x03) + ) + + def testLen(self): + assert len(self.b.clone("'A98A'H")) == 16 + + def testGetItem(self): + assert self.b.clone("'A98A'H")[0] == 1 + assert self.b.clone("'A98A'H")[1] == 0 + assert self.b.clone("'A98A'H")[2] == 1 + + def testContains(self): + assert 1 in univ.BitString([0, 0, 0, 0, 1]) + assert 0 not in univ.BitString([1, 1]) + + if sys.version_info[:2] > (2, 4): + def testReverse(self): + assert reversed(univ.BitString([0, 0, 1])) == univ.BitString([1, 0, 0]) + + def testAsOctets(self): + assert self.b.clone(hexValue='A98A').asOctets() == ints2octs((0xa9, 0x8a)), 'testAsOctets() fails' + + def testAsInts(self): + assert self.b.clone(hexValue='A98A').asNumbers() == (0xa9, 0x8a), 'testAsNumbers() fails' + + def testMultipleOfEightNoPadding(self): + try: + self.b.clone((1, 0, 1)).asOctets(padding=False) + except PyAsn1Error: + pass + else: + assert 0, "non 8-bit bitstring didn't fail" + + def testMultipleOfEightPadding(self): + assert self.b.clone((1, 0, 1)).asNumbers(padding=True) == (5,) + + def testAsInteger(self): + assert self.b.clone('11000000011001').asInteger(padding=True) == 12313 + assert self.b.clone('1100110011011111').asInteger(padding=False) == 52447 + +class OctetStringTestCase(unittest.TestCase): + + def testBinDefault(self): + + class BinDefault(univ.OctetString): + defaultBinValue = '1000010111101110101111000000111011' + + assert BinDefault() == univ.OctetString(binValue='1000010111101110101111000000111011') + + def testHexDefault(self): + + class HexDefault(univ.OctetString): + defaultHexValue = 'FA9823C43E43510DE3422' + + assert HexDefault() == univ.OctetString(hexValue='FA9823C43E43510DE3422') + + def testInit(self): + assert univ.OctetString(str2octs('abcd')) == str2octs('abcd'), '__init__() fails' + + def testBinStr(self): + assert univ.OctetString(binValue="1000010111101110101111000000111011") == ints2octs( + (133, 238, 188, 14, 192)), 'bin init fails' + + def testHexStr(self): + assert univ.OctetString(hexValue="FA9823C43E43510DE3422") == ints2octs( + (250, 152, 35, 196, 62, 67, 81, 13, 227, 66, 32)), 'hex init fails' + + def testTuple(self): + assert univ.OctetString((1, 2, 3, 4, 5)) == ints2octs((1, 2, 3, 4, 5)), 'tuple init failed' + + if sys.version_info[0] <= 2: + def testUnicode(self): + assert univ.OctetString(unicode('q')) == 'q', 'unicode init fails' + else: + def testUnicode(self): + assert univ.OctetString('q') == str2octs('q'), 'unicode init fails' + + def testStr(self): + assert str(univ.OctetString('q')) == 'q', '__str__() fails' + + def testSeq(self): + assert univ.OctetString('q')[0] == str2octs('q')[0], '__getitem__() fails' + + def testRepr(self): + assert eval(repr(univ.OctetString('abc')), {'OctetString': univ.OctetString}) == univ.OctetString( + 'abc'), 'repr() fails' + + def testAsOctets(self): + assert univ.OctetString('abcd').asOctets() == str2octs('abcd'), 'testAsOctets() fails' + + def testAsInts(self): + assert univ.OctetString('abcd').asNumbers() == (97, 98, 99, 100), 'testAsNumbers() fails' + + def testEmpty(self): + try: + str(univ.OctetString()) + except PyAsn1Error: + pass + else: + assert 0, 'empty OctetString() not reported' + + def testAdd(self): + assert univ.OctetString('') + 'q' == str2octs('q'), '__add__() fails' + + def testRadd(self): + assert 'b' + univ.OctetString('q') == str2octs('bq'), '__radd__() fails' + + def testMul(self): + assert univ.OctetString('a') * 2 == str2octs('aa'), '__mul__() fails' + + def testRmul(self): + assert 2 * univ.OctetString('b') == str2octs('bb'), '__rmul__() fails' + + def testTag(self): + assert univ.OctetString().getTagSet() == tag.TagSet( + (), + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x04) + ) + + def testContains(self): + s = univ.OctetString('abcd') + assert str2octs('b') in s + assert str2octs('B') not in s + + if sys.version_info[:2] > (2, 4): + def testReverse(self): + assert reversed(univ.OctetString('abcd')) == univ.OctetString('dcba') + + +class Null(unittest.TestCase): + def testStr(self): + assert str(univ.Null('')) == '', 'str() fails' + + def testRepr(self): + assert eval(repr(univ.Null()), {'Null': univ.Null}) == univ.Null(), 'repr() fails' + + def testTag(self): + assert univ.Null().getTagSet() == tag.TagSet( + (), + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05) + ) + + def testConstraints(self): + try: + univ.Null(2) + except error.ValueConstraintError: + pass + else: + assert 0, 'constraint fail' + + +class RealTestCase(unittest.TestCase): + def testFloat4BinEnc(self): + assert univ.Real((0.25, 2, 3)) == 2.0, 'float initializer for binary encoding fails' + + def testStr(self): + assert str(univ.Real(1.0)) == '1.0', 'str() fails' + + def testRepr(self): + assert eval(repr(univ.Real(-4.1)), {'Real': univ.Real}) == univ.Real(-4.1), 'repr() fails' + assert repr(univ.Real(-4.1)) == 'Real((-41, 10, -1))', 'repr() fails' + assert eval(repr(univ.Real('inf')), {'Real': univ.Real}) == univ.Real('inf'), 'repr() fails' + assert repr(univ.Real('inf')) == 'Real(\'inf\')', 'repr() fails' + + def testAdd(self): + assert univ.Real(-4.1) + 1.4 == -2.7, '__add__() fails' + + def testRadd(self): + assert 4 + univ.Real(0.5) == 4.5, '__radd__() fails' + + def testSub(self): + assert univ.Real(3.9) - 1.7 == 2.2, '__sub__() fails' + + def testRsub(self): + assert 6.1 - univ.Real(0.1) == 6, '__rsub__() fails' + + def testMul(self): + assert univ.Real(3.0) * -3 == -9, '__mul__() fails' + + def testRmul(self): + assert 2 * univ.Real(3.0) == 6, '__rmul__() fails' + + def testDiv(self): + assert univ.Real(3.0) / 2 == 1.5, '__div__() fails' + + def testRdiv(self): + assert 6 / univ.Real(3.0) == 2, '__rdiv__() fails' + + def testMod(self): + assert univ.Real(3.0) % 2 == 1, '__mod__() fails' + + def testRmod(self): + assert 4 % univ.Real(3.0) == 1, '__rmod__() fails' + + def testPow(self): + assert univ.Real(3.0) ** 2 == 9, '__pow__() fails' + + def testRpow(self): + assert 2 ** univ.Real(2.0) == 4, '__rpow__() fails' + + def testInt(self): + assert int(univ.Real(3.0)) == 3, '__int__() fails' + + def testLong(self): + assert int(univ.Real(8.0)) == 8, '__long__() fails' + + def testFloat(self): + assert float(univ.Real(4.0)) == 4.0, '__float__() fails' + + def testPrettyIn(self): + assert univ.Real((3, 10, 0)) == 3, 'prettyIn() fails' + + # infinite float values + def testStrInf(self): + assert str(univ.Real('inf')) == 'inf', 'str() fails' + + def testAddInf(self): + assert univ.Real('inf') + 1 == float('inf'), '__add__() fails' + + def testRaddInf(self): + assert 1 + univ.Real('inf') == float('inf'), '__radd__() fails' + + def testIntInf(self): + try: + assert int(univ.Real('inf')) + except OverflowError: + pass + else: + assert 0, '__int__() fails' + + def testLongInf(self): + try: + assert int(univ.Real('inf')) + except OverflowError: + pass + else: + assert 0, '__long__() fails' + assert int(univ.Real(8.0)) == 8, '__long__() fails' + + def testFloatInf(self): + assert float(univ.Real('-inf')) == float('-inf'), '__float__() fails' + + def testPrettyInInf(self): + assert univ.Real(float('inf')) == float('inf'), 'prettyIn() fails' + + def testPlusInf(self): + assert univ.Real('inf').isPlusInfinity(), 'isPlusInfinity failed' + + def testMinusInf(self): + assert univ.Real('-inf').isMinusInfinity(), 'isMinusInfinity failed' + + def testPos(self): + assert +univ.Real(1.0) == 1.0, '__pos__() fails' + + def testNeg(self): + assert -univ.Real(1.0) == -1.0, '__neg__() fails' + + def testRound(self): + assert round(univ.Real(1.123), 2) == 1.12, '__round__() fails' + + def testFloor(self): + assert math.floor(univ.Real(1.6)) == 1.0, '__floor__() fails' + + def testCeil(self): + assert math.ceil(univ.Real(1.2)) == 2.0, '__ceil__() fails' + + if sys.version_info[0:2] > (2, 5): + def testTrunc(self): + assert math.trunc(univ.Real(1.1)) == 1.0, '__trunc__() fails' + + def testTag(self): + assert univ.Real().getTagSet() == tag.TagSet( + (), + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x09) + ) + + +class ObjectIdentifier(unittest.TestCase): + def testStr(self): + assert str(univ.ObjectIdentifier((1, 3, 6))) == '1.3.6', 'str() fails' + + def testRepr(self): + assert eval(repr(univ.ObjectIdentifier('1.3.6')), + {'ObjectIdentifier': univ.ObjectIdentifier}) == univ.ObjectIdentifier('1.3.6'), 'repr() fails' + + def testEq(self): + assert univ.ObjectIdentifier((1, 3, 6)) == (1, 3, 6), '__cmp__() fails' + + def testAdd(self): + assert univ.ObjectIdentifier((1, 3)) + (6,) == (1, 3, 6), '__add__() fails' + + def testRadd(self): + assert (1,) + univ.ObjectIdentifier((3, 6)) == (1, 3, 6), '__radd__() fails' + + def testLen(self): + assert len(univ.ObjectIdentifier((1, 3))) == 2, '__len__() fails' + + def testPrefix(self): + o = univ.ObjectIdentifier('1.3.6') + assert o.isPrefixOf((1, 3, 6)), 'isPrefixOf() fails' + assert o.isPrefixOf((1, 3, 6, 1)), 'isPrefixOf() fails' + assert not o.isPrefixOf((1, 3)), 'isPrefixOf() fails' + + def testInput1(self): + assert univ.ObjectIdentifier('1.3.6') == (1, 3, 6), 'prettyIn() fails' + + def testInput2(self): + assert univ.ObjectIdentifier((1, 3, 6)) == (1, 3, 6), 'prettyIn() fails' + + def testInput3(self): + assert univ.ObjectIdentifier(univ.ObjectIdentifier('1.3') + (6,)) == (1, 3, 6), 'prettyIn() fails' + + def testUnicode(self): + s = '1.3.6' + if sys.version_info[0] < 3: + s = s.decode() + assert univ.ObjectIdentifier(s) == (1, 3, 6), 'unicode init fails' + + def testTag(self): + assert univ.ObjectIdentifier().getTagSet() == tag.TagSet( + (), + tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x06) + ) + + def testContains(self): + s = univ.ObjectIdentifier('1.3.6.1234.99999') + assert 1234 in s + assert 4321 not in s + + +class SequenceOf(unittest.TestCase): + def setUp(self): + self.s1 = univ.SequenceOf( + componentType=univ.OctetString('') + ) + self.s2 = self.s1.clone() + + def testRepr(self): + assert eval(repr(self.s1.clone().setComponents('a', 'b')), + {'SequenceOf': univ.SequenceOf, 'OctetString': univ.OctetString}) == self.s1.clone().setComponents( + 'a', 'b'), 'repr() fails' + + def testTag(self): + assert self.s1.getTagSet() == tag.TagSet( + (), + tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10) + ), 'wrong tagSet' + + def testSeq(self): + self.s1.setComponentByPosition(0, univ.OctetString('abc')) + assert self.s1[0] == str2octs('abc'), 'set by idx fails' + self.s1[0] = 'cba' + assert self.s1[0] == str2octs('cba'), 'set by idx fails' + + def testCmp(self): + self.s1.clear() + self.s1.setComponentByPosition(0, 'abc') + self.s2.clear() + self.s2.setComponentByPosition(0, univ.OctetString('abc')) + assert self.s1 == self.s2, '__cmp__() fails' + + def testSubtypeSpec(self): + s = self.s1.clone(subtypeSpec=constraint.ConstraintsUnion( + constraint.SingleValueConstraint(str2octs('abc')) + )) + try: + s.setComponentByPosition(0, univ.OctetString('abc')) + except PyAsn1Error: + assert 0, 'constraint fails' + try: + s.setComponentByPosition(1, univ.OctetString('Abc')) + except PyAsn1Error: + try: + s.setComponentByPosition(1, univ.OctetString('Abc'), + verifyConstraints=False) + except PyAsn1Error: + assert 0, 'constraint failes with verifyConstraints=True' + else: + assert 0, 'constraint fails' + + def testComponentTagsMatching(self): + s = self.s1.clone() + s.strictConstraints = True # This requires types equality + o = univ.OctetString('abc').subtype(explicitTag=tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 12)) + try: + s.setComponentByPosition(0, o) + except PyAsn1Error: + pass + else: + assert 0, 'inner supertype tag allowed' + + def testComponentConstraintsMatching(self): + s = self.s1.clone() + o = univ.OctetString().subtype( + subtypeSpec=constraint.ConstraintsUnion(constraint.SingleValueConstraint(str2octs('cba')))) + s.strictConstraints = True # This requires types equality + try: + s.setComponentByPosition(0, o.clone('cba')) + except PyAsn1Error: + pass + else: + assert 0, 'inner supertype constraint allowed' + s.strictConstraints = False # This requires subtype relationships + try: + s.setComponentByPosition(0, o.clone('cba')) + except PyAsn1Error: + assert 0, 'inner supertype constraint disallowed' + else: + pass + + def testSizeSpec(self): + s = self.s1.clone(sizeSpec=constraint.ConstraintsUnion( + constraint.ValueSizeConstraint(1, 1) + )) + s.setComponentByPosition(0, univ.OctetString('abc')) + try: + s.verifySizeSpec() + except PyAsn1Error: + assert 0, 'size spec fails' + s.setComponentByPosition(1, univ.OctetString('abc')) + try: + s.verifySizeSpec() + except PyAsn1Error: + pass + else: + assert 0, 'size spec fails' + + def testGetComponentTagMap(self): + assert self.s1.getComponentTagMap().getPosMap() == { + univ.OctetString.tagSet: univ.OctetString('') + } + + def testSubtype(self): + self.s1.clear() + assert self.s1.subtype( + implicitTag=tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 2), + subtypeSpec=constraint.SingleValueConstraint(1, 3), + sizeSpec=constraint.ValueSizeConstraint(0, 1) + ) == self.s1.clone( + tagSet=tag.TagSet(tag.Tag(tag.tagClassPrivate, + tag.tagFormatSimple, 2)), + subtypeSpec=constraint.ConstraintsIntersection(constraint.SingleValueConstraint(1, 3)), + sizeSpec=constraint.ValueSizeConstraint(0, 1) + ) + + def testClone(self): + self.s1.setComponentByPosition(0, univ.OctetString('abc')) + s = self.s1.clone() + assert len(s) == 0 + s = self.s1.clone(cloneValueFlag=1) + assert len(s) == 1 + assert s.getComponentByPosition(0) == self.s1.getComponentByPosition(0) + + def testSetComponents(self): + assert self.s1.clone().setComponents('abc', 'def') == \ + self.s1.setComponentByPosition(0, 'abc').setComponentByPosition(1, 'def') + + def testAppend(self): + self.s1.clear() + self.s1.setComponentByPosition(0, univ.OctetString('abc')) + assert len(self.s1) == 1 + self.s1.append('def') + assert len(self.s1) == 2 + assert list(self.s1) == [str2octs(x) for x in ['abc', 'def']] + + def testExtend(self): + self.s1.clear() + self.s1.setComponentByPosition(0, univ.OctetString('abc')) + assert len(self.s1) == 1 + self.s1.extend(['def', 'ghi']) + assert len(self.s1) == 3 + assert list(self.s1) == [str2octs(x) for x in ['abc', 'def', 'ghi']] + + def testCount(self): + self.s1.clear() + for x in ['abc', 'def', 'abc']: + self.s1.append(x) + assert self.s1.count(str2octs('abc')) == 2 + assert self.s1.count(str2octs('def')) == 1 + assert self.s1.count(str2octs('ghi')) == 0 + + def testIndex(self): + self.s1.clear() + for x in ['abc', 'def', 'abc']: + self.s1.append(x) + assert self.s1.index(str2octs('abc')) == 0 + assert self.s1.index(str2octs('def')) == 1 + assert self.s1.index(str2octs('abc'), 1) == 2 + + def testSort(self): + self.s1.clear() + self.s1[0] = 'b' + self.s1[1] = 'a' + assert list(self.s1) == [str2octs('b'), str2octs('a')] + self.s1.sort() + assert list(self.s1) == [str2octs('a'), str2octs('b')] + + +class Sequence(unittest.TestCase): + def setUp(self): + self.s1 = univ.Sequence(componentType=namedtype.NamedTypes( + namedtype.NamedType('name', univ.OctetString('')), + namedtype.OptionalNamedType('nick', univ.OctetString('')), + namedtype.DefaultedNamedType('age', univ.Integer(34)) + )) + + def testRepr(self): + assert eval(repr(self.s1.clone().setComponents('a', 'b')), + {'Sequence': univ.Sequence, 'OctetString': univ.OctetString, 'Integer': univ.Integer, + 'NamedTypes': namedtype.NamedTypes, 'NamedType': namedtype.NamedType, + 'OptionalNamedType': namedtype.OptionalNamedType, + 'DefaultedNamedType': namedtype.DefaultedNamedType}) == self.s1.clone().setComponents('a', 'b'), 'repr() fails' + + def testTag(self): + assert self.s1.getTagSet() == tag.TagSet( + (), + tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10) + ), 'wrong tagSet' + + def testById(self): + self.s1.setComponentByName('name', univ.OctetString('abc')) + assert self.s1.getComponentByName('name') == str2octs('abc'), 'set by name fails' + + def testByKey(self): + self.s1['name'] = 'abc' + assert self.s1['name'] == str2octs('abc'), 'set by key fails' + + def testContains(self): + assert 'name' in self.s1 + assert '<missing>' not in self.s1 + + def testGetNearPosition(self): + assert self.s1.getComponentTagMapNearPosition(1).getPosMap() == { + univ.OctetString.tagSet: univ.OctetString(''), + univ.Integer.tagSet: univ.Integer(34) + } + assert self.s1.getComponentPositionNearType( + univ.OctetString.tagSet, 1 + ) == 1 + + def testGetDefaultComponentByPosition(self): + self.s1.clear() + assert self.s1.getDefaultComponentByPosition(0) is None + assert self.s1.getDefaultComponentByPosition(2) == univ.Integer(34) + + def testSetDefaultComponents(self): + self.s1.clear() + assert self.s1.getComponentByPosition(2) is None + self.s1.setComponentByPosition(0, univ.OctetString('Ping')) + self.s1.setComponentByPosition(1, univ.OctetString('Pong')) + self.s1.setDefaultComponents() + assert self.s1.getComponentByPosition(2) == 34 + + def testClone(self): + self.s1.setComponentByPosition(0, univ.OctetString('abc')) + self.s1.setComponentByPosition(1, univ.OctetString('def')) + self.s1.setComponentByPosition(2, univ.Integer(123)) + s = self.s1.clone() + assert s.getComponentByPosition(0) != self.s1.getComponentByPosition(0) + assert s.getComponentByPosition(1) != self.s1.getComponentByPosition(1) + assert s.getComponentByPosition(2) != self.s1.getComponentByPosition(2) + s = self.s1.clone(cloneValueFlag=1) + assert s.getComponentByPosition(0) == self.s1.getComponentByPosition(0) + assert s.getComponentByPosition(1) == self.s1.getComponentByPosition(1) + assert s.getComponentByPosition(2) == self.s1.getComponentByPosition(2) + + def testComponentTagsMatching(self): + s = self.s1.clone() + s.strictConstraints = True # This requires types equality + o = univ.OctetString('abc').subtype(explicitTag=tag.Tag(tag.tagClassPrivate, tag.tagFormatSimple, 12)) + try: + s.setComponentByName('name', o) + except PyAsn1Error: + pass + else: + assert 0, 'inner supertype tag allowed' + + def testComponentConstraintsMatching(self): + s = self.s1.clone() + o = univ.OctetString().subtype( + subtypeSpec=constraint.ConstraintsUnion(constraint.SingleValueConstraint(str2octs('cba')))) + s.strictConstraints = True # This requires types equality + try: + s.setComponentByName('name', o.clone('cba')) + except PyAsn1Error: + pass + else: + assert 0, 'inner supertype constraint allowed' + s.strictConstraints = False # This requires subtype relationships + try: + s.setComponentByName('name', o.clone('cba')) + except PyAsn1Error: + assert 0, 'inner supertype constraint disallowed' + else: + pass + + def testSetComponents(self): + assert self.s1.clone().setComponents(name='a', nick='b', age=1) == \ + self.s1.setComponentByPosition(0, 'a').setComponentByPosition(1, 'b').setComponentByPosition(2, 1) + + def testSetToDefault(self): + s = self.s1.clone() + s.setComponentByPosition(0, univ.noValue) + s[2] = univ.noValue + assert s[0] == univ.OctetString('') + assert s[2] == univ.Integer(34) + + def testIter(self): + assert list(self.s1) == ['name', 'nick', 'age'] + + def testKeys(self): + self.s1.setComponentByPosition(0, univ.OctetString('abc')) + self.s1.setComponentByPosition(1, univ.OctetString('def')) + self.s1.setComponentByPosition(2, univ.Integer(123)) + assert list(self.s1.keys()) == ['name', 'nick', 'age'] + + def testValues(self): + self.s1.setComponentByPosition(0, univ.OctetString('abc')) + self.s1.setComponentByPosition(1, univ.OctetString('def')) + self.s1.setComponentByPosition(2, univ.Integer(123)) + assert list(self.s1.values()) == [str2octs('abc'), str2octs('def'), 123] + + def testItems(self): + self.s1.setComponentByPosition(0, univ.OctetString('abc')) + self.s1.setComponentByPosition(1, univ.OctetString('def')) + self.s1.setComponentByPosition(2, univ.Integer(123)) + assert list(self.s1.items()) == [(x[0], str2octs(x[1])) for x in [('name', 'abc'), ('nick', 'def')]] + [('age', 123)] + + def testUpdate(self): + self.s1.clear() + assert list(self.s1.values()) == [None, None, None] + self.s1.update(**{'name': 'abc', 'nick': 'def', 'age': 123}) + assert list(self.s1.items()) == [(x[0], str2octs(x[1])) for x in [('name', 'abc'), ('nick', 'def')]] + [('age', 123)] + self.s1.update(('name', 'ABC')) + assert list(self.s1.items()) == [(x[0], str2octs(x[1])) for x in [('name', 'ABC'), ('nick', 'def')]] + [('age', 123)] + self.s1.update(name='CBA') + assert list(self.s1.items()) == [(x[0], str2octs(x[1])) for x in [('name', 'CBA'), ('nick', 'def')]] + [('age', 123)] + + +class SetOf(unittest.TestCase): + def setUp(self): + self.s1 = univ.SetOf(componentType=univ.OctetString('')) + + def testTag(self): + assert self.s1.getTagSet() == tag.TagSet( + (), + tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11) + ), 'wrong tagSet' + + def testSeq(self): + self.s1.setComponentByPosition(0, univ.OctetString('abc')) + assert self.s1[0] == str2octs('abc'), 'set by idx fails' + self.s1.setComponentByPosition(0, self.s1[0].clone('cba')) + assert self.s1[0] == str2octs('cba'), 'set by idx fails' + + +class Set(unittest.TestCase): + def setUp(self): + self.s1 = univ.Set(componentType=namedtype.NamedTypes( + namedtype.NamedType('name', univ.OctetString('')), + namedtype.OptionalNamedType('null', univ.Null('')), + namedtype.DefaultedNamedType('age', univ.Integer(34)) + )) + self.s2 = self.s1.clone() + + def testTag(self): + assert self.s1.getTagSet() == tag.TagSet( + (), + tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11) + ), 'wrong tagSet' + + def testByTypeWithPythonValue(self): + self.s1.setComponentByType(univ.OctetString.tagSet, 'abc') + assert self.s1.getComponentByType( + univ.OctetString.tagSet + ) == str2octs('abc'), 'set by name fails' + + def testByTypeWithInstance(self): + self.s1.setComponentByType(univ.OctetString.tagSet, univ.OctetString('abc')) + assert self.s1.getComponentByType( + univ.OctetString.tagSet + ) == str2octs('abc'), 'set by name fails' + + def testGetTagMap(self): + assert self.s1.getTagMap().getPosMap() == { + univ.Set.tagSet: univ.Set() + } + + def testGetComponentTagMap(self): + assert self.s1.getComponentTagMap().getPosMap() == { + univ.OctetString.tagSet: univ.OctetString(''), + univ.Null.tagSet: univ.Null(''), + univ.Integer.tagSet: univ.Integer(34) + } + + def testGetPositionByType(self): + assert self.s1.getComponentPositionByType( + univ.Null().getTagSet() + ) == 1 + + def testSetToDefault(self): + self.s1.setComponentByName('name', univ.noValue) + assert self.s1['name'] == univ.OctetString('') + + def testIter(self): + assert list(self.s1) == ['name', 'null', 'age'] + + +class Choice(unittest.TestCase): + def setUp(self): + innerComp = univ.Choice(componentType=namedtype.NamedTypes( + namedtype.NamedType('count', univ.Integer()), + namedtype.NamedType('flag', univ.Boolean()) + )) + self.s1 = univ.Choice(componentType=namedtype.NamedTypes( + namedtype.NamedType('name', univ.OctetString()), + namedtype.NamedType('sex', innerComp) + )) + + def testTag(self): + assert self.s1.getTagSet() == tag.TagSet(), 'wrong tagSet' + + def testRepr(self): + assert eval(repr(self.s1.clone().setComponents('a')), + {'Choice': univ.Choice, 'OctetString': univ.OctetString, 'Integer': univ.Integer, + 'Boolean': univ.Boolean, 'NamedTypes': namedtype.NamedTypes, + 'NamedType': namedtype.NamedType}) == self.s1.clone().setComponents('a'), 'repr() fails' + assert eval(repr(self.s1.clone().setComponents( + sex=self.s1.setComponentByPosition(1).getComponentByPosition(1).clone().setComponents( + count=univ.Integer(123)))), + {'Choice': univ.Choice, 'OctetString': univ.OctetString, 'Integer': univ.Integer, + 'Boolean': univ.Boolean, 'NamedTypes': namedtype.NamedTypes, + 'NamedType': namedtype.NamedType}) == self.s1.clone().setComponents( + sex=self.s1.setComponentByPosition(1).getComponentByPosition(1).clone().setComponents( + count=univ.Integer(123))), 'repr() fails' + + def testContains(self): + self.s1.setComponentByType(univ.OctetString.tagSet, 'abc') + assert 'name' in self.s1 + assert 'sex' not in self.s1 + + self.s1.setComponentByType(univ.Integer.tagSet, 123, innerFlag=True) + assert 'name' not in self.s1 + assert 'sex' in self.s1 + + def testIter(self): + self.s1.setComponentByType(univ.OctetString.tagSet, 'abc') + assert list(self.s1) == ['name'] + self.s1.setComponentByType(univ.Integer.tagSet, 123, innerFlag=True) + assert list(self.s1) == ['sex'] + + def testOuterByTypeWithPythonValue(self): + self.s1.setComponentByType(univ.OctetString.tagSet, 'abc') + assert self.s1.getComponentByType( + univ.OctetString.tagSet + ) == str2octs('abc') + + def testOuterByTypeWithInstanceValue(self): + self.s1.setComponentByType( + univ.OctetString.tagSet, univ.OctetString('abc') + ) + assert self.s1.getComponentByType( + univ.OctetString.tagSet + ) == str2octs('abc') + + def testInnerByTypeWithPythonValue(self): + self.s1.setComponentByType(univ.Integer.tagSet, 123, innerFlag=True) + assert self.s1.getComponentByType( + univ.Integer.tagSet, 1 + ) == 123 + + def testInnerByTypeWithInstanceValue(self): + self.s1.setComponentByType( + univ.Integer.tagSet, univ.Integer(123), innerFlag=True + ) + assert self.s1.getComponentByType( + univ.Integer.tagSet, 1 + ) == 123 + + def testCmp(self): + self.s1.setComponentByName('name', univ.OctetString('abc')) + assert self.s1 == str2octs('abc'), '__cmp__() fails' + + def testGetComponent(self): + self.s1.setComponentByType(univ.OctetString.tagSet, 'abc') + assert self.s1.getComponent() == str2octs('abc'), 'getComponent() fails' + + def testGetName(self): + self.s1.setComponentByType(univ.OctetString.tagSet, 'abc') + assert self.s1.getName() == 'name', 'getName() fails' + + def testSetComponentByPosition(self): + self.s1.setComponentByPosition(0, univ.OctetString('Jim')) + assert self.s1 == str2octs('Jim') + + def testClone(self): + self.s1.setComponentByPosition(0, univ.OctetString('abc')) + s = self.s1.clone() + assert len(s) == 0 + s = self.s1.clone(cloneValueFlag=1) + assert len(s) == 1 + assert s.getComponentByPosition(0) == self.s1.getComponentByPosition(0) + + def testSetToDefault(self): + s = self.s1.clone() + s.setComponentByName('sex', univ.noValue) + assert s['sex'] is not univ.noValue + + +suite = unittest.TestLoader().loadTestsFromModule(sys.modules[__name__]) + +if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(suite)
\ No newline at end of file |