def setUp(self):
        def side_effect(trigger, payload, trace_context):
            self._dispatched_count += 1

        self.sensor_service = SensorService(mock.MagicMock())
        self.sensor_service._dispatcher = mock.Mock()
        self.sensor_service._dispatcher.dispatch = mock.MagicMock(
            side_effect=side_effect)
        self._dispatched_count = 0

        # reset default configuration value
        cfg.CONF.system.validate_trigger_payload = False
Exemple #2
0
    def setUp(self):
        super(SensorServiceTestCase, self).setUp()

        file_path = os.path.join(RESOURCES_DIR, 'test_sensor.py')
        trigger_types = ['trigger1', 'trigger2']
        parent_args = ['--config-file', TESTS_CONFIG_PATH]
        wrapper = SensorWrapper(pack='core',
                                file_path=file_path,
                                class_name='TestSensor',
                                trigger_types=trigger_types,
                                parent_args=parent_args)
        self._sensor_service = SensorService(sensor_wrapper=wrapper)
        self._sensor_service._get_api_client = mock.Mock()
    def setUp(self):
        def side_effect(trigger, payload, trace_context):
            self._dispatched_count += 1

        self.sensor_service = SensorService(mock.MagicMock())
        self.sensor_service._dispatcher = mock.Mock()
        self.sensor_service._dispatcher.dispatch = mock.MagicMock(side_effect=side_effect)
        self._dispatched_count = 0

        # Previously, cfg.CONF.system.validate_trigger_payload was set to False explicitly
        # here. Instead, we store original value so that the default is used, and if unit
        # test modifies this, we can set it to what it was (preserve test atomicity)
        self.validate_trigger_payload = cfg.CONF.system.validate_trigger_payload
    def setUp(self):
        super(SensorServiceTestCase, self).setUp()

        file_path = os.path.join(RESOURCES_DIR, 'test_sensor.py')
        trigger_types = ['trigger1', 'trigger2']
        parent_args = ['--config-file', TESTS_CONFIG_PATH]
        wrapper = SensorWrapper(pack='core', file_path=file_path,
                                class_name='TestSensor',
                                trigger_types=trigger_types,
                                parent_args=parent_args)
        self._sensor_service = SensorService(sensor_wrapper=wrapper)
        self._sensor_service._get_api_client = mock.Mock()
    def setUp(self):
        super(SensorServiceTestCase, self).setUp()

        file_path = os.path.join(RESOURCES_DIR, "test_sensor.py")
        trigger_types = ["trigger1", "trigger2"]
        parent_args = ["--config-file", TESTS_CONFIG_PATH]
        wrapper = SensorWrapper(
            pack="core",
            file_path=file_path,
            class_name="TestSensor",
            trigger_types=trigger_types,
            parent_args=parent_args,
        )
        self._sensor_service = SensorService(sensor_wrapper=wrapper)
        self._sensor_service._get_api_client = mock.Mock()
