# coding: utf-8
from autopath import do_autopath
do_autopath()

from tiramisu.setting import groups, owners
from tiramisu.config import Config
from tiramisu.option import StrOption, OptionDescription, submulti
from tiramisu.value import SubMulti, Multi
from tiramisu.error import SlaveError

from py.test import raises


def return_val(val=None):
    if val is None:
        return 'val'
    else:
        return val


def return_list(value=None):
    return ['val', 'val']


def return_list2(value=None):
    return [['val', 'val']]


def test_submulti():
    multi = StrOption('multi', '', multi=submulti)
    multi2 = StrOption('multi2', '', default_multi='yes', multi=submulti)
    multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti)
    od = OptionDescription('od', '', [multi, multi2, multi3])
    cfg = Config(od)
    assert cfg.getowner(multi) == owners.default
    assert cfg.multi == []
    assert cfg.getowner(multi) == owners.default
    assert cfg.getowner(multi) == owners.default
    assert cfg.multi3 == [['yes']]
    assert cfg.multi3[0] == ['yes']
    assert cfg.multi3[0][0] == 'yes'
    cfg.multi3[0]
    assert cfg.getowner(multi) == owners.default


def test_append_submulti():
    multi = StrOption('multi', '', multi=submulti)
    multi2 = StrOption('multi2', '', default_multi='yes', multi=submulti)
    multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti)
    od = OptionDescription('od', '', [multi, multi2, multi3])
    cfg = Config(od)
    owner = cfg.cfgimpl_get_settings().getowner()
    assert cfg.multi == []
    assert cfg.getowner(multi) == owners.default
    cfg.multi.append()
    assert cfg.getowner(multi) == owner
    assert cfg.multi == [[]]
    cfg.multi.append(['no'])
    assert cfg.multi == [[], ['no']]
    #
    assert cfg.multi2 == []
    assert cfg.getowner(multi2) == owners.default
    cfg.multi2.append()
    assert cfg.getowner(multi2) == owner
    assert cfg.multi2 == [['yes']]
    cfg.multi2.append(['no'])
    assert cfg.multi2 == [['yes'], ['no']]
    #
    assert cfg.multi3 == [['yes']]
    assert cfg.getowner(multi3) == owners.default
    cfg.multi3.append()
    assert cfg.getowner(multi3) == owner
    assert cfg.multi3 == [['yes'], []]
    cfg.multi3.append(['no'])
    assert cfg.multi3 == [['yes'], [], ['no']]


def test_append_unvalide_submulti():
    multi = StrOption('multi', '', multi=submulti)
    multi2 = StrOption('multi2', '', default_multi='yes', multi=submulti)
    multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti)
    od = OptionDescription('od', '', [multi, multi2, multi3])
    cfg = Config(od)
    assert cfg.multi == []
    assert cfg.getowner(multi) == owners.default
    raises(ValueError, "cfg.multi.append(1)")
    assert cfg.multi == []
    assert cfg.getowner(multi) == owners.default
    #
    assert cfg.multi2 == []
    raises(ValueError, "cfg.multi2.append('no')")
    assert cfg.getowner(multi) == owners.default
    assert cfg.multi2 == []
    #
    assert cfg.multi3 == [['yes']]
    assert cfg.getowner(multi3) == owners.default
    raises(ValueError, "cfg.multi3[0].append(1)")
    assert cfg.multi3 == [['yes']]
    assert cfg.getowner(multi3) == owners.default
    raises(ValueError, "cfg.multi3[0].append([])")
    assert cfg.multi3 == [['yes']]
    assert cfg.getowner(multi3) == owners.default


