Exemple #1
0
    def test_execute_with_accumulator_missing_action_callbacks(self):
        action = Action(app_name='HelloWorld',
                        action_name='Add Three',
                        arguments=[
                            Argument('num1', reference='1'),
                            Argument('num2', reference='action2'),
                            Argument('num3', value='10.2')
                        ])
        accumulator = {'1': '-5.6', 'missing': '4.3', '3': '45'}
        instance = AppInstance.create(app_name='HelloWorld',
                                      device_name='device1')

        result = {'started_triggered': False, 'result_triggered': False}

        def callback_is_sent(sender, **kwargs):
            if isinstance(sender, Action):
                self.assertIn('event', kwargs)
                self.assertIn(kwargs['event'],
                              (WalkoffEvent.ActionStarted,
                               WalkoffEvent.ActionArgumentsInvalid))
                if kwargs['event'] == WalkoffEvent.ActionStarted:
                    result['started_triggered'] = True
                else:
                    result['result_triggered'] = True

        WalkoffEvent.CommonWorkflowSignal.connect(callback_is_sent)
        action.execute(instance.instance, accumulator)

        self.assertTrue(result['started_triggered'])
        self.assertTrue(result['result_triggered'])
Exemple #2
0
 def test_execute_with_complex_args(self):
     action = Action(app_name='HelloWorld',
                     action_name='Json Sample',
                     arguments=[
                         Argument('json_in',
                                  value={
                                      'a':
                                      '-5.6',
                                      'b': {
                                          'a': '4.3',
                                          'b': 5.3
                                      },
                                      'c': ['1', '2', '3'],
                                      'd': [{
                                          'a': '',
                                          'b': 3
                                      }, {
                                          'a': '',
                                          'b': -1.5
                                      }, {
                                          'a': '',
                                          'b': -0.5
                                      }]
                                  })
                     ])
     instance = AppInstance.create(app_name='HelloWorld',
                                   device_name='device1')
     result = action.execute(instance.instance, {})
     self.assertAlmostEqual(result.result, 11.0)
     self.assertEqual(result.status, 'Success')
     self.assertEqual(action._output, result)
Exemple #3
0
    def test_execute_sends_callbacks(self):
        action = Action(app_name='HelloWorld',
                        action_name='Add Three',
                        arguments=[
                            Argument('num1', value='-5.6'),
                            Argument('num2', value='4.3'),
                            Argument('num3', value='10.2')
                        ])
        instance = AppInstance.create(app_name='HelloWorld',
                                      device_name='device1')

        result = {'started_triggered': False, 'result_triggered': False}

        def callback_is_sent(sender, **kwargs):
            if isinstance(sender, Action):
                self.assertIn('event', kwargs)
                self.assertIn(kwargs['event'],
                              (WalkoffEvent.ActionStarted,
                               WalkoffEvent.ActionExecutionSuccess))
                if kwargs['event'] == WalkoffEvent.ActionStarted:
                    result['started_triggered'] = True
                else:
                    self.assertIn('data', kwargs)
                    data = kwargs['data']
                    self.assertEqual(data['status'], 'Success')
                    self.assertAlmostEqual(data['result'], 8.9)
                    result['result_triggered'] = True

        WalkoffEvent.CommonWorkflowSignal.connect(callback_is_sent)

        action.execute(instance.instance, {})
        self.assertTrue(result['started_triggered'])
        self.assertTrue(result['result_triggered'])
Exemple #4
0
 def test_execute_no_args(self):
     action = Action(app_name='HelloWorld', action_name='helloWorld')
     instance = AppInstance.create(app_name='HelloWorld',
                                   device_name='device1')
     self.assertEqual(action.execute(instance.instance, {}),
                      ActionResult({'message': 'HELLO WORLD'}, 'Success'))
     self.assertEqual(action._output,
                      ActionResult({'message': 'HELLO WORLD'}, 'Success'))
