# -*- coding: GBK -*-    
 | 
#write:zb  
 | 
#  
 | 
##@package PythonTrack.py  
 | 
# Ä£¿éµÄ¼òҪ˵Ã÷:´úÂëÖ´ÐÐÂÊ×·×ÙÄ£¿é  
 | 
# @author:zb  
 | 
# @date 2010-01-01 00:00  
 | 
# @version 2.0  
 | 
#  
 | 
# ÐÞ¸Äʱ¼ä ÐÞ¸ÄÈË ÐÞ¸ÄÄÚÈÝ  
 | 
# @change: "2010-05-14 09:35" zb ¸ü¸Ä´úÂë×¢ÊÍ  
 | 
# @change: "2010-06-09 17:50" zfl ÐÞ¸ÄPY½âÎöÂß¼¡¢ÐÂÔö²¿·Ö¹¦ÄÜ  
 | 
# @change: "2010-07-02 17:30" zfl ÐÞÕýPY½âÎö£¬¶ªÊ§ÎÞË«#×¢Êͺ¯ÊýµÄBug£¬Ð޸ı¨¸æÄÚÈÝ£¬´úÂëÈ«²¿ÏÔʾ£¬ÐǺŴú±íΪִÐÐ  
 | 
# @change: "2010-07-14 13:55" zfl Ð޸ı¨¸æÄÚÈÝ,·Ö½çÃæÏÔʾºÍдÈëÎļþ£»¼°ÐÐºÅµÄ¶ÔÆëÏÔʾ  
 | 
# @change: "2010-07-20 14:25" zfl ÐÞ¸ÄPYÄÚ²¿´¢´æÀàΪ¶ÀÁ¢Ä£¿é  
 | 
# @change: "2010-07-26 15:00" zfl Ð¼ӲâÊÔ±¨¸æÔØÈ빦ÄÜ  
 | 
# @change: "2010-08-03 11:50" zfl Ð¼ӷµ»ØPy¸²¸ÇÂʹ¦ÄÜ  
 | 
# @change: "2010-08-06 11:50" zfl Ð¼ӷµ»Ø¿ÉÖ´ÐÐÓï¾ä×ÜÐÐÊý¹¦ÄÜ  
 | 
# @change: "2010-11-03 10:00" zfl Ð¼ÓÉú³É×ÜÖ´ÐÐÂʱ¨¸æ  
 | 
# @change: "2012-02-23 15:30" Alee ¿ÕÎļþ±¨´í·À·¶£¬¾ßÌåÔÒòδ²é  
 | 
#  
 | 
# Ä£¿éÏêϸ˵Ã÷:´úÂëÖ´ÐÐÂÊ×·×ÙÄ£¿é  
 | 
#  
 | 
#-------------------------------------------------------------------------------  
 | 
  
 | 
"""Version = 2012-02-23 15:30"""  
 | 
  
 | 
#-------------------------------------------------------------------------------  
 | 
#µ¼Èë  
 | 
import os  
 | 
import time  
 | 
import traceback  
 | 
import PyTrackObj  
 | 
import ReportAnalyzer  
 | 
  
 | 
#-------------------------------------------------------------------------------  
 | 
#È«¾Ö±äÁ¿  
 | 
  
 | 
FORM_NAME = "PythonTrack"  
 | 
  
 | 
g_pyObjDic = {}                   # py¶ÔÏó×Öµä  
 | 
#IGNORE_FUNC_LIST = eval(GameWorld.GetGui().GetIniData("PythonTrack",'IgnoreFunc'))         #ºöÂÔº¯ÊýÁÐ±í  
 | 
  
 | 
IGNORE_FUNC_LIST = []  
 | 
SCRIPT_PATH = os.getcwd() + '\\' + 'Script'         # Script·¾¶  
 | 
REPORT_PATH = os.getcwd() + '\\' + 'TestReport'     # TestReport·¾¶  
 | 
  
 | 
#--µ÷ÊÔº¯Êý----------------------------------------------------------------------  
 | 
  
 | 
NOW_TIME = 'log%s%s%s%s%s%s.txt'%tuple(['%02d'%time.localtime()[i] for i in range(6)])  
 | 
  
 | 
  
 | 
MD5_KEY = "renshk"  
 | 
  
 | 
## Ð´logº¯Êý  
 | 
#  @param *varlist ²»¶¨²Î  
 | 
#  @return ÎÞ·µ»ØÖµ  
 | 
#  @remarks ½«´«ÈëµÄlogÐÅϢдÈëÖ¸¶¨logÎļþ  
 | 
