IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 网络设备自动化测试之逻辑拓扑自动生成 -> 正文阅读

[开发测试]网络设备自动化测试之逻辑拓扑自动生成

设计说明

网络设备功能测试自动化时,有成千上万个测试案例,幸好拓扑总共只有几十种。但是仍然不能针对每种拓扑都去连好线,这样资源开销太大,又难以维护。实际中我们使用拓扑交换,每台DUT只需要和拓扑交换机相连即可。然后定义好这几十种逻辑拓扑的xml文件,测试用例中指明所使用的拓扑。运行用例时根据逻辑拓扑来划分拓扑交换机上的vlan,从而实现逻辑拓扑的自动生成。同时也会为每个DUT的接口自动配置IP地址。

这种逻辑拓扑生成的方式非常灵活,支持以任意顺序执行全部或者任意部分的测试用例。

扩展性好:增加新拓扑只需要定义新的逻辑拓扑xml文件。如果DUT数目不足,可以在物理拓扑中增加新的DUT。如果拓扑交换机的端口不足,可以轻松扩展为支持多个拓扑交换机。

代码实现

pysical_top.xml:

这里dut1使用了逻辑端口编号,而拓扑交换机使用了实际的接口编号。是因为DUT的端口常会变化,但是拓扑交换机的接口通常不变。这里只列出了三台DUT,实际中DUT比这个多。实际中还有测试仪接口连接在拓扑交换机上。但是因为对测试仪接口的拓扑生成和DUT的一样,所以这里没有额外再列出。这个框架可以轻松扩展为支持多个拓扑交换机,只需要将物理拓扑中的拓扑交换机即dst_dev也提取出来,后续和单机一样水平扩展即可。

<?xml version="1.0" encoding="UTF-8"?>
<Topology>
<Devices name="dut1" type="dut" model="router">
	<Connections src_dev="dut1" src_port="port1" dst_dev="tsw1" dst_port="gigabitethernet 1/0/0"></Connections>
	<Connections src_dev="dut1" src_port="port2" dst_dev="tsw1" dst_port="gigabitethernet 1/0/1"></Connections>
	<Connections src_dev="dut1" src_port="port3" dst_dev="tsw1" dst_port="gigabitethernet 1/0/2"></Connections>
	<Connections src_dev="dut1" src_port="port4" dst_dev="tsw1" dst_port="gigabitethernet 1/0/3"></Connections>
</Devices>
<Devices name="dut2" type="dut" model="router">
	<Connections src_dev="dut2" src_port="port1" dst_dev="tsw1" dst_port="gigabitethernet 1/0/4"></Connections>
	<Connections src_dev="dut2" src_port="port2" dst_dev="tsw1" dst_port="gigabitethernet 1/0/5"></Connections>
	<Connections src_dev="dut2" src_port="port3" dst_dev="tsw1" dst_port="gigabitethernet 1/0/6"></Connections>
	<Connections src_dev="dut2" src_port="port4" dst_dev="tsw1" dst_port="gigabitethernet 1/0/7"></Connections>
</Devices>
<Devices name="dut3" type="dut" model="router">
	<Connections src_dev="dut3" src_port="port1" dst_dev="tsw1" dst_port="gigabitethernet 1/0/8"></Connections>
	<Connections src_dev="dut3" src_port="port2" dst_dev="tsw1" dst_port="gigabitethernet 1/0/9"></Connections>
	<Connections src_dev="dut3" src_port="port3" dst_dev="tsw1" dst_port="gigabitethernet 1/0/10"></Connections>
	<Connections src_dev="dut3" src_port="port4" dst_dev="tsw1" dst_port="gigabitethernet 1/0/11"></Connections>
</Devices>
</Topology>

triangle.xml

本例中定义了三角形的逻辑拓扑xml文件triangle.xml。

<?xml version="1.0" encoding="UTF-8"?>

<Connections src_dev="dut1" src_port="port1" dst_dev="dut2" dst_port="port1"></Connections>
<Connections src_dev="dut1" src_port="port2" dst_dev="dut3" dst_port="port2"></Connections>
<Connections src_dev="dut2" src_port="port2" dst_dev="dut3" dst_port="port1"></Connections>

topology.py

#python3.8
#coding=utf-8
#author=liuyifan

VLAN_START = 4000
IP_ADDRESS_PATTERN = "51.0.{}.{}/24"

from bs4 import BeautifulSoup

