Skip to content

Commit b53635e

Browse files
committed
ACLP Logs - stabilize integration tests - fix teardown
1 parent 0d07f53 commit b53635e

1 file changed

Lines changed: 66 additions & 20 deletions

File tree

test/integration/models/monitor/test_monitor_logs.py

Lines changed: 66 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
import pytest
1111

12-
from linode_api4 import LinodeClient, LogsStreamType, PaginatedList
12+
from linode_api4 import LinodeClient, LogsStreamType, PaginatedList, Region
1313
from linode_api4.objects import (
1414
ObjectStorageACL,
1515
ObjectStorageBucket,
@@ -28,12 +28,20 @@
2828
not in {"yes", "true"},
2929
reason=f"{_RUN_ACLP_LOGS_STREAM_TESTS} environment variable must be set to 'yes' or 'true'",
3030
)
31+
_STREAM_FIXTURE_CLEANUP_WAIT = 2700
32+
_STREAM_FIXTURE_PROVISIONING_WAIT = 3600
3133

3234

3335
@pytest.fixture(scope="session")
34-
def create_object_storage_key(test_linode_client: LinodeClient):
36+
def region(test_linode_client: LinodeClient):
37+
region = get_region(test_linode_client, {"Object Storage"})
38+
yield region
39+
40+
41+
@pytest.fixture(scope="session")
42+
def create_object_storage_key(test_linode_client: LinodeClient, region: Region):
3543
key = test_linode_client.object_storage.keys_create(
36-
label=get_test_label(),
44+
label=get_test_label(), regions=[region.id]
3745
)
3846
yield key
3947
key.delete()
@@ -43,19 +51,19 @@ def create_object_storage_key(test_linode_client: LinodeClient):
4351
def test_destination(
4452
test_linode_client: LinodeClient,
4553
create_object_storage_key: ObjectStorageKeys,
54+
region: Region,
4655
):
4756
dest, bucket = _create_destination_with_bucket(
48-
test_linode_client, create_object_storage_key
57+
test_linode_client, create_object_storage_key, region
4958
)
5059
yield dest
5160
_delete_destination_with_bucket(test_linode_client, dest, bucket)
5261

5362

5463
def _create_destination_with_bucket(
55-
client: LinodeClient, key: ObjectStorageKeys
64+
client: LinodeClient, key: ObjectStorageKeys, region: Region
5665
):
5766
"""Helper that creates an OBJ bucket and a logs destination backed by it."""
58-
region = get_region(client, {"Object Storage"})
5967
bucket = client.object_storage.bucket_create(
6068
cluster_or_region=region.id,
6169
label=get_test_label(),
@@ -79,9 +87,17 @@ def _delete_destination_with_bucket(
7987
client: LinodeClient, dest: LogsDestination, bucket: ObjectStorageBucket
8088
):
8189
"""Helper that deletes a logs destination and its backing OBJ bucket."""
82-
send_request_when_resource_available(timeout=1800, func=dest.delete)
90+
91+
def no_stream_attached():
92+
streams = client.monitor.streams()
93+
return all(
94+
all(d.id != dest.id for d in s.destinations) for s in streams
95+
)
96+
97+
wait_for_condition(30, _STREAM_FIXTURE_CLEANUP_WAIT, no_stream_attached)
98+
send_request_when_resource_available(timeout=100, func=dest.delete)
8399
_empty_bucket(client, bucket)
84-
send_request_when_resource_available(timeout=1800, func=bucket.delete)
100+
send_request_when_resource_available(timeout=100, func=bucket.delete)
85101

86102

87103
def _skip_if_streams_exist(client: LinodeClient):
@@ -304,9 +320,10 @@ def test_fails_to_create_stream_invalid_destination(invalid_destination_error):
304320
def create_secondary_destination(
305321
test_linode_client: LinodeClient,
306322
create_object_storage_key: ObjectStorageKeys,
323+
region: Region,
307324
):
308325
dest, bucket = _create_destination_with_bucket(
309-
test_linode_client, create_object_storage_key
326+
test_linode_client, create_object_storage_key, region
310327
)
311328
yield dest
312329
_delete_destination_with_bucket(test_linode_client, dest, bucket)
@@ -317,6 +334,7 @@ def create_stream(
317334
test_linode_client: LinodeClient,
318335
test_destination: LogsDestination,
319336
invalid_destination_error, # This ensures run order to keep negative test case deterministic
337+
create_secondary_destination: LogsDestination, # This ensures teardown order - stream must be deleted before its destinations can be deleted
320338
):
321339
_skip_if_streams_exist(test_linode_client)
322340

@@ -328,7 +346,41 @@ def create_stream(
328346
assert stream.id is not None
329347
assert stream.status == LogsStreamStatus.provisioning
330348
yield stream
331-
send_request_when_resource_available(timeout=1800, func=stream.delete)
349+
_stream_teardown(test_linode_client, stream)
350+
351+
352+
def _wait_for_stream_updatable(client: LinodeClient, stream_id: int):
353+
"""
354+
Blocks until the stream with the given id reaches active or inactive status.
355+
Updating destinations or other attributes puts the stream
356+
back into a transitional state, and attempting to delete or modify it while
357+
transitioning results in [400] errors.
358+
"""
359+
360+
def is_stream_updatable():
361+
stream = client.load(LogsStream, stream_id)
362+
return stream.status in (
363+
LogsStreamStatus.active,
364+
LogsStreamStatus.inactive,
365+
)
366+
367+
wait_for_condition(
368+
30, _STREAM_FIXTURE_PROVISIONING_WAIT, is_stream_updatable
369+
)
370+
371+
372+
def _stream_teardown(test_linode_client: LinodeClient, stream: LogsStream):
373+
_wait_for_stream_updatable(test_linode_client, stream.id)
374+
send_request_when_resource_available(timeout=100, func=stream.delete)
375+
376+
# The delete request returns 200 but stream deletion is async on the backend.
377+
# Wait until the stream is fully gone before teardown continues, so that
378+
# dependent fixtures (e.g. create_secondary_destination) can proceed with teardown.
379+
def is_stream_deleted():
380+
existing = test_linode_client.monitor.streams()
381+
return all(s.id != stream.id for s in existing)
382+
383+
wait_for_condition(30, _STREAM_FIXTURE_CLEANUP_WAIT, is_stream_deleted)
332384

333385

334386
@pytest.fixture(scope="session")
@@ -347,7 +399,9 @@ def is_stream_provisioned():
347399
LogsStreamStatus.inactive,
348400
)
349401

350-
wait_for_condition(60, 3600, is_stream_provisioned)
402+
wait_for_condition(
403+
60, _STREAM_FIXTURE_PROVISIONING_WAIT, is_stream_provisioned
404+
)
351405

352406
yield test_linode_client.load(LogsStream, create_stream.id)
353407

@@ -360,15 +414,7 @@ def wait_for_updatable_status(
360414
Waits for the stream to be in an active or inactive state before a test runs.
361415
Streams can switch to `provisioning` state between updates. This makes sure the previous update is fully finished.
362416
"""
363-
364-
def is_stream_updatable():
365-
stream = test_linode_client.load(LogsStream, provisioned_stream.id)
366-
return stream.status in (
367-
LogsStreamStatus.active,
368-
LogsStreamStatus.inactive,
369-
)
370-
371-
wait_for_condition(30, 3600, is_stream_updatable)
417+
_wait_for_stream_updatable(test_linode_client, provisioned_stream.id)
372418

373419

374420
@_SKIP_STREAM_TESTS

0 commit comments

Comments
 (0)