def LogEx(*varlist):  
 | 
    info='[%s%s%s%s%s%s]'%tuple(['%02d'%time.localtime()[i] for i in range(6)])  
 | 
    for i in range(1,len(varlist)):  
 | 
        curValue = varlist[i]  
 | 
        info+="( "+str(type(curValue))+":"+str(curValue)+" ),"  
 | 
      
 | 
    logfile = open("log\\" +  NOW_TIME, 'a')  
 | 
    logfile.write('\t'*int(varlist[0])+info+'\n')  
 | 
    logfile.close()  
 | 
      
 | 
      
 | 
LogEx(0, "SCRIPT_PATH=%s"%SCRIPT_PATH)  
 | 
      
 | 
      
 | 
## ¼Ç¼ִÐÐÇé¿ö  
 | 
#  @param pyName£º±»Ö´ÐеÄPyÃû£¬º¯ÊýÃû£¬µÚ¼¸ÐÐ  
 | 
#  @return ÎÞ  
 | 
#  @remarks £º¼Ç¼ִÐÐÇé¿ö  
 | 
def DoTrack(pyName, funcName, rowIndex, returnValue):  
 | 
#    LogEx(0, 'DoTrack() pyName=%s, funcName=%s, rowIndex=%d, returnValue=%s'%(pyName, funcName, rowIndex, returnValue))  
 | 
    global g_pyObjDic  
 | 
      
 | 
    try:  
 | 
        # Î´´´½¨¸Ãpy¶ÔÏó  
 | 
        if not g_pyObjDic.has_key(pyName):  
 | 
    #        print pyName  
 | 
            g_pyObjDic[pyName] = PyTrackObj.GetPyObj(pyName, MD5_KEY, SCRIPT_PATH)# ´´½¨py¶ÔÏó  
 | 
                  
 | 
        # ¸üк¯Êý¶ÔÏó״̬    
 | 
        g_pyObjDic[pyName].UpdateFuncState(funcName, int(rowIndex), returnValue)  
 | 
#        LogEx(0, "g_pyObjDic.keys()=%s"%g_pyObjDic.keys())  
 | 
    except:  
 | 
        LogEx(1, "Error--%s"%traceback.format_exc())  
 | 
  
 | 
          
 | 
## ¼ÆËãÖ¸¶¨Ä¿Â¼ÏÂPYÎļþµÄÖ´ÐÐÇé¿ö£¬²¢·µ»Ø½á¹û  
 | 
#  @param path£ºÖ¸¶¨Ä¿Â¼  
 | 
#  @param pathCoverageList£º±£´æÖ¸¶¨Ä¿Â¼µÄÖ´ÐÐÇé¿ö  
 | 
#  @return ·µ»ØÖ¸¶¨Ä¿Â¼ÏÂPYÎļþµÄµÄÖ´ÐÐÇé¿ö(ÒÑÖ´ÐÐÐÐÊý£¬×ÜÐÐÊý)  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷£º¼ÆËãÖ¸¶¨Ä¿Â¼ÏÂPYÎļþµÄµÄÖ´ÐÐÇé¿ö£¬²¢·µ»Ø½á¹û  
 | 
def CalcPathCoverage(path, pathCoverageList=None):  
 | 
    global g_pyObjDic  
 | 
      
 | 
    execRowCount = 0  
 | 
    totalRowCount = 0  
 | 
  
 | 
#    LogEx(0, path)  
 | 
    for dir in os.listdir(path):  
 | 
        curPath = path + "\\" + dir  
 | 
        # ÊÇÎļþ  
 | 
        if os.path.isfile(curPath) and (dir.endswith(".py") or dir.endswith(".PY")):  
 | 
            # Î´´´½¨¸Ãpy¶ÔÏó  
 | 
            if not g_pyObjDic.has_key(dir):  
 | 
                # ´´½¨py¶ÔÏó  
 | 
                g_pyObjDic[dir] = PyTrackObj.GetPyObj(dir, MD5_KEY, SCRIPT_PATH)  
 | 
                  
 | 
            pyObj = g_pyObjDic[dir]  
 | 
            pyExecCount, pyTotalCount = pyObj.GetExecRowCount()  
 | 
            execRowCount += pyExecCount  
 | 
            totalRowCount += pyTotalCount  
 | 
              
 | 
