mirror of https://github.com/microsoft/WSL
348 lines
9.4 KiB
C
348 lines
9.4 KiB
C
/*++
|
|
|
|
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 <unistd.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <stdbool.h>
|
|
|
|
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
|