def setUp(self):
        self.request_mock = Mock()

        self.ts_epoch = 1451606400000
        self.ts_dt = datetime.datetime(2016, 1, 1)
        self.request_dict = {
            "children": [],
            "parent": None,
            "system": "system_name",
            "system_version": "0.0.1",
            "instance_name": "default",
            "command": "say",
            "id": "58542eb571afd47ead90d25f",
            "parameters": {},
            "comment": "bye!",
            "output": "nested output",
            "output_type": "STRING",
            "status": "IN_PROGRESS",
            "command_type": "ACTION",
            "created_at": self.ts_epoch,
            "updated_at": self.ts_epoch,
            "error_class": None,
            "metadata": {},
            "has_parent": True,
            "requester": None,
        }
        self.job_dict = {
            "name": "job_name",
            "trigger_type": "date",
            "trigger": {"run_date": self.ts_epoch, "timezone": "utc"},
            "request_template": {
                "system": "system",
                "system_version": "1.0.0",
                "instance_name": "default",
                "command": "speak",
                "parameters": {"message": "hey!"},
                "comment": "hi!",
                "metadata": {"request": "stuff"},
            },
            "misfire_grace_time": 3,
            "coalesce": True,
            "next_run_time": self.ts_epoch,
            "success_count": 0,
            "error_count": 0,
        }
        db_dict = copy.deepcopy(self.job_dict)
        db_dict["request_template"] = RequestTemplate(**db_dict["request_template"])
        db_dict["trigger"]["run_date"] = self.ts_dt
        db_dict["trigger"] = DateTrigger(**db_dict["trigger"])
        db_dict["next_run_time"] = self.ts_dt
        self.job = Job(**db_dict)

        db_dict = copy.deepcopy(self.request_dict)
        db_dict["created_at"] = self.ts_dt
        db_dict["updated_at"] = self.ts_dt
        self.request = Request(**db_dict)

        super(RequestAPITest, self).setUp()
Exemple #2
0
 def test_save_update_updated_at(self):
     request = Request(
         system="foo",
         command="bar",
         status="CREATED",
         updated_at="this_will_be_updated",
     )
     request.save()
     self.assertNotEqual(request.updated_at, "this_will_be_updated")
Exemple #3
0
 def test_command_lookup(self, monkeypatch, validator):
     request = Request(parameters={})
     lookup_mock = Mock(return_value=Mock(parameters=[]))
     monkeypatch.setattr(validator, "get_and_validate_command_for_system",
                         lookup_mock)
     validator.get_and_validate_parameters(request)
     lookup_mock.assert_called_once_with(request)
Exemple #4
0
    def get(self, request_id):
        """
        ---
        summary: Retrieve a specific Request
        parameters:
          - name: request_id
            in: path
            required: true
            description: The ID of the Request
            type: string
        responses:
          200:
            description: Request with the given ID
            schema:
              $ref: '#/definitions/Request'
          404:
            $ref: '#/definitions/404Error'
          50x:
            $ref: '#/definitions/50xError'
        tags:
          - Requests
        """
        self.logger.debug("Getting Request: %s", request_id)

        req = Request.objects.get(id=str(request_id))
        req.children = Request.objects(parent=req)

        self.write(self.parser.serialize_request(req, to_string=False))
Exemple #5
0
    def test_validate_command_choices_dictionary_list_response(
            self, validator):
        mock_client = Mock()
        mock_client.send_bg_request.return_value.output = '[{"value": "value"}]'
        validator._client = mock_client

        request = Request(
            system="foo",
            command="command1",
            parameters={"key1": "value"},
            system_version="0.0.1",
            instance_name="instance_name",
        )
        command = Mock(parameters=[
            Parameter(
                key="key1",
                choices=Choices(type="command", value="command_name"),
                optional=False,
            )
        ])

        validator.get_and_validate_parameters(request, command)
        mock_client.send_bg_request.assert_called_with(
            _command="command_name",
            _system_name="foo",
            _system_version="0.0.1",
            _instance_name="instance_name",
        )
Exemple #6
0
def _update_request_has_parent_model():
    from bg_utils.mongo.models import Request

    raw_collection = Request._get_collection()
    raw_collection.update_many({"parent": None}, {"$set": {"has_parent": False}})
    raw_collection.update_many(
        {"parent": {"$not": {"$eq": None}}}, {"$set": {"has_parent": True}}
    )
