Exemple #1
0
    def test_version_check_older_cluster(self):  # pylint: disable=invalid-name
        """
        Test that when hitting an older cluster without a cluster version, the time is updated and
        we mark the cluster check as passed/not done.

        We don't actually hit a live cluster, so we will enter a dummy value of None to the
        function call, which is what the result will be http gateway returns error.
        """

        state_file_path = sfctl_state.get_state_path()

        # empty the file
        open(state_file_path, 'w').close()

        current_utc_time = datetime.utcnow()

        # Check cluster version. This should update the last updated time (in state)
        checks_passed_or_not_done = check_cluster_version(
            False, dummy_cluster_version='NoResult')

        self.assertTrue(
            checks_passed_or_not_done,
            'check_cluster_version should return True '
            'because checks should not be performed, '
            'since we are simulating that we are a newer '
            'sfctl hitting a cluster without the '
            'get cluster version API.')

        self.assertGreater(
            sfctl_state.get_cluster_version_check_time(), current_utc_time,
            'check_cluster_version command should have modified the '
            'last checked time such that the time in state is greater than our '
            'time.')
Exemple #2
0
def launch():
    """Entry point for Service Fabric CLI.

    Configures and invokes CLI with arguments passed during the time the python
    session is launched.

    This is run every time a sfctl command is invoked.

    If you have a local error, say the command is not recognized, then the invoke command will
    raise an exception.
    If you have success, it will return error code 0.
    If the HTTP request returns an error, then an exception is not thrown, and error
    code is not 0."""

    args_list = sys.argv[1:]

    cli_env = cli()

    is_help_cmd = is_help_command(args_list)

    invocation_return_value = cli_env.invoke(args_list)

    # We don't invoke cluster version checking when the user gets an exception, since it means that
    # there is something wrong with their command input, such as missing a required parameter.
    # This is not the same as an error returned from the server, which does not raise an exception.
    # We should also not hit the cluster in the cases of the user inputting a help command (-h)

    if is_help_cmd:
        return invocation_return_value

    try:
        if invocation_return_value != 0 or ('cluster'
                                            and 'select' in sys.argv[1:]):
            # invocation_return_value is 0 on success
            check_cluster_version(on_failure_or_connection=True)
        else:
            check_cluster_version(on_failure_or_connection=False)

    except:  # pylint: disable=bare-except
        # Catch any exceptions from checking cluster version. For example, if we are not able
        # to read the state file due to corruption, fail silently.
        from knack.log import get_logger
        logger = get_logger(__name__)
        ex = sys.exc_info()[0]
        logger.info('Check cluster version failed due to error: %s', str(ex))

    return invocation_return_value
Exemple #3
0
    def test_version_check_not_triggered(self):  # pylint: disable=invalid-name
        """Test that under the following circumstances, a cluster version & sfctl version
        compatibility check is NOT triggered and if the last check time was left in a good state
        after the call:
            - The last check time was less than config.py - SF_CLI_VERSION_CHECK_INTERVAL

        NOTE: this is a unit test only, which relies on the
        custom_cluster.py - check_cluster_version
        function being called with the correct parameters, and being called at all.

        This test assumes SF_CLI_VERSION_CHECK_INTERVAL = 24 hours
        """

        current_utc_time = datetime.utcnow()

        adjusted_hour = current_utc_time.hour
        adjusted_minute = current_utc_time.minute
        adjusted_day = current_utc_time.day
        if adjusted_minute >= 5:
            adjusted_minute = adjusted_minute - 5
        elif adjusted_hour >= 1:
            adjusted_hour = adjusted_hour - 1
        else:
            adjusted_day = adjusted_day - 1
            adjusted_hour = 23

        utc_time_past = datetime(year=current_utc_time.year,
                                 month=current_utc_time.month,
                                 day=adjusted_day,
                                 hour=adjusted_hour,
                                 minute=adjusted_minute)

        cluster_version = 'invalid_version'

        # Configure last checked time to current time minus some amount of time less than 24 hours
        # Run check_cluster_version
        # Check that the values in the state file of the last checked time is correct
        # Test may fail if SF_CLI_VERSION_CHECK_INTERVAL value is too low.

        sfctl_state.set_cluster_version_check_time(utc_time_past)
        checks_passed_or_not_done = check_cluster_version(
            on_failure_or_connection=False,
            dummy_cluster_version=cluster_version)

        self.assertTrue(
            checks_passed_or_not_done,
            'check_cluster_version should return True '
            'because no checks were performed')
        self.assertEqual(
            utc_time_past, sfctl_state.get_cluster_version_check_time(),
            'check_cluster_version command should not have modified the '
            'last checked time values since it should have returned True, having '
            'done no work.')

        # Configure last checked time to current time
        # Run check_cluster_version
        # Check that the values in the state file of the last checked time is correct

        current_utc_time = datetime.utcnow()
        sfctl_state.set_cluster_version_check_time(current_utc_time)

        checks_passed_or_not_done = check_cluster_version(
            on_failure_or_connection=False,
            dummy_cluster_version=cluster_version)

        self.assertTrue(
            checks_passed_or_not_done,
            'check_cluster_version should return True '
            'because no checks were performed')
        self.assertEqual(
            current_utc_time, sfctl_state.get_cluster_version_check_time(),
            'check_cluster_version command should not have modified the '
            'last checked time values since it should have returned True, having '
            'done no work.')
