zoukankan      html  css  js  c++  java
  • python学习重温(1)自动case生成工具


         因为最近工作中,需要设计根据wirshark截获的报文自动产生测试case的小工具,我重温了python。这个笔记,就是根据这个工具的实现,来记录python语法的学习过程。

    这个工具的功能如下图所示,其中wirshark cap可以通过wirshark自身的功能导出为pmsl格式,也就是一种XML,同时公司使用的case script也是一种XML,只是添加了一些循环,判断等功能。

      

    所以这个工具涉及文件操作,XML解析和一些python的基本语法功能


    一、PYTHON 基本语法概念

    1.什么是main函数

    if __name__ == "__main__":


    上面这个就是python的main函数的声明


    2. 变量申明

    python对变量申明不像那么严格,但也不像shell那么随便。一般变量通过首次赋值产生,当超出作用范围时自动消亡。这几句话的意思是,变量如果要使用就一定要先给他赋值。比如

    print str1

    一定会报错

    Traceback (most recent call last):
      File "<pyshell#0>", line 1, in <module>
        print str1
    NameError: name 'str1' is not defined


    所以一定要先赋值

    str1 = 'hello'
    print str1


    python一样有全局变量和局部变量的概念。


    3. python 常用的变量类型

    数值型

    value = 12


    string

    str1 = 'hello'
    str1 = "hello"

    这里有个双引号还是单引号的问题,我的理解是除非设计转义字符,两者都是一样的。

    a = 'let\'s us'
    a = "let's us"



    list

    也就是C语言中的数组

    a = ['spam', 'eggs', 100, 1234]

    支持下标访问

    a[0]
    a[1]


    Dictionary

    大家称呼这个味字典型,其实可以类比为C语言中的结构体。因为python里面是没有struct这类东西的,当然python可以用class的方法替代struct。但Dictionary这个类型也可以在某些时候当做struct这个概念来用

    d = {"server":"mpilgrim", "database":"master"}


    这个类型是可以作为不同类型数据的container的,但要注意一个问题dictionary在插入的时候是乱序的,也就是说当我做

    d["newdata"]='fda'

    这个操作后,这个新加入的项会随机加在d中,不一定在最后。

    4.Python的层次结构

    python依靠代码缩进和:来确定代码的前后层次关系

    如下面这个函数,缩进起到了C语言中{}的作用。


    def GetEnumName(attribename,valuestr):
        """
        
        @author: limim
        
        @param attribename:attribname 
        @type attribename:str
        @param valuestr:mmt log value
        @type valuestr:str
        @return:the enum name
        @rtype:str
        """
        tree = ReadFromXml('PegasusEnumMapping.xml')
        root = tree.getroot()
        value = str(int(valuestr,16))
        errorret = ''
        for listnode in root.iter('attrib'):
            strlist = listnode.attrib['name'].split('.')
            attriblist = attribename.split('.')
            substrlist = strlist[(len(strlist)-4):]
            subattriblist = attriblist[(len(attriblist)-4):]
            if substrlist == subattriblist:
                for enumlistnode in listnode:
                    if enumlistnode[0].text == value:
                      return enumlistnode[1].text
                    else:
                      errorret = enumlistnode[1].text
        print "error"
        print attribename
        print 'mmt log value' + ' ' + valuestr
        print 'set default value' + ' ' + errorret
        print '##############'
        return errorret


    二、elementTree

    这个工具处理的主要文件格式是XML,就用elementTree这个库来处理,下面是要处理文件格式的一部分。

    <?xml version="1.0"?>
    <pdml version="0" creator="wireshark/1.20.0.1">
    <packet>
      <proto name="geninfo" pos="0" showname="General information" size="98">
        <field name="num" pos="0" show="1246" showname="Number" value="4de" size="98"/>
        <field name="len" pos="0" show="98" showname="Frame Length" value="62" size="98"/>
        <field name="caplen" pos="0" show="98" showname="Captured Length" value="62" size="98"/>
        <field name="timestamp" pos="0" show="Mar  6, 2013 18:28:28.729395000 China Standard Time" showname="Captured Time" value="1362565708.729395000" size="98"/>
      </proto>
      <proto name="frame" showname="Frame 1246: 98 bytes on wire (784 bits), 98 bytes captured (784 bits)" size="98" pos="0">
        <field name="frame.time" showname="Arrival Time: Mar  6, 2013 18:28:28.729395000 China Standard Time" size="0" pos="0" show="Mar  6, 2013 18:28:28.729395000"/>
        <field name="frame.time_epoch" showname="Epoch Time: 1362565708.729395000 seconds" size="0" pos="0" show="1362565708.729395000"/>
        <field name="frame.time_delta" showname="Time delta from previous captured frame: 0.000475000 seconds" size="0" pos="0" show="0.000475000"/>
        <field name="frame.time_delta_displayed" showname="Time delta from previous displayed frame: 0.000000000 seconds" size="0" pos="0" show="0.000000000"/>
        <field name="frame.time_relative" showname="Time since reference or first frame: 93.072253000 seconds" size="0" pos="0" show="93.072253000"/>
        <field name="frame.number" showname="Frame Number: 1246" size="0" pos="0" show="1246"/>
        <field name="frame.len" showname="Frame Length: 98 bytes (784 bits)" size="0" pos="0" show="98"/>
        <field name="frame.cap_len" showname="Capture Length: 98 bytes (784 bits)" size="0" pos="0" show="98"/>
        <field name="frame.marked" showname="Frame is marked: False" size="0" pos="0" show="0"/>
        <field name="frame.ignored" showname="Frame is ignored: False" size="0" pos="0" show="0"/>
        <field name="frame.protocols" showname="Protocols in frame: eth:ip:udp:mmtss:sicap" size="0" pos="0" show="eth:ip:udp:mmtss:sicap"/>
        <field name="frame.coloring_rule.name" showname="Coloring Rule Name: SICAP" size="0" pos="0" show="SICAP"/>
        <field name="frame.coloring_rule.string" showname="Coloring Rule String: sicap" size="0" pos="0" show="sicap"/>
      </proto>
      <proto name="eth" showname="Ethernet II, Src: 192.168.254.1 (00:0f:bb:69:93:ee), Dst: DCT-INF (00:10:18:cb:b5:fd)" size="14" pos="0">
        <field name="eth.dst" showname="Destination: DCT-INF (00:10:18:cb:b5:fd)" size="6" pos="0" show="00:10:18:cb:b5:fd" value="001018cbb5fd">
          <field name="eth.addr" showname="Address: DCT-INF (00:10:18:cb:b5:fd)" size="6" pos="0" show="00:10:18:cb:b5:fd" value="001018cbb5fd"/>
          <field name="eth.ig" showname=".... ...0 .... .... .... .... = IG bit: Individual address (unicast)" size="3" pos="0" show="0" value="0" unmaskedvalue="001018"/>
          <field name="eth.lg" showname=".... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)" size="3" pos="0" show="0" value="0" unmaskedvalue="001018"/>
        </field>
        <field name="eth.src" showname="Source: 192.168.254.1 (00:0f:bb:69:93:ee)" size="6" pos="6" show="00:0f:bb:69:93:ee" value="000fbb6993ee">
          <field name="eth.addr" showname="Address: 192.168.254.1 (00:0f:bb:69:93:ee)" size="6" pos="6" show="00:0f:bb:69:93:ee" value="000fbb6993ee"/>
          <field name="eth.ig" showname=".... ...0 .... .... .... .... = IG bit: Individual address (unicast)" size="3" pos="6" show="0" value="0" unmaskedvalue="000fbb"/>
          <field name="eth.lg" showname=".... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)" size="3" pos="6" show="0" value="0" unmaskedvalue="000fbb"/>
        </field>
        <field name="eth.type" showname="Type: IP (0x0800)" size="2" pos="12" show="0x0800" value="0800"/>
      </proto>


    1. 文件读取

    from xml.etree.ElementTree import ElementTree, Element
    import sys
    
    def ReadFromXml(path):
        ''''read from xml and prase it
            author:limin 
            path: the file path
            return ElementTree'''
        tree = ElementTree()
        tree.parse(path);
        return tree

    通过

    tree = ElementTree()
    tree.parse(path);

    就获得了XML文件的指针

     在调试模式下,可以看到tree就是根据读入的XML文件用不同层级的NODE构成的结构体。这个时候操作就很方便了,我们可以先拿到root,在遍历整个tree就可以方便的读取XML中任意一个节点的attrib,text,tag这些内容。


        
    def ReadPacketContent(tree,framenum):
        '''
        read the packet content
        node:the xml node
        num: the index of the node
        '''
        SicCapMessage = []
        root = tree.getroot()   #check the boundary
        num = 0
        flag = 0
        for node in root:  # proto level node
          if flag == 1:
            break
          num = num + 1
            #print protonode.tag,protonode.attrib
          for protonode in node: 
            if protonode.attrib['name'] == 'frame':
              frameList = parseFrameHead(protonode)
              if frameList[1] != str(framenum):
                break
              else:
                SicCapMessage.insert(0,frameList)
                print "find the frame, number is" + frameList[1] 
                flag = 1
        print num
        print len(root)
        if num == 0 or num > len(root) - 1:
           print "can not find the frame num"
           return SicCapMessage
        
        for protonode in root[num - 1]:
            if protonode.attrib['name'] == 'sicap':
                #dictPrint(parseSiCapMessage(protonode))
                SicCapMessage.extend(parseSiCapMessage(protonode))
            
        return SicCapMessage


    可以看到

    protonode.attrib

    就是一个dictionary类型的变量


    2.文件写入

    读取的问题解决了,剩下的就是写入了。只用调用

    tree.write('test.xml','UTF-8')

    就可以将内存中的tree写入文件

  • 相关阅读:
    vue 开发系列 企业微信整合
    MongoDB基础3
    MongoDB基础2
    MongoDB基础1
    SpringBoot MongoDB
    UWSGI
    Nginx
    编译python源码
    Flask部署
    Django个人工作总结
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3006047.html
Copyright © 2011-2022 走看看