2017-09-23 77 views
0

我试图在Python中实现一个脚本,该脚本会自动将测试序列(ERTMS子集-076-6-3)中定义的事件列表转换为更正式的定义;以便使用这种新形式在某些日志文件中搜索此事件。将半结构化文本列表转换为正式定义

的事件在一个半结构化的形式定义如下的例子:

  • “含有分组255被接收到一个应答器组的消息(NID_BG = BGB)”

  • “DMI符号状态(NID_MESSAGE_JRU = 21; DMI_SYMB_STATUS = < Bit66 = 0 & Bit68 = 0 & Bit70 = 0 & Bit72 = 0 & Bit74 = 0 & Bit76 = 0>)被记录”

  • “行车制动介入被记录。”
  • “SA-CONNECT.Confirm接收”
  • “SA-DATA请求与欧洲广播消息 ”的通信会话的发起“(NID_MESSAGE = 155)被发送”
  • “SA-DATA指示与欧洲广播收到“RBC/RIU系统版本”(NID_MESSAGE = 32)消息“
  • 驱动程序的验证操作记录在JRU上。

我现在的计划是解析每个事件列表和保存,我可以在日志检查值(即NID_MESSAGE_JRU = 21 Bit66 = 0 Bit68 = 0 Bit70 = 0 Bit72 = 0 Bit74 = 0 Bit76 = 0)并且将正确条件的评估函数的名称:

def and(): 
    return(NID_MESSAGE_JRU==21 && Bit66==0 && Bit68==0 && Bit70==0 && Bit72==0 && Bit74==0 && Bit76==0) 

然后该程序,然后分析日志,搜索将返回真到了那个功能的信息,记录比赛看看其他条件。

现在我正在寻找一种方法来尽可能地自动化这个过程,因为它有700多个测试序列,每个测试序列大概有80个事件。

经过一番研究后,我发现使用解析器生成器可以满足我的需求,但是我被困在它们的绝对数量中,我无法选择哪一个更适合我的问题。

我想出了另一种解决方案是,以评估我的事件用一些简单的正则表达式,并使用它们产生的评估条件,然后使用eval()来评价他们,我已经从日志加载后的值:

s = "DMI SYMBOL STATUS (NID_MESSAGE_JRU=21; DMI_SYMB_STATUS=<Bit66=0&Bit68=0&Bit70=0&Bit72=0&Bit74=0&Bit76=0>) is recorded" 

s1 = s[s.find("(")+1:s.find(" ")] 
s2 = s[s.find("<")+1:s.find(">")] 
condition = s1 + s2 
condition = re.sub('[=]','==',condition) 
condition = re.sub('[;&]', '&&',condition) 
condition='NID_MESSAGE_JRU==21&&Bit66==0&&Bit68==0 
      &&Bit70==0&&Bit72==0&&Bit74==0&&Bit76==0' 

对于哪个解析生成器适合我的需求,您有什么建议吗?还是应该继续使用正则表达式?或者我完全走错了路?

+0

基准3次测试都可以在这里:http://www.era.europa.eu/Document-Register/Pages/Set-2-Test -Sequences.aspx – Riccardo

+0

我无法下载测试序列文件(它们在大约35 MB下载时保持失败);设法通过将它们交叉加载到我的DropBox然后从那里下载来解决这个问题。 –

+0

到目前为止:4个.zip测试文件总共包含733个.zip测试用例(每个测试用例略大于1 MB)。每种情况都包括一个.bmp(Windows位图)图像,用于绘制测试场景(如列车速度与距离),一个.doc(Word 97)文档,以及一个.mdb(Microsoft Access)数据库,该数据库包含事件的测试顺序29张桌子,其中一些是空的。我还没有弄清楚数据库模式,但它看起来基本上重复了.doc(仅仅因为一大堆额外的东西被铲除)。 –

回答

0

我想我应该从要分析的字符串的综合列表开始。

我下载了测试数据文件(1009 MB)并解压缩它们(733 .zip文件,1009 MB)。然后我写了

from collections import Counter 
import glob 
import os 
import pyodbc 
from zipfile import ZipFile 

DATA_DIR  = "~/subset076"  # dir containing test-case .zip files 
TEMP_DIR  = "~/subset076/temp" 
CONN_STR  = r"DRIVER={{Microsoft Access Driver (*.mdb, *.accdb)}};DBQ={}" 
DATA_TABLE = "TSW_TCStep" 
DATA_FIELD = "ST_DESCRIPTION" 

def get_mdbs(): 
    for fname in glob.glob(os.path.join(DATA_DIR, "*.zip")): 
     zf = ZipFile(fname) 
     for member in zf.namelist(): 
      _, ext = os.path.splitext(member) 
      if ext.lower() == ".mdb": 
       print("Extracting", member) 
       zf.extract(member, path = TEMP_DIR) 

def get_test_strings(): 
    test_strings = Counter() 
    sql = "SELECT {} FROM {}".format(DATA_FIELD, DATA_TABLE) 
    for fname in glob.glob(os.path.join(TEMP_DIR, "*.mdb")): 
     print("Working on", fname) 
     with pyodbc.connect(CONN_STR.format(fname)) as conn: 
      cursor = conn.cursor() 
      cursor.execute(sql) 
      test_strings.update(row[0] for row in cursor) 
    return test_strings 

get_mdbs() 
ts = get_test_strings() 

其解压所有的.mdb文件(733个文件,718 MB),并抓住所有的测试序列事件串。我结束了4495个独特的字符串,总共73320个字符串。排序,你得到https://pastebin.com/reSGn8JE(约400 kB)。

我会继续上实际解析它的明天...

+0

感谢您的关注!我做了同样的分析,但得出结论,我不能单独评估一些事件,因为它们彼此相关,例如: - 驾驶员验证列车数据。 - 驾驶员的验证行为记录在JRU上。 - 完整的训练数据集记录在JRU上。 因此,至少我们需要订购该列表或更好的方法来分析每个测试用例(测试序列由多个测试用例组成),因为它们重复了很多次。 – Riccardo

+0

我不确定你正在试图做什么 - 在日志中搜索以查找测试错误?看起来你必须基本上实现一个测试器来查看你应该得到什么输出,然后比较理想的输出和日志中的实际输出。 –

+0

在任何情况下,数据库似乎组织得体(虽然官方架构将是有用的,并可能指出我错过的东西!)。 SC_Interfaces和SC_Internal表包含测试开始条件; TSW_TCStep包含测试的每个步骤,TSW_MessageHeader和TSW_MessageBody包含在每个步骤发送的消息(命令?),TSW_SpeedProfile具有列车移动,EC_Interfaces和EC_Internal为您提供预期结果。 –