blob: b0ad48a2757b92dcaff23b25bb78f3889af6e12f [file] [log] [blame]
Harald Welte2a36c1b2023-12-23 12:49:09 +01001#!/usr/bin/env python3
2
3# (C) 2023 by Harald Welte <laforge@osmocom.org>
4#
5# This program is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18import unittest
19import logging
20
21from pySim.utils import b2h, h2b, all_subclasses
22from pySim.tlv import *
23
24import pySim.iso7816_4
25import pySim.ts_102_221
26import pySim.ts_102_222
27import pySim.ts_31_102
28import pySim.ts_31_103
29import pySim.ts_51_011
30import pySim.sysmocom_sja2
31import pySim.gsm_r
32import pySim.cdma_ruim
33
34if 'unittest.util' in __import__('sys').modules:
35 # Show full diff in self.assertEqual.
36 __import__('sys').modules['unittest.util']._MAX_LENGTH = 999999999
37
38def get_qualified_name(c):
39 """return the qualified (by module) name of a class."""
40 return "%s.%s" % (c.__module__, c.__name__)
41
42class TLV_IE_Test(unittest.TestCase):
43 maxDiff = None
44
45 @classmethod
46 def get_classes(cls):
47 """get list of TLV_IE sub-classes."""
48 return all_subclasses(TLV_IE)
49
50 @classmethod
51 def setUpClass(cls):
52 """set-up method called once for this class by unittest framework"""
53 cls.classes = cls.get_classes()
54
55 def test_decode_tlv(self):
56 """Test the decoder for a TLV_IE. Requires the given TLV_IE subclass
57 to have a '_test_decode' attribute, containing a list of tuples. Each tuple
58 is a 2-tuple (hexstring, decoded_dict).
59 """
60 for c in self.classes:
61 name = get_qualified_name(c)
62 if hasattr(c, '_test_decode'):
63 for t in c._test_decode:
64 with self.subTest(name, test_decode=t):
65 inst = c()
66 encoded = t[0]
67 decoded = { camel_to_snake(c.__name__): t[1] }
68 context = t[2] if len(t) == 3 else {}
69 logging.debug("Testing decode of %s", name)
70 inst.from_tlv(h2b(encoded), context=context)
71 re_dec = inst.to_dict()
72 self.assertEqual(decoded, re_dec)
73
74 def test_encode_tlv(self):
75 """Test the encoder for a TLV_IE. Requires the given TLV_IE subclass
76 to have a '_test_encode' attribute, containing a list of tuples. Each tuple
77 is a 2-tuple (hexstring, decoded_dict).
78 """
79 for c in self.classes:
80 name = get_qualified_name(c)
81 if hasattr(c, '_test_encode'):
82 for t in c._test_encode:
83 with self.subTest(name, test_encode=t):
84 inst = c()
85 encoded = t[0]
86 decoded = { camel_to_snake(c.__name__): t[1] }
87 context = t[2] if len(t) == 3 else {}
88 logging.debug("Testing encode of %s", name)
89 inst.from_dict(decoded)
90 re_enc = b2h(inst.to_tlv(context))
91 self.assertEqual(encoded.upper(), re_enc.upper())
92
93 def test_de_encode_tlv(self):
94 """Test the decoder and encoder for a TLV_IE. Performs first a decoder
95 test, and then re-encodes the decoded data, comparing the re-encoded data with the
96 initial input data.
97
98 Requires the given TLV_IE subclass to have a '_test_de_encode' attribute,
99 containing a list of tuples. Each tuple is a 2-tuple (hexstring, decoded_dict).
100 """
101 for c in self.classes:
102 name = get_qualified_name(c)
103 if hasattr(c, '_test_de_encode'):
104 for t in c._test_de_encode:
105 with self.subTest(name, test_de_encode=t):
106 inst = c()
107 encoded = t[0]
108 decoded = { camel_to_snake(c.__name__): t[1] }
109 context = t[2] if len(t) == 3 else {}
110 logging.debug("Testing decode of %s", name)
111 inst.from_tlv(h2b(encoded), context=context)
112 re_dec = inst.to_dict()
113 self.assertEqual(decoded, re_dec)
114 logging.debug("Testing re-encode of %s", name)
115 re_enc = b2h(inst.to_tlv(context=context))
116 self.assertEqual(encoded.upper(), re_enc.upper())
117
118
119if __name__ == '__main__':
120 logger = logging.getLogger()
121 logger.setLevel(logging.DEBUG)
122 unittest.main()