class TestClean: @pytest.mark.parametrize( "req", [ Request(system="foo", command="bar", status="bad"), Request(system="foo", command="bar", command_type="BAD"), Request(system="foo", command="bar", output_type="BAD"), ], ) def test_bad_values(self, req): with pytest.raises(ModelValidationError): req.clean() @pytest.mark.parametrize( "parent, has_parent", [(None, False), ("something", True)], ) def test_set_has_parent(self, parent, has_parent): req = Request(command="bar", parent=parent) req.clean() assert req.has_parent is has_parent @pytest.mark.parametrize( "parent, has_parent", [(None, True), (Request(command="say"), False)], ) def test_parent_mismatch(self, parent, has_parent): req = Request(command="bar", parent=parent, has_parent=has_parent) with pytest.raises(ModelValidationError): req.clean()
def data_cleanup(): """Cleanup all data between test modules to ensure each one is independent""" yield Event.drop_collection() File.drop_collection() Garden.drop_collection() Job.drop_collection() RawFile.drop_collection() Request.drop_collection() RemoteUser.drop_collection() Role.drop_collection() System.drop_collection() User.drop_collection() UserToken.drop_collection()
class TestSendEventToParent(object): event = Event( payload_type="Request", payload=Request( system="system_test", command="command_test", namespace="test", ), ) def config_get(self, config_name): return [] @pytest.fixture() def command_blocklist(self): blocklist = CommandPublishingBlockList( namespace=self.event.payload.namespace, system=self.event.payload.system, command=self.event.payload.command, ).save() yield blocklist blocklist.delete() def test_command_exists_in_blocklist(self, command_blocklist, monkeypatch): monkeypatch.setattr(config, "get", self.config_get) assert event_blocklisted(self.event) def test_command_missing_in_blocklist(self, monkeypatch): monkeypatch.setattr(config, "get", self.config_get) assert not event_blocklisted(self.event) def test_event_not_request(self, monkeypatch): monkeypatch.setattr(config, "get", self.config_get) event = Event(name="ENTRY_STARTED") assert not event_blocklisted(event) def test_can_send_event_error(self, monkeypatch): monkeypatch.setattr(config, "get", self.config_get) event = Event(name="REQUEST_CREATE", error=True) assert event_blocklisted(event) def test_can_send_event_to_parent(self, monkeypatch): monkeypatch.setattr(config, "get", self.config_get) assert not event_blocklisted(self.event) def test_can_send_event_to_parent_blocklist(self, command_blocklist, monkeypatch): monkeypatch.setattr(config, "get", self.config_get) assert event_blocklisted(self.event)
def request_model(self, raw_file, local_garden_name): req = Request( system="foo", command="bar", status="CREATED", system_version="1.0.0", instance_name="foobar", namespace=local_garden_name, ) req.parameters = { "message": "hi", "file_param": { "type": "bytes", "id": str(raw_file.id) }, } req.output = "bye" req.parameters_gridfs.put = Mock() req.output_gridfs.put = Mock() return req
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()
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)
def test_request(test_request_template): request = Request( system=test_request_template.system, system_version=test_request_template.system_version, namespace=test_request_template.namespace, instance_name=test_request_template.instance_name, command=test_request_template.command, updated_at=datetime.datetime.utcnow, ) request.save() yield request request.delete()
def request_not_permitted(local_system): request = Request( system=local_system.name, system_version=local_system.version, namespace=local_system.namespace, command="mycommand", instance_name="default", parameters={"this": "doesntmatter"}, ) request.save() yield request request.delete()
def child_garden_request(): request = Request( namespace="child_garden", system="testsystem", system_version="1.0.0", instance_name="instance1", command="somecommand", parameters={}, ) request.save() yield request request.delete()
def request_permitted_child(remote_system, request_permitted): request = Request( system=remote_system.name, system_version=remote_system.version, namespace=remote_system.namespace, command="mycommand", instance_name="default", parameters={"im": "thechild"}, parent=request_permitted, ) request.save() yield request request.delete()
def request_with_gridfs_output(monkeypatch, local_system): monkeypatch.setattr(beer_garden.db.mongo.models, "REQUEST_MAX_PARAM_SIZE", 0) request = Request( system=local_system.name, system_version=local_system.version, namespace=local_system.namespace, command="mycommand", instance_name="default", parameters={"this": "doesntmatter"}, status="SUCCESS", output=_gridfs_output(), ) request.save() yield request request.delete()
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()
def test_parent_mismatch(self, parent, has_parent): req = Request(command="bar", parent=parent, has_parent=has_parent) with pytest.raises(ModelValidationError): req.clean()
class TestRequest(object): @pytest.fixture(autouse=True) def drop(self, mongo_conn): Request.drop_collection() def test_str(self): assert str(Request(command="command")) == "command" def test_repr(self): request = Request(command="command", status="CREATED") assert "name" in repr(request) assert "CREATED" in repr(request) @pytest.mark.parametrize( "req", [ Request(system="foo", command="bar", status="bad"), Request(system="foo", command="bar", command_type="BAD"), Request(system="foo", command="bar", output_type="BAD"), ], ) def test_clean_fail(self, req): with pytest.raises(ModelValidationError): req.clean() @pytest.mark.parametrize( "start,end", [("SUCCESS", "IN_PROGRESS"), ("SUCCESS", "ERROR"), ("IN_PROGRESS", "CREATED")], ) def test_invalid_status_transitions(self, bg_request, start, end): bg_request.status = start bg_request.output = None db.create(bg_request) with pytest.raises(RequestStatusTransitionError): bg_request.status = end db.update(bg_request) # TODO - Make these integration tests # @patch("bg_utils.mongo.models.Request.objects") # def test_find_one_or_none_found(self, objects_mock): # self.assertEqual(objects_mock.get.return_value, Request.find_or_none("id")) # # @patch("bg_utils.mongo.models.Request.objects") # def test_find_one_or_none_none_found(self, objects_mock): # objects_mock.get = Mock(side_effect=mongoengine.DoesNotExist) # self.assertIsNone(Request.find_or_none("id")) # # @patch("mongoengine.Document.save", Mock()) # 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") # Namespace was removed from the TEMPLATE_FIELDS list, so reduce by one def test_template_check(self): assert len(Request.TEMPLATE_FIELDS) == len( RequestTemplateSchema.get_attribute_names())
class RequestAPITest(TestHandlerBase): 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() def tearDown(self): Request.objects.delete() Job.objects.delete() def test_get(self): self.request.save() response = self.fetch("/api/v1/requests/" + str(self.request.id)) self.assertEqual(200, response.code) data = json.loads(response.body.decode("utf-8")) data.pop("updated_at") self.request_dict.pop("updated_at") self.assertEqual(self.request_dict, data) def test_patch_replace_duplicate(self): self.request.status = "SUCCESS" self.request.output = "output" self.request.save() body = json.dumps({ "operations": [ { "operation": "replace", "path": "/output", "value": "output" }, { "operation": "replace", "path": "/status", "value": "SUCCESS" }, ] }) response = self.fetch( "/api/v1/requests/" + str(self.request.id), method="PATCH", body=body, headers={"content-type": "application/json"}, ) self.assertEqual(200, response.code) self.request.reload() self.assertEqual("SUCCESS", self.request.status) self.assertEqual("output", self.request.output) def test_patch_replace_status(self): self.request.save() body = json.dumps({ "operations": [{ "operation": "replace", "path": "/status", "value": "SUCCESS" }] }) response = self.fetch( "/api/v1/requests/" + str(self.request.id), method="PATCH", body=body, headers={"content-type": "application/json"}, ) self.assertEqual(200, response.code) self.request.reload() self.assertEqual("SUCCESS", self.request.status) def test_patch_replace_output(self): self.request.output = "old_output_but_not_done_with_progress" self.request.save() body = json.dumps({ "operations": [{ "operation": "replace", "path": "/output", "value": "output" }] }) response = self.fetch( "/api/v1/requests/" + str(self.request.id), method="PATCH", body=body, headers={"content-type": "application/json"}, ) self.assertEqual(200, response.code) self.request.reload() self.assertEqual("output", self.request.output) def test_patch_replace_error_class(self): self.request.error_class = "Klazz1" body = json.dumps({ "operations": [{ "operation": "replace", "path": "/error_class", "value": "error" }] }) self.request.save() response = self.fetch( "/api/v1/requests/" + str(self.request.id), method="PATCH", body=body, headers={"content-type": "application/json"}, ) self.request.reload() self.assertEqual(200, response.code) self.assertEqual("error", self.request.error_class) def test_patch_replace_bad_status(self): self.request.save() body = json.dumps({ "operations": [{ "operation": "replace", "path": "/status", "value": "bad" }] }) response = self.fetch( "/api/v1/requests/" + str(self.request.id), method="PATCH", body=body, headers={"content-type": "application/json"}, ) self.assertGreaterEqual(response.code, 400) def test_patch_update_output_for_complete_request(self): self.request.status = "SUCCESS" self.request.output = "old_value" self.request.save() body = json.dumps({ "operations": [{ "operation": "replace", "path": "/output", "value": "shouldnt work", }] }) response = self.fetch( "/api/v1/requests/" + str(self.request.id), method="PATCH", body=body, headers={"content-type": "application/json"}, ) self.request.reload() self.assertGreaterEqual(response.code, 400) self.assertEqual(self.request.output, "old_value") def test_patch_no_system(self): good_id_does_not_exist = "".join("1" for _ in range(24)) response = self.fetch( "/api/v1/requests/" + good_id_does_not_exist, method="PATCH", body='{"operations": [{"operation": "fake"}]}', headers={"content-type": "application/json"}, ) self.assertEqual(response.code, 404) def test_patch_replace_bad_path(self): self.request.save() body = json.dumps({ "operations": [{ "operation": "replace", "path": "/bad", "value": "error" }] }) response = self.fetch( "/api/v1/requests/" + str(self.request.id), method="PATCH", body=body, headers={"content-type": "application/json"}, ) self.assertGreaterEqual(response.code, 400) def test_patch_bad_operation(self): self.request.save() response = self.fetch( "/api/v1/requests/" + str(self.request.id), method="PATCH", body='{"operations": [{"operation": "fake"}]}', headers={"content-type": "application/json"}, ) self.assertGreaterEqual(response.code, 400) def test_prometheus_endpoint(self): handler = self.app.find_handler(request=Mock(path="/api/v1/requests")) c = handler.handler_class( self.app, Mock(path="/api/v1/requests/111111111111111111111111")) assert c.prometheus_endpoint == "/api/v1/requests/<ID>" def test_update_job_numbers(self): self.job.save() self.request.metadata["_bg_job_id"] = str(self.job.id) self.request.save() body = json.dumps({ "operations": [{ "operation": "replace", "path": "/status", "value": "SUCCESS" }] }) response = self.fetch( "/api/v1/requests/" + str(self.request.id), method="PATCH", body=body, headers={"content-type": "application/json"}, ) self.assertEqual(response.code, 200) self.job.reload() self.assertEqual(self.job.success_count, 1) self.assertEqual(self.job.error_count, 0) def test_update_job_numbers_error(self): self.job.save() self.request.metadata["_bg_job_id"] = str(self.job.id) self.request.save() body = json.dumps({ "operations": [{ "operation": "replace", "path": "/status", "value": "ERROR" }] }) response = self.fetch( "/api/v1/requests/" + str(self.request.id), method="PATCH", body=body, headers={"content-type": "application/json"}, ) self.assertEqual(response.code, 200) self.job.reload() self.assertEqual(self.job.success_count, 0) self.assertEqual(self.job.error_count, 1) def test_update_job_invalid_id(self): self.request.metadata["_bg_job_id"] = "".join(["1" for _ in range(24)]) self.request.save() body = json.dumps({ "operations": [{ "operation": "replace", "path": "/status", "value": "ERROR" }] }) response = self.fetch( "/api/v1/requests/" + str(self.request.id), method="PATCH", body=body, headers={"content-type": "application/json"}, ) self.assertEqual(response.code, 200)
def db_cleanup(): yield RawFile.drop_collection() Request.drop_collection()
def test_repr(self): request = Request(command="command", status="CREATED") assert "name" in repr(request) assert "CREATED" in repr(request)
def test_str(self): assert str(Request(command="command")) == "command"
def drop(self, mongo_conn): Request.drop_collection()
def test_set_has_parent(self, parent, has_parent): req = Request(command="bar", parent=parent) req.clean() assert req.has_parent is has_parent
def clear_requests(app): Request.drop_collection()