2021-06-16 22:00:59 +08:00
|
|
|
"""Test device DB interface"""
|
|
|
|
|
2021-06-21 16:39:39 +08:00
|
|
|
import os
|
2021-06-16 22:00:59 +08:00
|
|
|
import unittest
|
|
|
|
import tempfile
|
2021-06-16 22:27:02 +08:00
|
|
|
from pathlib import Path
|
2021-06-16 22:00:59 +08:00
|
|
|
|
|
|
|
from artiq.master.databases import DeviceDB
|
|
|
|
from artiq.tools import file_import
|
|
|
|
|
|
|
|
|
|
|
|
DUMMY_DDB_FILE = """
|
|
|
|
device_db = {
|
|
|
|
"core": {
|
|
|
|
"type": "local",
|
|
|
|
"module": "artiq.coredevice.core",
|
|
|
|
"class": "Core",
|
|
|
|
"arguments": {"host": "::1", "ref_period": 1e-09},
|
|
|
|
},
|
|
|
|
|
2021-06-16 22:27:02 +08:00
|
|
|
"core_alias": "core",
|
|
|
|
"unresolved_alias": "dummy",
|
2021-06-16 22:00:59 +08:00
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
2021-06-21 16:39:39 +08:00
|
|
|
# tempfile.NamedTemporaryFile:
|
|
|
|
# use delete=False and manual cleanup
|
|
|
|
# for Windows compatibility
|
|
|
|
|
2021-06-16 22:00:59 +08:00
|
|
|
|
2021-06-16 22:27:02 +08:00
|
|
|
class TestDeviceDBImport(unittest.TestCase):
|
2021-06-16 22:00:59 +08:00
|
|
|
def test_no_device_db_in_file(self):
|
2021-06-21 16:39:39 +08:00
|
|
|
with tempfile.NamedTemporaryFile(mode="w+", suffix=".py", delete=False) as f:
|
|
|
|
print(f.name)
|
2021-06-16 22:00:59 +08:00
|
|
|
print("", file=f, flush=True)
|
|
|
|
|
|
|
|
with self.assertRaisesRegex(KeyError, "device_db"):
|
|
|
|
DeviceDB(f.name)
|
|
|
|
|
2021-06-21 16:39:39 +08:00
|
|
|
os.unlink(f.name)
|
|
|
|
|
2021-06-16 22:27:02 +08:00
|
|
|
def test_import_same_level(self):
|
|
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
|
|
# make sure both files land in the same directory
|
2021-06-21 16:39:39 +08:00
|
|
|
# tempfiles are cleanup together with tmpdir
|
|
|
|
args = dict(mode="w+", suffix=".py", dir=tmpdir, delete=False)
|
2021-06-16 22:27:02 +08:00
|
|
|
with tempfile.NamedTemporaryFile(
|
|
|
|
**args
|
|
|
|
) as fileA, tempfile.NamedTemporaryFile(**args) as fileB:
|
|
|
|
print(DUMMY_DDB_FILE, file=fileA, flush=True)
|
|
|
|
print(
|
|
|
|
f"""
|
|
|
|
from {Path(fileA.name).stem} import device_db
|
|
|
|
|
|
|
|
device_db["new_core_alias"] = "core"
|
|
|
|
""",
|
|
|
|
file=fileB,
|
|
|
|
flush=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
ddb = DeviceDB(fileB.name)
|
|
|
|
self.assertEqual(
|
|
|
|
ddb.get("new_core_alias", resolve_alias=True),
|
|
|
|
DeviceDB(fileA.name).get("core"),
|
|
|
|
)
|
|
|
|
|
2021-06-16 22:00:59 +08:00
|
|
|
|
|
|
|
class TestDeviceDB(unittest.TestCase):
|
|
|
|
def setUp(self):
|
2021-06-21 16:39:39 +08:00
|
|
|
self.ddb_file = tempfile.NamedTemporaryFile(
|
|
|
|
mode="w+", suffix=".py", delete=False
|
|
|
|
)
|
2021-06-16 22:00:59 +08:00
|
|
|
print(DUMMY_DDB_FILE, file=self.ddb_file, flush=True)
|
|
|
|
|
|
|
|
self.ddb = DeviceDB(self.ddb_file.name)
|
|
|
|
|
2021-06-21 16:39:39 +08:00
|
|
|
def tearDown(self):
|
|
|
|
self.ddb_file.close()
|
|
|
|
os.unlink(self.ddb_file.name)
|
|
|
|
|
2021-06-16 22:00:59 +08:00
|
|
|
def test_get(self):
|
|
|
|
core = self.ddb.get("core")
|
|
|
|
self.assertEqual(core["class"], "Core")
|
|
|
|
|
|
|
|
def test_get_alias(self):
|
|
|
|
with self.assertRaises(TypeError): # str indexing on str
|
2021-06-16 22:27:02 +08:00
|
|
|
self.ddb.get("core_alias")["class"]
|
2021-06-16 22:00:59 +08:00
|
|
|
|
|
|
|
self.assertEqual(
|
2021-06-16 22:27:02 +08:00
|
|
|
self.ddb.get("core_alias", resolve_alias=True), self.ddb.get("core")
|
2021-06-16 22:00:59 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
def test_get_unresolved_alias(self):
|
|
|
|
with self.assertRaisesRegex(KeyError, "dummy"):
|
2021-06-16 22:27:02 +08:00
|
|
|
self.ddb.get("unresolved_alias", resolve_alias=True)
|
2021-06-16 22:00:59 +08:00
|
|
|
|
|
|
|
def test_update(self):
|
|
|
|
with self.assertRaises(KeyError):
|
|
|
|
self.ddb.get("core_log")
|
|
|
|
|
|
|
|
update = """
|
|
|
|
device_db["core_log"] = {
|
|
|
|
"type": "controller",
|
|
|
|
"host": "::1",
|
|
|
|
"port": 1068,
|
|
|
|
"command": "aqctl_corelog -p {port} --bind {bind} ::1",
|
|
|
|
}"""
|
|
|
|
|
|
|
|
print(update, file=self.ddb_file, flush=True)
|
|
|
|
self.ddb.scan()
|
|
|
|
|
|
|
|
self.assertEqual(self.ddb.get("core_log")["type"], "controller")
|
|
|
|
|
|
|
|
def test_get_ddb(self):
|
|
|
|
ddb = self.ddb.get_device_db()
|
|
|
|
raw = file_import(self.ddb_file.name).device_db
|
|
|
|
|
|
|
|
self.assertEqual(ddb, raw)
|