1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-11 12:46:49 +00:00

test: no seeded admin password, settings changed only for a test, no local libvirt by default

- create_admin had a branch for `"test" in sys.argv` that gave the admin
  the password "admin"; 17 places signed in with it, and failed silently
  with ADMIN_PASSWORD set in the environment. The tests now make their
  own superuser and force_login it, and the shipped code has no test
  branch: the test runner gives migrate a password (also when
  ADMIN_PASSWORD is set but empty), so no data/admin_password is written
  into the checkout.
- AccountsTestCase builds its rows in setUpTestData instead of
  setUpClass and deleting them by hand.
- accounts tests set OTP_ENABLED with override_settings instead of
  assigning settings (one assignment was never undone, so later tests in
  the process ran with OTP on), and undo their app_settings change. The
  OTP login class reloads the URLs again only after the setting is off.
- computes/tests/test_views.py reached the machine's own libvirt
  (localhost over the socket) when TEST_LIBVIRT_HOST was unset; its live
  tests now run only with TEST_LIBVIRT_HOST, like the other live tests,
  as the README says.
This commit is contained in:
catborise 2026-11-06 11:17:59 +03:00
parent a4ea23004f
commit ee6b8d3e10
12 changed files with 67 additions and 74 deletions

View file

@ -24,7 +24,7 @@ class GeneratedAdminPasswordTestCase(TestCase):
plan = [(migration, False)]
out = io.StringIO()
env = {k: v for k, v in os.environ.items() if k not in ("ADMIN_PASSWORD", "ADMIN_USERNAME")}
with override_settings(BASE_DIR=Path(base_dir)), patch("sys.argv", ["manage.py", "migrate"]), patch.dict(
with override_settings(BASE_DIR=Path(base_dir)), patch.dict(
os.environ, env, clear=True
), redirect_stdout(out):
create_admin(sender=None, plan=plan, apps=apps)

View file

@ -3,11 +3,16 @@ enter a valid code; a user without one logs in with the password alone. The
device is chosen by the server (a posted device id is ignored), so the single
token field of the login page works and no one else's device can be used."""
import importlib
from django.contrib.auth import get_user_model
from django.test import RequestFactory, TestCase
from django.test import RequestFactory, TestCase, override_settings
from django.urls import clear_url_caches
from django_otp.oath import totp
from django_otp.plugins.otp_totp.models import TOTPDevice
import accounts.urls
import webvirtcloud.urls
from accounts.otp import SingleDeviceOTPForm
@ -84,6 +89,13 @@ class SingleDeviceOTPFormTestCase(TestCase):
self.assertFalse(self._form(otp_token=code).is_valid())
def reload_urls():
importlib.reload(accounts.urls)
importlib.reload(webvirtcloud.urls)
clear_url_caches()
@override_settings(OTP_ENABLED=True)
class OTPLoginHTTPTestCase(TestCase):
"""The actual login page (OTP_ENABLED): the single token field logs an
enrolled user in, and a user without a device needs only the password.
@ -92,32 +104,10 @@ class OTPLoginHTTPTestCase(TestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
import importlib
from django.conf import settings
from django.urls import clear_url_caches
import accounts.urls
import webvirtcloud.urls
cls._otp_was_enabled = settings.OTP_ENABLED
settings.OTP_ENABLED = True
importlib.reload(accounts.urls)
importlib.reload(webvirtcloud.urls)
clear_url_caches()
@classmethod
def tearDownClass(cls):
import importlib
from django.conf import settings
from django.urls import clear_url_caches
import accounts.urls
import webvirtcloud.urls
settings.OTP_ENABLED = cls._otp_was_enabled
importlib.reload(accounts.urls)
importlib.reload(webvirtcloud.urls)
clear_url_caches()
super().tearDownClass()
# class cleanups run last first: the URLs reload after the setting is off again
cls.addClassCleanup(reload_urls)
super().setUpClass() # turns OTP_ENABLED on
reload_urls()
def setUp(self):
self.user = get_user_model().objects.create_user("bob", password="pw-correct-horse")

View file

@ -5,7 +5,7 @@ from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Permission
from django.shortcuts import reverse
from django.test import Client, RequestFactory, TestCase
from django.test import Client, RequestFactory, TestCase, override_settings
from instances.models import Instance
@ -16,12 +16,9 @@ from accounts.utils import validate_ssh_key
class AccountsTestCase(TestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
# Add users for testing purposes
def setUpTestData(cls):
User = get_user_model()
cls.admin_user = User.objects.get(pk=1)
cls.admin_user = User.objects.create_superuser("accounts-admin", "admin@example.com", "pw")
cls.test_user = User.objects.create_user(username="test", password="test")
# Add compute
@ -38,16 +35,8 @@ class AccountsTestCase(TestCase):
name="test-vm",
)
@classmethod
def tearDownClass(cls):
if getattr(cls, "instance", None):
cls.instance.delete()
if getattr(cls, "compute", None):
cls.compute.delete()
super().tearDownClass()
def setUp(self):
self.client.login(request=RequestFactory().get("/"), username="admin", password="admin")
self.client.force_login(self.admin_user)
permission = Permission.objects.get(codename="change_password")
self.test_user.user_permissions.add(permission)
self.rsa_key = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC6OOdbfv27QVnSC6sKxGaHb6YFc+3gxCkyVR3cTSXE/n5BEGf8aOgBpepULWa1RZfxYHY14PlKULDygdXSdrrR2kNSwoKz/Oo4d+3EE92L7ocl1+djZbptzgWgtw1OseLwbFik+iKlIdqPsH+IUQvX7yV545ZQtAP8Qj1R+uCqkw== test@test"
@ -62,8 +51,8 @@ class AccountsTestCase(TestCase):
)
self.assertEqual(response.status_code, 200)
@override_settings(OTP_ENABLED=True)
def test_account_with_otp(self):
settings.OTP_ENABLED = True
response = self.client.get(
reverse("accounts:account", args=[self.test_user.id])
)
@ -249,7 +238,7 @@ class AccountsTestCase(TestCase):
self.assertRedirects(response, reverse("accounts:profile") + "#sshkeys")
def test_the_profile_lists_keys_and_tokens_where_links_land(self):
admin = get_user_model().objects.get(username="admin")
admin = self.admin_user
key = UserSSHKey.objects.create(user=admin, keyname="laptop", keypublic=self.rsa_key)
response = self.client.get(reverse("accounts:profile"))
# other pages link to #sshkeys and #apitokens
@ -288,6 +277,7 @@ class AccountsTestCase(TestCase):
)
self.assertFalse(form.is_valid())
self.addCleanup(setattr, app_settings, "ALLOW_INSTANCE_MULTIPLE_OWNER", app_settings.ALLOW_INSTANCE_MULTIPLE_OWNER)
app_settings.ALLOW_INSTANCE_MULTIPLE_OWNER = "False"
form = UserInstanceForm(
{