Exemple #1
0
    def test_pause_on_fail(self):
        # First shutdown the default setup trail.
        self.trail_client.shutdown(dry_run=False)

        def failing_action_function(trail_env, context):
            raise Exception('mock failure')

        step_a = Step(failing_action_function)
        step_b = Step(action_function_b)

        # Trail definition: The following example trail represents the following DAG:
        # step_a ----> step_b
        test_trail_definition = [(step_a, step_b)]

        context = Context(42)
        self.trail_server = TrailServer(test_trail_definition,
                                        delay=0.1,
                                        context=context)
        self.trail_server.serve(threaded=True)
        self.trail_client = TrailClient(self.trail_server.socket_file)

        self.trail_client.start()

        self.wait_till('failing_action_function', Step.PAUSED_ON_FAIL)

        self.check_step_attributes(
            StatusField.STATE, {
                'failing_action_function': Step.PAUSED_ON_FAIL,
                'action_function_b': Step.WAIT,
            })

        self.check_step_attributes(StatusField.RETURN_VALUE, {
            'failing_action_function': 'mock failure',
            'action_function_b': None,
        })
Exemple #2
0
    def test_message_passing(self):
        # First shutdown the default setup trail.
        self.trail_client.shutdown(dry_run=False)

        def io_action_function(trail_env, context):
            reply = trail_env.input('Prompting user')
            trail_env.output('Reply received: {}'.format(reply))

        def slow_action_function(trail_env, context):
            sleep(0.2)

        step_a = Step(io_action_function)
        step_b = Step(slow_action_function)

        # Trail definition: The following example trail represents the following DAG:
        # step_a ----> step_b
        #
        test_trail_definition = [(step_a, step_b)]

        context = Context(42)
        self.trail_server = TrailServer(test_trail_definition,
                                        delay=0.1,
                                        context=context)
        self.trail_server.serve(threaded=True)
        self.trail_client = TrailClient(self.trail_server.socket_file)

        self.trail_client.start()

        self.wait_till('io_action_function', Step.RUN)

        statuses = self.trail_client.status(name='io_action_function')

        self.assertEqual(len(statuses), 1)

        prompt_message = statuses[0][StatusField.UNREPLIED_PROMPT_MESSAGE]
        self.assertEqual(prompt_message, 'Prompting user')

        # Reply to steps
        self.trail_client.send_message_to_steps(name='io_action_function',
                                                message='Done',
                                                dry_run=False)

        self.wait_till('io_action_function', Step.SUCCESS)

        # Check reply
        statuses = self.trail_client.status(
            name='io_action_function', fields=[StatusField.OUTPUT_MESSAGES])
        self.assertEqual(len(statuses), 1)
        output_messages = statuses[0][StatusField.OUTPUT_MESSAGES]
        self.assertEqual(output_messages, ['Reply received: Done'])
Exemple #3
0
    def test_interrupt(self):
        # First shutdown the default setup trail.
        self.trail_client.shutdown(dry_run=False)

        # We need a long running step to be able to invoke interrupt on it.
        def long_running_action_function(trail_env, context):
            sleep(3)
            return "This is action A. Value from context: {}".format(
                context.value)

        step_a = Step(long_running_action_function)
        step_b = Step(action_function_b)

        # Define a trail with slightly long running steps.
        # The following example trail represents the following DAG:
        # step_a ----> step_b
        test_trail_definition = [(step_a, step_b)]

        context = Context(42)
        self.trail_server = TrailServer(test_trail_definition,
                                        delay=0.1,
                                        context=context)
        self.trail_server.serve(threaded=True)
        self.trail_client = TrailClient(self.trail_server.socket_file)

        self.trail_client.start()

        self.wait_till('long_running_action_function', Step.RUN)

        # long_running_action_function is a long running step (5 seconds), so terminate it.
        affected_steps = self.trail_client.interrupt(dry_run=False)
        self.check_affected_steps(affected_steps,
                                  ['long_running_action_function'])

        self.check_step_attributes(
            StatusField.STATE, {
                'long_running_action_function': Step.INTERRUPTED,
                'action_function_b': Step.WAIT,
            })

        # Make sure interrupted is a state that can be resumed from (re-run).
        affected_steps = self.trail_client.resume()
        self.check_affected_steps(affected_steps,
                                  ['long_running_action_function'])