class Topology():
    # 解析物理拓扑文件,将所有connections存储到字典中,(src_dev,src_port)是key,拓扑交换机的接口即dst_port是value
    def parse_pysical_top(self,xml_top_file):
        d = {}
        soup = BeautifulSoup(open(xml_top_file), 'html.parser')
        for c in soup.find_all("connections"):
            d[c.get("src_dev"),c.get("src_port")]=c.get("dst_port")
        return d

    # 解析逻辑拓扑文件,将所有connections存储到列表中,这是一个两层列表,第一层每一个元素代表一个connection,
    # 对于每一个connection列表第一个元素是(src_dev,src_port),第二个元素是(dst_dev,dst_port)
    def parse_logical_top(self,xml_top_file):
        lst, inner_lst = [], []
        soup = BeautifulSoup(open(xml_top_file), 'html.parser')
        for c in soup.find_all("connections"):
            inner_lst.append((c.get("src_dev"),c.get("src_port")))
            inner_lst.append((c.get("dst_dev"),c.get("dst_port")))
            lst.append(inner_lst)
            inner_lst = []
        return lst

    # 输入为parse_logical_top()的返回值,为每一个接口分配一个ip地址
    # 所有connections存储到列表中,这个一个三层列表,第一层每一个元素代表一个connection,
    # 对于一个connection列表第一个元素是[src_dev,src_port,ip_address],第二个元素是[dst_dev,dst_port,ip_address]。
    def generate_ip_address(self,logic):
        lst, inner_lst, inner_inner_lst = [], [], []
        for i in range(len(logic)):
            for j in range(len(logic[i])):
                inner_inner_lst.append(logic[i][j][0])
                inner_inner_lst.append(logic[i][j][1])
                inner_inner_lst.append(IP_ADDRESS_PATTERN.format(i+1,j+1))
                inner_lst.append(inner_inner_lst)
                inner_inner_lst = []
            lst.append(inner_lst)
            inner_lst = []
        return lst


    # 综合物理拓扑和逻辑拓扑的解析结果,得出拓扑交换机物理接口vlan划分关系。
    # 返回一个2维列表,一级列表中每个元素是一个列表。内层列表的内容为两个拓扑交换机的接口和它们所属的vlan。
    def partition_tsw_vlan(self,pysical,logic):
        lst, inner_lst = [], []
        vlan_offset = 0
        for connection in logic:
            for intf in connection:
                # 找到dut该接口所连的拓扑交换机的物理接口
                inner_lst.append(pysical[intf])
            inner_lst.append(VLAN_START + vlan_offset)
            vlan_offset += 1
            lst.append(inner_lst)
            inner_lst = []
        return lst

if __name__ == '__main__':
    top = Topology()
    pysical = top.parse_pysical_top("pysical_top.xml")
    print("物理拓扑解析结果:")
    pprint.pprint(pysical)
    logic = top.parse_logical_top("triangle.xml")
    print("逻辑拓扑解析结果:")
    pprint.pprint(logic)
    vlans = top.partition_tsw_vlan(pysical,logic)
    print("拓扑交换机VLAN划分方案:")
    pprint.pprint(vlans)
    addresses = top.generate_ip_address(logic)
    print("DUT接口IP地址分配方案:")
    pprint.pprint(addresses)
    #最后根据vlans中指定的vlan关系,使用拓扑交换机实际的命令来划分出vlan,就完成了逻辑拓扑的生成。
    #根据配置文件找出实际的DUT登录方式和对应的实际接口,配置相应的IP地址。

运行输出:

物理拓扑解析结果:
{('dut1', 'port1'): 'gigabitethernet 1/0/0',
 ('dut1', 'port2'): 'gigabitethernet 1/0/1',
 ('dut1', 'port3'): 'gigabitethernet 1/0/2',
 ('dut1', 'port4'): 'gigabitethernet 1/0/3',
 ('dut2', 'port1'): 'gigabitethernet 1/0/4',
 ('dut2', 'port2'): 'gigabitethernet 1/0/5',
 ('dut2', 'port3'): 'gigabitethernet 1/0/6',
 ('dut2', 'port4'): 'gigabitethernet 1/0/7',
 ('dut3', 'port1'): 'gigabitethernet 1/0/8',
 ('dut3', 'port2'): 'gigabitethernet 1/0/9',
 ('dut3', 'port3'): 'gigabitethernet 1/0/10',
 ('dut3', 'port4'): 'gigabitethernet 1/0/11'}
逻辑拓扑解析结果:
[[('dut1', 'port1'), ('dut2', 'port1')],
 [('dut1', 'port2'), ('dut3', 'port2')],
 [('dut2', 'port2'), ('dut3', 'port1')]]
拓扑交换机VLAN划分方案:
[['gigabitethernet 1/0/0', 'gigabitethernet 1/0/4', 4000],
 ['gigabitethernet 1/0/1', 'gigabitethernet 1/0/9', 4001],
 ['gigabitethernet 1/0/5', 'gigabitethernet 1/0/8', 4002]]
DUT接口IP地址分配方案:
[[['dut1', 'port1', '51.0.1.1/24'], ['dut2', 'port1', '51.0.1.2/24']],
 [['dut1', 'port2', '51.0.2.1/24'], ['dut3', 'port2', '51.0.2.2/24']],
 [['dut2', 'port2', '51.0.3.1/24'], ['dut3', 'port1', '51.0.3.2/24']]]

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-09-03 12:13:08  更:2021-09-03 12:15:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/21 3:43:11-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码