Exemple #5
0
 def test_execute_global_action(self):
     action = Action(app_name='HelloWorld',
                     action_name='global2',
                     arguments=[Argument('arg1', value='something')])
     instance = AppInstance.create(app_name='HelloWorld', device_name='')
     result = action.execute(instance.instance, {})
     self.assertAlmostEqual(result.result, 'something')
     self.assertEqual(result.status, 'Success')
     self.assertEqual(action._output, result)
Exemple #6
0
 def test_get_branch_invalid_action(self):
     flag = Condition('HelloWorld',
                      action_name='regMatch',
                      arguments=[Argument('regex', value='aaa')])
     branch = Branch(source_uid="1",
                     destination_uid='next',
                     conditions=[flag])
     action = Action('HelloWorld', 'helloWorld', uid="2")
     action._output = ActionResult(result='bbb', status='Success')
     workflow = Workflow(actions=[action], branches=[branch])
     self.assertIsNone(workflow.get_branch(action, {}))
Exemple #7
0
 def test_execute_with_accumulator_missing_action(self):
     action = Action(app_name='HelloWorld',
                     action_name='Add Three',
                     arguments=[
                         Argument('num1', reference='1'),
                         Argument('num2', reference='action2'),
                         Argument('num3', value='10.2')
                     ])
     accumulator = {'1': '-5.6', 'missing': '4.3', '3': '45'}
     instance = AppInstance.create(app_name='HelloWorld',
                                   device_name='device1')
     action.execute(instance.instance, accumulator)
Exemple #8
0
 def test_execute_with_args(self):
     action = Action(app_name='HelloWorld',
                     action_name='Add Three',
                     arguments=[
                         Argument('num1', value='-5.6'),
                         Argument('num2', value='4.3'),
                         Argument('num3', value='10.2')
                     ])
     instance = AppInstance.create(app_name='HelloWorld',
                                   device_name='device1')
     result = action.execute(instance.instance, {})
     self.assertAlmostEqual(result.result, 8.9)
     self.assertEqual(result.status, 'Success')
     self.assertEqual(action._output, result)
Exemple #9
0
 def test_set_args_invalid_format(self):
     action = Action(app_name='HelloWorld',
                     action_name='Add Three',
                     arguments=[
                         Argument('num1', value='-5.6'),
                         Argument('num2', value='4.3'),
                         Argument('num3', value='10.2')
                     ])
     with self.assertRaises(InvalidArgument):
         action.set_arguments([
             Argument('num1', value='-5.62'),
             Argument('num2', value='5'),
             Argument('num3', value='invalid')
         ])
Exemple #10
0
 def test_execute_with_accumulator_with_extra_actions(self):
     action = Action(app_name='HelloWorld',
                     action_name='Add Three',
                     arguments=[
                         Argument('num1', reference='1'),
                         Argument('num2', reference='action2'),
                         Argument('num3', value='10.2')
                     ])
     accumulator = {'1': '-5.6', 'action2': '4.3', '3': '45'}
     instance = AppInstance.create(app_name='HelloWorld',
                                   device_name='device1')
     result = action.execute(instance.instance, accumulator)
     self.assertAlmostEqual(result.result, 8.9)
     self.assertEqual(result.status, 'Success')
     self.assertEqual(action._output, result)
Exemple #11
0
 def create_action(self,
                   name='',
                   action='',
                   app='',
                   device='',
                   arguments=None,
                   risk=0):
     """Creates a new Action object and adds it to the Workflow's list of Actions.
     
     Args:
         name (str, optional): The name of the Action object. Defaults to an empty string.
         action (str, optional): The name of the action associated with a Action. Defaults to an empty string.
         app (str, optional): The name of the app associated with the Action. Defaults to an empty string.
         device (str, optional): The name of the device associated with the app associated with the Action. Defaults
             to an empty string.
         arguments (list[Argument]): A list of Argument objects that are parameters to the action execution. Defaults
             to None.
         risk (int, optional): The risk associated with the Action. Defaults to 0.
         
     """
     arguments = arguments if arguments is not None else []
     action = Action(name=name,
                     action_name=action,
                     app_name=app,
                     device_id=device,
                     arguments=arguments,
                     risk=risk)
     self.actions[action.uid] = action
     self.branches[action.uid] = []
     self._total_risk += risk
     logger.info('Action added to workflow {0}. Action: {1}'.format(
         self.name, self.actions[action.uid].read()))
