diff --git a/source/drm_manager.cpp b/source/drm_manager.cpp index 0dea920b..f7e31d6b 100644 --- a/source/drm_manager.cpp +++ b/source/drm_manager.cpp @@ -148,19 +148,19 @@ class DRM_LOCAL DrmManager::Impl { bool pnc_initialize_drm_ctrl_ta() const { int err = 0; - if ( s_pnc_session == nullptr) { - err = pnc_session_new(PNC_ALLOC_SIZE, &s_pnc_session); - if ( err == -ENODEV ) { - Info( "Provencecore driver is not loaded" ); - return false; - } - if ( err < 0 ) { - Throw( DRM_PncInitError, "Failed to open TrustZone module: {}. ", strerror(errno) ); - } - Debug( "ProvenCore session created. " ); - } else { + if ( s_pnc_session != nullptr) { Debug( "Found and reuse an existing ProvenCore session. " ); + return true; + } + err = pnc_session_new(PNC_ALLOC_SIZE, &s_pnc_session); + if ( err == -ENODEV ) { + Info( "Provencecore driver is not loaded" ); + return false; + } + if ( err < 0 ) { + Throw( DRM_PncInitError, "Failed to open TrustZone module: {}. ", strerror(errno) ); } + Debug( "ProvenCore session created. " ); try { int ret = 0; for (int timeout = 10; timeout > 0; timeout--) { @@ -1361,7 +1361,7 @@ class DRM_LOCAL DrmManager::Impl { Debug( "Build license request #{} to maintain current session", mLicenseCounter ); // Check if an error occurred -// checkDRMCtlrRet( getDrmController().waitNotTimerInitLoaded( 5 ) ); + checkDRMCtlrRet( getDrmController().waitNotTimerInitLoaded( 5 ) ); // Request challenge and metering info for new request checkDRMCtlrRet( getDrmController().synchronousExtractMeteringFile( numberOfDetectedIps, saasChallenge, meteringFile ) ); json_request["saasChallenge"] = saasChallenge; @@ -2339,7 +2339,7 @@ class DRM_LOCAL DrmManager::Impl { setLicense( license_json ); // Check if an error occurred - checkDRMCtlrRet( getDrmController().waitNotTimerInitLoaded( 5 ) ); + //checkDRMCtlrRet( getDrmController().waitNotTimerInitLoaded( 5 ) ); // Extract asynchronous health parameters from response Json::Value metering_node = JVgetOptional( license_json, "metering", Json::objectValue, Json::nullValue ); diff --git a/source/provencore.cpp b/source/provencore.cpp index 60fbc141..8b8746d3 100644 --- a/source/provencore.cpp +++ b/source/provencore.cpp @@ -146,8 +146,6 @@ int pnc_session_new(size_t size, pnc_session_t **session) { pnc_session_t *pnc_new; - printf("pnc_session_new: ENTRY *session=%p, session=%p, size=%ld\n", (void*)*session, (void*)session, size); - /* If we configure the session with a string rather than * a 64 bits id, we need more room in shared memory * to be able to store that string. @@ -173,13 +171,11 @@ int pnc_session_new(size_t size, pnc_session_t **session) *session = pnc_new; - printf("pnc_session_new: EXIT *session=%p, session=%p\n", (void*)*session, (void*)session); return 0; } void pnc_session_destroy(pnc_session_t *session) { - printf("pnc_session_destroy: ENTRY session=%p\n", (void*)session); if (session == NULL || session->fd == -1) { return; } @@ -188,7 +184,6 @@ void pnc_session_destroy(pnc_session_t *session) munmap(session->ptr, session->size); memset(session, 0, sizeof(pnc_session_t)); free(session); - printf("pnc_session_destroy: EXIT session=%p\n", (void*)session); } int pnc_session_config_by_name(pnc_session_t *session, const char *name) diff --git a/tests/conftest.py b/tests/conftest.py index 2b9a8688..9ee61b47 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -89,7 +89,8 @@ def get_default_conf_json(licensing_server_url): }, "settings": { "ws_connection_timeout": 3, - "ws_request_timeout": 5 + "ws_request_timeout": 5, + "ws_api_retry_duration": 5 } } @@ -229,7 +230,7 @@ def pytest_runtest_setup(item): """ Configure test initialization """ - # Check awsxrt tests + # Check awsf1 tests m_option = item.config.getoption('-m') if search(r'\bawsf1\b', m_option) and not search(r'\nnot\n\s+\bawsf1\b', m_option): skip_awsf1 = False @@ -249,12 +250,21 @@ def pytest_runtest_setup(item): if skip_awsxrt and markers: pytest.skip("Don't run XRT (Vitis) tests.") - # Check singleton tests - markers = tuple(item.iter_markers(name='no_parallel')) - if not item.config.getoption("singleton") and markers: - pytest.skip("Don't run singleton tests.") - elif item.config.getoption("singleton") and not markers: - pytest.skip("Run only singleton tests.") + # Determine if DRM Ctrl SW is under test + fpga_image = item.config.getoption('--fpga_image') + if fpga_image and fpga_image.endswith(".som"): + hybrid_test = True + fpga_driver = item.config.getoption('--fpga_driver') + if fpga_driver and fpga_driver == 'som_xrt': + hybrid_test = True + + if not hybrid_test: + # Check singleton tests + markers = tuple(item.iter_markers(name='no_parallel')) + if not item.config.getoption("singleton") and markers: + pytest.skip("Don't run singleton tests.") + elif item.config.getoption("singleton") and not markers: + pytest.skip("Run only singleton tests.") # Check integration tests markers = tuple(item.iter_markers(name='on_2_fpga')) diff --git a/tests/test_async_health.py b/tests/test_async_health.py index 3df8fb97..f9d6b061 100644 --- a/tests/test_async_health.py +++ b/tests/test_async_health.py @@ -449,28 +449,26 @@ def test_async_call_on_pause_when_health_is_enabled(accelize_drm, conf_json, cre conf_json.reset() conf_json['licensing']['url'] = _request.url + 'test_async_call_on_pause_depending_on_health_status' - logfile = log_file_factory.create(2) + logfile = log_file_factory.create(1) conf_json['settings'].update(logfile.json) conf_json.save() - with accelize_drm.DrmManager( - conf_json.path, cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) as drm_manager: - - # Set initial context on the live server - context = {'healthPeriod':300, - 'healthRetry':0, - 'health_cnt':0 - } - set_context(context) - assert get_context() == context + # Set initial context on the live server + context = {'healthPeriod':300, + 'healthRetry':0, + 'health_cnt':0 + } + set_context(context) + assert get_context() == context + with accelize_drm.DrmManager( + conf_json.path, cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) as drm_manager: # First, get license duration to align health period on it drm_manager.activate() - lic_dur = drm_manager.get('license_duration') drm_manager.deactivate(True) # Pause session drm_manager.deactivate() @@ -511,21 +509,20 @@ def test_no_async_call_on_pause_when_health_is_disabled(accelize_drm, conf_json, conf_json['settings'].update(logfile.json) conf_json.save() + # Set initial context on the live server + context = {'healthPeriod':0, + 'healthRetry':0, + 'health_cnt':0 + } + set_context(context) + assert get_context() == context + with accelize_drm.DrmManager( conf_json.path, cred_json.path, driver.read_register_callback, driver.write_register_callback, async_cb.callback ) as drm_manager: - - # Set initial context on the live server - context = {'healthPeriod':0, - 'healthRetry':0, - 'health_cnt':0 - } - set_context(context) - assert get_context() == context - # First, get license duration to align health period on it drm_manager.activate() lic_dur = drm_manager.get('license_duration') diff --git a/tests/test_controller_memory.py b/tests/test_controller_memory.py index 8ff73d7f..a101b457 100644 --- a/tests/test_controller_memory.py +++ b/tests/test_controller_memory.py @@ -6,7 +6,7 @@ from re import search, IGNORECASE -def test_wrong_drm_controller_address(accelize_drm, conf_json, cred_json, async_handle, +def test_wrong_drm_controller_address(accelize_drm, conf_json, cred_json, async_handler, log_file_factory): """Test when a wrong DRM Controller offset is given""" if accelize_drm.is_ctrl_sw: diff --git a/tests/test_drm_bridge.py b/tests/test_drm_bridge.py index 9ba0851b..01a6f220 100644 --- a/tests/test_drm_bridge.py +++ b/tests/test_drm_bridge.py @@ -125,7 +125,7 @@ def test_drm_bridge_on_kria(accelize_drm, async_handler, log_file_factory): assert text_json['product_id']['name'] == 'drm_1activator' assert text_json['extra']['csp'] == 'aws-f1' assert 'dualclk' in text_json['extra'] - assert text_json['drm_software'] + assert text_json['extra']['hybrid'] # Test controller bridge mailbox read-write content ref_list = [] diff --git a/tests/test_metered_mode_on_hw.py b/tests/test_metered_mode_on_hw.py index b9fc7906..39aff1c3 100644 --- a/tests/test_metered_mode_on_hw.py +++ b/tests/test_metered_mode_on_hw.py @@ -330,9 +330,11 @@ def test_metered_pause_resume_long_time(accelize_drm, conf_json, cred_json, asyn @pytest.mark.hwtst -def test_metered_pause_resume_from_new_object(accelize_drm, conf_json, cred_json, async_handler, log_file_factory): +def test_metered_pause_resume_from_new_object(accelize_drm, conf_json, conf_json_second, + cred_json, async_handler, log_file_factory): """ - Test no error occurs in normal pause/resume metering mode when the resume is executed from a new object and before the license expires + Test no error occurs in normal pause/resume metering mode when the resume + is executed from a new object and before the license expires """ driver = accelize_drm.pytest_fpga_driver[0] async_cb = async_handler.create() @@ -341,75 +343,80 @@ def test_metered_pause_resume_from_new_object(accelize_drm, conf_json, cred_json activators.reset_coin() activators.autotest() cred_json.set_user('accelize_accelerator_test_02') - logfile = log_file_factory.create(2) - conf_json['settings'].update(logfile.json) + logfile1 = log_file_factory.create(2) + conf_json['settings'].update(logfile1.json) conf_json.save() - drm_manager1 = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert not drm_manager1.get('session_status') - assert not drm_manager1.get('license_status') - activators.autotest(is_activated=False) - drm_manager1.activate() - start = datetime.now() - assert sum(drm_manager1.get('metered_data')) == 0 - assert drm_manager1.get('session_status') - assert drm_manager1.get('license_status') - session_id = drm_manager1.get('session_id') - assert len(session_id) > 0 - activators.autotest(is_activated=True) - lic_duration = drm_manager1.get('license_duration') - assert sum(drm_manager1.get('metered_data')) == 0 - activators.generate_coin() - activators.check_coin(drm_manager1.get('metered_data')) - assert sum(drm_manager1.get('metered_data')) != 0 - # Wait enough time to be sure the 2nd license has been provisioned - wait_deadline(start, lic_duration/2) - drm_manager1.deactivate(True) - assert drm_manager1.get('session_status') - assert drm_manager1.get('license_status') - assert drm_manager1.get('session_id') == session_id - activators.autotest(is_activated=True) - async_cb.assert_NoError() - sleep(1) - - # Create new object - drm_manager2 = accelize_drm.DrmManager( - conf_json.path, - cred_json.path, - driver.read_register_callback, - driver.write_register_callback, - async_cb.callback - ) - assert drm_manager1 != drm_manager2 - assert drm_manager2.get('session_status') - assert drm_manager2.get('license_status') - activators.autotest(is_activated=True) - assert drm_manager2.get('session_id') == '' - # Resume session - drm_manager2.activate(True) - assert drm_manager2.get('session_status') - assert drm_manager2.get('license_status') - activators.autotest(is_activated=True) - activators.check_coin(drm_manager2.get('metered_data')) - # Wait for license renewal - sleep(lic_duration+2) - assert drm_manager2.get('session_id') == session_id - assert drm_manager2.get('license_duration') == lic_duration - activators.generate_coin() - activators.check_coin(drm_manager2.get('metered_data')) - drm_manager2.deactivate() - assert not drm_manager2.get('session_status') - assert not drm_manager2.get('license_status') - assert drm_manager2.get('session_id') == '' - activators.autotest(is_activated=False) + with accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) as drm_manager1: + assert not drm_manager1.get('session_status') + assert not drm_manager1.get('license_status') + activators.autotest(is_activated=False) + drm_manager1.activate() + start = datetime.now() + assert sum(drm_manager1.get('metered_data')) == 0 + assert drm_manager1.get('session_status') + assert drm_manager1.get('license_status') + session_id = drm_manager1.get('session_id') + assert len(session_id) > 0 + activators.autotest(is_activated=True) + lic_duration = drm_manager1.get('license_duration') + assert sum(drm_manager1.get('metered_data')) == 0 + activators.generate_coin() + activators.check_coin(drm_manager1.get('metered_data')) + assert sum(drm_manager1.get('metered_data')) != 0 + # Wait enough time to be sure the 2nd license has been provisioned + wait_deadline(start, lic_duration/2) + drm_manager1.deactivate(True) + assert drm_manager1.get('session_status') + assert drm_manager1.get('license_status') + assert drm_manager1.get('session_id') == session_id + activators.autotest(is_activated=True) + async_cb.assert_NoError() + sleep(1) + + # Create new object + logfile2 = log_file_factory.create(2) + conf_json_second['settings'].update(logfile2.json) + conf_json_second.save() + + with accelize_drm.DrmManager( + conf_json_second.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) as drm_manager2: + assert drm_manager1 != drm_manager2 + assert drm_manager2.get('session_status') + assert drm_manager2.get('license_status') + activators.autotest(is_activated=True) + assert drm_manager2.get('session_id') == '' + # Resume session + drm_manager2.activate(True) + assert drm_manager2.get('session_status') + assert drm_manager2.get('license_status') + activators.autotest(is_activated=True) + activators.check_coin(drm_manager2.get('metered_data')) + # Wait for license renewal + sleep(lic_duration+2) + assert drm_manager2.get('session_id') == session_id + assert drm_manager2.get('license_duration') == lic_duration + activators.generate_coin() + activators.check_coin(drm_manager2.get('metered_data')) + drm_manager2.deactivate() + assert not drm_manager2.get('session_status') + assert not drm_manager2.get('license_status') + assert drm_manager2.get('session_id') == '' + activators.autotest(is_activated=False) + logfile2.remove() + logfile1.remove() async_cb.assert_NoError() - logfile.remove() @pytest.mark.minimum @@ -747,7 +754,7 @@ def test_async_call_during_pause(accelize_drm, conf_json, cred_json, async_handl activators.generate_coin() activators.check_coin(drm_manager.get('metered_data')) drm_manager.deactivate() - assert sum(drm_manager.get('metered_data')) == 0 + assert sum(drm_manager.get('metered_data')) == 0 log_content = logfile.read() assert len(list(findall(r'warning\b.*\bCannot access metering data when no session is running', log_content))) == 2 async_cb.assert_NoError() diff --git a/tests/test_nodelock_mode_on_hw.py b/tests/test_nodelock_mode_on_hw.py index b98d7c1f..02b1c04c 100644 --- a/tests/test_nodelock_mode_on_hw.py +++ b/tests/test_nodelock_mode_on_hw.py @@ -167,9 +167,6 @@ def test_nodelock_reuse_existing_license(accelize_drm, conf_json, cred_json, asy assert not drm_manager.get('license_status') assert drm_manager.get('drm_license_type') == 'Node-Locked' assert drm_manager.get('license_duration') == 0 - activators.check_coin(drm_manager.get('metered_data')) - activators[0].generate_coin() - activators.check_coin(drm_manager.get('metered_data')) # Stop application drm_manager.deactivate() async_cb.assert_NoError() @@ -191,8 +188,6 @@ def test_nodelock_reuse_existing_license(accelize_drm, conf_json, cred_json, asy assert not drm_manager.get('license_status') assert drm_manager.get('drm_license_type') == 'Node-Locked' assert drm_manager.get('license_duration') == 0 - activators[0].generate_coin() - activators.check_coin(drm_manager.get('metered_data')) # Stop application drm_manager.deactivate() async_cb.assert_NoError() @@ -339,14 +334,19 @@ def test_nodelock_limits(accelize_drm, conf_json, conf_json_second, cred_json, a @pytest.mark.no_parallel @pytest.mark.hwtst def test_metering_mode_is_blocked_after_nodelock_mode(accelize_drm, conf_json, cred_json, - async_handler, ws_admin): + async_handler, ws_admin, log_file_factory): """ Test we cannot switch to metering mode when nodelock is already set. Board needs to be reprogramed """ + if accelize_drm.is_ctrl_sw: + pytest.skip('Not to execute on SoM target') driver = accelize_drm.pytest_fpga_driver[0] async_cb = async_handler.create() cred_json.set_user('accelize_accelerator_test_03') # User with a single nodelock license + logfile = log_file_factory.create(2) + conf_json['settings'].update(logfile.json) + conf_json.save() try: # Set nodelock configuration @@ -367,6 +367,9 @@ def test_metering_mode_is_blocked_after_nodelock_mode(accelize_drm, conf_json, c # Set metering configuration conf_json.reset() + conf_json['settings'].update(logfile.json) + conf_json['settings']['log_file_append'] = True + conf_json.save() with accelize_drm.DrmManager( conf_json.path, cred_json.path, diff --git a/tests/test_trng_quality.py b/tests/test_trng_quality.py index cae56661..0b0b80de 100644 --- a/tests/test_trng_quality.py +++ b/tests/test_trng_quality.py @@ -8,7 +8,7 @@ from glob import glob from os import remove from os.path import getsize, isfile, dirname, join, realpath, basename -from re import search, findall, finditer, MULTILINE +from re import finditer from time import sleep, time from json import loads, dumps from datetime import datetime, timedelta @@ -23,12 +23,11 @@ LOG_FORMAT_LONG = "%Y-%m-%d %H:%M:%S.%e - %18s:%-4# [%=8l] %=6t, %v" -REGEX_PATTERN = r'Starting license request to \S+ with request:\n(^{.+?\n}$)' +REGEX_PATTERN = r'Starting (?:license|Health) request to \S+ with data:\n(^{.+?\n}$)' def parse_and_save_challenge(text, pattern, save_path=None): # Parse log file - print('Parsing requests from log file: %s' % logpath) request_list = list() for challenge in finditer(pattern, text, re.I | re.MULTILINE | re.DOTALL): request_list.append(loads(challenge.group(1))) @@ -274,9 +273,10 @@ def test_dna_and_challenge_duplication(accelize_drm, conf_json, cred_json, async @pytest.mark.no_parallel -def test_saas_challenge_quality(accelize_drm, conf_json, cred_json, async_handler, - log_file_factory): - nb_loop = 5 +def test_saas_challenge_quality_through_activates(accelize_drm, conf_json, + cred_json, async_handler, log_file_factory): + nb_loop = 3 + nb_req = 2 driver = accelize_drm.pytest_fpga_driver[0] async_cb = async_handler.create() async_cb.reset() @@ -292,9 +292,60 @@ def test_saas_challenge_quality(accelize_drm, conf_json, cred_json, async_handle ) as drm_manager: for i in range(nb_loop): drm_manager.activate() + lic_period = drm_manager.get('license_duration') + health_period = drm_manager.get('health_period') + max_period = max(lic_period, health_period) + while True: + if drm_manager.get('num_license_loaded') == 2: + sleep(nb_req*max_period + 2) + break + sleep(0.1) + drm_manager.deactivate() + log_content = logfile.read() + # Parse log file + challenge_list = parse_and_save_challenge(log_content, REGEX_PATTERN) + challenge_list = list(map(lambda x: x['saasChallenge'], challenge_list)) + ratio = int(max_period / min(lic_period, health_period)) + assert len(challenge_list) >= nb_loop * (nb_req + ratio + 2) + challenge_set = set(challenge_list) + try: + assert len(challenge_list) == len( challenge_set), "Found duplicate saas challenge" + except AssertionError as e: + dupl_dict = {} + for e in challenge_set: + nb = challenge_list.count(e) + if nb > 1: + print(f'challenge {e} appears {nb} times') + raise + logfile.remove() + async_cb.assert_NoError() + + +@pytest.mark.no_parallel +def test_saas_challenge_quality_through_instances(accelize_drm, conf_json, + cred_json, async_handler, log_file_factory): + nb_loop = 5 + driver = accelize_drm.pytest_fpga_driver[0] + async_cb = async_handler.create() + async_cb.reset() + logfile = log_file_factory.create(1) + conf_json['settings'].update(logfile.json) + conf_json['settings']['log_file_append'] = True + conf_json.save() + for i in range(nb_loop): + with accelize_drm.DrmManager( + conf_json.path, + cred_json.path, + driver.read_register_callback, + driver.write_register_callback, + async_cb.callback + ) as drm_manager: + drm_manager.activate() drm_manager.deactivate() log_content = logfile.read() - challenge_list = list(findall(r'"saasChallenge" : "([a-fA-F0-9]{32})",', log_content)) + challenge_list = parse_and_save_challenge(log_content, REGEX_PATTERN) + challenge_list = list(map(lambda x: x['saasChallenge'], challenge_list)) + assert len(challenge_list) >= nb_loop * 2 challenge_set = set(challenge_list) try: assert len(challenge_list) == len( challenge_set), "Found duplicate saas challenge" @@ -307,3 +358,4 @@ def test_saas_challenge_quality(accelize_drm, conf_json, cred_json, async_handle raise logfile.remove() async_cb.assert_NoError() +