997 lines
23 KiB
C
997 lines
23 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 2000 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
LogWrappers.h
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Helper classes for logging APIs
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Hakki T. Bostanci (hakkib) 06-Apr-2000
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#ifndef LOGWRAPPERS_H
|
||
|
#define LOGWRAPPERS_H
|
||
|
|
||
|
#include <map>
|
||
|
|
||
|
#include "LogWindow.h"
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
|
||
|
#define TLS_NOCONSOLE 0x04000000L
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
|
||
|
#define LOG_LEVELS 0x0000FFFFL // These are used to mask out the
|
||
|
#define LOG_STYLES 0xFFFF0000L // styles or levels from log object.
|
||
|
|
||
|
#define TLS_LOGALL 0x0000FFFFL // Log output. Logs all the time.
|
||
|
#define TLS_LOG 0x00000000L // Log output. Logs all the time.
|
||
|
#define TLS_INFO 0x00002000L // Log information.
|
||
|
#define TLS_ABORT 0x00000001L // Log Abort, then kill process.
|
||
|
#define TLS_SEV1 0x00000002L // Log at Severity 1 level
|
||
|
#define TLS_SEV2 0x00000004L // Log at Severity 2 level
|
||
|
#define TLS_SEV3 0x00000008L // Log at Severity 3 level
|
||
|
#define TLS_WARN 0x00000010L // Log at Warn level
|
||
|
#define TLS_PASS 0x00000020L // Log at Pass level
|
||
|
#define TLS_BLOCK 0x00000400L // Block the variation.
|
||
|
#define TLS_BREAK 0x00000800L // Debugger break;
|
||
|
#define TLS_CALLTREE 0x00000040L // Log call-tree (function tracking).
|
||
|
#define TLS_SYSTEM 0x00000080L // Log System debug.
|
||
|
#define TLS_TESTDEBUG 0x00001000L // Debug level.
|
||
|
#define TLS_TEST 0x00000100L // Log Test information (user).
|
||
|
#define TLS_VARIATION 0x00000200L // Log testcase level.
|
||
|
|
||
|
#define TLS_REFRESH 0x00010000L // Create new file || trunc to zero.
|
||
|
#define TLS_SORT 0x00020000L // Sort file output by instance.
|
||
|
#define TLS_DEBUG 0x00040000L // Output to debug (com) monitor).
|
||
|
#define TLS_MONITOR 0x00080000L // Output to 2nd screen.
|
||
|
#define TLS_PROLOG 0x00200000L // Prolog line information.
|
||
|
#define TLS_WINDOW 0x00400000L // Log to windows.
|
||
|
#define TLS_ACCESSON 0x00800000L // Keep log-file open.
|
||
|
#define TLS_DIFFABLE 0x01000000L // make log file windiff'able (no dates..)
|
||
|
#define TLS_NOHEADER 0x02000000L // suppress headers so it is more diffable
|
||
|
|
||
|
#define TL_LOG TLS_LOG ,_T(__FILE__),(int)__LINE__
|
||
|
#define TL_ABORT TLS_ABORT ,_T(__FILE__),(int)__LINE__
|
||
|
#define TL_SEV1 TLS_SEV1 ,_T(__FILE__),(int)__LINE__
|
||
|
#define TL_SEV2 TLS_SEV2 ,_T(__FILE__),(int)__LINE__
|
||
|
#define TL_SEV3 TLS_SEV3 ,_T(__FILE__),(int)__LINE__
|
||
|
#define TL_WARN TLS_WARN ,_T(__FILE__),(int)__LINE__
|
||
|
#define TL_PASS TLS_PASS ,_T(__FILE__),(int)__LINE__
|
||
|
#define TL_BLOCK TLS_BLOCK ,_T(__FILE__),(int)__LINE__
|
||
|
#define TL_INFO TLS_INFO ,_T(__FILE__),(int)__LINE__
|
||
|
#define TL_BREAK TLS_BREAK ,_T(__FILE__),(int)__LINE__
|
||
|
#define TL_CALLTREE TLS_CALLTREE ,_T(__FILE__),(int)__LINE__
|
||
|
#define TL_SYSTEM TLS_SYSTEM ,_T(__FILE__),(int)__LINE__
|
||
|
#define TL_TESTDEBUG TLS_TESTDEBUG,_T(__FILE__),(int)__LINE__
|
||
|
#define TL_TEST TLS_TEST ,_T(__FILE__),(int)__LINE__
|
||
|
#define TL_VARIATION TLS_VARIATION,_T(__FILE__),(int)__LINE__
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
|
||
|
class CLog
|
||
|
{
|
||
|
protected:
|
||
|
struct CResults
|
||
|
{
|
||
|
UINT nTotal;
|
||
|
UINT nPassed;
|
||
|
UINT nWarned;
|
||
|
UINT nFailedSev3;
|
||
|
UINT nFailedSev2;
|
||
|
UINT nFailedSev1;
|
||
|
UINT nBlocked;
|
||
|
UINT nAborted;
|
||
|
DWORD dwStartTime;
|
||
|
|
||
|
CResults()
|
||
|
{
|
||
|
ZeroMemory(this, sizeof(*this));
|
||
|
dwStartTime = GetTickCount();
|
||
|
}
|
||
|
|
||
|
void Update(DWORD dwLogLevel)
|
||
|
{
|
||
|
if (dwLogLevel & TLS_PASS) ++nPassed;
|
||
|
if (dwLogLevel & TLS_WARN) ++nWarned;
|
||
|
if (dwLogLevel & TLS_SEV3) ++nFailedSev3;
|
||
|
if (dwLogLevel & TLS_SEV2) ++nFailedSev2;
|
||
|
if (dwLogLevel & TLS_SEV1) ++nFailedSev1;
|
||
|
if (dwLogLevel & TLS_BLOCK) ++nBlocked;
|
||
|
if (dwLogLevel & TLS_ABORT) ++nAborted;
|
||
|
}
|
||
|
|
||
|
PCTSTR Report(PTSTR pBuffer, SIZE_T nBufferLen) const
|
||
|
{
|
||
|
DWORD dwUpTime = GetTickCount() - dwStartTime;
|
||
|
|
||
|
_sntprintf(
|
||
|
pBuffer,
|
||
|
nBufferLen,
|
||
|
_T("%d total, ")
|
||
|
_T("%d passed, ")
|
||
|
_T("%d warned, ")
|
||
|
_T("%d failed sev1, ")
|
||
|
_T("%d failed sev2, ")
|
||
|
_T("%d failed sev3, ")
|
||
|
_T("%d blocked, ")
|
||
|
_T("%d aborted tests in ")
|
||
|
_T("%d hours, ")
|
||
|
_T("%d mins, ")
|
||
|
_T("%d secs"),
|
||
|
nTotal,
|
||
|
nPassed,
|
||
|
nWarned,
|
||
|
nFailedSev3,
|
||
|
nFailedSev2,
|
||
|
nFailedSev1,
|
||
|
nBlocked,
|
||
|
nAborted,
|
||
|
dwUpTime / (1000 * 60 * 60),
|
||
|
(dwUpTime / (1000 * 60)) % 60,
|
||
|
(dwUpTime / 1000) % 60
|
||
|
);
|
||
|
|
||
|
return pBuffer;
|
||
|
}
|
||
|
|
||
|
PCTSTR Summary() const
|
||
|
{
|
||
|
if (nAborted)
|
||
|
{
|
||
|
return _T("TIMEOUT");
|
||
|
}
|
||
|
|
||
|
if (nBlocked)
|
||
|
{
|
||
|
return _T("NOCONFIG");
|
||
|
}
|
||
|
|
||
|
if (nFailedSev3 || nFailedSev2 || nFailedSev1)
|
||
|
{
|
||
|
return _T("FAIL");
|
||
|
}
|
||
|
|
||
|
return _T("PASS");
|
||
|
}
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
CLog()
|
||
|
{
|
||
|
m_pLogWindow = 0;
|
||
|
m_bMute = false;
|
||
|
}
|
||
|
|
||
|
virtual ~CLog()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
SetLogWindow(
|
||
|
CLogWindow *pLogWindow
|
||
|
)
|
||
|
{
|
||
|
m_pLogWindow = pLogWindow;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
Mute(bool bMute = true)
|
||
|
{
|
||
|
m_bMute = bMute;
|
||
|
}
|
||
|
|
||
|
PCTSTR
|
||
|
__cdecl
|
||
|
Log(
|
||
|
DWORD dwLogLevel,
|
||
|
PCTSTR pFile,
|
||
|
int nLine,
|
||
|
PCTSTR pFormat,
|
||
|
...
|
||
|
)
|
||
|
{
|
||
|
va_list arglist;
|
||
|
va_start(arglist, pFormat);
|
||
|
|
||
|
return LogV(dwLogLevel, pFile, nLine, pFormat, arglist);
|
||
|
}
|
||
|
|
||
|
PCTSTR
|
||
|
LogV(
|
||
|
DWORD dwLogLevel,
|
||
|
PCTSTR pFile,
|
||
|
int nLine,
|
||
|
PCTSTR pFormat,
|
||
|
va_list arglist
|
||
|
)
|
||
|
{
|
||
|
CCppMem<TCHAR> pszStr(bufvprintf(pFormat, arglist));
|
||
|
|
||
|
PCTSTR pszComment = _T("");
|
||
|
|
||
|
if (!m_bMute)
|
||
|
{
|
||
|
if (dwLogLevel & TLS_TEST)
|
||
|
{
|
||
|
m_TestResults.Update(dwLogLevel);
|
||
|
}
|
||
|
|
||
|
if (dwLogLevel & TLS_VARIATION)
|
||
|
{
|
||
|
if (dwLogLevel & (TLS_WARN | TLS_SEV1 | TLS_SEV2 | TLS_SEV3 | TLS_ABORT))
|
||
|
{
|
||
|
DWORD &rResult = m_ThreadResult[GetCurrentThreadId()];
|
||
|
|
||
|
if (rResult < dwLogLevel)
|
||
|
{
|
||
|
rResult = dwLogLevel;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (dwLogLevel & TLS_NOCONSOLE)
|
||
|
{
|
||
|
dwLogLevel &= ~TLS_NOCONSOLE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (dwLogLevel & TLS_DEBUG)
|
||
|
{
|
||
|
if (pFile)
|
||
|
{
|
||
|
OutputDebugString(pFile);
|
||
|
OutputDebugString(_T(" "));
|
||
|
}
|
||
|
|
||
|
OutputDebugString(pszStr);
|
||
|
OutputDebugString(_T("\n")); //bugbug: talk about inefficiency...
|
||
|
|
||
|
dwLogLevel &= ~TLS_DEBUG;
|
||
|
}
|
||
|
|
||
|
if (m_pLogWindow)
|
||
|
{
|
||
|
TCHAR Buffer[1024];
|
||
|
|
||
|
pszComment = m_pLogWindow->Log(
|
||
|
dwLogLevel,
|
||
|
pFile,
|
||
|
nLine,
|
||
|
pszStr,
|
||
|
m_VarResults.Report(Buffer, COUNTOF(Buffer))
|
||
|
);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_ftprintf(
|
||
|
dwLogLevel & TLS_INFO ? stdout : stderr,
|
||
|
_T("%s\n"),
|
||
|
pszStr
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LogStr(
|
||
|
dwLogLevel,
|
||
|
pFile,
|
||
|
nLine,
|
||
|
pszStr,
|
||
|
pszComment
|
||
|
);
|
||
|
}
|
||
|
|
||
|
return pszComment;
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
VOID
|
||
|
LogStr(
|
||
|
DWORD dwLogLevel,
|
||
|
PCTSTR pFile,
|
||
|
int nLine,
|
||
|
PCTSTR pStr,
|
||
|
PCTSTR pComment
|
||
|
)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
VOID
|
||
|
StartVariation()
|
||
|
{
|
||
|
++m_VarResults.nTotal;
|
||
|
m_ThreadResult[GetCurrentThreadId()] = TLS_PASS;
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
DWORD
|
||
|
EndVariation()
|
||
|
{
|
||
|
DWORD dwResult = m_ThreadResult[GetCurrentThreadId()];
|
||
|
m_VarResults.Update(dwResult);
|
||
|
return dwResult;
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
VOID
|
||
|
InitThread()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
VOID
|
||
|
DoneThread()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
VOID
|
||
|
StartBlock(PCTSTR pBlockName, BOOL bStamp = TRUE)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
virtual
|
||
|
VOID
|
||
|
EndBlock(PCTSTR pBlockName, BOOL bStamp = TRUE)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
CLogWindow *m_pLogWindow;
|
||
|
bool m_bMute;
|
||
|
|
||
|
protected:
|
||
|
CResults m_TestResults;
|
||
|
CResults m_VarResults;
|
||
|
|
||
|
std::map<DWORD, DWORD> m_ThreadResult;
|
||
|
};
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
|
||
|
class CNtLog : public CHandle<HANDLE, CNtLog>, public CLog
|
||
|
{
|
||
|
typedef CHandle<HANDLE, CNtLog> handle_type;
|
||
|
|
||
|
public:
|
||
|
CNtLog()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
CNtLog(
|
||
|
PCTSTR pszLogFile,
|
||
|
DWORD dwLogInfo,
|
||
|
LPSECURITY_ATTRIBUTES lpSecAttrs = 0
|
||
|
) :
|
||
|
handle_type((*m_Dll.CreateLogEx)(
|
||
|
pszLogFile,
|
||
|
dwLogInfo,
|
||
|
lpSecAttrs
|
||
|
))
|
||
|
{
|
||
|
InitThread();
|
||
|
}
|
||
|
|
||
|
void Destroy()
|
||
|
{
|
||
|
(*m_Dll.ReportStats)(*this);
|
||
|
(*m_Dll.RemoveParticipant)(*this);
|
||
|
(*m_Dll.DestroyLog)(*this);
|
||
|
}
|
||
|
|
||
|
bool IsValid()
|
||
|
{
|
||
|
return (HANDLE) *this != INVALID_HANDLE_VALUE;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
InitThread()
|
||
|
{
|
||
|
AddParticipant();
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
DoneThread()
|
||
|
{
|
||
|
RemoveParticipant();
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
AddParticipant(
|
||
|
DWORD dwLevels = 0,
|
||
|
int nMachineID = 0
|
||
|
) const
|
||
|
{
|
||
|
(*m_Dll.AddParticipant)(
|
||
|
*this,
|
||
|
dwLevels,
|
||
|
nMachineID
|
||
|
);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
RemoveParticipant() const
|
||
|
{
|
||
|
(*m_Dll.RemoveParticipant)(*this);
|
||
|
}
|
||
|
|
||
|
static
|
||
|
DWORD
|
||
|
ParseCmdLine(
|
||
|
PCTSTR pszCmdLine
|
||
|
)
|
||
|
{
|
||
|
return (*m_Dll.ParseCmdLine)(pszCmdLine);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
GetLogFileName(
|
||
|
PTSTR pszFileName
|
||
|
) const
|
||
|
{
|
||
|
return (*m_Dll.GetLogFileName)(*this, pszFileName);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
SetLogFileName(
|
||
|
PTSTR pszFileName
|
||
|
) const
|
||
|
{
|
||
|
(*m_Dll.SetLogFileName)(*this, pszFileName);
|
||
|
}
|
||
|
|
||
|
DWORD
|
||
|
GetLogInfo() const
|
||
|
{
|
||
|
return (*m_Dll.GetLogInfo)(*this);
|
||
|
}
|
||
|
|
||
|
DWORD
|
||
|
SetLogInfo(
|
||
|
DWORD dwInfo
|
||
|
) const
|
||
|
{
|
||
|
return (*m_Dll.SetLogInfo)(*this, dwInfo);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
PromptLog(
|
||
|
HWND hWnd = 0
|
||
|
) const
|
||
|
{
|
||
|
(*m_Dll.PromptLog)(hWnd, *this);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
GetTestStat(
|
||
|
DWORD dwLevel
|
||
|
) const
|
||
|
{
|
||
|
return (*m_Dll.GetTestStat)(*this, dwLevel);
|
||
|
}
|
||
|
|
||
|
int
|
||
|
GetVariationStat(
|
||
|
DWORD dwLevel
|
||
|
) const
|
||
|
{
|
||
|
return (*m_Dll.GetVariationStat)(*this, dwLevel);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
ClearTestStats() const
|
||
|
{
|
||
|
(*m_Dll.ClearTestStats)(*this);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
ClearVariationStats() const
|
||
|
{
|
||
|
(*m_Dll.ClearVariationStats)(*this);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
StartVariation()
|
||
|
{
|
||
|
CLog::StartVariation();
|
||
|
(*m_Dll.StartVariation)(*this);
|
||
|
}
|
||
|
|
||
|
DWORD
|
||
|
EndVariation()
|
||
|
{
|
||
|
CLog::EndVariation();
|
||
|
return (*m_Dll.EndVariation)(*this);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
ReportStats() const
|
||
|
{
|
||
|
(*m_Dll.ReportStats)(*this);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
LogStr(
|
||
|
DWORD dwLogLevel,
|
||
|
PCTSTR pFile,
|
||
|
int nLine,
|
||
|
PCTSTR pStr,
|
||
|
PCTSTR pComment
|
||
|
)
|
||
|
{
|
||
|
(*m_Dll.Log)(
|
||
|
*this,
|
||
|
dwLogLevel,
|
||
|
pFile,
|
||
|
nLine,
|
||
|
pComment && *pComment ? _T("%s (%s)") : _T("%s"),
|
||
|
pStr,
|
||
|
pComment
|
||
|
);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
class CNtLogDLL
|
||
|
{
|
||
|
public:
|
||
|
CNtLogDLL()
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
m_NtLog = CLibrary(_T("ntlog.dll"));
|
||
|
|
||
|
CreateLog = CCreateLog (m_NtLog, "tlCreateLog_"_AW);
|
||
|
CreateLogEx = CCreateLogEx (m_NtLog, "tlCreateLogEx_"_AW);
|
||
|
ParseCmdLine = CParseCmdLine (m_NtLog, "tlParseCmdLine_"_AW);
|
||
|
GetLogFileName = CGetLogFileName (m_NtLog, "tlGetLogFileName_"_AW);
|
||
|
SetLogFileName = CSetLogFileName (m_NtLog, "tlSetLogFileName_"_AW);
|
||
|
LogX = CLogX (m_NtLog, "tlLogX_"_AW);
|
||
|
Log = CLog (m_NtLog, "tlLog_"_AW);
|
||
|
DestroyLog = CDestroyLog (m_NtLog, "tlDestroyLog");
|
||
|
AddParticipant = CAddParticipant (m_NtLog, "tlAddParticipant");
|
||
|
RemoveParticipant = CRemoveParticipant (m_NtLog, "tlRemoveParticipant");
|
||
|
GetLogInfo = CGetLogInfo (m_NtLog, "tlGetLogInfo");
|
||
|
SetLogInfo = CSetLogInfo (m_NtLog, "tlSetLogInfo");
|
||
|
PromptLog = CPromptLog (m_NtLog, "tlPromptLog");
|
||
|
GetTestStat = CGetTestStat (m_NtLog, "tlGetTestStat");
|
||
|
GetVariationStat = CGetVariationStat (m_NtLog, "tlGetVariationStat");
|
||
|
ClearTestStats = CClearTestStats (m_NtLog, "tlClearTestStats");
|
||
|
ClearVariationStats = CClearVariationStats(m_NtLog, "tlClearVariationStats");
|
||
|
StartVariation = CStartVariation (m_NtLog, "tlStartVariation");
|
||
|
EndVariation = CEndVariation (m_NtLog, "tlEndVariation");
|
||
|
ReportStats = CReportStats (m_NtLog, "tlReportStats");
|
||
|
}
|
||
|
catch (...)
|
||
|
{
|
||
|
//_tprintf(_T("*** Cannot load NTLOG.DLL, no log file will be generated ***\n"));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
CLibrary m_NtLog;
|
||
|
|
||
|
public:
|
||
|
DECL_CWINAPI(HANDLE, APIENTRY, CreateLog, (LPCTSTR, DWORD));
|
||
|
DECL_CWINAPI(HANDLE, APIENTRY, CreateLogEx, (LPCTSTR, DWORD, LPSECURITY_ATTRIBUTES));
|
||
|
DECL_CWINAPI(DWORD, APIENTRY, ParseCmdLine, (LPCTSTR));
|
||
|
DECL_CWINAPI(int, APIENTRY, GetLogFileName, (HANDLE, LPTSTR));
|
||
|
DECL_CWINAPI(BOOL, APIENTRY, SetLogFileName, (HANDLE, LPCTSTR));
|
||
|
DECL_CWINAPI(BOOL, APIENTRY, LogX, (HANDLE, DWORD, LPCTSTR, int, LPCTSTR));
|
||
|
DECL_CWINAPI(BOOL, __cdecl, Log, (HANDLE, DWORD, LPCTSTR, int, LPCTSTR, ...));
|
||
|
DECL_CWINAPI(BOOL, APIENTRY, DestroyLog, (HANDLE));
|
||
|
DECL_CWINAPI(BOOL, APIENTRY, AddParticipant, (HANDLE, DWORD, int));
|
||
|
DECL_CWINAPI(BOOL, APIENTRY, RemoveParticipant, (HANDLE));
|
||
|
DECL_CWINAPI(DWORD, APIENTRY, GetLogInfo, (HANDLE));
|
||
|
DECL_CWINAPI(DWORD, APIENTRY, SetLogInfo, (HANDLE, DWORD));
|
||
|
DECL_CWINAPI(HANDLE, APIENTRY, PromptLog, (HWND, HANDLE));
|
||
|
DECL_CWINAPI(int, APIENTRY, GetTestStat, (HANDLE, DWORD));
|
||
|
DECL_CWINAPI(int, APIENTRY, GetVariationStat, (HANDLE, DWORD));
|
||
|
DECL_CWINAPI(BOOL, APIENTRY, ClearTestStats, (HANDLE));
|
||
|
DECL_CWINAPI(BOOL, APIENTRY, ClearVariationStats, (HANDLE));
|
||
|
DECL_CWINAPI(BOOL, APIENTRY, StartVariation, (HANDLE));
|
||
|
DECL_CWINAPI(DWORD, APIENTRY, EndVariation, (HANDLE));
|
||
|
DECL_CWINAPI(BOOL, APIENTRY, ReportStats, (HANDLE));
|
||
|
};
|
||
|
|
||
|
private:
|
||
|
static CNtLogDLL m_Dll;
|
||
|
};
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
|
||
|
// Invalid Log handle define
|
||
|
#define INVALID_LOGHANDLE -1
|
||
|
|
||
|
// Log file and debug output flags
|
||
|
#define NO_LOG 0x000000
|
||
|
#define STAT_LOG 0x000001 // Local logging operation
|
||
|
#define SUM_LOG 0x000002
|
||
|
#define ERR_LOG 0x000004
|
||
|
#define DBG_LOG 0x000008
|
||
|
#define SVR_STAT_LOG 0x010000
|
||
|
#define SVR_SUM_LOG 0x020000 // Lormaster Server logging operation
|
||
|
#define SVR_ERR_LOG 0x040000
|
||
|
#define SVR_DBG_LOG 0x080000
|
||
|
#define SVR_SQL_LOG 0x100000 // Perform SQL logging
|
||
|
|
||
|
// LogFile Creation flags
|
||
|
#define LOG_NEW 0x001
|
||
|
#define LOG_APPEND 0x002
|
||
|
#define LOG_NOCREATE 0x004
|
||
|
|
||
|
// Test result type
|
||
|
#define RESULT_INFO 0
|
||
|
#define RESULT_TESTPASS 1
|
||
|
#define RESULT_TESTFAIL 2
|
||
|
#define RESULT_TESTNA 3
|
||
|
#define RESULT_SUMMARY 4
|
||
|
#define RESULT_DEBUG 5
|
||
|
#define RESULT_ERRINFO 6
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
|
||
|
class CLorLog : public CHandle<unsigned long, CLorLog>, public CLog
|
||
|
{
|
||
|
typedef CHandle<unsigned long, CLorLog> handle_type;
|
||
|
|
||
|
public:
|
||
|
CLorLog()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
CLorLog(
|
||
|
const char *pTest_Name,
|
||
|
const char *pLog_Path,
|
||
|
unsigned long dwCreate_Flags,
|
||
|
unsigned long dwLog_Flags,
|
||
|
unsigned long dwDebug_Flags
|
||
|
) :
|
||
|
handle_type((*m_Dll.RegisterTest)(
|
||
|
pTest_Name,
|
||
|
pLog_Path,
|
||
|
dwCreate_Flags,
|
||
|
dwLog_Flags,
|
||
|
dwDebug_Flags
|
||
|
))
|
||
|
{
|
||
|
}
|
||
|
|
||
|
CLorLog(
|
||
|
const char *pTest_Name,
|
||
|
const char *pLog_Path,
|
||
|
DWORD Create_Flags,
|
||
|
DWORD Log_Flags,
|
||
|
DWORD Debug_Flags,
|
||
|
DWORD dwProcessID
|
||
|
) :
|
||
|
handle_type((*m_Dll.RegisterTest_ProcID)(
|
||
|
pTest_Name,
|
||
|
pLog_Path,
|
||
|
Create_Flags,
|
||
|
Log_Flags,
|
||
|
Debug_Flags,
|
||
|
dwProcessID
|
||
|
))
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void Destroy()
|
||
|
{
|
||
|
(*m_Dll.UnRegisterTest)(*this);
|
||
|
}
|
||
|
|
||
|
bool IsValid()
|
||
|
{
|
||
|
return *this != INVALID_LOGHANDLE;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
LogStr(
|
||
|
DWORD dwLogLevel,
|
||
|
PCTSTR pFile,
|
||
|
int nLine,
|
||
|
PCTSTR pStr,
|
||
|
PCTSTR pComment
|
||
|
)
|
||
|
{
|
||
|
DWORD dwType;
|
||
|
|
||
|
if (dwLogLevel & TLS_INFO)
|
||
|
{
|
||
|
dwType = RESULT_INFO;
|
||
|
}
|
||
|
else if (dwLogLevel & (TLS_WARN | TLS_SEV1 | TLS_SEV2 | TLS_SEV3 | TLS_ABORT))
|
||
|
{
|
||
|
dwType = RESULT_ERRINFO;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dwType = RESULT_INFO;
|
||
|
}
|
||
|
|
||
|
USES_CONVERSION;
|
||
|
|
||
|
(*m_Dll.TestResultEx)(
|
||
|
*this,
|
||
|
dwType,
|
||
|
pComment && *pComment ? "%1: %2!d!: %3 (%4)" : "%1: %2!d!: %3",
|
||
|
T2A(pFile),
|
||
|
nLine,
|
||
|
T2A(pStr),
|
||
|
T2A(pComment)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
class CLorLogDLL
|
||
|
{
|
||
|
public:
|
||
|
CLorLogDLL()
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
m_LorLog = CLibrary(_T("loglog32.dll"));
|
||
|
|
||
|
RegisterTest = CRegisterTest (m_LorLog, "RegisterTest");
|
||
|
RegisterTest_ProcID = CRegisterTest_ProcID(m_LorLog, "RegisterTest_ProcID");
|
||
|
TestResult = CTestResult (m_LorLog, "TestResult");
|
||
|
TestResultEx = CTestResultEx (m_LorLog, "TestResultEx");
|
||
|
UnRegisterTest = CUnRegisterTest (m_LorLog, "UnRegisterTest");
|
||
|
QueryTestResults = CQueryTestResults (m_LorLog, "QueryTestResults");
|
||
|
}
|
||
|
catch (...)
|
||
|
{
|
||
|
//_tprintf(_T("*** Cannot load LORLOG32.DLL, no log file will be generated ***\n"));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
CLibrary m_LorLog;
|
||
|
|
||
|
public:
|
||
|
DECL_CWINAPI(unsigned long, WINAPI, RegisterTest, (const char *, const char *, unsigned long, unsigned long, unsigned long));
|
||
|
DECL_CWINAPI(unsigned long, WINAPI, RegisterTest_ProcID, (const char *, const char *, DWORD, DWORD, DWORD, DWORD));
|
||
|
DECL_CWINAPI(int, WINAPI, TestResult, (unsigned long, unsigned long, const char *));
|
||
|
DECL_CWINAPI(int, __cdecl, TestResultEx, (unsigned long, unsigned long, const char *, ...));
|
||
|
DECL_CWINAPI(int, WINAPI, UnRegisterTest, (unsigned long));
|
||
|
DECL_CWINAPI(int, WINAPI, QueryTestResults, (unsigned long, unsigned long *, unsigned long *, unsigned long *));
|
||
|
};
|
||
|
|
||
|
private:
|
||
|
static CLorLogDLL m_Dll;
|
||
|
};
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
|
||
|
#define TIME_TO_STR_FORMAT \
|
||
|
_T("%d/%d/%02d %d:%02d:%02d %cM")
|
||
|
|
||
|
#define TIME_TO_STR_ARGS(st) \
|
||
|
st.wMonth, \
|
||
|
st.wDay, \
|
||
|
st.wYear % 100, \
|
||
|
st.wHour % 12, \
|
||
|
st.wMinute, \
|
||
|
st.wSecond, \
|
||
|
st.wHour / 12 ? _T('P') : _T('A') \
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
|
||
|
class CBvtLog : public CLog
|
||
|
{
|
||
|
public:
|
||
|
struct COwners
|
||
|
{
|
||
|
PCTSTR pTestName;
|
||
|
PCTSTR pContactName;
|
||
|
PCTSTR pMgrName;
|
||
|
PCTSTR pDevPrimeName;
|
||
|
PCTSTR pDevAltName;
|
||
|
PCTSTR pTestPrimeName;
|
||
|
PCTSTR pTestAltName;
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
CBvtLog()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
CBvtLog(
|
||
|
COwners *pOwners,
|
||
|
PCTSTR filename,
|
||
|
PCTSTR mode = _T("at"),
|
||
|
int shflag = _SH_DENYWR
|
||
|
) :
|
||
|
m_nIntent(0),
|
||
|
m_nBlock(0),
|
||
|
m_pOwners(pOwners),
|
||
|
m_LogFile(filename, mode, shflag)
|
||
|
{
|
||
|
setvbuf(m_LogFile, 0, _IONBF, 0);
|
||
|
|
||
|
GetLocalTime(&m_StartTime);
|
||
|
|
||
|
StartBlock(_T("TESTRESULT"), FALSE);
|
||
|
}
|
||
|
|
||
|
~CBvtLog()
|
||
|
{
|
||
|
GetLocalTime(&m_EndTime);
|
||
|
|
||
|
ReportStats();
|
||
|
|
||
|
EndBlock(_T("TESTRESULT"), FALSE);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
ReportStats() const
|
||
|
{
|
||
|
_ftprintf(
|
||
|
m_LogFile,
|
||
|
_T("\n")
|
||
|
_T("%*sTEST: %s\n")
|
||
|
_T("%*sRESULT: %s\n")
|
||
|
_T("%*sBUILD: %d\n")
|
||
|
_T("%*sMACHINE: %s\n")
|
||
|
_T("%*sCONTACT: %s\n")
|
||
|
_T("%*sMGR CONTACT: %s\n")
|
||
|
_T("%*sDEV PRIME: %s\n")
|
||
|
_T("%*sDEV ALT: %s\n")
|
||
|
_T("%*sTEST PRIME: %s\n")
|
||
|
_T("%*sTEST ALT: %s\n")
|
||
|
_T("%*sSTART TIME: ") TIME_TO_STR_FORMAT _T("\n")
|
||
|
_T("%*sEND TIME: ") TIME_TO_STR_FORMAT _T("\n")
|
||
|
_T("\n"),
|
||
|
m_nIntent, _T(""), m_pOwners->pTestName,
|
||
|
m_nIntent, _T(""), m_VarResults.Summary(), //bugbug
|
||
|
m_nIntent, _T(""), COSVersionInfo().dwBuildNumber,
|
||
|
m_nIntent, _T(""), (PCTSTR) CComputerName(TRUE),
|
||
|
m_nIntent, _T(""), m_pOwners->pContactName,
|
||
|
m_nIntent, _T(""), m_pOwners->pMgrName,
|
||
|
m_nIntent, _T(""), m_pOwners->pDevPrimeName,
|
||
|
m_nIntent, _T(""), m_pOwners->pDevAltName,
|
||
|
m_nIntent, _T(""), m_pOwners->pTestPrimeName,
|
||
|
m_nIntent, _T(""), m_pOwners->pTestAltName,
|
||
|
m_nIntent, _T(""), TIME_TO_STR_ARGS(m_StartTime),
|
||
|
m_nIntent, _T(""), TIME_TO_STR_ARGS(m_EndTime)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
LogStr(
|
||
|
DWORD dwLogLevel,
|
||
|
PCTSTR pFile,
|
||
|
int nLine,
|
||
|
PCTSTR pStr,
|
||
|
PCTSTR pComment
|
||
|
)
|
||
|
{
|
||
|
PCTSTR pszText;
|
||
|
int iImage;
|
||
|
|
||
|
CLogWindow::FindNtLogLevel(dwLogLevel, &pszText, &iImage);
|
||
|
|
||
|
_ftprintf(
|
||
|
m_LogFile,
|
||
|
pComment && *pComment ? _T("%*s%s: %s (%s)\n") : _T("%*s%s: %s\n"),
|
||
|
m_nIntent, _T(""),
|
||
|
pszText,
|
||
|
pStr,
|
||
|
pComment
|
||
|
);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
StartBlock(PCTSTR pBlockName, BOOL bStamp /*= TRUE*/)
|
||
|
{
|
||
|
SYSTEMTIME st;
|
||
|
GetLocalTime(&st);
|
||
|
|
||
|
_ftprintf(
|
||
|
m_LogFile,
|
||
|
bStamp ? _T("%*s[%s %d - ") TIME_TO_STR_FORMAT _T("]\n") : _T("%*s[%s]\n"),
|
||
|
m_nIntent, _T(""), pBlockName,
|
||
|
InterlockedIncrement(&m_nBlock),
|
||
|
TIME_TO_STR_ARGS(st)
|
||
|
);
|
||
|
|
||
|
m_nIntent += 4;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
EndBlock(PCTSTR pBlockName, BOOL bStamp /*= TRUE*/)
|
||
|
{
|
||
|
m_nIntent -= 4;
|
||
|
|
||
|
SYSTEMTIME st;
|
||
|
GetLocalTime(&st);
|
||
|
|
||
|
_ftprintf(
|
||
|
m_LogFile,
|
||
|
bStamp ? _T("%*s[/%s - ") TIME_TO_STR_FORMAT _T("]\n\n") : _T("%*s[/%s]\n\n"),
|
||
|
m_nIntent, _T(""), pBlockName,
|
||
|
TIME_TO_STR_ARGS(st)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
public:
|
||
|
COwners *m_pOwners;
|
||
|
|
||
|
CCFile m_LogFile;
|
||
|
|
||
|
SYSTEMTIME m_StartTime;
|
||
|
SYSTEMTIME m_EndTime;
|
||
|
|
||
|
int m_nIntent; //bugbug
|
||
|
|
||
|
LONG m_nBlock;
|
||
|
};
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
|
||
|
extern CCppMem<CLog> g_pLog;
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
//
|
||
|
//
|
||
|
|
||
|
template <DWORD dwLogLevel>
|
||
|
struct CLogHelper
|
||
|
{
|
||
|
PCTSTR
|
||
|
__cdecl
|
||
|
operator ()(
|
||
|
PCTSTR pFormat,
|
||
|
...
|
||
|
)
|
||
|
{
|
||
|
va_list arglist;
|
||
|
va_start(arglist, pFormat);
|
||
|
|
||
|
return g_pLog->LogV(dwLogLevel, _T(""), 0, pFormat, arglist);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#endif LOGWRAPPERS_H
|