]> Cypherpunks.ru repositories - pyderasn.git/blobdiff - tests/test_pyderasn.py
Raise copyright years
[pyderasn.git] / tests / test_pyderasn.py
index f48548ecfb925a1368917b0aacf6dc9c57147336..e8f8bdf4570e1c52adbf2b7a7c5a827c47a2099c 100644 (file)
@@ -1,6 +1,6 @@
 # coding: utf-8
 # PyDERASN -- Python ASN.1 DER/CER/BER codec with abstract structures
-# Copyright (C) 2017-2021 Sergey Matveev <stargrave@stargrave.org>
+# Copyright (C) 2017-2024 Sergey Matveev <stargrave@stargrave.org>
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Lesser General Public License as
@@ -32,6 +32,7 @@ from string import whitespace
 from time import mktime
 from time import time
 from unittest import TestCase
+from unittest.mock import patch
 
 from dateutil.tz import UTC
 from hypothesis import assume
@@ -678,7 +679,7 @@ class TestBoolean(CommonMixin, TestCase):
             repr(obj)
             list(obj.pps())
 
-    @given(integers(min_value=2))
+    @given(integers(min_value=2, max_value=10))
     def test_invalid_len(self, l):
         with self.assertRaises(InvalidLength):
             Boolean().decode(b"".join((
@@ -1271,6 +1272,8 @@ def bit_string_values_strategy(draw, schema=None, value_required=False, do_expl=
         if generation_choice == 2 or draw(booleans()):
             return draw(binary(max_size=len(schema) // 8))
         if generation_choice == 3 or draw(booleans()):
+            if len(schema) == 0:
+                return ()
             return tuple(draw(lists(sampled_from([name for name, _ in schema]))))
         return None
     value = _value(value_required)
@@ -2213,8 +2216,18 @@ class TestOctetString(CommonMixin, TestCase):
         integers(min_value=0),
         binary(max_size=5),
         decode_path_strat,
+        booleans(),
     )
-    def test_symmetric(self, values, value, tag_expl, offset, tail_junk, decode_path):
+    def test_symmetric(
+            self,
+            values,
+            value,
+            tag_expl,
+            offset,
+            tail_junk,
+            decode_path,
+            keep_memoryview,
+    ):
         for klass in (OctetString, OctetStringInherited):
             _, _, _, _, default, optional, _decoded = values
             obj = klass(
@@ -2242,6 +2255,7 @@ class TestOctetString(CommonMixin, TestCase):
                 obj_expled.decod(obj_expled_cer, ctx={"bered": True}).encode(),
                 obj_expled_encoded,
             )
+            ctx_dummy["keep_memoryview"] = keep_memoryview
             ctx_copied = deepcopy(ctx_dummy)
             obj_decoded, tail = obj_expled.decode(
                 obj_expled_encoded + tail_junk,
@@ -2257,6 +2271,10 @@ class TestOctetString(CommonMixin, TestCase):
             self.assertNotEqual(obj_decoded, obj)
             self.assertEqual(bytes(obj_decoded), bytes(obj_expled))
             self.assertEqual(bytes(obj_decoded), bytes(obj))
+            self.assertIsInstance(
+                obj_decoded._value,
+                memoryview if keep_memoryview else bytes,
+            )
             self.assertSequenceEqual(obj_decoded.encode(), obj_expled_encoded)
             self.assertSequenceEqual(obj_decoded.expl_tag, tag_expl)
             self.assertEqual(obj_decoded.expl_tlen, len(tag_expl))
@@ -2677,8 +2695,8 @@ def oid_strategy(draw):
     if first_arc in (0, 1):
         second_arc = draw(integers(min_value=0, max_value=39))
     else:
-        second_arc = draw(integers(min_value=0))
-    other_arcs = draw(lists(integers(min_value=0)))
+        second_arc = draw(integers(min_value=0, max_value=1 << 63))
+    other_arcs = draw(lists(integers(min_value=0, max_value=1 << 63)))
     return tuple([first_arc, second_arc] + other_arcs)
 
 
@@ -2909,21 +2927,27 @@ class TestObjectIdentifier(CommonMixin, TestCase):
         with self.assertRaisesRegex(DecodeError, "unfinished OID"):
             obj.decode(data)
 
-    @given(integers(min_value=0))
+    @given(integers(min_value=0, max_value=1 << 63))
     def test_invalid_short(self, value):
         with self.assertRaises(InvalidOID):
             ObjectIdentifier((value,))
         with self.assertRaises(InvalidOID):
             ObjectIdentifier("%d" % value)
 
-    @given(integers(min_value=3), integers(min_value=0))
+    @given(
+        integers(min_value=3, max_value=1 << 63),
+        integers(min_value=0, max_value=1 << 63),
+    )
     def test_invalid_first_arc(self, first_arc, second_arc):
         with self.assertRaises(InvalidOID):
             ObjectIdentifier((first_arc, second_arc))
         with self.assertRaises(InvalidOID):
             ObjectIdentifier("%d.%d" % (first_arc, second_arc))
 
-    @given(integers(min_value=0, max_value=1), integers(min_value=40))
+    @given(
+        integers(min_value=0, max_value=1),
+        integers(min_value=40, max_value=1 << 63),
+    )
     def test_invalid_second_arc(self, first_arc, second_arc):
         with self.assertRaises(InvalidOID):
             ObjectIdentifier((first_arc, second_arc))
@@ -5062,6 +5086,14 @@ class TestUTCTime(TimeMixin, CommonMixin, TestCase):
         with self.assertRaisesRegex(ValueError, "only naive"):
             UTCTime(datetime(2000, 1, 1, 1, tzinfo=UTC))
 
+    def test_raises_if_no_dateutil(self):
+        with patch("pyderasn.tzUTC", new="missing"):
+            with self.assertRaisesRegex(NotImplementedError, "dateutil"):
+                UTCTime(datetime.now()).totzdatetime()
+
+    def test_tzinfo_gives_datetime_with_tzutc_tzinfo(self):
+        self.assertEqual(UTCTime(datetime.now()).totzdatetime().tzinfo, UTC)
+
 
 @composite
 def tlv_value_strategy(draw):
@@ -5250,8 +5282,18 @@ class TestAny(CommonMixin, TestCase):
         integers(min_value=0),
         binary(max_size=5),
         decode_path_strat,
+        booleans(),
     )
-    def test_symmetric(self, values, value, tag_expl, offset, tail_junk, decode_path):
+    def test_symmetric(
+            self,
+            values,
+            value,
+            tag_expl,
+            offset,
+            tail_junk,
+            decode_path,
+            keep_memoryview,
+    ):
         for klass in (Any, AnyInherited):
             _, _, optional, _decoded = values
             obj = klass(value=value, optional=optional, _decoded=_decoded)
@@ -5271,6 +5313,7 @@ class TestAny(CommonMixin, TestCase):
             list(obj_expled.pps())
             pprint(obj_expled, big_blobs=True, with_decode_path=True)
             obj_expled_encoded = obj_expled.encode()
+            ctx_dummy["keep_memoryview"] = keep_memoryview
             ctx_copied = deepcopy(ctx_dummy)
             obj_decoded, tail = obj_expled.decode(
                 obj_expled_encoded + tail_junk,
@@ -5285,6 +5328,10 @@ class TestAny(CommonMixin, TestCase):
             self.assertEqual(obj_decoded, obj_expled)
             self.assertEqual(bytes(obj_decoded), bytes(obj_expled))
             self.assertEqual(bytes(obj_decoded), bytes(obj))
+            self.assertIsInstance(
+                obj_decoded._value,
+                memoryview if keep_memoryview else bytes,
+            )
             self.assertSequenceEqual(obj_decoded.encode(), obj_expled_encoded)
             self.assertSequenceEqual(obj_decoded.expl_tag, tag_expl)
             self.assertEqual(obj_decoded.expl_tlen, len(tag_expl))
@@ -5937,7 +5984,7 @@ def sequences_strategy(draw, seq_klass):
     return seq_outer, expect_outers
 
 
-class SeqMixing(object):
+class SeqMixin(object):
     def test_invalid_value_type(self):
         with self.assertRaises(InvalidValueType) as err:
             self.base_klass(123)
@@ -6451,7 +6498,7 @@ class SeqMixing(object):
         self.assertTrue(decoded.bered)
 
 
-class TestSequence(SeqMixing, CommonMixin, TestCase):
+class TestSequence(SeqMixin, CommonMixin, TestCase):
     base_klass = Sequence
 
     @given(
@@ -6497,7 +6544,7 @@ class TestSequence(SeqMixing, CommonMixin, TestCase):
         self.assertEqual(seq["ok"], True)
 
 
-class TestSet(SeqMixing, CommonMixin, TestCase):
+class TestSet(SeqMixin, CommonMixin, TestCase):
     base_klass = Set
 
     @settings(max_examples=LONG_TEST_MAX_EXAMPLES)
@@ -6612,7 +6659,7 @@ def seqof_values_strategy(draw, schema=None, do_expl=False):
     )
 
 
-class SeqOfMixing(object):
+class SeqOfMixin(object):
     def test_invalid_value_type(self):
         with self.assertRaises(InvalidValueType) as err:
             self.base_klass(123)
@@ -6714,7 +6761,7 @@ class SeqOfMixing(object):
             schema = Boolean()
         bound_min = d.draw(integers(min_value=1, max_value=1 << 7))
         bound_max = d.draw(integers(min_value=bound_min, max_value=1 << 7))
-        value = [Boolean(False)] * d.draw(integers(max_value=bound_min - 1))
+        value = [Boolean(False)] * d.draw(integers(min_value=0, max_value=bound_min - 1))
         with self.assertRaises(BoundsError) as err:
             SeqOf(value=value, bounds=(bound_min, bound_max))
         repr(err.exception)
@@ -7082,7 +7129,7 @@ class SeqOfMixing(object):
         self.assertTrue(decoded.bered)
 
 
-class TestSequenceOf(SeqOfMixing, CommonMixin, TestCase):
+class TestSequenceOf(SeqOfMixin, CommonMixin, TestCase):
     class SeqOf(SequenceOf):
         schema = "whatever"
     base_klass = SeqOf
@@ -7166,7 +7213,7 @@ class TestSequenceOf(SeqOfMixing, CommonMixin, TestCase):
         self.assertFalse(seqof.ready)
 
 
-class TestSetOf(SeqOfMixing, CommonMixin, TestCase):
+class TestSetOf(SeqOfMixin, CommonMixin, TestCase):
     class SeqOf(SetOf):
         schema = "whatever"
     base_klass = SeqOf
@@ -7419,7 +7466,11 @@ class TestPP(TestCase):
     def test_oid_printing(self, d):
         oids = {
             str(ObjectIdentifier(k)): v * 2
-            for k, v in d.draw(dictionaries(oid_strategy(), text_letters())).items()
+            for k, v in d.draw(dictionaries(
+                oid_strategy(),
+                text_letters(),
+                min_size=1,
+            )).items()
         }
         chosen = d.draw(sampled_from(sorted(oids)))
         chosen_id = oids[chosen]