Exemple #7
0
def _update_request_parent_field_type():
    """Change GenericReferenceField to ReferenceField"""
    from bg_utils.mongo.models import Request

    raw_collection = Request._get_collection()
    for request in raw_collection.find({"parent._ref": {"$type": "object"}}):
        raw_collection.update_one(
            {"_id": request["_id"]}, {"$set": {"parent": request["parent"]["_ref"]}}
        )
Exemple #8
0
 def test_validate_value_in_choices_no_choices(self, validator):
     req = Request(system="foo",
                   command="command1",
                   parameters={"key1": "value"})
     command_parameter = Mock(key="key1",
                              multi=False,
                              type="String",
                              choices=None)
     command = Mock(parameters=[command_parameter])
     validator.get_and_validate_parameters(req, command)
Exemple #9
0
    def test_update_and_validate_parameter_extract_parameter_multi_not_list(
            self, validator):
        req = Request(system="foo",
                      command="command1",
                      parameters={"key1": "NOT A LIST"})
        command_parameter = Mock(key="key1", multi=True)
        command = Mock(parameters=[command_parameter])

        with pytest.raises(ModelValidationError):
            validator.get_and_validate_parameters(req, command)
Exemple #10
0
    def __init__(self, clients, heartbeat_interval=10, timeout_seconds=30):
        self.logger = logging.getLogger(__name__)
        self.display_name = "Plugin Status Monitor"
        self.clients = clients
        self.heartbeat_interval = heartbeat_interval
        self.timeout = timedelta(seconds=timeout_seconds)
        self.status_request = Request(command="_status",
                                      command_type="EPHEMERAL")

        super(PluginStatusMonitor, self).__init__(logger=self.logger,
                                                  name="PluginStatusMonitor")
Exemple #11
0
 def test_update_and_validate_parameter_extract_parameter_nullable_no_default(
         self, validator):
     req = Request(system="foo", command="command1", parameters={})
     command_parameter = Parameter(key="key1",
                                   multi=False,
                                   nullable=True,
                                   default=None)
     command = Mock(parameters=[command_parameter])
     validated_parameters = validator.get_and_validate_parameters(
         req, command)
     assert validated_parameters["key1"] is None
Exemple #12
0
    def test_update_and_validate_parameter_extract_parameter_optional_no_default(
            self, validator):
        req = Request(system="foo", command="command1", parameters={})
        command_parameter = Parameter(key="key1",
                                      multi=False,
                                      optional=True,
                                      default=None)
        command = Mock(parameters=[command_parameter])

        with pytest.raises(ModelValidationError):
            validator.get_and_validate_parameters(req, command)
Exemple #13
0
 def test_validate_regex_nullable(self, validator):
     req = Request(system="foo",
                   command="command1",
                   parameters={"key1": None})
     command_parameter = Parameter(key="key1",
                                   multi=False,
                                   type="String",
                                   regex=r"^Hi.*",
                                   nullable=True)
     command = Command("test", parameters=[command_parameter])
     validator.get_and_validate_parameters(req, command)
Exemple #14
0
 def test_validate_value_in_choices_multi_valid_choice(self, validator):
     req = Request(system="foo",
                   command="command1",
                   parameters={"key1": ["v1", "v2"]})
     command_parameter = Mock(
         key="key1",
         multi=True,
         type="String",
         choices=Mock(type="static", value=["v1", "v2"]),
     )
     command = Mock(parameters=[command_parameter])
     validator.get_and_validate_parameters(req, command)
Exemple #15
0
 def test_validate_value_in_choices_optional_none_allowed(self, validator):
     req = Request(system="foo", command="command1", parameters={})
     command_parameter = Mock(
         key="key1",
         multi=False,
         type="String",
         optional=True,
         default=None,
         choices=Mock(type="static", value=["value1", "value3"]),
     )
     command = Mock(parameters=[command_parameter])
     validator.get_and_validate_parameters(req, command)
Exemple #16
0
def initialize_counts():
    for request in Request.objects(status__in=["CREATED", "IN_PROGRESS"]):
        label_args = {
            "system": request.system,
            "system_version": request.system_version,
            "instance_name": request.instance_name,
        }

        if request.status == "CREATED":
            queued_request_gauge.labels(**label_args).inc()
        elif request.status == "IN_PROGRESS":
            in_progress_request_gauge.labels(**label_args).inc()