Exemple #12
0
 def test_init_app_action_only_with_device(self):
     action = Action('HelloWorld', 'helloWorld', device_id='test')
     self.__compare_init(action,
                         '',
                         'helloWorld',
                         'HelloWorld',
                         device_id='test')
Exemple #13
0
    def test_save_workflow_invalid_input_format(self):
        initial_workflow = flask_server.running_context.controller.get_workflow(
            'test', 'helloWorldWorkflow')
        workflow_name = initial_workflow.name
        initial_actions = [
            action.read() for action in initial_workflow.actions.values()
        ]
        initial_actions[0]['position']['x'] = 0.0
        initial_actions[0]['position']['y'] = 0.0
        added_action = Action(name='new_id',
                              app_name='HelloWorld',
                              action_name='pause',
                              arguments=[Argument("seconds", value=5)],
                              position={
                                  'x': 0,
                                  'y': 0
                              }).read()
        added_action['arguments'][0]['value'] = 'aaaa'

        initial_actions.append(added_action)
        data = {"actions": initial_actions}
        self.post_with_status_check(
            '/api/playbooks/test/workflows/{0}/save'.format(workflow_name),
            data=json.dumps(data),
            headers=self.headers,
            content_type='application/json',
            status_code=INVALID_INPUT_ERROR)
Exemple #14
0
    def test_save_workflow_new_start_action(self):
        initial_workflow = flask_server.running_context.controller.get_workflow(
            'test', 'helloWorldWorkflow')
        workflow_name = initial_workflow.name
        initial_actions = [
            action.read() for action in initial_workflow.actions.values()
        ]
        initial_actions[0]['position']['x'] = 0.0
        initial_actions[0]['position']['y'] = 0.0
        added_action = Action(name='new_id',
                              app_name='HelloWorld',
                              action_name='pause',
                              arguments=[Argument('seconds', value=5)],
                              position={
                                  'x': 0,
                                  'y': 0
                              }).read()

        initial_actions.append(added_action)
        data = {"actions": initial_actions, "start": "new_start"}
        self.post_with_status_check(
            '/api/playbooks/test/workflows/{0}/save'.format(workflow_name),
            data=json.dumps(data),
            headers=self.headers,
            content_type='application/json')

        resulting_workflow = flask_server.running_context.controller.get_workflow(
            'test', workflow_name)
        self.assertEqual(resulting_workflow.start, "new_start")
Exemple #15
0
    def update_from_json(self, json_in):
        """Reconstruct a Workflow object based on JSON data.

           Args:
               json_in (JSON dict): The JSON data to be parsed and reconstructed into a Workflow object.
        """

        backup_actions = self.deepcopy_actions_with_events()
        backup_branches = deepcopy(self.branches)
        self.actions = {}
        if 'name' in json_in:
            self.name = json_in['name']
        uid = json_in['uid'] if 'uid' in json_in else self.uid
        try:
            if 'start' in json_in and json_in['start']:
                self.start = json_in['start']
            self.actions = {}
            self.uid = uid
            for action_json in json_in['actions']:
                action = Action.create(action_json)
                self.actions[action_json['uid']] = action
            if "branches" in json_in:
                branches = [
                    Branch.create(cond_json)
                    for cond_json in json_in['branches']
                ]
                self.branches = {}
                for branch in branches:
                    if branch.source_uid not in self.branches:
                        self.branches[branch.source_uid] = []
                    self.branches[branch.source_uid].append(branch)
        except (UnknownApp, UnknownAppAction, InvalidArgument):
            self.restore_actions_and_events(backup_actions)
            self.branches = backup_branches
            raise