#            LogEx(1, pyObj.GetName(), pyExecCount, pyTotalCount)  
 | 
              
 | 
        # ÊÇÎļþ¼Ð  
 | 
        if os.path.isdir(curPath) and not dir.startswith("."):  
 | 
            if pathCoverageList != None:  
 | 
                pyExecCount, pyTotalCount = CalcPathCoverage(curPath, pathCoverageList)  
 | 
            else:  
 | 
                pyExecCount, pyTotalCount = CalcPathCoverage(curPath)  
 | 
                  
 | 
            execRowCount += pyExecCount  
 | 
            totalRowCount += pyTotalCount  
 | 
      
 | 
    if pathCoverageList != None:  
 | 
        if totalRowCount == 0:  
 | 
            percent = 0.0  
 | 
        else:  
 | 
            percent = float(execRowCount)/totalRowCount*100  
 | 
              
 | 
        pathCoverageList.append([path, percent])  
 | 
      
 | 
    return execRowCount, totalRowCount  
 | 
          
 | 
  
 | 
## ·µ»Ø²âÊÔ±¨¸æ¸²¸ÇÂÊ  
 | 
#  @param filePath: PYÎļþÃû»òPyĿ¼·¾¶  
 | 
#  @return ²âÊÔ±¨¸æ¸²¸ÇÂÊ·µ»Ø  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷£º½«²âÊÔ±¨¸æ¸²¸ÇÂÊ·µ»Ø  
 | 
def GetCoverage(sPath):  
 | 
    LogEx(0, "GetCoverage(filePath=%s)"%sPath)  
 | 
    global g_pyObjDic  
 | 
      
 | 
    if sPath.find("\\") == -1 and sPath.endswith(".py") or sPath.endswith(".PY"):  
 | 
          
 | 
        fileName = sPath  
 | 
        # Î´´´½¨¸Ãpy¶ÔÏó  
 | 
        if not g_pyObjDic.has_key(fileName):  
 | 
            g_pyObjDic[fileName] = PyTrackObj.GetPyObj(fileName, MD5_KEY, SCRIPT_PATH)    # ´´½¨py¶ÔÏó  
 | 
          
 | 
        return g_pyObjDic[fileName].GetExecPercent()  
 | 
      
 | 
    if not os.path.isdir(sPath):  
 | 
        LogEx(1, sPath + " is not exist!")  
 | 
        return 0.0  
 | 
      
 | 
    pyExecCount, pyTotalCount = CalcPathCoverage(sPath)  
 | 
      
 | 
    if pyTotalCount == 0:  
 | 
        return 0.0  
 | 
    return float(pyExecCount)/pyTotalCount*100  
 | 
  
 | 
  
 | 
## ·µ»Ø²âÊÔ±¨¸æ×Ü¿ÉÖ´ÐÐÐÐÊý  
 | 
#  @param filePath: PYÎļþÃû»òPyĿ¼·¾¶  
 | 
#  @return ²âÊÔ±¨¸æ×Ü¿ÉÖ´ÐÐÐÐÊý·µ»Ø  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷£º½«²âÊÔ±¨¸æ×Ü¿ÉÖ´ÐÐÐÐÊý·µ»Ø  
 | 
def GetTotalLineCount(sPath):  
 | 
    LogEx(0, "GetCoverage(filePath=%s£©"%sPath)  
 | 
    global g_pyObjDic  
 | 
      
 | 
    if sPath.find("\\") == -1 and (sPath.endswith(".py") or sPath.endswith(".PY")):  
 | 
          
 | 
        fileName = sPath  
 | 
        # Î´´´½¨¸Ãpy¶ÔÏó  
 | 
        if not g_pyObjDic.has_key(fileName):  
 | 
            g_pyObjDic[fileName] = PyTrackObj.GetPyObj(fileName, MD5_KEY, SCRIPT_PATH)    # ´´½¨py¶ÔÏó  
 | 
          
 | 
        return g_pyObjDic[fileName].CalcFuncExecCount()[1]  
 | 
      
 | 
    if not os.path.isdir(sPath):  
 | 
        LogEx(1, sPath + "is not exist!")  
 | 
        return 0  
 | 
      
 | 
    return CalcPathCoverage(sPath)[1]  
 | 
  
 | 
  
 | 
## ·µ»ØÈ«²¿PYÖ´ÐÐÇé¿ö×ܱ¨¸æ  
 | 
#  @param filePath: PYÎļþ·¾¶  
 | 
#  @param MD5Key: MD5ÃÜÔ¿  
 | 
#  @returnÈ«²¿PYÖ´ÐÐÇé¿ö×ܱ¨¸æ  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷£º  
 | 
