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

788 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.add_string_variable("test", "12345")
assert ns.test.get_value() == "12345"
ns.add_string_variable("zxcv", "23456")
assert ns.zxcv.get_value() == "23456"
def test_create_ns_with_vars(self):
ns = Namespace()
ns.add_namespace(Namespace("os"))
ns.os.add_string_variable("test", "123")
ns.os.add_namespace(Namespace("linux"))
ns.os.linux.add_string_variable("shortname", "CLD")
assert ns.os.test.get_value() == "123"
assert ns.os["test"].get_value() == "123"
assert ns.os.linux.shortname.get_value() == "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.get_value() == "123"
assert ns.os.linux.shortname.get_value() == "CLD"
assert ns.os.linux.fullname.get_value() == "Calculate Linux Desktop"
assert ns.os.linux.root == ns
nsif.fill(ns, """
[os][linux]
shortname = CLDX
""")
assert ns.os.linux.shortname.get_value() == "CLDX"
assert ns.os.linux.fullname.get_value() == "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.get_value() == "123,345"
nsif.fill(ns, """
[os]
test -= 123
""")
assert ns.os.test.get_value() == "345"
nsif.fill(ns, """
[os]
test += asdf,qwer,zxcv
""")
assert ns.os.test.get_value() == "345,asdf,qwer,zxcv"
nsif.fill(ns, """
[os]
test -= asdf,zxcv
""")
assert ns.os.test.get_value() == "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.get_value() 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.get_value() 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.get_value() 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.get_value() == "1"
assert ns.custom.test2.zxcv.get_value() == "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.add_string_variable("test", "zxcv")
ns.add_namespace(os)
assert ns.os.test.get_value() == "zxcv"
assert ns.os["test"].get_value() == "zxcv"
assert "test" in ns.os
ns.os.test.set_value("123")
assert ns.os.test.get_value() == "123"
ns.os["test"].set_value("234")
assert ns.os.test.get_value() == "234"
def test_variable_get_value(self):
class TestVar(Variable):
def get(self):
return "A"
var = TestVar("test")
assert var.get_value() == "A"
def test_namespace_lookup(self):
ns = Namespace()
os = Namespace("os")
device = Namespace("device")
linux = Namespace("linux")
ns.add_namespace(os)
os.add_namespace(linux)
os.add_namespace(device)
device1 = device.add_namespace()
device1.add_string_variable("dev", "/dev/sda")
device2 = device.add_namespace()
device2.add_string_variable("dev", "/dev/sdb")
device3 = device.add_namespace()
device3.add_string_variable("dev", "/dev/sdc")
ns.add_string_variable("first", "first")
os.add_string_variable("second", "second")
linux.add_string_variable("third", "third")
assert ns.first.get_value() == "first"
assert ns.root.os.second.get_value() == "second"
assert ns.os.second.get_value() == "second"
assert os.root.os.second.get_value() == "second"
assert os.second.get_value() == "second"
assert linux.third.get_value() == "third"
assert linux.root.os.second.get_value() == "second"
with pytest.raises(VariableNotFoundError):
os.third
assert ns.os.device[0].dev.get_value() == "/dev/sda"
assert ns.os.device["0"].dev.get_value() == "/dev/sda"
assert ns.os.device[1].dev.get_value() == "/dev/sdb"
assert ns.os.device[2].dev.get_value() == "/dev/sdc"
assert ns.os.device.parent.second.get_value() == "second"
assert ns.os.device.parent.parent.os.second.get_value() == "second"
assert ns.os.device.parent.parent.parent.os.second.\
get_value() == "second"
def test_variable_get_value_by_variable(self):
class TestVar1(Variable):
def get(self):
return "%s,B" % self.vars.test2.get_value(self)
class TestVar2(Variable):
def get(self):
return "A"
ns = Namespace()
ns.add_variable(TestVar1("test1"))
ns.add_variable(TestVar2("test2"))
assert ns.test1.get_value() == "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.get_value(self)
ns = Namespace()
test1 = TestVar1("test1")
ns.add_variable(test1)
ns.add_string_variable("test2", "A")
assert ns.test1.get_value() == "A,B"
assert test1.counter == 1
# test for get cached variable value
assert ns.test1.get_value() == "A,B"
assert test1.counter == 1
# change value of test2 for recalculate test1
ns.test2.set_value("C")
assert ns.test1.get_value() == "C,B"
assert test1.counter == 2
# change value of test2 for recalculate test1
ns.test2.set_value("D")
assert ns.test1.get_value() == "D,B"
assert test1.counter == 3
def test_cyclic_variable(self):
class TestVar1(Variable):
def get(self):
return "%s,test1" % self.vars.test2.get_value(self)
class TestVar2(Variable):
def get(self):
return "%s,test2" % self.vars.test3.get_value(self)
class TestVar3(Variable):
def get(self):
return "%s,test3" % self.vars.test1.get_value(self)
test1 = TestVar1("test1")
test2 = TestVar2("test2")
test3 = TestVar3("test3")
ns = Namespace()
ns.add_variable(test1)
ns.add_variable(test2)
ns.add_variable(test3)
with pytest.raises(CyclicVariableError) as e:
ns.test1.get_value()
assert e.value.queue[:-1] == ("test1", "test2", "test3")
with pytest.raises(VariableError) as e:
ns.test1.get_value()
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.get_value(self)
class TestVar2(Variable):
def get(self):
return "ZZZZ"
test1 = TestVar1("test1")
test2 = TestVar2("test2")
ns = Namespace()
ns.add_variable(test1)
ns.add_variable(test2)
assert test1.get_value() == "ZZZZ,test1"
test1.set_value("VVVV")
assert test1.get_value() == "VVVV"
assert test1.counter == 1
test2.set_value("XXXX")
assert test1.get_value() == "VVVV"
assert test1.counter == 1
test1.invalidate()
assert test1.get_value() == "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.get_value(self):
return "%s,test1" % self.vars.vara.get_value(self)
else:
return "%s,test1" % self.vars.varb.get_value(self)
vartest = VarTest("vartest")
ns = Namespace()
ns.add_variable(vartest)
ns.add_string_variable("vara", "vara")
ns.add_string_variable("varb", "varb")
ns.add_string_variable("ifvar", "true")
assert vartest.get_value() == "vara,test1"
assert vartest.counter == 1
ns.vara.set_value("varc")
assert vartest.get_value() == "varc,test1"
assert vartest.counter == 2
ns.ifvar.set_value("")
assert vartest.get_value() == "varb,test1"
assert vartest.counter == 3
ns.vara.set_value("vard")
assert vartest.get_value() == "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.get_value() == "test1"
with pytest.raises(VariableError):
test1.set_value("test2")
assert test1.get_value() == "test1"
test1.set_value("test2", force=True)
assert test1.get_value() == "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.set_value("test3")
test1.set_value("test2")
assert test1.get_value() == "test2"
def test_integer_variable(self):
class TestVar1(Variable):
properties = [IntegerVariable]
test1 = TestVar1("test1")
with pytest.raises(VariableError):
test1.set_value("test3")
test1.set_value("33")
assert test1.get_value() == 33
test1.set_value("-33")
assert test1.get_value() == -33
def test_default_value_property(self):
class TestVar1(Variable):
def get(self):
return "123"
test1 = TestVar1("test1")
assert test1.get_value() == "123"
test1.set_value("987")
test1.addProperty(DefaultValue("567"))
assert test1.get_value() == "987"
test1.invalidate()
assert test1.get_value() == "567"
def test_get_comment(self):
class TestVar1(Variable):
def get(self):
return "123"
class TestVar2(Variable):
def get(self):
return "234"
def get_comment(self):
return "[%s]" % self.get_value()
class TestVar3(Variable):
def get(self):
return "ZXC %s" % self.vars.test2.get_comment_value(self)
ns = Namespace()
test1 = TestVar1("test1")
assert test1.get_value() == "123"
assert test1.get_comment() == "123"
test2 = TestVar2("test2")
assert test2.get_value() == "234"
assert test2.get_comment() == "[234]"
test3 = TestVar3("test3")
ns.add_variable(test1)
ns.add_variable(test2)
ns.add_variable(test3)
assert test3.get_value() == "ZXC [234]"
test2.set_value("567")
assert test3.get_value() == "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 choice_comment(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.choice_comment()
assert test2.choice() == ["test1", "test2"]
assert test2.choice_comment() == [("test1", "test1"),
("test2", "test2")]
assert test3.choice() == ["test1", "test2"]
assert test3.choice_comment() == [("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.get_value() == "simple value"
assert ns.level.uselocalsimple.get_value() == "Using simple value"
assert ns.level.usefullsimple.get_value() == "Using simple value"
with pytest.raises(VariableError):
ns.level.badchoice.choice()
with pytest.raises(VariableError):
ns.level.badchoice.choice_comment()
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.choice_comment() == [
("/dev/sda1", "SWAP"),
("/dev/sda2", "ROOT"),
("/dev/sda3", "DATA")]
ns.level.disks.set_value(["/dev/sda2", "/dev/sda1"])
assert ns.level.disks.get_value() == ["/dev/sda2", "/dev/sda1"]
assert ns.level.comment_choice.choice() == ["/dev/sda2", "/dev/sda1"]
assert ns.level.comment_choice.choice_comment() == [
("/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.get_value() == "/ test"
def test_hash_variable(self):
# hash variable
ns = Namespace()
vl = VariableLoader()
vl.fill(ns, "tests/vars/variables", "testvars")
assert ns.level.linux.get_fullname() == "level.linux"
assert ns.level.linux.ver.fullname == "level.linux.ver"
assert ns.level.linux.ver.get_value() == "1.0"
assert ns.level.linux.shortname.get_value() == "CLD"
# проверка обновления значения hash переменной при обновлении
# значения у зависимой перемнной
ns.level.version.set_value("2.0")
assert ns.level.linux.ver.get_value() == "2.0"
# проверка установки значения hash переменной
ns.level.linux.ver.set_value("3.0")
assert ns.level.linux.ver.get_value() == "3.0"
# после установки хотя бы одного значения в hash переменной
# обновление остальных прекращаются до инвалидации (так как
# значения рассматриваются комплексно)
ns.level.myshortname.set_value("CLDG")
assert ns.level.linux.shortname.get_value() == "CLD"
# проверка попытки изменить readonly переменную
with pytest.raises(VariableError):
ns.level.linux.shortname.set_value("CLDX")
# проверка сбора значения hash перемнной
ns.level.linux.invalidate()
assert ns.level.linux.ver.get_value() == "2.0"
assert ns.level.linux.shortname.get_value() == "CLDG"
assert ns.level.linux.test.get_value() == "my test - 2.0"
# проверка обновления значения переменной, используеющей одно
# из значений hash переменной
assert ns.level.shortname_test.get_value() == "CLDG test"
ns.level.linux.shortname.set_value("CLDX", force=True)
assert ns.level.shortname_test.get_value() == "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.get_value() == "/dev/sda"
assert ns.level.device[1].dev.get_value() == "/dev/sdb"
assert ns.level.device.get_value() == [{"dev": "/dev/sda",
"type": "hdd",
"name": "Samsung SSD"},
{"dev": "/dev/sdb",
"type": "flash",
"name": "Transcend 64GB"}]
assert ns.level.device[1].type.get_value() == "flash"
# проверка обновления списка пространства имён у табличной переменной
ns.level.devicelist.set_value(["/dev/sda", "/dev/sdb", "/dev/sdc"])
assert ns.level.device[2].type.get_value() == "usbhdd"
assert [x.type.get_value() for x in ns.level.device] == ["hdd",
"flash",
"usbhdd"]
assert ns.level.device_child.get_value() == "hdd"
ns.level.devicelist.set_value(["/dev/sda", "/dev/sdb"])
ns.level.device[0].type.set_value("flash")
assert ns.level.device.get_value() == [{"dev": "/dev/sda",
"type": "flash",
"name": "Samsung SSD"},
{"dev": "/dev/sdb",
"type": "flash",
"name": "Transcend 64GB"}]
assert ns.level.device_child.get_value() == "flash"
# после установки хотя бы одного значения в table переменной
# обновление остальных прекращаются до инвалидации (так как
# значения рассматриваются комплексно)
ns.level.devicelist.set_value(["/dev/sda", "/dev/sdb", "/dev/sdc"])
assert [x.dev.get_value() for x in ns.level.device] == ["/dev/sda",
"/dev/sdb"]
ns.level.device.invalidate()
assert [x.dev.get_value() for x in ns.level.device] == ["/dev/sda",
"/dev/sdb",
"/dev/sdc"]
# проверить на повторное изменение, убедится, что _drop_child
# отрабатывает
ns.level.devicelist.set_value(["/dev/sda", "/dev/sdb",
"/dev/sdc", "/dev/sdd"])
ns.level.device.invalidate()
assert [x.dev.get_value() 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.add_namespace(Namespace("test"))
ns.test.add_namespace(Namespace("test2"))
error_message = ("Missed 'hash_vars' attribute for table "
"variable test.test2.testtable")
with pytest.raises(VariableError) as e:
ns.test.test2.add_namespace(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.add_namespace(Namespace("test"))
ns.test.add_namespace(Namespace("test2"))
error_message = ("Missed 'hash_vars' attribute for hash "
"variable test.test2.testhash")
with pytest.raises(VariableError) as e:
ns.test.test2.add_namespace(Testhash("testhash", ns.test.test2))
assert str(e.value) == error_message
def test_namespace_iteration(self):
ns = Namespace()
ns0 = ns.add_namespace()
ns0.add_string_variable("test", "123")
ns1 = ns.add_namespace()
ns1.add_string_variable("test", "234")
ns2 = ns.add_namespace()
ns2.add_string_variable("test", "456")
assert [x.test.get_value() 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.get_value() == "testing"
assert ns.level.level3.myvar2.get_value() == "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.get_value()
assert str(e.value) == error_message
# TODO: тест использует значения на конкретной машине
# def test_simple(self):
# ns = Namespace()
# vl = VariableLoader()
# vl.fill(ns, *VariableLoader.default())
# # нужно исправить тест, так
# # assert [x.name.get_value() for x in ns.os.gentoo.repositories] ==\
# ["gentoo","distros","calculate","custom"]
# assert ns.os.gentoo.make_profile.get_value() ==\
# "/etc/portage/make.profile"
# assert ns.os.gentoo.profile.path.get_value() ==\
# "/var/db/repos/distros/profiles/CLD/amd64/20"
# assert ns.os.gentoo.profile.name.get_value() ==\
# "distros:CLD/amd64/20"
def test_profile_filler(self):
ns = Namespace()
vl = VariableLoader()
vl.fill(ns, "tests/vars/variables", "testvars")
class ProfileFillerTest(ProfileFiller):
def get_repository_map(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.get_value() == "test1"
assert ns.os.hashvar.value2.get_value() == "test2"
assert ns.os.tablevar[0].dev.get_value() == "/dev/sdb1"
assert ns.os.tablevar[1].dev.get_value() == "/dev/sdb2"
pf = ProfileFillerTest()
pf.fill(ns, "tests/utils/gentoo/repos/distros/profiles/CLD/amd64")
assert ns.os.linux.test.get_value() == "test"
assert ns.os.linux.arch.get_value() == "amd64"
assert ns.os.linux.title.get_value() ==\
"Calculate Linux Desktop KDE 20"
# Hash
assert ns.os.hashvar.value1.get_value() == "20"
assert ns.os.hashvar.value2.get_value() == "30"
ns.os.hashvar.value1.set_value("40")
assert ns.os.hashvar.value1.get_value() == "40"
ns.os.hashvar.value1.invalidate()
assert ns.os.hashvar.value1.get_value() == "20"
# Table
assert ns.os.tablevar[0].dev.get_value() == "/dev/sda1"
assert ns.os.tablevar[1].dev.get_value() == "/dev/sda2"
assert ns.os.tablevar[2].dev.get_value() == "/dev/sda5"
ns.os.tablevar[0].dev.invalidate()
assert ns.os.tablevar[0].dev.get_value() == "/dev/sda1"
assert ns.os.tablevar[1].dev.get_value() == "/dev/sda2"
assert ns.os.tablevar[2].dev.get_value() == "/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.get_value() is not None