def test_pop_submulti():
    multi = StrOption('multi', '', multi=submulti)
    multi2 = StrOption('multi2', '', default_multi='yes', multi=submulti)
    multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti)
    od = OptionDescription('od', '', [multi, multi2, multi3])
    cfg = Config(od)
    owner = cfg.cfgimpl_get_settings().getowner()
    assert cfg.multi == []
    assert cfg.getowner(multi3) == owners.default
    cfg.multi = [['no', 'yes'], ['peharps']]
    assert cfg.getowner(multi) == owner
    assert cfg.multi == [['no', 'yes'], ['peharps']]
    cfg.multi[0].pop(1)
    assert cfg.multi == [['no'], ['peharps']]
    cfg.multi[0].pop(0)
    assert cfg.multi == [[], ['peharps']]
    cfg.multi.pop(1)
    assert cfg.multi == [[]]
    cfg.multi.pop(0)
    assert cfg.multi == []
    #
    assert cfg.multi3 == [['yes']]
    assert cfg.getowner(multi3) == owners.default
    cfg.multi3.pop(0)
    assert cfg.getowner(multi) == owner
    assert cfg.multi3 == []
    del(cfg.multi3)
    assert cfg.getowner(multi3) == owners.default
    cfg.multi3[0].pop(0)
    assert cfg.getowner(multi3) == owner
    assert cfg.multi3 == [[]]


def test_sort_submulti():
    multi = StrOption('multi', '', multi=submulti)
    multi2 = StrOption('multi2', '', default_multi='yes', multi=submulti)
    multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti)
    od = OptionDescription('od', '', [multi, multi2, multi3])
    cfg = Config(od)
    owner = cfg.cfgimpl_get_settings().getowner()
    assert cfg.multi == []
    assert cfg.getowner(multi) == owners.default
    cfg.multi.sort()
    assert cfg.getowner(multi) == owner
    cfg.multi = [['no', 'yes'], ['peharps']]
    cfg.multi.sort()
    assert cfg.multi == [['no', 'yes'], ['peharps']]
    cfg.multi.sort(reverse=True)
    assert cfg.multi == [['peharps'], ['no', 'yes']]
    cfg.multi[1].sort(reverse=True)
    assert cfg.multi == [['peharps'], ['yes', 'no']]
    cfg.multi[1].sort()
    assert cfg.multi == [['peharps'], ['no', 'yes']]
    #
    assert cfg.multi3 == [['yes']]
    assert cfg.getowner(multi3) == owners.default
    cfg.multi3.sort()
    assert cfg.getowner(multi) == owner
    assert cfg.multi3 == [['yes']]
    del(cfg.multi3)
    assert cfg.getowner(multi3) == owners.default
    cfg.multi3[0].sort()
    assert cfg.getowner(multi) == owner
    assert cfg.multi3 == [['yes']]


def test_reverse_submulti():
    multi = StrOption('multi', '', multi=submulti)
    multi2 = StrOption('multi2', '', default_multi='yes', multi=submulti)
    multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti)
    od = OptionDescription('od', '', [multi, multi2, multi3])
    cfg = Config(od)
    owner = cfg.cfgimpl_get_settings().getowner()
    assert cfg.multi == []
    assert cfg.getowner(multi) == owners.default
    cfg.multi.reverse()
    assert cfg.getowner(multi) == owner
    cfg.multi = [['no', 'yes'], ['peharps']]
    cfg.multi.reverse()
    assert cfg.multi == [['peharps'], ['no', 'yes']]
    cfg.multi[1].reverse()
    assert cfg.multi == [['peharps'], ['yes', 'no']]
    #
    assert cfg.multi3 == [['yes']]
    assert cfg.getowner(multi3) == owners.default
    cfg.multi3.reverse()
    assert cfg.getowner(multi) == owner
    assert cfg.multi3 == [['yes']]
    del(cfg.multi3)
    assert cfg.getowner(multi3) == owners.default
    cfg.multi3[0].reverse()
    assert cfg.getowner(multi) == owner
    assert cfg.multi3 == [['yes']]


def test_insert_submulti():
    multi = StrOption('multi', '', multi=submulti)
    multi2 = StrOption('multi2', '', default_multi='yes', multi=submulti)
    multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti)
    od = OptionDescription('od', '', [multi, multi2, multi3])
    cfg = Config(od)
    owner = cfg.cfgimpl_get_settings().getowner()
    assert cfg.multi == []
    assert cfg.getowner(multi) == owners.default
    cfg.multi.insert(0, ['no'])
    assert cfg.getowner(multi) == owner
    assert cfg.multi == [['no']]
    assert isinstance(cfg.multi, Multi)
    assert isinstance(cfg.multi[0], SubMulti)
    #
    assert cfg.multi3 == [['yes']]
    assert cfg.getowner(multi3) == owners.default
    cfg.multi3.insert(1, [])
    assert cfg.getowner(multi3) == owner
    assert cfg.multi3 == [['yes'], []]
    cfg.multi3.insert(0, ['no'])
    assert cfg.multi3 == [['no'], ['yes'], []]
    del(cfg.multi3)
    assert cfg.getowner(multi3) == owners.default
    cfg.multi3[0].insert(0, 'no')
    assert cfg.getowner(multi3) == owner
    assert cfg.multi3 == [['no', 'yes']]


