def _get_environment_filter(parent_trace, kb_session, all, environment):
    '''
    Helper method to get filter for which environment to look into when searching in the KnowledgeBase
    store.
    '''
    if all == True:
        environment_filter = CLI_Utils().get_environment_filter(
            parent_trace,
            kb_session,
            filter_type=CLI_Utils.ANY_ENV_FILTER,
            sandbox=None)
    elif environment != None:
        click.echo(CLI_Utils().sandox_announcement(environment))
        environment_filter = CLI_Utils().get_environment_filter(
            parent_trace,
            kb_session,
            filter_type=CLI_Utils.SPECIFIC_SANDBOX_ENV_FILTER,
            sandbox=environment)
    else:
        environment_filter = CLI_Utils().get_environment_filter(
            parent_trace,
            kb_session,
            filter_type=CLI_Utils.ONLY_BASE_ENV_FILTER,
            sandbox=environment)
    return environment_filter
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 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()
Exemple #4
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)
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 diff(kb_session, manifest_api, kind, namespace, name):
    '''
    Makes a diff between two versions of a manifest.
    
    For a list of valid MANIFEST_APIs and KINDs, try 'get apis'
    
    For a list of valid NAMESPACEs and NAMEs, try 'get assertions'

    MANIFEST_API must be a versionless manifest API. 
    
    Example: 'delivery-planning.journeys.a6i.io', (as opposed to 'delivery-planning.journeys.a6i.io/v1a'). 
    '''
    timer = ApodeixiTimer()
    func_trace = FunctionalTrace(parent_trace=None, path_mask=None)
    root_trace = func_trace.doing("CLI call to post",
                                  origination={'signaled_from': __file__})

    kb_operation_succeeded = False
    try:

        my_trace = root_trace.doing(
            "Invoking ManifestUtils's postByFile service")

        diff_result = ManifestUtils().diff_manifest(
            parent_trace=my_trace,
            store=kb_session.store,
            manifest_api_name=manifest_api,
            namespace=namespace,
            name=name,
            kind=kind,
            version1=None,
            version2=None)
        kb_operation_succeeded = True

        diff_description = CLI_Utils().describe_diff_response(
            my_trace, kb_session, diff_result)

        # GOTCHA:
        # Make sure to remove non-ascii characters before passing the description to click.echo, since it
        # will raise errors if there are characters like \uFFFFD in the description
        #
        diff_description = StringUtils().to_ascii(diff_description)

        click.echo(diff_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)
        if kb_operation_succeeded:
            error_msg                       = "KnowledgeBase operation completed, but run into a problem when preparing "\
                                                + "a description of the response:\n"\
                                                + error_msg
        # 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:
        try:
            error_msg = CLI_ErrorReporting(kb_session).report_generic_error(
                parent_trace=root_trace, generic_error=ex)
            if kb_operation_succeeded:
                error_msg                   = "KnowledgeBase operation completed, but run into a problem when preparing "\
                                                + "a description of the response:\n"\
                                                + error_msg
        except Exception as ex2:
            error_msg                       = "CLI run into trouble: found error:\n\n\t" + str(ex) + "\n\n" \
                                                + "To make things worse, when trying to produce an error log file with a "\
                                                + "stack trace, run into an additional error:\n\n\t" + str(ex2)
        # 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()
def form(kb_session, posting_api, namespace, subnamespace, dry_run,
         environment, timestamp):
    '''
    Requests a form (an Excel spreadsheet) which (after some edits, as appropriate) can be used as the
    input to the post command.
    '''
    timer = ApodeixiTimer()
    func_trace = FunctionalTrace(parent_trace=None, path_mask=None)
    root_trace = func_trace.doing("CLI call to post",
                                  origination={'signaled_from': __file__})
    kb_operation_succeeded = False
    try:
        # Catch warnings and handle them so that we avoid spurious noise in the CLI due to noisy 3rd party libraries
        with warnings.catch_warnings(record=True) as w:
            WarningUtils().turn_traceback_on(root_trace, warnings_list=w)
            if environment != None:
                kb_session.store.activate(parent_trace=root_trace,
                                          environment_name=environment)
                click.echo(CLI_Utils().sandox_announcement(environment))
            elif dry_run == True:
                sandbox_name = kb_session.provisionSandbox(root_trace)
                click.echo(CLI_Utils().sandox_announcement(sandbox_name))
            '''
            else:
                raise ApodeixiError(root_trace, "Sorry, only sandbox-isolated runs are supported at this time. Aborting.")
            '''
            # Now that we have pinned down the environment (sandbox or not) in which to call the KnowledgeBase's services,
            # set that environment's tag to use for KnoweldgeBase's posting logs, if the user set it.
            if timestamp:
                kb_session.store.current_environment(root_trace).config(
                    root_trace).use_timestamps = timestamp

            my_trace = root_trace.doing(
                "Invoking KnowledgeBase's requestForm service")

            output_dir = _os.getcwd()
            clientURL = kb_session.store.getClientURL(my_trace)
            relative_path, void = PathUtils().relativize(parent_trace=my_trace,
                                                         root_dir=clientURL,
                                                         full_path=output_dir)

            form_request = kb_session.store.getBlindFormRequest(
                parent_trace=my_trace,
                relative_path=relative_path,
                posting_api=posting_api,
                namespace=namespace,
                subnamespace=subnamespace)

            response, log_txt, rep = kb_session.kb.requestForm(
                parent_trace=my_trace, form_request=form_request)
            kb_operation_succeeded = True
            manifests_description = CLI_Utils().describe_req_form_response(
                my_trace,
                form_request_response=response,
                store=kb_session.store,
                representer=rep)

            click.echo(manifests_description)
            output = "Success"
            click.echo(output)
            click.echo(timer.elapsed_time_message())

            WarningUtils().handle_warnings(root_trace, warning_list=w)

    except ApodeixiError as ex:
        error_msg = CLI_ErrorReporting(kb_session).report_a6i_error(
            parent_trace=root_trace, a6i_error=ex)
        if kb_operation_succeeded:
            error_msg                       = "KnowledgeBase operation completed, but run into a problem when preparing "\
                                                + "a description of the response:\n"\
                                                + error_msg
        # 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:
        try:
            error_msg = CLI_ErrorReporting(kb_session).report_generic_error(
                parent_trace=root_trace, generic_error=ex)
            if kb_operation_succeeded:
                error_msg                   = "KnowledgeBase operation completed, but run into a problem when preparing "\
                                                + "a description of the response:\n"\
                                                + error_msg
        except Exception as ex2:
            error_msg                       = "CLI run into trouble: found error:\n\n\t" + str(ex) + "\n\n" \
                                                + "To make things worse, when trying to produce an error log file with a "\
                                                + "stack trace, run into an additional error:\n\n\t" + str(ex2)
        # 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()
