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爲您提供預期結果。 –