def test_insert_unvalide_submulti():
    multi = StrOption('multi', '', multi=submulti)
    multi2 = StrOption('multi2', '', default_multi='yes', multi=submulti)
    multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti)
    od = OptionDescription('od', '', [multi, multi2, multi3])
    cfg = Config(od)
    assert cfg.multi == []
    assert cfg.getowner(multi) == owners.default
    raises(ValueError, "cfg.multi.insert(0, 1)")
    assert cfg.multi == []
    assert cfg.getowner(multi) == owners.default
    #
    assert cfg.multi3 == [['yes']]
    assert cfg.getowner(multi3) == owners.default
    raises(ValueError, "cfg.multi3[0].insert(0, 1)")
    assert cfg.multi3 == [['yes']]
    assert cfg.getowner(multi3) == owners.default


def test_extend_submulti():
    multi = StrOption('multi', '', multi=submulti)
    multi2 = StrOption('multi2', '', default_multi='yes', multi=submulti)
    multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti)
    od = OptionDescription('od', '', [multi, multi2, multi3])
    cfg = Config(od)
    owner = cfg.cfgimpl_get_settings().getowner()
    assert cfg.multi == []
    assert cfg.getowner(multi) == owners.default
    cfg.multi.extend([['no']])
    assert cfg.getowner(multi) == owner
    assert cfg.multi == [['no']]
    assert isinstance(cfg.multi, Multi)
    assert isinstance(cfg.multi[0], SubMulti)
    #
    assert cfg.multi3 == [['yes']]
    assert cfg.getowner(multi3) == owners.default
    cfg.multi3.extend([[]])
    assert cfg.getowner(multi3) == owner
    assert cfg.multi3 == [['yes'], []]
    cfg.multi3.extend([['no']])
    assert cfg.multi3 == [['yes'], [], ['no']]
    del(cfg.multi3)
    assert cfg.getowner(multi3) == owners.default
    cfg.multi3[0].extend(['no'])
    assert cfg.getowner(multi3) == owner
    assert cfg.multi3 == [['yes', 'no']]


def test_extend_unvalide_submulti():
    multi = StrOption('multi', '', multi=submulti)
    multi2 = StrOption('multi2', '', default_multi='yes', multi=submulti)
    multi3 = StrOption('multi3', '', default=[['yes']], multi=submulti)
    od = OptionDescription('od', '', [multi, multi2, multi3])
    cfg = Config(od)
    assert cfg.multi == []
    assert cfg.getowner(multi) == owners.default
    raises(ValueError, "cfg.multi.extend([[1]])")
    assert cfg.multi == []
    assert cfg.getowner(multi) == owners.default
    #
    assert cfg.multi3 == [['yes']]
    assert cfg.getowner(multi3) == owners.default
    raises(ValueError, "cfg.multi3[0].extend([1])")
    assert cfg.multi3 == [['yes']]
    assert cfg.getowner(multi3) == owners.default


def test_callback_submulti_str():
    multi = StrOption('multi', '', multi=submulti, callback=return_val)
    od = OptionDescription('od', '', [multi])
    cfg = Config(od)
    cfg.read_write()
    owner = cfg.cfgimpl_get_settings().getowner()
    assert cfg.getowner(multi) == owners.default
    assert cfg.multi == [['val']]
    cfg.multi.append()
    assert cfg.getowner(multi) == owner
    assert cfg.multi == [['val'], ['val']]
    del(cfg.multi)
    assert cfg.getowner(multi) == owners.default
    cfg.multi[0].append()
    assert cfg.getowner(multi) == owner
    assert cfg.multi == [['val', 'val']]