def post(kb_session, file, dry_run, environment, timestamp):
    '''
    Posts contents of an Excel file to the KnowledgeBase.
    The filename must be of the form '<some string><posting API>.xlsx' for some supported KnowledgeBase posting API.
    '''
    timer = ApodeixiTimer()
    func_trace = FunctionalTrace(parent_trace=None, path_mask=None)
    root_trace = func_trace.doing("CLI call to post",
                                  origination={'signaled_from': __file__})

    kb_operation_succeeded = False
    try:
        if environment != None:
            kb_session.store.activate(parent_trace=root_trace,
                                      environment_name=environment)
            click.echo(CLI_Utils().sandox_announcement(environment))
        elif dry_run == True:
            sandbox_name = kb_session.provisionSandbox(root_trace)
            click.echo(CLI_Utils().sandox_announcement(sandbox_name))
        '''
        else:
            raise ApodeixiError(root_trace, "Sorry, only sandbox-isolated runs are supported at this time. Aborting.")
        '''
        # Now that we have pinned down the environment (sandbox or not) in which to call the KnowledgeBase's services,
        # set that environment's tag to use for KnoweldgeBase's posting logs, if the user set it.
        if timestamp:
            kb_session.store.current_environment(root_trace).config(
                root_trace).use_timestamps = timestamp

        if len(
                _os.path.split(file)[0]
        ) == 0:  # This must be a local file in our working directory, no folder was given
            file = _os.getcwd() + "/" + file
        my_trace = root_trace.doing(
            "Invoking KnowledgeBase's postByFile service")
        response, log_txt = kb_session.kb.postByFile(
            parent_trace=my_trace,
            path_of_file_being_posted=file,
            excel_sheet="Posting Label")
        kb_operation_succeeded = True
        manifests_description = CLI_Utils().describe_post_response(
            my_trace, response, kb_session.store)

        click.echo(manifests_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)
        if kb_operation_succeeded:
            error_msg                       = "KnowledgeBase operation completed, but run into a problem when preparing "\
                                                + "a description of the response:\n"\
                                                + error_msg
        # 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:
        try:
            error_msg = CLI_ErrorReporting(kb_session).report_generic_error(
                parent_trace=root_trace, generic_error=ex)
            if kb_operation_succeeded:
                error_msg                   = "KnowledgeBase operation completed, but run into a problem when preparing "\
                                                + "a description of the response:\n"\
                                                + error_msg
        except Exception as ex2:
            error_msg                       = "CLI run into trouble: found error:\n\n\t" + str(ex) + "\n\n" \
                                                + "To make things worse, when trying to produce an error log file with a "\
                                                + "stack trace, run into an additional error:\n\n\t" + str(ex2)
        # 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()
