From 46955f3ff7203fba782b2e3c52d2e8ab22e026bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kr=C3=B6ger?= Date: Thu, 17 Jul 2025 16:15:53 +0200 Subject: [PATCH 1/4] Run tests with Debian Bookworm --- tests/test_integration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_integration.py b/tests/test_integration.py index b0cd7603..9cbc5ab2 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -118,7 +118,7 @@ def setUp(self): self.vm_obj['memory'] = 2048 self.vm_obj['no_monitoring'] = True self.vm_obj['num_cpu'] = 2 - self.vm_obj['os'] = 'bullseye' + self.vm_obj['os'] = 'bookworm' self.vm_obj['project'] = 'test' self.vm_obj['puppet_environment'] = None self.vm_obj['puppet_ca'] = 'testing-puppetca.innogames.de' From 0010bca3231d8339bd103f70d3c5684244622927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kr=C3=B6ger?= Date: Fri, 18 Jul 2025 08:51:03 +0200 Subject: [PATCH 2/4] Use new auto assign logic for ip addresses We no longer want users to pick ip addresses but just specify the network and then they get automatically an ip address. The exception is manually setting an ip address in which case we can use the adminapi to get an ip address and lock it so others do not use it. --- tests/conftest.py | 46 +++------------------------------------ tests/test_integration.py | 13 ++++------- 2 files changed, 7 insertions(+), 52 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 2941ff94..83336452 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,32 +1,27 @@ """igvm - Shared functions -Copyright (c) 2020 InnoGames GmbH +Copyright (c) 2025 InnoGames GmbH """ from datetime import datetime, timezone -from math import ceil, log from re import match -from time import sleep from shlex import quote +from time import sleep from typing import Optional import boto3 from adminapi.dataset import Query from adminapi.exceptions import DatasetError -from adminapi.filters import Any, Not, Regexp +from adminapi.filters import Any, Regexp from botocore.exceptions import ClientError from libvirt import VIR_DOMAIN_RUNNING -from igvm.exceptions import IGVMTestError from igvm.hypervisor import Hypervisor from igvm.settings import HYPERVISOR_ATTRIBUTES, AWS_RETURN_CODES from tests import ( IGVM_LOCKED_TIMEOUT, JENKINS_EXECUTOR, - PYTEST_XDIST_WORKER, - PYTEST_XDIST_WORKER_COUNT, VM_HOSTNAME_PATTERN, - VM_NET, ) @@ -70,14 +65,6 @@ def clean_all(route_network, datacenter_type, vm_hostname=None): # Remove all connected Serveradmin objects. clean_serveradmin({'hostname': Regexp(pattern)}) - # Try to remove VMs with the same IP in any case because we use custom - # logic to assign them and we want to avoid IP address conflicts. - # Index 1 is usually used for the test's subject VM, - # 2 might be used for testing IP change. - for ip_attr in ('ipv4', 'ipv6'): - ips = [get_next_address(VM_NET, i, ip_attr) for i in [1, 2]] - clean_serveradmin({ip_attr: Any(*ips)}) - def clean_hv(hv, pattern): # We never know what happened on the HV, so always refresh @@ -207,30 +194,3 @@ def _wait_for_state_reached(ec2_client, instance_id: str, state: str, if not any(error in str(e) for error in ['InvalidInstanceID', 'IncorrectInstanceState']): raise - - -def get_next_address(vm_net, index, ip_attr): - non_vm_hosts = list(Query({ - 'project_network': vm_net, - 'servertype': Not('vm'), - }, [ip_attr])) - offset = 1 if len(non_vm_hosts) > 0 else 0 - subnet_levels = ceil(log(PYTEST_XDIST_WORKER_COUNT + offset, 2)) - project_network = Query({'hostname': vm_net}, [ip_attr]).get() - try: - subnets = list(project_network[ip_attr].subnets(subnet_levels)) - except ValueError: - raise IGVMTestError( - 'Can\'t split {} into enough subnets ' - 'for {} parallel tests'.format( - vm_net, PYTEST_XDIST_WORKER_COUNT, - ) - ) - if len(non_vm_hosts) > subnets[0].num_addresses: - raise IGVMTestError( - 'Can\'t split {} into enough subnets ' - 'for {} parallel tests'.format( - vm_net, PYTEST_XDIST_WORKER_COUNT, - ) - ) - return subnets[PYTEST_XDIST_WORKER + 1][index] diff --git a/tests/test_integration.py b/tests/test_integration.py index 9cbc5ab2..f0a350ac 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -58,7 +58,6 @@ from tests.conftest import ( clean_all, cmd, - get_next_address, ) basicConfig(level=INFO) @@ -114,7 +113,7 @@ def setUp(self): self.vm_obj['environment'] = 'testing' self.vm_obj['hostname'] = VM_HOSTNAME self.vm_obj['hypervisor'] = None - self.vm_obj['intern_ip'] = get_next_address(VM_NET, 1, self.ip_attr) + self.vm_obj['project_network'] = VM_NET self.vm_obj['memory'] = 2048 self.vm_obj['no_monitoring'] = True self.vm_obj['num_cpu'] = 2 @@ -688,15 +687,11 @@ def test_reject_out_of_sync_serveradmin(self): vm_migrate(VM_HOSTNAME) def test_new_address(self): - # We don't have a way to ask for new IP address from Serveradmin - # and lock it for us. The method below will usually work fine. - # When it starts failing, we must develop retry method. - new_address = get_next_address(VM_NET, 2, 'ipv4') - + new_address = Query({'hostname': VM_NET}, ['intern_ip']).get_free_ip_addr(lock=True) change_address(VM_HOSTNAME, new_address, offline=True) - obj = Query({'hostname': VM_HOSTNAME}, ['intern_ip']).get() - self.assertEqual(obj['intern_ip'], new_address) + obj = Query({'hostname': VM_HOSTNAME}, ['ipv4']).get() + self.assertEqual(obj['ipv4'], new_address) with _get_vm(VM_HOSTNAME) as vm: vm.run(cmd('ip a | grep {}', new_address)) self.check_vm_present() From a5250c40498ddf33de85415c37a03811b46e7e1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kr=C3=B6ger?= Date: Mon, 21 Jul 2025 14:03:21 +0200 Subject: [PATCH 3/4] Update dependencies and bump version --- igvm/__init__.py | 4 ++-- requirements-tests.txt | 2 +- requirements.txt | 6 +++--- setup.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/igvm/__init__.py b/igvm/__init__.py index b96ec0c8..05b9b25e 100644 --- a/igvm/__init__.py +++ b/igvm/__init__.py @@ -1,6 +1,6 @@ """igvm - Main Module -Copyright (c) 2024 InnoGames GmbH +Copyright (c) 2025 InnoGames GmbH """ -VERSION = (2, 2, 4) +VERSION = (2, 2, 5) diff --git a/requirements-tests.txt b/requirements-tests.txt index e75b0b28..fe653b6e 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -1,2 +1,2 @@ -r requirements.txt -mock \ No newline at end of file +mock diff --git a/requirements.txt b/requirements.txt index 57e7750e..775f4482 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ -setuptools~=73.0 -adminapi@git+https://github.com/innogames/serveradmin.git@v4.15.0#egg=adminapi +setuptools~=80.9 +adminapi@git+https://github.com/innogames/serveradmin.git@v4.22.1#egg=adminapi netaddr~=0.8 -cffi~=1.14 +cffi~=1.17 paramiko~=2.7 Fabric3~=1.14 libvirt-python>=7,<=9 diff --git a/setup.py b/setup.py index 0498db9c..ca92521d 100755 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ """igvm - Setup -Copyright (c) 2024 InnoGames GmbH +Copyright (c) 2025 InnoGames GmbH """ from setuptools import setup From c4a30cbc0eaf1e1098b2f5fcb66c97dd17ae251e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kr=C3=B6ger?= Date: Tue, 22 Jul 2025 16:04:53 +0200 Subject: [PATCH 4/4] Fix test for unreasonable memory size It seemed once unrealistic to have 200GB for a single VM. Adjust to modern standards. --- tests/test_integration.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_integration.py b/tests/test_integration.py index f0a350ac..bac6f732 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -420,7 +420,8 @@ def _get_mem_vm(): mem_set(VM_HOSTNAME, '2G') with self.assertRaises(IGVMError): - mem_set(VM_HOSTNAME, '200G') + # We do not expect our test HVs have so much memory soon. + mem_set(VM_HOSTNAME, '20000G') # Not dividable with self.assertRaises(IGVMError): @@ -431,7 +432,8 @@ def _get_mem_vm(): self.vm.shutdown() with self.assertRaises(IGVMError): - mem_set(VM_HOSTNAME, '200G') + # We do not expect our test HVs have so much memory soon. + mem_set(VM_HOSTNAME, '20000G') mem_set(VM_HOSTNAME, '1024M') self.assertEqual(_get_mem_hv(), 1024)