def test_callback_submulti_list():
    multi = StrOption('multi', '', multi=submulti, callback=return_list)
    od = OptionDescription('od', '', [multi])
    cfg = Config(od)
    cfg.read_write()
    owner = cfg.cfgimpl_get_settings().getowner()
    assert cfg.multi == [['val', 'val']]
    assert cfg.getowner(multi) == owners.default
    cfg.multi.append()
    assert cfg.getowner(multi) == owner
    assert cfg.multi == [['val', 'val'], ['val', 'val']]
    cfg.multi.append()
    assert cfg.multi == [['val', 'val'], ['val', 'val'], ['val', 'val']]
    del(cfg.multi)
    assert cfg.getowner(multi) == owners.default
    cfg.multi[0].append()
    assert cfg.getowner(multi) == owner
    assert cfg.multi == [['val', 'val', None]]


def test_callback_submulti_list_list():
    multi = StrOption('multi', '', multi=submulti, callback=return_list2)
    od = OptionDescription('od', '', [multi])
    cfg = Config(od)
    cfg.read_write()
    owner = cfg.cfgimpl_get_settings().getowner()
    assert cfg.multi == [['val', 'val']]
    assert cfg.getowner(multi) == owners.default
    cfg.multi.append()
    assert cfg.getowner(multi) == owner
    assert cfg.multi == [['val', 'val'], []]
    del(cfg.multi)
    assert cfg.getowner(multi) == owners.default
    cfg.multi[0].append()
    assert cfg.getowner(multi) == owner
    assert cfg.multi == [['val', 'val', None]]
    del(cfg.multi)
    cfg.multi.append()


#FIXME multi sur une master


def test_groups_with_master_submulti():
    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
    interface1.impl_set_group_type(groups.master)
    assert interface1.impl_get_group_type() == groups.master


def test_groups_with_master_in_config_submulti():
    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
    interface1.impl_set_group_type(groups.master)
    Config(interface1)
    assert interface1.impl_get_group_type() == groups.master


def test_values_with_master_and_slaves_submulti():
    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
    interface1.impl_set_group_type(groups.master)
    maconfig = OptionDescription('toto', '', [interface1])
    cfg = Config(maconfig)
    cfg.read_write()
    owner = cfg.cfgimpl_get_settings().getowner()
    assert interface1.impl_get_group_type() == groups.master
    assert cfg.getowner(ip_admin_eth0) == owners.default
    assert cfg.getowner(netmask_admin_eth0) == owners.default
    assert cfg.ip_admin_eth0.netmask_admin_eth0 == []
    cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.145")
    assert cfg.ip_admin_eth0.ip_admin_eth0 == ["192.168.230.145"]
    assert cfg.ip_admin_eth0.netmask_admin_eth0 == [[]]
    assert cfg.getowner(ip_admin_eth0) == owner
    assert cfg.getowner(netmask_admin_eth0) == owners.default
    cfg.ip_admin_eth0.ip_admin_eth0 = ["192.168.230.145", "192.168.230.147"]
    assert cfg.ip_admin_eth0.netmask_admin_eth0 == [[], []]
    raises(SlaveError, 'cfg.ip_admin_eth0.netmask_admin_eth0.append(None)')
    raises(SlaveError, 'cfg.ip_admin_eth0.netmask_admin_eth0.pop(0)')
    cfg.ip_admin_eth0.netmask_admin_eth0[0].append('255.255.255.0')
    assert cfg.ip_admin_eth0.netmask_admin_eth0 == [['255.255.255.0'], []]
    cfg.ip_admin_eth0.netmask_admin_eth0[0].pop(0)
    assert cfg.ip_admin_eth0.netmask_admin_eth0 == [[], []]
    raises(ValueError, 'cfg.ip_admin_eth0.netmask_admin_eth0 = ["255.255.255.0", "255.255.255.0"]')


