def test_warning_utils(self): root_trace = FunctionalTrace( parent_trace=None, path_mask=self._path_mask).doing("Testing Warning Utils") try: TEST_SCENARIO = 'test_warning_utils' my_trace = root_trace.doing("Testing a fake warning") with warnings.catch_warnings(record=True) as w: WarningUtils().turn_traceback_on(my_trace, warnings_list=w) warnings.warn("Test warning for Warning Utils", DeprecationWarning) WarningUtils().handle_warnings(my_trace, warning_list=w) # The handling of the warning should raise an exception, so we should not get here self.assertTrue(1 == 2) except ApodeixiError as ex: output_txt = ex.trace_message() self._compare_to_expected_txt(parent_trace=my_trace, output_txt=output_txt, test_output_name=TEST_SCENARIO, save_output_txt=True)
def _attach_subtree(self, df_to_attach, intervals, tree_to_attach_to, docking_uid, xlr_config, acronym_schema): store = tree_to_attach_to.uid_store entity_type = intervals[0].entity_name subtree = BreakdownTree(uid_store = store, entity_type=entity_type, parent_UID=docking_uid) rows = list(df_to_attach.iterrows()) root_trace = FunctionalTrace(parent_trace=None, path_mask=self._path_mask).doing("Populating subtree", data={'subtree.entity_type' : entity_type, 'columns' : list(df_to_attach.columns)}, origination = { 'signaled_from': __file__}) store.set_acronym_schema(root_trace, acronym_schema) for idx in range(len(rows)): for interval in intervals: my_trace = root_trace.doing(activity="Processing fragment", data={'row': idx, 'interval': interval}) subtree.readDataframeFragment( interval = interval, row = rows[idx], parent_trace = my_trace, all_rows = rows, xlr_config = xlr_config, acronym_schema = None) root_trace = FunctionalTrace(parent_trace=None, path_mask=self._path_mask).doing("Attaching subtree", data = {"docking UID" : "'" + subtree.parent_UID + "'", "entity_type" : "'" + entity_type + "'"}) tree_to_attach_to.dock_subtree(entity_type, subtree, root_trace)
def apis(kb_session): ''' Gets the list of posting and manifest APIs supported by the KnowledgeBase ''' timer = ApodeixiTimer() func_trace = FunctionalTrace(parent_trace=None, path_mask=None) root_trace = func_trace.doing("CLI call to get posting APIs", origination={'signaled_from': __file__}) try: posting_apis_description = CLI_Utils().get_apodeixi_apis( root_trace, kb_session) click.echo(posting_apis_description) output = "Success" click.echo(output) click.echo(timer.elapsed_time_message()) except ApodeixiError as ex: error_msg = CLI_ErrorReporting(kb_session).report_a6i_error( parent_trace=root_trace, a6i_error=ex) # GOTCHA # Use print, not click.echo or click exception because they don't correctly display styling # (colors, underlines, etc.). So use vanilla Python print and then exit print(error_msg) _sys.exit() except Exception as ex: click.echo("Unrecoverable error: " + str(ex)) _sys.exit()
def setUp(self): super().setUp() self.root = FunctionalTrace(parent_trace=None, path_mask=self._path_mask) self.step1 = self.root.doing(activity="Processing Step 1", flow_stage=None, data={'fun fact': '-'}, origination={'secret origin': '-'}) self.step2 = self.root.doing(activity="Processing Step 2", flow_stage='Got past Step 1', data=None) for idx in range(5): if idx == 3: self.step2i = self.step2.doing( activity="In loop cycle Step 2-" + str(idx), flow_stage="Loop inside Step 2", data={ 'idx': idx, 'comment': 'Merrily processing loop' }, origination={ 'concrete class': str(self.__class__.__name__) })
def products(kb_session, all, environment): ''' Gets the list of valid products for the system. ''' timer = ApodeixiTimer() func_trace = FunctionalTrace(parent_trace=None, path_mask=None) root_trace = func_trace.doing("CLI call to get products", origination={'signaled_from': __file__}) try: environment_filter = _get_environment_filter(root_trace, kb_session, all, environment) products_description = CLI_Utils().get_products( root_trace, kb_session, environment_filter) click.echo(products_description) output = "Success" click.echo(output) click.echo(timer.elapsed_time_message()) except ApodeixiError as ex: error_msg = CLI_ErrorReporting(kb_session).report_a6i_error( parent_trace=root_trace, a6i_error=ex) # GOTCHA # Use print, not click.echo or click exception because they don't correctly display styling # (colors, underlines, etc.). So use vanilla Python print and then exit print(error_msg) _sys.exit() except Exception as ex: click.echo("Unrecoverable error: " + str(ex)) _sys.exit()
def activateTestConfig(self): ''' Modifies environment variables to ensure that Apodeixi uses a configuration specific for tests. This change endures until the dual method self.deactivateTestConfig() is called. ''' # Remember it before we change it to use a test configuration, and then restore it in the tearDown method self.original_config_directory = _os.environ.get(self.CONFIG_DIRECTORY()) # Here we want the location of this class, not its concrete derived class, # since the location of the Apodexei config to be used for tests is globally unique # So we use __file__ # # MODIFICATION ON APRIL, 2022: As part of adding tests in CI/CD, we made it possible for a CI/CD pipeline # to specify a location for the Apodeixi config directory that should be used for integration tests. # As a result, we only hard-code such config directory if we are not running in an environment where that # has been already set. This enables: # 1) Preservation of traditional Apodeixi feature for developers, whereby tests will "auto discover" # the test_db to use even if the environment variable for the Apodeixi CONFIG_DIRECTORY is not set # 2) Enablement of new use case for CI/CD: externally injected configuration of which config directory to use if not self.INJECTED_CONFIG_DIRECTORY in _os.environ.keys(): # Use case: developer runs tests locally _os.environ[self.CONFIG_DIRECTORY()] = _os.path.join(_os.path.dirname(__file__), '../../../../apodeixi-testdb') else: # Use case: CI/CD pipeline runs tests in a Docker container _os.environ[self.CONFIG_DIRECTORY()] = _os.environ[self.INJECTED_CONFIG_DIRECTORY] func_trace = FunctionalTrace( parent_trace = None, path_mask = None) # path_mask has not been set yet as an attribute root_trace = func_trace.doing("Loading Apodeixi configuration", origination = {'signaled_from': __file__}) self.a6i_config = ApodeixiConfig(root_trace)
def test_docking_1(self): DOCKING_UID = 'A2.B1' ENTITY_TO_DOCK = "Costs" columns = [ENTITY_TO_DOCK, 'Purpose'] row0 = ["Charlie's per diem", 'Customer Visit'] df = _pd.DataFrame(columns=columns, data = [row0]) DATA_TO_ATTACH = next(df.iterrows())[1] root_trace = FunctionalTrace(parent_trace=None, path_mask=self._path_mask).doing("Tesing docking") entity_instance = None try: tree = self._create_breakdown_tree(root_trace, 'docking_1') xlr_config = self._create_posting_config(root_trace, 'docking_1') my_trace = FunctionalTrace(parent_trace=None, path_mask=self._path_mask).doing("Docking uid='" + DOCKING_UID + "'") tree.dockEntityData ( full_docking_uid = DOCKING_UID, entity_type = ENTITY_TO_DOCK, data_to_attach = DATA_TO_ATTACH, parent_trace = my_trace, uid_to_overwrite = None, xlr_config = xlr_config, acronym_schema = None) result_dict = tree.as_dicts() except ApodeixiError as ex: print(ex.trace_message()) self.assertTrue(1==2) self._compare_to_expected_yaml(root_trace, result_dict, test_output_name = 'docking_1', save_output_dict=True)
def test_cli_diff_basic(self): ''' Tests diff functionality between the lastest version of a manifest and its prior version ''' self.setScenario("cli.basic_diff") self.setCurrentTestName('basic_diff') self.selectTestDataLocation() root_trace = FunctionalTrace(parent_trace=None, path_mask=self._path_mask) \ .doing("Running " + self.currentTestName()) PRODUCTS_FILE = 'products.static-data.admin.a6i.xlsx' SCORING_CYCLES_FILE = 'scoring-cycles.static-data.admin.a6i.xlsx' BIG_ROCKS_FILE_V1 = 'v1.big-rocks.journeys.a6i.xlsx' BIG_ROCKS_FILE_V2 = 'v2.big-rocks.journeys.a6i.xlsx' MANIFEST_API = 'delivery-planning.journeys.a6i.io' KIND = 'big-rock' NAMESPACE = 'cicloquimica.production' NAME = 'modernization.fy-22.astrea.official' #STATIC_DATA_WORKING_DIR = "admin/static-data" #PRODUCT_WORKING_DIR = "journeys/FY 22/Astrea/Official" _path_of = self.fullpath_of MASK_COMBINED = CLI_Utils().combined_mask(root_trace, self.a6i_config) # This will fool the CLI to treat our provisioned environment for this test as if it were the base environment self.overwrite_test_context( root_trace ) # Overwrites self.a6i_config , the store, the test_db, etc. my_trace = root_trace.doing("Running commands") COMMANDS = [ ['post', '--timestamp', "_CLI__1", _path_of(PRODUCTS_FILE)], ['post', '--timestamp', "_CLI__2", _path_of(SCORING_CYCLES_FILE)], ['post', '--timestamp', "_CLI__3", _path_of(BIG_ROCKS_FILE_V1)], ['post', '--timestamp', "_CLI__4", _path_of(BIG_ROCKS_FILE_V2)], ['diff', MANIFEST_API, KIND, NAMESPACE, NAME] ] self.skeleton_test( parent_trace=my_trace, cli_command_list=COMMANDS, output_cleanining_lambda=MASK_COMBINED, when_to_check_environment=CLI_Test_Skeleton.ONLY_AT_END)
def __init__(self): try: func_trace = FunctionalTrace(parent_trace=None, path_mask=None) root_trace = func_trace.doing( "Initializing KB_Session for Apodeixi CLI", origination={'signaled_from': __file__}) # The initializer will set self.a6i_config. But in a sort of chicken-and egg situation, we find # ourselves forced to load a "temporary" config object to figure out the class name of the initializer ot use. # This "temporary" config might not be the "right class" if the initializer # is not the default Apodeixi class (for example, if an Apodeixi extension is using a derived initializer # class), but at least the "temporary" config will let us get the initializer class. # temporary_config = ApodeixiConfig(root_trace) initializer_class_name = temporary_config.get_CLI_InitializerClassname( root_trace) try: module_path, class_name = initializer_class_name.rsplit('.', 1) module = import_module(module_path) initializer_class = getattr(module, class_name) initializer = initializer_class() except (ImportError, AttributeError) as ex: raise ApodeixiError(root_trace, "Unable to construct class '" + str(initializer_class_name) + "'", data={"error": ex.msg}) initializer.initialize(root_trace, self) # This will look like '210703.102746', meaning the 3rd of July of 2021 at 10:27 am (and 46 sec). # Intention is this timestamp as an "identifier" of this KnowledgeBase session, by using as prefix # to folders or files (e.g., sandboxes, logs) created during the existence of this KnowledgeBase session dt = _datetime.datetime.today() self.timestamp = dt.strftime("%y%m%d.%H%M%S") self.error_count = 1 # Increments each time we log an error except ApodeixiError as ex: error_msg = CLI_ErrorReporting(None).report_a6i_error( parent_trace=root_trace, a6i_error=ex) # GOTCHA # Use print, not click.echo or click exception because they don't correctly display styling # (colors, underlines, etc.). So use vanilla Python print and then exit print(error_msg) _sys.exit() except Exception as ex: print("Unrecoverable error: " + str(ex)) _sys.exit()
def setUp(self): super().setUp() root_trace = FunctionalTrace( parent_trace=None, path_mask=self._path_mask).doing("Selecting stack for test case") self.selectStack(root_trace) root_trace = FunctionalTrace( parent_trace=None, path_mask=self._path_mask).doing( "Retrieving product list from config", origination={'signaled_from': __file__}) self.products = [ "LIQ", "CCB", "FCC", "FCM", "TI", "ESS", "GPP", "FCQ", "LPR", "MBTLOS", "MBTPOS", "MLZ", "PHX", "KON", "OPI", "RISK", "SUM" ]
def test_attach_subtree(self): result_dict = None root_trace = FunctionalTrace(parent_trace=None, path_mask=self._path_mask).doing("Attaching subtree") try: tree1 = self._create_breakdown_tree(root_trace, 'attach_subtree') subtree_df = self._create_df2() xlr_config = self._create_posting_config(root_trace, 'attach_subtree') subtree_intervals = [ Interval(None, ['Expectation', 'Description']), Interval(None, [ 'Acceptance Criteria', 'Artifact'])] acronym_schema = UID_Acronym_Schema() acronym_schema.acronyminfo_list = [AcronymInfo("A", "A"), AcronymInfo("B", "B"), AcronymInfo("C", "C"), AcronymInfo("E", "Expectation"), AcronymInfo("AC", "Acceptance Criteria")] self._attach_subtree( df_to_attach = subtree_df, intervals = subtree_intervals, tree_to_attach_to = tree1, docking_uid = 'A2.B1.C1', xlr_config = xlr_config, acronym_schema = acronym_schema) result_dict = tree1.as_dicts() except ApodeixiError as ex: print(ex.trace_message()) self.assertTrue(1==2) self._compare_to_expected_yaml(root_trace, result_dict, test_output_name = 'attach_subtree', save_output_dict=True)
def _malformed_input_test_skeleton(self, test_case_nb, expect_error): test_case_name = 'user_validation_' + str(test_case_nb) result_dict = None root_trace = FunctionalTrace( parent_trace=None, path_mask=self._path_mask).doing("Validating mal-formed input") try: self._attempt_to_run(test_case_name, expect_error) except ApodeixiError as ex: if expect_error: output_txt = "================== This test verifies that the following user validation works:\n\n" output_txt += Test_MalformedInput.VALIDATIONS_DICT[ test_case_nb] output_txt += "\n\n================ Below is the error message the user would get:" output_txt += ex.trace_message(exclude_stack_trace=True) self._compare_to_expected_txt(root_trace, output_txt, test_case_name, save_output_txt=True) return else: print(ex.trace_message()) self.assertTrue(1 == 2) if expect_error: # Shouldn't have gotten here, since an exception should have been raised before. So fail test self.assertTrue(1 == 2)
def report_a6i_error(self, parent_trace, a6i_error): ''' Displays a high-level summary of the `a6i_error`, with detailed information saved to a log file. The log file will be in the folder called @param a6i_error An ApodeixiError object whose content must be reported to the user. ''' def MSK(txt): # Abbreviation for the masking logic if a6i_error.functional_trace.path_mask != None: return a6i_error.functional_trace.path_mask(txt) else: return txt data_msg = '' for k in a6i_error.data.keys(): data_msg += '\n' + MSK(FunctionalTrace._ins(k)) + ': ' + MSK( str(a6i_error.data[k])) if len(data_msg) > 0: data_msg = '\n' + data_msg + '\n' report_header = self.FAIL("\n" + a6i_error.msg + data_msg) high_level_msg = self._report_error(parent_trace, a6i_error, report_header) return high_level_msg
def test_generateUID(self): # Each scenario is a triple of [parent uid input, acronym input, expected output] root_trace = FunctionalTrace( parent_trace=None, path_mask=self._path_mask).doing("Testing generateUID") scenarios = [[['FRA'], None, 'FRA', ('FRA1', 'FRA1')], [['W'], None, 'W', ('W1', 'W1')], [['W', 'PO'], 'W1', 'PO', ('W1.PO1', 'PO1')], [['FRA', 'USD'], 'FRA1', 'USD', ('FRA1.USD1', 'USD1')], [['FRA'], None, 'FRA', ('FRA2', 'FRA2')], [['FRA', 'USD'], 'FRA1', 'USD', ('FRA1.USD2', 'USD2')], [['FRA', 'USD', 'NY'], 'FRA1.USD2', 'NY', ('FRA1.USD2.NY1', 'NY1')], [['FRA', 'USD', 'NY'], 'FRA1.USD3', 'NY', 'error']] try: for (acronym_space, parent_uid, acronym, expected) in scenarios: acronym_schema = UID_Acronym_Schema() acronym_schema.acronyminfo_list = [ AcronymInfo(acronym=x, entity_name=x) for x in acronym_space ] self.store.set_acronym_schema(root_trace, acronym_schema) result = self.attempt_generateUID(root_trace, parent_uid, acronym) self.assertEqual(result, expected) except ApodeixiError as ex: print(ex.trace_message()) self.assertTrue(1 == 2)
def test_time_bucket_comparison(self): root_trace = FunctionalTrace( parent_trace=None, path_mask=self._path_mask).doing( "Testing parser for quarter time buckets") tests = [ FY_Quarter(2021, 1, month_fiscal_year_starts=6), FY_Quarter(2021, 4, month_fiscal_year_starts=6), FY_Quarter(2021, 2, month_fiscal_year_starts=6), FY_Quarter(2024, 1, month_fiscal_year_starts=6), FY_Quarter(2019, 4, month_fiscal_year_starts=6), FY_Quarter(2019, 1, month_fiscal_year_starts=1), FY_Quarter(2018, 4, month_fiscal_year_starts=6), FY_Quarter(2019, 4, month_fiscal_year_starts=6), ] output = "" for idx in range(1, len(tests)): time_bucket_1 = tests[idx - 1] time_bucket_2 = tests[idx] last_day_1 = time_bucket_1.last_day().strftime("%d %B %Y") last_day_2 = time_bucket_2.last_day().strftime("%d %B %Y") comparison = time_bucket_1.less_than(root_trace, time_bucket_2) output += "\n" + time_bucket_1.display() + " < " + time_bucket_2.display() + " ?\t" \ + str(comparison) + "\t\tReason: last days are: " + last_day_1 + ", " + last_day_2 + ")" self._compare_to_expected_txt( parent_trace=root_trace, output_txt=output, test_output_name='test_time_bucket_compare', save_output_txt=True)
def test_a6i_config(self): try: root_trace = FunctionalTrace( parent_trace=None, path_mask=self._path_mask).doing( "Testing loading for Apodeixi Config") config = ApodeixiConfig(root_trace) # To ensure determistic output, mask parent part of any path that is mentioned in the configuration before # displaying it in regression putput # clean_dict = DictionaryUtils().apply_lambda( parent_trace=root_trace, root_dict=config.config_dict, root_dict_name="Apodeixi config", lambda_function=self._path_mask) config_txt = DictionaryFormatter().dict_2_nice( parent_trace=root_trace, a_dict=clean_dict, flatten=True) self._compare_to_expected_txt(parent_trace=root_trace, output_txt=config_txt, test_output_name='test_a6i_config', save_output_txt=True) except ApodeixiError as ex: print(ex.trace_message()) self.assertTrue(1 == 2)
def _impl_timebucket_standardization_test(self, TEST_NAME, HEADER, INDEX_COL, lower_level_key=None): try: root_trace = FunctionalTrace( parent_trace=None, path_mask=self._path_mask).doing( "Testing DataFrame timebucket tidying up") a6i_config = ApodeixiConfig(root_trace) INPUT_FULL_PATH = self.input_data + "/" + TEST_NAME + ".xlsx" input_df = _pd.read_excel(io=INPUT_FULL_PATH, header=HEADER, index_col=INDEX_COL) output_df, info = TimebucketStandardizer( ).standardizeAllTimebucketColumns(root_trace, a6i_config, input_df, lower_level_key) self._compare_to_expected_df(parent_trace=root_trace, output_df=output_df, test_output_name=TEST_NAME) except ApodeixiError as ex: print(ex.trace_message()) raise ex
def test_yaml_2_full_dataframe(self): MANIFEST_FILE = 'yaml_2_dataframe_INPUT.yaml' # Input file common across multiple tests MANIFESTS_FOLDER = self.input_data OUTPUT_FOLDER = self.output_data OUTPUT_FILE = 'yaml_2_full_dataframe_OUTPUT.csv' df = None subtree = None root_trace = FunctionalTrace(parent_trace=None, path_mask=self._path_mask).doing("Testing yam_2_full_df") try: rep = AsDataframe_Representer() df, subtree = rep.yaml_2_df(root_trace, MANIFESTS_FOLDER, MANIFEST_FILE, 'scaffolding.jobs-to-be-done', sparse=False, abbreviate_uids=True) # Save DataFrame in case the assertion below fails, so that we can do a visual comparison of OUTPUT vs EXPECTED csv files df.to_csv(OUTPUT_FOLDER + '/' + OUTPUT_FILE) except ApodeixiError as ex: print(ex.trace_message()) self.assertTrue(1==2) self.assertEqual(subtree, self._expected_subtree()) self._compare_to_expected_df( root_trace, output_df = df, test_output_name = "yaml_2_full_dataframe", columns_to_ignore = [], id_column = None)
def setUp(self): super().setUp() # We can't rely on Python's built-in '__file__' property to find the location of the concrete class # that is running, since we are in the parent class and we will get the parent class's filename, not the concrete class's. # So instead we rely on the inspect package me__file__ = inspect.getfile(self.__class__) # self.input_data = _os.path.join(_os.path.dirname(__file__), 'input_data') # Doesn't work - use inpectt instead self.input_data = _os.path.join( _os.path.dirname(me__file__), 'input_data') # Works ! :-) Thanks inspect! # self.output_data = _os.path.join(_os.path.dirname(__file__), 'output_data') # Doesn't work - use inpectt instead self.output_data = _os.path.join( _os.path.dirname(me__file__), 'output_data') # Works ! :-) Thanks inspect! # self.output_data = _os.path.join(_os.path.dirname(__file__), 'output_data') # Doesn't work - use inpectt instead self.expected_data = _os.path.join( _os.path.dirname(me__file__), 'expected_data') # Works ! :-) Thanks inspect! # Output data is not in source control, so if we are in a clean repo the folder might not exist, so created it # if needed root_trace = FunctionalTrace(None, path_mask=self._path_mask) PathUtils().create_path_if_needed(root_trace, self.output_data) # For unit tests, don't enforce referential integrity since we will test data in mock stores that may # reference things that don't really exist self.a6i_config.enforce_referential_integrity = False
def run_script(self, scenario, test_name, excel_relative_path, excel_file, excel_sheet, nb_manifests, from_nothing, namespace, subnamespace, posting_api, setup_dependencies): self.setScenario(scenario) self.setCurrentTestName(test_name) # big rock burnout for product Opus self.selectTestDataLocation() script = Post_and_Update_Script(self) root_trace = FunctionalTrace( parent_trace=None, path_mask=self._path_mask).doing("Running script for " + self.scenario()) script._run_basic_flow(parent_trace=root_trace, from_nothing=from_nothing, namespace=namespace, subnamespace=subnamespace, posting_api=posting_api, excel_relative_path=excel_relative_path, excel_file=excel_file, excel_sheet=excel_sheet, nb_manifests_expected=nb_manifests, generated_form_worksheet=SkeletonController. GENERATED_FORM_WORKSHEET, setup_dependencies=setup_dependencies)
def test_merge_lists(self): root_trace = FunctionalTrace( parent_trace=None, path_mask=self._path_mask).doing("Testing List Merger") try: INPUT_FOLDER = self.input_data OUTPUT_FOLDER = self.output_data TEST_SCENARIO = 'test_merge_lists' OUTPUT_FILE = TEST_SCENARIO + '_OUTPUT.txt' EXPECTED_FILE = TEST_SCENARIO + '_EXPECTED.txt' list1 = [1000, 3000, 4000, 5000, 8000, 9000] list2 = [1000, 2000, 3000, 4000, 5000, 6000, 7000, 9000] my_trace = root_trace.doing("Merging lists") merger = ListMerger(parent_trace=my_trace, list1=list1, list2=list2, list1_name="left", list2_name="right") merged_list = merger.merge(my_trace) my_trace = root_trace.doing( "Comparing merge list to expected output") output_txt = '============ List1 ================\n' + str(list1) output_txt += '\n\n============ List2 ================\n' + str( list2) output_txt += '\n\n============ Merged Result ================\n' + merger.format_results( my_trace) ''' output_txt = '\n'.join(['\t\t'.join(["Element: " + str(e[0]), "LEFT" if e[1] else " ", "RIGHT" if e[2] else " "]) for e in merged_list]) ''' self._compare_to_expected_txt(parent_trace=my_trace, output_txt=output_txt, test_output_name=TEST_SCENARIO, save_output_txt=True) except ApodeixiError as ex: print(ex.trace_message()) self.assertTrue(1 == 2)
def test_milestones(self): root_trace = FunctionalTrace( parent_trace=None, path_mask=self._path_mask).doing('Testing MilestoneController') self.impl_testcase(parent_trace=root_trace, test_name='milestones', controller_class=MilestonesController, nb_manifests_expected=2, excel_sheet='Sheet1', ctx_range='b2:c20')
def setUp(self): super().setUp() self.activateTestConfig() # Used by derived classes to mask some paths that are logged out so that regression output is # deterministic root_trace = FunctionalTrace(parent_trace=None, path_mask=None).doing("Configuring test path mask", origination = {'signaled_from': __file__}) self._path_mask = PathUtils().get_mask_lambda(parent_trace=root_trace, a6i_config=self.a6i_config)
def _select_namespace(self): root_trace = FunctionalTrace( parent_trace=None, path_mask=self._path_mask).doing( "Retrieving organization and knowledge base areas " " from ApodeixiConfig") ORGANIZATION = self.a6i_config.getOrganization(root_trace) KNOWLEDGE_BASE_AREAS = self.a6i_config.getKnowledgeBaseAreas( root_trace) NAMESPACE = ORGANIZATION + "." + KNOWLEDGE_BASE_AREAS[1] return NAMESPACE
def setUp(self): super().setUp() # Flow scenario tests are "realistic", so for them we want to enforce referential integrity. self.a6i_config.enforce_referential_integrity = True root_trace = FunctionalTrace( parent_trace=None, path_mask=self._path_mask).doing("Selecting stack for test case") self.selectStack(root_trace)
def config(kb_session, environment): ''' Displays the Apodeixi configuration. ''' T0 = _datetime.datetime.now() func_trace = FunctionalTrace(parent_trace=None, path_mask=None) root_trace = func_trace.doing("CLI call to get products", origination={'signaled_from': __file__}) try: if environment != None: kb_session.store.activate(parent_trace=root_trace, environment_name=environment) click.echo(CLI_Utils().sandox_announcement(environment)) client_url = kb_session.store.getClientURL(root_trace) postings_url = kb_session.store.getPostingsURL(root_trace) click.echo("\n----- Current environment -----") click.echo("\nclient URL:\t\t" + str(client_url)) click.echo("postings URL:\t\t" + str(postings_url)) config_txt = DictionaryFormatter().dict_2_nice( root_trace, kb_session.a6i_config.config_dict, flatten=True) click.echo("\n\n----- Config Settings -----") click.echo("\n" + config_txt) output = "Success" click.echo(output) except ApodeixiError as ex: error_msg = CLI_ErrorReporting(kb_session).report_a6i_error( parent_trace=root_trace, a6i_error=ex) # GOTCHA # Use print, not click.echo or click exception because they don't correctly display styling # (colors, underlines, etc.). So use vanilla Python print and then exit print(error_msg) _sys.exit() except Exception as ex: click.echo("Unrecoverable error: " + str(ex)) _sys.exit() T1 = _datetime.datetime.now() duration = T1 - T0 duration_msg = str(duration.seconds) + "." + str( duration.microseconds) + " sec" click.echo(duration_msg)
def test_read_df_fragment(self): result_dict = None root_trace = FunctionalTrace(parent_trace=None, path_mask=self._path_mask).doing("Reading df fragment") try: tree = self._create_breakdown_tree(root_trace, 'read_df_fragment') result_dict = tree.as_dicts() except ApodeixiError as ex: print(ex.trace_message()) self.assertTrue(1==2) self._compare_to_expected_yaml(root_trace, result_dict, test_output_name = 'read_df_fragment', save_output_dict=True)
def _posting_testing_skeleton(self, store, test_case_name, excel_file): all_manifests_dicts = [] try: root_trace = FunctionalTrace(parent_trace=None, path_mask=self._path_mask).doing("Posting excel file", data={ 'excel_file' : excel_file}, origination = { 'signaled_from' : __file__, 'concrete class': str(self.__class__.__name__)}) kbase = KnowledgeBase(root_trace, store, a6i_config=self.a6i_config) response, log_txt = kbase.postByFile( parent_trace = root_trace, path_of_file_being_posted = excel_file, excel_sheet = "Sheet1") NB_MANIFESTS_EXPECTED = 3 if len(response.createdManifests()) != NB_MANIFESTS_EXPECTED: raise ApodeixiError(root_trace, 'Expected ' + str(NB_MANIFESTS_EXPECTED) + ' manifests, but found ' + str(len(all_manifests_dicts))) # Retrieve the manifests created manifest_dict = {} for handle in response.createdManifests(): loop_trace = root_trace.doing("Retrieving manifest for handle " + str(handle), origination = { 'concrete class': str(self.__class__.__name__), 'signaled_from': __file__}) manifest_dict, manifest_path = store.retrieveManifest(loop_trace, handle) self._compare_to_expected_yaml(loop_trace, manifest_dict, test_case_name + "." + handle.kind) return except ApodeixiError as ex: print(ex.trace_message()) self.assertTrue(1==2) # If we get this far, the tests failed since we should have returned within the try statement. # So hardcode an informative failure. self.assertTrue("Shouldn't have gotten to this line" == 0)
def test_find(self): UID_TO_FIND = 'A2.B1.C1' NAME_OF_ENTITY_TO_FIND = 'c4' entity_instance = None try: my_trace = FunctionalTrace(parent_trace=None, path_mask=self._path_mask).doing("Finding uid='" + UID_TO_FIND + "'") tree = self._create_breakdown_tree(my_trace, "Finding UID") entity_instance = tree.find (UID_TO_FIND, my_trace) except ApodeixiError as ex: print(ex.trace_message()) self.assertTrue(1==2) self.assertEqual(entity_instance.name, NAME_OF_ENTITY_TO_FIND)
def test_tokenize(self): # Each scenario is a pair of [input, expected output] root_trace = FunctionalTrace( parent_trace=None, path_mask=self._path_mask).doing("Testing tokenize") scenarios = [['av45.p1.e12', ['av45', 'p1', 'e12']], ['w0', ['w0']], ['eq3.q', 'error'], ['WE4.T3x', 'error']] try: for (uid, expected) in scenarios: result = self.attempt_tokenize(root_trace, uid) self.assertEqual(result, expected) except ApodeixiError as ex: print(ex.trace_message()) self.assertTrue(1 == 2)