Skip to content

Investigate CI analytics pollution #12671

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 18 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion .github/workflows/aws-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ jobs:
# add the GitHub API token to avoid rate limit issues
GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DEBUG: 1
DISABLE_EVENTS: 1
TEST_PATH: "tests/unit"
JUNIT_REPORTS_FILE: "pytest-junit-unit.xml"
PYTEST_ARGS: "${{ env.TINYBIRD_PYTEST_ARGS }} -o junit_suite_name=unit-tests"
Expand Down Expand Up @@ -365,6 +366,7 @@ jobs:
env:
# add the GitHub API token to avoid rate limit issues
GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DISABLE_EVENTS: 1
PYTEST_ARGS: "${{ env.TINYBIRD_PYTEST_ARGS }}${{ env.TESTSELECTION_PYTEST_ARGS }} --splits 4 --group ${{ matrix.group }} --store-durations --clean-durations --ignore=tests/unit/ --ignore=tests/bootstrap"
COVERAGE_FILE: "target/.coverage.integration-${{ env.PLATFORM }}-${{ matrix.group }}"
JUNIT_REPORTS_FILE: "target/pytest-junit-integration-${{ env.PLATFORM }}-${{ matrix.group }}.xml"
Expand Down Expand Up @@ -427,6 +429,9 @@ jobs:
env:
# add the GitHub API token to avoid rate limit issues
GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# TODO: Unify environment variable configuration such that we accept `LOCALSTACK_`-prefixed variables
# everywhere and not only within the Docker container as implemented in `bin/docker-entrypoint.sh`
LOCALSTACK_DISABLE_EVENTS: 1
TEST_PATH: "tests/bootstrap"
COVERAGE_FILE: ".coverage.bootstrap"
JUNIT_REPORTS_FILE: "pytest-junit-bootstrap.xml"
Expand Down Expand Up @@ -544,6 +549,7 @@ jobs:
# add the GitHub API token to avoid rate limit issues
GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DEBUG: 1
DISABLE_EVENTS: 1
LOCALSTACK_INTERNAL_TEST_COLLECT_METRIC: 1
PYTEST_ARGS: "${{ env.TINYBIRD_PYTEST_ARGS }}${{ env.TESTSELECTION_PYTEST_ARGS }} --reruns 3 -m acceptance_test -o junit_suite_name='acceptance_test'"
COVERAGE_FILE: "target/.coverage.acceptance-${{ env.PLATFORM }}"
Expand Down Expand Up @@ -625,6 +631,7 @@ jobs:
# add the GitHub API token to avoid rate limit issues
GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DEBUG: 1
DISABLE_EVENTS: 1
COVERAGE_FILE: ".coverage.cloudwatch_v1"
TEST_PATH: "tests/aws/services/cloudwatch/"
JUNIT_REPORTS_FILE: "pytest-junit-cloudwatch-v1.xml"
Expand Down Expand Up @@ -675,6 +682,7 @@ jobs:
# add the GitHub API token to avoid rate limit issues
GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
COVERAGE_FILE: ".coverage.dynamodb_v2"
DISABLE_EVENTS: 1
TEST_PATH: "tests/aws/services/dynamodb/ tests/aws/services/dynamodbstreams/ tests/aws/services/lambda_/event_source_mapping/test_lambda_integration_dynamodbstreams.py"
JUNIT_REPORTS_FILE: "pytest-junit-dynamodb-v2.xml"
PYTEST_ARGS: "${{ env.TINYBIRD_PYTEST_ARGS }} --reruns 3 -o junit_suite_name=dynamodb_v2"
Expand Down Expand Up @@ -724,6 +732,7 @@ jobs:
# add the GitHub API token to avoid rate limit issues
GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DEBUG: 1
DISABLE_EVENTS: 1
COVERAGE_FILE: ".coverage.events_v1"
TEST_PATH: "tests/aws/services/events/"
JUNIT_REPORTS_FILE: "pytest-junit-events-v1.xml"
Expand Down Expand Up @@ -774,6 +783,7 @@ jobs:
env:
# add the GitHub API token to avoid rate limit issues
GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DISABLE_EVENTS: 1
TEST_PATH: "tests/aws/services/cloudformation/v2"
PYTEST_ARGS: "${{ env.TINYBIRD_PYTEST_ARGS }} --reruns 3 -o junit_suite_name='cloudformation_v2'"
PROVIDER_OVERRIDE_CLOUDFORMATION: "engine-v2"
Expand Down Expand Up @@ -870,7 +880,7 @@ jobs:
env:
# add the GitHub API token to avoid rate limit issues
GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DISABLE_EVENTS: "1"
DISABLE_EVENTS: 1
DEBUG: 1
IMAGE_NAME: "localstack/localstack:latest"
run: |
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/tests-cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ jobs:
env:
PYTEST_ADDOPTS: "${{ env.TINYBIRD_PYTEST_ARGS }}-p no:localstack.testing.pytest.fixtures -p no:localstack_snapshot.pytest.snapshot -p no:localstack.testing.pytest.filters -p no:localstack.testing.pytest.fixture_conflicts -p no:localstack.testing.pytest.validation_tracking -p no:localstack.testing.pytest.path_filter -p no:tests.fixtures -p no:localstack.testing.pytest.stepfunctions.fixtures -p no:localstack.testing.pytest.cloudformation.fixtures -s"
TEST_PATH: "tests/cli/"
DISABLE_EVENTS: 1
run: make test