Exemple #16
0
 def test_branch_with_priority(self):
     flag = Condition('HelloWorld',
                      action_name='regMatch',
                      arguments=[Argument('regex', value='aaa')])
     branch_one = Branch(source_uid="1",
                         destination_uid='five',
                         conditions=[flag],
                         priority="5")
     branch_two = Branch(source_uid="1",
                         destination_uid='one',
                         conditions=[flag],
                         priority="1")
     action = Action('HelloWorld', 'helloWorld', uid="1")
     action._output = ActionResult(result='aaa', status='Success')
     workflow = Workflow(actions=[action],
                         branches=[branch_one, branch_two])
     self.assertEqual(workflow.get_branch(action, {}), "one")
Exemple #17
0
 def test_init_with_arguments_with_conversion(self):
     action = Action('HelloWorld',
                     'returnPlusOne',
                     arguments=[Argument('number', value='-5.6')])
     self.__compare_init(action,
                         '',
                         'returnPlusOne',
                         'HelloWorld',
                         arguments=[Argument('number', value='-5.6')])
Exemple #18
0
 def test_init_templated(self):
     action = Action('HelloWorld',
                     'helloWorld',
                     templated=True,
                     raw_representation={'a': 42})
     self.__compare_init(action,
                         '',
                         'helloWorld',
                         'HelloWorld',
                         templated=True,
                         raw_representation={'a': 42})
Exemple #19
0
    def test_get_branch(self):
        flag = Condition('HelloWorld',
                         action_name='regMatch',
                         arguments=[Argument('regex', value='aaa')])
        branch = Branch(source_uid="1", destination_uid="2", conditions=[flag])
        action = Action('HelloWorld', 'helloWorld', uid="1")
        action._output = ActionResult(result='aaa', status='Success')
        workflow = Workflow(actions=[action], branches=[branch])

        result = {'triggered': False}

        def validate_sent_data(sender, **kwargs):
            if isinstance(sender, Branch):
                self.assertIn('event', kwargs)
                self.assertEqual(kwargs['event'], WalkoffEvent.BranchTaken)
                result['triggered'] = True

        WalkoffEvent.CommonWorkflowSignal.connect(validate_sent_data)

        self.assertEqual(workflow.get_branch(action, {}), '2')
        self.assertTrue(result['triggered'])
Exemple #20
0
    def test_execute_multiple_triggers(self):
        triggers = [
            Condition('HelloWorld',
                      action_name='regMatch',
                      arguments=[Argument('regex', value='aaa')])
        ]
        action = Action(app_name='HelloWorld',
                        action_name='helloWorld',
                        triggers=triggers)
        instance = AppInstance.create(app_name='HelloWorld',
                                      device_name='device1')
        action.send_data_to_trigger({"data_in": {"data": 'a'}})

        trigger_taken = {'triggered': 0}
        trigger_not_taken = {'triggered': 0}

        def callback_is_sent(sender, **kwargs):
            if kwargs['event'] == WalkoffEvent.TriggerActionTaken:
                trigger_taken['triggered'] += 1
            elif kwargs['event'] == WalkoffEvent.TriggerActionNotTaken:
                action.send_data_to_trigger({"data_in": {"data": 'aaa'}})
                trigger_not_taken['triggered'] += 1

        WalkoffEvent.CommonWorkflowSignal.connect(callback_is_sent)

        action.execute(instance.instance, {})
        self.assertEqual(trigger_taken['triggered'], 1)
        self.assertEqual(trigger_not_taken['triggered'], 1)
Exemple #21
0
 def test_execute_generates_uid(self):
     action = Action(app_name='HelloWorld', action_name='helloWorld')
     original_execution_uid = action.get_execution_uid()
     instance = AppInstance.create(app_name='HelloWorld',
                                   device_name='device1')
     action.execute(instance.instance, {})
     self.assertNotEqual(action.get_execution_uid(), original_execution_uid)
Exemple #22
0
 def test_init_with_flags(self):
     triggers = [
         Condition('HelloWorld',
                   action_name='regMatch',
                   arguments=[Argument('regex', value='(.*)')]),
         Condition('HelloWorld',
                   action_name='regMatch',
                   arguments=[Argument('regex', value='a')])
     ]
     action = Action('HelloWorld', 'helloWorld', triggers=triggers)
     self.__compare_init(action,
                         '',
                         'helloWorld',
                         'HelloWorld',
                         triggers=['regMatch', 'regMatch'])
