Skip to content

Commit bc5a533

Browse files
authored
E2E tests for Cloud Run hello-broken and logging-manual samples (#3971)
* E2E test for hello-broken * e2e test for logging-manual and linting * Linting * Linting * Re-writing test to use client library * Removing unused import
1 parent 2b508e6 commit bc5a533

File tree

7 files changed

+404
-0
lines changed

7 files changed

+404
-0
lines changed

run/hello-broken/e2e_test.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Copyright 2020 Google, LLC.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# This sample creates a secure two-service application running on Cloud Run.
16+
# This test builds and deploys the two secure services
17+
# to test that they interact properly together.
18+
19+
import os
20+
import subprocess
21+
from urllib import request
22+
import uuid
23+
24+
import pytest
25+
26+
27+
@pytest.fixture()
28+
def services():
29+
# Unique suffix to create distinct service names
30+
suffix = uuid.uuid4().hex
31+
project = os.environ["GOOGLE_CLOUD_PROJECT"]
32+
33+
# Build and Deploy Cloud Run Services
34+
subprocess.run(
35+
[
36+
"gcloud",
37+
"builds",
38+
"submit",
39+
"--project",
40+
project,
41+
"--substitutions",
42+
f"_SUFFIX={suffix}",
43+
"--config",
44+
"e2e_test_setup.yaml",
45+
"--quiet",
46+
],
47+
check=True,
48+
)
49+
50+
# Get the URL for the service and the token
51+
service = subprocess.run(
52+
[
53+
"gcloud",
54+
"run",
55+
"--project",
56+
project,
57+
"--platform=managed",
58+
"--region=us-central1",
59+
"services",
60+
"describe",
61+
f"hello-{suffix}",
62+
"--format=value(status.url)",
63+
],
64+
stdout=subprocess.PIPE,
65+
check=True,
66+
).stdout.strip()
67+
68+
token = subprocess.run(
69+
["gcloud", "auth", "print-identity-token"], stdout=subprocess.PIPE, check=True
70+
).stdout.strip()
71+
72+
yield service, token
73+
74+
subprocess.run(
75+
[
76+
"gcloud",
77+
"run",
78+
"services",
79+
"delete",
80+
f"hello-{suffix}",
81+
"--project",
82+
project,
83+
"--platform",
84+
"managed",
85+
"--region",
86+
"us-central1",
87+
"--quiet",
88+
],
89+
check=True,
90+
)
91+
92+
93+
def test_end_to_end(services):
94+
service = services[0].decode()
95+
token = services[1].decode()
96+
97+
# Broken
98+
with pytest.raises(Exception) as e:
99+
req = request.Request(service, headers={"Authorization": f"Bearer {token}"})
100+
request.urlopen(req)
101+
assert "HTTP Error 500: Internal Server Error" in str(e.value)
102+
103+
# Improved
104+
req = request.Request(
105+
f"{service}/improved", headers={"Authorization": f"Bearer {token}"}
106+
)
107+
response = request.urlopen(req)
108+
assert response.status == 200
109+
110+
body = response.read()
111+
assert "Hello World" == body.decode()

run/hello-broken/e2e_test_setup.yaml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Copyright 2020 Google, LLC.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
steps:
16+
- # Build the renderer image
17+
name: gcr.io/cloud-builders/docker:latest
18+
args: ['build', '--tag=gcr.io/$PROJECT_ID/hello-${_SUFFIX}', '.']
19+
20+
- # Push the container image to Container Registry
21+
name: gcr.io/cloud-builders/docker
22+
args: ['push', 'gcr.io/$PROJECT_ID/hello-${_SUFFIX}']
23+
24+
- # Deploy to Cloud Run
25+
name: gcr.io/cloud-builders/gcloud
26+
args:
27+
- run
28+
- deploy
29+
- hello-${_SUFFIX}
30+
- --image
31+
- gcr.io/$PROJECT_ID/hello-${_SUFFIX}
32+
- --region
33+
- us-central1
34+
- --platform
35+
- managed
36+
- --no-allow-unauthenticated
37+
38+
images:
39+
- 'gcr.io/$PROJECT_ID/hello-${_SUFFIX}'

run/hello-broken/noxfile_config.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# Default TEST_CONFIG_OVERRIDE for python repos.
16+
17+
# You can copy this file into your directory, then it will be inported from
18+
# the noxfile.py.
19+
20+
# The source of truth:
21+
# https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/noxfile_config.py
22+
23+
TEST_CONFIG_OVERRIDE = {
24+
# You can opt out from the test for specific Python versions.
25+
26+
# We only run the cloud run tests in py38 session.
27+
'ignored_versions': ["2.7", "3.6", "3.7"],
28+
29+
# An envvar key for determining the project id to use. Change it
30+
# to 'BUILD_SPECIFIC_GCLOUD_PROJECT' if you want to opt in using a
31+
# build specific Cloud project. You can also use your own string
32+
# to use your own Cloud project.
33+
'gcloud_project_env': 'GCLOUD_PROJECT',
34+
# 'gcloud_project_env': 'BUILD_SPECIFIC_GCLOUD_PROJECT',
35+
36+
# A dictionary you want to inject into your test. Don't put any
37+
# secrets here. These values will override predefined values.
38+
'envs': {},
39+
}

run/logging-manual/e2e_test.py

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# Copyright 2020 Google, LLC.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# This sample creates a secure two-service application running on Cloud Run.
16+
# This test builds and deploys the two secure services
17+
# to test that they interact properly together.
18+
19+
import os
20+
import subprocess
21+
import time
22+
from urllib import request
23+
import uuid
24+
25+
from google.cloud import logging_v2
26+
27+
import pytest
28+
29+
30+
@pytest.fixture()
31+
def services():
32+
# Unique suffix to create distinct service names
33+
suffix = uuid.uuid4().hex
34+
project = os.environ["GOOGLE_CLOUD_PROJECT"]
35+
36+
# Build and Deploy Cloud Run Services
37+
subprocess.run(
38+
[
39+
"gcloud",
40+
"builds",
41+
"submit",
42+
"--project",
43+
project,
44+
"--substitutions",
45+
f"_SUFFIX={suffix}",
46+
"--config",
47+
"e2e_test_setup.yaml",
48+
"--quiet",
49+
],
50+
check=True,
51+
)
52+
53+
# Get the URL for the service and the token
54+
service = subprocess.run(
55+
[
56+
"gcloud",
57+
"run",
58+
"--project",
59+
project,
60+
"--platform=managed",
61+
"--region=us-central1",
62+
"services",
63+
"describe",
64+
f"logging-{suffix}",
65+
"--format=value(status.url)",
66+
],
67+
stdout=subprocess.PIPE,
68+
check=True,
69+
).stdout.strip()
70+
71+
id_token = subprocess.run(
72+
["gcloud", "auth", "print-identity-token"], stdout=subprocess.PIPE, check=True
73+
).stdout.strip()
74+
75+
yield service, id_token, project, f"logging-{suffix}"
76+
77+
subprocess.run(
78+
[
79+
"gcloud",
80+
"run",
81+
"services",
82+
"delete",
83+
f"logging-{suffix}",
84+
"--project",
85+
project,
86+
"--platform",
87+
"managed",
88+
"--region",
89+
"us-central1",
90+
"--quiet",
91+
],
92+
check=True,
93+
)
94+
95+
96+
def test_end_to_end(services):
97+
service = services[0].decode()
98+
id_token = services[1].decode()
99+
project = services[2]
100+
service_name = services[3]
101+
102+
# Test that the service is responding
103+
req = request.Request(
104+
service,
105+
headers={
106+
"Authorization": f"Bearer {id_token}",
107+
"X-Cloud-Trace-Context": "foo/bar",
108+
},
109+
)
110+
response = request.urlopen(req)
111+
assert response.status == 200
112+
113+
body = response.read()
114+
assert body.decode() == "Hello Logger!"
115+
116+
# Test that the logs are writing properly to stackdriver
117+
time.sleep(10) # Slight delay writing to stackdriver
118+
client = logging_v2.LoggingServiceV2Client()
119+
resource_names = [f"projects/{project}"]
120+
filters = (
121+
"resource.type=cloud_run_revision "
122+
"AND severity=NOTICE "
123+
f"AND resource.labels.service_name={service_name} "
124+
"AND jsonPayload.component=arbitrary-property"
125+
)
126+
127+
# Retry a maximum number of 10 times to find results in stackdriver
128+
for x in range(10):
129+
iterator = client.list_log_entries(resource_names, filter_=filters)
130+
for entry in iterator:
131+
# If there are any results, exit loop
132+
break
133+
134+
assert iterator.num_results
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright 2020 Google, LLC.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
steps:
16+
- # Build the renderer image
17+
name: gcr.io/cloud-builders/docker:latest
18+
args: ['build', '--tag=gcr.io/$PROJECT_ID/logging-${_SUFFIX}', '.']
19+
20+
- # Push the container image to Container Registry
21+
name: gcr.io/cloud-builders/docker
22+
args: ['push', 'gcr.io/$PROJECT_ID/logging-${_SUFFIX}']
23+
24+
- # Deploy to Cloud Run
25+
name: gcr.io/cloud-builders/gcloud
26+
args:
27+
- run
28+
- deploy
29+
- logging-${_SUFFIX}
30+
- --image
31+
- gcr.io/$PROJECT_ID/logging-${_SUFFIX}
32+
- --region
33+
- us-central1
34+
- --platform
35+
- managed
36+
- --set-env-vars
37+
- GOOGLE_CLOUD_PROJECT=$PROJECT_ID
38+
- --no-allow-unauthenticated
39+
40+
images:
41+
- 'gcr.io/$PROJECT_ID/logging-${_SUFFIX}'

0 commit comments

Comments
 (0)