Skip to content

Commit e57ca09

Browse files
authored
test server for python e2e tests (#136)
* add instrumented test server and docker file for it * add cloudbuild.yaml * copyright headers * new tag * add step IDs
1 parent d4ca1f1 commit e57ca09

7 files changed

Lines changed: 214 additions & 0 deletions

File tree

.dockerignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.git
2+
docs/
3+
.tox
4+
**/venv/
5+
.mypy_cache/

cloudbuild.yaml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright 2021 Google
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+
- name: docker
17+
id: build-test-server
18+
args:
19+
- build
20+
- --tag=gcr.io/$PROJECT_ID/opentelemetry-operations-python-e2e-test-server
21+
- --file=e2e-test-server/Dockerfile
22+
- .
23+
24+
- name: gcr.io/opentelemetry-ops-e2e/opentelemetry-operations-e2e-testing:0.5.5
25+
id: run-tests
26+
env:
27+
- "PROJECT_ID=$PROJECT_ID"
28+
args:
29+
- local
30+
- --image=gcr.io/$PROJECT_ID/opentelemetry-operations-python-e2e-test-server
31+
- --network=cloudbuild
32+
33+
logsBucket: gs://opentelemetry-ops-e2e-cloud-build-logs

e2e-test-server/Dockerfile

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Copyright 2021 Google
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+
# https://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+
# Build relative to root of repository i.e. `docker build --file Dockerfile --tag=$tag ..`
16+
17+
FROM python:3.9-slim as python-base
18+
ENV PYTHONFAULTHANDLER=1 \
19+
PYTHONUNBUFFERED=1 \
20+
PYTHONHASHSEED=random \
21+
PIP_NO_CACHE_DIR=off \
22+
PIP_DISABLE_PIP_VERSION_CHECK=on \
23+
PIP_DEFAULT_TIMEOUT=100 \
24+
SRC="/src"
25+
WORKDIR $SRC
26+
27+
FROM python-base as build-base
28+
# copy local dependencies
29+
COPY opentelemetry-exporter-gcp-trace opentelemetry-exporter-gcp-trace
30+
WORKDIR $SRC/e2e-test-server
31+
# copy requirements/constraints
32+
COPY e2e-test-server/requirements.txt e2e-test-server/constraints.txt ./
33+
RUN python -m venv venv && ./venv/bin/pip install -r requirements.txt
34+
35+
FROM python-base
36+
WORKDIR $SRC/e2e-test-server
37+
COPY --from=build-base $SRC/e2e-test-server/venv venv/
38+
COPY e2e-test-server/ ./
39+
40+
ENTRYPOINT ["./venv/bin/gunicorn"]

e2e-test-server/constraints.txt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
cachetools==4.2.2
2+
certifi==2020.12.5
3+
chardet==4.0.0
4+
click==7.1.2
5+
Flask==1.1.2
6+
google-api-core==1.26.3
7+
google-auth==1.30.0
8+
google-cloud-core==1.6.0
9+
google-cloud-trace==0.24.0
10+
googleapis-common-protos==1.53.0
11+
grpcio==1.37.0
12+
gunicorn==20.1.0
13+
idna==2.10
14+
itsdangerous==1.1.0
15+
Jinja2==2.11.3
16+
MarkupSafe==1.1.1
17+
opentelemetry-api==1.1.0
18+
opentelemetry-sdk==1.1.0
19+
opentelemetry-semantic-conventions==0.20b0
20+
packaging==20.9
21+
protobuf==3.15.8
22+
pyasn1==0.4.8
23+
pyasn1-modules==0.2.8
24+
pyparsing==2.4.7
25+
pytz==2021.1
26+
requests==2.25.1
27+
rsa==4.7.2
28+
six==1.15.0
29+
urllib3==1.26.4
30+
Werkzeug==1.0.1

e2e-test-server/gunicorn.conf.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright 2021 Google
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+
# https://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+
import os
16+
17+
if "PORT" not in os.environ:
18+
raise Exception("Must supply environment variable PORT")
19+
20+
bind = "0.0.0.0:{}".format(os.environ["PORT"])
21+
22+
# Needed to prevent forking for OTel
23+
workers = 1
24+
25+
wsgi_app = "server:app"
26+
27+
# log requests to stdout
28+
accesslog = "-"

e2e-test-server/requirements.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-c constraints.txt
2+
../opentelemetry-exporter-gcp-trace
3+
opentelemetry-sdk
4+
opentelemetry-api
5+
Flask
6+
gunicorn

e2e-test-server/server.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Copyright 2021 Google
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+
# https://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+
import contextlib
16+
import os
17+
from typing import Iterator
18+
19+
from flask import Flask, Response, request
20+
from opentelemetry.exporter.cloud_trace import CloudTraceSpanExporter
21+
from opentelemetry.sdk.trace import TracerProvider
22+
from opentelemetry.sdk.trace.export import BatchSpanProcessor
23+
from opentelemetry.sdk.trace.sampling import ALWAYS_ON
24+
from opentelemetry.trace import Tracer
25+
26+
TEST_ID = "test-id"
27+
INSTRUMENTING_MODULE_NAME = "opentelemetry-ops-e2e-test-server"
28+
29+
app = Flask(__name__)
30+
31+
32+
@contextlib.contextmanager
33+
def common_setup() -> Iterator[tuple[str, Tracer]]:
34+
"""\
35+
Context manager with common setup for test endpoints
36+
37+
It extracts the test-id header, creates a tracer, and finally flushes
38+
spans created during the test
39+
"""
40+
41+
if TEST_ID not in request.headers:
42+
raise Exception(f"{TEST_ID} header is required")
43+
test_id = request.headers[TEST_ID]
44+
45+
tracer_provider = TracerProvider(
46+
sampler=ALWAYS_ON,
47+
active_span_processor=BatchSpanProcessor(
48+
CloudTraceSpanExporter(project_id=os.environ.get("PROJECT_ID"))
49+
),
50+
)
51+
tracer = tracer_provider.get_tracer(INSTRUMENTING_MODULE_NAME)
52+
53+
try:
54+
yield test_id, tracer
55+
finally:
56+
tracer_provider.shutdown()
57+
58+
59+
@app.route("/health")
60+
def health():
61+
return "OK", 200
62+
63+
64+
@app.route("/basicTrace", methods=["POST"])
65+
def basicTrace():
66+
"""Create a basic trace"""
67+
68+
with common_setup() as (test_id, tracer):
69+
with tracer.start_span("basicTrace", attributes={TEST_ID: test_id}):
70+
pass
71+
72+
return Response(status=200)

0 commit comments

Comments
 (0)