push-to-tinybird:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/tests-podman.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ jobs:
PYTEST_ARGS: "${{ env.TINYBIRD_PYTEST_ARGS }}"
TEST_PATH: "tests/integration/docker_utils"
DEBUG: "1"
DISABLE_EVENTS: 1
run: |
# determine path of podman socket
podmanSocket=$(podman system info --format json | jq -r '.host.remoteSocket.path')
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/tests-pro-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ jobs:
- name: Test Pro Startup
env:
DEBUG: 1
DISABLE_EVENTS: 1
DNS_ADDRESS: 0
LOCALSTACK_AUTH_TOKEN: "test"
working-directory: localstack-ext
Expand Down Expand Up @@ -330,9 +331,9 @@ jobs:
# add the GitHub API token to avoid rate limit issues
GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DEBUG: 1
DISABLE_EVENTS: 1
DISABLE_BOTO_RETRIES: 1
DNS_ADDRESS: 0
LAMBDA_EXECUTOR: "local"
LOCALSTACK_AUTH_TOKEN: "test"
AWS_SECRET_ACCESS_KEY: "test"
AWS_ACCESS_KEY_ID: "test"
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/tests-s3-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ jobs:
PYTEST_ARGS: "${{ env.TINYBIRD_PYTEST_ARGS }}-o junit_family=legacy --junitxml=target/pytest-junit-s3-image-${{ matrix.arch }}.xml"
TEST_PATH: "tests/aws/services/s3"
DEBUG: 1
DISABLE_EVENTS: 1
run: |
mkdir target
make docker-run-tests-s3-only
Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ PIP_CMD ?= pip3
TEST_PATH ?= .
TEST_EXEC ?= python -m
PYTEST_LOGLEVEL ?= warning
export DISABLE_EVENTS ?= 1 ## disable analytics events from being sent to the backend

uname_m := $(shell uname -m)
ifeq ($(uname_m),x86_64)
Expand Down Expand Up @@ -91,14 +92,14 @@ start: ## Manually start the local infrastructure for testing
($(VENV_RUN); exec bin/localstack start --host)

