You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
calculate-utils-4-lib/tests/vars/test_namespace.py

786 lines
27 KiB

4 years ago
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
4 years ago
@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