def test_reset_values_with_master_and_slaves_submulti():
    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
    interface1.impl_set_group_type(groups.master)
    maconfig = OptionDescription('toto', '', [interface1])
    cfg = Config(maconfig)
    cfg.read_write()
    owner = cfg.cfgimpl_get_settings().getowner()
    assert interface1.impl_get_group_type() == groups.master
    assert cfg.getowner(ip_admin_eth0) == owners.default
    assert cfg.getowner(netmask_admin_eth0) == owners.default
    cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.145")
    assert cfg.getowner(ip_admin_eth0) == owner
    assert cfg.getowner(netmask_admin_eth0) == owners.default
    del(cfg.ip_admin_eth0.ip_admin_eth0)
    assert cfg.getowner(ip_admin_eth0) == owners.default
    assert cfg.getowner(netmask_admin_eth0) == owners.default
    assert cfg.ip_admin_eth0.ip_admin_eth0 == []
    assert cfg.ip_admin_eth0.netmask_admin_eth0 == []
    #
    cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.145")
    cfg.ip_admin_eth0.netmask_admin_eth0[0].append('255.255.255.0')
    assert cfg.getowner(ip_admin_eth0) == owner
    assert cfg.getowner(netmask_admin_eth0, 0) == owner
    del(cfg.ip_admin_eth0.ip_admin_eth0)
    assert cfg.getowner(ip_admin_eth0) == owners.default
#    assert cfg.getowner(netmask_admin_eth0) == owners.default
    assert cfg.ip_admin_eth0.ip_admin_eth0 == []
    assert cfg.ip_admin_eth0.netmask_admin_eth0 == []


def test_values_with_master_and_slaves_slave_submulti():
    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
    interface1.impl_set_group_type(groups.master)
    maconfig = OptionDescription('toto', '', [interface1])
    cfg = Config(maconfig)
    cfg.read_write()
    assert cfg.ip_admin_eth0.netmask_admin_eth0 == []
    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0 = [['255.255.255.0']]")
    cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.145")
    cfg.ip_admin_eth0.netmask_admin_eth0 = [['255.255.255.0']]
    cfg.ip_admin_eth0.netmask_admin_eth0[0] = ['255.255.255.0']
    cfg.ip_admin_eth0.netmask_admin_eth0[0][0] = '255.255.255.0'
    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0 = [['255.255.255.0'], ['255.255.255.0']]")
    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0 = []")
    del(cfg.ip_admin_eth0.netmask_admin_eth0)
    cfg.ip_admin_eth0.netmask_admin_eth0 = [['255.255.255.0']]
    cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.145")
    assert cfg.ip_admin_eth0.netmask_admin_eth0 == [['255.255.255.0'], []]
    cfg.ip_admin_eth0.netmask_admin_eth0 = [['255.255.255.0'], ['255.255.255.0']]
    raises(SlaveError, 'cfg.ip_admin_eth0.netmask_admin_eth0.pop(1)')


def test_values_with_master_and_slaves_master_submulti():
    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
    interface1.impl_set_group_type(groups.master)
    maconfig = OptionDescription('toto', '', [interface1])
    cfg = Config(maconfig)
    cfg.read_write()
    cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.145")
    cfg.ip_admin_eth0.ip_admin_eth0 = ["192.168.230.145"]
    cfg.ip_admin_eth0.ip_admin_eth0 = ["192.168.230.145", "192.168.230.145"]
    cfg.ip_admin_eth0.netmask_admin_eth0 = [['255.255.255.0'], ['255.255.255.0']]
    raises(SlaveError, 'cfg.ip_admin_eth0.ip_admin_eth0 = ["192.168.230.145"]')
    assert cfg.ip_admin_eth0.netmask_admin_eth0 == [['255.255.255.0'], ['255.255.255.0']]
    cfg.ip_admin_eth0.ip_admin_eth0.pop(1)
    assert cfg.ip_admin_eth0.ip_admin_eth0 == ["192.168.230.145"]
    assert cfg.ip_admin_eth0.netmask_admin_eth0 == [['255.255.255.0']]
    del(cfg.ip_admin_eth0.ip_admin_eth0)
    assert cfg.ip_admin_eth0.ip_admin_eth0 == []
    assert cfg.ip_admin_eth0.netmask_admin_eth0 == []


def test_values_with_master_and_slaves_master_error_submulti():
    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
    interface1.impl_set_group_type(groups.master)
    maconfig = OptionDescription('toto', '', [interface1])
    cfg = Config(maconfig)
    cfg.read_write()
    cfg.ip_admin_eth0.ip_admin_eth0 = ["192.168.230.145", "192.168.230.145"]
    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0 = [['255.255.255.0']]")
    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0 = [['255.255.255.0'], ['255.255.255.0'], ['255.255.255.0']]")
    cfg.ip_admin_eth0.netmask_admin_eth0 = [['255.255.255.0'], ['255.255.255.0']]
    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0 = [['255.255.255.0']]")
    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0 = [['255.255.255.0'], ['255.255.255.0'], ['255.255.255.0']]")


