blob: 3fb10620596ecd67f943bcbf6520561903be3708 [file] [log] [blame]
Harald Welte865eea62023-01-27 19:26:12 +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 *
22from pySim.filesystem 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
32
33def get_qualified_name(c):
34 """return the qualified (by module) name of a class."""
35 return "%s.%s" % (c.__module__, c.__name__)
36
37class LinFixed_Test(unittest.TestCase):
38 classes = all_subclasses(LinFixedEF)
39
40 def test_decode_record(self):
41 """Test the decoder for a linear-fixed EF. Requires the given LinFixedEF subclass
42 to have an '_test_decode' attribute, containing a list of tuples. Each tuple can
43 either be a
44 * 2-tuple (hexstring, decoded_dict) or a
45 * 3-tuple (hexstring, record_nr, decoded_dict)
46 """
47 for c in self.classes:
48 name = get_qualified_name(c)
49 if hasattr(c, '_test_decode'):
50 for t in c._test_decode:
51 with self.subTest(name, test_decode=t):
52 inst = c()
53 if len(t) == 2:
54 encoded = t[0]
55 rec_num = 1
56 decoded = t[1]
57 else:
58 encoded = t[0]
59 rec_num = t[1]
60 decoded = t[2]
61 logging.debug("Testing decode of %s", name)
62 re_dec = inst.decode_record_hex(encoded, rec_num)
63 self.assertEqual(decoded, re_dec)
64
65 def test_encode_record(self):
66 """Test the encoder for a linear-fixed EF. Requires the given LinFixedEF subclass
67 to have an '_test_encode' attribute, containing a list of tuples. Each tuple can
68 either be a
69 * 2-tuple (hexstring, decoded_dict) or a
70 * 3-tuple (hexstring, record_nr, decoded_dict)
71 """
72 for c in self.classes:
73 name = get_qualified_name(c)
74 if hasattr(c, '_test_encode'):
75 for t in c._test_encode:
76 with self.subTest(name, test_encode=t):
77 inst = c()
78 if len(t) == 2:
79 encoded = t[0]
80 rec_num = 1
81 decoded = t[1]
82 else:
83 encoded = t[0]
84 rec_num = t[1]
85 decoded = t[2]
86 logging.debug("Testing encode of %s", name)
87 re_enc = inst.encode_record_hex(decoded, rec_num)
88 self.assertEqual(encoded, re_enc)
89
90 def test_de_encode_record(self):
91 """Test the decoder and encoder for a linear-fixed EF. Performs first a decoder
92 test, and then re-encodes the decoded data, comparing the re-encoded data with the
93 initial input data.
94
95 Requires the given LinFixedEF subclass to have a '_test_de_encode' attribute,
96 containing a list of tuples. Each tuple can
97 either be a
98 * 2-tuple (hexstring, decoded_dict) or a
99 * 3-tuple (hexstring, record_nr, 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 if len(t) == 2:
108 encoded = t[0]
109 rec_num = 1
110 decoded = t[1]
111 else:
112 encoded = t[0]
113 rec_num = t[1]
114 decoded = t[2]
115 logging.debug("Testing decode of %s", name)
116 re_dec = inst.decode_record_hex(encoded, rec_num)
117 self.assertEqual(decoded, re_dec)
118 # re-encode the decoded data
119 logging.debug("Testing re-encode of %s", name)
120 re_enc = inst.encode_record_hex(re_dec, rec_num)
121 self.assertEqual(encoded, re_enc)
122
123
124class TransRecEF_Test(unittest.TestCase):
125 classes = all_subclasses(TransRecEF)
126
127 def test_decode_record(self):
128 """Test the decoder for a transparent record-oriented EF. Requires the given TransRecEF subclass
129 to have an '_test_decode' attribute, containing a list of tuples. Each tuple has to be a
130 2-tuple (hexstring, decoded_dict).
131 """
132 for c in self.classes:
133 name = get_qualified_name(c)
134 if hasattr(c, '_test_decode'):
135 for t in c._test_decode:
136 with self.subTest(name, test_decode=t):
137 inst = c()
138 encoded = t[0]
139 decoded = t[1]
140 logging.debug("Testing decode of %s", name)
141 re_dec = inst.decode_record_hex(encoded)
142 self.assertEqual(decoded, re_dec)
143
144 def test_encode_record(self):
145 """Test the encoder for a transparent record-oriented EF. Requires the given TransRecEF subclass
146 to have an '_test_encode' attribute, containing a list of tuples. Each tuple has to be a
147 2-tuple (hexstring, decoded_dict).
148 """
149 for c in self.classes:
150 name = get_qualified_name(c)
151 if hasattr(c, '_test_decode'):
152 for t in c._test_decode:
153 with self.subTest(name, test_decode=t):
154 inst = c()
155 encoded = t[0]
156 decoded = t[1]
157 logging.debug("Testing decode of %s", name)
158 re_dec = inst.decode_record_hex(encoded)
159 self.assertEqual(decoded, re_dec)
160
161
162 def test_de_encode_record(self):
163 """Test the decoder and encoder for a transparent record-oriented EF. Performs first a decoder
164 test, and then re-encodes the decoded data, comparing the re-encoded data with the
165 initial input data.
166
167 Requires the given TransRecEF subclass to have a '_test_de_encode' attribute,
168 containing a list of tuples. Each tuple has to be a 2-tuple (hexstring, decoded_dict).
169 """
170 for c in self.classes:
171 name = get_qualified_name(c)
172 if hasattr(c, '_test_de_encode'):
173 for t in c._test_de_encode:
174 with self.subTest(name, test_de_encode=t):
175 inst = c()
176 encoded = t[0]
177 decoded = t[1]
178 logging.debug("Testing decode of %s", name)
179 re_dec = inst.decode_record_hex(encoded)
180 self.assertEqual(decoded, re_dec)
181 # re-encode the decoded data
182 logging.debug("Testing re-encode of %s", name)
183 re_enc = inst.encode_record_hex(re_dec)
184 self.assertEqual(encoded, re_enc)
185
186
187class TransparentEF_Test(unittest.TestCase):
188 @classmethod
189 def get_classes(cls):
190 """get list of TransparentEF sub-classes which are not a TransRecEF subclass."""
191 classes = all_subclasses(TransparentEF)
192 trans_rec_classes = all_subclasses(TransRecEF)
193 return filter(lambda c: c not in trans_rec_classes, classes)
194
195 @classmethod
196 def setUpClass(cls):
197 """set-up method called once for this class by unittest framework"""
198 cls.classes = cls.get_classes()
199
200 def test_decode_file(self):
201 """Test the decoder for a transparent EF. Requires the given TransparentEF subclass
202 to have a '_test_decode' attribute, containing a list of tuples. Each tuple
203 is a 2-tuple (hexstring, decoded_dict).
204 """
205 for c in self.classes:
206 name = get_qualified_name(c)
207 if hasattr(c, '_test_decode'):
208 for t in c._test_decode:
209 with self.subTest(name, test_decode=t):
210 inst = c()
211 encoded = t[0]
212 decoded = t[1]
213 logging.debug("Testing decode of %s", name)
214 re_dec = inst.decode_hex(encoded)
215 self.assertEqual(decoded, re_dec)
216
217 def test_encode_file(self):
218 """Test the encoder for a transparent EF. Requires the given TransparentEF subclass
219 to have a '_test_encode' attribute, containing a list of tuples. Each tuple
220 is a 2-tuple (hexstring, decoded_dict).
221 """
222 for c in self.classes:
223 name = get_qualified_name(c)
224 if hasattr(c, '_test_encode'):
225 for t in c._test_encode:
226 with self.subTest(name, test_encode=t):
227 inst = c()
228 encoded = t[0]
229 decoded = t[1]
230 logging.debug("Testing encode of %s", name)
231 re_dec = inst.decode_hex(encoded)
232 self.assertEqual(decoded, re_dec)
233
234 def test_de_encode_file(self):
235 """Test the decoder and encoder for a transparent EF. Performs first a decoder
236 test, and then re-encodes the decoded data, comparing the re-encoded data with the
237 initial input data.
238
239 Requires the given TransparentEF subclass to have a '_test_de_encode' attribute,
240 containing a list of tuples. Each tuple is a 2-tuple (hexstring, decoded_dict).
241 """
242 for c in self.classes:
243 name = get_qualified_name(c)
244 if hasattr(c, '_test_de_encode'):
245 for t in c._test_de_encode:
246 with self.subTest(name, test_de_encode=t):
247 inst = c()
248 encoded = t[0]
249 decoded = t[1]
250 logging.debug("Testing decode of %s", name)
251 re_dec = inst.decode_hex(encoded)
252 self.assertEqual(decoded, re_dec)
253 logging.debug("Testing re-encode of %s", name)
254 re_dec = inst.decode_hex(encoded)
255 re_enc = inst.encode_hex(re_dec)
256 self.assertEqual(encoded, re_enc)
257
258
259if __name__ == '__main__':
260 logger = logging.getLogger()
261 logger.setLevel(logging.DEBUG)
262 unittest.main()