Exemple #9
0
    def skeleton_test(self,
                      parent_trace,
                      cli_command_list,
                      output_cleanining_lambda,
                      when_to_check_environment=PER_COMMAND):
        '''
        @param when_to_check_environment A string enum, that determines how frequently to check the contents
                    of the environment as the CLI commands execulte. Possible values:

                    * CLI_Test_Skeleton.PER_COMMAND
                    * CLI_Test_Skeleton.ONLY_AT_END
                    * CLI_Test_Skeleton.NEVER
        '''
        ME = CLI_Test_Skeleton
        try:
            my_trace = self.trace_environment(parent_trace,
                                              "Isolating test case")
            if self.provisioned_env_name == None:
                # This is the second time we provision the isolated environment, but now with a different context, i.e.,
                # different self.a6i_config and different self.test_config_dict than the first time we provisioned
                # an isolated environment, which was in self.setUp. See comments there. The environment provisioned
                # here is a child of the one configured in self.setUp, and is fo
                self.provisionIsolatedEnvironment(my_trace)
                if when_to_check_environment == ME.PER_COMMAND:
                    self.check_environment_contents(my_trace)
                self.provisioned_env_name = self.stack().store(
                ).current_environment(my_trace).name(my_trace)
            else:
                self.stack().store().activate(my_trace,
                                              self.provisioned_env_name)

            my_trace = self.trace_environment(
                parent_trace,
                "Invoking " + str(len(cli_command_list)) + " commands")
            if True:
                runner = CliRunner()
                for raw_command_argv in cli_command_list:
                    # The raw_command_arv might include some lambdas that need to be evaluated not in order to
                    # determine the real argv to pass to the CLI. The reason there might be lambdas is that some
                    # parameters for some commands can only be determined after earlier commands are run, so they
                    # aren't known when the command list was defined, and only now that we have run prior commands
                    # can it be determined.
                    # Example:
                    #       The sandbox to use, if flag "--sandbox" is on. That can only be known after
                    # self.sandbox is set, which happens when the first command runs.
                    def _unraw_param(param):
                        if callable(param):
                            return param()
                        else:
                            # As a precaution, make sure we return a string. Otherwise, if param is an int,
                            # click will later through some exception
                            return str(param)

                    # Note: two operations are being done here:
                    #
                    # 1) Replacing a "delayed parameter": a parameter that couldn't be given when the caller's code was
                    #   written, but can at runtime, so the "delayed parameter" is a callable that, if called, would return
                    #   the actual parameter to use. Example: the sandbox parameter, which is determined in the first
                    #   post of the script and must be passed to all subsequent post commands so they continue the work
                    #   in a common sandbox.
                    # 2) Filtering out nulls. That is a trick to enable the caller, for example, to use the same script
                    #   for both dry runs and live runs. All the caller has to do is set the "--sandbox <sandbox>" to a
                    #   value when using the script with a sandbox, and to None when doing it live.
                    command_argv = [
                        _unraw_param(param) for param in raw_command_argv
                        if param != None
                    ]

                    loop_trace = self.trace_environment(
                        my_trace, "Executing '" +
                        " ".join([str(cmd) for cmd in command_argv]) + "'")
                    # Some Python libraries can be too noisy with warnings, and these get printed out to standard err/output
                    # where the CLI will regard as "part of output" and display them in regression test output. This makes
                    # regression output both ugly and sometimes non-deterministc.
                    # To remedy this, we change the warning context to catch all warnings and based on what we catch, either
                    # 1. raise an ApodeixiError so that the Apodeixi developer can change the code construct that led to the
                    #    warning, possible as the ApodeixiError will include a stack trace to pin point where in the Apodeixi
                    #    code the warning was triggered,
                    # 2. or ignore the warning if that is pure noise and no code change in Apodeixi could prevent it from being
                    #   triggered
                    #
                    with warnings.catch_warnings(record=True) as w:
                        WarningUtils().turn_traceback_on(parent_trace,
                                                         warnings_list=w)

                        result = runner.invoke(self.cli, command_argv)

                        WarningUtils().handle_warnings(parent_trace,
                                                       warning_list=w)

                    if result.exit_code != 0:
                        raise ApodeixiError(loop_trace,
                                            "CLI command failed",
                                            data={
                                                "CLI exit code":
                                                str(result.exit_code),
                                                "CLI exception":
                                                str(result.exc_info),
                                                "CLI output":
                                                str(result.output),
                                                "CLI traceback":
                                                str(result.exc_info)
                                            })

                    sandbox = CLI_Utils().infer_sandbox_name(
                        loop_trace, result.output)
                    if sandbox != None:
                        # We only overwrite self.sandbox if this particular command chose a sandbox. Otherwise
                        # we retain whatever self.sandbox was set by prior commands. This is important since some commands
                        # don't have a --sandbox option (Example: get namespaces), but that does not mean that
                        # our intention is to switch out of the sandbox and into the parent environment.
                        self.sandbox = sandbox

                    command_flags = [
                        token for token in command_argv
                        if token.startswith("--")
                    ]
                    if command_argv[0] in ["post"]:
                        argv_without_arguments = command_argv[:1]
                    elif command_argv[0] in ["get"]:
                        argv_without_arguments = command_argv[:2]
                    elif command_argv[0] in ["import"]:
                        argv_without_arguments = command_argv[:2]
                    elif command_argv[0] in ["diff"]:
                        argv_without_arguments = command_argv[:1]
                    else:
                        raise ApodeixiError(
                            my_trace, "Command not recognized: '" +
                            str(command_argv[0]) + "'")

                    argv_without_arguments.extend(
                        command_flags)  # Like post --dry-run

                    # Once we are done building it, command_without_flag_params will be something like
                    #
                    #   => post --dry-run products.static-data.admin.a6i.xlsx
                    #
                    # or
                    #
                    #   => post --sandbox products.static-data.admin.a6i.xlsx
                    #
                    # hence it will be suitable for inclusion in deterministic output. For example, we remove
                    # timestamp-sensitive sandbox names (if any) and also the full path for the posted file.
                    command_without_flag_params = " ".join(
                        argv_without_arguments)
                    if command_argv[0] in ["post"] or command_argv[:2] in [[
                            "get", "form"
                    ]]:
                        # These are commands with a unique argument. Other commands lack it
                        path_posted = command_argv[-1]
                        unique_argument = _os.path.split(path_posted)[1]
                        command_without_flag_params += " " + unique_argument
                    elif command_argv[:2] in [["import", "aha"]]:
                        args = command_argv[-4:]
                        command_without_flag_params += " " + " ".join(args)

                    output_to_display = "=> " + command_without_flag_params + "\n\n"

                    if output_cleanining_lambda == None:
                        output_to_display += result.output
                    else:
                        output_to_display += output_cleanining_lambda(
                            result.output)

                    self.check_cli_output(
                        parent_trace=loop_trace,
                        cli_output=output_to_display,
                        cli_command=" ".join(
                            argv_without_arguments)  # Like post --dry-run
                    )
                    if when_to_check_environment == ME.PER_COMMAND:
                        self._check_CLI_environment(loop_trace)

            if when_to_check_environment == ME.ONLY_AT_END:
                # We display the consolidated effect of all commands in the script onto the KnowledgeBase used by the CLI
                self._check_CLI_environment(my_trace)

            my_trace = self.trace_environment(parent_trace,
                                              "Deactivating environment")
            self.stack().store().deactivate(my_trace)

        except ApodeixiError as ex:
            click.echo(ex.trace_message())
            self.assertTrue(1 == 2)
