-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
re-introduce eager service loading #12657
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
import pytest | ||
import requests | ||
from botocore.exceptions import ClientError | ||
|
||
from localstack.config import in_docker | ||
from localstack.testing.pytest.container import ContainerFactory | ||
from localstack.utils.bootstrap import ContainerConfigurators, get_gateway_url | ||
|
||
pytestmarks = pytest.mark.skipif( | ||
condition=in_docker(), reason="cannot run bootstrap tests in docker" | ||
) | ||
|
||
|
||
def test_strict_service_loading( | ||
container_factory: ContainerFactory, | ||
wait_for_localstack_ready, | ||
aws_client_factory, | ||
): | ||
ls_container = container_factory( | ||
configurators=[ | ||
ContainerConfigurators.random_container_name, | ||
ContainerConfigurators.random_gateway_port, | ||
ContainerConfigurators.random_service_port_range(20), | ||
ContainerConfigurators.env_vars( | ||
{"STRICT_SERVICE_LOADING": "1", "SERVICES": "s3,sqs,sns"} | ||
), | ||
] | ||
) | ||
running_container = ls_container.start() | ||
wait_for_localstack_ready(running_container) | ||
url = get_gateway_url(ls_container) | ||
|
||
# check service-status returned by health endpoint | ||
response = requests.get(f"{url}/_localstack/health") | ||
assert response.ok | ||
|
||
services = response.json().get("services") | ||
|
||
assert services.pop("sqs") == "available" | ||
assert services.pop("s3") == "available" | ||
assert services.pop("sns") == "available" | ||
|
||
assert services | ||
assert all(services.get(key) == "disabled" for key in services.keys()) | ||
|
||
# activate sqs service | ||
client = aws_client_factory(endpoint_url=url) | ||
result = client.sqs.list_queues() | ||
assert result | ||
|
||
# verify cloudwatch is not activated | ||
with pytest.raises(ClientError) as e: | ||
client.cloudwatch.list_metrics() | ||
|
||
e.match( | ||
"Service 'cloudwatch' is not enabled. Please check your 'SERVICES' configuration variable." | ||
) | ||
assert e.value.response["ResponseMetadata"]["HTTPStatusCode"] == 501 | ||
|
||
# check status again | ||
response = requests.get(f"{url}/_localstack/health") | ||
assert response.ok | ||
|
||
services = response.json().get("services") | ||
|
||
# sqs should be running now | ||
assert services.get("sqs") == "running" | ||
assert services.get("s3") == "available" | ||
assert services.get("sns") == "available" | ||
assert services.get("cloudwatch") == "disabled" | ||
|
||
|
||
def test_eager_service_loading( | ||
container_factory: ContainerFactory, | ||
wait_for_localstack_ready, | ||
aws_client_factory, | ||
): | ||
ls_container = container_factory( | ||
configurators=[ | ||
ContainerConfigurators.random_container_name, | ||
ContainerConfigurators.random_gateway_port, | ||
ContainerConfigurators.random_service_port_range(20), | ||
ContainerConfigurators.env_vars( | ||
{"EAGER_SERVICE_LOADING": "1", "SERVICES": "s3,sqs,sns"} | ||
), | ||
] | ||
) | ||
running_container = ls_container.start() | ||
wait_for_localstack_ready(running_container) | ||
url = get_gateway_url(ls_container) | ||
|
||
# check service-status returned by health endpoint | ||
response = requests.get(f"{url}/_localstack/health") | ||
assert response.ok | ||
|
||
services = response.json().get("services") | ||
|
||
assert services.pop("sqs") == "running" | ||
assert services.pop("s3") == "running" | ||
assert services.pop("sns") == "running" | ||
|
||
assert services | ||
assert all(services.get(key) == "disabled" for key in services.keys()) | ||
|
||
|
||
def test_eager_and_strict_service_loading( | ||
container_factory: ContainerFactory, | ||
wait_for_localstack_ready, | ||
aws_client_factory, | ||
): | ||
# this is undocumented behavior, to allow eager loading of specific services while not restricting services loading | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI I arrived at this PR because I was specifically trying to figure out how to eager load specific services in a specific order without loading everything or preventing services from ever being enabled. Lucky issue searching turned up this PR. My use case is building integration tests that have isolated localstack containers and building/deploying images to ecr for lambda as well as spinning up RDS. I ended up getting tripped up because depending on whether RDS or ECR was started first, ECR might be 4510 or 4511. All that is to say, at least one person (me) finds this behavior useful and would appreciate the behavior being documented! Looking forward to see this PR land either way. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jeremygiberson please keep in mind though that we still don't technically guarantee that these port assignments would be deterministic. |
||
ls_container = container_factory( | ||
configurators=[ | ||
ContainerConfigurators.random_container_name, | ||
ContainerConfigurators.random_gateway_port, | ||
ContainerConfigurators.random_service_port_range(20), | ||
ContainerConfigurators.env_vars( | ||
{ | ||
"EAGER_SERVICE_LOADING": "1", | ||
"SERVICES": "s3,sqs,sns", | ||
"STRICT_SERVICE_LOADING": "0", | ||
} | ||
), | ||
] | ||
) | ||
running_container = ls_container.start() | ||
wait_for_localstack_ready(running_container) | ||
url = get_gateway_url(ls_container) | ||
|
||
# check service-status returned by health endpoint | ||
response = requests.get(f"{url}/_localstack/health") | ||
assert response.ok | ||
|
||
services = response.json().get("services") | ||
|
||
assert services.pop("sqs") == "running" | ||
assert services.pop("s3") == "running" | ||
assert services.pop("sns") == "running" | ||
|
||
assert services | ||
assert all(services.get(key) == "available" for key in services.keys()) |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice 👏 thanks for adding these.
Might also be good to add a case for
{"EAGER_SERVICE_LOADING": "0", "SERVICES": "s3,sqs,sns"}
just to make sure we have no regression there.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would be covered by the test above:
test_strict_service_loading
.STRICT_SERVICE_LOADING
is set to1
by default in LocalStack, andEAGER_SERVICE_LOADING
to 0.If something were to change with eager loading, I believe the test above would start failing as we're asserting that the services are
available
and notrunning
? But we could make that explicit as well, here we are depending on default values.