]> Cypherpunks.ru repositories - pyderasn.git/blobdiff - tests/test_pyderasn.py
Colourized output
[pyderasn.git] / tests / test_pyderasn.py
index 23127261feb9175309eea0f8b6e41356f0e7cf56..18ce656a109ca525104cd8a158b0a9aa33d830cc 100644 (file)
@@ -1,6 +1,6 @@
 # coding: utf-8
 # PyDERASN -- Python ASN.1 DER codec with abstract structures
 # coding: utf-8
 # PyDERASN -- Python ASN.1 DER codec with abstract structures
-# Copyright (C) 2017 Sergey Matveev <stargrave@stargrave.org>
+# Copyright (C) 2017-2018 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
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU Lesser General Public License as
@@ -50,14 +50,15 @@ from six import PY2
 from six import text_type
 
 from pyderasn import _pp
 from six import text_type
 
 from pyderasn import _pp
+from pyderasn import abs_decode_path
 from pyderasn import Any
 from pyderasn import BitString
 from pyderasn import BMPString
 from pyderasn import Boolean
 from pyderasn import BoundsError
 from pyderasn import Choice
 from pyderasn import Any
 from pyderasn import BitString
 from pyderasn import BMPString
 from pyderasn import Boolean
 from pyderasn import BoundsError
 from pyderasn import Choice
-from pyderasn import decode_path_defby
 from pyderasn import DecodeError
 from pyderasn import DecodeError
+from pyderasn import DecodePathDefBy
 from pyderasn import Enumerated
 from pyderasn import GeneralizedTime
 from pyderasn import GeneralString
 from pyderasn import Enumerated
 from pyderasn import GeneralizedTime
 from pyderasn import GeneralString