class SensorServiceTestCase(unittest2.TestCase):
    def setUp(self):
        def side_effect(trigger, payload, trace_context):
            self._dispatched_count += 1

        self.sensor_service = SensorService(mock.MagicMock())
        self.sensor_service._dispatcher = mock.Mock()
        self.sensor_service._dispatcher.dispatch = mock.MagicMock(
            side_effect=side_effect)
        self._dispatched_count = 0

        # Previously, cfg.CONF.system.validate_trigger_payload was set to False explicitly
        # here. Instead, we store original value so that the default is used, and if unit
        # test modifies this, we can set it to what it was (preserve test atomicity)
        self.validate_trigger_payload = cfg.CONF.system.validate_trigger_payload

    def tearDown(self):
        # Replace original configured value for payload validation
        cfg.CONF.system.validate_trigger_payload = self.validate_trigger_payload

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeMock(TEST_SCHEMA)))
    def test_dispatch_success(self):
        # define a valid payload
        payload = {
            'name': 'John Doe',
            'age': 25,
            'career': ['foo, Inc.', 'bar, Inc.'],
            'married': True,
            'awards': {
                '2016': ['hoge prize', 'fuga prize']
            },
            'income': 50000,
            'country': 'US',
        }

        # dispatching a trigger
        self.sensor_service.dispatch('trigger-name', payload)

        # This assumed that the target tirgger dispatched
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeMock(TEST_SCHEMA)))
    def test_dispatch_success_with_default_config_and_invalid_payload(self):
        """Tests that an invalid payload still results in dispatch success with default config

        The previous config defition used StrOpt instead of BoolOpt for
        cfg.CONF.system.validate_trigger_payload. This meant that even though the intention
        was to bypass validation, the fact that this option was a string, meant it always
        resulted in True during conditionals.the

        However, the other unit tests directly modified
        cfg.CONF.system.validate_trigger_payload before running, which
        obscured this bug during testing.

        This test (as well as resetting cfg.CONF.system.validate_trigger_payload
        to it's original value during tearDown) will test validation does
        NOT take place with the default configuration.
        """

        # define a invalid payload (the type of 'age' is incorrect)
        payload = {
            'name': 'John Doe',
            'age': '25',
        }

        self.sensor_service.dispatch('trigger-name', payload)

        # The default config is to disable validation. So, we want to make sure
        # the dispatch actually went through.
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeMock(TEST_SCHEMA)))
    def test_dispatch_failure_caused_by_incorrect_type(self):
        # define a invalid payload (the type of 'age' is incorrect)
        payload = {
            'name': 'John Doe',
            'age': '25',
        }

        # set config to stop dispatching when the payload comply with target trigger_type
        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('trigger-name', payload)

        # This assumed that the target trigger isn't dispatched
        self.assertEqual(self._dispatched_count, 0)

        # reset config to permit force dispatching
        cfg.CONF.system.validate_trigger_payload = False

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeMock(TEST_SCHEMA)))
    def test_dispatch_failure_caused_by_lack_of_required_parameter(self):
        # define a invalid payload (lack of required property)
        payload = {
            'age': 25,
        }
        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 0)

        # reset config to permit force dispatching
        cfg.CONF.system.validate_trigger_payload = False

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeMock(TEST_SCHEMA)))
    def test_dispatch_failure_caused_by_extra_parameter(self):
        # define a invalid payload ('hobby' is extra)
        payload = {
            'name': 'John Doe',
            'hobby': 'programming',
        }
        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 0)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeMock(TEST_SCHEMA)))
    def test_dispatch_success_with_multiple_type_value(self):
        payload = {
            'name': 'John Doe',
            'income': 1234,
        }

        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('trigger-name', payload)

        # reset payload which can have different type
        payload['income'] = 'secret'

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 2)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeMock(TEST_SCHEMA)))
    def test_dispatch_success_with_null(self):
        payload = {
            'name': 'John Doe',
            'age': None,
        }

        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeMock()))
    def test_dispatch_success_without_payload_schema(self):
        # the case trigger has no property
        self.sensor_service.dispatch('trigger-name', {})
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=None))
    def test_dispatch_success_without_trigger_type(self):
        self.sensor_service.dispatch('trigger-name', {})
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=None))
    def test_dispatch_trigger__type_not_in_db_should_still_dispatch(self):
        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('not-in-database-ref', {})
        self.assertEqual(self._dispatched_count, 1)