Exemple #10
0
    def run_script(self, parent_trace, SANDBOX_FUNC, cli_arguments_dict):

        _path_of = self.myTest.fullpath_of

        MASK_COMBINED = CLI_Utils().combined_mask(parent_trace,
                                                  self.myTest.a6i_config)

        _s = CLI_Basic_Script
        _args = cli_arguments_dict

        # This will fool the CLI to treat our provisioned environment for this test as if it were the base environment
        self.myTest.overwrite_test_context(
            parent_trace
        )  # Overwrites self.a6i_config , the store, the test_db, etc.

        if SANDBOX_FUNC != None:
            __dry_run = '--dry-run'
            __environment = '--environment'
            ENV_CHOICE = SANDBOX_FUNC
        else:  # Case for life runs
            __dry_run = None
            __environment = None
            ENV_CHOICE = None

        COMMANDS = [
            [
                'post', __dry_run, '--timestamp', "_CLI__1",
                _path_of(_args[_s.PRODUCT_FILE])
            ],
            [
                'post', __environment, ENV_CHOICE, '--timestamp', "_CLI__2",
                _path_of(_args[_s.SCORING_CYCLE_FILE])
            ],
            [
                'post', __environment, ENV_CHOICE, '--timestamp', "_CLI__3",
                _path_of(_args[_s.BIG_ROCKS_v1_FILE])
            ],
            ['get', 'products', __environment, ENV_CHOICE],
            ['get', 'scoring-cycles', __environment, ENV_CHOICE],
            ['get', 'namespaces'],
            #['get', 'environments'], # Can't test- environment count non-deterministic
            ['get', 'apis'],
        ]

        self.myTest.skeleton_test(parent_trace=parent_trace,
                                  cli_command_list=COMMANDS,
                                  output_cleanining_lambda=MASK_COMBINED)

        # For the next test, we need to switch the working directory for click
        my_trace = parent_trace.doing(
            "Running with working directory in the collaboration area")
        store = self.myTest.stack().store()

        if self.myTest.sandbox != None:
            root_dir = _os.path.dirname(
                store.base_environment(my_trace).manifestsURL(my_trace))
            envs_dir = root_dir + "/" + File_KBEnv_Impl.ENVS_FOLDER

            working_dir                 = envs_dir + "/" + self.myTest.sandbox + "/external-collaboration/" \
                                            + _args[_s.REL_PATH_IN_EXT_COLLABORATION]
        else:
            clientURL = store.base_environment(my_trace).clientURL(my_trace)
            working_dir = clientURL + "/" + _args[
                _s.REL_PATH_IN_EXT_COLLABORATION]

        PathUtils().create_path_if_needed(parent_trace, working_dir)
        _os.chdir(working_dir)

        COMMANDS_2 = [[
            'get', 'form', __environment, ENV_CHOICE, '--timestamp', "_CLI__4",
            _args[_s.BIG_ROCKS_API], _args[_s.NAMESPACE],
            _args[_s.SUB_NAMESPACE]
        ],
                      [
                          'post', __environment, ENV_CHOICE, '--timestamp',
                          "_CLI__5",
                          _path_of(_args[_s.BIG_ROCKS_v2_FILE])
                      ],
                      [
                          'get', 'form', __environment, ENV_CHOICE,
                          '--timestamp', "_CLI__6",
                          _args[_s.BIG_MILESTONES_API], _args[_s.NAMESPACE],
                          _args[_s.SUB_NAMESPACE]
                      ],
                      [
                          'post', __environment, ENV_CHOICE, '--timestamp',
                          "_CLI__7",
                          _path_of(_args[_s.BIG_MILESTONES_v1_FILE])
                      ],
                      [
                          'get', 'form', __environment, ENV_CHOICE,
                          '--timestamp', "_CLI__8",
                          _args[_s.BIG_MILESTONES_API], _args[_s.NAMESPACE],
                          _args[_s.SUB_NAMESPACE]
                      ],
                      [
                          'post', __environment, ENV_CHOICE, '--timestamp',
                          "_CLI__9",
                          _path_of(_args[_s.BIG_MILESTONES_v2_FILE])
                      ],
                      [
                          'get', 'form', __environment, ENV_CHOICE,
                          '--timestamp', "_CLI__10",
                          _args[_s.BIG_MILESTONES_API], _args[_s.NAMESPACE],
                          _args[_s.SUB_NAMESPACE]
                      ], ['get', 'assertions', __environment, ENV_CHOICE]]

        self.myTest.skeleton_test(parent_trace=parent_trace,
                                  cli_command_list=COMMANDS_2,
                                  output_cleanining_lambda=MASK_COMBINED)
    def test_milestones_referenced_big_rock_version(self):
        '''
        Tests that integrity checks exist to prevent posting a milestones manifest if it references a
        version of the big rocks that is not the latest.
        '''
        try:
            self.setScenario("foreign_key.milestones_big_rock_version")
            self.setCurrentTestName('fkey.ml_2_br')
            self.selectTestDataLocation()

            root_trace                      = FunctionalTrace(parent_trace=None, path_mask=self._path_mask) \
                                                .doing("Running " + self.currentTestName())

            PRODUCT_FILE = "products.static-data.admin.a6i.xlsx"
            SCORING_CYCLE_FILE = "scoring-cycles.static-data.admin.a6i.xlsx"
            BIG_ROCKS_v1_FILE = "opus.v1.big-rocks.journeys.a6i.xlsx"
            BIG_ROCKS_v2_FILE = "opus.v2.big-rocks.journeys.a6i.xlsx"
            MILESTONES_FILE = "opus.v1.milestone.journeys.a6i.xlsx"
            BIG_ROCKS_API = "big-rocks.journeys.a6i"
            MILESTONES_API = "milestone.journeys.a6i"
            NAMESPACE = "my-corp.production"
            SUB_NAMESPACE = "modernization"
            REL_PATH_IN_EXT_COLLABORATION = "journeys/Dec 2020/FusionOpus/Default"

            _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.

            # For this test, we need to switch the working directory for click
            my_trace = root_trace.doing(
                "Running with working directory in the collaboration area")
            store = self.stack().store()

            clientURL = store.base_environment(my_trace).clientURL(my_trace)
            working_area = clientURL + "/" + REL_PATH_IN_EXT_COLLABORATION
            PathUtils().create_path_if_needed(my_trace, working_area)
            _os.chdir(working_area)

            COMMANDS = [
                ['post', '--timestamp', "_CLI__1",
                 _path_of(PRODUCT_FILE)],
                [
                    'post', '--timestamp', "_CLI__2",
                    _path_of(SCORING_CYCLE_FILE)
                ],
                [
                    'post', '--timestamp', "_CLI__3",
                    _path_of(BIG_ROCKS_v1_FILE)
                ],  # v1 of big-rocks
                [
                    'get', 'form', '--timestamp', "_CLI__4", MILESTONES_API,
                    NAMESPACE, SUB_NAMESPACE
                ],  # milestones -> big-rocks v1
                [
                    'get', 'form', '--timestamp', "_CLI__5", BIG_ROCKS_API,
                    NAMESPACE, SUB_NAMESPACE
                ],
                [
                    'post', '--timestamp', "_CLI__6",
                    _path_of(BIG_ROCKS_v2_FILE)
                ],  # v2 of big-rocks
                ['get', 'assertions'],
                ['post', '--timestamp', "_CLI__7",
                 _path_of(MILESTONES_FILE)],  # Should trigger an error
            ]

            self.skeleton_test(
                parent_trace=my_trace,
                cli_command_list=COMMANDS,
                output_cleanining_lambda=MASK_COMBINED,
                when_to_check_environment=CLI_Test_Skeleton.NEVER)
        except ApodeixiError as ex:
            print(ex.trace_message())
            self.assertTrue(1 == 2)