Exemple #23
0
    def test_set_args_valid(self):
        action = Action(app_name='HelloWorld',
                        action_name='Add Three',
                        arguments=[
                            Argument('num1', value='-5.6'),
                            Argument('num2', value='4.3'),
                            Argument('num3', value='10.2')
                        ])
        arguments = [
            Argument('num1', value='-5.62'),
            Argument('num2', value='5'),
            Argument('num3', value='42.42')
        ]
        action.set_arguments(arguments)

        arguments = {
            'num1': Argument('num1', value='-5.62'),
            'num2': Argument('num2', value='5'),
            'num3': Argument('num3', value='42.42')
        }
        self.assertEqual(len(action.arguments), len(arguments))
        for arg_name, arg in action.arguments.items():
            self.assertIn(arg_name, arguments)
            self.assertEqual(arg, arguments[arg_name])
Exemple #24
0
 def test_init_with_position(self):
     action = Action('HelloWorld',
                     'helloWorld',
                     position={
                         'x': 13,
                         'y': 42
                     })
     self.__compare_init(action,
                         '',
                         'helloWorld',
                         'HelloWorld',
                         position={
                             'x': 13,
                             'y': 42
                         })
Exemple #25
0
    def test_execute_action_which_raises_exception_sends_callbacks(self):
        action = Action(app_name='HelloWorld', action_name='Buggy')
        instance = AppInstance.create(app_name='HelloWorld',
                                      device_name='device1')

        result = {'started_triggered': False, 'result_triggered': False}

        def callback_is_sent(sender, **kwargs):
            if isinstance(sender, Action):
                self.assertIn('event', kwargs)
                self.assertIn(kwargs['event'],
                              (WalkoffEvent.ActionStarted,
                               WalkoffEvent.ActionExecutionError))
                if kwargs['event'] == WalkoffEvent.ActionStarted:
                    result['started_triggered'] = True
                elif kwargs['event'] == WalkoffEvent.ActionExecutionError:
                    result['result_triggered'] = True

        WalkoffEvent.CommonWorkflowSignal.connect(callback_is_sent)

        action.execute(instance.instance, {})

        self.assertTrue(result['started_triggered'])
        self.assertTrue(result['result_triggered'])
Exemple #26
0
    def test_save_workflow_invalid_app_reload_actions(self):
        initial_workflow = flask_server.running_context.controller.get_workflow(
            'test', 'helloWorldWorkflow')
        workflow_name = initial_workflow.name
        initial_actions = [
            action.read() for action in initial_workflow.actions.values()
        ]
        actions_unmod = deepcopy(initial_actions)
        initial_actions[0]['position']['x'] = 0.0
        initial_actions[0]['position']['y'] = 0.0
        added_action = Action(name='new_id',
                              app_name='HelloWorld',
                              action_name='pause',
                              arguments=[Argument("seconds", value=5)],
                              position={
                                  'x': 0,
                                  'y': 0
                              }).read()
        added_action['app_name'] = 'Invalid'

        initial_actions.append(added_action)
        data = {"actions": initial_actions}
        self.post_with_status_check(
            '/api/playbooks/test/workflows/{0}/save'.format(workflow_name),
            data=json.dumps(data),
            headers=self.headers,
            content_type='application/json',
            status_code=INVALID_INPUT_ERROR)

        workflow = flask_server.running_context.controller.get_workflow(
            'test', 'helloWorldWorkflow')
        new_actions = [action.read() for action in workflow.actions.values()]
        for action in actions_unmod:
            action.pop('position')
        for action in new_actions:
            action.pop('position')
            action.pop('event')
        self.assertListEqual(actions_unmod, new_actions)
