def test_WINNF_FT_S_GPR_3(self, config_filename): """GWPZ Exclusion Zone One or more CBSDs, located inside a GWPZ, request Grants and are rejected """ config = loadConfig(config_filename) # Step1: Admin Test Harness injects a GWPZ into the SAS UUT self._sas_admin.InjectWisp(config['gwpzRecord']) # Step2: Admin Test Harness triggers CPAS and waits until completion of CPAS self.TriggerDailyActivitiesImmediatelyAndWaitUntilComplete() # Step3: DP Test Harness registers N > 0 CBSDs cbsd_ids = self.assertRegistered(config['registrationRequests'], config['conditionalRegistrationData']) # Step4: DP Test Harness requests one Grant per registered CBSD grant_request = config['grantRequests'] addCbsdIdsToRequests(cbsd_ids, grant_request) request = {'grantRequest': grant_request} response = self._sas.Grant(request)['grantResponse'] self.assertEqual(len(response), len(grant_request)) for response_num, response in enumerate(response): self.assertEqual(response['cbsdId'], request['grantRequest'][response_num]['cbsdId']) self.assertEqual(response['response']['responseCode'], 400)
def test_WINNF_FT_S_RLQ_6(self, config_filename): """[Configurable] Multiple Relinquishments.""" config = loadConfig(config_filename) # Very light checking of the config file. self.assertValidConfig( config, { 'registrationRequests': list, 'conditionalRegistrationData': list, 'grantRequests': list, 'relinquishmentRequestsFirst': list, 'relinquishmentRequestsSecond': list, 'expectedResponseCodesFirst': list, 'expectedResponseCodesSecond': list }) self.assertEqual(len(config['relinquishmentRequestsFirst']), len(config['expectedResponseCodesFirst'])) self.assertEqual(len(config['relinquishmentRequestsSecond']), len(config['expectedResponseCodesSecond'])) # Whitelist FCC IDs. for device in config['registrationRequests']: self._sas_admin.InjectFccId({ 'fccId': device['fccId'], 'fccMaxEirp': 47 }) # Whitelist user IDs. for device in config['registrationRequests']: self._sas_admin.InjectUserId({'userId': device['userId']}) # Register devices and get grants try: cbsd_ids, grant_ids = self.assertRegisteredAndGranted( config['registrationRequests'], config['grantRequests'], config['conditionalRegistrationData']) except Exception: logging.error( common_strings.EXPECTED_SUCCESSFUL_REGISTRATION_AND_GRANT) raise # First relinquishment relinquishment_request = config['relinquishmentRequestsFirst'] addCbsdIdsToRequests(cbsd_ids, relinquishment_request) addGrantIdsToRequests(grant_ids, relinquishment_request) request = {'relinquishmentRequest': relinquishment_request} responses = self._sas.Relinquishment(request)['relinquishmentResponse'] # Check relinquishment response self.assertEqual(len(responses), len(config['expectedResponseCodesFirst'])) relinquished_grant_ids = [] has_error = False for i, response in enumerate(responses): expected_response_codes = config['expectedResponseCodesFirst'][i] logging.debug('Looking at response number %d', i) logging.debug( 'Expecting to see response code in set %s in response: %s', expected_response_codes, response) # Check response code. response_code = response['response']['responseCode'] if response_code not in expected_response_codes: has_error = True logging.error( 'Error: response %d is expected to have a responseCode in set %s but instead had responseCode %d.', i, expected_response_codes, response_code) logging.error('Relinquishment request: %s', config['relinquishmentRequestsFirst'][i]) logging.error('Relinquishment response: %s', response) # "If the corresponding request contained a valid cbsdId and grantId, the # response shall contain the same grantId." if 'cbsdId' and 'grantId' in relinquishment_request[i]: if (relinquishment_request[i]['cbsdId'] in cbsd_ids) and (relinquishment_request[i]['grantId'] in grant_ids): cbsd_index = cbsd_ids.index( relinquishment_request[i]['cbsdId']) grant_index = grant_ids.index( relinquishment_request[i]['grantId']) # Check if CBSD ID is paired with the corresponding Grant ID. if cbsd_index == grant_index: self.assertEqual(response['grantId'], relinquishment_request[i]['grantId']) relinquished_grant_ids.append(response['grantId']) del request, responses # Outside the 'for' loop. # Test will stop here if there are any errors, else continue. self.assertFalse( has_error, 'Error found in at least one of the responses. See logs for details.' ) # Second relinquishment relinquishment_request = config['relinquishmentRequestsSecond'] addCbsdIdsToRequests(cbsd_ids, relinquishment_request) addGrantIdsToRequests(grant_ids, relinquishment_request) request = {'relinquishmentRequest': relinquishment_request} responses = self._sas.Relinquishment(request)['relinquishmentResponse'] # Check relinquishment response self.assertEqual(len(responses), len(config['expectedResponseCodesSecond'])) for i, response in enumerate(responses): expected_response_codes = config['expectedResponseCodesSecond'][i] logging.debug('Looking at response number %d', i) logging.debug( 'Expecting to see response code in set %s in response: %s', expected_response_codes, response) # Check response code. response_code = response['response']['responseCode'] if response_code not in expected_response_codes: has_error = True logging.error( 'Error: response %d is expected to have a responseCode in set %s but instead had responseCode %d.', i, expected_response_codes, response_code) logging.error('Relinquishment request: %s', config['relinquishmentRequestsSecond'][i]) logging.error('Relinquishment response: %s', response) if 'cbsdId' and 'grantId' in relinquishment_request[i]: if (relinquishment_request[i]['cbsdId'] in cbsd_ids) and (relinquishment_request[i]['grantId'] in grant_ids): cbsd_index = cbsd_ids.index( relinquishment_request[i]['cbsdId']) grant_index = grant_ids.index( relinquishment_request[i]['grantId']) if cbsd_index == grant_index: if relinquishment_request[i][ 'grantId'] not in relinquished_grant_ids: self.assertEqual( response['grantId'], relinquishment_request[i]['grantId']) # Outside the 'for' loop. self.assertFalse( has_error, 'Error found in at least one of the responses. See logs for details.' )
def test_WINNF_FT_S_DRG_6(self, config_filename): """[Configurable] Array Deregistration.""" config = loadConfig(config_filename) # Very light checking of the config file. self.assertValidConfig( config, { 'registrationRequests': list, 'conditionalRegistrationData': list, 'grantRequests': list, 'heartbeatRequests': list, 'deregistrationRequests': list, 'expectedResponseCodes': list }) self.assertEqual(len(config['registrationRequests']), len(config['grantRequests'])) self.assertEqual(len(config['grantRequests']), len(config['heartbeatRequests'])) self.assertEqual(len(config['heartbeatRequests']), len(config['deregistrationRequests'])) self.assertEqual(len(config['deregistrationRequests']), len(config['expectedResponseCodes'])) # Whitelist FCC IDs. for device in config['registrationRequests']: self._sas_admin.InjectFccId({ 'fccId': device['fccId'], 'fccMaxEirp': 47 }) # Whitelist user IDs. for device in config['registrationRequests']: self._sas_admin.InjectUserId({'userId': device['userId']}) # Step 2 & 3: Register devices and get grants try: cbsd_ids, grant_ids = self.assertRegisteredAndGranted( config['registrationRequests'], config['grantRequests'], config['conditionalRegistrationData']) except Exception: logging.error( common_strings.EXPECTED_SUCCESSFUL_REGISTRATION_AND_GRANT) raise # Step 4: First Heartbeat Request heartbeat_request = config['heartbeatRequests'] addCbsdIdsToRequests(cbsd_ids, heartbeat_request) addGrantIdsToRequests(grant_ids, heartbeat_request) request = {'heartbeatRequest': heartbeat_request} responses = self._sas.Heartbeat(request)['heartbeatResponse'] self.assertEqual(len(responses), len(heartbeat_request)) # Check heartbeat response for i, response in enumerate(responses): self.assertEqual(response['response']['responseCode'], 0) del request, responses # Step 5: First deregistration request deregister_request = config['deregistrationRequests'] addCbsdIdsToRequests(cbsd_ids, deregister_request) request = {'deregistrationRequest': deregister_request} responses_1 = self._sas.Deregistration( request)['deregistrationResponse'] # Check the deregistration response self.assertEqual(len(responses_1), len(config['expectedResponseCodes'])) has_error = False registration_request = config['registrationRequests'] conditional_registration_data = config['conditionalRegistrationData'] for i, response in enumerate(responses_1): expected_response_codes = config['expectedResponseCodes'][i] logging.debug('Looking at response number %d', i) logging.debug( 'Expecting to see response code in set %s in response: %s', expected_response_codes, response) # Check response code. response_code = response['response']['responseCode'] if response_code not in expected_response_codes: has_error = True logging.error( 'Error: response %d is expected to have a responseCode in set %s but instead had responseCode %d.', i, expected_response_codes, response_code) logging.error('Deregistration request: %s', config['deregistrationRequests'][i]) logging.error('Deregistration response: %s', response) # "If the corresponding request contained a valid cbsdId, the # response shall contain the same cbsdId." if 'cbsdId' in deregister_request[i]: if deregister_request[i]['cbsdId'] in cbsd_ids: self.assertEqual(response['cbsdId'], deregister_request[i]['cbsdId']) else: self.assertFalse('cbsdId' in response) # remove still registered CBSDs from the next preload conditional registration if response['response']['responseCode'] != 0: cbsd_to_be_removed_from_next_reg = registration_request[i] indexes_conditional_to_remove = [ index for index, c in enumerate(conditional_registration_data) if c['cbsdSerialNumber'] == cbsd_to_be_removed_from_next_reg['cbsdSerialNumber'] and c['fccId'] == cbsd_to_be_removed_from_next_reg['fccId'] ] for index in reversed(indexes_conditional_to_remove): del conditional_registration_data[index] # Outside the 'for' loop. # Test will stop here if there are any errors, else continue. self.assertFalse( has_error, 'Error found in at least one of the responses. See logs for details.' ) # Step 6: Send the Deregistration request from Step 5 again request = {'deregistrationRequest': deregister_request} responses_2 = self._sas.Deregistration( request)['deregistrationResponse'] # Check the deregistration response self.assertEqual(len(responses_2), len(deregister_request)) self.assertEqual(len(responses_2), len(responses_1)) # If the corresponding responseCode in the previous Deregistration Response # Message was 102, the responseCode shall be 102. for i, (response1, response2) in enumerate( (zip(responses_1, responses_2))): logging.debug('Looking at response number %d, response: %s', i, response2) if response1['response']['responseCode'] == 102: self.assertEqual(response2['response']['responseCode'], 102) else: # Otherwise, the responseCode shall be INVALID_VALUE or DEREGISTER. self.assertTrue( response2['response']['responseCode'] in [103, 105]) self.assertFalse('cbsdId' in response2) del request, responses_2 # Step 7: Send registration request from Step 2 cbsd_ids = self.assertRegistered(registration_request, conditional_registration_data) # Step 8: Heartbeat Request heartbeat_requests = config['heartbeatRequests'] addCbsdIdsToRequests(cbsd_ids, heartbeat_requests) request = {'heartbeatRequest': heartbeat_requests} responses = self._sas.Heartbeat(request)['heartbeatResponse'] self.assertEqual(len(responses), len(heartbeat_requests)) # Check heartbeat response for i, response in enumerate(responses): logging.debug('Looking at response number %d', i) logging.debug('Actual response: %s', response) self.assertTrue(response['response']['responseCode'] in [103, 500])
def test_WINNF_FT_S_EXZ_2(self, config_filename): """Exclusion Zones defined in NTIA TR 15-517 The responseCode = 400 for CBSDs located within 50meters of all Exclusion Zones or inside Exclusion Zones. """ config = loadConfig(config_filename) # Very light checking of the config file. self.assertEqual(len(config['registrationRequestsN1']), len(config['grantRequestsN1'])) self.assertEqual(len(config['registrationRequestsN2']), len(config['grantRequestsN2'])) self.assertEqual(len(config['registrationRequestsN3']), len(config['grantRequestsN3'])) # Enforce NTIA Exlusion zones self._sas_admin.TriggerEnableNtiaExclusionZones() try: # Register N1 devices cbsd_ids_N1 = self.assertRegistered( config['registrationRequestsN1'], config['conditionalRegistrationDataN1']) # Register N2 devices cbsd_ids_N2 = self.assertRegistered( config['registrationRequestsN2'], config['conditionalRegistrationDataN2']) # Register N3 devices cbsd_ids_N3 = self.assertRegistered( config['registrationRequestsN3'], config['conditionalRegistrationDataN3']) except Exception as e: logging.error(common_strings.EXPECTED_SUCCESSFUL_REGISTRATION) # Trigger daily activities self.TriggerDailyActivitiesImmediatelyAndWaitUntilComplete() # Generating grant requests for N1 and validating responses grant_request_N1 = config['grantRequestsN1'] addCbsdIdsToRequests(cbsd_ids_N1, grant_request_N1) request_N1 = {'grantRequest': grant_request_N1} response_N1 = self._sas.Grant(request_N1)['grantResponse'] self.assertEqual(len(response_N1), len(grant_request_N1)) # Generating grant requests for N2 and validating responses # Request grant grant_request_N2 = config['grantRequestsN2'] addCbsdIdsToRequests(cbsd_ids_N2, grant_request_N2) request_N2 = {'grantRequest': grant_request_N2} response_N2 = self._sas.Grant(request_N2)['grantResponse'] self.assertEqual(len(response_N2), len(grant_request_N2)) for response_num, response in enumerate(response_N2): self.assertEqual( response['cbsdId'], request_N2['grantRequest'][response_num]['cbsdId']) self.assertFalse('grantId' in response) self.assertEqual(response['response']['responseCode'], 400) # Generating grant requests for N3 and validating responses grant_request_N3 = config['grantRequestsN3'] addCbsdIdsToRequests(cbsd_ids_N3, grant_request_N3) request_N3 = {'grantRequest': grant_request_N3} response_N3 = self._sas.Grant(request_N3)['grantResponse'] self.assertEqual(len(response_N3), len(grant_request_N3)) for response_num, response in enumerate(response_N3): self.assertEqual( response['cbsdId'], request_N3['grantRequest'][response_num]['cbsdId']) self.assertFalse('grantId' in response) self.assertEqual(response['response']['responseCode'], 400)
def test_WINNF_FT_S_DRG_6(self, config_filename): """[Configurable] Array Deregistration.""" config = loadConfig(config_filename) # Very light checking of the config file. self.assertValidConfig( config, { 'registrationRequests': list, 'conditionalRegistrationData': list, 'grantRequests': list, 'heartbeatRequests': list, 'deregistrationRequests': list, 'expectedResponseCodes': list }) self.assertEqual(len(config['registrationRequests']), len(config['grantRequests'])) self.assertEqual(len(config['grantRequests']), len(config['heartbeatRequests'])) self.assertEqual(len(config['heartbeatRequests']), len(config['deregistrationRequests'])) self.assertEqual(len(config['deregistrationRequests']), len(config['expectedResponseCodes'])) # Whitelist FCC IDs. for device in config['registrationRequests']: self._sas_admin.InjectFccId({ 'fccId': device['fccId'], 'fccMaxEirp': 47 }) # Whitelist user IDs. for device in config['registrationRequests']: self._sas_admin.InjectUserId({'userId': device['userId']}) # Step 2 & 3: Register devices and get grants try: cbsd_ids, grant_ids = self.assertRegisteredAndGranted( config['registrationRequests'], config['grantRequests'], config['conditionalRegistrationData']) except Exception: logging.error( common_strings.EXPECTED_SUCCESSFUL_REGISTRATION_AND_GRANT) raise # Step 4: First Heartbeat Request heartbeat_request = config['heartbeatRequests'] addCbsdIdsToRequests(cbsd_ids, heartbeat_request) addGrantIdsToRequests(grant_ids, heartbeat_request) request = {'heartbeatRequest': heartbeat_request} responses = self._sas.Heartbeat(request)['heartbeatResponse'] self.assertEqual(len(responses), len(heartbeat_request)) # Check heartbeat response for i, response in enumerate(responses): self.assertEqual(response['response']['responseCode'], 0) del request, responses # Step 5: First deregistration request deregister_request = config['deregistrationRequests'] addCbsdIdsToRequests(cbsd_ids, deregister_request) request = {'deregistrationRequest': deregister_request} responses_1 = self._sas.Deregistration( request)['deregistrationResponse'] # Check the deregistration response self.assertEqual(len(responses_1), len(config['expectedResponseCodes'])) for i, response in enumerate(responses_1): expected_response_codes = config['expectedResponseCodes'][i] logging.debug('Looking at response number %d', i) logging.debug( 'Expecting to see response code in set %s in response: %s', expected_response_codes, response) self.assertIn(response['response']['responseCode'], expected_response_codes) # "If the corresponding request contained a valid cbsdId, the # response shall contain the same cbsdId." if 'cbsdId' in deregister_request[i]: if deregister_request[i]['cbsdId'] in cbsd_ids: self.assertEqual(response['cbsdId'], deregister_request[i]['cbsdId']) else: self.assertFalse('cbsdId' in response) # Step 6: Send the Deregistration request from Step 5 again request = {'deregistrationRequest': deregister_request} responses_2 = self._sas.Deregistration( request)['deregistrationResponse'] # Check the deregistration response self.assertEqual(len(responses_2), len(deregister_request)) self.assertEqual(len(responses_2), len(responses_1)) # If the corresponding responseCode in the previous Deregistration Response # Message was 102, the responseCode shall be 102. for i, (response1, response2) in enumerate( (zip(responses_1, responses_2))): logging.debug('Looking at response number %d, response: %s', i, response2) if response1['response']['responseCode'] == 102: self.assertEqual(response2['response']['responseCode'], 102) else: # Otherwise, the responseCode shall be INVALID_VALUE or DEREGISTER. self.assertTrue( response2['response']['responseCode'] in [103, 105]) self.assertFalse('cbsdId' in response2) del request, responses_2 # Step 7: Send registration request from Step 2 cbsd_ids = self.assertRegistered(config['registrationRequests'], config['conditionalRegistrationData']) # Step 8: Heartbeat Request heartbeat_requests = config['heartbeatRequests'] addCbsdIdsToRequests(cbsd_ids, heartbeat_requests) request = {'heartbeatRequest': heartbeat_requests} responses = self._sas.Heartbeat(request)['heartbeatResponse'] self.assertEqual(len(responses), len(heartbeat_requests)) # Check heartbeat response for i, response in enumerate(responses): logging.debug('Looking at response number %d', i) logging.debug('Actual response: %s', response) self.assertTrue(response['response']['responseCode'] in [103, 500])
def test_WINNF_FT_S_HBT_10(self, config_filename): """[Configurable] Heartbeat with optional intervening grant termination or blacklist.""" config = loadConfig(config_filename) # Very light checking of the config file. self.assertValidConfig( config, { 'registrationRequests': list, 'conditionalRegistrationData': list, 'fccIdsBlacklist': list, 'grantRequests': list, 'heartbeatRequests': list, 'expectedResponseCodes': list }) self.assertEqual(len(config['registrationRequests']), len(config['grantRequests'])) self.assertEqual(len(config['grantRequests']), len(config['heartbeatRequests'])) self.assertEqual(len(config['heartbeatRequests']), len(config['expectedResponseCodes'])) # Register devices try: cbsd_ids = self.assertRegistered( config['registrationRequests'], config['conditionalRegistrationData']) except Exception: logging.error(common_strings.EXPECTED_SUCCESSFUL_REGISTRATION) raise # Request grant grant_request = config['grantRequests'] addCbsdIdsToRequests(cbsd_ids, grant_request) request = {'grantRequest': grant_request} # Check grant response response = self._sas.Grant(request)['grantResponse'] self.assertEqual(len(response), len(grant_request)) grant_ids = [] grant_expire_times = [] for _, resp in enumerate(response): self.assertEqual(resp['response']['responseCode'], 0) grant_ids.append(resp['grantId']) grant_expire_times.append( datetime.strptime(resp['grantExpireTime'], '%Y-%m-%dT%H:%M:%SZ')) del request, response # Blacklist N2 CBSDs for fcc_id in config['fccIdsBlacklist']: self._sas_admin.BlacklistByFccId({'fccId': fcc_id}) blacklisted_cbsd_ids = [] for cbsd_id, request in zip(cbsd_ids, config['registrationRequests']): if request['fccId'] in config['fccIdsBlacklist']: blacklisted_cbsd_ids.append(cbsd_id) # First Heartbeat Request heartbeat_request = config['heartbeatRequests'] addCbsdIdsToRequests(cbsd_ids, heartbeat_request) addGrantIdsToRequests(grant_ids, heartbeat_request) request = {'heartbeatRequest': heartbeat_request} responses = self._sas.Heartbeat(request)['heartbeatResponse'] self.assertEqual(len(responses), len(heartbeat_request)) # Check heartbeat response self.assertEqual(len(responses), len(config['expectedResponseCodes'])) for i, response in enumerate(responses): expected_response_codes = config['expectedResponseCodes'][i] logging.debug('Looking at response number %d', i) logging.debug( 'Expecting to see response code in set %s in response: %s', expected_response_codes, response) self.assertIn(response['response']['responseCode'], expected_response_codes) # Check if the request contains CBSD ID if 'cbsdId' in heartbeat_request[i]: # Check if CBSD ID is valid if (heartbeat_request[i]['cbsdId'] in cbsd_ids) and (heartbeat_request[i]['cbsdId'] not in blacklisted_cbsd_ids): self.assertEqual(response['cbsdId'], heartbeat_request[i]['cbsdId']) # Check if the request contains Grant ID if 'grantId' in heartbeat_request[i]: # Check if Grant ID is valid if heartbeat_request[i]['grantId'] in grant_ids: cbsd_index = cbsd_ids.index( heartbeat_request[i]['cbsdId']) grant_index = grant_ids.index( heartbeat_request[i]['grantId']) # Check if CBSD ID is paired with the corresponding Grant ID. if cbsd_index == grant_index: self.assertEqual( response['grantId'], heartbeat_request[i]['grantId']) if response['response']['responseCode'] == 0: transmit_expire_time = datetime.strptime( response['transmitExpireTime'], '%Y-%m-%dT%H:%M:%SZ') self.assertLess(datetime.utcnow(), transmit_expire_time) self.assertLessEqual( (transmit_expire_time - datetime.utcnow()).total_seconds(), 240) self.assertLessEqual(transmit_expire_time, grant_expire_times[i]) if ('grantRenew' in heartbeat_request[i]) and ( heartbeat_request[i]['grantRenew']): grant_expire_time = datetime.strptime( response['grantExpireTime'], '%Y-%m-%dT%H:%M:%SZ') self.assertLess(datetime.utcnow(), grant_expire_time) else: transmit_expire_time = datetime.strptime( response['transmitExpireTime'], '%Y-%m-%dT%H:%M:%SZ') self.assertLessEqual(transmit_expire_time, datetime.utcnow())