mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Countless bug fixes, mostly do do with VR redundancy
Also added some new unit tests and adjusted the code to make them work
This commit is contained in:
parent
553bf21b37
commit
bdda01d269
@ -530,13 +530,11 @@ class CsForwardingRules(CsDataBag):
|
|||||||
|
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
config = CsConfig(False)
|
config = CsConfig()
|
||||||
logging.basicConfig(filename=config.get_logger(),
|
logging.basicConfig(filename=config.get_logger(),
|
||||||
level=config.get_level(),
|
level=config.get_level(),
|
||||||
format=config.get_format())
|
format=config.get_format())
|
||||||
config.set_cl()
|
|
||||||
config.set_address()
|
config.set_address()
|
||||||
cl = config.get_cmdline()
|
|
||||||
|
|
||||||
# IP configuration
|
# IP configuration
|
||||||
config.address().compare()
|
config.address().compare()
|
||||||
|
|||||||
@ -26,7 +26,7 @@ import time
|
|||||||
from CsRoute import CsRoute
|
from CsRoute import CsRoute
|
||||||
from CsRule import CsRule
|
from CsRule import CsRule
|
||||||
|
|
||||||
VRRP_TYPES = ['guest', 'public']
|
VRRP_TYPES = ['guest']
|
||||||
|
|
||||||
|
|
||||||
class CsAddress(CsDataBag):
|
class CsAddress(CsDataBag):
|
||||||
@ -42,38 +42,37 @@ class CsAddress(CsDataBag):
|
|||||||
if dev == "id":
|
if dev == "id":
|
||||||
continue
|
continue
|
||||||
for ip in self.dbag[dev]:
|
for ip in self.dbag[dev]:
|
||||||
ret.append(CsInterface(ip))
|
ret.append(CsInterface(ip, self.config))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def get_guest_if(self):
|
||||||
|
"""
|
||||||
|
Return CsIp object for the first guest interface
|
||||||
|
"""
|
||||||
|
for ip in self.get_ips():
|
||||||
|
if ip.is_guest():
|
||||||
|
return ip
|
||||||
|
return None
|
||||||
|
|
||||||
def get_guest_ip(self):
|
def get_guest_ip(self):
|
||||||
"""
|
"""
|
||||||
Return the ip of the first guest interface
|
Return the ip of the first guest interface
|
||||||
For use with routers not vpcrouters
|
For use with routers not vpcrouters
|
||||||
"""
|
"""
|
||||||
for ip in self.get_ips():
|
ip = self.get_guest_if()
|
||||||
if ip.is_guest():
|
if ip:
|
||||||
return ip.get_ip()
|
return ip.get_ip()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_guest_gateway(self):
|
|
||||||
"""
|
|
||||||
Return the gateway of the first guest interface
|
|
||||||
For use with routers not vpcrouters
|
|
||||||
"""
|
|
||||||
for ip in self.get_ips():
|
|
||||||
if ip.is_guest():
|
|
||||||
return ip.get_gateway()
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_guest_netmask(self):
|
def get_guest_netmask(self):
|
||||||
"""
|
"""
|
||||||
Return the gateway of the first guest interface
|
Return the netmask of the first guest interface
|
||||||
For use with routers not vpcrouters
|
For use with routers not vpcrouters
|
||||||
"""
|
"""
|
||||||
for ip in self.get_ips():
|
ip = self.get_guest_if()
|
||||||
if ip.is_guest():
|
if ip:
|
||||||
return ip.get_netmask()
|
return ip.get_netmask()
|
||||||
return None
|
return "255.255.255.0"
|
||||||
|
|
||||||
def needs_vrrp(self, o):
|
def needs_vrrp(self, o):
|
||||||
"""
|
"""
|
||||||
@ -144,8 +143,9 @@ class CsAddress(CsDataBag):
|
|||||||
|
|
||||||
class CsInterface:
|
class CsInterface:
|
||||||
""" Hold one single ip """
|
""" Hold one single ip """
|
||||||
def __init__(self, o):
|
def __init__(self, o, config):
|
||||||
self.address = o
|
self.address = o
|
||||||
|
self.config = config
|
||||||
|
|
||||||
def get_ip(self):
|
def get_ip(self):
|
||||||
return self.get_attr("public_ip")
|
return self.get_attr("public_ip")
|
||||||
@ -154,7 +154,17 @@ class CsInterface:
|
|||||||
return self.get_attr("netmask")
|
return self.get_attr("netmask")
|
||||||
|
|
||||||
def get_gateway(self):
|
def get_gateway(self):
|
||||||
|
if self.config.is_vpc():
|
||||||
return self.get_attr("gateway")
|
return self.get_attr("gateway")
|
||||||
|
else:
|
||||||
|
return self.config.cmdline().get_guest_gw()
|
||||||
|
|
||||||
|
def get_gateway_cidr(self):
|
||||||
|
return "%s/%s" % (self.get_gateway(), self.get_size())
|
||||||
|
|
||||||
|
def get_size(self):
|
||||||
|
""" Return the network size in bits (24, 16, 8 etc) """
|
||||||
|
return self.get_attr("size")
|
||||||
|
|
||||||
def get_device(self):
|
def get_device(self):
|
||||||
return self.get_attr("device")
|
return self.get_attr("device")
|
||||||
@ -205,7 +215,7 @@ class CsDevice:
|
|||||||
self.tableNo = dev[3]
|
self.tableNo = dev[3]
|
||||||
self.table = "Table_%s" % dev
|
self.table = "Table_%s" % dev
|
||||||
self.fw = config.get_fw()
|
self.fw = config.get_fw()
|
||||||
self.cl = config.get_cmdline()
|
self.cl = config.cmdline()
|
||||||
|
|
||||||
def configure_rp(self):
|
def configure_rp(self):
|
||||||
"""
|
"""
|
||||||
@ -250,7 +260,7 @@ class CsIP:
|
|||||||
self.address = {}
|
self.address = {}
|
||||||
self.list()
|
self.list()
|
||||||
self.fw = config.get_fw()
|
self.fw = config.get_fw()
|
||||||
self.cl = config.get_cmdline()
|
self.cl = config.cmdline()
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
def setAddress(self, address):
|
def setAddress(self, address):
|
||||||
@ -284,7 +294,7 @@ class CsIP:
|
|||||||
if " DOWN " in i:
|
if " DOWN " in i:
|
||||||
cmd2 = "ip link set %s up" % self.getDevice()
|
cmd2 = "ip link set %s up" % self.getDevice()
|
||||||
# Do not change the state of ips on a redundant router that are managed by vrrp or CsRedundant
|
# Do not change the state of ips on a redundant router that are managed by vrrp or CsRedundant
|
||||||
if self.cl.is_redundant() and self.needs_vrrp():
|
if self.config.cmdline().is_redundant() and self.needs_vrrp():
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
CsHelper.execute(cmd2)
|
CsHelper.execute(cmd2)
|
||||||
@ -412,7 +422,7 @@ class CsIP:
|
|||||||
|
|
||||||
if self.get_type() == "public" and self.config.is_vpc():
|
if self.get_type() == "public" and self.config.is_vpc():
|
||||||
if self.address["source_nat"]:
|
if self.address["source_nat"]:
|
||||||
vpccidr = self.cl.get_vpccidr()
|
vpccidr = self.config.cmdline().get_vpccidr()
|
||||||
self.fw.append(["filter", "", "-A FORWARD -s %s ! -d %s -j ACCEPT" % (vpccidr, vpccidr)])
|
self.fw.append(["filter", "", "-A FORWARD -s %s ! -d %s -j ACCEPT" % (vpccidr, vpccidr)])
|
||||||
self.fw.append(["nat", "", "-A POSTROUTING -j SNAT -o %s --to-source %s" % (self.dev, self.address['public_ip'])])
|
self.fw.append(["nat", "", "-A POSTROUTING -j SNAT -o %s --to-source %s" % (self.dev, self.address['public_ip'])])
|
||||||
# route.flush()
|
# route.flush()
|
||||||
|
|||||||
@ -28,24 +28,25 @@ class CsConfig(object):
|
|||||||
__LOG_FILE = "/var/log/cloud.log"
|
__LOG_FILE = "/var/log/cloud.log"
|
||||||
__LOG_LEVEL = "DEBUG"
|
__LOG_LEVEL = "DEBUG"
|
||||||
__LOG_FORMAT = "%(asctime)s %(levelname)-8s %(message)s"
|
__LOG_FORMAT = "%(asctime)s %(levelname)-8s %(message)s"
|
||||||
|
cl = None
|
||||||
|
|
||||||
def __init__(self, load=False):
|
def __init__(self):
|
||||||
if load:
|
|
||||||
self_set_cl()
|
|
||||||
self_set_address()
|
|
||||||
self.fw = []
|
self.fw = []
|
||||||
|
|
||||||
def set_cl(self):
|
|
||||||
self.cl = CsCmdLine("cmdline")
|
|
||||||
|
|
||||||
def address(self):
|
|
||||||
return self.ips
|
|
||||||
|
|
||||||
def set_address(self):
|
def set_address(self):
|
||||||
self.ips = CsAddress("ips", self)
|
self.ips = CsAddress("ips", self)
|
||||||
|
|
||||||
def get_cmdline(self):
|
@classmethod
|
||||||
return self.cl
|
def get_cmdline_instance(cls):
|
||||||
|
if cls.cl is None:
|
||||||
|
cls.cl = CsCmdLine("cmdline")
|
||||||
|
return cls.cl
|
||||||
|
|
||||||
|
def cmdline(self):
|
||||||
|
return self.get_cmdline_instance()
|
||||||
|
|
||||||
|
def address(self):
|
||||||
|
return self.ips
|
||||||
|
|
||||||
def get_fw(self):
|
def get_fw(self):
|
||||||
return self.fw
|
return self.fw
|
||||||
@ -66,7 +67,7 @@ class CsConfig(object):
|
|||||||
return self.cl.get_domain()
|
return self.cl.get_domain()
|
||||||
|
|
||||||
def get_dns(self):
|
def get_dns(self):
|
||||||
return self.get_cmdline().get_dns()
|
return self.cmdline().get_dns()
|
||||||
|
|
||||||
def get_format(self):
|
def get_format(self):
|
||||||
return self.__LOG_FORMAT
|
return self.__LOG_FORMAT
|
||||||
|
|||||||
@ -28,7 +28,7 @@ class CsDataBag(object):
|
|||||||
self.dbag = self.db.getDataBag()
|
self.dbag = self.db.getDataBag()
|
||||||
if config:
|
if config:
|
||||||
self.fw = config.get_fw()
|
self.fw = config.get_fw()
|
||||||
self.cl = config.get_cmdline()
|
self.cl = config.cmdline()
|
||||||
self.config = config
|
self.config = config
|
||||||
|
|
||||||
def dump(self):
|
def dump(self):
|
||||||
@ -51,14 +51,32 @@ class CsDataBag(object):
|
|||||||
class CsCmdLine(CsDataBag):
|
class CsCmdLine(CsDataBag):
|
||||||
""" Get cmdline config parameters """
|
""" Get cmdline config parameters """
|
||||||
|
|
||||||
|
def idata(self):
|
||||||
|
if "config" in self.dbag:
|
||||||
|
return self.dbag['config']
|
||||||
|
else:
|
||||||
|
return {}
|
||||||
|
|
||||||
def is_redundant(self):
|
def is_redundant(self):
|
||||||
if "redundant_router" in self.dbag['config']:
|
if "redundant_router" in self.idata():
|
||||||
return self.dbag['config']['redundant_router'] == "true"
|
return self.idata()['redundant_router'] == "true"
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def get_guest_gw(self):
|
||||||
|
if "guestgw" in self.idata():
|
||||||
|
return self.idata()['guestgw']
|
||||||
|
else:
|
||||||
|
return "1.2.3.4"
|
||||||
|
|
||||||
|
def get_guest_gw_cidr(self):
|
||||||
|
if "guestgw" in self.idata():
|
||||||
|
return "%s/%s" % (self.idata()['guestgw'], self.idata()['guestcidrsize'])
|
||||||
|
else:
|
||||||
|
return "1.2.3.4/8"
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
if "name" in self.dbag['config']:
|
if "name" in self.idata():
|
||||||
return self.dbag['config']['name']
|
return self.idata()['name']
|
||||||
else:
|
else:
|
||||||
return "unloved-router"
|
return "unloved-router"
|
||||||
|
|
||||||
@ -66,31 +84,31 @@ class CsCmdLine(CsDataBag):
|
|||||||
dns = []
|
dns = []
|
||||||
names = "dns1 dns2"
|
names = "dns1 dns2"
|
||||||
for name in names:
|
for name in names:
|
||||||
if name in self.dbag['config']:
|
if name in self.idata():
|
||||||
dns.append(self.dbag['config'][name])
|
dns.append(self.idata()[name])
|
||||||
return dns
|
return dns
|
||||||
|
|
||||||
def get_type(self):
|
def get_type(self):
|
||||||
if "type" in self.dbag['config']:
|
if "type" in self.idata():
|
||||||
return self.dbag['config']['type']
|
return self.idata()['type']
|
||||||
else:
|
else:
|
||||||
return "unknown"
|
return "unknown"
|
||||||
|
|
||||||
def get_domain(self):
|
def get_domain(self):
|
||||||
if "domain" in self.dbag['config']:
|
if "domain" in self.config:
|
||||||
return self.dbag['config']['domain']
|
return self.idata()['domain']
|
||||||
else:
|
else:
|
||||||
return "cloudnine.internal"
|
return "cloudnine.internal"
|
||||||
|
|
||||||
def get_vpccidr(self):
|
def get_vpccidr(self):
|
||||||
if "vpccidr" in self.dbag['config']:
|
if "vpccidr" in self.idata():
|
||||||
return self.dbag['config']['vpccidr']
|
return self.idata()['vpccidr']
|
||||||
else:
|
else:
|
||||||
return "unknown"
|
return "unknown"
|
||||||
|
|
||||||
def is_master(self):
|
def is_master(self):
|
||||||
if not self.is_redundant():
|
if not self.is_redundant():
|
||||||
return False
|
return False
|
||||||
if "redundant_master" in self.dbag['config']:
|
if "redundant_master" in self.idata():
|
||||||
return self.dbag['config']['redundant_master'] == "true"
|
return self.idata()['redundant_master'] == "true"
|
||||||
return False
|
return False
|
||||||
|
|||||||
@ -54,7 +54,7 @@ class CsDhcp(CsDataBag):
|
|||||||
CsHelper.hup_dnsmasq("dnsmasq", "dnsmasq")
|
CsHelper.hup_dnsmasq("dnsmasq", "dnsmasq")
|
||||||
|
|
||||||
def configure_server(self):
|
def configure_server(self):
|
||||||
#self.conf.addeq("dhcp-hostsfile=%s" % DHCP_HOSTS)
|
# self.conf.addeq("dhcp-hostsfile=%s" % DHCP_HOSTS)
|
||||||
for i in self.devinfo:
|
for i in self.devinfo:
|
||||||
if not i['dnsmasq']:
|
if not i['dnsmasq']:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@ -101,6 +101,9 @@ class CsFile:
|
|||||||
if line.strip() == start:
|
if line.strip() == start:
|
||||||
sind = index + 1
|
sind = index + 1
|
||||||
found = True
|
found = True
|
||||||
|
if sind == -1:
|
||||||
|
content.insert(0, start + "\n")
|
||||||
|
content.append(end + "\n")
|
||||||
self.new_config[sind:eind] = content
|
self.new_config[sind:eind] = content
|
||||||
|
|
||||||
def greplace(self, search, replace):
|
def greplace(self, search, replace):
|
||||||
|
|||||||
@ -38,7 +38,6 @@ def is_mounted(name):
|
|||||||
|
|
||||||
def mount_tmpfs(name):
|
def mount_tmpfs(name):
|
||||||
if not is_mounted(name):
|
if not is_mounted(name):
|
||||||
print "Mounting it"
|
|
||||||
execute("mount tmpfs %s -t tmpfs" % name)
|
execute("mount tmpfs %s -t tmpfs" % name)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -54,7 +54,7 @@ class CsRedundant(object):
|
|||||||
CONNTRACKD_CONFIG = "/etc/conntrackd/conntrackd.conf"
|
CONNTRACKD_CONFIG = "/etc/conntrackd/conntrackd.conf"
|
||||||
|
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
self.cl = config.get_cmdline()
|
self.cl = config.cmdline()
|
||||||
self.address = config.address()
|
self.address = config.address()
|
||||||
|
|
||||||
def set(self):
|
def set(self):
|
||||||
@ -95,10 +95,16 @@ class CsRedundant(object):
|
|||||||
file.commit()
|
file.commit()
|
||||||
|
|
||||||
# conntrackd configuration
|
# conntrackd configuration
|
||||||
control = self.address.get_control_if()
|
guest = self.address.get_guest_if()
|
||||||
connt = CsFile("/etc/conntrackd/conntrackd.conf")
|
connt = CsFile("/etc/conntrackd/conntrackd.conf")
|
||||||
connt.search("[\s\t]IPv4_interface ", "\t\tIPv4_interface %s" % control.get_ip())
|
connt.section("Multicast {", "}", [
|
||||||
connt.search("[\s\t]Interface ", "\t\tInterface %s" % control.get_device())
|
"IPv4_address 225.0.0.50\n",
|
||||||
|
"Group 3780\n",
|
||||||
|
"IPv4_interface %s\n" % guest.get_ip(),
|
||||||
|
"Interface %s\n" % guest.get_device(),
|
||||||
|
"SndSocketBuffer 1249280\n",
|
||||||
|
"RcvSocketBuffer 1249280\n",
|
||||||
|
"Checksum on\n"])
|
||||||
connt.section("Address Ignore {", "}", self._collect_ignore_ips())
|
connt.section("Address Ignore {", "}", self._collect_ignore_ips())
|
||||||
connt.commit()
|
connt.commit()
|
||||||
if connt.is_changed():
|
if connt.is_changed():
|
||||||
@ -209,6 +215,6 @@ class CsRedundant(object):
|
|||||||
lines = []
|
lines = []
|
||||||
for o in self.address.get_ips():
|
for o in self.address.get_ips():
|
||||||
if o.needs_vrrp():
|
if o.needs_vrrp():
|
||||||
str = " %s brd %s dev %s\n" % (o.get_cidr(), o.get_broadcast(), o.get_ip())
|
str = " %s brd %s dev %s\n" % (o.get_gateway_cidr(), o.get_broadcast(), o.get_device())
|
||||||
lines.append(str)
|
lines.append(str)
|
||||||
return lines
|
return lines
|
||||||
|
|||||||
@ -32,6 +32,7 @@ def merge(dbag, ip):
|
|||||||
ip['device'] = 'eth' + str(ip['nic_dev_id'])
|
ip['device'] = 'eth' + str(ip['nic_dev_id'])
|
||||||
ip['broadcast'] = str(ipo.broadcast)
|
ip['broadcast'] = str(ipo.broadcast)
|
||||||
ip['cidr'] = str(ipo.ip) + '/' + str(ipo.prefixlen)
|
ip['cidr'] = str(ipo.ip) + '/' + str(ipo.prefixlen)
|
||||||
|
ip['size'] = str(ipo.prefixlen)
|
||||||
ip['network'] = str(ipo.network) + '/' + str(ipo.prefixlen)
|
ip['network'] = str(ipo.network) + '/' + str(ipo.prefixlen)
|
||||||
if 'nw_type' not in ip.keys():
|
if 'nw_type' not in ip.keys():
|
||||||
ip['nw_type'] = 'public'
|
ip['nw_type'] = 'public'
|
||||||
|
|||||||
@ -7,10 +7,19 @@ class TestCsAddress(unittest.TestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
merge.DataBag.DPATH = "."
|
merge.DataBag.DPATH = "."
|
||||||
|
self.csaddress = CsAddress("ips", {})
|
||||||
|
|
||||||
def test_needs_vrrp(self):
|
def test_needs_vrrp(self):
|
||||||
csaddress = CsAddress("ips", {})
|
self.assertTrue(self.csaddress.needs_vrrp({"nw_type": "guest"}))
|
||||||
self.assertTrue(csaddress.needs_vrrp({"nw_type": "public"}))
|
|
||||||
|
def test_get_guest_if(self):
|
||||||
|
self.assertTrue(self.csaddress.get_guest_if() is None)
|
||||||
|
|
||||||
|
def test_get_guest_ip(self):
|
||||||
|
self.assertTrue(self.csaddress.get_guest_ip() is None)
|
||||||
|
|
||||||
|
def test_get_guest_netmask(self):
|
||||||
|
self.assertTrue(self.csaddress.get_guest_netmask() == "255.255.255.0")
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
@ -12,7 +12,7 @@ class TestCsApp(unittest.TestCase):
|
|||||||
|
|
||||||
def test_init(self):
|
def test_init(self):
|
||||||
csconfig = CsConfig()
|
csconfig = CsConfig()
|
||||||
csconfig.set_cl()
|
csconfig.cmdline()
|
||||||
csip = CsIP("eth0", csconfig)
|
csip = CsIP("eth0", csconfig)
|
||||||
csapp = CsApp(csip)
|
csapp = CsApp(csip)
|
||||||
self.assertTrue(csapp is not None)
|
self.assertTrue(csapp is not None)
|
||||||
|
|||||||
@ -9,7 +9,7 @@ class TestCsConfig(unittest.TestCase):
|
|||||||
merge.DataBag.DPATH = "."
|
merge.DataBag.DPATH = "."
|
||||||
|
|
||||||
def test_ini(self):
|
def test_ini(self):
|
||||||
csconfig = CsConfig(False)
|
csconfig = CsConfig()
|
||||||
self.assertTrue(csconfig is not None)
|
self.assertTrue(csconfig is not None)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
21
systemvm/test/python/TestCsInterface.py
Normal file
21
systemvm/test/python/TestCsInterface.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import unittest
|
||||||
|
from cs.CsAddress import CsInterface
|
||||||
|
from cs.CsConfig import CsConfig
|
||||||
|
from cs.CsDatabag import CsCmdLine
|
||||||
|
import merge
|
||||||
|
|
||||||
|
|
||||||
|
class TestCsInterface(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
merge.DataBag.DPATH = "."
|
||||||
|
csconfig = CsConfig()
|
||||||
|
self.cmdline = CsCmdLine("cmdline", csconfig)
|
||||||
|
csconfig.cl = self.cmdline
|
||||||
|
self.csinterface = CsInterface({}, csconfig)
|
||||||
|
|
||||||
|
def test_get_gateway(self):
|
||||||
|
self.assertTrue(self.csinterface.get_gateway() == "1.2.3.4")
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import unittest
|
import unittest
|
||||||
from cs.CsRedundant import CsRedundant
|
from cs.CsRedundant import CsRedundant
|
||||||
from cs.CsConfig import CsConfig
|
from cs.CsConfig import CsConfig
|
||||||
|
from cs.CsDatabag import CsCmdLine
|
||||||
import merge
|
import merge
|
||||||
|
|
||||||
|
|
||||||
@ -8,10 +9,11 @@ class TestCsRedundant(unittest.TestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
merge.DataBag.DPATH = "."
|
merge.DataBag.DPATH = "."
|
||||||
|
self.cmdline = CsCmdLine("cmdline", {})
|
||||||
|
|
||||||
def test_init(self):
|
def test_init(self):
|
||||||
csconfig = CsConfig()
|
csconfig = CsConfig()
|
||||||
csconfig.set_cl()
|
csconfig.cl = self.cmdline
|
||||||
csconfig.set_address()
|
csconfig.set_address()
|
||||||
|
|
||||||
csredundant = CsRedundant(csconfig)
|
csredundant = CsRedundant(csconfig)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user