131 lines
5.4 KiB
Python
131 lines
5.4 KiB
Python
"""Smoke tests executed in an environment containing an official NetBox tag."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import inspect
|
|
import os
|
|
import sys
|
|
import unittest
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
|
|
NETBOX_SOURCE = Path(os.environ["NETBOX_SOURCE"]).resolve()
|
|
EXPECTED_VERSION = os.environ["NETBOX_EXPECTED_VERSION"]
|
|
sys.path.insert(0, str(NETBOX_SOURCE / "netbox"))
|
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "netbox.settings")
|
|
os.environ.setdefault("NETBOX_CONFIGURATION", "netbox_test_configuration")
|
|
|
|
import django # noqa: E402
|
|
|
|
django.setup()
|
|
|
|
from django.apps import apps # noqa: E402
|
|
from django.db.migrations.autodetector import MigrationAutodetector # noqa: E402
|
|
from django.db.migrations.loader import MigrationLoader # noqa: E402
|
|
from django.db.migrations.questioner import MigrationQuestioner # noqa: E402
|
|
from django.db.migrations.state import ProjectState # noqa: E402
|
|
from django.template.loader import get_template # noqa: E402
|
|
from django.urls import resolve, reverse # noqa: E402
|
|
|
|
from core.models import Job # noqa: E402
|
|
from netbox.jobs import JobRunner # noqa: E402
|
|
from netbox_plugin_store import config # noqa: E402
|
|
from netbox_plugin_store.jobs import PluginLifecycleJob # noqa: E402
|
|
from netbox_plugin_store.navigation import menu # noqa: E402
|
|
from users.models import User # noqa: E402
|
|
|
|
|
|
class OfficialNetBoxCompatibilityTests(unittest.TestCase):
|
|
def test_exact_netbox_and_django_runtime(self):
|
|
from django.conf import settings
|
|
|
|
self.assertEqual(settings.RELEASE.version, EXPECTED_VERSION)
|
|
self.assertGreaterEqual(sys.version_info, (3, 12))
|
|
self.assertEqual(django.get_version(), "6.0.7" if EXPECTED_VERSION == "4.6.5" else "6.0.8")
|
|
|
|
def test_plugin_config_is_registered(self):
|
|
app = apps.get_app_config("netbox_plugin_store")
|
|
self.assertIsInstance(app, config)
|
|
self.assertEqual(config.min_version, "4.6.5")
|
|
self.assertEqual(config.max_version, "4.6.8")
|
|
|
|
def test_jobrunner_queue_metadata_and_run_arguments_are_compatible(self):
|
|
self.assertIn("queue_name", inspect.signature(Job.enqueue).parameters)
|
|
self.assertTrue(issubclass(PluginLifecycleJob, JobRunner))
|
|
with patch.object(Job, "enqueue", return_value="queued") as enqueue:
|
|
result = PluginLifecycleJob.enqueue(
|
|
user="operator",
|
|
queue_name="compatibility",
|
|
audit_id=12,
|
|
slug="example-plugin",
|
|
action="install",
|
|
version="1.0.0",
|
|
dry_run=True,
|
|
actor_id=34,
|
|
)
|
|
self.assertEqual(result, "queued")
|
|
args, kwargs = enqueue.call_args
|
|
self.assertIs(args[0].__func__, PluginLifecycleJob.handle.__func__)
|
|
self.assertEqual(kwargs["queue_name"], "compatibility")
|
|
self.assertEqual(kwargs["audit_id"], 12)
|
|
self.assertEqual(kwargs["actor_id"], 34)
|
|
|
|
def test_navigation_urls_and_permission_semantics(self):
|
|
self.assertFalse(hasattr(User(), "is_staff"))
|
|
urls = {
|
|
"catalog": reverse("plugins:netbox_plugin_store:catalog"),
|
|
"status": reverse("plugins:netbox_plugin_store:status"),
|
|
"audit-list": reverse("plugins:netbox_plugin_store:audit-list"),
|
|
"audit-detail": reverse("plugins:netbox_plugin_store:audit-detail", kwargs={"pk": 7}),
|
|
"plugin-detail": reverse(
|
|
"plugins:netbox_plugin_store:plugin-detail", kwargs={"slug": "example-plugin"}
|
|
),
|
|
"lifecycle-confirm": reverse(
|
|
"plugins:netbox_plugin_store:lifecycle-confirm",
|
|
kwargs={"slug": "example-plugin", "action": "install"},
|
|
),
|
|
"lifecycle-action": reverse(
|
|
"plugins:netbox_plugin_store:lifecycle-action",
|
|
kwargs={"slug": "example-plugin", "action": "install"},
|
|
),
|
|
}
|
|
for name, url in urls.items():
|
|
self.assertEqual(resolve(url).url_name, name)
|
|
|
|
items = [item for group in menu.groups for item in group.items]
|
|
self.assertEqual(len(items), 3)
|
|
for item in items:
|
|
self.assertTrue(item.auth_required)
|
|
self.assertFalse(item.staff_only)
|
|
self.assertEqual(item.permissions, ["netbox_plugin_store.manage_plugin"])
|
|
|
|
def test_templates_resolve_and_compile_from_installed_wheel(self):
|
|
for name in (
|
|
"audit_detail.html",
|
|
"audit_list.html",
|
|
"catalog.html",
|
|
"confirm.html",
|
|
"detail.html",
|
|
"status.html",
|
|
):
|
|
template = get_template(f"netbox_plugin_store/{name}")
|
|
self.assertIsNotNone(template.template)
|
|
self.assertIsNotNone(get_template("base/layout.html").template)
|
|
|
|
def test_migration_graph_and_model_state_have_no_drift(self):
|
|
loader = MigrationLoader(None, ignore_no_migrations=True)
|
|
self.assertIn(("netbox_plugin_store", "0001_initial"), loader.disk_migrations)
|
|
from_state = loader.project_state()
|
|
to_state = ProjectState.from_apps(apps)
|
|
changes = MigrationAutodetector(
|
|
from_state,
|
|
to_state,
|
|
MigrationQuestioner(specified_apps={"netbox_plugin_store"}),
|
|
).changes(graph=loader.graph, trim_to_apps={"netbox_plugin_store"})
|
|
self.assertNotIn("netbox_plugin_store", changes)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main(verbosity=2)
|