Exemple #7
0
class SensorServiceTestCase(unittest2.TestCase):
    def setUp(self):
        def side_effect(trigger, payload, trace_context):
            self._dispatched_count += 1

        self.sensor_service = SensorService(mock.MagicMock())
        self.sensor_service._trigger_dispatcher_service._dispatcher = mock.Mock()
        self.sensor_service._trigger_dispatcher_service._dispatcher.dispatch = \
            mock.MagicMock(side_effect=side_effect)
        self._dispatched_count = 0

        # Previously, cfg.CONF.system.validate_trigger_payload was set to False explicitly
        # here. Instead, we store original value so that the default is used, and if unit
        # test modifies this, we can set it to what it was (preserve test atomicity)
        self.validate_trigger_payload = cfg.CONF.system.validate_trigger_payload

    def tearDown(self):
        # Replace original configured value for payload validation
        cfg.CONF.system.validate_trigger_payload = self.validate_trigger_payload

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeDBMock(TEST_SCHEMA)))
    def test_dispatch_success_valid_payload_validation_enabled(self):
        cfg.CONF.system.validate_trigger_payload = True

        # define a valid payload
        payload = {
            'name': 'John Doe',
            'age': 25,
            'career': ['foo, Inc.', 'bar, Inc.'],
            'married': True,
            'awards': {'2016': ['hoge prize', 'fuga prize']},
            'income': 50000
        }

        # dispatching a trigger
        self.sensor_service.dispatch('trigger-name', payload)

        # This assumed that the target tirgger dispatched
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeDBMock(TEST_SCHEMA)))
    @mock.patch('st2common.services.triggers.get_trigger_db_by_ref',
                mock.MagicMock(return_value=TriggerDBMock(type='trigger-type-ref')))
    def test_dispatch_success_with_validation_enabled_trigger_reference(self):
        # Test a scenario where a Trigger ref and not TriggerType ref is provided
        cfg.CONF.system.validate_trigger_payload = True

        # define a valid payload
        payload = {
            'name': 'John Doe',
            'age': 25,
            'career': ['foo, Inc.', 'bar, Inc.'],
            'married': True,
            'awards': {'2016': ['hoge prize', 'fuga prize']},
            'income': 50000
        }

        self.assertEqual(self._dispatched_count, 0)

        # dispatching a trigger
        self.sensor_service.dispatch('pack.86582f21-1fbc-44ea-88cb-0cd2b610e93b', payload)

        # This assumed that the target tirgger dispatched
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeDBMock(TEST_SCHEMA)))
    def test_dispatch_success_with_validation_disabled_and_invalid_payload(self):
        """
        Tests that an invalid payload still results in dispatch success with default config

        The previous config defition used StrOpt instead of BoolOpt for
        cfg.CONF.system.validate_trigger_payload. This meant that even though the intention
        was to bypass validation, the fact that this option was a string, meant it always
        resulted in True during conditionals.the

        However, the other unit tests directly modified
        cfg.CONF.system.validate_trigger_payload before running, which
        obscured this bug during testing.

        This test (as well as resetting cfg.CONF.system.validate_trigger_payload
        to it's original value during tearDown) will test validation does
        NOT take place with the default configuration.
        """
        cfg.CONF.system.validate_trigger_payload = False

        # define a invalid payload (the type of 'age' is incorrect)
        payload = {
            'name': 'John Doe',
            'age': '25',
        }

        self.sensor_service.dispatch('trigger-name', payload)

        # The default config is to disable validation. So, we want to make sure
        # the dispatch actually went through.
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeDBMock(TEST_SCHEMA)))
    def test_dispatch_failure_caused_by_incorrect_type(self):
        # define a invalid payload (the type of 'age' is incorrect)
        payload = {
            'name': 'John Doe',
            'age': '25',
        }

        # set config to stop dispatching when the payload comply with target trigger_type
        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('trigger-name', payload)

        # This assumed that the target trigger isn't dispatched
        self.assertEqual(self._dispatched_count, 0)

        # reset config to permit force dispatching
        cfg.CONF.system.validate_trigger_payload = False

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeDBMock(TEST_SCHEMA)))
    def test_dispatch_failure_caused_by_lack_of_required_parameter(self):
        # define a invalid payload (lack of required property)
        payload = {
            'age': 25,
        }
        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 0)

        # reset config to permit force dispatching
        cfg.CONF.system.validate_trigger_payload = False

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeDBMock(TEST_SCHEMA)))
    def test_dispatch_failure_caused_by_extra_parameter(self):
        # define a invalid payload ('hobby' is extra)
        payload = {
            'name': 'John Doe',
            'hobby': 'programming',
        }
        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 0)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeDBMock(TEST_SCHEMA)))
    def test_dispatch_success_with_multiple_type_value(self):
        payload = {
            'name': 'John Doe',
            'income': 1234,
        }

        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('trigger-name', payload)

        # reset payload which can have different type
        payload['income'] = 'secret'

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 2)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeDBMock(TEST_SCHEMA)))
    def test_dispatch_success_with_null(self):
        payload = {
            'name': 'John Doe',
            'age': None,
        }

        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeDBMock()))
    def test_dispatch_success_without_payload_schema(self):
        # the case trigger has no property
        self.sensor_service.dispatch('trigger-name', {})
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=None))
    def test_dispatch_trigger_type_not_in_db_should_not_dispatch(self):
        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('not-in-database-ref', {})
        self.assertEqual(self._dispatched_count, 0)

    def test_datastore_methods(self):
        self.sensor_service._datastore_service = mock.Mock()

        # Verify methods take encrypt, decrypt and scope arguments
        self.sensor_service.get_value(name='foo1', scope=SYSTEM_SCOPE, decrypt=True)

        call_kwargs = self.sensor_service.datastore_service.get_value.call_args[1]
        expected_kwargs = {
            'name': 'foo1',
            'local': True,
            'scope': SYSTEM_SCOPE,
            'decrypt': True
        }
        self.assertEqual(call_kwargs, expected_kwargs)

        self.sensor_service.set_value(name='foo2', value='bar', scope=USER_SCOPE, encrypt=True)

        call_kwargs = self.sensor_service.datastore_service.set_value.call_args[1]
        expected_kwargs = {
            'name': 'foo2',
            'value': 'bar',
            'ttl': None,
            'local': True,
            'scope': USER_SCOPE,
            'encrypt': True
        }
        self.assertEqual(call_kwargs, expected_kwargs)

        self.sensor_service.delete_value(name='foo3', scope=USER_SCOPE)

        call_kwargs = self.sensor_service.datastore_service.delete_value.call_args[1]
        expected_kwargs = {
            'name': 'foo3',
            'local': True,
            'scope': USER_SCOPE
        }
        self.assertEqual(call_kwargs, expected_kwargs)