@@ -4902,9 +4903,9 @@ class TestOIDDefines(TestCase):
             max_size=len(value_names),
         ))
         _schema = [
             max_size=len(value_names),
         ))
         _schema = [
-            ("type", ObjectIdentifier(defines=(value_name_chosen, {
+            ("type", ObjectIdentifier(defines=(((value_name_chosen,), {
                 oid: Integer() for oid in oids[:-1]
                 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 i, value_name in enumerate(value_names):
             _schema.append((value_name, Any(expl=tag_ctxp(i))))
@@ -4927,7 +4928,7 @@ class TestOIDDefines(TestCase):
 
 
 class TestDefinesByPath(TestCase):
 
 
 class TestDefinesByPath(TestCase):
-    def runTest(self):
+    def test_generated(self):
         class Seq(Sequence):
             schema = (
                 ("type", ObjectIdentifier()),
         class Seq(Sequence):
             schema = (
                 ("type", ObjectIdentifier()),
@@ -4990,27 +4991,39 @@ class TestDefinesByPath(TestCase):
         seq_integered, _ = Seq().decode(seq_integered_raw)
         self.assertIsNone(seq_integered["value"].defined)
         defines_by_path.append(
         seq_integered, _ = Seq().decode(seq_integered_raw)
         self.assertIsNone(seq_integered["value"].defined)
         defines_by_path.append(
-            (("type",), ("value", {
+            (("type",), ((("value",), {
                 type_integered: Integer(),
                 type_sequenced: SeqInner(),
                 type_integered: Integer(),
                 type_sequenced: SeqInner(),
-            }))
+            }),))
+        )
+        seq_integered, _ = Seq().decode(
+            seq_integered_raw,
+            ctx={"defines_by_path": defines_by_path},
         )
         )
-        seq_integered, _ = Seq().decode(seq_integered_raw, defines_by_path=defines_by_path)
         self.assertIsNotNone(seq_integered["value"].defined)
         self.assertEqual(seq_integered["value"].defined[0], type_integered)
         self.assertEqual(seq_integered["value"].defined[1], Integer(123))
         self.assertIsNotNone(seq_integered["value"].defined)
         self.assertEqual(seq_integered["value"].defined[0], type_integered)
         self.assertEqual(seq_integered["value"].defined[1], Integer(123))
+        self.assertTrue(seq_integered_raw[
+            seq_integered["value"].defined[1].offset:
+        ].startswith(Integer(123).encode()))
 
 
-        seq_sequenced, _ = Seq().decode(seq_sequenced_raw, defines_by_path=defines_by_path)
+        seq_sequenced, _ = Seq().decode(
+            seq_sequenced_raw,
+            ctx={"defines_by_path": defines_by_path},
+        )
         self.assertIsNotNone(seq_sequenced["value"].defined)
         self.assertEqual(seq_sequenced["value"].defined[0], type_sequenced)
         seq_inner = seq_sequenced["value"].defined[1]
         self.assertIsNone(seq_inner["valueInner"].defined)
 
         defines_by_path.append((
         self.assertIsNotNone(seq_sequenced["value"].defined)
         self.assertEqual(seq_sequenced["value"].defined[0], type_sequenced)
         seq_inner = seq_sequenced["value"].defined[1]
         self.assertIsNone(seq_inner["valueInner"].defined)
 
         defines_by_path.append((
-            ("value", decode_path_defby(type_sequenced), "typeInner"),
-            ("valueInner", {type_innered: Pairs()}),
+            ("value", DecodePathDefBy(type_sequenced), "typeInner"),
+            ((("valueInner",), {type_innered: Pairs()}),),
         ))
         ))
-        seq_sequenced, _ = Seq().decode(seq_sequenced_raw, defines_by_path=defines_by_path)
+        seq_sequenced, _ = Seq().decode(
+            seq_sequenced_raw,
+            ctx={"defines_by_path": defines_by_path},
+        )
         self.assertIsNotNone(seq_sequenced["value"].defined)
         self.assertEqual(seq_sequenced["value"].defined[0], type_sequenced)
         seq_inner = seq_sequenced["value"].defined[1]
         self.assertIsNotNone(seq_sequenced["value"].defined)
         self.assertEqual(seq_sequenced["value"].defined[0], type_sequenced)
         seq_inner = seq_sequenced["value"].defined[1]
@@ -5023,18 +5036,21 @@ class TestDefinesByPath(TestCase):
         defines_by_path.append((
             (
                 "value",
         defines_by_path.append((
             (
                 "value",
-                decode_path_defby(type_sequenced),
+                DecodePathDefBy(type_sequenced),
                 "valueInner",
                 "valueInner",
-                decode_path_defby(type_innered),
+                DecodePathDefBy(type_innered),
                 any,
                 "type",
             ),
                 any,
                 "type",
             ),
-            ("value", {
+            ((("value",), {
                 type_integered: Integer(),
                 type_octet_stringed: OctetString(),
                 type_integered: Integer(),
                 type_octet_stringed: OctetString(),
-            }),
+            }),),
         ))
         ))
-        seq_sequenced, _ = Seq().decode(seq_sequenced_raw, defines_by_path=defines_by_path)
+        seq_sequenced, _ = Seq().decode(
+            seq_sequenced_raw,
+            ctx={"defines_by_path": defines_by_path},
+        )
         self.assertIsNotNone(seq_sequenced["value"].defined)
         self.assertEqual(seq_sequenced["value"].defined[0], type_sequenced)
         seq_inner = seq_sequenced["value"].defined[1]
         self.assertIsNotNone(seq_sequenced["value"].defined)
         self.assertEqual(seq_sequenced["value"].defined[0], type_sequenced)
         seq_inner = seq_sequenced["value"].defined[1]
@@ -5044,3 +5060,82 @@ class TestDefinesByPath(TestCase):
         for pair_input, pair_got in zip(pairs_input, pairs_got):
             self.assertEqual(pair_got["value"][0].defined[0], pair_input[0])
             self.assertEqual(pair_got["value"][0].defined[1], pair_input[1])
         for pair_input, pair_got in zip(pairs_input, pairs_got):
             self.assertEqual(pair_got["value"][0].defined[0], pair_input[0])
             self.assertEqual(pair_got["value"][0].defined[1], pair_input[1])
+
+    @given(oid_strategy(), integers())
+    def test_simple(self, oid, tgt):
+        class Inner(Sequence):
+            schema = (
+                ("oid", ObjectIdentifier(defines=((("..", "tgt"), {
+                    ObjectIdentifier(oid): Integer(),
+                }),))),
+            )
+
+        class Outer(Sequence):
+            schema = (
+                ("inner", Inner()),
+                ("tgt", OctetString()),
+            )
+
+        inner = Inner()
+        inner["oid"] = ObjectIdentifier(oid)
+        outer = Outer()
+        outer["inner"] = inner
+        outer["tgt"] = OctetString(Integer(tgt).encode())
+        decoded, _ = Outer().decode(outer.encode())
+        self.assertEqual(decoded["tgt"].defined[1], Integer(tgt))
+
+
+class TestAbsDecodePath(TestCase):
+    @given(
+        lists(text(alphabet=ascii_letters, min_size=1)).map(tuple),
+        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,
+        )
+
+    @given(
+        lists(text(alphabet=ascii_letters, min_size=1)).map(tuple),
+        lists(text(alphabet=ascii_letters, min_size=1), min_size=1).map(tuple),
+    )
+    def test_abs(self, decode_path, rel_path):
+        self.assertSequenceEqual(
+            abs_decode_path(decode_path, ("/",) + rel_path),
+            rel_path,
+        )
+
+    @given(
+        lists(text(alphabet=ascii_letters, min_size=1), min_size=5).map(tuple),
+        integers(min_value=1, max_value=3),
+        lists(text(alphabet=ascii_letters, min_size=1), min_size=1).map(tuple),
+    )
+    def test_dots(self, decode_path, number_of_dots, rel_path):
+        self.assertSequenceEqual(
+            abs_decode_path(decode_path, tuple([".."] * number_of_dots) + rel_path),
+            decode_path[:-number_of_dots] + rel_path,
+        )
+
+
+class TestStrictDefaultExistence(TestCase):
+    @given(data_strategy())
+    def runTest(self, d):
+        count = d.draw(integers(min_value=1, max_value=10))
+        chosen = d.draw(integers(min_value=0, max_value=count - 1))
+        _schema = [
+            ("int%d" % i, Integer(expl=tag_ctxc(i + 1)))
+            for i in range(count)
+        ]
+
+        class Seq(Sequence):
+            schema = _schema
+        seq = Seq()
+        for i in range(count):
+            seq["int%d" % i] = Integer(123)
+        raw = seq.encode()
+        chosen = "int%d" % chosen
+        seq.specs[chosen] = seq.specs[chosen](default=123)
+        seq.decode(raw)
+        with assertRaisesRegex(self, DecodeError, "DEFAULT value met"):
+            seq.decode(raw, ctx={"strict_default_existence": True})