This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
dexter gerrit-no-reply at lists.osmocom.orgdexter has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/24012 )
Change subject: filesystem: add unit tests for encoder/decoder methods
......................................................................
filesystem: add unit tests for encoder/decoder methods
Some files have a custom _encode... and _decode... metod. Those methods
can be detected automatically and tested with a test vector that is
directly defined in the respective file class.
Change-Id: I02d884547f4982e0b8ed7ef21b8cda75237942e2
Related: OS#4963
---
M pySim/filesystem.py
M pySim/ts_102_221.py
M pySim/ts_31_102.py
M pySim/ts_31_103.py
M pySim/ts_51_011.py
A tests/test_files.py
6 files changed, 126 insertions(+), 1 deletion(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/12/24012/1
diff --git a/pySim/filesystem.py b/pySim/filesystem.py
index dec521e..f0c985c 100644
--- a/pySim/filesystem.py
+++ b/pySim/filesystem.py
@@ -34,7 +34,7 @@
from typing import cast, Optional, Iterable, List, Any, Dict, Tuple
-from pySim.utils import sw_match, h2b, b2h, is_hex
+from pySim.utils import sw_match, h2b, b2h, is_hex, JsonEncoder
from pySim.construct import filter_dict
from pySim.exceptions import *
from pySim.jsonpath import js_path_find, js_path_modify
@@ -378,6 +378,58 @@
sels.update({x.name:x for x in self.parent.children.values() if x != self})
return sels
+ def test_encode_decode(self, verbose=False):
+ """Unit-test to verify the encoder and decoder function of a certain
+ file. To run this, simply define a _encode_decode_testvector[] testvector
+ list inside the specific file implementation. The list shall contain at
+ least one dictionary with at least one set of abstract data.
+ """
+
+ # Find out which encoder/decoder functions are present
+ has_dec_rec = hasattr(self.__class__, '_decode_record_hex') and callable(getattr(self.__class__, '_decode_record_hex'))
+ has_enc_rec = hasattr(self.__class__, '_encode_record_hex') and callable(getattr(self.__class__, '_encode_record_hex'))
+ has_dec = hasattr(self.__class__, '_decode_hex') and callable(getattr(self.__class__, '_decode_hex'))
+ has_enc = hasattr(self.__class__, '_encode_hex') and callable(getattr(self.__class__, '_encode_hex'))
+ has_testvec = hasattr(self.__class__, '_encode_decode_testvector')
+
+ # Check if a decoder, encoder and a testvector is present
+ if has_dec_rec and has_enc_rec:
+ print("Testing %s (record oriented)" % (self.name))
+ encode = self._encode_record_hex
+ decode = self._decode_record_hex
+ if not has_testvec:
+ print(" Cannot test: Please define _encode_decode_testvector[] in %s" % (self.name))
+ return
+ elif has_dec and has_enc:
+ print("Testing %s (transparent)" % (self.name))
+ encode = self._encode_hex
+ decode = self._decode_hex
+ if not has_testvec:
+ print(" Cannot test: Please define _encode_decode_testvector[] in %s" % (self.name))
+ return
+ else:
+ return
+
+ # Encode+Decode the test data and make sure the end result matches the
+ # input
+ for testvec_json in self.__class__._encode_decode_testvector:
+ print(" testvec_json: " + str(testvec_json))
+ testvec = json.loads(testvec_json)
+ if verbose:
+ print(" testvec: " + str(testvec))
+ encoded = encode(testvec)
+ if verbose:
+ print(" encoded: " + str(encoded))
+ decoded = decode(encoded)
+ if verbose:
+ print(" decoded: " + str(decoded))
+ decoded_json = json.dumps(decoded, cls=JsonEncoder)
+ if verbose:
+ print(" decoded_json: " + str(decoded_json))
+ if testvec_json != decoded_json:
+ raise ValueError("The encoded end result (decoded_json) does not match the original input (testvec_json)")
+ else:
+ print(" Ok.")
class TransparentEF(CardEF):
"""Transparent EF (Entry File) in the smart card filesystem.
diff --git a/pySim/ts_102_221.py b/pySim/ts_102_221.py
index 88a36a1..ab4ecf6 100644
--- a/pySim/ts_102_221.py
+++ b/pySim/ts_102_221.py
@@ -189,6 +189,7 @@
# TS 102 221 Section 13.2
class EF_ICCID(TransparentEF):
+ _encode_decode_testvector = ['{"iccid": "8988211000000433188"}']
def __init__(self, fid='2fe2', sfid=0x02, name='EF.ICCID', desc='ICC Identification'):
super().__init__(fid, sfid=sfid, name=name, desc=desc, size={10,10})
diff --git a/pySim/ts_31_102.py b/pySim/ts_31_102.py
index de729be..e7f5fbb 100644
--- a/pySim/ts_31_102.py
+++ b/pySim/ts_31_102.py
@@ -291,6 +291,7 @@
# TS 31.102 4.4.11.8
class EF_SUCI_Calc_Info(TransparentEF):
+ _encode_decode_testvector = ['{"prot_scheme_id_list": [{"priority": 0, "identifier": 2, "key_index": 1}, {"priority": 1, "identifier": 1, "key_index": 2}, {"priority": 2, "identifier": 0, "key_index": 0}], "hnet_pubkey_list": [{"hnet_pubkey_identifier": 27, "hnet_pubkey": "0272da71976234ce833a6907425867b82e074d44ef907dfb4b3e21c1c2256ebcd1"}, {"hnet_pubkey_identifier": 30, "hnet_pubkey": "5a8d38864820197c3394b92613b20b91633cbd897119273bf8e4a6f4eec0a650"}]}']
def __init__(self, fid="4f07", sfid=0x07, name='EF.SUCI_Calc_Info', size={2, None},
desc='SUCI Calc Info'):
super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
diff --git a/pySim/ts_31_103.py b/pySim/ts_31_103.py
index 1009ba3..bac7a7d 100644
--- a/pySim/ts_31_103.py
+++ b/pySim/ts_31_103.py
@@ -117,6 +117,8 @@
# TS 31.103 Section 4.2.8
class EF_PCSCF(LinFixedEF):
+ _encode_decode_testvector = ['{"addr": "192.168.100.110", "addr_type": "01"}',
+ '{"addr": "hello,world", "addr_type": "00"}']
def __init__(self, fid='6f09', sfid=None, name='EF.P-CSCF', desc='P-CSCF Address'):
super().__init__(fid=fid, sfid=sfid, name=name, desc=desc)
def _decode_record_hex(self, raw_hex):
diff --git a/pySim/ts_51_011.py b/pySim/ts_51_011.py
index 8e4428c..06f4c0e 100644
--- a/pySim/ts_51_011.py
+++ b/pySim/ts_51_011.py
@@ -376,6 +376,8 @@
# TS 51.011 Section 10.5.5
class EF_MSISDN(LinFixedEF):
+ _encode_decode_testvector = ['{"msisdn": [1, 1, "+4916012345678"]}',
+ '{"msisdn": [1, 3, "123456"]}']
def __init__(self, fid='6f40', sfid=None, name='EF.MSISDN', desc='MSISDN'):
super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len={15, 34})
def _decode_record_hex(self, raw_hex_data):
@@ -465,6 +467,8 @@
# TS 51.011 Section 10.3.2
class EF_IMSI(TransparentEF):
+ _encode_decode_testvector = ['{"imsi": "001010000000102"}',
+ '{"imsi": "123456789012345"}']
def __init__(self, fid='6f07', sfid=None, name='EF.IMSI', desc='IMSI', size={9,9}):
super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
def _decode_hex(self, raw_hex):
@@ -474,6 +478,9 @@
# TS 51.011 Section 10.3.4
class EF_PLMNsel(TransRecEF):
+ _encode_decode_testvector = ['{"mcc": "123", "mnc": "45"}',
+ '{"mcc": "001", "mnc": "01"}',
+ '{"mcc": "456", "mnc": "123"}']
def __init__(self, fid='6f30', sfid=None, name='EF.PLMNsel', desc='PLMN selector',
size={24,None}, rec_len=3):
super().__init__(fid, name=name, sfid=sfid, desc=desc, size=size, rec_len=rec_len)
@@ -517,6 +524,9 @@
# TS 51.011 Section 10.3.11
class EF_SPN(TransparentEF):
+ _encode_decode_testvector = ['{"spn": ["testme", false, false]}',
+ '{"spn": ["", true, false]}',
+ '{"spn": ["hello world", false, true]}']
def __init__(self, fid='6f46', sfid=None, name='EF.SPN', desc='Service Provider Name', size={17,17}):
super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
def _decode_hex(self, raw_hex):
@@ -638,6 +648,10 @@
'corporate'/BcdAdapter(Bytes(4)))
# TS 51.011 Section 10.3.30
class EF_CNL(TransRecEF):
+ _encode_decode_testvector = ['{"mcc": "", "mnc": "", "network_subset": 255, "service_provider_id": 255, "corporate_id": 255}',
+ '{"mcc": "001", "mnc": "01", "network_subset": 23, "service_provider_id": 42, "corporate_id": 5}',
+ '{"mcc": "123", "mnc": "567", "network_subset": 255, "service_provider_id": 255, "corporate_id": 255}',
+ '{"mcc": "262", "mnc": "12", "network_subset": 111, "service_provider_id": 0, "corporate_id": 0}']
def __init__(self, fid='6f32', sfid=None, name='EF.CNL', size={6,None}, rec_len=6,
desc='Co-operative Network List'):
super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, rec_len=rec_len)
@@ -676,6 +690,10 @@
# TS 51.011 Section 10.3.35..37
class EF_xPLMNwAcT(TransRecEF):
+ _encode_decode_testvector = ['{"mcc": "001", "mnc": "01", "act": ["UTRAN", "E-UTRAN", "GSM", "GSM COMPACT", "cdma2000 HRPD", "cdma2000 1xRTT"]}',
+ '{"mcc": "001", "mnc": "01", "act": ["UTRAN", "E-UTRAN WB-S1", "GSM", "GSM COMPACT", "cdma2000 HRPD", "cdma2000 1xRTT"]}',
+ '{"mcc": "001", "mnc": "01", "act": ["UTRAN", "E-UTRAN NB-S1", "GSM", "GSM COMPACT", "cdma2000 HRPD", "cdma2000 1xRTT"]}',
+ '{"mcc": "001", "mnc": "01", "act": ["UTRAN", "E-UTRAN WB-S1", "E-UTRAN NB-S1", "GSM", "GSM COMPACT", "cdma2000 HRPD", "cdma2000 1xRTT"]}']
def __init__(self, fid, sfid=None, name=None, desc=None, size={40,None}, rec_len=5):
super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, rec_len=rec_len)
def _decode_record_hex(self, in_hex):
diff --git a/tests/test_files.py b/tests/test_files.py
new file mode 100755
index 0000000..a855afa
--- /dev/null
+++ b/tests/test_files.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+
+import unittest
+from pySim import utils
+from pySim.ts_31_102 import EF_SUCI_Calc_Info
+
+from typing import List
+
+import json
+import gc
+
+from pySim.ts_51_011 import EF, DF, EF_SST_map
+from pySim.ts_31_102 import EF_UST_map, EF_USIM_ADF_map
+from pySim.ts_31_103 import EF_IST_map, EF_ISIM_ADF_map
+
+from pySim.filesystem import CardEF, CardMF, CardDF, CardADF
+from pySim.ts_51_011 import CardProfileSIM, DF_TELECOM, DF_GSM
+from pySim.ts_102_221 import CardProfileUICC
+from pySim.ts_31_102 import CardApplicationUSIM
+from pySim.ts_31_103 import CardApplicationISIM
+
+# Check if a file (specified by its name) exists in a given list with files
+def file_in_list(file_list, name):
+ for f in file_list:
+ if f.name == name:
+ return True
+ return False
+
+class DecTestCase(unittest.TestCase):
+
+ def testFileContentDecoderEncoder(self):
+ # Create files in memory
+ profile = CardProfileUICC()
+ profile.add_application(CardApplicationUSIM)
+ profile.add_application(CardApplicationISIM)
+ df_telecom = DF_TELECOM()
+ df_gsm = DF_GSM()
+
+ # Collect one sample of each EF from memory
+ test_candidates = []
+ for obj in gc.get_objects():
+ if isinstance(obj, CardEF):
+ if not file_in_list(test_candidates, obj.name):
+ test_candidates.append(obj)
+
+ # Execute integrated encoder/decoder unit tests
+ for obj in test_candidates:
+ obj.test_encode_decode()
+
+if __name__ == "__main__":
+ unittest.main()
--
To view, visit https://gerrit.osmocom.org/c/pysim/+/24012
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I02d884547f4982e0b8ed7ef21b8cda75237942e2
Gerrit-Change-Number: 24012
Gerrit-PatchSet: 1
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210430/fe364622/attachment.htm>