def test_values_with_master_owner_submulti():
    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
    interface1.impl_set_group_type(groups.master)
    maconfig = OptionDescription('toto', '', [interface1])
    cfg = Config(maconfig)
    cfg.read_write()
    owner = cfg.cfgimpl_get_settings().getowner()
    assert cfg.getowner(ip_admin_eth0) == owners.default
    assert cfg.getowner(netmask_admin_eth0) == owners.default
    cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.145")
    assert cfg.getowner(ip_admin_eth0) == owner
    assert cfg.getowner(netmask_admin_eth0) == owners.default
    cfg.ip_admin_eth0.ip_admin_eth0.pop(0)
    assert cfg.getowner(ip_admin_eth0) == owner
    assert cfg.getowner(netmask_admin_eth0) == owners.default


def test_values_with_master_disabled_submulti():
    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
    interface1.impl_set_group_type(groups.master)
    maconfig = OptionDescription('toto', '', [interface1])
    cfg = Config(maconfig)
    cfg.read_write()
    cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.145")
    cfg.ip_admin_eth0.ip_admin_eth0.pop(0)
    cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.145")
    cfg.ip_admin_eth0.netmask_admin_eth0 = [["192.168.230.145"]]
    cfg.ip_admin_eth0.ip_admin_eth0.pop(0)
    del(cfg.ip_admin_eth0.netmask_admin_eth0)
    cfg.cfgimpl_get_settings()[netmask_admin_eth0].append('disabled')
    cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.145")
    cfg.ip_admin_eth0.ip_admin_eth0.pop(0)

    #delete with value in disabled var
    cfg.cfgimpl_get_settings()[netmask_admin_eth0].remove('disabled')
    cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.145")
    cfg.ip_admin_eth0.netmask_admin_eth0 = [["192.168.230.145"]]
    cfg.cfgimpl_get_settings()[netmask_admin_eth0].append('disabled')
    cfg.ip_admin_eth0.ip_admin_eth0.pop(0)

    #append with value in disabled var
    cfg.cfgimpl_get_settings()[netmask_admin_eth0].remove('disabled')
    cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.145")
    cfg.ip_admin_eth0.netmask_admin_eth0 = [["192.168.230.145"]]
    cfg.cfgimpl_get_settings()[netmask_admin_eth0].append('disabled')
    cfg.ip_admin_eth0.ip_admin_eth0.append('192.168.230.43')


def test_multi_insert_master_submulti():
    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
    interface1.impl_set_group_type(groups.master)
    maconfig = OptionDescription('toto', '', [interface1])
    cfg = Config(maconfig)
    cfg.read_write()
    raises(SlaveError, "cfg.ip_admin_eth0.ip_admin_eth0.insert(0, 'nok')")
    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0.insert(0, 'nok')")
    cfg.ip_admin_eth0.ip_admin_eth0.append('192.168.1.1')
    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0[0].insert(0, 'nok')")


def test_multi_sort_master_submulti():
    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
    interface1.impl_set_group_type(groups.master)
    maconfig = OptionDescription('toto', '', [interface1])
    cfg = Config(maconfig)
    cfg.read_write()
    raises(SlaveError, "cfg.ip_admin_eth0.ip_admin_eth0.sort()")
    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0.sort()")
    cfg.ip_admin_eth0.ip_admin_eth0.append('192.168.1.1')
    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0[0].sort()")


def test_multi_reverse_master_submulti():
    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
    interface1.impl_set_group_type(groups.master)
    maconfig = OptionDescription('toto', '', [interface1])
    cfg = Config(maconfig)
    cfg.read_write()
    raises(SlaveError, "cfg.ip_admin_eth0.ip_admin_eth0.reverse()")
    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0.reverse()")
    cfg.ip_admin_eth0.ip_admin_eth0.append('192.168.1.1')
    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0[0].reverse()")