docker-run-tests: ## Initializes the test environment and runs the tests in a docker container
docker run -e LOCALSTACK_INTERNAL_TEST_COLLECT_METRIC=1 --entrypoint= -v `pwd`/.git:/opt/code/localstack/.git -v `pwd`/requirements-test.txt:/opt/code/localstack/requirements-test.txt -v `pwd`/.test_durations:/opt/code/localstack/.test_durations -v `pwd`/tests/:/opt/code/localstack/tests/ -v `pwd`/dist/:/opt/code/localstack/dist/ -v `pwd`/target/:/opt/code/localstack/target/ -v /var/run/docker.sock:/var/run/docker.sock -v /tmp/localstack:/var/lib/localstack \
docker run -e LOCALSTACK_INTERNAL_TEST_COLLECT_METRIC=1 -e DISABLE_EVENTS=$${DISABLE_EVENTS:-1} --entrypoint= -v `pwd`/.git:/opt/code/localstack/.git -v `pwd`/requirements-test.txt:/opt/code/localstack/requirements-test.txt -v `pwd`/.test_durations:/opt/code/localstack/.test_durations -v `pwd`/tests/:/opt/code/localstack/tests/ -v `pwd`/dist/:/opt/code/localstack/dist/ -v `pwd`/target/:/opt/code/localstack/target/ -v /var/run/docker.sock:/var/run/docker.sock -v /tmp/localstack:/var/lib/localstack \
$(IMAGE_NAME):$(DEFAULT_TAG) \
bash -c "make install-test && DEBUG=$(DEBUG) PYTEST_LOGLEVEL=$(PYTEST_LOGLEVEL) PYTEST_ARGS='$(PYTEST_ARGS)' COVERAGE_FILE='$(COVERAGE_FILE)' JUNIT_REPORTS_FILE=$(JUNIT_REPORTS_FILE) TEST_PATH='$(TEST_PATH)' LAMBDA_IGNORE_ARCHITECTURE=1 LAMBDA_INIT_POST_INVOKE_WAIT_MS=50 TINYBIRD_PYTEST_ARGS='$(TINYBIRD_PYTEST_ARGS)' TINYBIRD_DATASOURCE='$(TINYBIRD_DATASOURCE)' TINYBIRD_TOKEN='$(TINYBIRD_TOKEN)' TINYBIRD_URL='$(TINYBIRD_URL)' CI_REPOSITORY_NAME='$(CI_REPOSITORY_NAME)' CI_WORKFLOW_NAME='$(CI_WORKFLOW_NAME)' CI_COMMIT_BRANCH='$(CI_COMMIT_BRANCH)' CI_COMMIT_SHA='$(CI_COMMIT_SHA)' CI_JOB_URL='$(CI_JOB_URL)' CI_JOB_NAME='$(CI_JOB_NAME)' CI_JOB_ID='$(CI_JOB_ID)' CI='$(CI)' TEST_AWS_REGION_NAME='${TEST_AWS_REGION_NAME}' TEST_AWS_ACCESS_KEY_ID='${TEST_AWS_ACCESS_KEY_ID}' TEST_AWS_ACCOUNT_ID='${TEST_AWS_ACCOUNT_ID}' make test-coverage"

docker-run-tests-s3-only: ## Initializes the test environment and runs the tests in a docker container for the S3 only image
# TODO: We need node as it's a dependency of the InfraProvisioner at import time, remove when we do not need it anymore
# g++ is a workaround to fix the JPype1 compile error on ARM Linux "gcc: fatal error: cannot execute ‘cc1plus’" because the test dependencies include the runtime dependencies.
docker run -e LOCALSTACK_INTERNAL_TEST_COLLECT_METRIC=1 --entrypoint= -v `pwd`/.git:/opt/code/localstack/.git -v `pwd`/requirements-test.txt:/opt/code/localstack/requirements-test.txt -v `pwd`/tests/:/opt/code/localstack/tests/ -v `pwd`/target/:/opt/code/localstack/target/ -v /var/run/docker.sock:/var/run/docker.sock -v /tmp/localstack:/var/lib/localstack \
docker run -e LOCALSTACK_INTERNAL_TEST_COLLECT_METRIC=1 -e DISABLE_EVENTS=$${DISABLE_EVENTS:-1} --entrypoint= -v `pwd`/.git:/opt/code/localstack/.git -v `pwd`/requirements-test.txt:/opt/code/localstack/requirements-test.txt -v `pwd`/tests/:/opt/code/localstack/tests/ -v `pwd`/target/:/opt/code/localstack/target/ -v /var/run/docker.sock:/var/run/docker.sock -v /tmp/localstack:/var/lib/localstack \
$(IMAGE_NAME):$(DEFAULT_TAG) \
bash -c "apt-get update && apt-get install -y g++ git && make install-test && apt-get install -y --no-install-recommends gnupg && mkdir -p /etc/apt/keyrings && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && echo \"deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main\" > /etc/apt/sources.list.d/nodesource.list && apt-get update && apt-get install -y --no-install-recommends nodejs && DEBUG=$(DEBUG) PYTEST_LOGLEVEL=$(PYTEST_LOGLEVEL) PYTEST_ARGS='$(PYTEST_ARGS)' TEST_PATH='$(TEST_PATH)' TINYBIRD_PYTEST_ARGS='$(TINYBIRD_PYTEST_ARGS)' TINYBIRD_DATASOURCE='$(TINYBIRD_DATASOURCE)' TINYBIRD_TOKEN='$(TINYBIRD_TOKEN)' TINYBIRD_URL='$(TINYBIRD_URL)' CI_COMMIT_BRANCH='$(CI_COMMIT_BRANCH)' CI_COMMIT_SHA='$(CI_COMMIT_SHA)' CI_JOB_URL='$(CI_JOB_URL)' CI_JOB_NAME='$(CI_JOB_NAME)' CI_JOB_ID='$(CI_JOB_ID)' CI='$(CI)' make test"

