import pytest import os from calculate.vars.datavars import Namespace, Variable, CyclicVariableError,\ VariableError, ReadonlyVariable,\ ChoiceVariable, IntegerVariable,\ StringVariable, DefaultValue,\ TableVariable, HashVariable,\ VariableNotFoundError from calculate.vars.vars_loader import NamespaceIniFiller, VariableLoader,\ ProfileFiller, NamespaceIniFillerStrict @pytest.mark.vars class TestNamespace: def test_init_empty_namespace(self): ns = Namespace() assert ns.childs == {} assert ns.variables == {} def test_create_variable(self): ns = Namespace() ns.addStringVariable("test", "12345") assert ns.test.getValue() == "12345" ns.addStringVariable("zxcv", "23456") assert ns.zxcv.getValue() == "23456" def test_create_ns_with_vars(self): ns = Namespace() ns.addNamespace(Namespace("os")) ns.os.addStringVariable("test", "123") ns.os.addNamespace(Namespace("linux")) ns.os.linux.addStringVariable("shortname", "CLD") assert ns.os.test.getValue() == "123" assert ns.os["test"].getValue() == "123" assert ns.os.linux.shortname.getValue() == "CLD" assert ns.os.root == ns def test_fill_namespace_simple(self): ns = Namespace() nsif = NamespaceIniFiller() nsif.fill(ns, """ [os] test = 123 [os][linux] shortname = CLD fullname = Calculate Linux Desktop """) assert ns.os.test.getValue() == "123" assert ns.os.linux.shortname.getValue() == "CLD" assert ns.os.linux.fullname.getValue() == "Calculate Linux Desktop" assert ns.os.linux.root == ns nsif.fill(ns, """ [os][linux] shortname = CLDX """) assert ns.os.linux.shortname.getValue() == "CLDX" assert ns.os.linux.fullname.getValue() == "Calculate Linux Desktop" def test_fill_namespace_append_and_remove(self): ns = Namespace() nsif = NamespaceIniFiller() nsif.fill(ns, """ [os] test = 123 [os] test += 345 """) assert ns.os.test.getValue() == "123,345" nsif.fill(ns, """ [os] test -= 123 """) assert ns.os.test.getValue() == "345" nsif.fill(ns, """ [os] test += asdf,qwer,zxcv """) assert ns.os.test.getValue() == "345,asdf,qwer,zxcv" nsif.fill(ns, """ [os] test -= asdf,zxcv """) assert ns.os.test.getValue() == "345,qwer" def test_fill_namespace_clear_namespaces(self): ns = Namespace() nsif = NamespaceIniFiller() nsif.fill(ns, """ [test][0] dev = /dev/sda1 mount = swap [test][1] dev = /dev/sda2 mount = / [test][2] dev = /dev/sda5 mount = /var/calculate """) assert [x.dev.getValue() for x in ns.test] == ['/dev/sda1', '/dev/sda2', '/dev/sda5'] nsif.fill(ns, """ [test][0] dev = /dev/sdb1 mount = swap [test][1] dev = /dev/sdb2 mount = / """) assert [x.dev.getValue() for x in ns.test] == ['/dev/sdb1', '/dev/sdb2', '/dev/sda5'] nsif.fill(ns, """ [test][] [test][0] dev = /dev/sdb1 mount = swap [test][1] dev = /dev/sdb2 mount = / """) assert [x.dev.getValue() for x in ns.test] == ['/dev/sdb1', '/dev/sdb2'] def test_fill_namespace_strict_clear(self): ns = Namespace() nsif = NamespaceIniFiller() nsif.fill(ns, """ [os][test][0] dev = /dev/sda1 mount = swap [os][test][1] dev = /dev/sda2 mount = / [os][test][2] dev = /dev/sda5 mount = /var/calculate [custom][test] zxcv = 1 [custom][test2] zxcv = 2 """) assert ns.custom.test.zxcv.getValue() == "1" assert ns.custom.test2.zxcv.getValue() == "2" nsifs = NamespaceIniFillerStrict() nsifs.fill(ns, """ [os][test][] [custom][] """) assert [x for x in ns.custom] == [] def test_get_namespace_attrs(self): ns = Namespace() os = Namespace("os") os.addStringVariable("test", "zxcv") ns.addNamespace(os) assert ns.os.test.getValue() == "zxcv" assert ns.os["test"].getValue() == "zxcv" assert "test" in ns.os ns.os.test.setValue("123") assert ns.os.test.getValue() == "123" ns.os["test"].setValue("234") assert ns.os.test.getValue() == "234" def test_variable_get_value(self): class TestVar(Variable): def get(self): return "A" var = TestVar("test") assert var.getValue() == "A" def test_namespace_lookup(self): ns = Namespace() os = Namespace("os") device = Namespace("device") linux = Namespace("linux") ns.addNamespace(os) os.addNamespace(linux) os.addNamespace(device) device1 = device.addNamespace() device1.addStringVariable("dev", "/dev/sda") device2 = device.addNamespace() device2.addStringVariable("dev", "/dev/sdb") device3 = device.addNamespace() device3.addStringVariable("dev", "/dev/sdc") ns.addStringVariable("first", "first") os.addStringVariable("second", "second") linux.addStringVariable("third", "third") assert ns.first.getValue() == "first" assert ns.root.os.second.getValue() == "second" assert ns.os.second.getValue() == "second" assert os.root.os.second.getValue() == "second" assert os.second.getValue() == "second" assert linux.third.getValue() == "third" assert linux.root.os.second.getValue() == "second" with pytest.raises(VariableNotFoundError): os.third assert ns.os.device[0].dev.getValue() == "/dev/sda" assert ns.os.device["0"].dev.getValue() == "/dev/sda" assert ns.os.device[1].dev.getValue() == "/dev/sdb" assert ns.os.device[2].dev.getValue() == "/dev/sdc" assert ns.os.device.parent.second.getValue() == "second" assert ns.os.device.parent.parent.os.second.getValue() == "second" assert ns.os.device.parent.parent.parent.os.second.\ getValue() == "second" def test_variable_get_value_by_variable(self): class TestVar1(Variable): def get(self): return "%s,B" % self.vars.test2.getValue(self) class TestVar2(Variable): def get(self): return "A" ns = Namespace() ns.addVariable(TestVar1("test1")) ns.addVariable(TestVar2("test2")) assert ns.test1.getValue() == "A,B" def test_variable_get_value_by_changed_variable(self): class TestVar1(Variable): counter = 0 def get(self): self.counter += 1 return "%s,B" % self.vars.test2.getValue(self) ns = Namespace() test1 = TestVar1("test1") ns.addVariable(test1) ns.addStringVariable("test2", "A") assert ns.test1.getValue() == "A,B" assert test1.counter == 1 # test for get cached variable value assert ns.test1.getValue() == "A,B" assert test1.counter == 1 # change value of test2 for recalculate test1 ns.test2.setValue("C") assert ns.test1.getValue() == "C,B" assert test1.counter == 2 # change value of test2 for recalculate test1 ns.test2.setValue("D") assert ns.test1.getValue() == "D,B" assert test1.counter == 3 def test_cyclic_variable(self): class TestVar1(Variable): def get(self): return "%s,test1" % self.vars.test2.getValue(self) class TestVar2(Variable): def get(self): return "%s,test2" % self.vars.test3.getValue(self) class TestVar3(Variable): def get(self): return "%s,test3" % self.vars.test1.getValue(self) test1 = TestVar1("test1") test2 = TestVar2("test2") test3 = TestVar3("test3") ns = Namespace() ns.addVariable(test1) ns.addVariable(test2) ns.addVariable(test3) with pytest.raises(CyclicVariableError) as e: ns.test1.getValue() assert e.value.queue[:-1] == ("test1", "test2", "test3") with pytest.raises(VariableError) as e: ns.test1.getValue() def test_drop_invalidate_after_set_value(self): class TestVar1(Variable): counter = 0 def get(self): self.counter += 1 return "%s,test1" % self.vars.test2.getValue(self) class TestVar2(Variable): def get(self): return "ZZZZ" test1 = TestVar1("test1") test2 = TestVar2("test2") ns = Namespace() ns.addVariable(test1) ns.addVariable(test2) assert test1.getValue() == "ZZZZ,test1" test1.setValue("VVVV") assert test1.getValue() == "VVVV" assert test1.counter == 1 test2.setValue("XXXX") assert test1.getValue() == "VVVV" assert test1.counter == 1 test1.invalidate() assert test1.getValue() == "XXXX,test1" assert test1.counter == 2 def test_change_invalidator_variable(self): class VarTest(Variable): counter = 0 def get(self): self.counter += 1 if self.vars.ifvar.getValue(self): return "%s,test1" % self.vars.vara.getValue(self) else: return "%s,test1" % self.vars.varb.getValue(self) vartest = VarTest("vartest") ns = Namespace() ns.addVariable(vartest) ns.addStringVariable("vara", "vara") ns.addStringVariable("varb", "varb") ns.addStringVariable("ifvar", "true") assert vartest.getValue() == "vara,test1" assert vartest.counter == 1 ns.vara.setValue("varc") assert vartest.getValue() == "varc,test1" assert vartest.counter == 2 ns.ifvar.setValue("") assert vartest.getValue() == "varb,test1" assert vartest.counter == 3 ns.vara.setValue("vard") assert vartest.getValue() == "varb,test1" assert vartest.counter == 3 def test_readonly_varaible(self): class TestVar1(Variable): properties = [ReadonlyVariable, StringVariable] def get(self): return "test1" test1 = TestVar1("test1") assert test1.getValue() == "test1" with pytest.raises(VariableError): test1.setValue("test2") assert test1.getValue() == "test1" test1.setValue("test2", force=True) assert test1.getValue() == "test2" def test_choice_variable(self): class TestVar1(Variable): properties = [ChoiceVariable] def choice(self): return ["test1", "test2"] test1 = TestVar1("test1") with pytest.raises(VariableError): test1.setValue("test3") test1.setValue("test2") assert test1.getValue() == "test2" def test_integer_variable(self): class TestVar1(Variable): properties = [IntegerVariable] test1 = TestVar1("test1") with pytest.raises(VariableError): test1.setValue("test3") test1.setValue("33") assert test1.getValue() == 33 test1.setValue("-33") assert test1.getValue() == -33 def test_default_value_property(self): class TestVar1(Variable): def get(self): return "123" test1 = TestVar1("test1") assert test1.getValue() == "123" test1.setValue("987") test1.addProperty(DefaultValue("567")) assert test1.getValue() == "987" test1.invalidate() assert test1.getValue() == "567" def test_get_comment(self): class TestVar1(Variable): def get(self): return "123" class TestVar2(Variable): def get(self): return "234" def getComment(self): return "[%s]" % self.getValue() class TestVar3(Variable): def get(self): return "ZXC %s" % self.vars.test2.getCommentValue(self) ns = Namespace() test1 = TestVar1("test1") assert test1.getValue() == "123" assert test1.getComment() == "123" test2 = TestVar2("test2") assert test2.getValue() == "234" assert test2.getComment() == "[234]" test3 = TestVar3("test3") ns.addVariable(test1) ns.addVariable(test2) ns.addVariable(test3) assert test3.getValue() == "ZXC [234]" test2.setValue("567") assert test3.getValue() == "ZXC [567]" def test_wrong_choice_varaible(self): class TestVar1(Variable): properties = [ChoiceVariable] class TestVar2(Variable): properties = [ChoiceVariable] def choice(self): return ["test1", "test2"] class TestVar3(Variable): properties = [ChoiceVariable] def choiceComment(self): return [("test1", "Test1"), ("test2", "Test2")] test1 = TestVar1("test1") test2 = TestVar2("test2") test3 = TestVar3("test3") with pytest.raises(VariableError): test1.choice() with pytest.raises(VariableError): test1.choiceComment() assert test2.choice() == ["test1", "test2"] assert test2.choiceComment() == [("test1", "test1"), ("test2", "test2")] assert test3.choice() == ["test1", "test2"] assert test3.choiceComment() == [("test1", "Test1"), ("test2", "Test2")] def test_loading_test_variable_module(self): ns = Namespace() vl = VariableLoader() vl.fill(ns, "tests/vars/variables", "testvars") assert ns.level.simple.getValue() == "simple value" assert ns.level.uselocalsimple.getValue() == "Using simple value" assert ns.level.usefullsimple.getValue() == "Using simple value" with pytest.raises(VariableError): ns.level.badchoice.choice() with pytest.raises(VariableError): ns.level.badchoice.choiceComment() assert ns.level.simple_choice.choice() == ["/dev/sda1", "/dev/sda2", "/dev/sda3"] assert ns.level.comment_choice.choice() == ["/dev/sda1", "/dev/sda2", "/dev/sda3"] assert ns.level.comment_choice.choiceComment() == [ ("/dev/sda1", "SWAP"), ("/dev/sda2", "ROOT"), ("/dev/sda3", "DATA")] ns.level.disks.setValue(["/dev/sda2", "/dev/sda1"]) assert ns.level.disks.getValue() == ["/dev/sda2", "/dev/sda1"] assert ns.level.comment_choice.choice() == ["/dev/sda2", "/dev/sda1"] assert ns.level.comment_choice.choiceComment() == [ ("/dev/sda2", "ROOT"), ("/dev/sda1", "SWAP")] assert ns.level is not ns.level.level2.root assert ns is ns.level.level2.root assert ns.level.level2.vargetter.getValue() == "/ test" def test_hash_variable(self): # hash variable ns = Namespace() vl = VariableLoader() vl.fill(ns, "tests/vars/variables", "testvars") assert ns.level.linux.getFullname() == "level.linux" assert ns.level.linux.ver.fullname == "level.linux.ver" assert ns.level.linux.ver.getValue() == "1.0" assert ns.level.linux.shortname.getValue() == "CLD" # проверка обновления значения hash переменной при обновлении # значения у зависимой перемнной ns.level.version.setValue("2.0") assert ns.level.linux.ver.getValue() == "2.0" # проверка установки значения hash переменной ns.level.linux.ver.setValue("3.0") assert ns.level.linux.ver.getValue() == "3.0" # после установки хотя бы одного значения в hash переменной # обновление остальных прекращаются до инвалидации (так как # значения рассматриваются комплексно) ns.level.myshortname.setValue("CLDG") assert ns.level.linux.shortname.getValue() == "CLD" # проверка попытки изменить readonly переменную with pytest.raises(VariableError): ns.level.linux.shortname.setValue("CLDX") # проверка сбора значения hash перемнной ns.level.linux.invalidate() assert ns.level.linux.ver.getValue() == "2.0" assert ns.level.linux.shortname.getValue() == "CLDG" assert ns.level.linux.test.getValue() == "my test - 2.0" # проверка обновления значения переменной, используеющей одно # из значений hash переменной assert ns.level.shortname_test.getValue() == "CLDG test" ns.level.linux.shortname.setValue("CLDX", force=True) assert ns.level.shortname_test.getValue() == "CLDX test" def test_table_variable(self): # table variable ns = Namespace() vl = VariableLoader() vl.fill(ns, "tests/vars/variables", "testvars") assert ns.level.device[0].dev.getValue() == "/dev/sda" assert ns.level.device[1].dev.getValue() == "/dev/sdb" assert ns.level.device.getValue() == [{"dev": "/dev/sda", "type": "hdd", "name": "Samsung SSD"}, {"dev": "/dev/sdb", "type": "flash", "name": "Transcend 64GB"}] assert ns.level.device[1].type.getValue() == "flash" # проверка обновления списка пространства имён у табличной переменной ns.level.devicelist.setValue(["/dev/sda", "/dev/sdb", "/dev/sdc"]) assert ns.level.device[2].type.getValue() == "usbhdd" assert [x.type.getValue() for x in ns.level.device] == ["hdd", "flash", "usbhdd"] assert ns.level.device_child.getValue() == "hdd" ns.level.devicelist.setValue(["/dev/sda", "/dev/sdb"]) ns.level.device[0].type.setValue("flash") assert ns.level.device.getValue() == [{"dev": "/dev/sda", "type": "flash", "name": "Samsung SSD"}, {"dev": "/dev/sdb", "type": "flash", "name": "Transcend 64GB"}] assert ns.level.device_child.getValue() == "flash" # после установки хотя бы одного значения в table переменной # обновление остальных прекращаются до инвалидации (так как # значения рассматриваются комплексно) ns.level.devicelist.setValue(["/dev/sda", "/dev/sdb", "/dev/sdc"]) assert [x.dev.getValue() for x in ns.level.device] == ["/dev/sda", "/dev/sdb"] ns.level.device.invalidate() assert [x.dev.getValue() for x in ns.level.device] == ["/dev/sda", "/dev/sdb", "/dev/sdc"] # проверить на повторное изменение, убедится, что _drop_child # отрабатывает ns.level.devicelist.setValue(["/dev/sda", "/dev/sdb", "/dev/sdc", "/dev/sdd"]) ns.level.device.invalidate() assert [x.dev.getValue() for x in ns.level.device] == ["/dev/sda", "/dev/sdb", "/dev/sdc", "/dev/sdd"] def test_wrong_table_variable(self): class Testtable(TableVariable): class Data(TableVariable.Data): def get(self): return [{'dev': '123', 'name': '098'}] ns = Namespace() ns.addNamespace(Namespace("test")) ns.test.addNamespace(Namespace("test2")) error_message = ("Missed 'hash_vars' attribute for table " "variable test.test2.testtable") with pytest.raises(VariableError) as e: ns.test.test2.addNamespace(Testtable("testtable", ns.test.test2)) assert str(e.value) == error_message def test_wrong_hash_variable(self): class Testhash(HashVariable): class Data(HashVariable.Data): def get(self): return {'dev': '123', 'name': '098'} ns = Namespace() ns.addNamespace(Namespace("test")) ns.test.addNamespace(Namespace("test2")) error_message = ("Missed 'hash_vars' attribute for hash " "variable test.test2.testhash") with pytest.raises(VariableError) as e: ns.test.test2.addNamespace(Testhash("testhash", ns.test.test2)) assert str(e.value) == error_message def test_namespace_iteration(self): ns = Namespace() ns0 = ns.addNamespace() ns0.addStringVariable("test", "123") ns1 = ns.addNamespace() ns1.addStringVariable("test", "234") ns2 = ns.addNamespace() ns2.addStringVariable("test", "456") assert [x.test.getValue() for x in ns] == ["123", "234", "456"] def test_subnamespace(self): ns = Namespace() vl = VariableLoader() vl.fill(ns, "tests/vars/variables", "testvars") assert ns.level.level3.my_var1.getValue() == "testing" assert ns.level.level3.myvar2.getValue() == "testing2" def test_variable_not_found(self): ns = Namespace() vl = VariableLoader() vl.fill(ns, "tests/vars/variables", "testvars") error_message = "Variable or namespace level.level3.myvar3 not found" with pytest.raises(VariableError) as e: ns.level.level3.myvar3.getValue() assert str(e.value) == error_message # TODO: тест использует значения на конкретной машине # def test_simple(self): # ns = Namespace() # vl = VariableLoader() # vl.fill(ns, *VariableLoader.default()) # # нужно исправить тест, так # # assert [x.name.getValue() for x in ns.os.gentoo.repositories] ==\ # ["gentoo","distros","calculate","custom"] # assert ns.os.gentoo.make_profile.getValue() ==\ # "/etc/portage/make.profile" # assert ns.os.gentoo.profile.path.getValue() ==\ # "/var/db/repos/distros/profiles/CLD/amd64/20" # assert ns.os.gentoo.profile.name.getValue() == "distros:CLD/amd64/20" def test_profile_filler(self): ns = Namespace() vl = VariableLoader() vl.fill(ns, "tests/vars/variables", "testvars") class ProfileFillerTest(ProfileFiller): def getRepositoryMap(self, ns): curdir = os.getcwd() return {'distros': os.path.join(curdir, "tests/utils/gentoo/repos/distros"), 'calculate': os.path.join(curdir, "tests/utils/gentoo/repos/calculate"), 'gentoo': os.path.join(curdir, "tests/utils/gentoo/portage")} assert ns.os.hashvar.value1.getValue() == "test1" assert ns.os.hashvar.value2.getValue() == "test2" assert ns.os.tablevar[0].dev.getValue() == "/dev/sdb1" assert ns.os.tablevar[1].dev.getValue() == "/dev/sdb2" pf = ProfileFillerTest() pf.fill(ns, "tests/utils/gentoo/repos/distros/profiles/CLD/amd64") assert ns.os.linux.test.getValue() == "test" assert ns.os.linux.arch.getValue() == "amd64" assert ns.os.linux.title.getValue() == "Calculate Linux Desktop KDE 20" # Hash assert ns.os.hashvar.value1.getValue() == "20" assert ns.os.hashvar.value2.getValue() == "30" ns.os.hashvar.value1.setValue("40") assert ns.os.hashvar.value1.getValue() == "40" ns.os.hashvar.value1.invalidate() assert ns.os.hashvar.value1.getValue() == "20" # Table assert ns.os.tablevar[0].dev.getValue() == "/dev/sda1" assert ns.os.tablevar[1].dev.getValue() == "/dev/sda2" assert ns.os.tablevar[2].dev.getValue() == "/dev/sda5" ns.os.tablevar[0].dev.invalidate() assert ns.os.tablevar[0].dev.getValue() == "/dev/sda1" assert ns.os.tablevar[1].dev.getValue() == "/dev/sda2" assert ns.os.tablevar[2].dev.getValue() == "/dev/sda5" def test_fill_namespace_by_module(self): pass # ns = Namespace() # vl = VariableLoader() # vl.fill(ns, *VariableLoader.default()) # assert "os" in ns # assert "config" in ns.os.gentoo # assert "main" in ns # assert ns.os.gentoo.config.getValue() is not None