Exemple #4
0
    def test_version_check_triggered(self):
        """Test that under the following circumstances, a cluster version & sfctl version
        compatibility check is triggered and verify that the last check time was left
        in a good state after the call:
            - The last check time (in state) doesn't exist yet
            - An error has occurred during function call
            - On connection to a new cluster even
                if time since last check is less than SF_CLI_VERSION_CHECK_INTERVAL
            - The last check time (in state) was greater than
                config.py's SF_CLI_VERSION_CHECK_INTERVAL

        NOTE: this is a unit test only, which relies on the
        custom_cluster.py - check_cluster_version
        function being called with the correct parameters, and being called at all.
        """

        # Start session state with condition last check time does not exist:
        state_file_path = sfctl_state.get_state_path()
        # If anything other than one line with our state exists in the file
        # (2 lines total - one to specify the section)
        # then throw an error. This may happen if sfctl uses the state file for something else.
        # If the state file ends up being used for anything else
        # other than last checked API version time, then modify this test then to remove
        # only that one line.
        with open(state_file_path) as state_file:
            content = state_file.readlines()

        content_trimmed = []
        for line in content:
            if line.strip():
                content_trimmed.append(line)

        self.assertLess(
            len(content_trimmed), 3,
            'sfctl state file should not have more than 2 lines. '
            'Content: ' + str(content_trimmed))

        # empty the file
        open(state_file_path, 'w').close()

        # Create cluster version object.
        cluster_version = 'invalid_version'

        current_utc_time = datetime.utcnow()

        # Check cluster version. This should update the last updated time (in state)
        checks_passed_or_not_done = check_cluster_version(
            False, dummy_cluster_version=cluster_version)

        self.assertFalse(
            checks_passed_or_not_done,
            'check_cluster_version should return False '
            'because checks were performed and the '
            'versions do not match')
        self.assertGreater(
            sfctl_state.get_cluster_version_check_time(), current_utc_time,
            'check_cluster_version command should have modified the '
            'last checked time such that the time in state is greater than our '
            'time.')

        # Set the last checked time in state to something recent, and set calling on failure
        # to True
        sfctl_state.set_cluster_version_check_time(current_utc_time)

        checks_passed_or_not_done = check_cluster_version(
            on_failure_or_connection=True,
            dummy_cluster_version=cluster_version)

        self.assertFalse(
            checks_passed_or_not_done,
            'check_cluster_version should return False '
            'because checks were performed and the '
            'versions do not match')
        self.assertGreater(
            sfctl_state.get_cluster_version_check_time(), current_utc_time,
            'check_cluster_version command should have modified the '
            'last checked time such that the time in state is greater than our '
            'time.')

        # Last check time is in the past (well past SF_CLI_VERSION_CHECK_INTERVAL),
        # so should trigger an update and a check
        utc_time_past = datetime(year=current_utc_time.year - 1,
                                 month=12,
                                 day=20,
                                 hour=0,
                                 minute=0,
                                 second=0)

        sfctl_state.set_cluster_version_check_time(utc_time_past)

        checks_passed_or_not_done = check_cluster_version(
            on_failure_or_connection=False,
            dummy_cluster_version=cluster_version)

        self.assertFalse(
            checks_passed_or_not_done,
            'check_cluster_version should return False '
            'because checks were performed and the '
            'versions do not match')
        self.assertGreater(
            sfctl_state.get_cluster_version_check_time(), utc_time_past,
            'check_cluster_version command should have modified the '
            'last checked time such that the time in state is greater than our '
            'time.')