def test_add_trigger_event_filter(self): app = Goblet(function_name="goblet_example") app.eventarc(event_filters=[ { "attribute": "type", "value": "google.cloud.storage.object.v1.finalized", }, { "attribute": "bucket", "value": "BUCKET" }, ])(dummy_function) eventarc = app.handlers["eventarc"] assert len(eventarc.resources) == 1 assert eventarc.resources[0]["func"] == dummy_function assert eventarc.resources[0]["topic"] is None assert eventarc.resources[0]["event_filters"] == [ { "attribute": "type", "value": "google.cloud.storage.object.v1.finalized" }, { "attribute": "bucket", "value": "BUCKET" }, ]
def test_deploy_pubsub_cross_project(self, monkeypatch): monkeypatch.setenv("GOOGLE_PROJECT", "goblet") monkeypatch.setenv("GOOGLE_LOCATION", "us-central1") monkeypatch.setenv("GOBLET_TEST_NAME", "pubsub-deploy-cross-project") monkeypatch.setenv("GOBLET_HTTP_TEST", "REPLAY") service_account = "*****@*****.**" app = Goblet(function_name="goblet-topic-cross-project") setattr(app, "entrypoint", "app") app.topic("test", project="goblet-cross-project")(dummy_function) Deployer({ "name": app.function_name }).deploy(app, force=True, config={"pubsub": { "serviceAccountEmail": service_account }}) put_subscription = get_response( "pubsub-deploy-cross-project", "put-v1-projects-goblet-subscriptions-goblet-topic-cross-project-test_1.json", ) responses = get_responses("pubsub-deploy-cross-project") assert "goblet-cross-project" in put_subscription["body"]["topic"] assert len(responses) == 5
def test_deploy_cloudrun(self, monkeypatch): monkeypatch.setenv("GOOGLE_PROJECT", "goblet") monkeypatch.setenv("GOOGLE_LOCATION", "us-central1") monkeypatch.setenv("GOBLET_HTTP_TEST", "REPLAY") mock = Mock() monkeypatch.setattr(subprocess, "check_output", mock) app = Goblet(function_name="goblet", backend="cloudrun") setattr(app, "entrypoint", "app") app.handlers["http"] = HTTP(dummy_function) Deployer({"name": app.function_name}).deploy( app, only_function=True, force=True, config={"cloudrun": {"no-allow-unauthenticated": "", "max-instances": "2"}}, ) assert set( [ "gcloud", "run", "deploy", "--no-allow-unauthenticated", "--max-instances", "2", ] ).issubset(set(mock.call_args[0][0]))
def test_cloudrun_custom_artifact(self, monkeypatch, requests_mock): monkeypatch.setenv("GOOGLE_PROJECT", "goblet") monkeypatch.setenv("GOOGLE_LOCATION", "us-central1") monkeypatch.setenv("GOBLET_TEST_NAME", "deployer-cloudrun-artifact") monkeypatch.setenv("GOBLET_HTTP_TEST", "REPLAY") requests_mock.register_uri("PUT", "https://storage.googleapis.com/mock") app = Goblet(function_name="goblet", backend="cloudrun") setattr(app, "entrypoint", "app") app.handlers["http"] = HTTP(dummy_function) app.deploy( only_function=True, force=True, config={ "cloudrun_revision": { "serviceAccount": "*****@*****.**" }, "cloudbuild": { "artifact_registry": "us-central1-docker.pkg.dev/newgoblet/cloud-run-source-deploy/goblet", "serviceAccount": "projects/goblet/serviceAccounts/[email protected]", }, }, ) response = get_response( "deployer-cloudrun-artifact", "post-v1-projects-goblet-builds_1.json" ) assert ( "newgoblet" in response["body"]["metadata"]["build"]["artifacts"]["images"][0] )
def test_add_schedule(self, monkeypatch): app = Goblet(function_name="goblet_example") monkeypatch.setenv("GOOGLE_PROJECT", "TEST_PROJECT") monkeypatch.setenv("GOOGLE_LOCATION", "us-central1") app.schedule("* * * * *", description="test")(dummy_function) scheduler = app.handlers["schedule"] assert len(scheduler.resources) == 1 scheule_json = { "name": "projects/TEST_PROJECT/locations/us-central1/jobs/goblet_example-dummy_function", "schedule": "* * * * *", "timeZone": "UTC", "description": "test", "attemptDeadline": None, "retry_config": None, "httpTarget": { "body": None, "headers": { "X-Goblet-Type": "schedule", "X-Goblet-Name": "dummy_function", }, "httpMethod": "GET", "oidcToken": {}, }, } assert scheduler.resources["dummy_function"][ "job_json"] == scheule_json assert scheduler.resources["dummy_function"]["func"] == dummy_function
def test_deploy_cloudrun(self, monkeypatch, requests_mock): monkeypatch.setenv("GOOGLE_PROJECT", "goblet") monkeypatch.setenv("GOOGLE_LOCATION", "us-central1") monkeypatch.setenv("GOBLET_TEST_NAME", "deployer-cloudrun-deploy") monkeypatch.setenv("GOBLET_HTTP_TEST", "REPLAY") requests_mock.register_uri("PUT", "https://storage.googleapis.com/mock") app = Goblet(function_name="goblet", backend="cloudrun") setattr(app, "entrypoint", "app") app.handlers["http"] = HTTP(dummy_function) app.deploy( only_function=True, force=True, config={ "cloudrun_revision": { "serviceAccount": "*****@*****.**" } }, ) responses = get_responses("deployer-cloudrun-deploy") assert len(responses) == 9
def test_call_route(self): app = Goblet(function_name="goblet_example") mock = Mock() mock_param = Mock() app.route("/test")(mock_dummy_function(mock)) @app.route("/test/{param}", methods=["POST"]) def mock_function2(param): mock_param(param) return True mock_event1 = Mock() mock_event1.path = "/test" mock_event1.method = "GET" mock_event1.headers = {} mock_event1.json = {} app(mock_event1, None) mock_event2 = Mock() mock_event2.path = "/test/param" mock_event2.method = "POST" mock_event2.headers = {} mock_event2.json = {} app(mock_event2, None) assert mock.call_count == 1 mock_param.assert_called_once_with("param")
def test_add_topic(self): app = Goblet(function_name="goblet_example") app.topic("test")(dummy_function) pubsub = app.handlers["pubsub"] assert len(pubsub.resources) == 1 assert (pubsub.resources["test"]["trigger"]["dummy_function"]["func"] == dummy_function)
def test_add_topic_with_subscription(self): app = Goblet(function_name="goblet_example") app.topic("test", use_subscription="true")(dummy_function) pubsub = app.handlers["pubsub"] assert len(pubsub.resources) == 1 assert (pubsub.resources["test"]["subscription"]["dummy_function"] ["func"] == dummy_function)
def test_add_topic_filter(self): app = Goblet(function_name="goblet_example") app.topic("test", filter='attributes.test = "1"')(dummy_function) pubsub = app.handlers["pubsub"] assert len(pubsub.resources) == 1 assert (pubsub.resources["test"]["trigger"]["dummy_function"]["filter"] == 'attributes.test = "1"')
def test_add_bucket(self, monkeypatch): app = Goblet(function_name="goblet_example") app.storage("test", "finalize")(dummy_function) app.storage("test2", "archive")(dummy_function) storage = app.handlers["storage"] assert len(storage.resources) == 2 assert storage.resources[0]["event_type"] == "finalize" assert storage.resources[1]["event_type"] == "archive"
def test_destroy_http_function_all(self, monkeypatch): monkeypatch.setenv("GOOGLE_PROJECT", "goblet") monkeypatch.setenv("GOOGLE_LOCATION", "us-central1") monkeypatch.setenv("GOBLET_TEST_NAME", "deployer-function-destroy-all") monkeypatch.setenv("GOBLET_HTTP_TEST", "REPLAY") app = Goblet(function_name="goblet_example") app.destroy(all=True) responses = get_responses("deployer-function-destroy-all") assert len(responses) == 4
def test_call_storage(self, monkeypatch): app = Goblet(function_name="goblet_example") mock = Mock() app.storage("test", "finalize")(mock_dummy_function(mock)) mock_context = Mock() mock_context.event_type = "providers/cloud.storage/eventTypes/bucket.finalize" event = {"bucket": "test"} app(event, mock_context) assert mock.call_count == 1
def test_add_base_route(self): app = Goblet(function_name="goblet_example") app.route("/home")(dummy_function) gateway = app.handlers["route"] assert len(gateway.resources) == 1 route_entry = gateway.resources["/home"]["GET"] assert route_entry.method == "GET" assert route_entry.function_name == "dummy_function" assert route_entry.uri_pattern == "/home" assert route_entry.route_function == dummy_function
def test_cors(self): app = Goblet(function_name="goblet_cors") app2 = Goblet(function_name="goblet_cors", cors=CORSConfig(allow_origin="app-level")) @app.route("/test", cors=True) def mock_function(): return "200" @app2.route("/test2") def mock_function2(): return Response("200") @app2.route("/override", cors=CORSConfig(allow_origin="override")) def mock_function_override(): return Response("200") @app.route("/test3", cors=CORSConfig(allow_origin="localhost")) def mock_function3(): return jsonify("200") mock_event1 = Mock() mock_event1.path = "/test" mock_event1.method = "GET" mock_event1.headers = {} mock_event1.json = {} resp = app(mock_event1, None) assert resp.headers["Access-Control-Allow-Origin"] == "*" mock_event2 = Mock() mock_event2.path = "/test2" mock_event2.method = "GET" mock_event2.headers = {} mock_event2.json = {} resp2 = app2(mock_event2, None) assert resp2.headers["Access-Control-Allow-Origin"] == "app-level" mock_event_override = Mock() mock_event_override.path = "/override" mock_event_override.method = "GET" mock_event_override.headers = {} mock_event_override.json = {} resp2 = app2(mock_event_override, None) assert resp2.headers["Access-Control-Allow-Origin"] == "override" mock_event3 = Mock() mock_event3.path = "/test3" mock_event3.method = "GET" mock_event3.headers = {} mock_event3.json = {} resp3 = app(mock_event3, None) assert resp3[2]["Access-Control-Allow-Origin"] == "localhost"
def test_add_route_path_params(self): app = Goblet(function_name="goblet_example") app.route("/home/{home_id}", content_types={"home_id": "boolean"})(dummy_function) gateway = app.handlers["route"] assert len(gateway.resources) == 1 route_entry = gateway.resources["/home/{home_id}"]["GET"] assert route_entry.method == "GET" assert route_entry.function_name == "dummy_function" assert route_entry.uri_pattern == "/home/{home_id}" assert route_entry.route_function == dummy_function
def test_destroy_cloudrun(self, monkeypatch): monkeypatch.setenv("GOOGLE_PROJECT", "goblet") monkeypatch.setenv("GOOGLE_LOCATION", "us-central1") monkeypatch.setenv("GOBLET_TEST_NAME", "deployer-cloudrun-destroy") monkeypatch.setenv("GOBLET_HTTP_TEST", "REPLAY") app = Goblet(function_name="goblet", backend="cloudrun") app.destroy() responses = get_responses("deployer-cloudrun-destroy") assert len(responses) == 1 assert responses[0]["body"]["status"] == "Success" assert responses[0]["body"]["details"]["name"] == "goblet"
def test_call_route(self): app = Goblet(function_name="goblet_example") mock = Mock() app.http()(mock_dummy_function(mock)) mock_request = Mock() mock_request.path = "/" mock_request.headers = {} mock_request.json = {} app(mock_request, None) assert mock.call_count == 1
def test_call_eventarc_topic_no_response(self): app = Goblet(function_name="goblet_example") app.eventarc(topic="test")(mock_dummy_function(dummy_function)) request = Mock() request.path = "/x-goblet-eventarc-triggers/goblet-example-dummy-function" request.headers = { "Ce-Type": "google.cloud.pubsub.topic.v1.messagePublished", "Ce-Source": "//pubsub.googleapis.com/projects/goblet/topics/test", } resp = app(request, None) assert resp.status_code == 200
def test_add_topic_attributes(self): app = Goblet(function_name="goblet_example") app.topic("test", attributes={"test": True})(dummy_function) pubsub = app.handlers["pubsub"] assert len(pubsub.resources) == 1 assert (pubsub.resources["test"]["trigger"]["dummy_function"]["func"] == dummy_function) assert pubsub.resources["test"]["trigger"]["dummy_function"][ "attributes"] == { "test": True } assert (pubsub.resources["test"]["trigger"]["dummy_function"]["filter"] == 'attributes.test = "True"')
def test_deploy_http_function(self, monkeypatch): monkeypatch.setenv("GOOGLE_PROJECT", "goblet") monkeypatch.setenv("GOOGLE_LOCATION", "us-central1") monkeypatch.setenv("GOBLET_TEST_NAME", "deployer-function-deploy") monkeypatch.setenv("GOBLET_HTTP_TEST", "REPLAY") app = Goblet(function_name="goblet_example") setattr(app, "entrypoint", "app") app.handlers["http"] = HTTP(dummy_function) Deployer().deploy(app, only_function=True, force=True) responses = get_responses("deployer-function-deploy") assert len(responses) == 3
def test_add_trigger_topic(self): app = Goblet(function_name="goblet_example") app.eventarc(topic="test")(dummy_function) eventarc = app.handlers["eventarc"] assert len(eventarc.resources) == 1 assert eventarc.resources[0]["func"] == dummy_function assert eventarc.resources[0]["topic"] == "test" assert eventarc.resources[0]["event_filters"] == [{ "attribute": "type", "value": "google.cloud.pubsub.topic.v1.messagePublished", }]
def test_call_headers_dict(self): app = Goblet(function_name="goblet_example") mock = Mock() @app.http(headers={"test": 1, "test2": 2}) def mock_function(request): mock() return True mock_request = Mock() mock_request.path = "/" mock_request.headers = {"test": 1, "test2": 2} mock_request.json = {} mock_request2 = Mock() mock_request2.path = "/" mock_request2.headers = {"test": 1} mock_request2.json = {} mock_request3 = Mock() mock_request3.path = "/" mock_request3.headers = {"test": 3} mock_request3.json = {} app(mock_request, None) app(mock_request2, None) app(mock_request3, None) assert mock.call_count == 1
def test_destroy_http_function(self, monkeypatch): monkeypatch.setenv("GOOGLE_PROJECT", "goblet") monkeypatch.setenv("GOOGLE_LOCATION", "us-central1") monkeypatch.setenv("GOBLET_TEST_NAME", "deployer-function-destroy") monkeypatch.setenv("GOBLET_HTTP_TEST", "REPLAY") app = Goblet(function_name="goblet_test_app") app.destroy() responses = get_responses("deployer-function-destroy") assert len(responses) == 1 assert responses[0]["body"]["metadata"]["type"] == "DELETE_FUNCTION" assert ( responses[0]["body"]["metadata"]["target"] == "projects/goblet/locations/us-central1/functions/goblet_test_app" )
def test_deploy_http_function(self, monkeypatch, requests_mock): monkeypatch.setenv("GOOGLE_PROJECT", "goblet") monkeypatch.setenv("GOOGLE_LOCATION", "us-central1") monkeypatch.setenv("GOBLET_TEST_NAME", "deployer-function-deploy") monkeypatch.setenv("GOBLET_HTTP_TEST", "REPLAY") requests_mock.register_uri("PUT", "https://storage.googleapis.com/mock") app = Goblet(function_name="goblet_example") setattr(app, "entrypoint", "app") app.handlers["http"] = HTTP(dummy_function) app.deploy(only_function=True, force=True) responses = get_responses("deployer-function-deploy") assert len(responses) == 3
def test_deploy_http_function_v2(self, monkeypatch, requests_mock): monkeypatch.setenv("GOOGLE_PROJECT", "goblet") monkeypatch.setenv("GOOGLE_LOCATION", "us-central1") monkeypatch.setenv("GOBLET_TEST_NAME", "deployer-function-deploy-v2") monkeypatch.setenv("GOBLET_HTTP_TEST", "REPLAY") requests_mock.register_uri("PUT", "https://storage.googleapis.com/mock") app = Goblet(function_name="goblet-test-http-v2", backend="cloudfunctionv2") setattr(app, "entrypoint", "app") app.handlers["http"].register_http(dummy_function, {}) app.deploy(only_function=True, force=True, config={"runtime": "python38"}) responses = get_responses("deployer-function-deploy-v2") assert len(responses) == 3
def test_set_iam_bindings(self, monkeypatch): monkeypatch.setenv("GOOGLE_PROJECT", "goblet") monkeypatch.setenv("GOOGLE_LOCATION", "us-central1") monkeypatch.setenv("GOBLET_TEST_NAME", "deployer-function-bindings") monkeypatch.setenv("GOBLET_HTTP_TEST", "REPLAY") app = Goblet(function_name="goblet_bindings") setattr(app, "entrypoint", "app") app.handlers["http"] = HTTP(dummy_function) bindings = [{"role": "roles/cloudfunctions.invoker", "members": ["allUsers"]}] Deployer(config={"name": "goblet_test_app"}).deploy( app, only_function=True, config={"bindings": bindings}, force=True ) responses = get_responses("deployer-function-bindings") assert len(responses) == 4 assert responses[2]["body"]["bindings"] == bindings
def test_call_subscription(self): app = Goblet(function_name="goblet_example") mock = Mock() app.topic("test")(mock_dummy_function(mock)) mock_request = Mock() mock_request.headers = {} event = {"data": base64.b64encode("test".encode())} mock_request.json = { "message": event, "subscription": "projects/PROJECT/subscriptions/goblet_example-test", } # assert dummy_function is run app(mock_request, None) assert mock.call_count == 1
def test_cloudfunction_delta(self, monkeypatch, requests_mock): monkeypatch.setenv("GOOGLE_PROJECT", "goblet") monkeypatch.setenv("GOOGLE_LOCATION", "us-east1") monkeypatch.setenv("GOBLET_TEST_NAME", "deployer-cloudfunction-delta") monkeypatch.setenv("GOBLET_HTTP_TEST", "REPLAY") requests_mock.register_uri( "HEAD", "https://storage.googleapis.com/mock", headers={"x-goog-hash": "crc32c=+kjoHA==, md5=QcWxCkEOHzBSBgerQcjMEg=="}, ) app = Goblet(function_name="goblet_test_app") app_backend = app.backend_class(app) assert not app_backend.delta(f"{DATA_DIR_MAIN}/test_zip.txt.zip") assert app_backend.delta(f"{DATA_DIR_MAIN}/fail_test_zip.txt.zip")
def test_set_iam_bindings(self, monkeypatch, requests_mock): monkeypatch.setenv("GOOGLE_PROJECT", "goblet") monkeypatch.setenv("GOOGLE_LOCATION", "us-central1") monkeypatch.setenv("GOBLET_TEST_NAME", "deployer-function-bindings") monkeypatch.setenv("GOBLET_HTTP_TEST", "REPLAY") requests_mock.register_uri("PUT", "https://storage.googleapis.com/mock") app = Goblet(function_name="goblet_bindings") setattr(app, "entrypoint", "app") app.handlers["http"] = HTTP(dummy_function) bindings = [{"role": "roles/cloudfunctions.invoker", "members": ["allUsers"]}] app.deploy(only_function=True, config={"bindings": bindings}, force=True) responses = get_responses("deployer-function-bindings") assert len(responses) == 4 assert responses[2]["body"]["bindings"] == bindings