1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-09 03:36:48 +00:00
webvirtcloud/computes/test_migration_address.py
catborise 5061cc7f2c fix(instances): a migration runs in the mode the VM's state allows, and is logged as it ran
moveto read the VM state for each flag and dropped options that did
not fit it, so a request could run as something else than asked; the
log then named the mode from the form ("live" or "offline"), not the
one used. The API did not log at all and answered "instance migrate is
started" after the migration had finished.

- moveto reads the state once. A running VM migrates live, or without
  live paused for the transfer (non-live); a paused VM stays paused; a
  shut-off VM moves offline. Live for a shut-off VM, offline for a
  running or paused one, and any other state are refused before
  anything changes. unsafe, auto converge (live only) and compressed
  apply to a running VM.
- migrate_instance logs the outcome for the VM page and the API: the
  mode and options used, or the error. The API answers
  "instance is migrated (<mode>)" and accepts requests that leave out
  an optional option.
- Post copy is gone from the form, the view and the API: only the
  flag was set, and without migrateStartPostCopy, which the app never
  called, the migration never switched to post copy.
2026-10-06 15:26:49 +03:00

58 lines
3.3 KiB
Python

"""A compute's migration address: where other hosts send a migrating VM's
memory. Empty means libvirt's default (the destination's own hostname)."""
from unittest.mock import MagicMock, patch
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError
from django.test import TestCase
from django.urls import reverse
from computes.models import Compute
from computes.validators import validate_migration_address
from instances.utils import migrate_instance
class MigrationAddressTests(TestCase):
def test_accepted_and_refused_values(self):
for value in ("192.0.2.12", "kvm102.example.org", "kvm-102", "2001:db8::12",
"kvm102.example.org."):
with self.subTest(value=value):
validate_migration_address(value)
for value in ("tcp://10.0.0.1", "10.0.0.1:49152", "[2001:db8::12]", "host name", "-bad", "a..b", "10.0.0.1/24", "x;y",
"2001:db8::12%eth0", "2001:db8::12%bad]:49152", "a.."):
with self.subTest(value=value), self.assertRaises(ValidationError):
validate_migration_address(value)
def test_migration_uri(self):
cases = {"": None, "192.0.2.12": "tcp://192.0.2.12", "kvm102.example.org": "tcp://kvm102.example.org",
"2001:db8::12": "tcp://[2001:db8::12]"}
for address, uri in cases.items():
with self.subTest(address=address):
self.assertEqual(Compute(migration_address=address).migration_uri, uri)
def test_the_compute_form_saves_it(self):
self.client.force_login(get_user_model().objects.create_superuser("ma-admin", "ma@example.com", "pw"))
compute = Compute.objects.create(name="ma", hostname="10.0.0.9", login="root", password="", type=2)
data = {"name": "ma", "hostname": "10.0.0.9", "login": "root", "type": 2, "details": "", "migration_address": "198.51.100.9"}
self.client.post(reverse("compute_update", args=[compute.id]), data)
compute.refresh_from_db()
self.assertEqual(compute.migration_address, "198.51.100.9")
self.client.post(reverse("compute_update", args=[compute.id]), {**data, "migration_address": "tcp://x"})
compute.refresh_from_db()
self.assertEqual(compute.migration_address, "198.51.100.9")
def test_a_migration_uses_the_destination_address(self):
source = Compute.objects.create(name="ma-src", hostname="10.0.0.8", login="root", password="", type=2)
dest = Compute.objects.create(name="ma-dst", hostname="kvm9", login="root", password="", type=2,
migration_address="198.51.100.9")
vm = MagicMock(compute=source, autostart=False)
vm.name = "vm"
with patch("instances.utils.connection_manager.host_is_up", return_value=True), \
patch("instances.utils.wvmInstances") as instances, \
patch("instances.utils.wvmInstance"), \
patch("instances.utils.Instance") as model:
model.objects.filter.return_value.first.return_value = None
user = get_user_model().objects.create_superuser("ma-mig", "mm@example.com", "pw")
migrate_instance(dest, vm, user, live=True)
self.assertEqual(instances.return_value.moveto.call_args.kwargs["uri"], "tcp://198.51.100.9")