def test_zip_no_file_error(self, normal_distribution_url, zip_data, tmpdir): pCT = probeCOCOATek(normal_distribution_url) for k1, v1 in zip_data.items(): with pytest.raises(ParamError) as e: tek_bin = pCT.get_tek_content( os.path.join(tmpdir, os.path.basename(k1)))
def test_listjson_normal(self, nokey, normal_distribution_url, normal_distribution_json, zip_data): pCT = probeCOCOATek(normal_distribution_url) with requests_mock.Mocker() as m: m.get(normal_distribution_url, content=normal_distribution_json.encode('utf-8')) for url in zip_data.keys(): m.get(url, content=bytes.fromhex(zip_data[url]["raw_data"])) tek_zip_list = pCT.get_zip_list() js_str = pCT.zip_list_toJson(nokey) js = json.loads(js_str) for i, z in enumerate(js): assert z["no"] == i assert z["url"] in [ j["url"] for j in json.loads(normal_distribution_json) ] assert z["created"] == datetime.fromtimestamp( round([ j["created"] for j in json.loads(normal_distribution_json) if z["url"] == j["url"] ][0] / 1000)).astimezone().isoformat() if "keys" in z: assert z["keys"]["count"] == len( zip_data[z["url"]]["keys"])
def test_tektext_normal(self, nocache, normal_distribution_url, normal_distribution_json, zip_data): pCT = probeCOCOATek(normal_distribution_url) if not nocache: for k,v in zip_data.items(): with open(os.path.join(pCT.cache_dir, os.path.basename(k)), 'wb') as f: f.write(bytes.fromhex(v["raw_data"])) with requests_mock.Mocker() as m: m.get(normal_distribution_url, content=normal_distribution_json.encode('utf-8')) for k,v in zip_data.items(): m.get(k, content=bytes.fromhex(zip_data[k]["raw_data"])) tek_bin = pCT.get_tek_content(k) text_lines = pCT.tek_toText(tek_bin) assert True in [("start_timestamp" in l) and ("{:%Y-%m-%d %H:%M:%S%z}]".format(datetime.fromtimestamp(tek_bin.start_timestamp).astimezone()) in l) for l in text_lines] assert True in [("end_timestamp" in l) and ("{:%Y-%m-%d %H:%M:%S%z}]".format(datetime.fromtimestamp(tek_bin.end_timestamp).astimezone()) in l) for l in text_lines] assert True in [("region" in l) and (str(tek_bin.region) in l) for l in text_lines] assert True in [("batch_num" in l) and (str(tek_bin.batch_num) in l) for l in text_lines] assert True in [("batch_size" in l) and (str(tek_bin.batch_size) in l) for l in text_lines] assert True in [("verification_key_version" in l) and (tek_bin.signature_infos[0].verification_key_version in l) for l in text_lines] assert True in [("verification_key_id" in l) and (tek_bin.signature_infos[0].verification_key_id in l) for l in text_lines] assert True in [("signature_algorithm" in l) and (tek_bin.signature_infos[0].signature_algorithm in l) for l in text_lines] assert True in [("Keys" in l) and ("Count" in l) and ("[{:}]".format(len(tek_bin.keys)) in l) for l in text_lines] for i, k in enumerate(tek_bin.keys): assert True in [("[{:03d}]".format(i+1) in l) and ("[{:}]".format(k.key_data.hex()) in l) for l in text_lines] assert True in [("transmission_risk_level" in l) and ("[{:}]".format(k.transmission_risk_level) in l) for l in text_lines] assert True in [("rolling_start_interval_number" in l) and ("[{:}]".format(k.rolling_start_interval_number) in l) for l in text_lines] assert True in [("rolling_period" in l) and ("[{:}]".format(k.rolling_period) in l) for l in text_lines] assert True in [("report_type" in l) and ("[{:}]".format(k.report_type) in l) for l in text_lines] assert True in [("days_since_onset_of_symptoms" in l) and ("[{:}]".format(k.days_since_onset_of_symptoms) in l) for l in text_lines]
def test_tekjson_normal(self, nocache, normal_distribution_url, normal_distribution_json, zip_data): pCT = probeCOCOATek(normal_distribution_url) if not nocache: for k,v in zip_data.items(): with open(os.path.join(pCT.cache_dir, os.path.basename(k)), 'wb') as f: f.write(bytes.fromhex(v["raw_data"])) with requests_mock.Mocker() as m: m.get(normal_distribution_url, content=normal_distribution_json.encode('utf-8')) for k,v in zip_data.items(): m.get(k, content=bytes.fromhex(zip_data[k]["raw_data"])) tek_bin = pCT.get_tek_content(k) js_str = pCT.tek_toJson(tek_bin) js = json.loads(js_str) assert js["start_timestamp"] == datetime.fromtimestamp(tek_bin.start_timestamp).astimezone().isoformat() assert js["end_timestamp"] == datetime.fromtimestamp(tek_bin.end_timestamp).astimezone().isoformat() assert js["region"] == tek_bin.region assert js["batch_num"] == tek_bin.batch_num assert js["batch_size"] == tek_bin.batch_size assert js["signature_infos"]["verification_key_version"] == tek_bin.signature_infos[0].verification_key_version assert js["signature_infos"]["verification_key_id"] == tek_bin.signature_infos[0].verification_key_id assert js["signature_infos"]["signature_algorithm"] == tek_bin.signature_infos[0].signature_algorithm assert len(js["keys"]) == len(tek_bin.keys) for k in js["keys"]: assert k["key_data"] in [tk.key_data.hex() for tk in tek_bin.keys if k["key_data"] == tk.key_data.hex()] assert k["transmission_risk_level"] in [tk.transmission_risk_level for tk in tek_bin.keys if k["key_data"] == tk.key_data.hex()] assert k["rolling_start_interval_number"] in [tk.rolling_start_interval_number for tk in tek_bin.keys if k["key_data"] == tk.key_data.hex()] assert k["rolling_period"] in [tk.rolling_period for tk in tek_bin.keys if k["key_data"] == tk.key_data.hex()] assert k["report_type"] in [tk.report_type for tk in tek_bin.keys if k["key_data"] == tk.key_data.hex()] assert k["days_since_onset_of_symptoms"] in [tk.days_since_onset_of_symptoms for tk in tek_bin.keys if k["key_data"] == tk.key_data.hex()]
def test_zip_invalid_data_error(self, normal_distribution_url, zip_data, invalid_zip_data): pCT = probeCOCOATek(normal_distribution_url) with requests_mock.Mocker() as m: for url in zip_data.keys(): m.get(url, content=bytes.fromhex(invalid_zip_data)) with pytest.raises(DataError) as e: tek_bin = pCT.get_tek_content(url)
def test_list_url_notfound_error(self, normal_distribution_url, zip_data): pCT = probeCOCOATek(normal_distribution_url) with requests_mock.Mocker() as m: m.get(normal_distribution_url, text='Not Found', status_code=404) for url in zip_data.keys(): m.get(url, content=bytes.fromhex(zip_data[url]["raw_data"])) with pytest.raises(requests.exceptions.HTTPError) as e: tek_zip_list = pCT.get_zip_list()
def test_zip_server_error(self, normal_distribution_url, zip_data): pCT = probeCOCOATek(normal_distribution_url) with requests_mock.Mocker() as m: for url in zip_data.keys(): m.get(url, content=bytes.fromhex(zip_data[url]["raw_data"]), status_code=500) with pytest.raises(requests.exceptions.HTTPError) as e: tek_bin = pCT.get_tek_content(url)
def test_constractclass_withoption_normal(self, normal_distribution_url, tmpdir): set_dir = tmpdir #assert not os.path.isdir(set_dir) pCT = probeCOCOATek(normal_distribution_url, cache_dir=set_dir) assert type(pCT) == probeCOCOATek assert pCT.tek_distribution_url == normal_distribution_url assert pCT.cache_dir == set_dir assert os.path.isdir(pCT.cache_dir)
def test_zip_from_url_nocache_normal(self, nocache, normal_distribution_url, zip_data): pCT = probeCOCOATek(normal_distribution_url) if not nocache: for k, v in zip_data.items(): with open(os.path.join(pCT.cache_dir, os.path.basename(k)), 'wb') as f: f.write(bytes.fromhex(v["raw_data"])) with requests_mock.Mocker() as m: for url in zip_data.keys(): m.get(url, content=bytes.fromhex(zip_data[url]["raw_data"])) tek_bin = pCT.get_tek_content(url) assert "{:%Y-%m-%d %H:%M:%S%z}".format( datetime.fromtimestamp(tek_bin.start_timestamp).astimezone( )) == "{:%Y-%m-%d %H:%M:%S%z}".format( datetime.strptime(zip_data[url]["start_timestamp"], "%Y-%m-%d %H:%M:%S%z").astimezone()) assert "{:%Y-%m-%d %H:%M:%S%z}".format( datetime.fromtimestamp(tek_bin.end_timestamp).astimezone() ) == "{:%Y-%m-%d %H:%M:%S%z}".format( datetime.strptime(zip_data[url]["end_timestamp"], "%Y-%m-%d %H:%M:%S%z").astimezone()) assert tek_bin.region == zip_data[url]["region"] assert tek_bin.batch_num == zip_data[url]["batch_num"] assert tek_bin.batch_size == zip_data[url]["batch_size"] assert tek_bin.signature_infos[ 0].verification_key_version == zip_data[url][ "signature_infos"]["verification_key_version"] assert tek_bin.signature_infos[ 0].verification_key_id == zip_data[url]["signature_infos"][ "verification_key_id"] assert tek_bin.signature_infos[ 0].signature_algorithm == zip_data[url]["signature_infos"][ "signature_algorithm"] assert set([k.key_data.hex() for k in tek_bin.keys]) == set( [z["key_data"] for z in zip_data[url]["keys"]]) assert set([k.transmission_risk_level for k in tek_bin.keys]) == set([ z["transmission_risk_level"] for z in zip_data[url]["keys"] ]) assert set([ k.rolling_start_interval_number for k in tek_bin.keys ]) == set([ z["rolling_start_interval_number"] for z in zip_data[url]["keys"] ]) assert set([k.rolling_period for k in tek_bin.keys]) == set( [z["rolling_period"] for z in zip_data[url]["keys"]]) assert set([k.report_type for k in tek_bin.keys]) == set( [z["report_type"] for z in zip_data[url]["keys"]]) assert set([ k.days_since_onset_of_symptoms for k in tek_bin.keys ]) == set([ z["days_since_onset_of_symptoms"] for z in zip_data[url]["keys"] ])
def test_list_url_invalid_json_error(self, normal_distribution_url, zip_data): pCT = probeCOCOATek(normal_distribution_url) with requests_mock.Mocker() as m: m.get(normal_distribution_url, content='invalid_json'.encode('utf-8')) for url in zip_data.keys(): m.get(url, content=bytes.fromhex(zip_data[url]["raw_data"])) with pytest.raises(DataError) as e: tek_zip_list = pCT.get_zip_list()
def test_listtext_no_data_error(self, nokey, normal_distribution_url, normal_distribution_json, zip_data): pCT = probeCOCOATek(normal_distribution_url) with requests_mock.Mocker() as m: m.get(normal_distribution_url, content=normal_distribution_json.encode('utf-8')) for url in zip_data.keys(): m.get(url, content=bytes.fromhex(zip_data[url]["raw_data"])) tek_zip_list = pCT.get_zip_list() pCT.tek_zip_list = [] with pytest.raises(DataError) as e: text_lines = pCT.zip_list_toText(nokey)
def test_dl_list_url_others_error(self, normal_distribution_url, zip_data, tmpdir): pCT = probeCOCOATek(normal_distribution_url) with requests_mock.Mocker() as m: m.get(normal_distribution_url, text='server error', status_code=500) for url in zip_data.keys(): m.get(url, content=bytes.fromhex(zip_data[url]["raw_data"])) with pytest.raises(requests.exceptions.HTTPError) as e: pCT.download_zips(tmpdir)
def test_dl_zip_invalid_data_error(self, normal_distribution_url, normal_distribution_json, zip_data, tmpdir, invalid_zip_data): pCT = probeCOCOATek(normal_distribution_url) with requests_mock.Mocker() as m: m.get(normal_distribution_url, content=normal_distribution_json.encode('utf-8')) for url in zip_data.keys(): m.get(url, content=bytes.fromhex(invalid_zip_data)) with pytest.raises(DataError) as e: pCT.download_zips(tmpdir)
def test_constractclass_default_normal(self): assert not os.path.isdir( os.path.join(os.path.expanduser("~"), ".probecocoatek" + os.sep + "cache")) pCT = probeCOCOATek() assert type(pCT) == probeCOCOATek assert pCT.tek_distribution_url == "https://covid19radar-jpn-prod.azureedge.net/c19r/440/list.json" assert pCT.cache_dir == os.path.join( os.path.expanduser("~"), ".probecocoatek" + os.sep + "cache") assert os.path.isdir(pCT.cache_dir) print(pCT.cache_dir)
def test_dl_zip_url_notfound_error(self, normal_distribution_url, normal_distribution_json, zip_data, tmpdir): pCT = probeCOCOATek(normal_distribution_url) with requests_mock.Mocker() as m: m.get(normal_distribution_url, content=normal_distribution_json.encode('utf-8')) for url in zip_data.keys(): m.get(url, content=bytes.fromhex(zip_data[url]["raw_data"]), status_code=404) with pytest.raises(requests.exceptions.HTTPError) as e: pCT.download_zips(tmpdir)
def test_tekjson_invalid_data_error(self, nocache, normal_distribution_url, normal_distribution_json, zip_data, invalid_zip_data): pCT = probeCOCOATek(normal_distribution_url) if not nocache: for k,v in zip_data.items(): with open(os.path.join(pCT.cache_dir, os.path.basename(k)), 'wb') as f: f.write(bytes.fromhex(v["raw_data"])) with requests_mock.Mocker() as m: m.get(normal_distribution_url, content=normal_distribution_json.encode('utf-8')) for k,v in zip_data.items(): m.get(k, content=bytes.fromhex(zip_data[k]["raw_data"])) tek_bin = pCT.get_tek_content(k) with pytest.raises(DataError) as e: js_str = pCT.tek_toJson(bytes.fromhex(invalid_zip_data))
def test_list_normal(self, normal_distribution_url, normal_distribution_json, zip_data): pCT = probeCOCOATek(normal_distribution_url) with requests_mock.Mocker() as m: m.get(normal_distribution_url, content=normal_distribution_json.encode('utf-8')) for url in zip_data.keys(): m.get(url, content=bytes.fromhex(zip_data[url]["raw_data"])) tek_zip_list = pCT.get_zip_list() print(tek_zip_list) for t in tek_zip_list: assert t["keys"]["count"] == len(zip_data[t["url"]]["keys"]) assert set(t["keys"]["key_data"]) == set( [z["key_data"] for z in zip_data[t["url"]]["keys"]]) assert os.path.isfile( os.path.join(pCT.cache_dir, os.path.basename(t["url"])))
def test_listtext_normal(self, nokey, normal_distribution_url, normal_distribution_json, zip_data): pCT = probeCOCOATek(normal_distribution_url) with requests_mock.Mocker() as m: m.get(normal_distribution_url, content=normal_distribution_json.encode('utf-8')) for url in zip_data.keys(): m.get(url, content=bytes.fromhex(zip_data[url]["raw_data"])) tek_zip_list = pCT.get_zip_list() text_lines = pCT.zip_list_toText(nokey) zip_list = json.loads(normal_distribution_json) key_cnt = 0 for i,z in enumerate(zip_list): assert True in [(str(i) in l) and (z["url"] in l) and ("[{:%Y-%m-%d %H:%M:%S%z}]".format(datetime.fromtimestamp(round(z["created"] / 1000)).astimezone()) in l) and (str(len(zip_data[z["url"]]["keys"])) in l) for l in text_lines] for i,v in enumerate(zip_data[z["url"]]["keys"]): assert (True in [(v["key_data"] in l) for l in text_lines]) != nokey key_cnt += 1 assert True in [("ZIP Count" in l) and (str(len(zip_list)) in l) for l in text_lines] assert (True in [("Keys Total Count" in l) and (str(key_cnt) in l) for l in text_lines]) != nokey
def test_dl_noexist_dir_normal(self, normal_distribution_url, normal_distribution_json, zip_data, tmpdir): pCT = probeCOCOATek(normal_distribution_url) for k, v in zip_data.items(): assert not os.path.exists(os.path.join(tmpdir, os.path.basename(k))) with requests_mock.Mocker() as m: m.get(normal_distribution_url, content=normal_distribution_json.encode('utf-8')) for url in zip_data.keys(): m.get(url, content=bytes.fromhex(zip_data[url]["raw_data"])) target_dir = os.path.join(tmpdir, "test") assert not os.path.exists(target_dir) pCT.download_zips(target_dir) for k, v in zip_data.items(): assert os.path.exists(target_dir) with open(os.path.join(target_dir, os.path.basename(k)), 'rb') as f: assert v["raw_data"] == f.read().hex()
def test_zip_by_absfile_normal(self, normal_distribution_url, zip_data, tmpdir): for k, v in zip_data.items(): with open(os.path.join(tmpdir, os.path.basename(k)), 'wb') as f: f.write(bytes.fromhex(v["raw_data"])) pCT = probeCOCOATek(normal_distribution_url) for k1, v1 in zip_data.items(): tek_bin = pCT.get_tek_content( os.path.join(tmpdir, os.path.basename(k1))) assert "{:%Y-%m-%d %H:%M:%S%z}".format( datetime.fromtimestamp(tek_bin.start_timestamp).astimezone() ) == "{:%Y-%m-%d %H:%M:%S%z}".format( datetime.strptime(v1["start_timestamp"], "%Y-%m-%d %H:%M:%S%z").astimezone()) assert "{:%Y-%m-%d %H:%M:%S%z}".format( datetime.fromtimestamp(tek_bin.end_timestamp).astimezone() ) == "{:%Y-%m-%d %H:%M:%S%z}".format( datetime.strptime(v1["end_timestamp"], "%Y-%m-%d %H:%M:%S%z").astimezone()) assert tek_bin.region == v1["region"] assert tek_bin.batch_num == v1["batch_num"] assert tek_bin.batch_size == v1["batch_size"] assert tek_bin.signature_infos[0].verification_key_version == v1[ "signature_infos"]["verification_key_version"] assert tek_bin.signature_infos[0].verification_key_id == v1[ "signature_infos"]["verification_key_id"] assert tek_bin.signature_infos[0].signature_algorithm == v1[ "signature_infos"]["signature_algorithm"] assert set([k.key_data.hex() for k in tek_bin.keys ]) == set([z["key_data"] for z in v1["keys"]]) assert set([k.transmission_risk_level for k in tek_bin.keys]) == set( [z["transmission_risk_level"] for z in v1["keys"]]) assert set([ k.rolling_start_interval_number for k in tek_bin.keys ]) == set([z["rolling_start_interval_number"] for z in v1["keys"]]) assert set([k.rolling_period for k in tek_bin.keys ]) == set([z["rolling_period"] for z in v1["keys"]]) assert set([k.report_type for k in tek_bin.keys ]) == set([z["report_type"] for z in v1["keys"]]) assert set([ k.days_since_onset_of_symptoms for k in tek_bin.keys ]) == set([z["days_since_onset_of_symptoms"] for z in v1["keys"]])
def main() -> int: parser = argparse.ArgumentParser( prog='probeCOCOATek', description= 'Probe TemporaryExposureKeys and Files of Exposure Notifications System in Japan a.k.a. "COCOA".', prefix_chars='-') parser.add_argument( "command", nargs=1, default="list", metavar="COMMAND{list,zip,dl}", help= "Command. 'list': Getting ZIP and TEK list with TEK distribution list. 'zip': Taking the ZIP's TEK details. 'dl': Downloading all TEK ZIP and list JSON from TEK distribution list to the specified directory." ) parser.add_argument( "param", nargs="?", default=None, metavar="COMMAND_PARAM", help= "Parameter per Command. With 'list', It means aggregate unit, Either the date('date') or the date and key('key'). With 'zip', specified ZIP url. With 'dl', Specified directory for downloading." ) parser.add_argument( "-nk", "--no-keys", action='store_true', dest="no_keys", help= "Without key information when printing ZIP and TEK list with TEK distribution list. Available with 'list' command." ) parser.add_argument("-nc", "--no-cache", action='store_true', dest="no_cache", help="** Not work yet ** Do not use cache.") parser.add_argument("-f", "--format", choices=("text", "json"), default="text", dest="format_type", help="Output format type, default is 'text'. ") parser.add_argument("-v", "--version", action="version", version=__version__) args = parser.parse_args(sys.argv[1:]) pCT = probeCOCOATek() if args.command is None or args.command == "": command = "list" else: command = args.command[0] if args.param is None or args.param == "": if command == "list": command_param = 'date' else: print("Error happens, command-param is invalid.") return 1 else: command_param = str(args.param) try: if command == "list": try: tek_zip_list = pCT.get_zip_list() if args.format_type == "text": text_lines = pCT.zip_list_toText(args.no_keys) print(os.linesep.join(text_lines)) elif args.format_type == "json": print(pCT.zip_list_toJson(args.no_keys)) else: print("Format type error.") return 1 except Exception as e: print("Error happens, when getting TEK distribution list.") raise e elif command == "zip": try: tek_bin = pCT.get_tek_content(command_param) if args.format_type == "text": text_lines = pCT.tek_toText(tek_bin) print(os.linesep.join(text_lines)) elif args.format_type == "json": print(pCT.tek_toJson(tek_bin)) else: print("Format type error.") return 1 except Exception as e: print("Error happens, when getting TEK ZIP detail.") raise e elif command == "dl": try: pCT.download_zips(command_param) print("Download done.") except Exception as e: print( "Error happens, when downloading TEK ZIP and distribution list." ) raise e else: print("Argument other error happens.") return 1 except Exception as e: tb = sys.exc_info()[2] print(e.with_traceback(tb)) return 1 return 0
def test_constractclass_no_tek_distribution_url_error(self): with pytest.raises(ParamError) as e: pCT = probeCOCOATek("")
def test_constractclass_invalid_cachedir_error(self, tmpdir): t = tmpdir.join("dummy.txt") t.write("dummy") with pytest.raises(ParamError) as e: pCT = probeCOCOATek(cache_dir=t)