| # -*- 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)  | 
|           | 
|   | 
| #-------------------------------------------------------------------------------  |