Skip to content

Commit fdcc03f

Browse files
authored
test: evaluate skipped tests, fix failing tests, add step in e2e workflow to mark build as failed (#351)
* update test_linode.py * evaluate skipped tests, add steps in e2e workflow, fix flaky tests * lint * fix flaky tests in lke and volume * add some safety wait until functions for reorder test * update test_delete_interface_containing_vpc, test_linode_initate_migration
1 parent 78e2de6 commit fdcc03f

File tree

5 files changed

+156
-90
lines changed

5 files changed

+156
-90
lines changed

.github/workflows/e2e-test-pr.yml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ jobs:
1919
runs-on: ubuntu-latest
2020
if:
2121
github.event_name == 'workflow_dispatch' && inputs.sha != ''
22+
env:
23+
EXIT_STATUS: 0
2224

2325
steps:
2426
- uses: actions-ecosystem/action-regex-match@v2
@@ -83,8 +85,8 @@ jobs:
8385
timestamp=$(date +'%Y%m%d%H%M')
8486
report_filename="${timestamp}_sdk_test_report.xml"
8587
status=0
86-
if ! python3 -m pytest test/integration/${INTEGRATION_TEST_PATH} --junitxml="${report_filename}"; then
87-
echo "Tests failed, but attempting to upload results anyway"
88+
if ! python3 -m pytest test/integration/${INTEGRATION_TEST_PATH} --disable-warnings --junitxml="${report_filename}"; then
89+
echo "EXIT_STATUS=1" >> $GITHUB_ENV
8890
fi
8991
env:
9092
LINODE_TOKEN: ${{ secrets.LINODE_TOKEN }}
@@ -135,4 +137,13 @@ jobs:
135137
status: 'completed',
136138
conclusion: process.env.conclusion
137139
});
138-
return result;
140+
return result;
141+
142+
- name: Test Execution Status Handler
143+
run: |
144+
if [[ "$EXIT_STATUS" != 0 ]]; then
145+
echo "Test execution contains failure(s)"
146+
exit $EXIT_STATUS
147+
else
148+
echo "Tests passed!"
149+
fi

test/integration/conftest.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,10 @@ def test_domain(test_linode_client):
155155
def test_volume(test_linode_client):
156156
client = test_linode_client
157157
timestamp = str(time.time_ns())
158+
region = client.regions()[0]
158159
label = "TestSDK-" + timestamp
159160

160-
volume = client.volume_create(
161-
label=label, region=get_region(client, {"Block Storage"})
162-
)
161+
volume = client.volume_create(label=label, region=region)
163162

164163
yield volume
165164

