Skip to content

Commit

Permalink
test: fastapi tests running locally,
Browse files Browse the repository at this point in the history
reduced external dependencies,
removed duplicate test
  • Loading branch information
therightstuff committed Oct 12, 2023
1 parent 6a05ffc commit 260b5b7
Show file tree
Hide file tree
Showing 11 changed files with 85 additions and 121 deletions.
37 changes: 0 additions & 37 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,50 +382,13 @@ def integration_tests_fastapi(

@nox.session(python=python_versions())
def component_tests(session):
component_tests_attr_max_size(
session=session,
fastapi_version="0.78.0", # arbitrary version
uvicorn_version="0.16.0", # TODO don't update, see https://lumigo.atlassian.net/browse/RD-11466
)
component_tests_execution_tags(
session=session,
fastapi_version="0.78.0", # arbitrary version
uvicorn_version="0.16.0", # TODO don't update, see https://lumigo.atlassian.net/browse/RD-11466
)


def component_tests_attr_max_size(
session,
fastapi_version,
uvicorn_version,
):
install_package("uvicorn", uvicorn_version, session)
install_package("fastapi", fastapi_version, session)

session.install(".")

temp_file = create_component_tempfile("attr_max_size")
with session.chdir("src/test/components"):
session.install("-r", OTHER_REQUIREMENTS)

try:
session.run(
"pytest",
"--tb",
"native",
"--log-cli-level=INFO",
"--color=yes",
"-v",
"./tests/test_attr_max_size.py",
env={
"LUMIGO_DEBUG_SPANDUMP": temp_file,
"OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT": "1",
},
)
finally:
clean_outputs(temp_file, session)


def component_tests_execution_tags(
session,
fastapi_version,
Expand Down
15 changes: 15 additions & 0 deletions src/test/components/start_uvicorn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import argparse
import uvicorn


def serve(app, port):
"""Serve the web application."""
uvicorn.run(app, port=port)


if __name__ == "__main__":
argParser = argparse.ArgumentParser()
argParser.add_argument("--app", help="app name")
argParser.add_argument("--port", type=int, help="port number")
args = argParser.parse_args()
serve(args.app, args.port)
16 changes: 5 additions & 11 deletions src/test/components/tests/app_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from test.test_utils.processes import kill_process


class FastApiSample(object):
def __init__(self):
class FastApiApp(object):
def __init__(self, app: str, port: int):
cwd = Path(__file__).parent.parent
print(f"cwd = {cwd}")
env = {
Expand All @@ -16,19 +16,13 @@ def __init__(self):
"OTEL_SERVICE_NAME": "fastapi_test_app",
}
print(f"env = {env}")
venv_bin_path = Path(sys.executable).parent
print(f"venv_bin_path = {venv_bin_path}")
cmd = (
f". {venv_bin_path}/activate;"
"uvicorn fastapi_external_apis.app:app --port 8021 &"
"uvicorn app:app --port 8020 &"
)
print(f"venv bin path = {Path(sys.executable).parent}")
cmd = [sys.executable, "start_uvicorn.py", "--app", app, "--port", str(port)]
print(f"cmd = {cmd}")
self.process = subprocess.Popen(
cmd,
cwd=cwd,
env=env,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
Expand All @@ -39,7 +33,7 @@ def __init__(self):
is_app_running = True
break
if not is_app_running:
raise Exception("FastApiSample app failed to start")
raise Exception(f"FastApiApp app '{app}' failed to start on port {port}")

def __enter__(self):
return self
Expand Down
44 changes: 0 additions & 44 deletions src/test/components/tests/test_attr_max_size.py

This file was deleted.

11 changes: 8 additions & 3 deletions src/test/components/tests/test_execution_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@

import requests

from .app_runner import FastApiSample
from .app_runner import FastApiApp

APP_PORT = 8020
EXTERNAL_APP_PORT = 8021


class TestExecutionTags(unittest.TestCase):
def test_execution_tag(self):
with FastApiSample():
response = requests.get("http://localhost:8020/invoke-request")
with FastApiApp("app:app", APP_PORT), FastApiApp(
"fastapi_external_apis.app:app", EXTERNAL_APP_PORT
):
response = requests.get(f"http://localhost:{APP_PORT}/invoke-request")
response.raise_for_status()

body = response.json()
Expand Down
6 changes: 2 additions & 4 deletions src/test/integration/fastapi/app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,13 @@ async def root():

@app.get("/invoke-requests")
def invoke_requests():
response = requests.get("https://api.chucknorris.io/jokes/random")
response = requests.get("http://localhost:8021/little-response")
return response.json()


@app.get("/invoke-requests-large-response")
def invoke_requests_big_response():
response = requests.get(
"http://universities.hipolabs.com/search?country=United+States"
)
response = requests.get("http://localhost:8021/big-response")
response.raise_for_status()
return response.json()

Expand Down
Empty file.
16 changes: 16 additions & 0 deletions src/test/integration/fastapi/fastapi_external_apis/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from fastapi import FastAPI, Request

app = FastAPI()


@app.get("/big-response")
def get_big_response():
return {"data": "a" * 10_000}


@app.get("/little-response")
def get_little_response(request: Request):
return {
"url": str(request.url),
"data": "a" * 100
}
11 changes: 8 additions & 3 deletions src/test/integration/fastapi/start_uvicorn.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import argparse
import uvicorn


def serve():
def serve(app, port):
"""Serve the web application."""
uvicorn.run("app:app", port=8000)
uvicorn.run(app, port=port)


if __name__ == "__main__":
serve()
argParser = argparse.ArgumentParser()
argParser.add_argument("--app", help="app name")
argParser.add_argument("--port", type=int, help="port number")
args = argParser.parse_args()
serve(args.app, args.port)
12 changes: 6 additions & 6 deletions src/test/integration/fastapi/tests/app_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from test.test_utils.processes import kill_process


class FastApiSample(object):
def __init__(self):
class FastApiApp(object):
def __init__(self, app: str, port: int):
cwd = Path(__file__).parent.parent
print(f"cwd = {cwd}")
env = {
Expand All @@ -16,7 +16,8 @@ def __init__(self):
"OTEL_SERVICE_NAME": "fastapi_test_app",
}
print(f"env = {env}")
cmd = [sys.executable, "start_uvicorn.py"]
print(f"venv bin path = {Path(sys.executable).parent}")
cmd = [sys.executable, "start_uvicorn.py", "--app", app, "--port", str(port)]
print(f"cmd = {cmd}")
self.process = subprocess.Popen(
cmd,
Expand All @@ -27,13 +28,12 @@ def __init__(self):
)
is_app_running = False
for line in self.process.stderr:
print(line)
if "Uvicorn running" in str(line):
print(f"FastApiSample app: {line}")
is_app_running = True
break
print(line)
if not is_app_running:
raise Exception("FastApiSample app failed to start")
raise Exception(f"FastApiApp app '{app}' failed to start on port {port}")

def __enter__(self):
return self
Expand Down
38 changes: 25 additions & 13 deletions src/test/integration/fastapi/tests/test_fastapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@

import requests

from .app_runner import FastApiSample
from .app_runner import FastApiApp

APP_PORT = 8020
EXTERNAL_APP_PORT = 8021


class TestFastApiSpans(unittest.TestCase):
def test_200_OK(self):
with FastApiSample():
response = requests.get("http://localhost:8000/")
with FastApiApp("app:app", APP_PORT):
response = requests.get(f"http://localhost:{APP_PORT}/")
response.raise_for_status()

body = response.json()
Expand All @@ -27,7 +30,9 @@ def test_200_OK(self):
self.assertEqual(root["kind"], "SpanKind.SERVER")
self.assertEqual(root["attributes"]["http.status_code"], 200)
self.assertEqual(root["attributes"]["http.method"], "GET")
self.assertEqual(root["attributes"]["http.url"], "http://127.0.0.1:8000/")
self.assertEqual(
root["attributes"]["http.url"], f"http://127.0.0.1:{APP_PORT}/"
)

# assert internal spans
internals = spans_container.get_internals()
Expand All @@ -44,13 +49,17 @@ def test_200_OK(self):
)

def test_requests_instrumentation(self):
with FastApiSample():
response = requests.get("http://localhost:8000/invoke-requests")
with FastApiApp("app:app", APP_PORT), FastApiApp(
"fastapi_external_apis.app:app", EXTERNAL_APP_PORT
):
response = requests.get(f"http://localhost:{APP_PORT}/invoke-requests")
response.raise_for_status()

body = response.json()

self.assertIn("https://api.chucknorris.io/jokes/", body["url"])
expected_url = f"http://localhost:{EXTERNAL_APP_PORT}/little-response"

self.assertIn(expected_url, body["url"])

spans_container = SpansContainer.get_spans_from_file(
wait_time_sec=10, expected_span_count=4
Expand All @@ -64,7 +73,8 @@ def test_requests_instrumentation(self):
self.assertEqual(root["attributes"]["http.status_code"], 200)
self.assertIsNotNone(root["attributes"]["http.request.headers"])
self.assertEqual(
root["attributes"]["http.url"], "http://127.0.0.1:8000/invoke-requests"
root["attributes"]["http.url"],
f"http://127.0.0.1:{APP_PORT}/invoke-requests",
)

# assert external request span
Expand All @@ -74,7 +84,7 @@ def test_requests_instrumentation(self):
self.assertEqual(external_request_span["attributes"]["http.method"], "GET")
self.assertEqual(
external_request_span["attributes"]["http.url"],
"https://api.chucknorris.io/jokes/random",
expected_url,
)
self.assertEqual(
external_request_span["attributes"]["http.status_code"], 200
Expand Down Expand Up @@ -102,9 +112,11 @@ def test_requests_instrumentation(self):
)

def test_large_span_attribute_size_default_max_size(self):
with FastApiSample():
with FastApiApp("app:app", APP_PORT), FastApiApp(
"fastapi_external_apis.app:app", EXTERNAL_APP_PORT
):
response = requests.get(
"http://localhost:8000/invoke-requests-large-response"
f"http://localhost:{APP_PORT}/invoke-requests-large-response"
)
response.raise_for_status()

Expand All @@ -124,7 +136,7 @@ def test_large_span_attribute_size_default_max_size(self):
self.assertEqual(root_attributes["http.status_code"], 200)
self.assertEqual(
root_attributes["http.url"],
"http://127.0.0.1:8000/invoke-requests-large-response",
f"http://127.0.0.1:{APP_PORT}/invoke-requests-large-response",
)
self.assertEqual(root_attributes["http.method"], "GET")

Expand All @@ -135,7 +147,7 @@ def test_large_span_attribute_size_default_max_size(self):
self.assertEqual(external_request_span["attributes"]["http.method"], "GET")
self.assertEqual(
external_request_span["attributes"]["http.url"],
"http://universities.hipolabs.com/search?country=United+States",
f"http://localhost:{EXTERNAL_APP_PORT}/big-response",
)
self.assertEqual(
external_request_span["attributes"]["http.status_code"], 200
Expand Down

0 comments on commit 260b5b7

Please sign in to comment.