from copy import copy
from copy import deepcopy
from datetime import datetime
+from datetime import timedelta
from importlib import import_module
+from os import environ
+from random import random
from string import ascii_letters
from string import digits
from string import printable
from string import whitespace
+from time import mktime
from time import time
from unittest import TestCase
from pyderasn import VisibleString
+max_examples = environ.get("MAX_EXAMPLES")
settings.register_profile("local", settings(
deadline=5000,
+ **({"max_examples": int(max_examples)} if max_examples else {})
))
settings.load_profile("local")
LONG_TEST_MAX_EXAMPLES = settings().max_examples * 4
def assert_exceeding_data(self, call, junk):
- if len(junk) > 0:
- with assertRaisesRegex(self, ExceedingData, "%d trailing bytes" % len(junk)):
- call()
+ if len(junk) <= 0:
+ return
+ with assertRaisesRegex(self, ExceedingData, "%d trailing bytes" % len(junk)) as err:
+ call()
+ repr(err)
class TestHex(TestCase):
self.assertSequenceEqual(obj.impl, impl_tag)
self.assertFalse(obj.expled)
- @given(binary())
+ @given(binary(min_size=1))
def test_expl_inherited(self, expl_tag):
class Inherited(self.base_klass):
expl = expl_tag
list(obj.pps())
pprint(obj, big_blobs=True, with_decode_path=True)
- @given(booleans(), booleans(), binary(), binary())
+ @given(booleans(), booleans(), binary(min_size=1), binary(min_size=1))
def test_comparison(self, value1, value2, tag1, tag2):
for klass in (Boolean, BooleanInherited):
obj1 = klass(value1)
pprint(obj, big_blobs=True, with_decode_path=True)
hash(obj)
- @given(integers(), integers(), binary(), binary())
+ @given(integers(), integers(), binary(min_size=1), binary(min_size=1))
def test_comparison(self, value1, value2, tag1, tag2):
for klass in (Integer, IntegerInherited):
obj1 = klass(value1)
self.assertEqual(obj.lenindef, lenindef_expected)
self.assertTrue(obj.bered)
self.assertEqual(len(encoded), obj.tlvlen)
+ repr(obj)
+ list(obj.pps())
+ pprint(obj, big_blobs=True, with_decode_path=True)
@given(
integers(min_value=0),
self.assertEqual(obj.lenindef, lenindef_expected)
self.assertTrue(obj.bered)
self.assertEqual(len(encoded), obj.tlvlen)
+ repr(obj)
+ list(obj.pps())
+ pprint(obj, big_blobs=True, with_decode_path=True)
@given(
integers(min_value=0),
list(obj.pps())
pprint(obj, big_blobs=True, with_decode_path=True)
- @given(binary(), binary())
+ @given(binary(min_size=1), binary(min_size=1))
def test_comparison(self, tag1, tag2):
for klass in (Null, NullInherited):
obj1 = klass(impl=tag1)
pprint(obj, big_blobs=True, with_decode_path=True)
hash(obj)
- @given(oid_strategy(), oid_strategy(), binary(), binary())
+ @given(oid_strategy(), oid_strategy(), binary(min_size=1), binary(min_size=1))
def test_comparison(self, value1, value2, tag1, tag2):
for klass in (ObjectIdentifier, ObjectIdentifierInherited):
obj1 = klass(value1)
list(obj.pps())
pprint(obj, big_blobs=True, with_decode_path=True)
- @given(integers(), integers(), binary(), binary())
+ @given(integers(), integers(), binary(min_size=1), binary(min_size=1))
def test_comparison(self, value1, value2, tag1, tag2):
class E(Enumerated):
schema = (
if value.microsecond > 0:
self.assertFalse(obj_encoded.endswith(b"0Z"))
+ def test_repr_not_ready(self):
+ unicode(GeneralizedTime()) if PY2 else str(GeneralizedTime())
+ repr(GeneralizedTime())
+
def test_x690_vector_valid(self):
for data in ((
b"19920521000000Z",
datetime(2010, 1, 2, 3, 4, 5, 0),
)
+ def test_go_vectors_valid_ber(self):
+ for data in ((
+ b"20100102030405+0607",
+ b"20100102030405-0607",
+ )):
+ GeneralizedTime(data, ctx={"bered": True})
+
+ def test_utc_offsets(self):
+ """Some know equal UTC offsets
+ """
+ dts = [
+ GeneralizedTime(data.encode("ascii"), ctx={"bered": True})
+ for data in (
+ "200101011830Z",
+ "200101012230+04",
+ "200101011130-0700",
+ "200101011500-03:30",
+ )
+ ]
+ self.assertEqual(dts[0], dts[1])
+ self.assertEqual(dts[0], dts[2])
+ self.assertEqual(dts[0], dts[3])
+
+ @settings(max_examples=LONG_TEST_MAX_EXAMPLES)
+ @given(data_strategy())
+ def test_valid_ber(self, d):
+ min_year = 1901 if PY2 else 2
+ year = d.draw(integers(min_value=min_year, max_value=9999))
+ month = d.draw(integers(min_value=1, max_value=12))
+ day = d.draw(integers(min_value=1, max_value=28))
+ hours = d.draw(integers(min_value=0, max_value=23))
+ data = "%04d%02d%02d%02d" % (year, month, day, hours)
+ dt = datetime(year, month, day, hours)
+ fractions_sign = d.draw(sampled_from(" ,."))
+ fractions = None
+ if fractions_sign != " ":
+ fractions = random()
+ if d.draw(booleans()):
+ minutes = d.draw(integers(min_value=0, max_value=59))
+ data += "%02d" % minutes
+ dt += timedelta(seconds=60 * minutes)
+ if d.draw(booleans()):
+ seconds = d.draw(integers(min_value=0, max_value=59))
+ data += "%02d" % seconds
+ dt += timedelta(seconds=seconds)
+ if fractions is not None:
+ dt += timedelta(microseconds=10**6 * fractions)
+ elif fractions is not None:
+ dt += timedelta(seconds=60 * fractions)
+ elif fractions is not None:
+ dt += timedelta(seconds=3600 * fractions)
+ if fractions is not None:
+ data += fractions_sign + str(fractions)[2:]
+ if d.draw(booleans()):
+ data += "Z"
+ elif d.draw(booleans()):
+ offset_hour = d.draw(integers(min_value=0, max_value=13))
+ sign = 1
+ if d.draw(booleans()):
+ data += "-"
+ sign = -1
+ else:
+ data += "+"
+ dt -= timedelta(seconds=sign * 3600 * offset_hour)
+ data += "%02d" % offset_hour
+ minutes_separator = d.draw(sampled_from((None, "", ":")))
+ if minutes_separator is not None:
+ offset_minute = d.draw(integers(min_value=0, max_value=59))
+ dt -= timedelta(seconds=sign * 60 * offset_minute)
+ data += "%s%02d" % (minutes_separator, offset_minute)
+ data = data.encode("ascii")
+ data_der = GeneralizedTime.tag_default + len_encode(len(data)) + data
+ try:
+ GeneralizedTime().decod(data_der)
+ except DecodeError:
+ dered = False
+ else:
+ dered = True
+ obj = GeneralizedTime().decod(data_der, ctx={"bered": True})
+ if dt.year > 1970:
+ self.assertEqual(
+ mktime(obj.todatetime().timetuple()),
+ mktime(dt.timetuple()),
+ )
+ elif not PY2:
+ self.assertEqual(obj.todatetime().timestamp(), dt.timestamp())
+ self.assertEqual(obj.ber_encoded, not dered)
+ self.assertEqual(obj.bered, not dered)
+ self.assertEqual(obj.ber_raw, None if dered else data)
+ self.assertEqual(obj.encode() == data_der, dered)
+ repr(obj)
+ bytes(obj)
+ str(obj)
+
+ def test_invalid_ber(self):
+ for data in ((
+ # "00010203040506.07",
+ "-0010203040506.07",
+ "0001-203040506.07",
+ "000102-3040506.07",
+ "00010203-40506.07",
+ "0001020304-506.07",
+ "000102030405-6.07",
+ "00010203040506.-7",
+ "+0010203040506.07",
+ "0001+203040506.07",
+ "000102+3040506.07",
+ "00010203+40506.07",
+ "0001020304+506.07",
+ "000102030405+6.07",
+ "00010203040506.+7",
+ " 0010203040506.07",
+ "0001 203040506.07",
+ "000102 3040506.07",
+ "00010203 40506.07",
+ "0001020304 506.07",
+ "000102030405 6.07",
+ "00010203040506. 7",
+ "001 0203040506.07",
+ "00012 03040506.07",
+ "0001023 040506.07",
+ "000102034 0506.07",
+ "00010203045 06.07",
+ "0001020304056 .07",
+ "00010203040506.7 ",
+ "00010203040506.",
+ "0001020304050607",
+
+ "-0010203040506",
+ "0001-203040506",
+ "000102-3040506",
+ "00010203-40506",
+ "0001020304-506",
+ "000102030405-6",
+ "0001+203040506",
+ "000102+3040506",
+ "00010203+40506",
+ "0001020304+506",
+ "000102030405+6",
+ " 0010203040506",
+ "0001 203040506",
+ "000102 3040506",
+ "00010203 40506",
+ "0001020304 506",
+ "000102030405 6",
+ "001 0203040506",
+ "00012 03040506",
+ "0001023 040506",
+ "000102034 0506",
+ "00010203045 06",
+ "0001020304056 ",
+
+ "-00102030405.07",
+ "0001-2030405.07",
+ "000102-30405.07",
+ "00010203-405.07",
+ "0001020304-5.07",
+ "000102030405.-7",
+ "+00102030405.07",
+ "0001+2030405.07",
+ "00010203+405.07",
+ "0001020304+5.07",
+ "000102030405.+7",
+ " 00102030405.07",
+ "0001 2030405.07",
+ "000102 30405.07",
+ "00010203 405.07",
+ "0001020304 5.07",
+ "000102030405. 7",
+ "001 02030405.07",
+ "00012 030405.07",
+ "0001023 0405.07",
+ "000102034 05.07",
+ "00010203045 .07",
+ "000102030405.7 ",
+ "000102030405.",
+
+ "-001020304.07",
+ "0001-20304.07",
+ "000102-304.07",
+ "00010203-4.07",
+ "0001020304.-7",
+ "+001020304.07",
+ "0001+20304.07",
+ "00010203+4.07",
+ "0001020304.+7",
+ " 001020304.07",
+ "0001 20304.07",
+ "000102 304.07",
+ "00010203 4.07",
+ "0001020304. 7",
+ "001 020304.07",
+ "00012 0304.07",
+ "0001023 04.07",
+ "000102034 .07",
+ "0001020304.7 ",
+ "0001020304.",
+
+ "00010203",
+ "00010203040506Y",
+ "0001010100+0001",
+ "0001010100+00:01",
+ "0001010100+01",
+
+ "00010203040506.07+15",
+ "00010203040506.07-15",
+ "00010203040506.07+14:60",
+ "00010203040506.07+1460",
+ "00010203040506.07-1460",
+ "00010203040506.07+00:60",
+ "00010203040506.07-00:60",
+
+ "00010203040506+15",
+ "00010203040506-15",
+ "00010203040506+14:60",
+ "00010203040506+1460",
+ "00010203040506-1460",
+ "00010203040506+00:60",
+ "00010203040506-00:60",
+
+ "0001020304050.07",
+ "00010203040.07",
+ "000102030.07",
+ "0001020304050",
+ "00010203040",
+ "000102030",
+ )):
+ with self.assertRaises(DecodeError):
+ GeneralizedTime(data.encode("ascii"), ctx={"bered": True})
+ data = data.replace(".", ",")
+ with self.assertRaises(DecodeError):
+ GeneralizedTime(data.encode("ascii"), ctx={"bered": True})
+
@given(
binary(
min_size=(LEN_YYYYMMDDHHMMSSZ - 1) // 2,
with assertRaisesRegex(self, DecodeError, "only microsecond fractions"):
GeneralizedTime(b"20010101000000.0000001Z")
+ def test_non_pure_integers(self):
+ for data in ((
+ # b"20000102030405Z,
+ b"+2000102030405Z",
+ b"2000+102030405Z",
+ b"200001+2030405Z",
+ b"20000102+30405Z",
+ b"2000010203+405Z",
+ b"200001020304+5Z",
+ b"20000102030405.+6Z",
+ b"20000102030405.-6Z",
+ b"_2000102030405Z",
+ b"2000_102030405Z",
+ b"200001_2030405Z",
+ b"20000102_30405Z",
+ b"2000010203_405Z",
+ b"200001020304_5Z",
+ b"20000102030405._6Z",
+ b"20000102030405.6_Z",
+ b" 2000102030405Z",
+ b"2000 102030405Z",
+ b"200001 2030405Z",
+ b"20000102 30405Z",
+ b"2000010203 405Z",
+ b"200001020304 5Z",
+ b"20000102030405. 6Z",
+ b"200 0102030405Z",
+ b"20001 02030405Z",
+ b"2000012 030405Z",
+ b"200001023 0405Z",
+ b"20000102034 05Z",
+ b"2000010203045 Z",
+ b"20000102030405.6 Z",
+ )):
+ with self.assertRaises(DecodeError):
+ GeneralizedTime(data)
+
class TestUTCTime(TimeMixin, CommonMixin, TestCase):
base_klass = UTCTime
def additional_symmetric_check(self, value, obj_encoded):
pass
+ def test_repr_not_ready(self):
+ unicode(GeneralizedTime()) if PY2 else str(GeneralizedTime())
+ repr(UTCTime())
+
def test_x690_vector_valid(self):
for data in ((
b"920521000000Z",
datetime(1991, 5, 6, 23, 45, 40, 0),
)
+ def test_non_pure_integers(self):
+ for data in ((
+ # b"000102030405Z",
+ b"+10102030405Z",
+ b"00+102030405Z",
+ b"0001+2030405Z",
+ b"000102+30405Z",
+ b"00010203+405Z",
+ b"0001020304+5Z",
+ b"_10102030405Z",
+ b"00_102030405Z",
+ b"0001_2030405Z",
+ b"000102_30405Z",
+ b"00010203_405Z",
+ b"0001020304_5Z",
+ b"00010203045_Z",
+ b" 10102030405Z",
+ b"00 102030405Z",
+ b"0001 2030405Z",
+ b"000102 30405Z",
+ b"00010203 405Z",
+ b"0001020304 5Z",
+ b"1 0102030405Z",
+ b"001 02030405Z",
+ b"00012 030405Z",
+ b"0001023 0405Z",
+ b"000102034 05Z",
+ b"00010203045 Z",
+ )):
+ with self.assertRaises(DecodeError):
+ UTCTime(data)
+
+ def test_x680_vector_valid_ber(self):
+ for data, dt in ((
+ (b"8201021200Z", datetime(1982, 1, 2, 12)),
+ (b"8201020700-0500", datetime(1982, 1, 2, 12)),
+ (b"0101021200Z", datetime(2001, 1, 2, 12)),
+ (b"0101020700-0500", datetime(2001, 1, 2, 12)),
+ )):
+ data_der = UTCTime.tag_default + len_encode(len(data)) + data
+ obj = UTCTime().decod(data_der, ctx={"bered": True})
+ self.assertEqual(obj, dt)
+ self.assertEqual(obj.todatetime(), dt)
+ self.assertTrue(obj.ber_encoded)
+ self.assertTrue(obj.bered)
+ self.assertEqual(obj.ber_raw, data)
+ self.assertNotEqual(obj.encode(), data_der)
+ repr(obj)
+
+ def test_go_vectors_valid_ber(self):
+ for data in ((
+ b"910506164540-0700",
+ b"910506164540+0730",
+ b"9105062345Z",
+ b"5105062345Z",
+ )):
+ data = UTCTime.tag_default + len_encode(len(data)) + data
+ obj = UTCTime().decod(data, ctx={"bered": True})
+ self.assertTrue(obj.ber_encoded)
+ self.assertTrue(obj.bered)
+ self.assertNotEqual(obj.encode(), data)
+ repr(obj)
+
+ @settings(max_examples=LONG_TEST_MAX_EXAMPLES)
+ @given(data_strategy())
+ def test_valid_ber(self, d):
+ year = d.draw(integers(min_value=0, max_value=99))
+ month = d.draw(integers(min_value=1, max_value=12))
+ day = d.draw(integers(min_value=1, max_value=28))
+ hours = d.draw(integers(min_value=0, max_value=23))
+ minute = d.draw(integers(min_value=0, max_value=59))
+ data = "%02d%02d%02d%02d%02d" % (year, month, day, hours, minute)
+ dt = datetime(
+ year + (2000 if year < 50 else 1900),
+ month,
+ day,
+ hours,
+ minute,
+ )
+ dered = False
+ if d.draw(booleans()):
+ dered = True
+ seconds = d.draw(integers(min_value=0, max_value=59))
+ data += "%02d" % seconds
+ dt += timedelta(seconds=seconds)
+ if d.draw(booleans()):
+ data += "Z"
+ else:
+ dered = False
+ offset_hour = d.draw(integers(min_value=0, max_value=13))
+ offset_minute = d.draw(integers(min_value=0, max_value=59))
+ offset = timedelta(seconds=offset_hour * 3600 + offset_minute * 60)
+ if d.draw(booleans()):
+ dt += offset
+ data += "-"
+ else:
+ dt -= offset
+ data += "+"
+ data += "%02d%02d" % (offset_hour, offset_minute)
+ data = data.encode("ascii")
+ data_der = UTCTime.tag_default + len_encode(len(data)) + data
+ obj = UTCTime().decod(data_der, ctx={"bered": True})
+ self.assertEqual(obj, dt)
+ self.assertEqual(obj.todatetime(), dt)
+ self.assertEqual(obj.ber_encoded, not dered)
+ self.assertEqual(obj.bered, not dered)
+ self.assertEqual(obj.ber_raw, None if dered else data)
+ self.assertEqual(obj.encode() == data_der, dered)
+ repr(obj)
+ bytes(obj)
+ str(obj)
+
+ def test_invalid_ber(self):
+ for data in ((
+ # b"0001020304Z",
+ b"-101020304Z",
+ b"00-1020304Z",
+ b"0001-20304Z",
+ b"000102-304Z",
+ b"000102-104Z",
+ b"00000203-4Z",
+ b"+101020304Z",
+ b"00+1020304Z",
+ b"0001+20304Z",
+ b"000102+304Z",
+ b"000102+104Z",
+ b"00000203+4Z",
+ b" 101020304Z",
+ b"00 1020304Z",
+ b"0001 20304Z",
+ b"000102 304Z",
+ b"000102 104Z",
+ b"00000203 4Z",
+ b"1 01020304Z",
+ b"001 020304Z",
+ b"00012 0304Z",
+ b"0001023 04Z",
+ b"0001021 04Z",
+ b"000002034 Z",
+ b"0013020304Z",
+ b"0001000304Z",
+ b"0001320304Z",
+ b"0001022404Z",
+ b"0001020360Z",
+ b"0002300304Z",
+ b"0001020304",
+ b"0001020304T",
+ b"0001020304+",
+ b"0001020304-",
+ b"0001020304+0",
+ b"0001020304+00",
+ b"0001020304+000",
+ b"0001020304+000Z",
+ b"0001020304+0000Z",
+ b"0001020304+-101",
+ b"0001020304+01-1",
+ b"0001020304+0060",
+ b"0001020304+1401",
+ b"5001010000+0001",
+ b"000102030Z",
+ b"0001020Z",
+ )):
+ with self.assertRaises(DecodeError):
+ UTCTime(data, ctx={"bered": True})
+ data = data[:8] + data[8+2:]
+ with self.assertRaises(DecodeError):
+ UTCTime(data, ctx={"bered": True})
+
+ for data in ((
+ # b"000102030405Z",
+ b"-10102030405Z",
+ b"00-102030405Z",
+ b"0001-2030405Z",
+ b"000102-30405Z",
+ b"000102-10405Z",
+ b"00000203-405Z",
+ b"0000020304-5Z",
+ b"+10102030405Z",
+ b"00+102030405Z",
+ b"0001+2030405Z",
+ b"000102+30405Z",
+ b"000102+10405Z",
+ b"00000203+405Z",
+ b"0000020304+5Z",
+ b" 10102030405Z",
+ b"00 102030405Z",
+ b"0001 2030405Z",
+ b"000102 30405Z",
+ b"000102 10405Z",
+ b"00000203 405Z",
+ b"0000020304 5Z",
+ b"1 0102030405Z",
+ b"001 02030405Z",
+ b"00012 030405Z",
+ b"0001023 0405Z",
+ b"0001021 0405Z",
+ b"000002034 05Z",
+ b"00000203045 Z",
+ b"001302030405Z",
+ b"000100030405Z",
+ b"000132030405Z",
+ b"000102240405Z",
+ b"000102036005Z",
+ b"000230030405Z",
+ b"000102030460Z",
+ b"000102030405",
+ b"000102030405T",
+ b"000102030405+",
+ b"000102030405-",
+ b"000102030405+0",
+ b"000102030405+00",
+ b"000102030405+000",
+ b"000102030405+000Z",
+ b"000102030405+0000Z",
+ b"000102030405+-101",
+ b"000102030405+01-1",
+ b"000102030405+0060",
+ b"000102030405+1401",
+ b"500101000002+0003",
+ )):
+ with self.assertRaises(DecodeError):
+ UTCTime(data, ctx={"bered": True})
+
@given(integers(min_value=0, max_value=49))
def test_pre50(self, year):
self.assertEqual(
pprint(obj, big_blobs=True, with_decode_path=True)
self.assertSequenceEqual(obj.encode(), integer_encoded)
- @given(binary(), binary())
+ @given(binary(min_size=1), binary(min_size=1))
def test_comparison(self, value1, value2):
for klass in (Any, AnyInherited):
obj1 = klass(value1)
t, _, lv = tag_strip(seq_encoded)
_, _, v = len_decode(lv)
seq_encoded_lenindef = t + LENINDEF + v + EOC
+ with self.assertRaises(DecodeError):
+ seq.decode(seq_encoded_lenindef)
ctx_copied = deepcopy(ctx_dummy)
ctx_copied["bered"] = True
seq_decoded_lenindef, tail_lenindef = seq.decode(
min_size=1,
)).items())
tags = [tag_encode(tag) for tag in d.draw(sets(
- integers(min_value=0),
+ integers(min_value=1),
min_size=len(_schema),
max_size=len(_schema),
))]
def test_missing_from_spec(self, d):
names = list(d.draw(sets(text_letters(), min_size=2)))
tags = [tag_encode(tag) for tag in d.draw(sets(
- integers(min_value=0),
+ integers(min_value=1),
min_size=len(names),
max_size=len(names),
))]
with assertRaisesRegex(self, ValueError, "schema must be specified"):
self.base_klass.__mro__[1]()
- @given(booleans(), booleans(), binary(), binary())
+ @given(booleans(), booleans(), binary(min_size=1), binary(min_size=1))
def test_comparison(self, value1, value2, tag1, tag2):
class SeqOf(self.base_klass):
schema = Boolean()
t, _, lv = tag_strip(obj_encoded)
_, _, v = len_decode(lv)
obj_encoded_lenindef = t + LENINDEF + v + EOC
+ with self.assertRaises(DecodeError):
+ obj.decode(obj_encoded_lenindef)
obj_decoded_lenindef, tail_lenindef = obj.decode(
obj_encoded_lenindef + tail_junk,
ctx={"bered": True},
min_size=len(value_names),
max_size=len(value_names),
))
- _schema = [
- ("type", ObjectIdentifier(defines=(((value_name_chosen,), {
- oid: Integer() for oid in oids[:-1]
- }),))),
- ]
- for i, value_name in enumerate(value_names):
- _schema.append((value_name, Any(expl=tag_ctxp(i))))
+ for definable_class in (Any, OctetString, BitString):
+ _schema = [
+ ("type", ObjectIdentifier(defines=(((value_name_chosen,), {
+ oid: Integer() for oid in oids[:-1]
+ }),))),
+ ]
+ for i, value_name in enumerate(value_names):
+ _schema.append((value_name, definable_class(expl=tag_ctxp(i))))
- class Seq(Sequence):
- schema = _schema
- seq = Seq()
- for value_name, value in zip(value_names, values):
- seq[value_name] = Any(Integer(value).encode())
- seq["type"] = oid_chosen
- seq, _ = Seq().decode(seq.encode())
- for value_name in value_names:
- if value_name == value_name_chosen:
- continue
- self.assertIsNone(seq[value_name].defined)
- if value_name_chosen in oids[:-1]:
- self.assertIsNotNone(seq[value_name_chosen].defined)
- self.assertEqual(seq[value_name_chosen].defined[0], oid_chosen)
- self.assertIsInstance(seq[value_name_chosen].defined[1], Integer)
- repr(seq)
- list(seq.pps())
- pprint(seq, big_blobs=True, with_decode_path=True)
+ class Seq(Sequence):
+ schema = _schema
+ seq = Seq()
+ for value_name, value in zip(value_names, values):
+ seq[value_name] = definable_class(Integer(value).encode())
+ seq["type"] = oid_chosen
+ seq, _ = Seq().decode(seq.encode())
+ for value_name in value_names:
+ if value_name == value_name_chosen:
+ continue
+ self.assertIsNone(seq[value_name].defined)
+ if value_name_chosen in oids[:-1]:
+ self.assertIsNotNone(seq[value_name_chosen].defined)
+ self.assertEqual(seq[value_name_chosen].defined[0], oid_chosen)
+ self.assertIsInstance(seq[value_name_chosen].defined[1], Integer)
+ repr(seq)
+ list(seq.pps())
+ pprint(seq, big_blobs=True, with_decode_path=True)
class TestDefinesByPath(TestCase):
(type_integered, Integer(234)),
)
for t, v in pairs_input:
- pair = Pair()
- pair["type"] = t
- pair["value"] = PairValue((Any(v),))
- pairs.append(pair)
+ pairs.append(Pair((
+ ("type", t),
+ ("value", PairValue((Any(v),))),
+ )))
seq_inner = SeqInner()
seq_inner["typeInner"] = type_innered
seq_inner["valueInner"] = Any(pairs)
decoded, _ = Outer().decode(outer.encode())
self.assertEqual(decoded["tgt"].defined[1], Integer(tgt))
+ def test_remaining_data(self):
+ oid = ObjectIdentifier("1.2.3")
+ class Seq(Sequence):
+ schema = (
+ ("oid", ObjectIdentifier(defines=((("tgt",), {
+ oid: Integer(),
+ }),))),
+ ("tgt", OctetString()),
+ )
+
+ seq = Seq((
+ ("oid", oid),
+ ("tgt", OctetString(Integer(123).encode() + b"junk")),
+ ))
+ with assertRaisesRegex(self, DecodeError, "remaining data"):
+ Seq().decode(seq.encode())
+
+ def test_remaining_data_seqof(self):
+ oid = ObjectIdentifier("1.2.3")
+ class SeqOf(SetOf):
+ schema = OctetString()
+
+ class Seq(Sequence):
+ schema = (
+ ("oid", ObjectIdentifier(defines=((("tgt",), {
+ oid: Integer(),
+ }),))),
+ ("tgt", SeqOf()),
+ )
+
+ seq = Seq((
+ ("oid", oid),
+ ("tgt", SeqOf([OctetString(Integer(123).encode() + b"junk")])),
+ ))
+ with assertRaisesRegex(self, DecodeError, "remaining data"):
+ Seq().decode(seq.encode())
+
class TestAbsDecodePath(TestCase):
@given(
lists(text(alphabet=ascii_letters, min_size=1), min_size=1).map(tuple),
)
def test_concat(self, decode_path, rel_path):
- self.assertSequenceEqual(
- abs_decode_path(decode_path, rel_path),
- decode_path + rel_path,
- )
+ dp = abs_decode_path(decode_path, rel_path)
+ self.assertSequenceEqual(dp, decode_path + rel_path)
+ repr(dp)
@given(
lists(text(alphabet=ascii_letters, min_size=1)).map(tuple),