class SensorServiceTestCase(unittest2.TestCase):
    @classmethod
    def setUpClass(cls):
        super(SensorServiceTestCase, cls).setUpClass()
        tests_config.parse_args()

    def setUp(self):
        super(SensorServiceTestCase, self).setUp()

        file_path = os.path.join(RESOURCES_DIR, "test_sensor.py")
        trigger_types = ["trigger1", "trigger2"]
        parent_args = ["--config-file", TESTS_CONFIG_PATH]
        wrapper = SensorWrapper(
            pack="core",
            file_path=file_path,
            class_name="TestSensor",
            trigger_types=trigger_types,
            parent_args=parent_args,
        )
        self._sensor_service = SensorService(sensor_wrapper=wrapper)
        self._sensor_service._get_api_client = mock.Mock()

    def test_datastore_operations_list_values(self):
        # Verify prefix filtering
        mock_api_client = mock.Mock()
        mock_api_client.keys.get_all.return_value = []
        self._set_mock_api_client(mock_api_client)

        self._sensor_service.list_values(local=True, prefix=None)
        mock_api_client.keys.get_all.assert_called_with(prefix="core.TestSensor:")
        self._sensor_service.list_values(local=True, prefix="ponies")
        mock_api_client.keys.get_all.assert_called_with(prefix="core.TestSensor:ponies")

        self._sensor_service.list_values(local=False, prefix=None)
        mock_api_client.keys.get_all.assert_called_with(prefix=None)
        self._sensor_service.list_values(local=False, prefix="ponies")
        mock_api_client.keys.get_all.assert_called_with(prefix="ponies")

        # No values in the datastore
        mock_api_client = mock.Mock()
        mock_api_client.keys.get_all.return_value = []
        self._set_mock_api_client(mock_api_client)

        values = self._sensor_service.list_values(local=True)
        self.assertEqual(values, [])
        values = self._sensor_service.list_values(local=False)
        self.assertEqual(values, [])

        # Values in the datastore
        kvp1 = KeyValuePair()
        kvp1.name = "test1"
        kvp1.value = "bar"
        kvp2 = KeyValuePair()
        kvp2.name = "test2"
        kvp2.value = "bar"
        mock_return_value = [kvp1, kvp2]
        mock_api_client.keys.get_all.return_value = mock_return_value
        self._set_mock_api_client(mock_api_client)

        values = self._sensor_service.list_values(local=True)
        self.assertEqual(len(values), 2)
        self.assertEqual(values, mock_return_value)

    def test_datastore_operations_get_value(self):
        mock_api_client = mock.Mock()
        kvp1 = KeyValuePair()
        kvp1.name = "test1"
        kvp1.value = "bar"
        mock_api_client.keys.get_by_id.return_value = kvp1
        self._set_mock_api_client(mock_api_client)

        value = self._sensor_service.get_value(name="test1", local=False)
        self.assertEqual(value, kvp1.value)

    def test_datastore_operations_set_value(self):
        mock_api_client = mock.Mock()
        mock_api_client.keys.update.return_value = True
        self._set_mock_api_client(mock_api_client)

        value = self._sensor_service.set_value(name="test1", value="foo", local=False)
        self.assertTrue(value)

    def test_datastore_operations_delete_value(self):
        mock_api_client = mock.Mock()
        mock_api_client.keys.delete.return_value = True
        self._set_mock_api_client(mock_api_client)

        value = self._sensor_service.delete_value(name="test", local=False)
        self.assertTrue(value)

    def _set_mock_api_client(self, mock_api_client):
        mock_method = mock.Mock()
        mock_method.return_value = mock_api_client
        self._sensor_service._get_api_client = mock_method