def test_multi_extend_master_submulti():
    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
    interface1.impl_set_group_type(groups.master)
    maconfig = OptionDescription('toto', '', [interface1])
    cfg = Config(maconfig)
    cfg.read_write()
    raises(SlaveError, "cfg.ip_admin_eth0.ip_admin_eth0.extend(['ok'])")
    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0.extend(['ok'])")
    cfg.ip_admin_eth0.ip_admin_eth0.append('192.168.1.1')
    raises(SlaveError, "cfg.ip_admin_eth0.netmask_admin_eth0[0].extend(['ok'])")


def test_slave_submulti():
    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=submulti)
    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
    interface1.impl_set_group_type(groups.master)
    maconfig = OptionDescription('toto', '', [interface1])
    cfg = Config(maconfig)
    cfg.read_write()
    assert cfg.ip_admin_eth0.ip_admin_eth0.__class__.__name__ == 'Multi'
    assert cfg.ip_admin_eth0.netmask_admin_eth0.__class__.__name__ == 'Multi'
    cfg.ip_admin_eth0.ip_admin_eth0.append('192.168.1.1')
    assert cfg.ip_admin_eth0.ip_admin_eth0.__class__.__name__ == 'Multi'
    assert cfg.ip_admin_eth0.netmask_admin_eth0.__class__.__name__ == 'Multi'
    assert cfg.ip_admin_eth0.ip_admin_eth0[0].__class__.__name__ == 'str'
    assert cfg.ip_admin_eth0.netmask_admin_eth0[0].__class__.__name__ == 'SubMulti'


def test__master_is_submulti():
    ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=submulti)
    netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
    interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
    interface1.impl_set_group_type(groups.master)
    maconfig = OptionDescription('toto', '', [interface1])
    cfg = Config(maconfig)
    cfg.read_write()
    owner = cfg.cfgimpl_get_settings().getowner()
    assert interface1.impl_get_group_type() == groups.master
    assert cfg.getowner(ip_admin_eth0) == owners.default
    assert cfg.getowner(netmask_admin_eth0) == owners.default
    assert cfg.ip_admin_eth0.netmask_admin_eth0 == []
    cfg.ip_admin_eth0.ip_admin_eth0.append(["192.168.230.145"])
    assert cfg.ip_admin_eth0.ip_admin_eth0 == [["192.168.230.145"]]
    assert cfg.ip_admin_eth0.netmask_admin_eth0 == [None]
    assert cfg.getowner(ip_admin_eth0) == owner
    assert cfg.getowner(netmask_admin_eth0) == owners.default
    cfg.ip_admin_eth0.ip_admin_eth0 = [["192.168.230.145"], ["192.168.230.147"]]
    assert cfg.ip_admin_eth0.netmask_admin_eth0 == [None, None]
    raises(SlaveError, 'cfg.ip_admin_eth0.netmask_admin_eth0.append(None)')
    raises(SlaveError, 'cfg.ip_admin_eth0.netmask_admin_eth0.pop(0)')
    cfg.ip_admin_eth0.ip_admin_eth0[0].append('192.168.1.1')
    assert cfg.ip_admin_eth0.ip_admin_eth0 == [["192.168.230.145", '192.168.1.1'], ["192.168.230.147"]]
    cfg.ip_admin_eth0.ip_admin_eth0[0].pop(0)
    assert cfg.ip_admin_eth0.ip_admin_eth0 == [["192.168.1.1"], ["192.168.230.147"]]
    raises(ValueError, 'cfg.ip_admin_eth0.ip_admin_eth0 = ["192.168.1.1", "192.168.1.1"]')


def test_callback_submulti():
    multi = StrOption('multi', '', multi=submulti)
    multi2 = StrOption('multi2', '', multi=submulti, callback=return_val, callback_params={'': ((multi, False),)})
    od = OptionDescription('multi', '', [multi, multi2])
    cfg = Config(od)
    cfg.read_write()
    owner = cfg.cfgimpl_get_settings().getowner()
    assert cfg.getowner(multi) == owners.default
    assert cfg.multi == []
    assert cfg.multi2 == []
    cfg.multi.append(['val'])
    assert cfg.getowner(multi) == owner
    assert cfg.getowner(multi2) == owners.default
    assert cfg.multi == [['val']]
    assert cfg.multi2 == [['val']]