mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 11:16:47 +00:00
The VM page polls the VM state every 5 s and reloads when it differs from the state the page was rendered with. Since the polling moved to pollWhileVisible, that state was kept in a top-level "var status", which is not a page variable but the browser's window.status. Where the browser does not keep a value there, the poll compared the answer with "" and reloaded the page every 5 s, back to its first tab. The variable is now vm_status. A Node test runs the page's script with a window.status that keeps nothing.
62 lines
2.6 KiB
Python
62 lines
2.6 KiB
Python
"""Pages poll the server through static/js/poll.js: one request at a time,
|
|
none while the page is hidden. Its behaviour is checked with Node."""
|
|
|
|
import json
|
|
import re
|
|
import shutil
|
|
import subprocess
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
from django.conf import settings
|
|
|
|
BASE = Path(settings.BASE_DIR)
|
|
POLLING_TEMPLATES = ["instances/templates/instance.html", "computes/templates/overview.html"]
|
|
|
|
|
|
class PollTestCase(unittest.TestCase):
|
|
@unittest.skipUnless(shutil.which("node"), "node is not installed")
|
|
def test_poll_js(self):
|
|
result = subprocess.run(
|
|
["node", str(BASE / "webvirtcloud/js_tests/poll.test.js"), str(BASE / "static/js/poll.js")],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=60,
|
|
)
|
|
self.assertEqual(result.returncode, 0, result.stderr)
|
|
|
|
def test_pages_poll_through_poll_js(self):
|
|
for template in POLLING_TEMPLATES:
|
|
with self.subTest(template=template):
|
|
source = (BASE / template).read_text()
|
|
self.assertNotIn("setInterval", source)
|
|
self.assertIn("pollWhileVisible(", source)
|
|
|
|
@unittest.skipUnless(shutil.which("node"), "node is not installed")
|
|
def test_the_vm_page_reloads_only_when_the_state_changes(self):
|
|
# "status" is a property of the browser's window: a page variable of
|
|
# that name holds what the browser makes of it (a string, or nothing)
|
|
source = (BASE / "instances/templates/instance.html").read_text()
|
|
script = re.search(r"<script>\s*(backgroundJobRunning = false;.*?)</script>", source, re.S).group(1)
|
|
script = script.replace("{{ instance.status|lower }}", "1").replace(
|
|
"{% url 'instances:status' instance.id %}", "/instances/1/status/"
|
|
)
|
|
js = """
|
|
const vm = require("vm");
|
|
const results = {};
|
|
for (const answer of [1, 5]) {
|
|
let reloads = 0;
|
|
const page = {
|
|
pollWhileVisible: (interval, request, onData) => { onData({status: answer}); return {stop() {}}; },
|
|
$: () => ({submit() {}}),
|
|
};
|
|
page.window = {location: {reload: () => reloads++}};
|
|
Object.defineProperty(page, "status", {get: () => "", set: () => {}});
|
|
vm.runInNewContext(SCRIPT, vm.createContext(page));
|
|
results[answer] = reloads;
|
|
}
|
|
console.log(JSON.stringify(results));
|
|
""".replace("SCRIPT", json.dumps(script))
|
|
out = subprocess.run(["node", "-e", js], capture_output=True, text=True, timeout=30)
|
|
self.assertEqual(out.returncode, 0, out.stderr)
|
|
self.assertEqual(json.loads(out.stdout), {"1": 0, "5": 1})
|