Exemple #12
0
    def run_script(self, parent_trace, SANDBOX_FUNC, cli_arguments_dict):

        _path_of = self.myTest.fullpath_of

        MASK_COMBINED = CLI_Utils().combined_mask(parent_trace,
                                                  self.myTest.a6i_config)

        _s = CLI_BigRocks_and_Milestones_Script
        _args = cli_arguments_dict

        # This will fool the CLI to treat our provisioned environment for this test as if it were the base environment
        self.myTest.overwrite_test_context(
            parent_trace
        )  # Overwrites self.a6i_config , the store, the test_db, etc.

        my_trace = parent_trace.doing(
            "Running with working directory in the collaboration area")
        store = self.myTest.stack().store()
        if self.myTest.sandbox != None:
            root_dir = _os.path.dirname(
                store.base_environment(my_trace).manifestsURL(my_trace))
            envs_dir = root_dir + "/" + File_KBEnv_Impl.ENVS_FOLDER

            working_dir                 = envs_dir + "/" + self.myTest.sandbox + "/external-collaboration/" \
                                            + _args[_s.REL_PATH_IN_EXT_COLLABORATION]
        else:
            clientURL = store.base_environment(my_trace).clientURL(my_trace)
            working_dir = clientURL + "/" + _args[
                _s.REL_PATH_IN_EXT_COLLABORATION]

        PathUtils().create_path_if_needed(parent_trace, working_dir)
        _os.chdir(working_dir)

        if SANDBOX_FUNC != None:
            __dry_run = '--dry-run'
            __environment = '--environment'
            ENV_CHOICE = SANDBOX_FUNC
        else:  # Case for life runs
            __dry_run = None
            __environment = None
            ENV_CHOICE = None

        COMMANDS_1 = [
            # Initialize static data
            [
                'post', __dry_run, '--timestamp', "_CLI__1",
                _path_of(_args[_s.PRODUCT_FILE])
            ],
            [
                'post', __environment, ENV_CHOICE, '--timestamp', "_CLI__2",
                _path_of(_args[_s.SCORING_CYCLE_FILE])
            ],
            # Create big rocks v1
            [
                'get', 'form', __environment, ENV_CHOICE, '--timestamp',
                "_CLI__3", _args[_s.BIG_ROCKS_API], _args[_s.NAMESPACE],
                _args[_s.SUB_NAMESPACE]
            ],
            [
                'post', __environment, ENV_CHOICE, '--timestamp', "_CLI__4",
                _path_of(_args[_s.BIG_ROCKS_v1_FILE])
            ],
            # Create milestones v1
            [
                'get', 'form', __environment, ENV_CHOICE, '--timestamp',
                "_CLI__5", _args[_s.BIG_MILESTONES_API], _args[_s.NAMESPACE],
                _args[_s.SUB_NAMESPACE]
            ],
            [
                'post', __environment, ENV_CHOICE, '--timestamp', "_CLI__6",
                _path_of(_args[_s.BIG_MILESTONES_v1_FILE])
            ],
        ]

        self.myTest.skeleton_test(
            parent_trace=my_trace,
            cli_command_list=COMMANDS_1,
            output_cleanining_lambda=MASK_COMBINED,
            when_to_check_environment=CLI_Test_Skeleton.NEVER)

        # Check that manifest is as expected
        NAME = "experimental.march-2021.turbotax.iot-experiment"
        NAMESPACE = "intuit.innovations"
        self.myTest.check_manifest(my_trace,
                                   'delivery-planning.journeys.a6i.io',
                                   NAMESPACE, NAME, 'big-rock')
        self.myTest.check_manifest(my_trace,
                                   'delivery-planning.journeys.a6i.io',
                                   NAMESPACE, NAME, 'big-rock-estimate')
        self.myTest.check_manifest(my_trace,
                                   'delivery-planning.journeys.a6i.io',
                                   NAMESPACE, NAME, 'modernization-milestone')

        COMMANDS_2 = [
            # First try to update big rocks v2 - should fail due to foreign key constraints
            [
                'get', 'form', __environment, ENV_CHOICE, '--timestamp',
                "_CLI__7", _args[_s.BIG_ROCKS_API], _args[_s.NAMESPACE],
                _args[_s.SUB_NAMESPACE]
            ],
            [
                'post', __environment, ENV_CHOICE, '--timestamp', "_CLI__8",
                _path_of(_args[_s.BIG_ROCKS_v2_FILE])
            ],
            # Update milestones v2 - should remove the reference that caused big rocks v2 to fail
            [
                'get', 'form', __environment, ENV_CHOICE, '--timestamp',
                "_CLI__9", _args[_s.BIG_MILESTONES_API], _args[_s.NAMESPACE],
                _args[_s.SUB_NAMESPACE]
            ],
            [
                'post', __environment, ENV_CHOICE, '--timestamp', "_CLI__10",
                _path_of(_args[_s.BIG_MILESTONES_v2_FILE])
            ],
            # Second try to update big rocks v2 - should work now that user removed references in
            # milestones v2 to the rocks that were removed in v2
            [
                'post', __environment, ENV_CHOICE, '--timestamp', "_CLI__11",
                _path_of(_args[_s.BIG_ROCKS_v2_FILE])
            ],
        ]

        self.myTest.skeleton_test(
            parent_trace=my_trace,
            cli_command_list=COMMANDS_2,
            output_cleanining_lambda=MASK_COMBINED,
            when_to_check_environment=CLI_Test_Skeleton.NEVER)

        # Check that manifest is as expected
        self.myTest.check_manifest(my_trace,
                                   'delivery-planning.journeys.a6i.io',
                                   NAMESPACE, NAME, 'big-rock')
        self.myTest.check_manifest(my_trace,
                                   'delivery-planning.journeys.a6i.io',
                                   NAMESPACE, NAME, 'big-rock-estimate')
        self.myTest.check_manifest(my_trace,
                                   'delivery-planning.journeys.a6i.io',
                                   NAMESPACE, NAME, 'modernization-milestone')

        COMMANDS_3 = [
            # Get final forms
            [
                'get', 'form', __environment, ENV_CHOICE, '--timestamp',
                "_CLI__12", _args[_s.BIG_ROCKS_API], _args[_s.NAMESPACE],
                _args[_s.SUB_NAMESPACE]
            ],
            [
                'get', 'form', __environment, ENV_CHOICE, '--timestamp',
                "_CLI__13", _args[_s.BIG_MILESTONES_API], _args[_s.NAMESPACE],
                _args[_s.SUB_NAMESPACE]
            ],
            # Summarize assertions created
            ['get', 'assertions', __environment, ENV_CHOICE]
        ]

        self.myTest.skeleton_test(
            parent_trace=my_trace,
            cli_command_list=COMMANDS_3,
            output_cleanining_lambda=MASK_COMBINED,
            when_to_check_environment=CLI_Test_Skeleton.ONLY_AT_END)
    def run_script(self, parent_trace, SANDBOX_FUNC, cli_arguments_dict):

        _path_of                     = self.myTest.fullpath_of

        MASK_COMBINED               = CLI_Utils().combined_mask(parent_trace, self.myTest.a6i_config)

        _s                          = CLI_StaticData_Script
        _args                       = cli_arguments_dict

        # This will fool the CLI to treat our provisioned environment for this test as if it were the base environment
        self.myTest.overwrite_test_context(parent_trace) # Overwrites self.a6i_config , the store, the test_db, etc.
        

        if SANDBOX_FUNC != None:
            __dry_run               = '--dry-run'
            __environment           = '--environment'
            ENV_CHOICE              = SANDBOX_FUNC
        else: # Case for life runs
            __dry_run               = None
            __environment           = None
            ENV_CHOICE              = None 

        # For the next test, we need to switch the working directory for click
        my_trace                    = parent_trace.doing("Running with working directory in the collaboration area")
        store                       = self.myTest.stack().store()

        if self.myTest.sandbox != None:
            root_dir                    = _os.path.dirname(store.base_environment(my_trace).manifestsURL(my_trace))
            envs_dir                    = root_dir + "/" + File_KBEnv_Impl.ENVS_FOLDER

            working_dir                 = envs_dir + "/" + self.myTest.sandbox + "/external-collaboration/" \
                                            + _args[_s.REL_PATH_IN_EXT_COLLABORATION]
            
        else:
            clientURL                   = store.base_environment(my_trace).clientURL(my_trace)
            working_dir                 = clientURL + "/" + _args[_s.REL_PATH_IN_EXT_COLLABORATION]

        PathUtils().create_path_if_needed(parent_trace, working_dir)
        _os.chdir(working_dir)
        COMMANDS                    = [
                                        ['get', 'form',                 __environment, ENV_CHOICE,  '--timestamp', "_CLI__1", 
                                            _args[_s.STATIC_DATA_API], _args[_s.NAMESPACE]],            
                                        ['post',                    __dry_run,                      '--timestamp', "_CLI__2", 
                                            _path_of(_args[_s.STATIC_DATA_v1_FILE])],
                                        ['get', 'form',                 __environment, ENV_CHOICE,  '--timestamp', "_CLI__3", 
                                            _args[_s.STATIC_DATA_API], _args[_s.NAMESPACE]], 
                                        ['post',                    __environment, ENV_CHOICE,      '--timestamp', "_CLI__4",
                                            _path_of(_args[_s.STATIC_DATA_v2_FILE])],
                                        ['get', 'form',                 __environment, ENV_CHOICE,  '--timestamp', "_CLI__5", 
                                            _args[_s.STATIC_DATA_API], _args[_s.NAMESPACE]], 

                                    ]

        self.myTest.skeleton_test(  parent_trace                = parent_trace,
                                    cli_command_list            = COMMANDS,
                                    output_cleanining_lambda    = MASK_COMBINED,
                                    when_to_check_environment   = CLI_Test_Skeleton.ONLY_AT_END)





                                                   