Expand Down
4 changes: 3 additions & 1 deletion localstack-core/localstack/services/sns/analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
Usage analytics for SNS internal endpoints
"""

from localstack.utils.analytics.metrics import LabeledCounter
from localstack.utils.analytics.metrics import Counter, LabeledCounter

# number of times SNS internal endpoint per resource types
# (e.g. PlatformMessage invoked 10x times, SMSMessage invoked 3x times, SubscriptionToken...)
internal_api_calls = LabeledCounter(
namespace="sns", name="internal_api_call", labels=["resource_type"]
)

test_counter = Counter(namespace="test", name="test_ci_pollution")
3 changes: 2 additions & 1 deletion localstack-core/localstack/services/sns/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
from localstack.utils.collections import PaginatedList, select_from_typed_dict
from localstack.utils.strings import short_uid, to_bytes, to_str

from .analytics import internal_api_calls
from .analytics import internal_api_calls, test_counter

# set up logger
LOG = logging.getLogger(__name__)
Expand Down Expand Up @@ -870,6 +870,7 @@ def create_topic(
data_protection_policy: attributeValue = None,
**kwargs,
) -> CreateTopicResponse:
test_counter.increment()
moto_response = call_moto(context)
store = self.get_store(account_id=context.account_id, region_name=context.region)
topic_arn = moto_response["TopicArn"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ def publish_metrics() -> None:
return

collected_metrics = MetricRegistry().collect()
# TODO: remove intentional debug exception used to expose places where metrics are sent unintentionally
raise Exception(f"METRICS_WOULD_BE_PUBLISHED_BUT_SHOULD_NOT. Metrics: {collected_metrics}") # noqa

if not collected_metrics.payload: # Skip publishing if no metrics remain after filtering
return

Expand Down
2 changes: 1 addition & 1 deletion localstack-core/localstack/utils/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ def config_env_vars(cfg: ContainerConfiguration):
# Show a deprecation warning for each individual env var collected above
LOG.warning(
"Non-prefixed environment variable %(env_var)s is forwarded to the LocalStack container! "
"Please use `LOCALSTACK_%(env_var)s` instead of %(env_var)s to explicitly mark this environment variable to be forwarded form the CLI to the LocalStack Runtime.",
"Please use `LOCALSTACK_%(env_var)s` instead of %(env_var)s to explicitly mark this environment variable to be forwarded from the CLI to the LocalStack Runtime.",
{"env_var": non_prefixed_env_var},
)

Expand Down
6 changes: 6 additions & 0 deletions tests/bootstrap/test_container_configurators.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ def test_container_configurator_no_deprecation_warning_on_prefix(
# set non-prefixed well-known environment variable on the mocked OS env
monkeypatch.setenv("LOCALSTACK_SERVICES", "1")

# delete non-prefixed analytic events variable, which gets picked up automatically from the default Makefile config
monkeypatch.delenv("DISABLE_EVENTS", False)

container: Container = container_factory()
configure_container(container)

Expand All @@ -197,6 +200,9 @@ def test_container_configurator_no_deprecation_warning_for_ci_env_var(
# set the "CI" env var indicating that we are running in a CI environment
monkeypatch.setenv("CI", "1")

# delete non-prefixed analytic events variable, which gets picked up automatically from the default Makefile config
monkeypatch.delenv("DISABLE_EVENTS", False)

container: Container = container_factory()
configure_container(container)

Expand Down
2 changes: 2 additions & 0 deletions tests/unit/cli/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ def test_validate_config_syntax_error(runner, monkeypatch, tmp_path):
assert "Error" in result.output


# TODO: temporarily skip to trigger other CI builds during CI analytics pollution investigation
@pytest.mark.skip
@pytest.mark.parametrize(
"cli_input,expected_cmd,expected_params",
[
Expand Down
Loading