diff --git a/instances/templates/create_inst_block.html b/instances/templates/create_inst_block.html index a5a17f8b..4729f458 100644 --- a/instances/templates/create_inst_block.html +++ b/instances/templates/create_inst_block.html @@ -15,37 +15,35 @@ {% include "create_steps.html" with step=1 %}
{% trans "Choose the host the VM runs on." %}
- {% for compute in computes %} - {% if compute.status is True %} - -
-
{{ compute.name }}
-
-
{% trans "CPU" %} · {{ compute.cpu_count }} vCPU
-
-
-
-
- + {% for compute in reachable_computes %} +
+
+
{{ compute.name }}
+
+
{% trans "CPU" %} · {{ compute.cpu_count }} vCPU
+
+
+
+
-
-
{% trans "Memory" %} · {{ compute.ram_size|filesizeformat }}
-
-
-
-
- {{ compute.ram_usage }}% -
-
-
-
- {% endif %} +
+
{% trans "Memory" %} · {{ compute.ram_size|filesizeformat }}
+
+
+
+
+ {{ compute.ram_usage }}% +
+
+ +
+ {% empty %} -

{% trans "No compute is reachable." %}

+

{% trans "No compute is reachable." %}

{% endfor %}
diff --git a/instances/tests/test_create_dialog_cpu.py b/instances/tests/test_create_dialog_cpu.py index 2e627fae..1b294216 100644 --- a/instances/tests/test_create_dialog_cpu.py +++ b/instances/tests/test_create_dialog_cpu.py @@ -112,3 +112,34 @@ class CreateDialogCpuTestCase(TestCase): # the earlier opening's answer (99) is ignored; a failed read is a dash self.assertEqual(result["final"], [["42%", "42", "42%"], ["0%", None, "—"], ["0%", None, "…"]]) self.assertEqual(result["all"], urls[:2] + urls + urls) + + +class CreateDialogHostsTestCase(TestCase): + """The dialog lists the reachable computes; without one it says so.""" + + def setUp(self): + self.client.force_login(get_user_model().objects.create_superuser("cd-admin", "cd@example.com", "pw")) + for i in (1, 2): + Compute.objects.create(name=f"cd{i}", hostname=f"192.0.2.{i}", login="u", password="p", type=1) + for name, value in (("cpu_count", 1), ("ram_size", 1024), ("ram_usage", 0)): + p = patch.object(Compute, name, new_callable=PropertyMock, return_value=value) + p.start() + self.addCleanup(p.stop) + p = patch("instances.views.utils.refr") + p.start() + self.addCleanup(p.stop) + + def dialog(self, reachable): + with patch.object(Compute, "status", property(lambda compute: compute.name in reachable)): + response = self.client.get(reverse("instances:index")) + return html.fromstring(response.content).get_element_by_id("AddInstance") + + def test_only_reachable_computes_are_listed(self): + dialog = self.dialog({"cd2"}) + self.assertEqual([e.text for e in dialog.xpath(".//a/div/div[1]")], ["cd2"]) + self.assertNotIn("No compute is reachable.", dialog.text_content()) + + def test_no_reachable_compute_is_said(self): + dialog = self.dialog(set()) + self.assertEqual(dialog.xpath(".//a"), []) + self.assertIn("No compute is reachable.", dialog.text_content()) diff --git a/instances/views.py b/instances/views.py index 3ba2816f..561ea37b 100755 --- a/instances/views.py +++ b/instances/views.py @@ -85,7 +85,8 @@ def index(request): return render( request, "allinstances.html", - {"computes": computes, "instances": instances, "show_hosts": show_hosts, "own_hosts_down": own_hosts_down}, + {"computes": computes, "instances": instances, "show_hosts": show_hosts, "own_hosts_down": own_hosts_down, + "reachable_computes": [c for c in computes if c.status is True]}, )