Exemple #17
0
 def setUp(self):
     brew_view.backend = Mock()
     brew_view.transport = Mock()
     self.default_request = Request(
         system="foo",
         command="bar",
         parameters={"baz": "bat"},
         output="output",
         status="CREATED",
     )
     self.default_request.validate_backend = Mock()
     self.app = brew_view.app.test_client()
Exemple #18
0
    def test_extract_parameter_non_multi_calls_with_default(
            self, validate_mock, validator):
        req = Request(system="foo", command="command1", parameters={})
        command_parameter = Mock(key="key1",
                                 multi=False,
                                 default="default_value")
        command = Mock(parameters=[command_parameter])
        validate_mock.side_effect = lambda w, x, y, z: w

        validator.get_and_validate_parameters(req, command)
        validate_mock.assert_called_once_with("default_value",
                                              command_parameter, command, req)
Exemple #19
0
    def test_validate_parameter_based_on_type_null_not_nullable(
            self, validator):
        req = Request(system="foo",
                      command="command1",
                      parameters={"key1": None})
        command_parameter = Mock(key="key1",
                                 multi=False,
                                 type="String",
                                 nullable=False)
        command = Mock(parameters=[command_parameter])

        with pytest.raises(ModelValidationError):
            validator.get_and_validate_parameters(req, command)
Exemple #20
0
 def test_validate_maximum_nullable(self, validator):
     req = Request(system="foo",
                   command="command1",
                   parameters={"key1": None})
     command_parameter = Parameter(
         key="key1",
         multi=False,
         type="Integer",
         optional=False,
         minimum=3,
         nullable=True,
     )
     command = Command("test", parameters=[command_parameter])
     validator.get_and_validate_parameters(req, command)
Exemple #21
0
    def test_validate_value_in_choices_multi_invalid_choice(self, validator):
        req = Request(system="foo",
                      command="command1",
                      parameters={"key1": ["v1", "v2"]})
        command_parameter = Mock(
            key="key1",
            multi=True,
            type="String",
            optional=False,
            choices=Mock(type="static", value=["v1", "v3"]),
        )
        command = Mock(parameters=[command_parameter])

        with pytest.raises(ModelValidationError):
            validator.get_and_validate_parameters(req, command)
Exemple #22
0
    def test_missing_nested_parameters(self, validator):
        req = Request(system="foo",
                      command="command1",
                      parameters={"key1": {}})
        nested_parameter = Mock(key="foo",
                                multi=False,
                                type="String",
                                optional=False)
        command_parameter = Mock(key="key1",
                                 multi=False,
                                 type="Dictionary",
                                 parameters=[nested_parameter])
        command = Mock(parameters=[command_parameter])

        with pytest.raises(ModelValidationError):
            validator.get_and_validate_parameters(req, command)
    def setUp(self):
        self.app = brew_view.app.test_client()

        self.default_request = Request(
            system="foo",
            command="bar",
            parameters={"baz": "bat"},
            output="output",
            status="CREATED",
        )
        self.default_request.validate_backend = Mock()

        objects_patch = patch("bg_utils.mongo.models.Request.objects")
        self.addCleanup(objects_patch.stop)
        self.objects_mock = objects_patch.start()
        self.objects_mock.return_value = None
        self.objects_mock.get = Mock(return_value=self.default_request)
Exemple #24
0
    def test_update_and_validate_parameter_extract_parameter_multi(
            self, validate_mock, validator):
        req = Request(system="foo",
                      command="command1",
                      parameters={"key1": [1, 2]})
        command_parameter = Mock(key="key1", multi=True)
        command = Mock(parameters=[command_parameter])
        validate_mock.side_effect = lambda w, x, y, z: w

        validator.get_and_validate_parameters(req, command)
        validate_mock.assert_has_calls(
            [
                call(1, command_parameter, command, req),
                call(2, command_parameter, command, req),
            ],
            any_order=True,
        )
