Skip to content

Commit

Permalink
chore(test): Improve tests
Browse files Browse the repository at this point in the history
  • Loading branch information
alithethird committed Jan 17, 2025
1 parent cdb1902 commit f7e9645
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 12 deletions.
6 changes: 1 addition & 5 deletions .trivyignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
# ignore CVE introduced by python3-gunicorn
CVE-2022-40897
# pypa/setuptools: Remote code execution via download
CVE-2024-6345
# pebble: Calling Decoder.Decode on a message which contains deeply nested structures can cause a panic due to stack exhaustion
CVE-2024-34156
# pebble: Go stdlib
CVE-2024-45338
# go-app: Go crypto lib
CVE-2024-45337
CVE-2024-45337
6 changes: 3 additions & 3 deletions tests/integration/integrations/test_tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,19 @@


@pytest.mark.parametrize(
"tracing_app, port",
"tracing_app_fixture, port",
[
("flask_tracing_app", 8000),
("django_tracing_app", 8000),
("fastapi_tracing_app", 8080),
("go_tracing_app", 8080),
],
indirect=["tracing_app"],
)
@pytest.mark.skip_juju_version("3.4") # Tempo only supports Juju>=3.4
async def test_workload_tracing(
ops_test: OpsTest,
model: Model,
tracing_app: Application,
tracing_app_fixture: str,
port: int,
request: pytest.FixtureRequest,
get_unit_ips,
Expand All @@ -49,6 +48,7 @@ async def test_workload_tracing(
except Exception as e:
logger.info(f"Tempo is already deployed {e}")

tracing_app = request.getfixturevalue(tracing_app_fixture)
idle_list = [tracing_app.name]

if tracing_app.name != "flask-tracing-k8s":
Expand Down
27 changes: 27 additions & 0 deletions tests/unit/flask/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,33 @@
}
}

LAYER_WITH_TRACING = {
"services": {
"flask": {
"override": "replace",
"startup": "enabled",
"command": f"/bin/python3 -m gunicorn -c /flask/gunicorn.conf.py app:app -k sync",
"after": ["statsd-exporter"],
"user": "_daemon_",
"environment": {
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://test-ip:4318",
"OTEL_SERVICE_NAME": "flask-k8s",
},
},
"statsd-exporter": {
"override": "merge",
"command": (
"/bin/statsd_exporter --statsd.mapping-config=/statsd-mapping.conf "
"--statsd.listen-udp=localhost:9125 "
"--statsd.listen-tcp=localhost:9125"
),
"summary": "statsd exporter service",
"startup": "enabled",
"user": "_daemon_",
},
}
}

LAYER_WITH_WORKER = {
"services": {
"flask": {
Expand Down
19 changes: 19 additions & 0 deletions tests/unit/flask/test_tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,22 @@ def test_tracing_relation(harness: Harness):
service_env = container.get_plan().services["flask"].environment
assert service_env["OTEL_EXPORTER_OTLP_ENDPOINT"] == "http://test-ip:4318"
assert service_env["OTEL_SERVICE_NAME"] == "flask-k8s"


def test_tracing_not_activated(harness: Harness):
"""
arrange: Deploy the charm without a relation to the Tempo charm.
act: Run all initial hooks.
assert: The flask service should not have the environment variables OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_SERVICE_NAME.
"""
harness.set_model_name("flask-model")

container = harness.model.unit.get_container(FLASK_CONTAINER_NAME)
container.add_layer("a_layer", DEFAULT_LAYER)

harness.begin_with_initial_hooks()

assert harness.model.unit.status == ops.ActiveStatus()
service_env = container.get_plan().services["flask"].environment
assert service_env.get("OTEL_EXPORTER_OTLP_ENDPOINT", None) is None
assert service_env.get("OTEL_SERVICE_NAME", None) is None
39 changes: 35 additions & 4 deletions tests/unit/flask/test_webserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@
from paas_charm.charm_state import CharmState
from paas_charm.utils import enable_pebble_log_forwarding

from .constants import DEFAULT_LAYER, FLASK_CONTAINER_NAME
from .constants import DEFAULT_LAYER, FLASK_CONTAINER_NAME, LAYER_WITH_TRACING

GUNICORN_CONFIG_TEST_PARAMS = [
pytest.param(
{"workers": 10},
DEFAULT_LAYER,
textwrap.dedent(
f"""\
bind = ['0.0.0.0:8000']
Expand All @@ -37,6 +38,7 @@
),
pytest.param(
{"threads": 2, "timeout": 3, "keepalive": 4},
DEFAULT_LAYER,
textwrap.dedent(
f"""\
bind = ['0.0.0.0:8000']
Expand All @@ -50,12 +52,41 @@
),
id="threads=2,timeout=3,keepalive=4",
),
pytest.param(
{},
LAYER_WITH_TRACING,
textwrap.dedent(
f"""\
bind = ['0.0.0.0:8000']
chdir = '/flask/app'
accesslog = '/var/log/flask/access.log'
errorlog = '/var/log/flask/error.log'
statsd_host = 'localhost:9125'
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import (
OTLPSpanExporter,
)
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
def post_fork(server, worker):
trace.set_tracer_provider(TracerProvider())
span_processor = BatchSpanProcessor(OTLPSpanExporter())
trace.get_tracer_provider().add_span_processor(span_processor)
"""
),
id="with-tracing",
),
]


@pytest.mark.parametrize("charm_state_params, config_file", GUNICORN_CONFIG_TEST_PARAMS)
@pytest.mark.parametrize("charm_state_params, layer, config_file", GUNICORN_CONFIG_TEST_PARAMS)
def test_gunicorn_config(
harness: Harness, charm_state_params, config_file, database_migration_mock
harness: Harness,
charm_state_params,
layer,
config_file,
database_migration_mock,
) -> None:
"""
arrange: create the Gunicorn webserver object with a controlled charm state generated by the
Expand All @@ -66,7 +97,7 @@ def test_gunicorn_config(
harness.begin()
container: ops.Container = harness.model.unit.get_container(FLASK_CONTAINER_NAME)
harness.set_can_connect(FLASK_CONTAINER_NAME, True)
container.add_layer("default", DEFAULT_LAYER)
container.add_layer("default", layer)

charm_state = CharmState(
framework="flask",
Expand Down

0 comments on commit f7e9645

Please sign in to comment.