class SensorServiceTestCase(unittest2.TestCase):
    def setUp(self):
        def side_effect(trigger, payload, trace_context):
            self._dispatched_count += 1

        self.sensor_service = SensorService(mock.MagicMock())
        self.sensor_service._dispatcher = mock.Mock()
        self.sensor_service._dispatcher.dispatch = mock.MagicMock(
            side_effect=side_effect)
        self._dispatched_count = 0

        # reset default configuration value
        cfg.CONF.system.validate_trigger_payload = False

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeMock(TEST_SCHEMA)))
    def test_dispatch_success(self):
        # define a valid payload
        payload = {
            'name': 'John Doe',
            'age': 25,
            'career': ['foo, Inc.', 'bar, Inc.'],
            'married': True,
            'awards': {
                '2016': ['hoge prize', 'fuga prize']
            },
            'income': 50000,
            'country': 'US',
        }

        # dispatching a trigger
        self.sensor_service.dispatch('trigger-name', payload)

        # This assumed that the target tirgger dispatched
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeMock(TEST_SCHEMA)))
    def test_dispatch_failure_caused_by_incorrect_type(self):
        # define a invalid payload (the type of 'age' is incorrect)
        payload = {
            'name': 'John Doe',
            'age': '25',
        }

        # set config to stop dispatching when the payload comply with target trigger_type
        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('trigger-name', payload)

        # This assumed that the target trigger isn't dispatched
        self.assertEqual(self._dispatched_count, 0)

        # reset config to permit force dispatching
        cfg.CONF.system.validate_trigger_payload = False

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeMock(TEST_SCHEMA)))
    def test_dispatch_failure_caused_by_lack_of_required_parameter(self):
        # define a invalid payload (lack of required property)
        payload = {
            'age': 25,
        }
        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 0)

        # reset config to permit force dispatching
        cfg.CONF.system.validate_trigger_payload = False

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeMock(TEST_SCHEMA)))
    def test_dispatch_failure_caused_by_extra_parameter(self):
        # define a invalid payload ('hobby' is extra)
        payload = {
            'name': 'John Doe',
            'hobby': 'programming',
        }
        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 0)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeMock(TEST_SCHEMA)))
    def test_dispatch_success_with_multiple_type_value(self):
        payload = {
            'name': 'John Doe',
            'income': 1234,
        }

        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('trigger-name', payload)

        # reset payload which can have different type
        payload['income'] = 'secret'

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 2)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeMock(TEST_SCHEMA)))
    def test_dispatch_success_with_null(self):
        payload = {
            'name': 'John Doe',
            'age': None,
        }

        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('trigger-name', payload)
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=TriggerTypeMock()))
    def test_dispatch_success_without_payload_schema(self):
        # the case trigger has no property
        self.sensor_service.dispatch('trigger-name', {})
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=None))
    def test_dispatch_success_without_trigger_type(self):
        self.sensor_service.dispatch('trigger-name', {})
        self.assertEqual(self._dispatched_count, 1)

    @mock.patch('st2common.services.triggers.get_trigger_type_db',
                mock.MagicMock(return_value=None))
    def test_dispatch_trigger__type_not_in_db_should_still_dispatch(self):
        cfg.CONF.system.validate_trigger_payload = True

        self.sensor_service.dispatch('not-in-database-ref', {})
        self.assertEqual(self._dispatched_count, 1)