Exemple #27
0
    def test_execute_with_triggers(self):
        triggers = [
            Condition('HelloWorld',
                      action_name='regMatch',
                      arguments=[Argument('regex', value='aaa')])
        ]
        action = Action(app_name='HelloWorld',
                        action_name='helloWorld',
                        triggers=triggers)
        instance = AppInstance.create(app_name='HelloWorld',
                                      device_name='device1')
        action.send_data_to_trigger({"data_in": {"data": 'aaa'}})

        result = {'triggered': False}

        def callback_is_sent(sender, **kwargs):
            if kwargs['event'] == WalkoffEvent.TriggerActionTaken:
                result['triggered'] = True

        WalkoffEvent.CommonWorkflowSignal.connect(callback_is_sent)
        action.execute(instance.instance, {})
        self.assertTrue(result['triggered'])
Exemple #28
0
 def test_init_with_name(self):
     action = Action('HelloWorld', 'helloWorld', name='test')
     self.__compare_init(action, 'test', 'helloWorld', 'HelloWorld')
Exemple #29
0
    def test_save_workflow(self):
        initial_workflow = flask_server.running_context.controller.get_workflow(
            'test', 'helloWorldWorkflow')
        workflow_name = initial_workflow.name
        initial_actions = [
            action.read() for action in initial_workflow.actions.values()
        ]
        initial_actions[0]['position']['x'] = 0.0
        initial_actions[0]['position']['y'] = 0.0
        added_action = Action('HelloWorld',
                              'pause',
                              name='new_id',
                              arguments=[Argument("seconds", value=5)],
                              position={
                                  'x': 0,
                                  'y': 0
                              },
                              uid="2").read()

        initial_actions.append(added_action)

        action_uid = "e1db14e0cc8d4179aff5f1080a2b7e91"
        added_branch = Branch(source_uid=action_uid,
                              destination_uid="2").read()

        data = {"actions": initial_actions, "branches": [added_branch]}
        self.post_with_status_check(
            '/api/playbooks/test/workflows/{0}/save'.format(workflow_name),
            data=json.dumps(data),
            headers=self.headers,
            content_type='application/json')

        resulting_workflow = flask_server.running_context.controller.get_workflow(
            'test', workflow_name)
        # compare the actions in initial and final workflow
        self.assertEqual(len(resulting_workflow.actions.keys()),
                         len(list(initial_actions)))
        for initial_action in initial_actions:
            self.assertIn(initial_action['uid'],
                          resulting_workflow.actions.keys())
            self.assertDictEqual(
                initial_action,
                resulting_workflow.actions[initial_action['uid']].read())

        self.assertEqual(added_branch["source_uid"],
                         resulting_workflow.branches[action_uid][0].source_uid)
        self.assertEqual(
            added_branch["destination_uid"],
            resulting_workflow.branches[action_uid][0].destination_uid)

        # assert that the file has been saved to a file
        workflows = [
            path.splitext(workflow)[0]
            for workflow in os.listdir(core.config.paths.workflows_path)
            if workflow.endswith('.playbook')
        ]
        matching_workflows = [
            workflow for workflow in workflows if workflow == 'test'
        ]
        self.assertEqual(len(matching_workflows), 1)

        # assert that the file loads properly after being saved
        flask_server.running_context.controller.workflows = {}
        flask_server.running_context.controller.load_playbook(
            os.path.join(core.config.paths.workflows_path, 'test.playbook'))
        loaded_workflow = flask_server.running_context.controller.get_workflow(
            'test', workflow_name)
        # compare the actions in loaded and expected workflow
        self.assertEqual(len(loaded_workflow.actions.keys()),
                         len(list(resulting_workflow.actions.keys())))

        def remove_uids(action):
            action.uid = ''

        for action_name, loaded_action in loaded_workflow.actions.items():
            self.assertIn(action_name, resulting_workflow.actions.keys())
            remove_uids(loaded_action)
            remove_uids(resulting_workflow.actions[action_name])
            self.assertDictEqual(
                loaded_action.read(),
                resulting_workflow.actions[action_name].read())
Exemple #30
0
 def test_init_with_uid(self):
     action = Action('HelloWorld', 'helloWorld', uid='test')
     self.__compare_init(action, '', 'helloWorld', 'HelloWorld', uid='test')