From 43ee5a85c0dada6c485d819360906285c14ade4a Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Wed, 6 Nov 2019 15:09:55 -0500 Subject: [PATCH 1/3] tests(videointelligence): do not set VPCSC-related env vars in noxfile --- videointelligence/noxfile.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/videointelligence/noxfile.py b/videointelligence/noxfile.py index 9a0e46e83078..b13ae2e5bdf5 100644 --- a/videointelligence/noxfile.py +++ b/videointelligence/noxfile.py @@ -118,19 +118,12 @@ def system(session): session.install("-e", "../test_utils/") session.install("-e", ".") - # Additional set up for VPC SC. - env = { - "PROJECT_NUMBER": "570941833855", - "GOOGLE_CLOUD_TESTS_VPCSC_OUTSIDE_IP": "10.1.1.1", - "GOOGLE_CLOUD_TESTS_VPCSC_INSIDE_IP": "55.55.0.0", - } # Run py.test against the system tests. if system_test_exists: - session.run("py.test", "--quiet", system_test_path, env=env, *session.posargs) + session.run("py.test", "--quiet", system_test_path, *session.posargs) + if system_test_folder_exists: - session.run( - "py.test", "--quiet", system_test_folder_path, env=env * session.posargs - ) + session.run("py.test", "--quiet", system_test_folder_path, *session.posargs) @nox.session(python="3.7") From 372af3d1a91d08f3afe6ee8281d1e7d11c3e0c6d Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Tue, 12 Nov 2019 12:27:51 -0500 Subject: [PATCH 2/3] tests(videointelligence): restore non-VPCSC systest Deleted inadvertently in PR #9193. Convert / simplify the restored test. --- videointelligence/tests/system/test_system.py | 41 +++++++++++++++++++ .../tests/{system.py => system/test_vpcsc.py} | 0 2 files changed, 41 insertions(+) create mode 100644 videointelligence/tests/system/test_system.py rename videointelligence/tests/{system.py => system/test_vpcsc.py} (100%) diff --git a/videointelligence/tests/system/test_system.py b/videointelligence/tests/system/test_system.py new file mode 100644 index 000000000000..528edcdfadfb --- /dev/null +++ b/videointelligence/tests/system/test_system.py @@ -0,0 +1,41 @@ +# Copyright 2019, Google LLC All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""System tests for VideoIntelligence API.""" + +import pytest + +from google.cloud import videointelligence_v1 +from test_utils.retry import RetryResult + + +INPUT_URI = "gs://cloud-samples-data/video/cat.mp4" + + +@pytest.fixture(scope="module") +def client(): + return videointelligence_v1.VideoIntelligenceServiceClient() + + +def test_annotate_video(client): + features_element = videointelligence_v1.enums.Feature.LABEL_DETECTION + features = [features_element] + response = client.annotate_video(input_uri=INPUT_URI, features=features) + + retry = RetryResult(result_predicate=bool, max_tries=7) + retry(response.done)() + + result = response.result() + annotations = result.annotation_results[0] + assert len(annotations.segment_label_annotations) > 0 diff --git a/videointelligence/tests/system.py b/videointelligence/tests/system/test_vpcsc.py similarity index 100% rename from videointelligence/tests/system.py rename to videointelligence/tests/system/test_vpcsc.py From e28a9d4a2c76e7e3ed44056bbcfa46a90040a7df Mon Sep 17 00:00:00 2001 From: Tres Seaver Date: Tue, 12 Nov 2019 12:59:59 -0500 Subject: [PATCH 3/3] refactor: make existing requests-based VPCSC tests legible --- videointelligence/tests/system/test_vpcsc.py | 114 +++++++------------ 1 file changed, 43 insertions(+), 71 deletions(-) diff --git a/videointelligence/tests/system/test_vpcsc.py b/videointelligence/tests/system/test_vpcsc.py index a73e4edc1634..e54a60b1d7b0 100644 --- a/videointelligence/tests/system/test_vpcsc.py +++ b/videointelligence/tests/system/test_vpcsc.py @@ -11,99 +11,71 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -"""System tests for VideoIntelligence API.""" +"""Verify videointelligence requests are blocked by VPCSC policy.""" import json import os import requests -import unittest from google.auth.transport import requests as goog_auth_requests -from google.cloud import videointelligence from google.oauth2 import service_account +import pytest + +from test_utils.vpcsc_config import vpcsc_config CLOUD_PLATFORM_SCOPE = "https://www.googleapis.com/auth/cloud-platform" CREDENTIALS_FILE = os.environ.get("GOOGLE_APPLICATION_CREDENTIALS") -OUTSIDE_BUCKET = os.environ.get("GOOGLE_CLOUD_TESTS_VPCSC_OUTSIDE_PERIMETER_BUCKET") -INSIDE_BUCKET = os.environ.get("GOOGLE_CLOUD_TESTS_VPCSC_INSIDE_PERIMETER_BUCKET") -IS_INSIDE_VPCSC = os.environ.get("GOOGLE_CLOUD_TESTS_IN_VPCSC") - +API_ENDPOINT_URL = "https://videointelligence.googleapis.com/v1/videos:annotate" -def get_access_token(): - """Returns an access token. - Generates access tokens using the provided service account key file. - """ +@pytest.fixture(scope="module") +def access_token(): + """Generate access token using the provided service account key file.""" creds = service_account.Credentials.from_service_account_file( CREDENTIALS_FILE, scopes=[CLOUD_PLATFORM_SCOPE] ) with requests.Session() as session: creds.refresh(goog_auth_requests.Request(session=session)) + return creds.token -class VideoIntelligenceSystemTestBase(unittest.TestCase): - client = None +@pytest.fixture(scope="module") +def headers(access_token): + return { + "Authorization": "Bearer " + access_token, + "Content-Type": "application/json", + } -def setUpModule(): - VideoIntelligenceSystemTestBase.client = ( - videointelligence.VideoIntelligenceServiceClient() +def _make_body(bucket_name): + return json.dumps( + { + "features": ["LABEL_DETECTION"], + "location_id": "us-west1", + "input_uri": "gs://{}/cat.mp4".format(bucket_name), + } ) -@unittest.skipUnless( - CREDENTIALS_FILE, "GOOGLE_APPLICATION_CREDENTIALS not set in environment." -) -class TestVideoIntelligenceClientVpcSc(VideoIntelligenceSystemTestBase): - # Tests to verify VideoIntelligence service requests blocked when trying to - # access resources outside of a secure perimeter. - def setUp(self): - VideoIntelligenceSystemTestBase.setUp(self) - # api-endpoint - self.url = "https://videointelligence.googleapis.com/v1/videos:annotate" - self.body = {"features": ["LABEL_DETECTION"], "location_id": "us-west1"} - - @unittest.skipUnless( - OUTSIDE_BUCKET, - "GOOGLE_CLOUD_TESTS_VPCSC_OUTSIDE_PERIMETER_BUCKET not set in environment.", - ) - @unittest.skipUnless( - IS_INSIDE_VPCSC, "GOOGLE_CLOUD_TESTS_IN_VPCSC not set in environment." - ) - def test_outside_perimeter_blocked(self): - headers = { - "Authorization": "Bearer " + get_access_token(), - "Content-Type": "application/json", - } - self.body["input_uri"] = "gs://{bucket}/cat.mp4".format(bucket=OUTSIDE_BUCKET) - r = requests.post(url=self.url, data=json.dumps(self.body), headers=headers) - resp = json.loads(r.text) - print(resp) - # Assert it returns permission denied from VPC SC - self.assertEqual(resp["error"]["code"], 403) - self.assertEqual(resp["error"]["status"], "PERMISSION_DENIED") - - @unittest.skipUnless( - INSIDE_BUCKET, - "GOOGLE_CLOUD_TESTS_VPCSC_INSIDE_PERIMETER_BUCKET not set in environment.", - ) - @unittest.skipUnless( - IS_INSIDE_VPCSC, "GOOGLE_CLOUD_TESTS_IN_VPCSC not set in environment." - ) - def test_inside_perimeter_allowed(self): - headers = { - "Authorization": "Bearer " + get_access_token(), - "Content-Type": "application/json", - } - self.body["input_uri"] = "gs://{bucket}/cat.mp4".format(bucket=INSIDE_BUCKET) - r = requests.post(url=self.url, data=json.dumps(self.body), headers=headers) - operation = json.loads(r.text) - print(operation) - - get_op_url = "https://videointelligence.googleapis.com/v1/" + operation["name"] - get_op = requests.get(url=get_op_url, headers=headers) - get_op_resp = json.loads(get_op.text) - print(get_op_resp) - # Assert that we do not get an error. - self.assertEqual(get_op_resp["name"], operation["name"]) +@vpcsc_config.skip_unless_inside_vpcsc +def test_outside_perimeter_blocked(headers): + body = _make_body(bucket_name=vpcsc_config.bucket_outside) + + response = requests.post(url=API_ENDPOINT_URL, data=body, headers=headers) + + assert response.json["error"]["code"] == 403 + assert response.json["error"]["status"] == "PERMISSION_DENIED" + + +@vpcsc_config.skip_unless_inside_vpcsc +def test_inside_perimeter_allowed(headers): + body = _make_body(bucket_name=vpcsc_config.inside_bucket) + + response = requests.post(url=API_ENDPOINT_URL, data=body, headers=headers) + + operation = response.json + op_url = "https://videointelligence.googleapis.com/v1/{}".format(operation["name"]) + op_response = requests.get(url=op_url, headers=headers) + # Assert that we do not get an error. + assert op_response.json["name"] == operation["name"]