Exemple #25
0
    def processRequest(self, request_id):
        """Validates and publishes a Request.

        :param str request_id: The ID of the Request to process
        :raises InvalidRequest: If the Request is invalid in some way
        :return: None
        """
        request_id = str(request_id)
        self.logger.info("Processing Request: %s", request_id)

        try:
            request = Request.find_or_none(request_id)
            if request is None:
                raise ModelValidationError(
                    "Could not find request with ID '%s'" % request_id)

            # Validates the request based on what is in the database.
            # This includes the validation of the request parameters,
            # systems are there, commands are there etc.
            request = self.request_validator.validate_request(request)
            request.save()

            try:
                self.clients["pika"].publish_request(
                    request,
                    confirm=True,
                    mandatory=True,
                    delivery_mode=pika.spec.PERSISTENT_DELIVERY_MODE,
                )
            except Exception:
                msg = "Error while publishing request to queue (%s[%s]-%s %s)" % (
                    request.system,
                    request.system_version,
                    request.instance_name,
                    request.command,
                )
                raise bg_utils.bg_thrift.PublishException(msg)

        except (mongoengine.ValidationError, ModelValidationError,
                RestError) as ex:
            self.logger.exception(ex)
            raise bg_utils.bg_thrift.InvalidRequest(request_id, str(ex))
Exemple #26
0
    def test_validate_command_choices_bad_value_type(self, validator):
        mock_client = Mock()
        mock_client.send_bg_request.return_value.output = '["value"]'
        validator._client = mock_client

        request = Request(
            system="foo",
            command="command1",
            parameters={"key1": "value"},
            system_version="0.0.1",
            instance_name="instance_name",
        )
        command = Mock(parameters=[
            Parameter(key="key1",
                      optional=False,
                      choices=Choices(type="command", value=1))
        ])

        with pytest.raises(ModelValidationError):
            validator.get_and_validate_parameters(request, command)
Exemple #27
0
    def test_validate_minimum_non_sequence(self, validator):
        req = Request(system="foo", command="command1", parameters={"key1": 5})

        command_parameter = Parameter(key="key1",
                                      multi=False,
                                      type="Integer",
                                      optional=False,
                                      minimum=3)
        command = Command("test", parameters=[command_parameter])
        validator.get_and_validate_parameters(req, command)

        command_parameter = Parameter(key="key1",
                                      multi=False,
                                      type="Integer",
                                      optional=False,
                                      minimum=10)
        command = Command("test", parameters=[command_parameter])

        with pytest.raises(ModelValidationError):
            validator.get_and_validate_parameters(req, command)
Exemple #28
0
    def test_validate_choices_static_bad_type(self, validator):
        command_parameter = Mock(
            key="key1",
            multi=False,
            type="String",
            optional=False,
            default=None,
            choices=Mock(type="static", value="bad str"),
            minimum=None,
            maximum=None,
            regex=None,
        )

        command = Mock(parameters=[command_parameter])

        req = Request(system="foo",
                      command="command1",
                      parameters={"key1": "1"})

        with pytest.raises(ModelValidationError):
            validator.get_and_validate_parameters(req, command)
Exemple #29
0
    def test_validate_url_choices(self, validator, response):
        session_mock = Mock()
        session_mock.get.return_value.text = response
        validator._session = session_mock

        req = Request(system="foo",
                      command="command1",
                      parameters={"key1": "value"})
        command_parameter = Mock(
            key="key1",
            type="String",
            optional=False,
            multi=False,
            choices=Mock(type="url", value="http://localhost"),
            minimum=None,
            maximum=None,
            regex=None,
        )
        command = Mock(parameters=[command_parameter])

        validator.get_and_validate_parameters(req, command)
        session_mock.get.assert_called_with("http://localhost", params={})
Exemple #30
0
    def test_validate_regex(self, validator):
        req = Request(system="foo",
                      command="command1",
                      parameters={"key1": "Hi World!"})

        command_parameter = Parameter(key="key1",
                                      multi=False,
                                      type="String",
                                      optional=False,
                                      regex=r"^Hi.*")
        command = Command("test", parameters=[command_parameter])
        validator.get_and_validate_parameters(req, command)

        command_parameter = Parameter(key="key1",
                                      multi=False,
                                      type="String",
                                      optional=False,
                                      regex=r"^Hello.*")
        command = Command("test", parameters=[command_parameter])

        with pytest.raises(ModelValidationError):
            validator.get_and_validate_parameters(req, command)