def GetDirPercent(filePath, MD5Key):  
 | 
      
 | 
    # ²âÊÔ±¨¸æ  
 | 
    testReport = ""  
 | 
    pathCoverageList = []  
 | 
    CRLF = "\r\n"  
 | 
    # ¼ÆËã¸÷Ä£¿é£¬Ö´ÐÐÇé¿ö  
 | 
    CalcPathCoverage(filePath, pathCoverageList)  
 | 
    pathCoverageList.reverse()  
 | 
  
 | 
    # Éú³É±¨¸æÎļþ  
 | 
    for pathCoverage in pathCoverageList:  
 | 
        path = pathCoverage[0].replace(SCRIPT_PATH, "")[1:]  
 | 
        gradeCnt = path.count("\\")  
 | 
          
 | 
        if gradeCnt == 0:  
 | 
            testReport += "Script: %0.2f%%%s"%(pathCoverage[1], CRLF)  
 | 
        else:  
 | 
            if gradeCnt == 1:  
 | 
                testReport += CRLF  
 | 
            testReport +=  "\t"*gradeCnt + "%s: %0.2f%%%s"%(path[path.rfind("\\")+1:], pathCoverage[1], CRLF)  
 | 
      
 | 
          
 | 
    reportMD5 = PyTrackObj.CalcStringMD5(testReport, MD5Key)  
 | 
    testReport += '%s²âÊÔ±¨¸æMD5:[%s]%s'%(CRLF*2, reportMD5, CRLF*2)  
 | 
    testReport += '±£´æÊ±¼ä:[%s-%s-%s %s:%s:%s]'%tuple(['%02d'%time.localtime()[i] for i in range(6)])  
 | 
      
 | 
    return testReport  
 | 
  
 | 
  
 | 
## ·µ»Ø²âÊÔ±¨¸æ  
 | 
#  @param fileName: PYÎļþÃû  
 | 
#  @param funcName: º¯ÊýÃû  
 | 
#  @param trackMode: ×·×Ùģʽ£¬1 Îļþ¡¢2 º¯Êý  
 | 
#  @param showMode: Êä³öģʽ£¬0 ½çÃæ¡¢1 Îļþ  
 | 
#  @param MD5Key: MD5ÃÜÔ¿  
 | 
#  @return Ö´Ðб¨¸æ  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷£º½«ËùÓб»Ö´Ðе½µÄÎļþÄÚÈÝºÏÆðÀ´·µ»Ø  
 | 
def GetTestResport(fileName, funcName, trackMode, outputMode=0, MD5Key=""):  
 | 
    LogEx(0, "GetTestResport(fileName=%s, funcName=%s, trackMode=%d, outputMode=%d)"%(fileName, funcName, trackMode, outputMode))  
 | 
    global g_pyObjDic  
 | 
      
 | 
    if os.path.isdir(fileName):  
 | 
        # ·µ»ØÈ«²¿PYÖ´ÐÐÇé¿ö×ܱ¨¸æ  
 | 
        return GetDirPercent(fileName, MD5Key)  
 | 
              
 | 
    # Î´´´½¨¸Ãpy¶ÔÏó  
 | 
    if not g_pyObjDic.has_key(fileName):  
 | 
        g_pyObjDic[fileName] = PyTrackObj.GetPyObj(fileName, MD5_KEY, SCRIPT_PATH)    # ´´½¨py¶ÔÏó  
 | 
      
 | 
    pyFileObj = g_pyObjDic[fileName]  
 | 
    testReport = pyFileObj.GetTestReport(funcName, trackMode, outputMode)  
 | 
      
 | 
    return testReport  
 | 
  
 | 
  
 | 
## ·µ»ØÔØÈë²âÊÔ±¨¸æ  
 | 
#  @param fileName: ±¨¸æÎļþÃû  
 | 
#  @param MD5Key: MD5ÃÜÔ¿  
 | 
#  @return ·µ»ØÖµ  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷£ºÔØÈë²âÊÔ±¨¸æ  
 | 
def SetTestResport(fileName, MD5Key=""):  
 | 
    LogEx(0, "SetTestResport(fileName=%s)"%(fileName))  
 | 
    global g_pyObjDic  
 | 
      
 | 
    # pyÃû¶ÔÓ¦µÄÎļþ²»´æÔÚ  
 | 
    if not os.path.isfile(fileName):  
 | 
        LogEx(1, "SetTestResport fileName=%s is not exist"%fileName)  
 | 
        return 0  
 | 
  
 | 
    # ¶ÁÈ¡Îļþ  
 | 
    infile = open(fileName,'r')  
 | 
    contentList = infile.readlines()  
 | 
    infile.close()  
 | 
      
 | 
    if len(contentList) == 0:  
 | 
        LogEx(1, "error: fileName=%s  empty report!"%fileName)  
 | 
        return 0  
 | 
      
 | 
    # »ñµÃpy¶ÔÏó  
 | 
    tempPyObj = ReportAnalyzer.ReportAnalyzer(fileName, contentList, MD5Key)  
 | 
      
 | 
    # ÔØÈëʧ°Ü  
 | 
    if tempPyObj == None:  
 | 
        LogEx(1, "SetTestResport fileName=%s Load Error"%fileName)  
 | 
        return 0  
 | 
      
 | 
    pyName = tempPyObj.GetName()  
 | 
