def expected_snapshot( test_case: TestCase, bridge_name: str, current_snapshot, snapshot_name: Optional[str] = None, ) -> Tuple[str, List[str]]: if snapshot_name is not None: combined_name = '{}.{}{}'.format( test_case.id(), snapshot_name, SNAPSHOT_EXTENSION, ) else: combined_name = '{}{}'.format(test_case.id(), SNAPSHOT_EXTENSION) snapshot_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), SNAPSHOT_DIR, combined_name, ) try: with open(snapshot_file, 'r') as file: prev_snapshot = [] for line in file: prev_snapshot.append(line.rstrip('\n')) except OSError as e: fail(test_case, str(e), bridge_name, combined_name, current_snapshot) return snapshot_file, prev_snapshot
def assert_bridge_snapshot_match(test_case: TestCase, bridge_name: str, service_manager: ServiceManager, snapshot_name: Optional[str] = None, include_stats: bool = True): """ Verifies the current bridge snapshot matches the snapshot saved in file for the given test case. Fails the test case if the snapshots differ. Args: test_case: Test case instance of the current test bridge_name: Name of the bridge service_manager: Service manager instance used to obtain the app to table number mapping snapshot_name: Name of the snapshot. For tests with multiple snapshots, this is used to distinguish the snapshots """ if snapshot_name is not None: combined_name = '{}.{}{}'.format(test_case.id(), snapshot_name, SNAPSHOT_EXTENSION) else: combined_name = '{}{}'.format(test_case.id(), SNAPSHOT_EXTENSION) snapshot_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), SNAPSHOT_DIR, combined_name) current_snapshot = _get_current_bridge_snapshot(bridge_name, service_manager, include_stats=include_stats) def fail(err_msg: str, _bridge_name: str): ofctl_cmd = "sudo ovs-ofctl dump-flows %s" % _bridge_name p = subprocess.Popen([ofctl_cmd], stdout=subprocess.PIPE, shell=True) ofctl_dump = p.stdout.read().decode("utf-8").strip() logging.error("cmd ofctl_dump: %s", ofctl_dump) msg = 'Snapshot mismatch with error:\n' \ '{}\n' \ 'To fix the error, update "{}" to the current snapshot:\n' \ '{}'.format(err_msg, snapshot_file, '\n'.join(current_snapshot)) return test_case.fail(msg) try: with open(snapshot_file, 'r') as file: prev_snapshot = [] for line in file: prev_snapshot.append(line.rstrip('\n')) except OSError as e: fail(str(e), bridge_name) return if set(current_snapshot) != set(prev_snapshot): fail('\n'.join(list(unified_diff(prev_snapshot, current_snapshot, fromfile='previous snapshot', tofile='current snapshot'))), bridge_name)
def test_get_interactions_file_not_exists_mapping_and_ggis_exist(self): """File for the ppis does not exist, it is created. Files ggis and entrez to uniprot exist.""" filename_ppis = TestCase.id(self) + '_ppis.txt' filename_ggis = TestCase.id(self) + '_ggis.txt' filename_entrez_to_uniprot = TestCase.id( self) + '_entrez_to_uniprot.txt' # Create entrez_to_uniprot file with open(filename_entrez_to_uniprot, 'w') as file_entrez_to_uniprot: file_entrez_to_uniprot.write( '6416\tP45985\n84665\tA0A087WX60\n84665\tQ86TC9\n90\tD3DPA4\n90\tQ04771\n' ) file_entrez_to_uniprot.write( '2624\tP23769\n6118\tB4DUL2\n6118\tP15927\n') # Create ggis file with open(filename_ggis, 'w') as file_ggis: file_ggis.write( 'BioGRID Interaction ID\tEntrez Gene Interactor A\tEntrez Gene Interactor B\tOther1\n' ) file_ggis.write('0\t6416\t84665\t0\n' + '1\t90\t2624\t1\n' + '2\t84665\t6118\t2\n') # Assert preconditions self.assertFalse(os.path.exists(filename_ppis), msg='As precondition ppis file should not exist') self.assertTrue(os.path.exists(filename_ggis), msg='As precondition ggis file should exist') self.assertTrue( os.path.exists(filename_entrez_to_uniprot), msg='As precondition entrez_to_uniprot file should exist') # Execute target method result = biogrid.get_interactions('', '', '', filename_ggis, filename_ppis, filename_entrez_to_uniprot, 1) # Check if dictionary is right try: self.assertEqual(dict, type(result)) self.assertEqual(6, len(result.keys())) for key in [ 'A0A087WX60', 'B4DUL2', 'D3DPA4', 'P15927', 'P23769', 'P45985' ]: self.assertIn(key, result.keys(), msg=f"Missing key {key}") self.assertIn('Q86TC9', result['B4DUL2']) self.assertIn('Q04771', result['P23769']) self.assertIn('Q86TC9', result['P45985']) finally: os.remove(filename_ggis) os.remove(filename_ppis) os.remove(filename_entrez_to_uniprot)
def assert_bridge_snapshot_match(test_case: TestCase, bridge_name: str, service_manager: ServiceManager, snapshot_name: Optional[str] = None): """ Verifies the current bridge snapshot matches the snapshot saved in file for the given test case. Fails the test case if the snapshots differ. Args: test_case: Test case instance of the current test bridge_name: Name of the bridge service_manager: Service manager instance used to obtain the app to table number mapping snapshot_name: Name of the snapshot. For tests with multiple snapshots, this is used to distinguish the snapshots """ if snapshot_name is not None: combined_name = '{}.{}{}'.format(test_case.id(), snapshot_name, SNAPSHOT_EXTENSION) else: combined_name = '{}{}'.format(test_case.id(), SNAPSHOT_EXTENSION) snapshot_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), SNAPSHOT_DIR, combined_name) current_snapshot = _get_current_bridge_snapshot(bridge_name, service_manager) def fail(err_msg: str): msg = 'Snapshot mismatch with error:\n' \ '{}\n' \ 'To fix the error, update "{}" to the current snapshot:\n' \ '{}'.format(err_msg, snapshot_file, '\n'.join(current_snapshot)) return test_case.fail(msg) try: with open(snapshot_file, 'r') as file: prev_snapshot = [] for line in file: prev_snapshot.append(line.rstrip('\n')) except OSError as e: fail(str(e)) return if set(current_snapshot) != set(prev_snapshot): fail('\n'.join( list( unified_diff(prev_snapshot, current_snapshot, fromfile='previous snapshot', tofile='current snapshot'))))
def test_read_dictionary_skip_header(self): # Create trio file with headers trios = [('Column1', 'Column2', 'Column3'), (1, 1, 2), (2, 3, 2), (3, 4, 5)] file_name = TestCase.id(self) + '_pairs.txt' with open(file_name, 'w') as file: for x, y, z in trios: file.write(f"{x}\t{y}\t{z}\n") # Execute target method result = read_dictionary_one_to_set('', file_name, order_pairs=True, col_indices=(1, 2), ignore_header=True) # Check headers are not taken as key, value pairs self.assertNotIn('Column1', result.keys(), msg="Missing key in dictionary") self.assertIn('1', result.keys(), msg="Missing key in dictionary") self.assertIn('2', result.keys(), msg="Missing key in dictionary") self.assertIn('4', result.keys(), msg="Missing key in dictionary") # Remove precondition files os.remove(file_name)
def random_key_for_test(test_case: unittest.TestCase) -> str: """ The atrociously-named TestCase#id returns things like tests.test_ip_address_node.TestIpAddressQuery.test__single_ip_addr_node__query_by_node_key letting us tie back a node to the test that created it """ return "{}{}".format(test_case.id(), uuid.uuid4())
def test_write_dictionary_one_to_set_empty_path_works(self): file_name = TestCase.id(self) + '_friends.txt' self.assertFalse(os.path.exists(file_name), msg='The file should not exist as precondition') write_dictionary_one_to_set(self.friends, '', file_name) self.assertTrue(os.path.exists(file_name), msg='The file was not created') os.remove(file_name)
def test_write_dictionary_one_to_set_non_existent_path_creates_file(self): file_name = TestCase.id(self) + '_friends.txt' file_path = 'a/path/' self.assertFalse(os.path.exists(file_path + file_name), msg='The file should not exist as precondition') write_dictionary_one_to_set(self.friends, file_path, file_name) self.assertTrue(os.path.exists(file_path + file_name), msg='The file was not created') os.remove(file_path + file_name) os.rmdir('a/path/') os.rmdir('a/')
def addSuccess(self, test: unittest.TestCase) -> None: """ Record that a test passed. """ self.results.append({ "status": "success", "name": test.id(), "errors": "", "description": test._testMethodDoc }) self.successes.append(test)
def test_write_dictionary_one_to_set_all_keys(self): file_name = TestCase.id(self) + '_friends.txt' self.assertFalse(os.path.exists(file_name), msg='The file should not exist as precondition') write_dictionary_one_to_set(self.friends, '', file_name) with open(file_name) as file: lines = file.readlines() self.assertIn('David\tEster\n', lines, msg='Missing entry line') self.assertIn('Michael\tDavid\n', lines, msg='Missing entry line') self.assertIn('James\tMartha\n', lines, msg='Missing entry line') os.remove(file_name)
def test_create_ggi_file_file_exists_do_nothing(self): # Create mock file filename_ggis = TestCase.id(self) + '_ggis.txt' file_ggis = open(filename_ggis, 'w') file_ggis.close() self.assertTrue(os.path.exists(filename_ggis), msg='ggis file should exist as precondition') create_ggi_file('', '', '', filename_ggis) self.assertTrue(os.path.exists(filename_ggis), msg='ggis file should exist after the creation method') os.remove(filename_ggis)
def test_read_dictionary_skip_header(self): # Create trio file with headers trios = [('Column1', 'Column2', 'Column3'), (1, 1, 2), (2, 3, 2), (3, 4, 5)] file_name = TestCase.id(self) + '_pairs.txt' with open(file_name, 'w') as file: for x, y, z in trios: file.write(f"{x}\t{y}\t{z}\n") # Execute target method result = read_dictionary_one_to_set('', file_name, order_pairs=True, col_indices=(1, 2), ignore_header=True) # Check headers are not taken as key, value pairs self.assertNotIn('Column1', result.keys(), msg="Missing key in dictionary") self.assertIn('1', result.keys(), msg="Missing key in dictionary") self.assertIn('2', result.keys(), msg="Missing key in dictionary") self.assertIn('4', result.keys(), msg="Missing key in dictionary") # Remove precondition files os.remove(file_name) def test_merge_dictionaries(self): d1 = {'A': {'B', 'C'}, 'D': {'C'}, 'C': {'d'}} d2 = {'A': {'a', 'b', 'c'}, 'B': {'b'}, 'C': {'c', 'd', 'e'}} d = merge_dictionaries(d1, d2) self.assertEqual( 4, len(d.keys()), msg="There is a wrong number of keys in the dictionary") self.assertEqual(5, len(d['A']), msg="The number of elements in 'A' should be 5") self.assertTrue('a' in d['A']) self.assertTrue('D' in d) self.assertEqual(1, len(d['D']), msg="The number of elements in 'D' should be 1") self.assertTrue('B' in d) self.assertEqual(1, len(d['B']), msg="The number of elements in 'B' should be 1") self.assertEqual(3, len(d['C']), msg="The number of elements in 'C' should be 3") self.assertTrue('c' in d['C'])
def __init__(self, test: TestCase, execution_time, status_id: int, error_msg=None, custom_msg=None): self.__test_case_object = test self.__test_case_name = self.__test_case_object.__str__() self.__test_status = TestStatus.get_status_string_by_id(status_id) self.__execution_time = execution_time self.__test_case_id = test.id() self.__error_msg = error_msg self.__custom_msg = custom_msg
def addError( self, test: unittest.TestCase, err: Tuple[Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]], ) -> None: """ Record that a test failed with an error. """ super().addError(test, err) self.results.append({ "status": "error", "name": test.id(), "errors": self.errors[-1][-1], "description": test._testMethodDoc })
def result_to_dict(self, type_: str, test: unittest.TestCase, err: Optional[Any] = None) -> Dict[str, Optional[str]]: msg = None if isinstance(err, tuple) and len(err) == 3: msg = self._exc_info_to_string(err, test) elif err: msg = str(err) return OrderedDict([ ('type', type_), ('id', test.id()), ('desc', test.shortDescription()), # May be None ('msg', msg), ])
def test_write_dictionary_one_to_set_one_row_each_set_entry(self): """Having a key with multiple values, writes one row for each key -- value pair""" file_name = TestCase.id(self) + '_friends.txt' self.assertFalse(os.path.exists(file_name), msg='The file should not exist as precondition') write_dictionary_one_to_set(self.friends, '', file_name) with open(file_name) as file: lines = file.readlines() self.assertEqual(6, len(lines), msg='Wrong number of lines in the file') self.assertIn('David\tEster\n', lines, msg='Missing entry line') self.assertIn('David\tMartha\n', lines, msg='Missing entry line') self.assertIn('David\tMathew\n', lines, msg='Missing entry line') os.remove(file_name)
def test_read_dictionary_missing_two_columns(self): """With a one column file, request default columns 0 and 1, report error""" # Create file with three columns, some not in lexicographic order file_name = TestCase.id(self) + '_single_column.txt' with open(file_name, 'w') as file: for x in range(5): file.write(f"{x}\n") with self.assertRaises( ValueError, msg= 'Should raise an exception because needed columns of the file are missing.' ): read_dictionary_one_to_set('', file_name, order_pairs=True) os.remove(file_name)
def test_read_dictionary_missing_index_columns(self): """With two columns file, indices other than (0, 1), like (1, 2), show error.""" # Create file with three columns, some not in lexicographic order pairs = [('a', 'b'), ('c', 'b'), ('d', 'e')] file_name = TestCase.id(self) + '_pairs.txt' with open(file_name, 'w') as file: for x, y in pairs: file.write(f"{x}\t{y}\n") with self.assertRaises( ValueError, msg= 'Should raise an exception because needed columns of the file are missing.' ): read_dictionary_one_to_set('', file_name, col_indices=(1, 2)) os.remove(file_name)
def test_read_dictionary_order_pairs_true(self): # Create file with pairs. Some with inverted lexicographic order pairs = [('a', 'b'), ('c', 'b'), ('d', 'e')] file_name = TestCase.id(self) + '_pairs.txt' with open(file_name, 'w') as file: for x, y in pairs: file.write(f"{x}\t{y}\n") # Execute target method result = read_dictionary_one_to_set('', file_name, order_pairs=True) # Check the pairs order was corrected, showing them as key and value when word1 < word2 Lexicographical order self.assertIn( 'b', result.keys(), msg="Missing key because it did not order the column values") self.assertEqual(3, len(result.keys()), msg="Wrong number of columns") os.remove(file_name)
def test_read_dictionary_indices_1_2(self): # Create file with three columns, some not in lexicographic order trios = [(1, 1, 2), (2, 3, 2), (3, 4, 5)] file_name = TestCase.id(self) + '_pairs.txt' with open(file_name, 'w') as file: for x, y, z in trios: file.write(f"{x}\t{y}\t{z}\n") # Execute target method result = read_dictionary_one_to_set('', file_name, order_pairs=True, col_indices=(1, 2)) # Check values are correct self.assertIn('1', result.keys(), msg="Missing key in dictionary") self.assertIn('2', result.keys(), msg="Missing key in dictionary") self.assertNotIn('3', result.keys(), msg="Incorrect key in dictionary") self.assertIn('4', result.keys(), msg="Missing key in dictionary") # Remove file os.remove(file_name)
def node_key_for_test(test_case: unittest.TestCase, node_key: str) -> str: """ The atrociously-named TestCase#id returns things like tests.test_ip_address_node.TestIpAddressQuery.test__single_ip_addr_node__query_by_node_key """ return "{}{}".format(test_case.id(), node_key)
def _test_id_to_name(test: unittest.TestCase) -> str: parts = test.id().split('.') assert len(parts) == 3, f"Unexpected test id: {test.id()}" return f"{parts[1]}_{parts[2]}"