Exemple #14
0
    def test_cli_rollover_basic(self):
        '''
        Tests rollover functionality when traversing fiscal years: if there is no previous manifest for FY 23 but one
        exists from FY 22, then trying to retrieve the latest manifest in FY 23 will result in the latest one from FY 22,
        as opposed to a template-based default.
        '''
        self.setScenario("cli.basic_rollover")
        self.setCurrentTestName('basic_rollover')
        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'
        BIG_ROCKS_POSTING_API = 'big-rocks.journeys.a6i'
        BIG_ROCKS_MANIFEST_API = "delivery-planning.journeys.a6i.io"  #/v1a"
        NAMESPACE = 'cicloquimica.production'
        FY23_NAME = "modernization.fy-23.astrea.official"
        SUB_NAMESPACE = 'modernization'
        FY22_REL_PATH_IN_EXT_COLLAB = "journeys/FY 22/Astrea/Official"
        FY23_REL_PATH_IN_EXT_COLLAB = "journeys/FY 23/Astrea/Official"
        FY23_GENERATED_FORM_FILE = "Astrea.modernization.big-rocks.journeys.a6i.xlsx"

        STATIC_DATA_WORKING_DIR = "admin/static-data"

        _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.

        store = self.stack().store()
        clientURL = store.base_environment(root_trace).clientURL(root_trace)

        # Post the static data
        my_trace = root_trace.doing("Running with working directory '" +
                                    STATIC_DATA_WORKING_DIR + "'")

        working_dir = clientURL + "/" + STATIC_DATA_WORKING_DIR

        PathUtils().create_path_if_needed(my_trace, working_dir)
        _os.chdir(working_dir)

        COMMANDS_1 = [
            ['post', '--timestamp', "_CLI__1",
             _path_of(PRODUCTS_FILE)],
            ['post', '--timestamp', "_CLI__2",
             _path_of(SCORING_CYCLES_FILE)],
        ]

        self.skeleton_test(parent_trace=my_trace,
                           cli_command_list=COMMANDS_1,
                           output_cleanining_lambda=MASK_COMBINED,
                           when_to_check_environment=CLI_Test_Skeleton.NEVER)

        # Post the FY 22 big rocks
        my_trace = root_trace.doing("Running with working directory '" +
                                    FY22_REL_PATH_IN_EXT_COLLAB + "'")
        fy22_working_dir = clientURL + "/" + FY22_REL_PATH_IN_EXT_COLLAB

        PathUtils().create_path_if_needed(my_trace, fy22_working_dir)
        _os.chdir(fy22_working_dir)

        COMMANDS_2 = [[
            'post', '--timestamp', "_CLI__3",
            _path_of(BIG_ROCKS_FILE_V1)
        ], ['post', '--timestamp', "_CLI__4",
            _path_of(BIG_ROCKS_FILE_V2)],
                      [
                          'get', 'form', '--timestamp', "_CLI__5",
                          BIG_ROCKS_POSTING_API, NAMESPACE, SUB_NAMESPACE
                      ]]

        self.skeleton_test(parent_trace=my_trace,
                           cli_command_list=COMMANDS_2,
                           output_cleanining_lambda=MASK_COMBINED,
                           when_to_check_environment=CLI_Test_Skeleton.NEVER)

        # For the next test, we need to switch the working directory for click
        my_trace = root_trace.doing("Running with working directory '" +
                                    FY23_REL_PATH_IN_EXT_COLLAB + "'")

        fy23_working_dir = clientURL + "/" + FY23_REL_PATH_IN_EXT_COLLAB

        PathUtils().create_path_if_needed(my_trace, fy23_working_dir)
        _os.chdir(fy23_working_dir)

        COMMANDS_3 = [
            [
                'get', 'form', '--timestamp', "_CLI__6", BIG_ROCKS_POSTING_API,
                NAMESPACE, SUB_NAMESPACE
            ],
            [
                'post', '--timestamp', "_CLI__7",
                fy23_working_dir + "/" + FY23_GENERATED_FORM_FILE
            ],
        ]

        self.skeleton_test(parent_trace=my_trace,
                           cli_command_list=COMMANDS_3,
                           output_cleanining_lambda=MASK_COMBINED,
                           when_to_check_environment=CLI_Test_Skeleton.NEVER)

        # Check that manifest is as expected right after a first FY 23 manifest is created from a rollover
        # For example, we expect its labels to include the rollFromName field to indicate its lineage as a continuation
        # of FY 22

        self.check_manifest(my_trace, BIG_ROCKS_MANIFEST_API, NAMESPACE,
                            FY23_NAME, 'big-rock')

        # Now we do a full cycle get-form + post, to see that the new lineage in FY 23 can take off as expected
        COMMANDS_4 = [
            [
                'get', 'form', '--timestamp', "_CLI__8", BIG_ROCKS_POSTING_API,
                NAMESPACE, SUB_NAMESPACE
            ],
            [
                'post', '--timestamp', "_CLI__9",
                fy23_working_dir + "/" + FY23_GENERATED_FORM_FILE
            ],
        ]

        self.skeleton_test(
            parent_trace=my_trace,
            cli_command_list=COMMANDS_4,
            output_cleanining_lambda=MASK_COMBINED,
            when_to_check_environment=CLI_Test_Skeleton.ONLY_AT_END)

        # Check that manifest is as expected right after we are no longer in a rollover situation, and are modifying
        # previous manifests in FY 23.
        #
        # For example, it should no longer be the case that its labels include the rollFromName field, as it used to
        # be the case when we created the first FY 23 manifest, since only that first manifested needed to
        # to indicate its lineage as a continuation of FY 22
        #
        self.check_manifest(my_trace, BIG_ROCKS_MANIFEST_API, NAMESPACE,
                            FY23_NAME, 'big-rock')