Exemple #10
0
class SensorServiceTestCase(unittest2.TestCase):
    @classmethod
    def setUpClass(cls):
        super(SensorServiceTestCase, cls).setUpClass()
        tests_config.parse_args()

    def setUp(self):
        super(SensorServiceTestCase, self).setUp()

        file_path = os.path.join(RESOURCES_DIR, 'test_sensor.py')
        trigger_types = ['trigger1', 'trigger2']
        parent_args = ['--config-file', TESTS_CONFIG_PATH]
        wrapper = SensorWrapper(pack='core',
                                file_path=file_path,
                                class_name='TestSensor',
                                trigger_types=trigger_types,
                                parent_args=parent_args)
        self._sensor_service = SensorService(sensor_wrapper=wrapper)
        self._sensor_service._get_api_client = mock.Mock()

    def test_datastore_operations_list_values(self):
        # Verify prefix filtering
        mock_api_client = mock.Mock()
        mock_api_client.keys.get_all.return_value = []
        self._set_mock_api_client(mock_api_client)

        self._sensor_service.list_values(local=True, prefix=None)
        mock_api_client.keys.get_all.assert_called_with(
            prefix='core.TestSensor:')
        self._sensor_service.list_values(local=True, prefix='ponies')
        mock_api_client.keys.get_all.assert_called_with(
            prefix='core.TestSensor:ponies')

        self._sensor_service.list_values(local=False, prefix=None)
        mock_api_client.keys.get_all.assert_called_with(prefix=None)
        self._sensor_service.list_values(local=False, prefix='ponies')
        mock_api_client.keys.get_all.assert_called_with(prefix='ponies')

        # No values in the datastore
        mock_api_client = mock.Mock()
        mock_api_client.keys.get_all.return_value = []
        self._set_mock_api_client(mock_api_client)

        values = self._sensor_service.list_values(local=True)
        self.assertEqual(values, [])
        values = self._sensor_service.list_values(local=False)
        self.assertEqual(values, [])

        # Values in the datastore
        kvp1 = KeyValuePair()
        kvp1.name = 'test1'
        kvp1.value = 'bar'
        kvp2 = KeyValuePair()
        kvp2.name = 'test2'
        kvp2.value = 'bar'
        mock_return_value = [kvp1, kvp2]
        mock_api_client.keys.get_all.return_value = mock_return_value
        self._set_mock_api_client(mock_api_client)

        values = self._sensor_service.list_values(local=True)
        self.assertEqual(len(values), 2)
        self.assertEqual(values, mock_return_value)

    def test_datastore_operations_get_value(self):
        mock_api_client = mock.Mock()
        kvp1 = KeyValuePair()
        kvp1.name = 'test1'
        kvp1.value = 'bar'
        mock_api_client.keys.get_by_id.return_value = kvp1
        self._set_mock_api_client(mock_api_client)

        value = self._sensor_service.get_value(name='test1', local=False)
        self.assertEqual(value, kvp1.value)

    def test_datastore_operations_set_value(self):
        mock_api_client = mock.Mock()
        mock_api_client.keys.update.return_value = True
        self._set_mock_api_client(mock_api_client)

        value = self._sensor_service.set_value(name='test1',
                                               value='foo',
                                               local=False)
        self.assertTrue(value)

    def test_datastore_operations_delete_value(self):
        mock_api_client = mock.Mock()
        mock_api_client.keys.delete.return_value = True
        self._set_mock_api_client(mock_api_client)

        value = self._sensor_service.delete_value(name='test', local=False)
        self.assertTrue(value)

    def _set_mock_api_client(self, mock_api_client):
        mock_method = mock.Mock()
        mock_method.return_value = mock_api_client
        self._sensor_service._get_api_client = mock_method