test/integration/helpers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def send_request_when_resource_available(
111111
if time.time() - start_time > timeout:
112112
raise TimeoutError(
113113
"Timeout Error: resource is not available in"
114-
+ timeout
114+
+ str(timeout)
115115
+ "seconds"
116116
)
117117
time.sleep(10)

test/integration/models/test_linode.py

Lines changed: 132 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from test.integration.helpers import (
33
get_test_label,
44
retry_sending_request,
5+
send_request_when_resource_available,
56
wait_for_condition,
67
)
78

@@ -65,6 +66,53 @@ def linode_with_volume_firewall(test_linode_client):
6566
linode_instance.delete()
6667

6768

69+
@pytest.fixture(scope="session")
70+
def linode_for_network_interface_tests(test_linode_client):
71+
client = test_linode_client
72+
available_regions = client.regions()
73+
chosen_region = available_regions[0]
74+
timestamp = str(time.time_ns())
75+
label = "TestSDK-" + timestamp
76+
77+
linode_instance, password = client.linode.instance_create(
78+
"g6-nanode-1", chosen_region, image="linode/debian10", label=label
79+
)
80+
81+
yield linode_instance
82+
83+
linode_instance.delete()
84+
85+
86+
@pytest.fixture(scope="session", autouse=True)
87+
def linode_for_disk_tests(test_linode_client):
88+
client = test_linode_client
89+
available_regions = client.regions()
90+
chosen_region = available_regions[0]
91+
label = get_test_label()
92+
93+
linode_instance, password = client.linode.instance_create(
94+
"g6-nanode-1",
95+
chosen_region,
96+
image="linode/debian10",
97+
label=label + "_long_tests",
98+
)
99+
100+
time.sleep(10)
101+
102+
# Provisioning time
103+
wait_for_condition(10, 300, get_status, linode_instance, "running")
104+
105+
time.sleep(10)
106+
107+
linode_instance.shutdown()
108+
109+
wait_for_condition(10, 100, get_status, linode_instance, "offline")
110+
111+
yield linode_instance
112+
113+
linode_instance.delete()
114+
115+
68116
@pytest.mark.smoke
69117
@pytest.fixture
70118
def create_linode_for_long_running_tests(test_linode_client):
@@ -289,22 +337,53 @@ def test_linode_volumes(linode_with_volume_firewall):
289337
assert "TestSDK" in volumes[0].label
290338

291339

292-
def test_linode_disk_duplicate(test_linode_client, create_linode):
293-
pytest.skip("Need to find out the space sizing when duplicating disks")
294-
linode = create_linode
340+
def wait_for_disk_status(disk: Disk, timeout):
341+
start_time = time.time()
342+
while True:
343+
try:
344+
if disk.status == "ready":
345+
return disk.status
346+
except ApiError:
347+
if time.time() - start_time > timeout:
348+
raise TimeoutError("Wait for condition timeout error")
349+
350+
351+
@pytest.mark.dependency()
352+
def test_disk_resize_and_duplicate(test_linode_client, linode_for_disk_tests):
353+
linode = linode_for_disk_tests
354+
355+
disk = linode.disks[0]
356+
357+
disk.resize(5000)
358+
359+
# Using hard sleep instead of wait as the status shows ready when it is resizing
360+
time.sleep(120)
295361

296362
disk = test_linode_client.load(Disk, linode.disks[0].id, linode.id)
297363

298-
try:
299-
dup_disk = disk.duplicate()
300-
assert dup_disk.linode_id == linode.id
301-
except ApiError as e:
302-
assert e.status == 400
303-
assert "Insufficient space" in str(e.json)
364+
assert disk.size == 5000
365+
366+
dup_disk = disk.duplicate()
367+
368+
time.sleep(40)
369+
370+
wait_for_disk_status(dup_disk, 120)
371+
372+
assert dup_disk.linode_id == linode.id
373+
374+
375+
@pytest.mark.dependency(depends=["test_disk_resize_and_duplicate"])
376+
def test_linode_create_disk(test_linode_client, linode_for_disk_tests):
377+
linode = test_linode_client.load(Instance, linode_for_disk_tests.id)
378+
379+
disk = linode.disk_create(size=500)
380+
381+
wait_for_disk_status(disk, 120)
382+
383+
assert disk.linode_id == linode.id
304384

305385

306386
def test_linode_instance_password(create_linode_for_pass_reset):
307-
pytest.skip("Failing due to mismatched request body")
308387
linode = create_linode_for_pass_reset[0]
309388
password = create_linode_for_pass_reset[1]
310389

@@ -343,25 +422,14 @@ def test_linode_initate_migration(test_linode_client):
343422

344423
wait_for_condition(10, 100, get_status, linode, "running")
345424
# Says it could take up to ~6 hrs for migration to fully complete
346-
linode.initiate_migration(region="us-central")
347425

348-
res = linode.delete()
349-
350-
assert res
351-
352-
353-
def test_linode_create_disk(create_linode):
354-
pytest.skip(
355-
"Pre-requisite for the test account need to comply with this test"
426+
send_request_when_resource_available(
427+
300, linode.initiate_migration, "us-central"
356428
)
357-
linode = create_linode
358-
disk, gen_pass = linode.disk_create()
359429

430+
res = linode.delete()
360431

361-
def test_disk_resize():
362-
pytest.skip(
363-
"Pre-requisite for the test account need to comply with this test"
364-
)
432+
assert res
365433

366434

367435
def test_config_update_interfaces(create_linode):
@@ -387,19 +455,9 @@ def test_config_update_interfaces(create_linode):
387455

388456

389457
def test_get_config(test_linode_client, create_linode):
390-
pytest.skip(
391-
"Model get method: client.load(Config, 123, 123) does not work..."
392-
)
393458
linode = create_linode
394-
json = test_linode_client.get(
395-
"linode/instances/"
396-
+ str(linode.id)
397-
+ "/configs/"
398-
+ str(linode.configs[0].id)
399-
)
400-
config = Config(
401-
test_linode_client, linode.id, linode.configs[0].id, json=json
402-
)
459+
460+
config = test_linode_client.load(Config, linode.configs[0].id, linode.id)
403461

404462
assert config.id == linode.configs[0].id
405463

@@ -429,18 +487,6 @@ def test_get_linode_types_overrides(test_linode_client):
429487
assert linode_type.region_prices[0].monthly >= 0
430488

431489

432-
def test_get_linode_type_by_id(test_linode_client):
433-
pytest.skip(
434-
"Might need Type to match how other object models are behaving e.g. client.load(Type, 123)"
435-
)
436-
437-
438-
def test_get_linode_type_gpu():
439-
pytest.skip(
440-
"Might need Type to match how other object models are behaving e.g. client.load(Type, 123)"
441-
)
442-
443-
444490
def test_save_linode_noforce(test_linode_client, create_linode):
445491
linode = create_linode
446492
old_label = linode.label
@@ -464,28 +510,29 @@ def test_save_linode_force(test_linode_client, create_linode):
464510

465511

466512
class TestNetworkInterface:
467-
def test_list(self, create_linode):
468-
linode = create_linode
513+
def test_list(self, linode_for_network_interface_tests):
514+
linode = linode_for_network_interface_tests
469515

470516
config: Config = linode.configs[0]
471517

472518
config.interface_create_public(
473519
primary=True,
474520
)
475-
config.interface_create_vlan(
476-
label="testvlan", ipam_address="10.0.0.3/32"
477-
)
521+
522+
label = str(time.time_ns()) + "vlabel"
523+
524+
config.interface_create_vlan(label=label, ipam_address="10.0.0.3/32")
478525

479526
interface = config.network_interfaces
480527

481528
assert interface[0].purpose == "public"
482529
assert interface[0].primary
483530
assert interface[1].purpose == "vlan"
484-
assert interface[1].label == "testvlan"
531+
assert interface[1].label == label
485532
assert interface[1].ipam_address == "10.0.0.3/32"
486533

487-
def test_create_public(self, create_linode):
488-
linode = create_linode
534+
def test_create_public(self, linode_for_network_interface_tests):
535+
linode = linode_for_network_interface_tests
489536

490537
config: Config = linode.configs[0]
491538

@@ -502,8 +549,8 @@ def test_create_public(self, create_linode):
502549
assert interface.purpose == "public"
503550
assert interface.primary
504551

505-
def test_create_vlan(self, create_linode):
506-
linode = create_linode
552+
def test_create_vlan(self, linode_for_network_interface_tests):
553+
linode = linode_for_network_interface_tests
507554

508555
config: Config = linode.configs[0]
509556

@@ -521,7 +568,11 @@ def test_create_vlan(self, create_linode):
521568
assert interface.label == "testvlan"
522569
assert interface.ipam_address == "10.0.0.2/32"
523570

524-
def test_create_vpc(self, create_linode, create_vpc_with_subnet_and_linode):
571+
def test_create_vpc(
572+
self,
573+
linode_for_network_interface_tests,
574+
create_vpc_with_subnet_and_linode,
575+
):
525576
vpc, subnet, linode, _ = create_vpc_with_subnet_and_linode
526577

527578
config: Config = linode.configs[0]
@@ -545,7 +596,11 @@ def test_create_vpc(self, create_linode, create_vpc_with_subnet_and_linode):
545596
assert interface.ipv4.nat_1_1 == linode.ipv4[0]
546597
assert interface.ip_ranges == ["10.0.0.5/32"]
547598

548-
def test_update_vpc(self, create_linode, create_vpc_with_subnet_and_linode):
599+
def test_update_vpc(
600+
self,
601+
linode_for_network_interface_tests,
602+
create_vpc_with_subnet_and_linode,
603+
):
549604
vpc, subnet, linode, _ = create_vpc_with_subnet_and_linode
550605

551606
config: Config = linode.configs[0]
@@ -575,25 +630,31 @@ def test_update_vpc(self, create_linode, create_vpc_with_subnet_and_linode):
575630
assert interface.ipv4.nat_1_1 == linode.ipv4[0]
576631
assert interface.ip_ranges == ["10.0.0.6/32"]
577632

578-
def test_reorder(self, create_linode):
579-
linode = create_linode
633+
def test_reorder(self, linode_for_network_interface_tests):
634+
linode = linode_for_network_interface_tests
580635

581636
config: Config = linode.configs[0]
582637

583638
pub_interface = config.interface_create_public(
584639
primary=True,
585640
)
641+
642+
label = str(time.time_ns()) + "vlabel"
586643
vlan_interface = config.interface_create_vlan(
587-
label="testvlan", ipam_address="10.0.0.3/32"
644+
label=label, ipam_address="10.0.0.3/32"
588645
)
589646

647+
send_request_when_resource_available(300, linode.shutdown)
648+
590649
interfaces = config.network_interfaces
591650
interfaces.reverse()
592651

593-
config.interface_reorder(interfaces)
652+
send_request_when_resource_available(
653+
300, config.interface_reorder, interfaces
654+
)
594655
config.invalidate()
595656

596-
assert [v.id for v in config.interfaces] == [
657+
assert [v.id for v in config.interfaces[:2]] == [
597658
vlan_interface.id,
598659
pub_interface.id,
599660
]
@@ -606,7 +667,11 @@ def test_delete_interface_containing_vpc(
606667
config: Config = linode.configs[0]
607668

608669
config.interfaces = []
609-
config.save()
670+
671+
# must power off linode before saving
672+
send_request_when_resource_available(300, linode.shutdown)
673+
674+
send_request_when_resource_available(60, config.save)
610675

611676
interface = config.interface_create_vpc(
612677
subnet=subnet,

0 commit comments

Comments
 (0)