예제 #1
0
    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)
예제 #3
0
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__)
                    })
예제 #5
0
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)
예제 #8
0
    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)
예제 #9
0
    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
예제 #14
0
 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)
예제 #16
0
    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)
예제 #19
0
    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)
예제 #21
0
    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)
예제 #22
0
 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)
예제 #26
0
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)
예제 #28
0
    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)
예제 #30
0
 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)