diff --git a/ansible/library/test_facts.py b/ansible/library/test_facts.py index c50d02ff599..e2c7ddf26a9 100644 --- a/ansible/library/test_facts.py +++ b/ansible/library/test_facts.py @@ -28,13 +28,20 @@ ''' EXAMPLES = ''' - Testbed CSV file example: + Testbed CSV file example - deprecated: # conf-name,group-name,topo,ptf_image_name,ptf,ptf_ip,ptf_ipv6,server,vm_base,dut,comment ptf1-m,ptf1,ptf32,docker-ptf,ptf-1,10.255.0.188/24,,server_1,,str-msn2700-01,Tests ptf vms-t1,vms1-1,t1,docker-ptf,ptf-2,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,Tests vms vms-t1-lag,vms1-1,t1-lag,docker-ptf,ptf-3,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,Tests vms ... + Testbed CSV file example - recommended: + # conf-name,group-name,topo,ptf_image_name,ptf,ptf_ip,ptf_ipv6,server,vm_base,dut,inv_file,auto_recover,comment + ptf1-m,ptf1,ptf32,docker-ptf,ptf-1,10.255.0.188/24,,server_1,,str-msn2700-01,lab,False,Tests ptf + vms-t1,vms1-1,t1,docker-ptf,ptf-2,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,lab,True,Tests vms + vms-t1-lag,vms1-1,t1-lag,docker-ptf,ptf-3,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,lab,True,Tests vms + ... + Testcases YAML File example: testcases: acl: @@ -98,7 +105,8 @@ class ParseTestbedTopoinfo(): """Parse the testbed file used to describe whole testbed info""" - TESTBED_FIELDS = ('conf-name', 'group-name', 'topo', 'ptf_image_name', 'ptf', 'ptf_ip', 'ptf_ipv6', 'server', 'vm_base', 'dut', 'comment') + TESTBED_FIELDS_DEPRECATED = ('conf-name', 'group-name', 'topo', 'ptf_image_name', 'ptf', 'ptf_ip', 'ptf_ipv6', 'server', 'vm_base', 'dut', 'comment') + TESTBED_FIELDS_RECOMMENDED = ('conf-name', 'group-name', 'topo', 'ptf_image_name', 'ptf', 'ptf_ip', 'ptf_ipv6', 'server', 'vm_base', 'dut', 'inv_name', 'auto_recover', 'comment') def __init__(self, testbed_file): self.testbed_filename = testbed_file @@ -113,13 +121,17 @@ def _cidr_to_ip_mask(network): def _read_testbed_topo_from_csv(): """Read csv testbed info file.""" with open(self.testbed_filename) as f: - topo = csv.DictReader(f, fieldnames=self.TESTBED_FIELDS, - delimiter=',') - - # Validate all field are in the same order and are present - header = next(topo) - for field in self.TESTBED_FIELDS: - assert header[field].replace('#', '').strip() == field + header = [field.strip(' #') for field in f.readline().strip().split(',')] + if len(header) == len(self.TESTBED_FIELDS_DEPRECATED): + testbed_fields = self.TESTBED_FIELDS_DEPRECATED + elif len(header) == len(self.TESTBED_FIELDS_RECOMMENDED): + testbed_fields = self.TESTBED_FIELDS_RECOMMENDED + else: + raise ValueError('Unsupported testbed fields %s' % str(header)) + for header_field, expect_field in zip(header, testbed_fields): + assert header_field == expect_field + + topo = csv.DictReader(f, fieldnames=testbed_fields, delimiter=',') for line in topo: if line['conf-name'].lstrip().startswith('#'): @@ -133,7 +145,7 @@ def _read_testbed_topo_from_csv(): _cidr_to_ip_mask(line["ptf_ipv6"]) line['duts'] = line['dut'].translate(string.maketrans("", ""), "[] ").split(';') - line['duts_map'] = {dut:line['duts'].index(dut) for dut in line['duts']} + line['duts_map'] = {dut: line['duts'].index(dut) for dut in line['duts']} del line['dut'] self.testbed_topo[line['conf-name']] = line diff --git a/ansible/testbed.csv b/ansible/testbed.csv index 3d0c7faf50e..53723f7746d 100644 --- a/ansible/testbed.csv +++ b/ansible/testbed.csv @@ -1,13 +1,13 @@ -# conf-name,group-name,topo,ptf_image_name,ptf,ptf_ip,ptf_ipv6,server,vm_base,dut,comment -ptf1-m,ptf1,ptf32,docker-ptf,ptf-unknown,10.255.0.188/24,,server_1,,str-msn2700-01,Test ptf Mellanox -ptf2-b,ptf2,ptf64,docker-ptf,ptf-unknown,10.255.0.189/24,,server_1,,lab-s6100-01,Test ptf Broadcom -vms-sn2700-t1,vms1-1,t1,docker-ptf,ptf-unknown,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,Tests Mellanox SN2700 vms -vms-sn2700-t1-lag,vms1-1,t1-lag,docker-ptf,ptf-unknown,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,Tests Mellanox SN2700 vms -vms-sn2700-t0,vms1-1,t0,docker-ptf,ptf-unknown,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,Tests Mellanox SN2700 vms -vms-s6000-t0,vms2-1,t0,docker-ptf,ptf-unknown,10.255.0.179/24,,server_1,VM0100,lab-s6000-01,Tests Dell S6000 vms -vms-a7260-t0,vms3-1,t0-116,docker-ptf,ptf-unknown,10.255.0.180/24,,server_1,VM0100,lab-a7260-01,Tests Arista A7260 vms -vms-s6100-t0,vms4-1,t0-64,docker-ptf,ptf-unknown,10.255.0.181/24,,server_1,VM0100,lab-s6100-01,Tests Dell S6100 vms -vms-s6100-t1,vms4-1,t1-64,docker-ptf,ptf-unknown,10.255.0.182/24,,server_1,VM0100,lab-s6100-01,Tests Dell S6100 vms -vms-s6100-t1-lag,vms5-1,t1-64-lag,docker-ptf,ptf-unknown,10.255.0.183/24,,server_1,VM0100,lab-s6100-01,Tests Dell S6100 vms -vms-multi-dut,vms1-duts,ptf64,docker-ptf,ptf-unknown,10.255.0.184/24,,server_1,VM0100,[dut-host1;dut-host2],Example Multi DUTs testbed -vms-example-ixia-1,vms6-1,t0-64,docker-ptf-ixia,example-ixia-ptf-1,10.0.0.30/32,,server_6,VM0600,example-s6100-dut-1,superman +# conf-name,group-name,topo,ptf_image_name,ptf,ptf_ip,ptf_ipv6,server,vm_base,dut,inv_name,auto_recover,comment +ptf1-m,ptf1,ptf32,docker-ptf,ptf-unknown,10.255.0.188/24,,server_1,,str-msn2700-01,lab,False,Test ptf Mellanox +ptf2-b,ptf2,ptf64,docker-ptf,ptf-unknown,10.255.0.189/24,,server_1,,lab-s6100-01,lab,False,Test ptf Broadcom +vms-sn2700-t1,vms1-1,t1,docker-ptf,ptf-unknown,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,lab,True,Tests Mellanox SN2700 vms +vms-sn2700-t1-lag,vms1-1,t1-lag,docker-ptf,ptf-unknown,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,lab,True,Tests Mellanox SN2700 vms +vms-sn2700-t0,vms1-1,t0,docker-ptf,ptf-unknown,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,lab,True,Tests Mellanox SN2700 vms +vms-s6000-t0,vms2-1,t0,docker-ptf,ptf-unknown,10.255.0.179/24,,server_1,VM0100,lab-s6000-01,lab,True,Tests Dell S6000 vms +vms-a7260-t0,vms3-1,t0-116,docker-ptf,ptf-unknown,10.255.0.180/24,,server_1,VM0100,lab-a7260-01,lab,True,Tests Arista A7260 vms +vms-s6100-t0,vms4-1,t0-64,docker-ptf,ptf-unknown,10.255.0.181/24,,server_1,VM0100,lab-s6100-01,lab,True,Tests Dell S6100 vms +vms-s6100-t1,vms4-1,t1-64,docker-ptf,ptf-unknown,10.255.0.182/24,,server_1,VM0100,lab-s6100-01,lab,True,Tests Dell S6100 vms +vms-s6100-t1-lag,vms5-1,t1-64-lag,docker-ptf,ptf-unknown,10.255.0.183/24,,server_1,VM0100,lab-s6100-01,lab,True,ests Dell S6100 vms +vms-multi-dut,vms1-duts,ptf64,docker-ptf,ptf-unknown,10.255.0.184/24,,server_1,VM0100,[dut-host1;dut-host2],lab,True,Example Multi DUTs testbed +vms-example-ixia-1,vms6-1,t0-64,docker-ptf-ixia,example-ixia-ptf-1,10.0.0.30/32,,server_6,VM0600,example-s6100-dut-1,lab,True,superman diff --git a/ansible/vtestbed.csv b/ansible/vtestbed.csv index 93a9f97c9b8..46c75c55a90 100644 --- a/ansible/vtestbed.csv +++ b/ansible/vtestbed.csv @@ -1,7 +1,7 @@ -# conf-name,group-name,topo,ptf_image_name,ptf,ptf_ip,ptf_ipv6,server,vm_base,dut,comment -vms-kvm-t0,vms6-1,t0,docker-ptf,ptf-01,10.250.0.102/24,fec0::ffff:afa:2/64,server_1,VM0100,[vlab-01],Tests virtual switch vm -vms-kvm-t0-64,vms6-1,t0-64,docker-ptf,ptf-01,10.250.0.102/24,fec0::ffff:afa:2/64,server_1,VM0100,[vlab-02],Tests virtual switch vm -vms-kvm-t1-lag,vms6-2,t1-lag,docker-ptf,ptf-02,10.250.0.106/24,fec0::ffff:afa:6/64,server_1,VM0104,[vlab-03],Tests virtual switch vm -vms-kvm-t0-2,vms6-3,t0,docker-ptf,ptf-03,10.250.0.108/24,fec0::ffff:afa:8/64,server_1,VM0104,[vlab-04],Tests virtual switch vm -vms-kvm-dual-t0,vms6-4,dualtor,docker-ptf,ptf-04,10.250.0.109/24,fec0::ffff:afa:9/64,server_1,VM0108,[vlab-05;vlab-06],Dual-TOR testbed -vms-kvm-multi-asic-t1-lag,vms6-4,t1-64-lag,docker-ptf,ptf-05,10.250.0.110/24,fec0::ffff:afa:a/64,server_1,VM0104,[vlab-07],Tests multi-asic virtual switch vm +# conf-name,group-name,topo,ptf_image_name,ptf,ptf_ip,ptf_ipv6,server,vm_base,dut,inv_name,auto_recover,comment +vms-kvm-t0,vms6-1,t0,docker-ptf,ptf-01,10.250.0.102/24,fec0::ffff:afa:2/64,server_1,VM0100,[vlab-01],lab,False,Tests virtual switch vm +vms-kvm-t0-64,vms6-1,t0-64,docker-ptf,ptf-01,10.250.0.102/24,fec0::ffff:afa:2/64,server_1,VM0100,[vlab-02],lab,False,Tests virtual switch vm +vms-kvm-t1-lag,vms6-2,t1-lag,docker-ptf,ptf-02,10.250.0.106/24,fec0::ffff:afa:6/64,server_1,VM0104,[vlab-03],lab,False,Tests virtual switch vm +vms-kvm-t0-2,vms6-3,t0,docker-ptf,ptf-03,10.250.0.108/24,fec0::ffff:afa:8/64,server_1,VM0104,[vlab-04],lab,False,Tests virtual switch vm +vms-kvm-dual-t0,vms6-4,dualtor,docker-ptf,ptf-04,10.250.0.109/24,fec0::ffff:afa:9/64,server_1,VM0108,[vlab-05;vlab-06],lab,False,Dual-TOR testbed +vms-kvm-multi-asic-t1-lag,vms6-4,t1-64-lag,docker-ptf,ptf-05,10.250.0.110/24,fec0::ffff:afa:a/64,server_1,VM0104,[vlab-07],lab,False,Tests multi-asic virtual switch vm diff --git a/docs/testbed/README.new.testbed.Configuration.md b/docs/testbed/README.new.testbed.Configuration.md index eb6b0571f91..49e7c0681ae 100644 --- a/docs/testbed/README.new.testbed.Configuration.md +++ b/docs/testbed/README.new.testbed.Configuration.md @@ -49,12 +49,12 @@ The devices section is a dictionary that contains all devices and hosts. This se For each device that you add, add the following: -| Hostname | ansible_host | ansible_ssh_user | ansible_ssh_pass | HwSKU | device_type | -| ------ | ------ | ------ | ------ | ------ | ------ | -| str-msn2700-01 | [IP Address] | [username] | [password] | DevSonic | DevSonic | -| str-7260-10 | [IP Address] | [username] | [password] |Arista-7260QX-64 | FanoutRoot | -| str-7260-10 | [IP Address] | [username] | [password] |Arista-7260QX-64 | FanoutLeaf | -| str-acs-serv-01 | [IP Address] | [username] | [password] | TestServ | Server | +| Hostname | ansible_host | ansible_ssh_user | ansible_ssh_pass | HwSKU | device_type | +| --------------- | ------------ | ---------------- | ---------------- | ---------------- | ----------- | +| str-msn2700-01 | [IP Address] | [username] | [password] | DevSonic | DevSonic | +| str-7260-10 | [IP Address] | [username] | [password] | Arista-7260QX-64 | FanoutRoot | +| str-7260-10 | [IP Address] | [username] | [password] | Arista-7260QX-64 | FanoutLeaf | +| str-acs-serv-01 | [IP Address] | [username] | [password] | TestServ | Server | - hostname - names the devices you will use - ansible_host - this is the managementIP where you can connect to to the device @@ -111,10 +111,10 @@ Define: This is where the topology configuration file for the testbed will collect information from when running TestbedProcessing.py. -| #conf-name | group-name | topo | ptf_image_name | ptf_ip | server | vm_base | dut | comment | -| ------ | ------ | ------ | ------ | ------ | ------ | ------ | ------ | ------ | -| [ptf32 conf-name] | [ptf32 group-name] | [ptf32] | [docker-ptf] | [ip address] | [server group] | [vm_base] | [dut] | [comment] | -| [t0 conf-name] | [t0 group-name] | [t0] | [docker-ptf] | [ip address] | [server group] | [vm_base] | [dut] | [comment] | +| #conf-name | group-name | topo | ptf_image_name | ptf_ip | server | vm_base | dut | inv_name | auto_recover | comment | +| ----------------- | ------------------ | ------- | -------------- | ------------ | -------------- | --------- | ----- | ---------- | -------------- | --------- | +| [ptf32 conf-name] | [ptf32 group-name] | [ptf32] | [docker-ptf] | [ip address] | [server group] | [vm_base] | [dut] | [inv_name] | [auto_recover] | [comment] | +| [t0 conf-name] | [t0 group-name] | [t0] | [docker-ptf] | [ip address] | [server group] | [vm_base] | [dut] | [inv_name] | [auto_recover] | [comment] | For each topology you use in your testbed environment, define the following: @@ -129,6 +129,8 @@ For each topology you use in your testbed environment, define the following: - server - server where the testbed resides. Choose a veos_group to use that contains both the lab server and virtual machines - vm_base - enter in the lowest ID value for the VMs you will be using to run the test cases. The lowest VM ID value can be found under the veos section of the testbed configuration file. IF empty, no VMs are used - dut - enter in the target DUT that is used in the testbed environment +- inv_name - inventory file name that contains the definition of the target DUTs +- auto_recover - (`yes`|`True`|`true`) to recover this testbed when runnings serve recovery script, (`no`|`False`|`false`) otherwise - comment - make a little note here - ansible - ansible_host - IP address with port number diff --git a/docs/testbed/README.testbed.Cli.md b/docs/testbed/README.testbed.Cli.md index 22d65128c80..e9d61dd27e7 100644 --- a/docs/testbed/README.testbed.Cli.md +++ b/docs/testbed/README.testbed.Cli.md @@ -12,9 +12,9 @@ ## Add/Remove topo ``` -# conf-name,group-name,topo,ptf_image_name,ptf,ptf_ip,ptf_ipv6,server,vm_base,dut,comment -vms1-1-t1,vms1-1,t1,docker-ptf,ptf-1,10.0.10.5/23,,server_1,VM0100,str-msn2700-11,t1 tests -vms1-1-t1-lag,vms1-1,t1-lag,docker-ptf,ptf-2,10.0.10.5/23,,server_1,VM0100,str-msn2700-11,t1-lag tests +# conf-name,group-name,topo,ptf_image_name,ptf,ptf_ip,ptf_ipv6,server,vm_base,dut,inv_name,auto_recover,comment +vms1-1-t1,vms1-1,t1,docker-ptf,ptf-1,10.0.10.5/23,,server_1,VM0100,str-msn2700-11,lab,True,t1 tests +vms1-1-t1-lag,vms1-1,t1-lag,docker-ptf,ptf-2,10.0.10.5/23,,server_1,VM0100,str-msn2700-11,lab,False,t1-lag tests ``` Goal is to use one VM with different topologies diff --git a/docs/testbed/README.testbed.Config.md b/docs/testbed/README.testbed.Config.md index 19d32950464..316c470f851 100644 --- a/docs/testbed/README.testbed.Config.md +++ b/docs/testbed/README.testbed.Config.md @@ -25,10 +25,10 @@ ### ```testbed.csv``` format ``` -# conf-name,group-name,topo,ptf_image_name,ptf,ptf_ip,ptf_ipv6,server,vm_base,dut,comment -ptf1-m,ptf1,ptf32,docker-ptf,ptf-1,10.255.0.188/24,,server_1,,str-msn2700-01,Tests ptf -vms-t1,vms1-1,t1,docker-ptf,ptf-2,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,Tests vms -vms-t1-lag,vms1-1,t1-lag,docker-ptf,ptf-3,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,Tests vms +# conf-name,group-name,topo,ptf_image_name,ptf,ptf_ip,ptf_ipv6,server,vm_base,dut,inv_name,auto_recover,comment +ptf1-m,ptf1,ptf32,docker-ptf,ptf-1,10.255.0.188/24,,server_1,,str-msn2700-01,lab,False,Tests ptf +vms-t1,vms1-1,t1,docker-ptf,ptf-2,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,lab,True,Tests vms +vms-t1-lag,vms1-1,t1-lag,docker-ptf,ptf-3,10.255.0.178/24,,server_1,VM0100,str-msn2700-01,lab,True,Tests vms ``` @@ -40,6 +40,8 @@ vms-t1-lag,vms1-1,t1-lag,docker-ptf,ptf-3,10.255.0.178/24,,server_1,VM0100,str-m - server – server where the testbed resides - vm_base – first VM for the testbed. If empty, no VMs are used - dut – target dut name +- inv_name - inventory file name that contains the definition of the target DUTs +- auto_recover - (`yes`|`True`|`true`) to recover this testbed when runnings serve recovery script, (`no`|`False`|`false`) otherwise - comment – any text here ### ```testbed.csv``` consistency rules diff --git a/tests/common/testbed.py b/tests/common/testbed.py index 83bab7cecb3..55c45de7b91 100644 --- a/tests/common/testbed.py +++ b/tests/common/testbed.py @@ -21,7 +21,8 @@ class TestbedInfo(object): """Parse the testbed file used to describe whole testbed info.""" - TESTBED_FIELDS = ('conf-name', 'group-name', 'topo', 'ptf_image_name', 'ptf', 'ptf_ip', 'ptf_ipv6', 'server', 'vm_base', 'dut', 'comment') + TESTBED_FIELDS_DEPRECATED = ('conf-name', 'group-name', 'topo', 'ptf_image_name', 'ptf', 'ptf_ip', 'ptf_ipv6', 'server', 'vm_base', 'dut', 'comment') + TESTBED_FIELDS_RECOMMENDED = ('conf-name', 'group-name', 'topo', 'ptf_image_name', 'ptf', 'ptf_ip', 'ptf_ipv6', 'server', 'vm_base', 'dut', 'inv_name', 'auto_recover', 'comment') def __init__(self, testbed_file): if testbed_file.endswith(".csv"): @@ -69,13 +70,18 @@ def _ip_mask_to_cidr(self, ip_address, netmask): def _read_testbed_topo_from_csv(self): """Read csv testbed info file.""" with open(self.testbed_filename) as f: - topo = csv.DictReader(f, fieldnames=self.TESTBED_FIELDS, - delimiter=',') + header = [field.strip(' #') for field in f.readline().strip().split(',')] + print(header) + if len(header) == len(self.TESTBED_FIELDS_DEPRECATED): + self.testbed_fields = self.TESTBED_FIELDS_DEPRECATED + elif len(header) == len(self.TESTBED_FIELDS_RECOMMENDED): + self.testbed_fields = self.TESTBED_FIELDS_RECOMMENDED + else: + raise ValueError('Unsupported testbed fields %s' % str(header)) + for header_field, expect_field in zip(header, self.testbed_fields): + assert header_field == expect_field - # Validate all field are in the same order and are present - header = next(topo) - for field in self.TESTBED_FIELDS: - assert header[field].replace('#', '').strip() == field + topo = csv.DictReader(f, fieldnames=self.testbed_fields, delimiter=',') for line in topo: if line['conf-name'].lstrip().startswith('#'): @@ -89,7 +95,7 @@ def _read_testbed_topo_from_csv(self): self._cidr_to_ip_mask(line['ptf_ipv6']) line['duts'] = line['dut'].translate(string.maketrans("", ""), "[] ").split(';') - line['duts_map'] = {dut:line['duts'].index(dut) for dut in line['duts']} + line['duts_map'] = {dut: line['duts'].index(dut) for dut in line['duts']} del line['dut'] self.testbed_topo[line['conf-name']] = line @@ -135,6 +141,7 @@ class IncIndentDumper(yaml.Dumper): [1]: https://web.archive.org/web/20170903201521/https://pyyaml.org/ticket/64 [2]: https://github.com/yaml/pyyaml/issues/127 """ + def increase_indent(self, flow=False, indentless=False): return yaml.Dumper.increase_indent(self, flow, False) @@ -153,7 +160,7 @@ def write_line_break(self, data=None): ptf_ipv6 = self._ip_mask_to_cidr(tb_dict["ptf_ipv6"], tb_dict["ptf_netmask_v6"]) testbed_mapping = zip( - self.TESTBED_FIELDS, + self.testbed_fields, [ tb_name, tb_dict["group-name"],