#    LogEx(1, "SetTestResport pyName=%s fileName=%s Load OK == %s"%(pyName, fileName, tempPyObj.GetTestReport("", 1, 1)))  
 | 
  
 | 
    # ¸²¸ÇÔÏȵÄPyObj  
 | 
    if not g_pyObjDic.has_key(pyName):  
 | 
        g_pyObjDic[pyName] = PyTrackObj.GetPyObj(pyName, MD5_KEY, SCRIPT_PATH)    # ´´½¨py¶ÔÏó  
 | 
      
 | 
    g_pyObjDic[pyName].AddPyObj(tempPyObj)  
 | 
      
 | 
#    LogEx(1, "SetTestResport pyName=%s fileName=%s Load OK == %s"%(pyName, fileName, g_pyObjDic[pyName].GetTestReport("", 1, 1)))  
 | 
      
 | 
    # ÔØÈë³É¹¦  
 | 
    return 1  
 | 
      
 | 
  
 | 
## Çå²âÊÔ±¨¸æ  
 | 
#  @param ²ÎÊý  
 | 
#  @return ·µ»ØÖµ  
 | 
#  @remarks º¯ÊýÏêϸ˵Ã÷£ºÈ«¾Ö±äÁ¿±»Ö´Ðе½µÄpy×ÖµäÇå¿Õ  
 | 
def Clear():  
 | 
    LogEx(0, "Clear()")  
 | 
    global g_pyObjDic  
 | 
    #Çå¿Õ×Öµä  
 | 
    g_pyObjDic = {}  
 | 
  
 | 
  
 | 
##¸üÐÂÓû§×·×Ùº¯ÊýÁÐ±í  
 | 
#  @param funcName: º¯ÊýÃû  
 | 
#  @param type: ÊÇ·ñ×·×Ù  
 | 
#  @return ·µ»ØÖµ  
 | 
#  @remarks ¸üÐÂÓû§×·×Ùº¯ÊýÁÐ±í  
 | 
def UpDateTrackFuncList(fileName, funcName, type):  
 | 
    LogEx(0, "UpDateTrackFuncList(fileName=%s, funcName=%s, type=%d)"%(fileName, funcName, type))  
 | 
    global g_pyObjDic  
 | 
      
 | 
    # ÊÇ·ñ×·×Ù  
 | 
    isTracking  = bool(type)  
 | 
              
 | 
    # Î´´´½¨¸Ãpy¶ÔÏó  
 | 
    if not g_pyObjDic.has_key(fileName):  
 | 
        g_pyObjDic[fileName] = PyTrackObj.GetPyObj(fileName, MD5_KEY, SCRIPT_PATH)    # ´´½¨py¶ÔÏó  
 | 
          
 | 
    pyObj = g_pyObjDic[fileName]  
 | 
      
 | 
    if isTracking == True:  
 | 
        pyObj.SetTrack(isTracking)  
 | 
      
 | 
    if funcName:  
 | 
        pyObj.FindFuncObj(funcName).SetTrack(isTracking)  
 | 
    else:  
 | 
        pyObj.SetAllFuncTrack(isTracking)  
 | 
  
 | 
  
 | 
## ÖØÖÃ×·×Ùº¯ÊýÁÐ±í  
 | 
#  @param ²ÎÊý  
 | 
#  @return ·µ»ØÖµ  
 | 
#  @remarks ÖØÖÃ×·×Ùº¯ÊýÁÐ±í  
 | 
def ResetTrackFuncList(fileName):  
 | 
    LogEx(0, "ResetTrackFuncList(fileName=%s)"%fileName)  
 | 
    global g_pyObjDic  
 | 
      
 | 
    # Î´´´½¨¸Ãpy¶ÔÏó  
 | 
    if not g_pyObjDic.has_key(fileName):  
 | 
#        LogEx(1, "ResetTrackFuncList: No File=%s"%fileName)  
 | 
        return  
 | 
          
 | 
    pyObj = g_pyObjDic[fileName]  
 | 
    pyObj.SetTrack(False)  
 | 
      
 | 
    # ±éÀúfuncObj  
 | 
    for funcObj in pyObj.GetFuncObjList():  
 | 
        funcObj.SetTrack(False)  
 | 
          
 | 
  
 | 
#-------------------------------------------------------------------------------  
 |