Exemple #4
0
    def setUp(self):
        self.step_a = Step(action_function_a)
        self.step_b = Step(action_function_b, foo='bar')
        self.step_c = Step(action_function_c)
        self.step_d = Step(action_function_d)
        self.step_e = Step(action_function_e)
        self.step_f = Step(action_function_f, foo='bar')
        self.step_g = Step(action_function_g)

        # Trail definition
        # The following example trail represents the following DAG:
        # The run-time (in seconds) of each step is mentioned below the step name.
        #         +----> step_b ----> step_c ----> step_d ----+
        #         |        1           1             1        |
        # step_a -|                                           +----> step_g
        #    1    |         1                         1       |        1
        #         +----> step_e -----------------> step_f ----+
        #
        test_trail_definition = [
            (self.step_a, self.step_b),
            (self.step_a, self.step_e),

            # First branch
            (self.step_b, self.step_c),
            (self.step_c, self.step_d),
            (self.step_d, self.step_g),

            # Second branch
            (self.step_e, self.step_f),
            (self.step_f, self.step_g),
        ]

        # Adding this for convenience in tests.
        self.step_list = [
            self.step_a,
            self.step_b,
            self.step_c,
            self.step_d,
            self.step_e,
            self.step_f,
            self.step_g,
        ]

        # Setup trail to run automatically (non-interactively)
        context = Context(42)
        self.trail_server = TrailServer(test_trail_definition,
                                        delay=0.1,
                                        context=context)
        self.trail_server.serve(threaded=True)
        self.trail_client = TrailClient(self.trail_server.socket_file)
    return "This is action E. Value from context: {}".format(context.value)


@accepts_context
def action_function_f(context):
    sleep(1)
    return "This is action F. Value from context: {}".format(context.value)


@accepts_context
def action_function_g(context):
    sleep(10)
    return "This is action G. Value from context: {}".format(context.value)


step_a = Step(action_function_a)
step_b = Step(action_function_b)
step_c = Step(action_function_c, foo='bar')
step_d = Step(action_function_d)
step_e = Step(action_function_e)
step_f = Step(action_function_f, foo='bar')
step_g = Step(action_function_g)


# Trail definition
# The following example trail represents the following DAG:
# The run-time (in seconds) of each step is mentioned below the step name.
#         +----> step_b ----> step_c ----> step_d ----+
#         |        10           1            10       |
# step_a -|                                           +----> step_g
#    5    |         5                         1       |        10
    if sleep_time > 5:
        return 'I have slept well.'
    else:
        return 'You woke me up too early, I am coming after you.'


def ending_point(action):
    return '[Here is how I feel] -- {}'.format(action)


# Now that we have the functions defined, we need to define action functions and wrap them in Steps.
# Below you will see the use of extraction_wrapper and create_conditional_step, two useful helpers that will allow
# us to easily convert the above functions into steps with behaviour that we want them to exhibit.

# Let us start with the most trivial case where we convert the starting_point function into a step.
start_the_day = Step(starting_point)
# If we had not used the @accepts_nothing decorator at the function defintion, we could have simply done:
# Step(accepts_nothing(starting_point))

# Now lets look at te "lazy" function.
# It has the following behaviour:
# 1. Accepts a string for branch choice.
# 2. If it matches BranchChoice.lazy, returns a string.
# 3. If it does not, then raises BranchNotChosen exception.
#
# We need to modify this behaviour to doing the following:
# 1. Accept TrailEnvironment and Context objects.
# 2. Extract the branch choice from the Context object using context.get_branch_choice method.
# 3. Call "lazy" function with the branch choice.
# 4. Use the return value as the return value of the step.
# 5. Use the exception raised as the return value of the step.
Exemple #7
0
import os

from time import sleep

from autotrail import (TrailServer, TrailClient, InteractiveTrail, interactive,
                       Step, StatusField, Instruction,
                       make_simple_templating_function)

logging.basicConfig(level=logging.DEBUG,
                    filename=os.path.join('/', 'tmp',
                                          'example_trail_server.log'))

# Action function and Step definitions
step_a = Step(
    Instruction(
        'step_a',
        make_simple_templating_function(
            'Check who are you using: /bin/whoami')))

step_b = Step(
    Instruction(
        'step_b',
        make_simple_templating_function(
            'Check the current directory with: /bin/pwd')))

step_c = Step(
    Instruction('step_c',
                make_simple_templating_function('List files using: ls -l')))

step_d = Step(
    Instruction(
    sleep(5)
    return value + 5


def action_function_f(value):
    sleep(1)
    return value + 6


def action_function_g(value):
    sleep(10)
    return value + 7


step_a = Step(action_function_a,
              pre_processor=pre_processor,
              post_processor=post_processor)
step_b = Step(action_function_b,
              pre_processor=pre_processor,
              post_processor=post_processor)
step_c = Step(action_function_c,
              pre_processor=pre_processor,
              post_processor=post_processor,
              foo='bar')
step_d = Step(action_function_d,
              pre_processor=pre_processor,
              post_processor=post_processor)
step_e = Step(action_function_e,
              pre_processor=pre_processor,
              post_processor=post_processor)
step_f = Step(action_function_f,