Source code for silq.tests.test_config

import unittest
import tempfile
import os

import silq
from silq.tools.config import *
from silq import config
from silq.pulses import Pulse

import qcodes as qc
from qcodes.instrument.parameter import Parameter


[docs]class TestConfig(unittest.TestCase):
[docs] def setUp(self): self.folder = tempfile.TemporaryDirectory() self.d = { 'pulses': { 'read': {'t_start': 0, 't_stop': 10}}, 'connections': ['connection1', 'connection2']} self.config = DictConfig('env1', folder=self.folder.name, config=self.d)
[docs] def tearDown(self): self.folder.cleanup()
[docs] def test_dicts_equal(self): self.assertTrue(self.dicts_equal(self.d, self.d)) self.assertTrue(self.dicts_equal(self.d, self.config)) self.assertTrue(self.dicts_equal(self.config, self.config)) self.config.x = 2 self.assertFalse(self.dicts_equal(self.d, self.config))
[docs] def test_save_load_dir(self): self.config.save(folder=self.folder.name, save_as_dir=True) filepath = os.path.join(self.folder.name, f'{self.config.name}.json') folderpath = os.path.join(self.folder.name, self.config.name) self.assertFalse(os.path.exists(filepath)) self.assertTrue(os.path.isdir(folderpath)) for filename in self.config.keys(): filepath = os.path.join(folderpath, '{}.json'.format(filename)) self.assertTrue(os.path.exists(filepath)) config_loaded = DictConfig('env1', folder=self.folder.name) self.assertFalse(config_loaded.save_as_dir) self.assertTrue(self.dicts_equal(self.config, config_loaded)) new_folder = tempfile.TemporaryDirectory() config_loaded.pulses.save_as_dir = True config_loaded.save(folder=new_folder.name) os.path.isdir(os.path.join(new_folder.name, 'pulses')) os.path.isfile(os.path.join(new_folder.name, 'pulses', 'read.json')) os.path.isfile(os.path.join(new_folder.name, 'connections.json')) config_loaded2 = DictConfig('env1', folder=new_folder.name) self.assertTrue(self.dicts_equal(self.config, config_loaded2)) self.assertIsInstance(config_loaded2.connections, ListConfig) new_folder.cleanup()
[docs] def test_load_no_update(self): self.config.save(folder=self.folder.name, save_as_dir=True) self.config.pulses.pop('read') old_config = self.config.load(update=False) self.assertIn('read', old_config['pulses']) self.assertNotIn('read', self.config.pulses) self.assertEqual(old_config, self.d) self.assertNotEqual(self.config, self.d)
[docs] def test_save_load_file(self): self.config.save(folder=self.folder.name) filepath = os.path.join(self.folder.name, f'{self.config.name}.json') folderpath = os.path.join(self.folder.name, self.config.name) self.assertTrue(os.path.exists(filepath)) self.assertFalse(os.path.exists(folderpath)) config_loaded = DictConfig('env1', folder=self.folder.name) self.assertFalse(config_loaded.save_as_dir) self.assertTrue(self.dicts_equal(self.config, config_loaded))
[docs] def test_save_load_dependent(self): self.config.pulses.read2 = {'t_start': 1, 't_stop': 'config:pulses.read.t_stop'} self.assertEqual(self.config.pulses.read2.t_stop, self.config.pulses.read.t_stop) self.assertEqual(dict.__getitem__(self.config.pulses.read2, 't_stop'), 'config:pulses.read.t_stop') self.config.save(folder=self.folder.name) config_loaded = DictConfig('env1', folder=self.folder.name) self.assertEqual(config_loaded.pulses.read2.t_stop, self.config.pulses.read.t_stop) self.assertEqual(dict.__getitem__(config_loaded.pulses.read2, 't_stop'), 'config:pulses.read.t_stop')
[docs] def test_load_dependent(self): self.d = { 't_start': 'config:pulses.read.t_start', 'pulses': { 'read': {'t_start': 0, 't_stop': 10}}, 'connections': ['connection1', 'connection2']} config = DictConfig('env1', folder=self.folder.name, config=self.d)
[docs] def test_refresh_add_list_config(self): self.d['x'] = [1,2,3] self.config.refresh(config=self.d) self.assertIn('x', self.config) self.assertEqual(self.config.x, self.d['x']) self.assertEqual(self.config, self.d)
[docs] def test_refresh_add_list_subconfig(self): self.d['pulses']['x'] = [1,2,3] self.config.refresh(config=self.d) self.assertIn('x', self.config.pulses) self.assertEqual(self.config.pulses.x, self.d['pulses']['x']) self.assertEqual(self.config, self.d)
[docs] def test_refresh_add_dict_config(self): self.d['x'] = {'test': 'val'} self.config.refresh(config=self.d) self.assertIn('x', self.config) self.assertEqual(self.config.x, self.d['x']) self.assertEqual(self.config, self.d)
[docs] def test_refresh_add_dict_subconfig(self): self.d['pulses']['x'] = {'test': 'val'} self.config.refresh(config=self.d) self.assertIn('x', self.config.pulses) self.assertEqual(self.config.pulses.x, self.d['pulses']['x']) self.assertEqual(self.config, self.d)
[docs] def test_override_refresh(self): self.d['pulses']['read'] = {'test': 'val'} self.config.refresh(config=self.d) self.assertIn('read', self.config.pulses) self.assertEqual(self.config, self.d)
[docs] def test_override_refresh_remove_DictConfig(self): self.d['pulses'] = {'test': 'val'} self.config.refresh(config=self.d) self.assertEqual(self.config, self.d)
[docs] def test_refresh_exclusive_set(self): # Override dict setitem to record all items that are set dict_set_items = [] dict_setitem = DictConfig.__setitem__ def record_dict_setitem(self, key, val): dict_set_items.append((key, val)) dict_setitem(self, key, val) DictConfig.__setitem__ = record_dict_setitem self.d['x'] = {'test': 'val'} self.config.refresh(config=self.d) self.assertEqual(dict_set_items, [('x', {'test': 'val'}), ('test', 'val')]) DictConfig.__setitem__ = dict_setitem
[docs] def test_add_SubConfig(self): subconfig = DictConfig(name='pulses', folder=None, config={'read': {}}) config.env1 = {'pulses': subconfig} self.assertIsInstance(config.env1, DictConfig) self.assertEqual(subconfig.config_path, 'config:env1.pulses')
[docs] def test_add_ListConfig(self): config.env1 = [1,2,3] self.assertIsInstance(config.env1, ListConfig)
[docs] def dicts_equal(self, d1, d2): d1_keys = list(d1.keys()) for d2_key, d2_val in d2.items(): if d2_key not in d1_keys: print(f'Key {d2_key} missing in d1') return False else: d1_keys.remove(d2_key) d1_val = d1[d2_key] if isinstance(d1_val, dict): if not isinstance(d2_val, dict): print(f'Key {d2_key} not dict in d2') return False if not self.dicts_equal(d1_val, d2_val): return False elif not d1_val == d2_val: print(f'Key {d2_key} differ ({d1_val} != {d2_val})') return False return True
[docs]class TestConfigPath(unittest.TestCase):
[docs] def setUp(self): self.original_environment = silq.environment self.d = { 'pulses': { 'read': {'t_start': 0, 't_stop': 10}}, 'connections': ['connection1', 'connection2'], 'properties': {}, 'env1': { 'properties': {'x':1, 'y':2}, 'pulses': { 'read': {'t_start': 1} } } } self.config = DictConfig('env1', config=self.d)
[docs] def tearDown(self): # Restore original environment silq.environment = self.original_environment
[docs] def test_basic_config_paths(self): self.assertEqual(self.config.config_path, 'config:') self.assertEqual(self.config.pulses.config_path, 'config:pulses') self.assertEqual(self.config.pulses.read.config_path, 'config:pulses.read') self.assertEqual(self.config.connections.config_path, 'config:connections')
[docs] def test_environment_config_paths(self): self.assertEqual(self.config.env1.config_path, 'config:env1') self.assertEqual(self.config.env1.properties.config_path, 'config:env1.properties') silq.environment = 'env1' self.assertEqual(self.config.env1.config_path, 'environment:') self.assertEqual(self.config.env1.properties.config_path, 'environment:properties') self.assertEqual(self.config.env1.pulses.config_path, 'environment:pulses') self.assertEqual(self.config.env1.pulses.read.config_path, 'environment:pulses.read')
[docs] def test_get_config_path(self): self.assertEqual(self.config['config:'], self.config) self.assertEqual(self.config.pulses['config:'], self.config) self.assertEqual(self.config['config:properties'], self.config.properties) self.assertEqual(self.config.properties['config:pulses'], self.config.pulses)
[docs] def test_get_environment_config_path(self): self.assertEqual(self.config['environment:'], self.config) self.assertEqual(self.config['environment:properties'], self.config.properties) self.assertEqual(self.config.properties['environment:'], self.config) self.assertEqual(self.config.properties['environment:properties'], self.config.properties) silq.environment = 'env1' self.assertEqual(self.config['environment:'], self.config.env1) self.assertEqual(self.config.properties['environment:'], self.config.env1) self.assertEqual(self.config['environment:pulses'], self.config.env1.pulses) self.assertEqual(self.config.properties['environment:pulses'], self.config.env1.pulses)
[docs]class TestConfigInheritance(unittest.TestCase):
[docs] def setUp(self): self.folder = tempfile.TemporaryDirectory() self.d = { 'pulses': { 'read': {'t_start': 0, 't_stop': 10}}, 'connections': ['connection1', 'connection2']} self.config = DictConfig('env1', folder=self.folder.name, config=self.d)
[docs] def tearDown(self): self.folder.cleanup()
[docs] def test_inherit_relative(self): self.config.pulses.read2 = {'inherit': 'read'} self.assertEqual(self.config.pulses.read2.inherit, 'read') self.assertIn('t_start', self.config.pulses.read2) self.assertEqual(self.config.pulses.read2.t_start, self.config.pulses.read.t_start) self.assertIn('t_stop', self.config.pulses.read2) self.assertEqual(self.config.pulses.read2.t_stop, self.config.pulses.read.t_stop)
[docs] def test_inherit_absolute(self): self.config.pulses2 = {'read': {'t_start': 1, 't_stop': 21}} self.config.pulses.read2 = {'inherit': 'config:pulses2.read'} self.assertEqual(self.config.pulses.read2.inherit, 'config:pulses2.read') self.assertEqual(self.config[self.config.pulses.read2.inherit], self.config.pulses2.read) self.assertIn('t_start', self.config.pulses.read2) self.assertEqual(self.config.pulses.read2.t_start, self.config.pulses2.read.t_start) self.assertIn('t_stop', self.config.pulses.read2) self.assertEqual(self.config.pulses.read2.t_stop, self.config.pulses2.read.t_stop)
[docs] def test_override_inherit(self): self.config.pulses.read2 = {'inherit': 'read', 't_stop': 20} self.assertEqual(self.config.pulses.read2.inherit, 'read') self.assertIn('t_start', self.config.pulses.read2) self.assertEqual(self.config.pulses.read2.t_start, self.config.pulses.read.t_start) self.assertIn('t_stop', self.config.pulses.read2) self.assertEqual(self.config.pulses.read2.t_stop, 20)
[docs]class TestConfigEnvironment(unittest.TestCase):
[docs] def setUp(self): self.original_environment = silq.environment self.d = { 'pulses': { 'read': {'t_start': 0, 't_stop': 10}}, 'connections': ['connection1', 'connection2'], 'properties': {}, 'env1': {'properties': {'x': 1, 'y': 2}}} self.config = DictConfig('config', config=self.d)
[docs] def tearDown(self): # Restore original environment silq.environment = self.original_environment
[docs] def test_no_environment(self): silq.environment = None self.assertEqual(self.config.config_path, 'config:') self.assertEqual(self.config.properties.config_path, 'config:properties') self.assertEqual(self.config.env1.properties.config_path, 'config:env1.properties')
[docs] def test_other_environment(self): silq.environment = 'env2' self.assertEqual(self.config.config_path, 'config:') self.assertEqual(self.config.properties.config_path, 'config:properties') self.assertEqual(self.config.env1.properties.config_path, 'config:env1.properties')
[docs] def test_environment(self): silq.environment = 'env1' self.assertEqual(self.config.config_path, 'config:') self.assertEqual(self.config.properties.config_path, 'config:properties') self.assertEqual(self.config.env1.properties.config_path, 'environment:properties')
[docs] def test_switch_environments(self): silq.environment = 'env2' self.assertEqual(self.config.config_path, 'config:') self.assertEqual(self.config.properties.config_path, 'config:properties') self.assertEqual(self.config.env1.properties.config_path, 'config:env1.properties') silq.environment = 'env1' self.assertEqual(self.config.config_path, 'config:') self.assertEqual(self.config.properties.config_path, 'config:properties') self.assertEqual(self.config.env1.properties.config_path, 'environment:properties') silq.environment = None self.assertEqual(self.config.config_path, 'config:') self.assertEqual(self.config.properties.config_path, 'config:properties') self.assertEqual(self.config.env1.properties.config_path, 'config:env1.properties')
[docs]class TestConfigMirroring(unittest.TestCase):
[docs] def setUp(self): self.original_environment = silq.environment self.d = { 'pulses': { 'read': {'t_start': 0, 't_stop': 10}}, 'connections': ['connection1', 'connection2'], 'properties': {}, 'env1': {'properties': {'x': 1, 'y': 2}}} self.config = DictConfig('config', config=self.d)
[docs] def tearDown(self): # Restore original environment silq.environment = self.original_environment
[docs] def test_simple_mirroring(self): silq.environment = None with self.assertRaises(KeyError): self.config.properties.x = 'config:properties.y' self.config.properties.y = 1 self.config.properties.x = 'config:properties.y' self.assertEqual(self.config.properties.y, 1) self.assertEqual(self.config.properties.x, 1) self.config.properties.x = 2 self.assertEqual(self.config.properties.y, 1) self.assertEqual(self.config.properties.x, 2) self.config.properties.y = 3 self.assertEqual(self.config.properties.y, 3) self.assertEqual(self.config.properties.x, 2)
[docs] def test_chained_mirroring(self): self.config.properties.z = 1 self.config.properties.y = 'config:properties.z' self.config.properties.x = 'config:properties.z' self.config.properties.w = 'config:properties.y' self.assertEqual(self.config.properties.z, 1) self.assertEqual(self.config.properties.y, 1) self.assertEqual(self.config.properties.x, 1) self.assertEqual(self.config.properties.w, 1) self.config.properties.z = 2 self.assertEqual(self.config.properties.z, 2) self.assertEqual(self.config.properties.y, 2) self.assertEqual(self.config.properties.x, 2) self.assertEqual(self.config.properties.w, 2)
[docs] def test_mirroring_change_environment(self): silq.environment = 'env1' self.config.env1.properties.y = 'environment:properties.x' self.assertEqual(self.config.env1.properties.y, 1) silq.environment = None with self.assertRaises(AttributeError): self.config.env1.properties.y
[docs]class TestConfigSignals(unittest.TestCase):
[docs] def setUp(self): self.original_environment = silq.environment self.d = { 'pulses': { 'read': {'t_start': 0, 't_stop': 10}}, 'connections': ['connection1', 'connection2'], 'properties': {}} self.config = DictConfig('env1', config=self.d) self.emitted_signals = [] self.config.signal.connect(self.register_signal)
[docs] def tearDown(self): # Restore original environment silq.environment = self.original_environment
[docs] def register_signal(self, sender, value): self.emitted_signals.append((sender, value))
[docs] def test_simple_signal_no_environment(self): self.config.properties.x = 1 self.assertEqual(len(self.emitted_signals), 2) self.assertEqual(self.emitted_signals[0], ('config:properties.x', 1)) self.assertEqual(self.emitted_signals[1], ('environment:properties.x', 1))
[docs] def test_simple_signal_environment(self): silq.environment = 'env1' self.config.properties.x = 1 self.assertEqual(len(self.emitted_signals), 1) self.assertEqual(self.emitted_signals[0], ('config:properties.x', 1)) self.config.env1 = {'properties.y': 42} self.emitted_signals = [] self.config.env1.properties.y = 43 self.assertEqual(len(self.emitted_signals), 1) self.assertEqual(self.emitted_signals[0], ('environment:properties.y', 43))
[docs] def test_signal_mirroring(self): with self.assertRaises(KeyError): self.config.properties.x = 'config:properties.y' self.config.properties.y = 1 self.config.properties.x = 'config:properties.y' self.assertEqual(self.config.properties.x, 1) self.emitted_signals = [] self.config.properties.y = 2 self.assertEqual(len(self.emitted_signals), 4) self.assertEqual(self.config.properties.y, 2) self.assertEqual(self.config.properties.x, 2) self.assertEqual(self.emitted_signals[0], ('config:properties.y', 2)) self.assertEqual(self.emitted_signals[1], ('environment:properties.y', 2)) self.assertEqual(self.emitted_signals[2], ('config:properties.x', 2)) self.assertEqual(self.emitted_signals[3], ('environment:properties.x', 2))
[docs] def test_signal_mirroring_environment(self): self.config.env1 = {'properties': {}} silq.environment = 'env1' self.config.env1.properties.y = 1 self.config.env1.properties.x = 'environment:properties.y' self.assertEqual(self.config.env1.properties.x, 1) self.emitted_signals = [] self.config.env1.properties.y = 2 self.assertEqual(self.config.env1.properties.y, 2) self.assertEqual(self.config.env1.properties.x, 2) self.assertEqual(self.emitted_signals[0], ('environment:properties.y', 2)) self.assertEqual(self.emitted_signals[1], ('environment:properties.x', 2))
[docs] def test_signal_inheritance(self): silq.environment = 'env1' self.config.properties.x = 1 self.assertEqual(len(self.emitted_signals), 1) self.assertEqual(self.emitted_signals[0], ('config:properties.x', 1)) self.config.properties2 = {'inherit': 'config:properties'} self.assertEqual(self.config.properties._inherited_configs, ['config:properties2']) self.assertIn('x', self.config.properties2) self.assertEqual(self.config.properties2.x, 1) # No signal emitted self.assertEqual(len(self.emitted_signals), 3) self.assertEqual(self.emitted_signals[1], ('config:properties2.inherit', 'config:properties')) self.assertEqual(self.emitted_signals[2], ('config:properties2', {'inherit': 'config:properties'})) self.config.properties.x = 2 self.assertEqual(len(self.emitted_signals), 5) self.assertEqual(self.emitted_signals[3], ('config:properties.x', 2)) self.assertEqual(self.emitted_signals[4], ('config:properties2.x', 2))
[docs] def test_signal_relative_inheritance(self): silq.environment = 'env1' self.config.pulses.read2 = {'inherit': 'read'} self.assertEqual(self.config.pulses.read._inherited_configs, ['config:pulses.read2']) self.emitted_signals = [] self.config.pulses.read.t_start = 30 self.assertEqual(self.config.pulses.read.t_start, 30) self.assertEqual(self.config.pulses.read2.t_start, 30) self.assertEqual(len(self.emitted_signals), 2) self.assertEqual(self.emitted_signals[0], ('config:pulses.read.t_start', 30)) self.assertEqual(self.emitted_signals[1], ('config:pulses.read2.t_start', 30))
[docs] def test_refresh_signals(self): silq.environment = 'env1' self.d['properties']['x'] = 2 self.config.refresh(self.d) self.assertEqual(self.config.properties.x, 2) self.assertEqual(len(self.emitted_signals), 1) self.assertEqual(self.emitted_signals[0], ('config:properties.x', 2)) self.d.pop('properties') self.config.refresh(self.d) self.assertNotIn('properties', self.config) self.assertEqual(len(self.emitted_signals), 1) self.d['pulses']['read2'] = {'t_start': 1, 't_stop': 2} self.config.refresh(self.d) self.assertEqual(len(self.emitted_signals), 4) self.assertEqual(self.emitted_signals[1], ('config:pulses.read2.t_start', 1)) self.assertEqual(self.emitted_signals[2], ('config:pulses.read2.t_stop', 2)) self.assertEqual(self.emitted_signals[3], ('config:pulses.read2', {'t_start': 1, 't_stop': 2}))
[docs]class test_connect_parameter_to_config(unittest.TestCase):
[docs] def setUp(self): self.original_environment = silq.environment self.silq_config = silq.config self.d = { 'pulses': { 'read': {'t_start': 0, 't_stop': 10}}, 'connections': ['connection1', 'connection2'], 'properties': {}, 'env1': {'properties': {'x': 1, 'y': 2}}} self.config = DictConfig('cfg', config=self.d) qc.config.user.silq_config = silq.config = self.config self.emitted_signals = [] self.config.signal.connect(self.register_signal)
[docs] def tearDown(self): silq.environment = self.original_environment qc.config.user.silq_config = silq.config = self.silq_config
[docs] def register_signal(self, sender, value): self.emitted_signals.append((sender, value))
[docs] def test_simple_connect_parameter(self): p = Parameter(name='param1', config_link='config:properties.x', set_cmd=None, initial_value=42) silq.config.properties.x = 41 self.assertEqual(p(), 41) def test_connect_parameter_to_environment(self): p = Parameter(name='param1', config_link='config:properties.x', set_cmd=None, initial_value=42) silq.config.properties.x = 41 self.assertEqual(p(), 41)
[docs] def test_connect_parameter_to_environment_config(self): p = Parameter(name='param1', config_link='environment:properties.x', set_cmd=None, initial_value=42) silq.config.env1.properties.x = 41 self.assertEqual(p(), 42) silq.config.properties.x = 43 self.assertEqual(p(), 43) silq.environment = 'env1' silq.config.env1.properties.x = 44 self.assertEqual(p(), 44) silq.config.properties.x = 45 self.assertEqual(p(), 44) silq.environment = None silq.config.env1.properties.x = 46 self.assertEqual(p(), 44) silq.config.properties.x = 47 self.assertEqual(p(), 47)
if __name__ == '__main__': unittest.main()