/*++ Copyright (c) Microsoft. All rights reserved. Module Name: lxtlog.h Abstract: This file contains lx test logging routines. --*/ #ifndef _LXT_LOG #define _LXT_LOG #include #include #include #include typedef enum _LxtLogType { LxtLogTypeFile = 0x1, LxtLogTypePrintf = 0x2, LxtLogTypeStress = 0x4, LxtLogTypeMax } LxtLogType, *PLxtLogType; typedef enum _LxtLogLevel { LxtLogLevelInfo = 0, LxtLogLevelError, LxtLogLevelResourceError, LxtLogLevelPass, LxtLogLevelStart, LxtLogLevelMax } LxtLogLevel, *PLxtLogLevel; #define LXT_LOG_TYPE_DEFAULT_MASK (LxtLogTypeFile | LxtLogTypePrintf) void LxtLog(LxtLogLevel LogLevel, const char* Message, ...); int LxtLogInitialize(const char* TestName, LxtLogType LogTypeMask, bool LogAppend); void LxtLogUninitialize(void); #define LXT_RESULT_SUCCESS (0) #define LXT_RESULT_FAILURE (-1) #define LXT_SUCCESS(Result) ((Result) != LXT_RESULT_FAILURE) #define LxtLogStart(str, ...) \ { \ LxtLog(LxtLogLevelStart, "START: %s:%u: " str "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ } #define LxtLogInfo(str, ...) \ { \ LxtLog(LxtLogLevelInfo, "INFO: %s:%u: " str "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ } #define LxtLogResourceError(str, ...) \ { \ LxtLog(LxtLogLevelResourceError, "RESOURCE_ERROR: %s:%u: " str "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ } #define LxtLogError(str, ...) \ { \ LxtLog(LxtLogLevelError, "ERROR: %s:%u: " str "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ } #define LxtLogPassed(str, ...) \ { \ LxtLog(LxtLogLevelPass, "PASS: %s:%u: " str "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ } #define LxtCheckErrno(fn) \ { \ Result = (fn); \ if (LXT_SUCCESS(Result) == 0) \ { \ LxtLogError("%s failed: %d (%s)", #fn, errno, strerror(errno)); \ goto ErrorExit; \ } \ } #define LxtCheckMapErrno(fn) \ { \ MapResult = (fn); \ Result = LXT_RESULT_SUCCESS; \ if (MapResult == MAP_FAILED) \ { \ Result = LXT_RESULT_FAILURE; \ LxtLogError("%s failed: %s", #fn, strerror(errno)); \ goto ErrorExit; \ } \ } #define LxtCheckMapErrnoFailure(_Fn, _ExpectedErrno) \ { \ MapResult = (_Fn); \ Result = LXT_RESULT_SUCCESS; \ if (MapResult != MAP_FAILED) \ { \ Result = LXT_RESULT_FAILURE; \ LxtLogError("%s succeeded, expected errno %d", #_Fn, (_ExpectedErrno)); \ goto ErrorExit; \ } \ \ if (errno != (_ExpectedErrno)) \ { \ LxtLogError("%s unexpected failure status: %d != %d (%s)", #_Fn, _ExpectedErrno, errno, strerror(errno)); \ \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ } #define LxtCheckNullErrno(_Fn) \ { \ PointerResult = (_Fn); \ Result = LXT_RESULT_SUCCESS; \ if (PointerResult == NULL) \ { \ Result = LXT_RESULT_FAILURE; \ LxtLogError("%s failed: %s", #_Fn, strerror(errno)); \ goto ErrorExit; \ } \ } #define LxtCheckNullErrnoFailure(_Fn, _ExpectedErrno) \ { \ PointerResult = (_Fn); \ Result = LXT_RESULT_SUCCESS; \ if (PointerResult != NULL) \ { \ LxtLogError("%s succeeded, expected errno %d", #_Fn, (_ExpectedErrno)); \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ \ if (errno != (_ExpectedErrno)) \ { \ LxtLogError("%s unexpected failure status: %d != %d (%s)", #_Fn, _ExpectedErrno, errno, strerror(errno)); \ \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ } // // The following macro is for functions where 0 is the only valid success value // (they don't return a pid or fd or anything), and where errno is set if an // error occurs. // #define LxtCheckErrnoZeroSuccess(_Fn) \ { \ Result = (_Fn); \ if (Result != LXT_RESULT_SUCCESS) \ { \ if (LXT_SUCCESS(Result) != 0) \ { \ LxtLogError("%s succeeded with %d, expected 0.", #_Fn, Result); \ } \ else \ { \ LxtLogError("%s failed: %d, errno %d (%s)", #_Fn, Result, errno, strerror(errno)); \ } \ \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ } #define LxtCheckErrnoFailure(_Fn, _ExpectedErrno) \ { \ Result = (_Fn); \ if ((LXT_SUCCESS(Result) != 0)) \ { \ LxtLogError("%s succeeded with %d, expected errno %d", #_Fn, Result, _ExpectedErrno); \ \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ \ if ((_ExpectedErrno) != errno) \ { \ LxtLogError("%s unexpected failure status: %d, %d != %d (%s)", #_Fn, Result, _ExpectedErrno, errno, strerror(errno)); \ \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ \ Result = LXT_RESULT_SUCCESS; \ } #define LxtCheckEqual(_Val1, _Val2, _Format) \ { \ if ((_Val1) != (_Val2)) \ { \ LxtLogError("{:%s (" _Format ") != %s (" _Format "):}", #_Val1, (_Val1), #_Val2, (_Val2)); \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ \ Result = LXT_RESULT_SUCCESS; \ } #define LxtCheckGreaterOrEqual(_Val1, _Val2, _Format) \ { \ if ((_Val1) < (_Val2)) \ { \ LxtLogError("{:%s (" _Format ") < %s (" _Format "):}", #_Val1, (_Val1), #_Val2, (_Val2)); \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ \ Result = LXT_RESULT_SUCCESS; \ } #define LxtCheckNotEqual(_Val1, _Val2, _Format) \ { \ if ((_Val1) == (_Val2)) \ { \ LxtLogError("{:%s (" _Format ") == %s (" _Format "):}", #_Val1, (_Val1), #_Val2, (_Val2)); \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ \ Result = LXT_RESULT_SUCCESS; \ } #define LxtCheckStringEqual(_Val1, _Val2) \ { \ if ((((_Val1) == NULL) && ((_Val2) != NULL)) || (((_Val1) != NULL) && ((_Val2) == NULL)) || \ (((_Val1) != (_Val2)) && (strcmp((_Val1), (_Val2)) != 0))) \ { \ \ LxtLogError("%s (\"%s\") != %s (\"%s\")", #_Val1, (_Val1), #_Val2, (_Val2)); \ \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ \ Result = LXT_RESULT_SUCCESS; \ } #define LxtCheckStringNotEqual(_Val1, _Val2) \ { \ if (strcmp((_Val1), (_Val2)) == 0) \ { \ LxtLogError("%s (\"%s\") == %s (\"%s\")", #_Val1, (_Val1), #_Val2, (_Val2)); \ \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ \ Result = LXT_RESULT_SUCCESS; \ } #define LxtCheckGreater(_Val1, _Val2, _Format) \ { \ if ((_Val1) <= (_Val2)) \ { \ LxtLogError("{:%s (" _Format ") <= %s (" _Format "):}", #_Val1, (_Val1), #_Val2, (_Val2)); \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ \ Result = LXT_RESULT_SUCCESS; \ } #define LxtCheckMemoryEqual(_Ptr1, _Ptr2, _Size) \ { \ Result = LxtCompareMemory((_Ptr1), (_Ptr2), (_Size), #_Ptr1, #_Ptr2); \ if (Result < 0) \ { \ LxtLogError("Memory contents were not equal"); \ goto ErrorExit; \ } \ } #define LxtCheckTrue(_Val) \ { \ if ((_Val) == FALSE) \ { \ LxtLogError("The expression (" #_Val ") does not equal true"); \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ \ Result = LXT_RESULT_SUCCESS; \ } #define LxtCheckResult(fn) \ { \ Result = (fn); \ if (LXT_SUCCESS(Result) == 0) \ { \ LxtLogError("%s failed", #fn); \ goto ErrorExit; \ } \ } // // Macro for functions that return a positive error value on failure, like // pthread functions. // #define LxtCheckResultError(_Fn) \ { \ Result = (_Fn); \ if (Result != 0) \ { \ LxtLogError("%s failed: %d (%s)", #_Fn, Result, strerror(Result)); \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ } #define LxtCheckResultErrorFailure(_Fn, _ExpectedErrno) \ { \ Result = (_Fn); \ if (Result == 0) \ { \ LxtLogError("%s succeeded, expected errno %d", #_Fn, _ExpectedErrno); \ \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ \ if ((_ExpectedErrno) != Result) \ { \ LxtLogError("%s unexpected failure status: %d != %d (%s)", #_Fn, (_ExpectedErrno), Result, strerror(Result)); \ \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ \ Result = LXT_RESULT_SUCCESS; \ } #endif // _LXT_LOG