def test_composite_command_error2(self):
        mocked_imp_succ = mock.Mock()
        mocked_imp_error = mock.Mock()

        start_time = get_now()
        end_time = get_now() + datetime.timedelta(5 / (24 * 60 * 60))

        mocked_imp_succ.execute.return_value = StepExecution(
            success=True,
            stdout='stdout',
            stderr='stderr',
            rc=0,
            start_time=start_time,
            end_time=end_time)
        mocked_imp_error.execute.return_value = StepExecution(
            success=False,
            stdout='stdout',
            stderr='stderr',
            rc=0,
            start_time=start_time,
            end_time=end_time)

        uc1 = UndoCommand(implementation=mocked_imp_succ, id_=1)
        uc2 = UndoCommand(implementation=mocked_imp_succ, id_=2)
        uc3 = UndoCommand(implementation=mocked_imp_succ, id_=3)
        uc4 = UndoCommand(implementation=mocked_imp_succ, id_=4)
        uc5 = UndoCommand(implementation=mocked_imp_succ, id_=5)

        ccu1 = CompositeCommand({uc1: []}, async_operator=self.ao)
        ccu2 = CompositeCommand({
            uc2: [uc3],
            uc3: [uc4]
        },
                                async_operator=self.ao)

        c1 = Command(implementation=mocked_imp_succ,
                     undo_implementation=ccu1,
                     id_=6)
        c2 = Command(implementation=mocked_imp_error,
                     undo_implementation=ccu2,
                     id_=7)
        c3 = Command(implementation=mocked_imp_succ,
                     undo_implementation=uc5,
                     id_=8)

        cc = CompositeCommand({c1: [c2], c2: [c3]}, async_operator=self.ao)

        res = cc.invoke()

        self.assertEqual(False, res)
        self.assertEqual(1, mocked_imp_succ.execute.call_count)
        self.assertEqual(1, mocked_imp_error.execute.call_count)

        res = cc.undo()

        self.assertEqual(True, res)
        self.assertEqual(2, mocked_imp_succ.execute.call_count)
        self.assertEqual(1, mocked_imp_error.execute.call_count)
    def test_composite_command_success(self):
        uc1 = UndoCommand(implementation=self.mocked_imp_succ,
                          var_context=self.mock_context,
                          id_=1)
        uc2 = UndoCommand(implementation=self.mocked_imp_succ,
                          var_context=self.mock_context,
                          id_=2)
        uc3 = UndoCommand(implementation=self.mocked_imp_succ,
                          var_context=self.mock_context,
                          id_=3)
        uc4 = UndoCommand(implementation=self.mocked_imp_succ,
                          var_context=self.mock_context,
                          id_=4)

        ccu1 = CompositeCommand({uc1: []}, stop_on_error=True)
        ccu2 = CompositeCommand({uc2: [uc3], uc3: [uc4]}, stop_on_error=True)

        c1 = Command(implementation=self.mocked_imp_succ,
                     var_context=self.mock_context,
                     undo_command=ccu1,
                     id_=5)
        c2 = Command(implementation=self.mocked_imp_succ,
                     var_context=self.mock_context,
                     undo_command=ccu2,
                     id_=6)

        cc = CompositeCommand({
            c1: [c2],
            c2: []
        },
                              stop_on_error=False,
                              stop_undo_on_error=False)

        res = cc.invoke()

        self.assertDictEqual(
            {
                5:
                CompletedProcess(success=True,
                                 stdout='stdout',
                                 stderr='stderr',
                                 rc=0,
                                 start_time=START,
                                 end_time=END),
                6:
                CompletedProcess(success=True,
                                 stdout='stdout',
                                 stderr='stderr',
                                 rc=0,
                                 start_time=START,
                                 end_time=END)
            }, cc.result)
        self.assertEqual(True, res)
        self.assertEqual(2, self.mocked_imp_succ.execute.call_count)
        self.assertEqual(0, self.mocked_imp_error.execute.call_count)
    def test_undo_on_error(self):
        mocked_imp_succ = mock.Mock()
        mocked_imp_error = mock.Mock()

        mocked_imp_succ.execute.return_value = StepExecution(
            success=True,
            stdout='stdout',
            stderr='stderr',
            rc=0,
            start_time=get_now(),
            end_time=get_now() + datetime.timedelta(5 / (24 * 60 * 60)))

        mocked_imp_error.execute.return_value = StepExecution(
            success=False,
            stdout='stdout',
            stderr='stderr',
            rc=0,
            start_time=get_now(),
            end_time=get_now() + datetime.timedelta(5 / (24 * 60 * 60)))

        uc1 = UndoCommand(implementation=mocked_imp_succ, id_=1)
        uc2 = UndoCommand(implementation=mocked_imp_error, id_=2)
        uc3 = UndoCommand(implementation=mocked_imp_succ, id_=3)

        c1 = Command(implementation=mocked_imp_succ,
                     undo_implementation=uc1,
                     id_=1)
        c2 = Command(implementation=mocked_imp_succ,
                     undo_implementation=uc2,
                     id_=2)
        c3 = Command(implementation=mocked_imp_error,
                     undo_implementation=uc3,
                     undo_on_error=True,
                     id_=3)

        cc1 = CompositeCommand({
            c1: [c2],
            c2: [c3]
        },
                               force_all=True,
                               id_=1,
                               async_operator=self.ao)

        res = cc1.invoke()

        self.assertFalse(res)

        res = cc1.undo()

        self.assertEqual(3, mocked_imp_succ.execute.call_count)
        self.assertEqual(2, mocked_imp_error.execute.call_count)
        self.assertFalse(res)
    def test_command_post_process(self):
        cp = CompletedProcess(success=True,
                              stdout='{"output": "this is a message"}',
                              stderr='',
                              rc=0,
                              start_time=datetime(2019, 4, 1))
        self.mock_implementation.execute.return_value = cp
        c = Command(implementation=self.mock_implementation,
                    var_context=self.mock_context,
                    undo_on_error=False,
                    post_process=
                    "import json\nvc.set('response', json.loads(cp.stdout))",
                    id_=1)

        c.invoke()
        self.mock_context.set.assert_called_once_with(
            'response', {"output": "this is a message"})

        c = Command(implementation=self.mock_implementation,
                    var_context=self.mock_context,
                    undo_on_error=False,
                    post_process="raise RuntimeError()",
                    id_=1)

        c.invoke()
        self.assertIn("Post-Process error", cp.stderr)
        self.assertIn("RuntimeError", cp.stderr)
        self.assertFalse(cp.success)
    def test_undo_command_invoke_not_executed(self):
        with mock.patch('dimensigon.use_cases.deployment.Command.success',
                        new_callable=mock.PropertyMock) as mock_success:
            mock_success.return_value = None
            type(self.mock_undo_command).success = mock.PropertyMock(
                return_value=None)
            self.mock_undo_command.invoke.return_value = True

            c = Command(implementation=self.mock_implementation,
                        undo_command=self.mock_undo_command,
                        var_context=self.mock_context,
                        undo_on_error=False,
                        id_=1)
            r = c.undo()
            self.mock_undo_command.invoke.assert_not_called()
            self.assertIsNone(r)
    def test_invoke(self):
        with mock.patch('dimensigon.use_cases.deployment.Command.success',
                        new_callable=mock.PropertyMock) as mock_success:
            mock_success.return_value = True

            c = Command(implementation=self.mock_implementation,
                        undo_command=self.mock_undo_command,
                        var_context=self.mock_context,
                        undo_on_error=False,
                        id_=1)
            r = c.invoke()
            # call a second time to see if only one time is called
            r = c.invoke()
            self.mock_implementation.execute.assert_called_once_with(
                self.params, context=self.mock_context, timeout=None)
            self.assertTrue(r)
    def test_result(self):
        type(self.mock_undo_command).success = mock.PropertyMock(
            return_value=True)
        self.mock_undo_command.invoke.return_value = True
        self.mock_undo_command._id.return_value = 2
        type(self.mock_undo_command).result = mock.PropertyMock(
            return_value={2: {
                'a': 2
            }})

        c = Command(implementation=self.mock_implementation,
                    undo_command=self.mock_undo_command,
                    var_context=self.mock_context,
                    undo_on_error=False,
                    id_=1)
        c._cp = {'success': True}
        self.assertDictEqual({1: {'success': True}, 2: {'a': 2}}, c.result)
    def test_command_no_undo(self):
        cp = CompletedProcess(success=True,
                              stdout='output: var',
                              stderr='',
                              rc=0,
                              start_time=datetime(2019, 4, 1))
        self.mock_implementation.execute.return_value = cp
        c = Command(implementation=self.mock_implementation,
                    var_context=self.mock_context,
                    undo_on_error=False,
                    id_=1)

        r = c.invoke()
        self.assertTrue(r)
        r = c.undo()
        self.assertTrue(r)
        self.assertDictEqual({1: cp}, c.result)
    def test_command_register(self):
        cp = CompletedProcess(success=True,
                              stdout='{"output": "this is a message"}',
                              stderr='',
                              rc=0,
                              start_time=datetime(2019, 4, 1))
        self.mock_implementation.execute.return_value = cp
        mock_register = mock.Mock()
        c = Command(implementation=self.mock_implementation,
                    var_context=self.mock_context,
                    register=mock_register,
                    undo_on_error=False,
                    post_process="",
                    id_=1)

        c.invoke()

        mock_register.save_step_execution.assert_called_once()
    def test_invoke_undo__step_undo_on_error_false(self):
        uc1 = UndoCommand(implementation=self.mocked_imp_succ,
                          var_context=self.mock_context,
                          id_=1)
        uc2 = UndoCommand(implementation=self.mocked_imp_error,
                          var_context=self.mock_context,
                          id_=2)
        uc3 = UndoCommand(implementation=self.mocked_imp_succ,
                          var_context=self.mock_context,
                          id_=3)

        c1 = Command(implementation=self.mocked_imp_succ,
                     var_context=self.mock_context,
                     undo_command=uc1,
                     id_=1)
        c2 = Command(implementation=self.mocked_imp_error,
                     var_context=self.mock_context,
                     undo_command=uc2,
                     undo_on_error=False,
                     id_=2)
        c3 = Command(implementation=self.mocked_imp_succ,
                     var_context=self.mock_context,
                     undo_command=uc3,
                     id_=3)

        cc1 = CompositeCommand({
            c1: [c2],
            c2: [c3]
        },
                               stop_on_error=True,
                               stop_undo_on_error=False,
                               id_=1)

        res = cc1.invoke()

        self.assertEqual(1, self.mocked_imp_succ.execute.call_count)
        self.assertEqual(1, self.mocked_imp_error.execute.call_count)
        self.assertFalse(res)

        res = cc1.undo()

        self.assertEqual(2, self.mocked_imp_succ.execute.call_count)
        self.assertEqual(1, self.mocked_imp_error.execute.call_count)
        self.assertTrue(res)
    def test_composite_command_success(self):
        mocked_imp_succ = mock.Mock()
        mocked_imp_error = mock.Mock()

        start_time = get_now()
        end_time = get_now() + datetime.timedelta(5 / (24 * 60 * 60))

        mocked_imp_succ.execute.return_value = StepExecution(
            success=True,
            stdout='stdout',
            stderr='stderr',
            rc=0,
            start_time=start_time,
            end_time=end_time)
        mocked_imp_error.execute.return_value = StepExecution(
            success=False,
            stdout='stdout',
            stderr='stderr',
            rc=0,
            start_time=start_time,
            end_time=end_time)

        uc1 = UndoCommand(implementation=mocked_imp_succ, id_=1)
        uc2 = UndoCommand(implementation=mocked_imp_succ, id_=2)
        uc3 = UndoCommand(implementation=mocked_imp_succ, id_=3)
        uc4 = UndoCommand(implementation=mocked_imp_succ, id_=4)

        c1 = Command(implementation=mocked_imp_succ,
                     undo_implementation=uc1,
                     id_=5)
        c2 = Command(implementation=mocked_imp_succ,
                     undo_implementation=uc2,
                     id_=6)
        c3 = Command(implementation=mocked_imp_error,
                     undo_implementation=uc3,
                     id_=7)
        c4 = Command(implementation=mocked_imp_succ,
                     undo_implementation=uc4,
                     id_=8)

        cc = CompositeCommand({c1: [c2, c3, c4]}, async_operator=self.ao)

        res = cc.invoke()

        self.assertDictEqual(
            {
                5:
                StepExecution(success=True,
                              stdout='stdout',
                              stderr='stderr',
                              rc=0,
                              start_time=start_time,
                              end_time=end_time),
                6:
                StepExecution(success=True,
                              stdout='stdout',
                              stderr='stderr',
                              rc=0,
                              start_time=start_time,
                              end_time=end_time),
                7:
                StepExecution(success=False,
                              stdout='stdout',
                              stderr='stderr',
                              rc=0,
                              start_time=start_time,
                              end_time=end_time),
                8:
                StepExecution(success=True,
                              stdout='stdout',
                              stderr='stderr',
                              rc=0,
                              start_time=start_time,
                              end_time=end_time),
            }, cc.execution)
        self.assertEqual(False, res)
        self.assertEqual(3, mocked_imp_succ.execute.call_count)
        self.assertEqual(1, mocked_imp_error.execute.call_count)
    def test_composite_command_error(self):
        uc1 = UndoCommand(implementation=self.mocked_imp_succ,
                          var_context=self.mock_context,
                          id_=1)
        uc2 = UndoCommand(implementation=self.mocked_imp_succ,
                          var_context=self.mock_context,
                          id_=2)
        uc3 = UndoCommand(implementation=self.mocked_imp_error,
                          var_context=self.mock_context,
                          id_=3)
        uc4 = UndoCommand(implementation=self.mocked_imp_succ,
                          var_context=self.mock_context,
                          id_=4)
        uc5 = UndoCommand(implementation=self.mocked_imp_succ,
                          var_context=self.mock_context,
                          id_=5)

        executor = ThreadPoolExecutor()
        ccu1 = CompositeCommand({uc1: []}, stop_on_error=True)
        ccu2 = CompositeCommand({uc2: [uc3, uc4]},
                                stop_on_error=True,
                                executor=executor)

        c6 = Command(implementation=self.mocked_imp_succ,
                     var_context=self.mock_context,
                     undo_command=ccu1,
                     id_=6)
        c7 = Command(implementation=self.mocked_imp_succ,
                     var_context=self.mock_context,
                     undo_command=ccu2,
                     id_=7)
        c8 = Command(implementation=self.mocked_imp_succ,
                     var_context=self.mock_context,
                     undo_command=uc5,
                     id_=8)

        cc = CompositeCommand({
            c6: [c7],
            c7: [c8]
        },
                              stop_on_error=False,
                              stop_undo_on_error=False,
                              executor=executor)

        res = cc.invoke()

        self.assertTrue(res)
        self.assertEqual(3, self.mocked_imp_succ.execute.call_count)
        self.assertEqual(0, self.mocked_imp_error.execute.call_count)

        res = cc.undo()

        self.assertFalse(res)
        self.assertEqual(7, self.mocked_imp_succ.execute.call_count)
        self.assertEqual(1, self.mocked_imp_error.execute.call_count)

        self.assertDictEqual(
            {
                1:
                CompletedProcess(success=True,
                                 stdout='stdout',
                                 stderr='stderr',
                                 rc=0,
                                 start_time=START,
                                 end_time=END),
                2:
                CompletedProcess(success=True,
                                 stdout='stdout',
                                 stderr='stderr',
                                 rc=0,
                                 start_time=START,
                                 end_time=END),
                3:
                CompletedProcess(success=False,
                                 stdout='stdout',
                                 stderr='stderr',
                                 rc=0,
                                 start_time=START,
                                 end_time=END),
                4:
                CompletedProcess(success=True,
                                 stdout='stdout',
                                 stderr='stderr',
                                 rc=0,
                                 start_time=START,
                                 end_time=END),
                5:
                CompletedProcess(success=True,
                                 stdout='stdout',
                                 stderr='stderr',
                                 rc=0,
                                 start_time=START,
                                 end_time=END),
                6:
                CompletedProcess(success=True,
                                 stdout='stdout',
                                 stderr='stderr',
                                 rc=0,
                                 start_time=START,
                                 end_time=END),
                7:
                CompletedProcess(success=True,
                                 stdout='stdout',
                                 stderr='stderr',
                                 rc=0,
                                 start_time=START,
                                 end_time=END),
                8:
                CompletedProcess(success=True,
                                 stdout='stdout',
                                 stderr='stderr',
                                 rc=0,
                                 start_time=START,
                                 end_time=END)
            }, cc.result)