/*
**==============================================================================
**
** Open Management Infrastructure (OMI)
**
** Copyright (c) Microsoft Corporation
**
** Licensed under the Apache License, Version 2.0 (the "License"); you may not
** use this file except in compliance with the License. You may obtain a copy
** of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
** MERCHANTABLITY OR NON-INFRINGEMENT.
**
** See the Apache 2 License for the specific language governing permissions
** and limitations under the License.
**
**==============================================================================
*/
#include <vector>
#include <algorithm>
#include <ut/ut.h>
#include <base/base.h>
#include <base/buf.h>
#include <base/batch.h>
#include <base/strings.h>
#include <base/paths.h>
#include <base/conf.h>
#include <base/dir.h>
#include <base/log.h>
#include <base/io.h>
#include <base/strarr.h>
#include <base/getopt.h>
#include <base/hashtable.h>
#include "MSFT_AllTypes.h"
#include "MSFT_Process.h"
using namespace std;
using namespace mi;
//#define ENABLE_PRINT
#if defined(_MSC_VER)
/* warning C6309: Argument '3' is null: this does not adhere to function specification of 'MI_Instance_AddElement' */
# pragma warning(disable : 6309)
#endif
extern "C"
{
extern MI_SchemaDecl test_repos_classDecl;
}
static FILE* outStream = NULL;
static string prefix;
static void setUp()
{
#if defined(ENABLE_PRINT)
outStream = stdout;
#else
outStream = Fopen(NULL_FILE, "w");
#endif
prefix = GetPath(ID_PREFIX);
}
static void cleanup()
{
#if defined(ENABLE_PRINT)
outStream = NULL;
#else
fclose(outStream);
outStream = NULL;
#endif
}
static void MemTest(const char* data, char ch, size_t size)
{
size_t i;
for (i = 0; i < size; i++)
{
if (data[i] != ch)
UT_ASSERT_FAILED_MSG("Memcheck failed");
}
}
static void TestAllocator1()
{
Batch a;
char data[256];
// make this member static, since pprefast does not like stack usage more
// than 16K
static char* blocks[4096];
const size_t N = sizeof(blocks) / sizeof(blocks[0]);
size_t i;
Batch_InitFromBuffer(&a, data, sizeof(data), BATCH_MAX_PAGES);
for (i = 1; i < N; i++)
{
char* p = (char*)Batch_Get(&a, i);
UT_ASSERT(p != NULL);
memset(p, i % 256, i);
blocks[i] = p;
}
// First chunk is 1 bytes as offset 0:
UT_ASSERT(data[0] == 1);
// Second chunk is 2 bytes as offset 8:
UT_ASSERT(data[8+0] == 2);
UT_ASSERT(data[8+1] == 2);
// Third chunk is 3 bytes as offset 16:
UT_ASSERT(data[16+0] == 3);
UT_ASSERT(data[16+1] == 3);
// Fourth chunk is 4 bytes as offset 24:
UT_ASSERT(data[24+0] == 4);
UT_ASSERT(data[24+1] == 4);
// Fifth chunk is 5 bytes as offset 32:
UT_ASSERT(data[32+0] == 5);
UT_ASSERT(data[32+1] == 5);
for (i = 1; i < N; i++)
{
char* p = blocks[i];
UT_ASSERT(p != NULL);
MemTest(p, i % 256, i);
}
Batch_Destroy(&a);
}
static void TestAllocator2()
{
Batch batch = BATCH_INITIALIZER;
char* blocks[512];
const size_t N = sizeof(blocks) / sizeof(blocks[0]);
size_t i;
for (i = 1; i < N; i++)
{
char* p = (char*)Batch_Get(&batch, i);
UT_ASSERT(p != NULL);
memset(p, i % 256, i);
blocks[i] = p;
}
for (i = 1; i < N; i++)
{
char* p = blocks[i];
UT_ASSERT(p != NULL);
MemTest(p, i % 256, i);
}
Batch_Destroy(&batch);
memset(&batch, 0, sizeof(batch));
}
static void TestAllocator3()
{
Batch* batch;
char* blocks[512];
const size_t N = sizeof(blocks) / sizeof(blocks[0]);
size_t i;
batch = Batch_New(8);
UT_ASSERT(batch != NULL);
for (i = 1; i < N; i++)
{
char* p = (char*)Batch_Get(batch, i);
UT_ASSERT(p != NULL);
memset(p, i % 256, i);
blocks[i] = p;
}
for (i = 1; i < N; i++)
{
char* p = blocks[i];
UT_ASSERT(p != NULL);
MemTest(p, i % 256, i);
}
Batch_Delete(batch);
}
static void TestGetName()
{
UT_ASSERT(strcmp(Type_NameOf(MI_BOOLEAN), "BOOLEAN") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_UINT8), "UINT8") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_SINT8), "SINT8") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_UINT16), "UINT16") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_SINT16), "SINT16") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_UINT32), "UINT32") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_SINT32), "SINT32") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_UINT64), "UINT64") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_SINT64), "SINT64") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_REAL32), "REAL32") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_REAL64), "REAL64") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_CHAR16), "CHAR16") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_DATETIME), "DATETIME") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_STRING), "STRING") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_REFERENCE), "REFERENCE") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_INSTANCE), "INSTANCE") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_BOOLEANA), "BOOLEANA") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_UINT8A), "UINT8A") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_SINT8A), "SINT8A") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_UINT16A), "UINT16A") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_SINT16A), "SINT16A") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_UINT32A), "UINT32A") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_SINT32A), "SINT32A") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_UINT64A), "UINT64A") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_SINT64A), "SINT64A") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_REAL32A), "REAL32A") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_REAL64A), "REAL64A") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_CHAR16A), "CHAR16A") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_DATETIMEA), "DATETIMEA") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_STRINGA), "STRINGA") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_REFERENCEA), "REFERENCEA") == 0);
UT_ASSERT(strcmp(Type_NameOf(MI_INSTANCEA), "INSTANCEA") == 0);
}
static void TestGetSize()
{
UT_ASSERT(Type_SizeOf(MI_BOOLEAN) == sizeof(MI_Boolean));
UT_ASSERT(Type_SizeOf(MI_UINT8) == sizeof(MI_Uint8));
UT_ASSERT(Type_SizeOf(MI_SINT8) == sizeof(MI_Sint8));
UT_ASSERT(Type_SizeOf(MI_UINT16) == sizeof(MI_Uint16));
UT_ASSERT(Type_SizeOf(MI_SINT16) == sizeof(MI_Sint16));
UT_ASSERT(Type_SizeOf(MI_UINT32) == sizeof(MI_Uint32));
UT_ASSERT(Type_SizeOf(MI_SINT32) == sizeof(MI_Sint32));
UT_ASSERT(Type_SizeOf(MI_UINT64) == sizeof(MI_Uint64));
UT_ASSERT(Type_SizeOf(MI_SINT64) == sizeof(MI_Sint64));
UT_ASSERT(Type_SizeOf(MI_REAL32) == sizeof(MI_Real32));
UT_ASSERT(Type_SizeOf(MI_REAL64) == sizeof(MI_Real64));
UT_ASSERT(Type_SizeOf(MI_CHAR16) == sizeof(MI_Char16));
UT_ASSERT(Type_SizeOf(MI_DATETIME) == sizeof(MI_Datetime));
UT_ASSERT(Type_SizeOf(MI_STRING) == sizeof(MI_String));
UT_ASSERT(Type_SizeOf(MI_REFERENCE) == sizeof(MI_Instance*));
UT_ASSERT(Type_SizeOf(MI_INSTANCE) == sizeof(MI_Instance*));
UT_ASSERT(Type_SizeOf(MI_BOOLEANA) == sizeof(MI_BooleanA));
UT_ASSERT(Type_SizeOf(MI_UINT8A) == sizeof(MI_Uint8A));
UT_ASSERT(Type_SizeOf(MI_SINT8A) == sizeof(MI_Sint8A));
UT_ASSERT(Type_SizeOf(MI_UINT16A) == sizeof(MI_Uint16A));
UT_ASSERT(Type_SizeOf(MI_SINT16A) == sizeof(MI_Sint16A));
UT_ASSERT(Type_SizeOf(MI_UINT32A) == sizeof(MI_Uint32A));
UT_ASSERT(Type_SizeOf(MI_SINT32A) == sizeof(MI_Sint32A));
UT_ASSERT(Type_SizeOf(MI_UINT64A) == sizeof(MI_Uint64A));
UT_ASSERT(Type_SizeOf(MI_SINT64A) == sizeof(MI_Sint64A));
UT_ASSERT(Type_SizeOf(MI_REAL32A) == sizeof(MI_Real32A));
UT_ASSERT(Type_SizeOf(MI_REAL64A) == sizeof(MI_Real64A));
UT_ASSERT(Type_SizeOf(MI_CHAR16A) == sizeof(MI_Char16A));
UT_ASSERT(Type_SizeOf(MI_DATETIMEA) == sizeof(MI_DatetimeA));
UT_ASSERT(Type_SizeOf(MI_STRINGA) == sizeof(MI_StringA));
UT_ASSERT(Type_SizeOf(MI_REFERENCEA) == sizeof(MI_ReferenceA));
UT_ASSERT(Type_SizeOf(MI_INSTANCEA) == sizeof(MI_InstanceA));
}
static MI_Instance* NewPerson(
MI_Uint32 key,
const MI_Char* first,
const MI_Char* last,
Batch* batch)
{
MI_Value value;
MI_Instance* inst;
MI_Result r;
const MI_ClassDecl* cd;
/* Find class decl for MSFT_Person */
cd = SchemaDecl_FindClassDecl(&test_repos_classDecl, T("MSFT_Person"));
UT_ASSERT(cd != NULL);
/* Create instance of MSFT_Person */
r = Instance_New(&inst, cd, batch);
UT_ASSERT(r == MI_RESULT_OK);
/* CIM_Person.Key */
value.uint32 = key;
r = MI_Instance_SetElement(inst, MI_T("Key"), &value, MI_UINT32, 0);
UT_ASSERT(r == MI_RESULT_OK);
/* CIM_Person.First */
value.string = (MI_Char*)first;
r = MI_Instance_SetElement(inst, MI_T("First"), &value, MI_STRING, 0);
UT_ASSERT(r == MI_RESULT_OK);
/* CIM_Person.Last */
value.string = (MI_Char*)last;
r = MI_Instance_SetElement(inst, MI_T("Last"), &value, MI_STRING, 0);
UT_ASSERT(r == MI_RESULT_OK);
return inst;
}
static void TestStringArray1(void)
{
Batch batch = BATCH_INITIALIZER;
StringArray sa;
MI_Result r;
static const MI_Char* data[] =
{
MI_T("Monday"),
MI_T("Tuesday"),
MI_T("Wednesday"),
MI_T("Thursday"),
MI_T("Friday"),
MI_T("Saturday"),
MI_T("Sunday"),
};
static const size_t size = MI_COUNT(data);
size_t i;
StringArray_Init(&sa, size, &batch);
for (i = 0; i < size; i++)
{
r = StringArray_Add(&sa, data[i]);
UT_ASSERT(r == MI_RESULT_OK);
}
UT_ASSERT(sa.size == size);
r = StringArray_Add(&sa, MI_T("Never"));
UT_ASSERT(r == MI_RESULT_FAILED);
#if 0
StringArray_Print(&sa, stdout);
#endif
for (i = 0; i < size; i++)
{
UT_ASSERT(Zcasecmp(sa.data[i], data[i]) == 0);
}
Batch_Destroy(&batch);
}
static void TestStringArray2(void)
{
Batch batch = BATCH_INITIALIZER;
StringArray sa;
static const size_t N = 12345;
size_t i;
StringArray_Init(&sa, N, &batch);
for (i = 0; i < N; i++)
{
MI_Result r;
MI_Char buf[32];
Szprintf(buf, MI_COUNT(buf), MI_T("%d"), (int)i);
r = StringArray_Add(&sa, buf);
UT_ASSERT(r == MI_RESULT_OK);
}
UT_ASSERT(sa.size == N);
for (i = 0; i < N; i++)
{
MI_Char buf[32];
Szprintf(buf, MI_COUNT(buf), MI_T("%d"), (int)i);
Zcasecmp(sa.data[i], buf);
}
Batch_Destroy(&batch);
}
void TestMessages()
{
MI_Result r;
MI_Instance* instanceName;
GetInstanceReq* req;
PostInstanceMsg* rsp;
MI_Value value;
MI_Uint64 msgID;
StringArray propertySet;
const MI_ClassDecl* cd;
Batch* b = NULL;
/* Set the msgID */
msgID = 12345;
/* Build GetInstance message */
req = GetInstanceReq_New(msgID, BinaryProtocolFlag);
UT_ASSERT(req);
/* Use the message's batch for all allocations */
b = req->base.batch;
UT_ASSERT(b);
/* Create an instance name */
{
cd = SchemaDecl_FindClassDecl(&test_repos_classDecl,
T("MSFT_Person"));
UT_ASSERT(cd != NULL);
r = Instance_New(&instanceName, cd, b);
UT_ASSERT(r == MI_RESULT_OK);
value.string = (MI_Char*)MI_T("CIM_Person");
MI_Instance_SetElement(instanceName, MI_T("__CLASS"), &value, MI_STRING, 0);
value.uint32 = 1234;
MI_Instance_SetElement(instanceName, MI_T("Key"), &value, MI_UINT32, 0);
}
/* Build a property list */
{
StringArray_Init(&propertySet, 2, b);
r = StringArray_Add(&propertySet, MI_T("First"));
UT_ASSERT(r == MI_RESULT_OK);
r = StringArray_Add(&propertySet, MI_T("Last"));
UT_ASSERT(r == MI_RESULT_OK);
}
req->instanceName = instanceName;
req->propertySet = &propertySet;
GetInstanceReq_Print(req, outStream);
/* Create response */
rsp = PostInstanceMsg_New(msgID);
UT_ASSERT(rsp);
rsp->instance = NewPerson(1, MI_T("George"), MI_T("Washington"), b);
UT_ASSERT(rsp);
PostInstanceMsg_Print(rsp, outStream);
/* Destroy instances */
MI_Instance_Delete(instanceName);
MI_Instance_Delete(rsp->instance);
/* Destroy the messages */
GetInstanceReq_Release(req);
PostInstanceMsg_Release(rsp);
}
void TestMessages2()
{
EnumerateInstancesReq* req;
MI_Uint64 msgID;
StringArray propertySet;
Batch* b = NULL;
/* Set the msgID */
msgID = 45678;
/* EnumerateInstancesReq */
req = EnumerateInstancesReq_New(msgID, BinaryProtocolFlag);
UT_ASSERT(req);
/* Use the messages's batch for all allocations */
b = req->base.batch;
/* EnumerateInstancesReq.className */
req->className = (MI_Char*)Batch_Zdup(b, MI_T("CIM_Person"));
/* EnumerateInstancesReq.deepInheritance */
req->deepInheritance = MI_TRUE;
/* EnumerateInstancesReq.propertySet */
{
MI_Result r;
StringArray_Init(&propertySet, 3, b);
r = StringArray_Add(&propertySet, MI_T("Key"));
UT_ASSERT(r == MI_RESULT_OK);
r = StringArray_Add(&propertySet, MI_T("First"));
UT_ASSERT(r == MI_RESULT_OK);
r = StringArray_Add(&propertySet, MI_T("Last"));
UT_ASSERT(r == MI_RESULT_OK);
req->propertySet = &propertySet;
}
EnumerateInstancesReq_Print(req, outStream);
/* Destroy the message */
EnumerateInstancesReq_Release(req);
}
static void TestStrings()
{
char buf[1024];
size_t n;
memset(buf, 0xFF, sizeof(buf));
n = Strlcpy(buf, "abc", 8);
UT_ASSERT(strcmp(buf, "abc") == 0);
UT_ASSERT(n == 3);
memset(buf, 0xFF, sizeof(buf));
n = Strlcpy(buf, "abc", 3);
UT_ASSERT(strcmp(buf, "ab") == 0);
UT_ASSERT(n == 3);
memset(buf, 0xFF, sizeof(buf));
n = Strlcpy(buf, "", 1);
UT_ASSERT(strcmp(buf, "") == 0);
UT_ASSERT(n == 0);
memset(buf, 0xFF, sizeof(buf));
n = Strlcpy(buf, "a", 2);
UT_ASSERT(strcmp(buf, "a") == 0);
UT_ASSERT(n == 1);
memset(buf, 0xFF, sizeof(buf));
n = Strlcpy(buf, "aaa", 8);
n = Strlcat(buf, "bbb", 8);
n = Strlcat(buf, "ccc", 8);
UT_ASSERT(strcmp(buf, "aaabbbc") == 0);
UT_ASSERT(n == 3);
n = Strlcat(buf, "ccddd", 10);
UT_ASSERT(strcmp(buf, "aaabbbccc") == 0);
UT_ASSERT(n == 5);
}
typedef struct _Elem
{
struct _Elem* next;
struct _Elem* prev;
int num;
}
Elem;
static void TestList()
{
Elem* head = NULL;
Elem* tail = NULL;
Elem* p;
/* Insert some elements */
{
Elem* e = (Elem*)malloc(sizeof(Elem));
UT_ASSERT(e != NULL);
e->num = 1;
List_Prepend(
(ListElem**)&head, (ListElem**)&tail, (ListElem*)e);
}
{
Elem* e = (Elem*)malloc(sizeof(Elem));
UT_ASSERT(e != NULL);
e->num = 2;
List_Prepend(
(ListElem**)&head, (ListElem**)&tail, (ListElem*)e);
}
{
Elem* e = (Elem*)malloc(sizeof(Elem));
UT_ASSERT(e != NULL);
e->num = 3;
List_Append(
(ListElem**)&head, (ListElem**)&tail, (ListElem*)e);
}
/* Test contents */
{
int i;
for (i = 0, p = head; p; p = p->next, i++)
{
switch (i)
{
case 0:
UT_ASSERT(p->num == 2);
break;
case 1:
UT_ASSERT(p->num == 1);
break;
case 2:
UT_ASSERT(p->num == 3);
break;
default:
UT_ASSERT_FAILED_MSG("unexpected");
}
}
}
/* Remove head */
{
Elem* tmp = head;
List_Remove(
(ListElem**)&head, (ListElem**)&tail, (ListElem*)head);
free(tmp);
}
/* Test contents */
{
int i;
for (i = 0, p = head; p; p = p->next, i++)
{
switch (i)
{
case 0:
UT_ASSERT(p->num == 1);
break;
case 1:
UT_ASSERT(p->num == 3);
break;
default:
UT_ASSERT_FAILED_MSG("unexpected");
}
}
}
/* Remove tail */
{
Elem* tmp = tail;
List_Remove(
(ListElem**)&head, (ListElem**)&tail, (ListElem*)tail);
free(tmp);
}
/* Test contents */
{
int i;
for (i = 0, p = head; p; p = p->next, i++)
{
switch (i)
{
case 0:
UT_ASSERT(p->num == 1);
break;
default:
UT_ASSERT_FAILED_MSG("unexpected");
}
}
}
UT_ASSERT(head == tail);
/* Remove final element */
{
Elem* tmp = head;
List_Remove(
(ListElem**)&head, (ListElem**)&tail, (ListElem*)head);
free(tmp);
}
UT_ASSERT(head == tail);
UT_ASSERT(head == NULL);
UT_ASSERT(tail == NULL);
}
static void TestFindClassDecl()
{
MI_ClassDecl* cd;
MI_MethodDecl* md;
cd = SchemaDecl_FindClassDecl(&test_repos_classDecl, T("MSFT_Person"));
UT_ASSERT(cd != NULL);
md = ClassDecl_FindMethodDecl(cd, T("NoSuchMethod"));
UT_ASSERT(md == NULL);
cd = SchemaDecl_FindClassDecl(&test_repos_classDecl, T("NoSuchClass"));
UT_ASSERT(cd == NULL);
md = ClassDecl_FindMethodDecl(cd, T("NoSuchMethod"));
UT_ASSERT(md == NULL);
md = ClassDecl_FindMethodDecl(0, 0);
UT_ASSERT(md == NULL);
}
static MI_Result AddString(
MI_Instance* inst,
const MI_Char* name,
const MI_Char* str)
{
MI_Value value;
value.string = (MI_Char*)str;
return MI_Instance_AddElement(
inst,
name,
&value,
MI_STRING,
0);
}
static MI_Instance* NewAllTypes(Batch* batch)
{
MI_Instance* base;
MSFT_AllTypes* inst;
MI_ClassDecl* cd;
MI_Result r;
cd = SchemaDecl_FindClassDecl(
&test_repos_classDecl, T("MSFT_AllTypes"));
UT_ASSERT(cd != NULL);
r = Instance_New(&base, cd, batch);
UT_ASSERT(r == MI_RESULT_OK);
inst = (MSFT_AllTypes*)base;
/* Key*/
#if 0
r = Instance_SetElementFromString(base, T("Key"), T("1234"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Key.exists == 1);
UT_ASSERT(inst->Key.value == 1234);
#endif
/* BooleanValue */
r = Instance_SetElementFromString(base, T("BooleanValue"), T("TRUE"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->BooleanValue.exists == 1);
UT_ASSERT(inst->BooleanValue.value == 1);
/* BooleanValue */
r = Instance_SetElementFromString(base, T("BooleanValue"), T("FALSE"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->BooleanValue.exists == 1);
UT_ASSERT(inst->BooleanValue.value == 0);
/* Uint8Value */
r = Instance_SetElementFromString(base, T("Uint8Value"), T("8"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Uint8Value.exists == 1);
UT_ASSERT(inst->Uint8Value.value == 8);
/* Sint8Value */
r = Instance_SetElementFromString(base, T("Sint8Value"), T("-8"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Sint8Value.exists == 1);
UT_ASSERT(inst->Sint8Value.value == -8);
/* Uint16Value */
r = Instance_SetElementFromString(base, T("Uint16Value"), T("16"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Uint16Value.exists == 1);
UT_ASSERT(inst->Uint16Value.value == 16);
/* Sint16Value */
r = Instance_SetElementFromString(base, T("Sint16Value"), T("-16"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Sint16Value.exists == 1);
UT_ASSERT(inst->Sint16Value.value == -16);
/* Uint32Value */
r = Instance_SetElementFromString(base, T("Uint32Value"), T("32"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Uint32Value.exists == 1);
UT_ASSERT(inst->Uint32Value.value == 32);
/* Sint32Value */
r = Instance_SetElementFromString(base, T("Sint32Value"), T("-32"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Sint32Value.exists == 1);
UT_ASSERT(inst->Sint32Value.value == -32);
/* Uint64Value */
r = Instance_SetElementFromString(base, T("Uint64Value"), T("64"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Uint64Value.exists == 1);
UT_ASSERT(inst->Uint64Value.value == 64);
/* Sint64Value */
r = Instance_SetElementFromString(base, T("Sint64Value"), T("-64"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Sint64Value.exists == 1);
UT_ASSERT(inst->Sint64Value.value == -64);
/* Real32Value */
r = Instance_SetElementFromString(base, T("Real32Value"), T("32.32"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Real32Value.exists == 1);
UT_ASSERT(inst->Real32Value.value > 32 && inst->Real32Value.value < 33);
/* Real64Value */
r = Instance_SetElementFromString(base, T("Real64Value"), T("64.64"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Real64Value.exists == 1);
UT_ASSERT(inst->Real64Value.value > 64 && inst->Real64Value.value < 65);
/* DatetimeValue */
r = Instance_SetElementFromString(base, T("TimestampValue"),
T("20051225120000.123456-360"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->TimestampValue.exists == 1);
/* Char16Value */
r = Instance_SetElementFromString(base, T("Char16Value"), T("1234"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Char16Value.exists == 1);
UT_ASSERT(inst->Char16Value.value == 1234);
/* DatetimeValue */
r = Instance_SetElementFromString(base, T("IntervalValue"),
T("12345678010101.123456:000"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->IntervalValue.exists == 1);
/* StringValue */
r = Instance_SetElementFromString(base, T("StringValue"), T("Hello"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->StringValue.exists == 1);
UT_ASSERT(Zcmp(inst->StringValue.value, T("Hello")) == 0);
/* Uint32Array */
{
MI_Uint32 data[] = { 10, 20, 30 };
MI_Value value;
value.uint32a.data = data;
value.uint32a.size = MI_COUNT(data);
r = MI_Instance_SetElement(base, T("Uint32Array"), &value, MI_UINT32A, 0);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Uint32Array.value.data[0] == 10);
UT_ASSERT(inst->Uint32Array.value.data[1] == 20);
UT_ASSERT(inst->Uint32Array.value.data[2] == 30);
}
/* StringArray */
{
MI_Char* data[] = { (MI_Char*)T("RED"), (MI_Char*)T("GREEN"), (MI_Char*)T("BLUE") };
MI_Value value;
value.stringa.data = data;
value.stringa.size = MI_COUNT(data);
r = MI_Instance_SetElement(base, T("StringArray"), &value, MI_STRINGA, 0);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(Zcmp(inst->StringArray.value.data[0], T("RED")) == 0);
UT_ASSERT(Zcmp(inst->StringArray.value.data[1], T("GREEN")) == 0);
UT_ASSERT(Zcmp(inst->StringArray.value.data[2], T("BLUE")) == 0);
}
return base;
}
static void TestAllTypes()
{
MI_Instance* base;
MSFT_AllTypes* inst;
MI_ClassDecl* cd;
MI_Result r;
FILE* os;
Batch batch = BATCH_INITIALIZER;
cd = SchemaDecl_FindClassDecl(
&test_repos_classDecl, T("MSFT_AllTypes"));
UT_ASSERT(cd != NULL);
r = Instance_New(&base, cd, &batch);
UT_ASSERT(r == MI_RESULT_OK);
inst = (MSFT_AllTypes*)base;
/* BooleanValue */
r = Instance_SetElementFromString(base, T("BooleanValue"), T("TRUE"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->BooleanValue.exists == 1);
UT_ASSERT(inst->BooleanValue.value == 1);
/* BooleanValue */
r = Instance_SetElementFromString(base, T("BooleanValue"), T("FALSE"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->BooleanValue.exists == 1);
UT_ASSERT(inst->BooleanValue.value == 0);
/* Uint8Value */
r = Instance_SetElementFromString(base, T("Uint8Value"), T("8"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Uint8Value.exists == 1);
UT_ASSERT(inst->Uint8Value.value == 8);
/* Sint8Value */
r = Instance_SetElementFromString(base, T("Sint8Value"), T("-8"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Sint8Value.exists == 1);
UT_ASSERT(inst->Sint8Value.value == -8);
/* Uint16Value */
r = Instance_SetElementFromString(base, T("Uint16Value"), T("16"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Uint16Value.exists == 1);
UT_ASSERT(inst->Uint16Value.value == 16);
/* Sint16Value */
r = Instance_SetElementFromString(base, T("Sint16Value"), T("-16"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Sint16Value.exists == 1);
UT_ASSERT(inst->Sint16Value.value == -16);
/* Uint32Value */
r = Instance_SetElementFromString(base, T("Uint32Value"), T("32"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Uint32Value.exists == 1);
UT_ASSERT(inst->Uint32Value.value == 32);
/* Sint32Value */
r = Instance_SetElementFromString(base, T("Sint32Value"), T("-32"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Sint32Value.exists == 1);
UT_ASSERT(inst->Sint32Value.value == -32);
/* Uint64Value */
r = Instance_SetElementFromString(base, T("Uint64Value"), T("64"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Uint64Value.exists == 1);
UT_ASSERT(inst->Uint64Value.value == 64);
/* Sint64Value */
r = Instance_SetElementFromString(base, T("Sint64Value"), T("-64"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Sint64Value.exists == 1);
UT_ASSERT(inst->Sint64Value.value == -64);
/* Real32Value */
r = Instance_SetElementFromString(base, T("Real32Value"), T("32.32"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Real32Value.exists == 1);
UT_ASSERT(inst->Real32Value.value > 32 && inst->Real32Value.value < 33);
/* Real64Value */
r = Instance_SetElementFromString(base, T("Real64Value"), T("64.64"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Real64Value.exists == 1);
UT_ASSERT(inst->Real64Value.value > 64 && inst->Real64Value.value < 65);
/* DatetimeValue */
r = Instance_SetElementFromString(base, T("TimestampValue"),
T("20051225120000.123456-360"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->TimestampValue.exists == 1);
/* Char16Value */
r = Instance_SetElementFromString(base, T("Char16Value"), T("1234"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Char16Value.exists == 1);
UT_ASSERT(inst->Char16Value.value == 1234);
/* DatetimeValue */
r = Instance_SetElementFromString(base, T("IntervalValue"),
T("12345678010101.123456:000"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->IntervalValue.exists == 1);
/* StringValue */
r = Instance_SetElementFromString(base, T("StringValue"), T("Hello"));
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->StringValue.exists == 1);
UT_ASSERT(Zcmp(inst->StringValue.value, T("Hello")) == 0);
/* Uint32Array */
{
MI_Uint32 data[] = { 10, 20, 30 };
MI_Value value;
value.uint32a.data = data;
value.uint32a.size = MI_COUNT(data);
r = MI_Instance_SetElement(base, T("Uint32Array"), &value, MI_UINT32A, 0);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst->Uint32Array.value.data[0] == 10);
UT_ASSERT(inst->Uint32Array.value.data[1] == 20);
UT_ASSERT(inst->Uint32Array.value.data[2] == 30);
}
/* StringArray */
{
MI_Char* data[] = { (MI_Char*)T("RED"), (MI_Char*)T("GREEN"), (MI_Char*)T("BLUE") };
MI_Value value;
value.stringa.data = data;
value.stringa.size = MI_COUNT(data);
r = MI_Instance_SetElement(base, T("StringArray"), &value, MI_STRINGA, 0);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(Zcmp(inst->StringArray.value.data[0], T("RED")) == 0);
UT_ASSERT(Zcmp(inst->StringArray.value.data[1], T("GREEN")) == 0);
UT_ASSERT(Zcmp(inst->StringArray.value.data[2], T("BLUE")) == 0);
}
/* Print */
os = outStream;
UT_ASSERT(os);
MI_Instance_Print(base, os, 0);
/* Convert */
{
MSFT_AllTypes conv;
r = Instance_InitConvert(
(MI_Instance*)&conv,
cd,
base,
MI_FALSE, /* Keys only */
MI_FALSE, /* allow-keyless */
MI_FALSE, /* copy */
&batch);
UT_ASSERT(r == MI_RESULT_OK);
MI_Instance_Destruct((MI_Instance*)&conv);
}
/* Convert */
{
MSFT_AllTypes conv;
r = Instance_InitConvert(
(MI_Instance*)&conv,
cd,
base,
MI_FALSE, /* Keys only */
MI_FALSE, /* allow-keyless */
MI_TRUE, /* copy */
&batch);
UT_ASSERT(r == MI_RESULT_OK);
MI_Instance_Destruct((MI_Instance*)&conv);
}
{
MI_Instance* dinst = NULL;
MSFT_AllTypes sinst;
memset(&sinst, 0, sizeof(sinst));
/* Create a dynamic instance will all string properties */
r = Instance_NewDynamic(&dinst, T("MSFT_AllTypes"), MI_FLAG_CLASS,
&batch);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(dinst != NULL);
r = AddString(dinst, T("Key"), T("999"));
UT_ASSERT(r == MI_RESULT_OK);
r = AddString(dinst, T("BooleanValue"), T("FALSE"));
UT_ASSERT(r == MI_RESULT_OK);
r = AddString(dinst, T("Uint8Value"), T("8"));
UT_ASSERT(r == MI_RESULT_OK);
r = AddString(dinst, T("Sint8Value"), T("-8"));
UT_ASSERT(r == MI_RESULT_OK);
r = AddString(dinst, T("Uint16Value"), T("16"));
UT_ASSERT(r == MI_RESULT_OK);
r = AddString(dinst, T("Sint16Value"), T("-16"));
UT_ASSERT(r == MI_RESULT_OK);
r = AddString(dinst, T("Uint32Value"), T("32"));
UT_ASSERT(r == MI_RESULT_OK);
r = AddString(dinst, T("Sint32Value"), T("-32"));
UT_ASSERT(r == MI_RESULT_OK);
r = AddString(dinst, T("Uint64Value"), T("64"));
UT_ASSERT(r == MI_RESULT_OK);
r = AddString(dinst, T("Sint64Value"), T("-64"));
UT_ASSERT(r == MI_RESULT_OK);
r = AddString(dinst, T("Real32Value"), T("32.32"));
UT_ASSERT(r == MI_RESULT_OK);
r = AddString(dinst, T("Real64Value"), T("64.64"));
UT_ASSERT(r == MI_RESULT_OK);
r = AddString(dinst, T("TimestampValue"),
T("20051225120000.123456-360"));
UT_ASSERT(r == MI_RESULT_OK);
r = AddString(dinst, T("Char16Value"), T("1234"));
UT_ASSERT(r == MI_RESULT_OK);
r = AddString(dinst, T("IntervalValue"),
T("12345678010101.123456:000"));
UT_ASSERT(r == MI_RESULT_OK);
r = AddString(dinst, T("StringValue"), T("Hello"));
UT_ASSERT(r == MI_RESULT_OK);
#if 0
MI_Instance_Print(dinst, stdout, 0);
#endif
/* Convert to static instance */
r = Instance_InitConvert(
(MI_Instance*)&sinst,
cd,
dinst,
MI_FALSE, /* Keys only */
MI_FALSE, /* allow-keyless */
MI_TRUE, /* copy */
&batch);
UT_ASSERT(r == MI_RESULT_OK);
#if 0
MI_Instance_Print(&sinst.__instance, stdout, 0);
#endif
UT_ASSERT(sinst.BooleanValue.exists == 1);
UT_ASSERT(sinst.BooleanValue.value == 0);
UT_ASSERT(sinst.Uint8Value.exists == 1);
UT_ASSERT(sinst.Uint8Value.value == 8);
UT_ASSERT(sinst.Sint8Value.exists == 1);
UT_ASSERT(sinst.Sint8Value.value == -8);
UT_ASSERT(sinst.Uint16Value.exists == 1);
UT_ASSERT(sinst.Uint16Value.value == 16);
UT_ASSERT(sinst.Sint16Value.exists == 1);
UT_ASSERT(sinst.Sint16Value.value == -16);
UT_ASSERT(sinst.Uint32Value.exists == 1);
UT_ASSERT(sinst.Uint32Value.value == 32);
UT_ASSERT(sinst.Sint32Value.exists == 1);
UT_ASSERT(sinst.Sint32Value.value == -32);
UT_ASSERT(sinst.Uint64Value.exists == 1);
UT_ASSERT(sinst.Uint64Value.value == 64);
UT_ASSERT(sinst.Sint64Value.exists == 1);
UT_ASSERT(sinst.Sint64Value.value == -64);
UT_ASSERT(sinst.Real32Value.exists == 1);
UT_ASSERT(sinst.Real32Value.value > 32 && sinst.Real32Value.value < 33);
UT_ASSERT(sinst.Real64Value.exists == 1);
UT_ASSERT(sinst.Real64Value.value > 64 && sinst.Real64Value.value < 65);
UT_ASSERT(sinst.TimestampValue.exists == 1);
UT_ASSERT(sinst.Char16Value.exists == 1);
UT_ASSERT(sinst.Char16Value.value == 1234);
UT_ASSERT(sinst.IntervalValue.exists == 1);
UT_ASSERT(sinst.StringValue.exists == 1);
UT_ASSERT(Zcmp(sinst.StringValue.value, T("Hello")) == 0);
MI_Instance_Destruct((MI_Instance*)&sinst);
MI_Instance_Delete(dinst);
}
MI_Instance_Delete(base);
Batch_Destroy(&batch);
}
#if 0
static bool Test(MI_Result r, const MI_Char* str)
{
return Zcmp(Result_ToString(r), str) == 0;
}
#endif
#if 0
static void TestLib1()
{
char path[MAX_PATH];
Lib_Format(path, NULL, "PersonProvider");
#if defined(CONFIG_OS_LINUX)
UT_ASSERT(strcmp(path, "libPersonProvider.so") == 0);
#elif defined(_MSC_VER)
UT_ASSERT(strcmp(path, "PersonProvider.dll") == 0);
#endif
}
static void TestLib2()
{
#define DIRNAME "../" CONFIG_LIBDIR
char path[MAX_PATH];
void* handle;
void* sym;
MI_Result r;
/* Format path */
Lib_Format(path, DIRNAME, "PersonProvider");
#if defined(CONFIG_OS_LINUX)
UT_ASSERT(strcmp(path, DIRNAME "/libPersonProvider.so") == 0);
#elif defined(_MSC_VER)
UT_ASSERT(strcmp(path, DIRNAME "/PersonProvider.dll") == 0);
#endif
/* Load library */
handle = Lib_Open(path);
if(!handle)
{
handle = Lib_Open("PersonProvider");
}
UT_ASSERT(handle != NULL);
/* Get 'MI_Main' symbol */
sym = Lib_Sym(handle, "MI_Main");
UT_ASSERT(sym != NULL);
/* Close the library */
r = Lib_Close(handle);
UT_ASSERT(r == MI_RESULT_OK);
}
#endif
void TestInstances()
{
MI_Result r;
MI_Instance* inst;
MI_Value value;
const MI_ClassDecl* cd;
Batch batch = BATCH_INITIALIZER;
/* Find class decl */
cd = SchemaDecl_FindClassDecl(&test_repos_classDecl, T("MSFT_Process"));
UT_ASSERT(cd != NULL);
/* Create instance of MSFT_Numbers */
r = Instance_New(&inst, cd, &batch);
UT_ASSERT(r == MI_RESULT_OK);
/* CIM_Person.Key */
value.uint64 = 1234;
r = MI_Instance_SetElement(inst, MI_T("WorkingSetSize"), &value, MI_UINT64, 0);
UT_ASSERT(r == MI_RESULT_OK);
/* Check value */
for (size_t i = 0; i < 1000000; i++)
{
MI_Value v;
MI_Type t;
MI_Uint32 f;
r = MI_Instance_GetElement(inst, MI_T("WorkingSetSize"), &v, &t, &f, 0);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(v.uint64 == 1234);
UT_ASSERT(t == MI_UINT64);
UT_ASSERT(!(f & MI_FLAG_NULL));
}
MI_Instance_Delete(inst);
Batch_Destroy(&batch);
}
static void TestDynamicInstances()
{
MI_Instance* inst;
MI_Result r;
MI_Value v;
Batch batch = BATCH_INITIALIZER;
Batch* b = &batch;
r = Instance_NewDynamic(&inst, T("MSFT_Person"), MI_FLAG_CLASS, b);
UT_ASSERT(r == MI_RESULT_OK);
v.uint32 = 1;
r = MI_Instance_AddElement(inst, T("Key"), &v, MI_UINT32, MI_FLAG_KEY);
UT_ASSERT(r == MI_RESULT_OK);
v.string = (MI_Char*)T("George");
r = MI_Instance_AddElement(inst, T("First"), &v, MI_STRING, 0);
UT_ASSERT(r == MI_RESULT_OK);
v.string = (MI_Char*)T("Washington");
r = MI_Instance_AddElement(inst, T("Last"), &v, MI_STRING, 0);
UT_ASSERT(r == MI_RESULT_OK);
/* Check "Key" */
{
MI_Type t;
MI_Uint32 f;
r = MI_Instance_GetElement(inst, T("Key"), &v, &t, &f, 0);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(v.uint32 == 1);
UT_ASSERT(t == MI_UINT32);
UT_ASSERT(!(f & MI_FLAG_NULL));
}
/* Check "First" */
{
MI_Type t;
MI_Uint32 f;
r = MI_Instance_GetElement(inst, T("First"), &v, &t, &f, 0);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(Zcmp(v.string, T("George")) == 0);
UT_ASSERT(t == MI_STRING);
UT_ASSERT(!(f & MI_FLAG_NULL));
}
/* Check "Last" */
{
MI_Type t;
MI_Uint32 f;
r = MI_Instance_GetElement(inst, T("Last"), &v, &t, &f, 0);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(Zcmp(v.string, T("Washington")) == 0);
UT_ASSERT(t == MI_STRING);
UT_ASSERT(!(f & MI_FLAG_NULL));
}
#if 0
MI_Instance_Print(inst, stdout, 0);
#endif
// Test cloning.
MI_Instance* clone = NULL;
r = MI_Instance_Clone(inst, &clone);
UT_ASSERT(r == MI_RESULT_OK);
#if 0
MI_Instance_Print(clone, stdout, 0);
#endif
/* Check "Key" */
{
MI_Type t;
MI_Uint32 f;
r = MI_Instance_GetElement(clone, T("Key"), &v, &t, &f, 0);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(v.uint32 == 1);
UT_ASSERT(t == MI_UINT32);
UT_ASSERT(!(f & MI_FLAG_NULL));
}
/* Check "First" */
{
MI_Type t;
MI_Uint32 f;
r = MI_Instance_GetElement(clone, T("First"), &v, &t, &f, 0);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(Zcmp(v.string, T("George")) == 0);
UT_ASSERT(t == MI_STRING);
UT_ASSERT(!(f & MI_FLAG_NULL));
}
/* Check "Last" */
{
MI_Type t;
MI_Uint32 f;
r = MI_Instance_GetElement(clone, T("Last"), &v, &t, &f, 0);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(Zcmp(v.string, T("Washington")) == 0);
UT_ASSERT(t == MI_STRING);
UT_ASSERT(!(f & MI_FLAG_NULL));
}
/* Pack/unpack the instance */
{
Buf buf = BUF_INITIALIZER;
MI_Instance* newInst;
Buf_Init(&buf, 4096);
/* Pack */
r = Instance_Pack(inst, MI_FALSE, NULL, NULL, &buf);
UT_ASSERT(r == MI_RESULT_OK);
/* Unpack */
r = Instance_Unpack(&newInst, &buf, b, MI_FALSE);
UT_ASSERT(r == MI_RESULT_OK);
#if 0
MI_Instance_Print(newInst, stdout, 0);
#endif
MI_Instance_Delete(newInst);
Buf_Destroy(&buf);
}
// Add many properties:
for (size_t i = 0; i < 1000; i++)
{
MI_Char buf[32];
Szprintf(buf, MI_COUNT(buf), T("P%d"), (int)i);
v.string = (MI_Char*)T("Junk");
r = MI_Instance_AddElement(inst, buf, &v, MI_STRING, 0);
UT_ASSERT(r == MI_RESULT_OK);
}
// Test basd name:
r = MI_Instance_AddElement(inst, T(""), NULL, MI_UINT32, 0);
UT_ASSERT(r == MI_RESULT_INVALID_PARAMETER);
// Test reference array:
{
MI_Instance* data[2];
for (size_t i = 0; i < 2; i++)
{
MI_Instance* tmp = NULL;
r = MI_Instance_Clone(inst, &tmp);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(tmp != NULL);
data[i] = tmp;
}
v.instancea.data = data;
v.instancea.size = 2;
r = MI_Instance_AddElement(inst, T("RefArray"), &v, MI_REFERENCEA, 0);
UT_ASSERT(r == MI_RESULT_OK);
for (size_t i = 0; i < 2; i++)
MI_Instance_Delete(data[i]);
}
MI_Instance_Print(inst, outStream, 0);
// Clone again
{
MI_Instance* tmp = NULL;
r = MI_Instance_Clone(inst, &tmp);
UT_ASSERT(r == MI_RESULT_OK);
MI_Instance_Delete(tmp);
}
MI_Instance_Delete(clone);
MI_Instance_Delete(inst);
Batch_Destroy(b);
}
/*
**==============================================================================
**
** TestBuf()
**
** This test excercises the Buf implementation. It packs and unpacks
** integer values of lengths 8-bit, 16-bit, 32-bit, and 64-bit. The values
** and the lengths are selected randomly. The unpacked values are compared
** with the original packed values (the original values are save in a
** vector).
**
**==============================================================================
*/
static void TestBuf()
{
Buf b;
vector<MI_Uint8> buf8;
vector<MI_Uint16> buf16;
vector<MI_Uint32> buf32;
vector<MI_Uint64> buf64;
vector<MI_Uint32> indices;
MI_Uint64 sum1 = 0;
MI_Uint64 sum2 = 0;
const size_t N = 100000;
MI_Result r;
Buf_Init(&b, 256);
for (size_t i = 0; i < N; i++)
{
buf8.push_back(rand() % 0xFF);
buf16.push_back(rand() % 0xFFFF);
buf32.push_back(rand() % 0xFFFFFFFF);
buf64.push_back(rand() % 0xFFFFFFFF);
indices.push_back((MI_Uint32)rand() % 3);
switch (indices[i])
{
case 0:
r = Buf_PackU8(&b, buf8[i]);
UT_ASSERT(r == MI_RESULT_OK);
sum1 += buf8[i];
break;
case 1:
r = Buf_PackU16(&b, buf16[i]);
UT_ASSERT(r == MI_RESULT_OK);
sum1 += buf16[i];
break;
case 2:
r = Buf_PackU32(&b, buf32[i]);
UT_ASSERT(r == MI_RESULT_OK);
sum1 += buf32[i];
break;
case 3:
r = Buf_PackU64(&b, buf64[i]);
sum1 += buf64[i];
UT_ASSERT(r == MI_RESULT_OK);
break;
}
}
for (size_t i = 0; i < N; i++)
{
switch (indices[i])
{
case 0:
{
MI_Uint8 x = 0;
r = Buf_UnpackU8(&b, &x);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(x == buf8[i]);
sum2 += buf8[i];
break;
}
case 1:
{
MI_Uint16 x = 0;
r = Buf_UnpackU16(&b, &x);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(x == buf16[i]);
sum2 += buf16[i];
break;
}
case 2:
{
MI_Uint32 x = 0;
r = Buf_UnpackU32(&b, &x);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(x == buf32[i]);
sum2 += buf32[i];
break;
}
case 3:
{
MI_Uint64 x = 0;
r = Buf_UnpackU64(&b, &x);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(x == buf64[i]);
sum2 += buf64[i];
break;
}
}
}
/* Verify that the check sums are the same */
UT_ASSERT(sum1 == sum2);
Buf_Destroy(&b);
}
/*
**==============================================================================
**
** TestBuf2()
**
** This test excercises the string pack/unpack functions of Buf.
** It packs N decimal formatted strings and then unpacks them, comparing
** that backed and unpacked forms are consistent.
**
**==============================================================================
*/
static void TestBuf2()
{
Buf b;
MI_Result r;
MI_Uint32 i;
const MI_Uint32 N = 10000;
Buf_Init(&b, 256);
for (i = 0; i < N; i++)
{
MI_Char buf[32];
Szprintf(buf, MI_COUNT(buf), T("%u"), i);
r = Buf_PackStr(&b, buf);
UT_ASSERT(r == MI_RESULT_OK);
}
for (i = 0; i < N; i++)
{
MI_Char buf[32];
const MI_Char* str = NULL;
Szprintf(buf, MI_COUNT(buf), T("%u"), i);
r = Buf_UnpackStr(&b, &str);
UT_ASSERT(r == MI_RESULT_OK);
}
Buf_Destroy(&b);
}
/*
**==============================================================================
**
** TestBuf3()
**
** This test excercises the integer array pack/unpack functions of Buf.
** It packs N arrays of various lengths and attempts to unpack them and
** compare the results.
**
**==============================================================================
*/
static void TestBuf3()
{
Buf b;
MI_Uint32 i;
const MI_Uint32 N = 100;
MI_Result r;
vector<MI_Uint8> a8;
vector<MI_Uint16> a16;
vector<MI_Uint32> a32;
vector<MI_Uint64> a64;
vector<MI_Uint8> b8;
vector<MI_Uint16> b16;
vector<MI_Uint32> b32;
vector<MI_Uint64> b64;
Buf_Init(&b, 256);
for (i = 0; i < N; i++)
{
a8.push_back((MI_Uint8)i);
a16.push_back((MI_Uint16)i);
a32.push_back((MI_Uint32)i);
a64.push_back((MI_Uint64)i);
{
r = Buf_PackU8A(&b, &a8[0], (MI_Uint32)a8.size());
UT_ASSERT(r == MI_RESULT_OK);
}
{
r = Buf_PackU16A(&b, &a16[0], (MI_Uint32)a16.size());
UT_ASSERT(r == MI_RESULT_OK);
}
{
r = Buf_PackU32A(&b, &a32[0], (MI_Uint32)a32.size());
UT_ASSERT(r == MI_RESULT_OK);
}
{
r = Buf_PackU64A(&b, &a64[0], (MI_Uint32)a64.size());
UT_ASSERT(r == MI_RESULT_OK);
}
}
for (i = 0; i < N; i++)
{
b8.push_back((MI_Uint8)i);
b16.push_back((MI_Uint16)i);
b32.push_back((MI_Uint32)i);
b64.push_back((MI_Uint64)i);
{
const MI_Uint8* data;
MI_Uint32 size;
r = Buf_UnpackU8A(&b, &data, &size);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT((MI_Uint32)b8.size() == size);
UT_ASSERT(memcmp(data, &b8[0], i * sizeof(MI_Uint8)) == 0);
}
{
const MI_Uint16* data;
MI_Uint32 size;
r = Buf_UnpackU16A(&b, &data, &size);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT((MI_Uint32)b16.size() == size);
UT_ASSERT(memcmp(data, &b16[0], i * sizeof(MI_Uint16)) == 0);
}
{
const MI_Uint32* data;
MI_Uint32 size;
r = Buf_UnpackU32A(&b, &data, &size);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT((MI_Uint32)b32.size() == size);
UT_ASSERT(memcmp(data, &b32[0], i * sizeof(MI_Uint32)) == 0);
}
{
const MI_Uint64* data;
MI_Uint32 size;
r = Buf_UnpackU64A(&b, &data, &size);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT((MI_Uint32)b64.size() == size);
UT_ASSERT(memcmp(data, &b64[0], i * sizeof(MI_Uint64)) == 0);
}
}
Buf_Destroy(&b);
}
/*
**==============================================================================
**
** TestBuf4()
**
** This test excercises the string array pack/unpack functions of Buf.
**
**==============================================================================
*/
static void TestBuf4()
{
Buf b;
MI_Result r;
const MI_Char* DATA[] =
{
T("Sunday"),
T("Monday"),
T("Tuesday"),
T("Wednesday"),
T("Thursday"),
T("Friday"),
T("Saturday"),
};
const MI_Uint32 SIZE = MI_COUNT(DATA);
const MI_Char** data;
MI_Uint32 size;
MI_Uint32 i;
{
Buf_Init(&b, 256);
r = Buf_PackStrA(&b, DATA, SIZE);
UT_ASSERT(r == MI_RESULT_OK);
r = Buf_UnpackStrA(&b, &data, &size);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(size == SIZE);
for (i = 0; i < size; i++)
UT_ASSERT(Zcmp(data[i], DATA[i]) == 0);
Buf_Destroy(&b);
}
{
Buf_Init(&b, 256);
r = Buf_PackStrA(&b, DATA, 1);
UT_ASSERT(r == MI_RESULT_OK);
r = Buf_UnpackStrA(&b, &data, &size);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(size == 1);
for (i = 0; i < size; i++)
UT_ASSERT(Zcmp(data[i], DATA[i]) == 0);
Buf_Destroy(&b);
}
{
Buf_Init(&b, 256);
r = Buf_PackStrA(&b, DATA, 0);
UT_ASSERT(r == MI_RESULT_OK);
r = Buf_UnpackStrA(&b, &data, &size);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(size == 0);
for (i = 0; i < size; i++)
UT_ASSERT(Zcmp(data[i], DATA[i]) == 0);
Buf_Destroy(&b);
}
{
MI_Uint32 j;
const MI_Uint32 N = 100;
Buf_Init(&b, 256);
for (j = 0; j < N; j++)
{
r = Buf_PackStrA(&b, DATA, SIZE);
UT_ASSERT(r == MI_RESULT_OK);
}
for (j = 0; j < N; j++)
{
r = Buf_UnpackStrA(&b, &data, &size);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(size == SIZE);
for (i = 0; i < size; i++)
UT_ASSERT(Zcmp(data[i], DATA[i]) == 0);
}
Buf_Destroy(&b);
}
}
static void TestLog()
{
MI_Result r;
MI_Char tmp[MAX_PATH_SIZE];
#if defined(CONFIG_OS_WINDOWS)
int tmp_i = _mkdir(GetPath(ID_TMPDIR));
MI_UNUSED(tmp_i);
#endif
/* Open the log (into text.log) */
r = Log_Open(ZSTempPath(tmp, "test2.log"));
UT_ASSERT(r == MI_RESULT_OK);
/* Set the log level to 'INFO' */
Log_SetLevel(LOG_INFO);
/* Write a log message of each level */
LOGF((T("fatal: %u"), 11111));
LOGE((T("error: %u"), 22222));
LOGW((T("warning: %u"), 33333));
LOGI((T("information: %u"), 44444));
LOGD((T("debug: %u"), 55555));
/* Close the log */
Log_Close();
/* verify that output was correct */
std::vector< unsigned char > content;
UT_ASSERT(ut::readFileContent(ut::StrToChar(tmp), content));
ut::removeIfExist(ut::StrToChar(tmp).c_str());
UT_ASSERT(!content.empty());
{
std::string s(reinterpret_cast<const char*>(&content[0]),
reinterpret_cast<const char*>(&content[0]) + content.size());
// expecting to find mentioning of all messages, excluding 'debug'
UT_ASSERT(s.find("FATAL") != string::npos);
UT_ASSERT(s.find("fatal: 11111") != string::npos);
UT_ASSERT(s.find("ERROR") != string::npos);
UT_ASSERT(s.find("error: 22222") != string::npos);
UT_ASSERT(s.find("WARNING") != string::npos);
UT_ASSERT(s.find("warning: 33333") != string::npos);
UT_ASSERT(s.find("INFO") != string::npos);
UT_ASSERT(s.find("information: 44444") != string::npos);
// these should not be in the file
UT_ASSERT(s.find("DEBUG") == string::npos);
UT_ASSERT(s.find("debug: 55555") == string::npos);
}
/* Test loglevel conversions */
{
const char* _symbols[] =
{
"Fatal",
"Error",
"Warning",
"Info",
"Debug",
};
const Log_Level _levels[] =
{
LOG_FATAL,
LOG_ERROR,
LOG_WARNING,
LOG_INFO,
LOG_DEBUG
};
const size_t n = sizeof(_symbols) / sizeof(_symbols[0]);
for (size_t i = 0; i < n; i++)
{
UT_ASSERT(Log_SetLevelFromString(_symbols[i]) == 0);
UT_ASSERT(Strcasecmp(
Log_GetLevelString(Log_GetLevel()), _symbols[i]) == 0);
UT_ASSERT(Log_GetLevel() == _levels[i]);
}
}
}
static void TestPackInstance()
{
MI_Instance* inst1 = NULL;
MI_Instance* inst2 = NULL;
Batch batch = BATCH_INITIALIZER;
Buf buf = BUF_INITIALIZER;
MI_Result r;
/* Create new instance of MSFT_AllTypes */
inst1 = NewAllTypes(&batch);
UT_ASSERT(inst1 != NULL);
/* Pack instance */
r = Instance_Pack(inst1, MI_FALSE, NULL, NULL, &buf);
UT_ASSERT(r == MI_RESULT_OK);
/* Unpack instance */
r = Instance_Unpack(&inst2, &buf, &batch, MI_FALSE);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(inst2 != NULL);
#if 0
MI_Instance_Print(inst1, stdout, 0);
MI_Instance_Print(inst2, stdout, 0);
#endif
/* Steal buffer memory and attach it to the batch. */
{
Page* page = Buf_StealPage(&buf);
UT_ASSERT(page != NULL);
Batch_AttachPage(&batch, page);
}
MI_Instance_Delete(inst1);
MI_Instance_Delete(inst2);
Buf_Destroy(&buf);
Batch_Destroy(&batch);
}
static void TestPage()
{
size_t n = sizeof (Page);
UT_ASSERT(n % 8 == 0);
}
#define TestOneCppProp(prop,valueParam) \
{ \
/* test auto-generated setters/getters/copy/assignment operators */ \
MSFT_AllTypes_Class inst1; \
\
UT_ASSERT(!inst1.prop().exists); \
inst1.prop##_value(valueParam); \
UT_ASSERT(inst1.prop().exists); \
UT_ASSERT(inst1.prop().value == valueParam); \
\
/* copy ctor of instance */ \
MSFT_AllTypes_Class inst2( inst1 ); \
\
UT_ASSERT(inst1.prop() == inst2.prop()); \
UT_ASSERT(inst1.prop##_value() == inst2.prop##_value()); \
\
/* assignment operator */ \
MSFT_AllTypes_Class inst3; \
\
UT_ASSERT(inst1.prop().exists != inst3.prop().exists); \
UT_ASSERT(!inst3.prop().exists); \
\
inst3 = inst1; \
UT_ASSERT(inst1.prop().exists == inst3.prop().exists); \
UT_ASSERT(inst1.prop().value == inst3.prop().value); \
UT_ASSERT(inst1.prop##_value() == inst3.prop##_value()); \
\
/* copy data using setters */ \
MSFT_AllTypes_Class inst4; \
\
UT_ASSERT(inst1.prop().exists != inst4.prop().exists); \
\
inst4.prop(inst1.prop()); \
UT_ASSERT(inst1.prop() == inst4.prop()); \
UT_ASSERT(inst1.prop##_value() == inst4.prop##_value()); \
\
/* test null assignment */ \
MSFT_AllTypes_Class inst_null; \
\
UT_ASSERT(inst4.prop() != inst_null.prop()); \
inst4 = inst_null; \
UT_ASSERT(inst4.prop() == inst_null.prop());\
}
static void TestBaseCppAllTypes()
{
TestOneCppProp(BooleanValue,MI_TRUE);
TestOneCppProp(BooleanValue,MI_FALSE);
TestOneCppProp(Uint8Value,0);
TestOneCppProp(Uint8Value,88);
TestOneCppProp(Sint8Value,0);
TestOneCppProp(Sint8Value,-88);
TestOneCppProp(Uint16Value,0);
TestOneCppProp(Uint16Value,1616);
TestOneCppProp(Sint16Value,0);
TestOneCppProp(Sint16Value,-1616);
TestOneCppProp(Uint32Value,0);
TestOneCppProp(Uint32Value,3232);
TestOneCppProp(Sint32Value,0);
TestOneCppProp(Sint32Value,-3232);
TestOneCppProp(Uint64Value,0);
TestOneCppProp(Uint64Value,6464);
TestOneCppProp(Sint64Value,0);
TestOneCppProp(Sint64Value,-6464);
TestOneCppProp(StringValue,MI_T("123"));
TestOneCppProp(StringValue,String(MI_T("123")));
TestOneCppProp(StringValue,String());
StringA sa; sa.PushBack(MI_T("123")); sa.PushBack(MI_T("321"));
//ATTN: add == in vector !! TestOneCppProp(StringArray,sa);
//TestOneCppProp(StringArray,StringA());
}
static void TestDir()
{
string path = prefix + "/base/tests/testdir";
Dir* dir = Dir_Open(path.c_str());
UT_ASSERT(dir != NULL);
vector<string> names1;
for (;;)
{
DirEnt* ent = Dir_Read(dir);
if (!ent)
break;
if (strcmp(ent->name, "..") == 0 || strcmp(ent->name, ".") == 0)
continue;
if (strcmp(ent->name, "CVS") == 0)
continue;
names1.push_back(ent->name);
}
sort(names1.begin(), names1.end());
vector<string> names2;
names2.push_back("dir1");
names2.push_back("dir2");
names2.push_back("file1");
names2.push_back("file2");
names2.push_back("file3");
UT_ASSERT(names1.size() == 5);
UT_ASSERT(names2.size() == 5);
UT_ASSERT(names1 == names2);
Dir_Close(dir);
}
static void TestStrArr()
{
char** data;
data = StrArr();
UT_ASSERT(StrArrLen(data) == 0);
StrArrCat(&data, "Red");
UT_ASSERT(StrArrLen(data) == 1);
StrArrCat(&data, "Green");
UT_ASSERT(StrArrLen(data) == 2);
StrArrCat(&data, "Blue");
UT_ASSERT(StrArrLen(data) == 3);
UT_ASSERT(strcmp(data[0], "Red") == 0);
UT_ASSERT(strcmp(data[1], "Green") == 0);
UT_ASSERT(strcmp(data[2], "Blue") == 0);
StrArrFree(data);
}
static void TestConf1()
{
char path[MAX_PATH_SIZE];
Conf* conf;
size_t n = 1;
Strlcpy(path, GetPath(ID_PREFIX), sizeof(path));
Strlcat(path, "/base/tests/file1.conf", sizeof(path));
/* Open configuration file */
conf = Conf_Open(path);
UT_ASSERT(conf != NULL);
for (;;)
{
const char* key;
const char* value;
int r = Conf_Read(conf, &key, &value);
if (r == 1)
break;
UT_ASSERT(r == 0);
switch (n)
{
case 1:
UT_ASSERT(strcmp(key, "Key1") == 0);
UT_ASSERT(strcmp(value, "Value1") == 0);
break;
case 2:
UT_ASSERT(strcmp(key, "Key2") == 0);
UT_ASSERT(strcmp(value, "Value2") == 0);
break;
case 3:
UT_ASSERT(strcmp(key, "Key3") == 0);
UT_ASSERT(strcmp(value, "Value3") == 0);
break;
case 4:
UT_ASSERT(strcmp(key, "Key4") == 0);
UT_ASSERT(strcmp(value, "Value4") == 0);
break;
case 5:
UT_ASSERT(strcmp(key, "Key5") == 0);
UT_ASSERT(strcmp(value, "Value5") == 0);
break;
case 6:
UT_ASSERT(strcmp(key, "Key6") == 0);
UT_ASSERT(strcmp(value, "") == 0);
break;
case 7:
UT_ASSERT(strcmp(key, "Key7") == 0);
UT_ASSERT(strcmp(value, "") == 0);
break;
default:
UT_ASSERT(UT_FALSE);
}
n++;
}
Conf_Close(conf);
}
static void TestConf2()
{
char path[MAX_PATH_SIZE];
Conf* conf;
size_t n = 1;
Strlcpy(path, GetPath(ID_PREFIX), sizeof(path));
Strlcat(path, "/base/tests/file2.conf", sizeof(path));
/* Open configuration file */
conf = Conf_Open(path);
UT_ASSERT(conf != NULL);
for (;;)
{
const char* key;
const char* value;
int r = Conf_Read(conf, &key, &value);
if (r == -1)
{
const char* err = Conf_Error(conf);
if (n == 1)
{
UT_ASSERT(strcmp(err, "expected '='") == 0);
UT_ASSERT(Conf_Line(conf) == 2);
}
else if (n == 2)
{
UT_ASSERT(strcmp(err, "expected keyword") == 0);
UT_ASSERT(Conf_Line(conf) == 3);
}
else if (n == 3)
{
UT_ASSERT(strcmp(err, "expected keyword") == 0);
UT_ASSERT(Conf_Line(conf) == 4);
}
else
UT_ASSERT(UT_FALSE);
}
else if (r == 0)
{
UT_ASSERT(n == 4);
UT_ASSERT(strcmp(key, "KEY1") == 0);
UT_ASSERT(strcmp(value, "VALUE1") == 0);
}
else
break;
n++;
}
Conf_Close(conf);
}
static void TestMkdirhier()
{
char tmp[MAX_PATH_SIZE];
Mkdirhier(TempPath(tmp, "/aaa/bbb/ccc/ddd"), 0755);
UT_ASSERT(Isdir(tmp));
}
static void TestIntToStr()
{
for (MI_Uint32 i = 0; i < 1000; i++)
{
char buf1[11];
size_t size1;
const char* str = Uint32ToStr(buf1, i, &size1);
char buf2[11];
size_t size2 = Snprintf(buf2, sizeof(buf2), "%u", i);
UT_ASSERT(str != NULL);
UT_ASSERT(size1 == size2);
UT_ASSERT(strcmp(str, buf2) == 0);
}
for (MI_Uint64 i = 0; i < 1000; i++)
{
char buf1[21];
size_t size1;
const char* str = Uint64ToStr(buf1, i, &size1);
char buf2[21];
size_t size2 = Snprintf(buf2, sizeof(buf2), UINT64_FMT, i);
UT_ASSERT(str != NULL);
UT_ASSERT(size1 == size2);
UT_ASSERT(strcmp(str, buf2) == 0);
}
}
static void TestGetOpt()
{
GetOptState state = GETOPTSTATE_INITIALIZER;
const char* argv[] =
{
"aaa",
"bbb",
"--help",
"--infile=/tmp/infile",
"--outfile",
"/tmp/outfile",
"-x=abc",
"ccc",
NULL,
};
int argc = sizeof(argv) / sizeof(argv[0]) - 1;
static const char* opts[] =
{
"--help",
"--infile:",
"--outfile:",
"-x:",
NULL,
};
int r;
bool help = false;
string infile;
string outfile;
string x;
for (;;)
{
r = GetOpt(&argc, argv, opts, &state);
if (r == -1)
{
fprintf(stderr, "GetOpt() failed: %s\n", state.err);
UT_ASSERT_FAILED_MSG("GetOpt failed");
}
if (r != 0)
break;
if (strcmp(state.opt, "--help") == 0)
help = true;
else if (strcmp(state.opt, "--infile") == 0)
infile = state.arg;
else if (strcmp(state.opt, "--outfile") == 0)
outfile = state.arg;
else if (strcmp(state.opt, "-x") == 0)
x = state.arg;
}
UT_ASSERT(argc == 3);
UT_ASSERT(strcmp(argv[0], "aaa") == 0);
UT_ASSERT(strcmp(argv[1], "bbb") == 0);
UT_ASSERT(strcmp(argv[2], "ccc") == 0);
UT_ASSERT(argv[3] == NULL);
UT_ASSERT(help == true);
UT_ASSERT(infile == "/tmp/infile");
UT_ASSERT(outfile == "/tmp/outfile");
UT_ASSERT(x == "abc");
}
static void TestGetOptErr()
{
GetOptState state = GETOPTSTATE_INITIALIZER;
const char* argv[] =
{
"aaa",
"--help",
"bbb",
"--outfile", /* missing option argument */
NULL,
};
int argc = sizeof(argv) / sizeof(argv[0]) - 1;
static const char* opts[] =
{
"--help",
"--outfile:",
NULL,
};
bool help = false;
string outfile;
string error;
for (;;)
{
int r = GetOpt(&argc, argv, opts, &state);
if (r == 1)
break;
if (r == 0)
{
if (strcmp(state.opt, "--help") == 0)
help = true;
else if (strcmp(state.opt, "--outfile") == 0)
outfile = state.arg;
}
if (r == -1)
{
error = state.err;
break;
}
}
UT_ASSERT(help == true);
UT_ASSERT(error == "missing option argument: --outfile");
UT_ASSERT(outfile == "");
}
static void TestMatchKeys()
{
MI_Result r;
MI_Instance* inst1;
MI_Instance* inst2;
MI_Instance* ref;
MI_Value value;
r = Instance_NewDynamic(&ref, T("MyRef"), MI_FLAG_CLASS, 0);
UT_ASSERT(r == MI_RESULT_OK);
value.uint32 = 57789;
r = MI_Instance_AddElement(ref, T("Key1"), &value, MI_UINT32, MI_FLAG_KEY);
UT_ASSERT(r == MI_RESULT_OK);
value.string = (MI_Char*)T("Bye");
r = MI_Instance_AddElement(ref, T("Key2"), &value, MI_STRING, MI_FLAG_KEY);
UT_ASSERT(r == MI_RESULT_OK);
r = Instance_NewDynamic(&inst1, T("MyClass"), MI_FLAG_ASSOCIATION, 0);
UT_ASSERT(r == MI_RESULT_OK);
r = Instance_NewDynamic(&inst2, T("MyClass"), MI_FLAG_CLASS, 0);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(Instance_MatchKeys(inst1, inst2) == MI_FALSE);
value.uint32 = 1234;
r = MI_Instance_AddElement(inst1, T("Key1"), &value,MI_UINT32, MI_FLAG_KEY);
UT_ASSERT(r == MI_RESULT_OK);
value.string = (MI_Char*)T("Hello");
r = MI_Instance_AddElement(inst1, T("Key2"), &value, MI_STRING,MI_FLAG_KEY);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(Instance_MatchKeys(inst1, inst2) == MI_FALSE);
value.uint32 = 1234;
r = MI_Instance_AddElement(inst2, T("Key1"), &value, MI_UINT32,MI_FLAG_KEY);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(Instance_MatchKeys(inst1, inst2) == MI_FALSE);
value.string = (MI_Char*)T("Hello");
r = MI_Instance_AddElement(inst2, T("Key2"), &value, MI_STRING,MI_FLAG_KEY);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(Instance_MatchKeys(inst1, inst2) == MI_TRUE);
value.reference = ref;
r = MI_Instance_AddElement(inst1, T("Key3"), &value,
MI_REFERENCE,MI_FLAG_KEY);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(Instance_MatchKeys(inst1, inst2) == MI_FALSE);
value.reference = ref;
r = MI_Instance_AddElement(inst2, T("Key3"), &value,
MI_REFERENCE,MI_FLAG_KEY);
UT_ASSERT(r == MI_RESULT_OK);
UT_ASSERT(Instance_MatchKeys(inst1, inst2) == MI_TRUE);
#if 0
__MI_Instance_Print(inst1, stdout, 0);
__MI_Instance_Print(inst2, stdout, 0);
#endif
__MI_Instance_Delete(inst1);
__MI_Instance_Delete(inst2);
__MI_Instance_Delete(ref);
}
static void TestWSManDatetime()
{
MI_Char buf[64];
{
MI_Datetime x;
UT_ASSERT(ParseWSManDatetime(T("P5Y"), &x) == 0);
UT_ASSERT(x.isTimestamp == 0);
UT_ASSERT(x.u.interval.days == 1826);
UT_ASSERT(x.u.interval.hours == 0);
UT_ASSERT(x.u.interval.minutes == 0);
UT_ASSERT(x.u.interval.seconds == 0);
UT_ASSERT(x.u.interval.microseconds == 0);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, T("P1826D")) == 0);
}
{
MI_Datetime x;
UT_ASSERT(ParseWSManDatetime(T("P1Y1M22D"), &x) == 0);
UT_ASSERT(x.isTimestamp == 0);
UT_ASSERT(x.u.interval.days == 417);
UT_ASSERT(x.u.interval.hours == 0);
UT_ASSERT(x.u.interval.minutes == 0);
UT_ASSERT(x.u.interval.seconds == 0);
UT_ASSERT(x.u.interval.microseconds == 0);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, T("P417D")) == 0);
}
{
MI_Datetime x;
UT_ASSERT(ParseWSManDatetime(T("P1Y1M22DT10H11M12S"), &x) == 0);
UT_ASSERT(x.isTimestamp == 0);
UT_ASSERT(x.u.interval.days == 417);
UT_ASSERT(x.u.interval.hours == 10);
UT_ASSERT(x.u.interval.minutes == 11);
UT_ASSERT(x.u.interval.seconds == 12);
UT_ASSERT(x.u.interval.microseconds == 0);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, T("P417DT10H11M12S")) == 0);
}
{
MI_Datetime x;
UT_ASSERT(ParseWSManDatetime(T("PT31S"), &x) == 0);
UT_ASSERT(x.isTimestamp == 0);
UT_ASSERT(x.u.interval.days == 0);
UT_ASSERT(x.u.interval.hours == 0);
UT_ASSERT(x.u.interval.minutes == 0);
UT_ASSERT(x.u.interval.seconds == 31);
UT_ASSERT(x.u.interval.microseconds == 0);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, T("PT31S")) == 0);
}
{
MI_Datetime x;
UT_ASSERT(ParseWSManDatetime(T("PT66S"), &x) == 0);
UT_ASSERT(x.isTimestamp == 0);
UT_ASSERT(x.u.interval.days == 0);
UT_ASSERT(x.u.interval.hours == 0);
UT_ASSERT(x.u.interval.minutes == 1);
UT_ASSERT(x.u.interval.seconds == 6);
UT_ASSERT(x.u.interval.microseconds == 0);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, T("PT1M6S")) == 0);
}
{
MI_Datetime x;
UT_ASSERT(ParseWSManDatetime(T("PT60S"), &x) == 0);
UT_ASSERT(x.isTimestamp == 0);
UT_ASSERT(x.u.interval.days == 0);
UT_ASSERT(x.u.interval.hours == 0);
UT_ASSERT(x.u.interval.minutes == 1);
UT_ASSERT(x.u.interval.seconds == 0);
UT_ASSERT(x.u.interval.microseconds == 0);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, T("PT1M")) == 0);
}
{
MI_Datetime x;
UT_ASSERT(ParseWSManDatetime(T("PT5.5S"), &x) == 0);
UT_ASSERT(x.isTimestamp == 0);
UT_ASSERT(x.u.interval.days == 0);
UT_ASSERT(x.u.interval.hours == 0);
UT_ASSERT(x.u.interval.minutes == 0);
UT_ASSERT(x.u.interval.seconds == 5);
UT_ASSERT(x.u.interval.microseconds == 500000);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, T("PT5.500000S")) == 0);
}
{
MI_Datetime x;
UT_ASSERT(ParseWSManDatetime(T("PT5.123456S"), &x) == 0);
UT_ASSERT(x.isTimestamp == 0);
UT_ASSERT(x.u.interval.days == 0);
UT_ASSERT(x.u.interval.hours == 0);
UT_ASSERT(x.u.interval.minutes == 0);
UT_ASSERT(x.u.interval.seconds == 5);
UT_ASSERT(x.u.interval.microseconds == 123456);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, T("PT5.123456S")) == 0);
}
{
MI_Datetime x;
UT_ASSERT(ParseWSManDatetime(T("P1Y2M3DT10H30M"), &x) == 0);
UT_ASSERT(x.isTimestamp == 0);
UT_ASSERT(x.u.interval.days == 429);
UT_ASSERT(x.u.interval.hours == 10);
UT_ASSERT(x.u.interval.minutes == 30);
UT_ASSERT(x.u.interval.seconds == 0);
UT_ASSERT(x.u.interval.microseconds == 0);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, T("P429DT10H30M")) == 0);
}
{
MI_Datetime x;
UT_ASSERT(ParseWSManDatetime(T("P1Y2MT"), &x) == 0);
UT_ASSERT(x.isTimestamp == 0);
UT_ASSERT(x.u.interval.days == 426);
UT_ASSERT(x.u.interval.hours == 0);
UT_ASSERT(x.u.interval.minutes == 0);
UT_ASSERT(x.u.interval.seconds == 0);
UT_ASSERT(x.u.interval.microseconds == 0);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, T("P426D")) == 0);
}
{
MI_Datetime x;
UT_ASSERT(ParseWSManDatetime(T("PT0.000001S"), &x) == 0);
UT_ASSERT(x.isTimestamp == 0);
UT_ASSERT(x.u.interval.days == 0);
UT_ASSERT(x.u.interval.hours == 0);
UT_ASSERT(x.u.interval.minutes == 0);
UT_ASSERT(x.u.interval.seconds == 0);
UT_ASSERT(x.u.interval.microseconds == 1);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, T("PT0.000001S")) == 0);
}
{
MI_Datetime x;
UT_ASSERT(ParseWSManDatetime(T("2010-12-31"), &x) == 0);
UT_ASSERT(x.isTimestamp == 1);
UT_ASSERT(x.u.timestamp.year == 2010);
UT_ASSERT(x.u.timestamp.month == 12);
UT_ASSERT(x.u.timestamp.day == 31);
UT_ASSERT(x.u.timestamp.hour == 0);
UT_ASSERT(x.u.timestamp.minute == 0);
UT_ASSERT(x.u.timestamp.second == 0);
UT_ASSERT(x.u.timestamp.microseconds == 0);
UT_ASSERT(x.u.timestamp.utc == 0);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, T("2010-12-31")) == 0);
}
{
MI_Datetime x;
UT_ASSERT(ParseWSManDatetime(T("2010-1-1"), &x) == -1);
}
{
MI_Datetime x;
const MI_Char STR[] = T("2010-12-31+06:33");
UT_ASSERT(ParseWSManDatetime(STR, &x) == 0);
UT_ASSERT(x.isTimestamp == 1);
UT_ASSERT(x.u.timestamp.year == 2010);
UT_ASSERT(x.u.timestamp.month == 12);
UT_ASSERT(x.u.timestamp.day == 31);
UT_ASSERT(x.u.timestamp.hour == 0);
UT_ASSERT(x.u.timestamp.minute == 0);
UT_ASSERT(x.u.timestamp.second == 0);
UT_ASSERT(x.u.timestamp.microseconds == 0);
UT_ASSERT(x.u.timestamp.utc == 393);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, STR) == 0);
}
{
MI_Datetime x;
const MI_Char STR[] = T("2010-12-31-06:20");
UT_ASSERT(ParseWSManDatetime(STR, &x) == 0);
UT_ASSERT(x.isTimestamp == 1);
UT_ASSERT(x.u.timestamp.year == 2010);
UT_ASSERT(x.u.timestamp.month == 12);
UT_ASSERT(x.u.timestamp.day == 31);
UT_ASSERT(x.u.timestamp.hour == 0);
UT_ASSERT(x.u.timestamp.minute == 0);
UT_ASSERT(x.u.timestamp.second == 0);
UT_ASSERT(x.u.timestamp.microseconds == 0);
UT_ASSERT(x.u.timestamp.utc == -380);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, STR) == 0);
}
{
MI_Datetime x;
const MI_Char STR[] = T("2010-12-31");
UT_ASSERT(ParseWSManDatetime(STR, &x) == 0);
UT_ASSERT(x.isTimestamp == 1);
UT_ASSERT(x.u.timestamp.year == 2010);
UT_ASSERT(x.u.timestamp.month == 12);
UT_ASSERT(x.u.timestamp.day == 31);
UT_ASSERT(x.u.timestamp.hour == 0);
UT_ASSERT(x.u.timestamp.minute == 0);
UT_ASSERT(x.u.timestamp.second == 0);
UT_ASSERT(x.u.timestamp.microseconds == 0);
UT_ASSERT(x.u.timestamp.utc == 0);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, STR) == 0);
}
{
MI_Datetime x;
UT_ASSERT(ParseWSManDatetime(T("2010-12-31T12:30:03Z"), &x) == 0);
UT_ASSERT(x.isTimestamp == 1);
UT_ASSERT(x.u.timestamp.year == 2010);
UT_ASSERT(x.u.timestamp.month == 12);
UT_ASSERT(x.u.timestamp.day == 31);
UT_ASSERT(x.u.timestamp.hour == 12);
UT_ASSERT(x.u.timestamp.minute == 30);
UT_ASSERT(x.u.timestamp.second == 03);
UT_ASSERT(x.u.timestamp.microseconds == 0);
UT_ASSERT(x.u.timestamp.utc == 0);
}
{
MI_Datetime x;
const MI_Char STR[] = T("2010-12-31T12:30:03+06:23");
UT_ASSERT(ParseWSManDatetime(STR, &x) == 0);
UT_ASSERT(x.isTimestamp == 1);
UT_ASSERT(x.u.timestamp.year == 2010);
UT_ASSERT(x.u.timestamp.month == 12);
UT_ASSERT(x.u.timestamp.day == 31);
UT_ASSERT(x.u.timestamp.hour == 12);
UT_ASSERT(x.u.timestamp.minute == 30);
UT_ASSERT(x.u.timestamp.second == 03);
UT_ASSERT(x.u.timestamp.microseconds == 0);
UT_ASSERT(x.u.timestamp.utc == 383);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, STR) == 0);
}
{
MI_Datetime x;
const MI_Char STR[] = T("12:30:03+06:23");
UT_ASSERT(ParseWSManDatetime(STR, &x) == 0);
UT_ASSERT(x.isTimestamp == 1);
UT_ASSERT(x.u.timestamp.year == 0);
UT_ASSERT(x.u.timestamp.month == 0);
UT_ASSERT(x.u.timestamp.day == 0);
UT_ASSERT(x.u.timestamp.hour == 12);
UT_ASSERT(x.u.timestamp.minute == 30);
UT_ASSERT(x.u.timestamp.second == 03);
UT_ASSERT(x.u.timestamp.microseconds == 0);
UT_ASSERT(x.u.timestamp.utc == 383);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, STR) == 0);
}
{
MI_Datetime x;
const MI_Char STR[] = T("12:30:03.1234567+06:23");
UT_ASSERT(ParseWSManDatetime(STR, &x) == 0);
UT_ASSERT(x.isTimestamp == 1);
UT_ASSERT(x.u.timestamp.year == 0);
UT_ASSERT(x.u.timestamp.month == 0);
UT_ASSERT(x.u.timestamp.day == 0);
UT_ASSERT(x.u.timestamp.hour == 12);
UT_ASSERT(x.u.timestamp.minute == 30);
UT_ASSERT(x.u.timestamp.second == 03);
UT_ASSERT(x.u.timestamp.microseconds == 123456);
UT_ASSERT(x.u.timestamp.utc == 383);
//PrintDatetime(&x);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, T("12:30:03.123456+06:23")) == 0);
}
{
MI_Datetime x;
const MI_Char STR[] = T("2010-12-31T12:30:03.123456+06:23");
UT_ASSERT(ParseWSManDatetime(STR, &x) == 0);
UT_ASSERT(x.isTimestamp == 1);
UT_ASSERT(x.u.timestamp.year == 2010);
UT_ASSERT(x.u.timestamp.month == 12);
UT_ASSERT(x.u.timestamp.day == 31);
UT_ASSERT(x.u.timestamp.hour == 12);
UT_ASSERT(x.u.timestamp.minute == 30);
UT_ASSERT(x.u.timestamp.second == 03);
UT_ASSERT(x.u.timestamp.microseconds == 123456);
UT_ASSERT(x.u.timestamp.utc == 383);
//PrintDatetime(&x);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, STR) == 0);
}
{
MI_Datetime x;
UT_ASSERT(ParseWSManDatetime( T("P4294967295D"), &x) == 0);
UT_ASSERT(x.isTimestamp == 0);
UT_ASSERT(x.u.interval.days == 4294967295U);
UT_ASSERT(x.u.interval.hours == 0);
UT_ASSERT(x.u.interval.minutes == 0);
UT_ASSERT(x.u.interval.seconds == 0);
UT_ASSERT(x.u.interval.microseconds == 0);
FormatWSManDatetime(&x, buf);
UT_ASSERT(Zcmp(buf, T("P4294967295D")) == 0);
}
}
typedef struct _TestBucket /* derives from HashBucket */
{
struct _TestBucket* next;
char* key;
long data;
}
TestBucket;
static size_t TestHash(
const HashBucket* bucket_)
{
/* Note: this algorithm has a poor distribution */
TestBucket* bucket = (TestBucket*)bucket_;
size_t h = 0;
char* key = bucket->key;
while (*key)
{
h += 5 * *key++;
}
return h;
}
static int TestEqual(
const HashBucket* bucket1_,
const HashBucket* bucket2_)
{
TestBucket* bucket1 = (TestBucket*)bucket1_;
TestBucket* bucket2 = (TestBucket*)bucket2_;
return strcmp(bucket1->key, bucket2->key) == 0;
}
static void TestRelease(
HashBucket* bucket_)
{
TestBucket* bucket = (TestBucket*)bucket_;
free(bucket->key);
free(bucket);
}
static void TestHashTable1()
{
HashTable table;
int r;
TestBucket* b;
r = HashTable_Init(&table, 1, TestHash, TestEqual, TestRelease);
UT_ASSERT(r == 0);
/* Insert some buckets */
{
/* Insert RED=1 */
{
b = (TestBucket*)calloc(1, sizeof(TestBucket));
UT_ASSERT(b != 0);
b->key = strdup("RED");
b->data = 1;
r = HashTable_Insert(&table, (HashBucket*)b);
UT_ASSERT(r == 0);
}
/* Insert GREEN=2 */
{
b = (TestBucket*)calloc(1, sizeof(TestBucket));
UT_ASSERT(b != 0);
b->key = strdup("GREEN");
b->data = 2;
r = HashTable_Insert(&table, (HashBucket*)b);
UT_ASSERT(r == 0);
}
/* Insert BLUE=3 */
{
b = (TestBucket*)calloc(1, sizeof(TestBucket));
UT_ASSERT(b != 0);
b->key = strdup("BLUE");
b->data = 3;
r = HashTable_Insert(&table, (HashBucket*)b);
UT_ASSERT(r == 0);
/* Insert BLUE=3 again (should fail) */
r = HashTable_Insert(&table, (HashBucket*)b);
UT_ASSERT(r == 1);
}
/* Find RED=1 */
{
TestBucket key;
key.key = (char*)"RED";
b = (TestBucket*)HashTable_Find(&table, (const HashBucket*)&key);
UT_ASSERT(b != 0);
UT_ASSERT(strcmp(b->key, "RED") == 0);
UT_ASSERT(b->data == 1);
}
/* Find GREEN=2 */
{
TestBucket key;
key.key = (char*)"GREEN";
b = (TestBucket*)HashTable_Find(&table, (const HashBucket*)&key);
UT_ASSERT(b != 0);
UT_ASSERT(strcmp(b->key, "GREEN") == 0);
UT_ASSERT(b->data == 2);
}
/* Find BLUE=3 */
{
TestBucket key;
key.key = (char*)"BLUE";
b = (TestBucket*)HashTable_Find(&table, (const HashBucket*)&key);
UT_ASSERT(b != 0);
UT_ASSERT(strcmp(b->key, "BLUE") == 0);
UT_ASSERT(b->data == 3);
}
/* Find YELLOW=4 (should fail) */
{
TestBucket key;
key.key = (char*)"YELLOW";
b = (TestBucket*)HashTable_Find(&table, (const HashBucket*)&key);
UT_ASSERT(b == 0);
}
/* Remove RED */
{
TestBucket key;
key.key = (char*)"RED";
r = HashTable_Remove(&table, (const HashBucket*)&key);
UT_ASSERT(r == 0);
/* Remove should fail now */
r = HashTable_Remove(&table, (const HashBucket*)&key);
UT_ASSERT(r == -1);
}
/* Remove GREEN */
{
TestBucket key;
key.key = (char*)"GREEN";
r = HashTable_Remove(&table, (const HashBucket*)&key);
UT_ASSERT(r == 0);
/* Remove should fail now */
r = HashTable_Remove(&table, (const HashBucket*)&key);
UT_ASSERT(r == -1);
}
/* Remove BLUE */
{
TestBucket key;
key.key = (char*)"BLUE";
r = HashTable_Remove(&table, (const HashBucket*)&key);
UT_ASSERT(r == 0);
/* Remove should fail now */
r = HashTable_Remove(&table, (const HashBucket*)&key);
UT_ASSERT(r == -1);
}
/* Remove YELLOW (should fail) */
{
TestBucket key;
key.key = (char*)"YELLOW";
r = HashTable_Remove(&table, (const HashBucket*)&key);
UT_ASSERT(r == -1);
}
}
/* Release all the memroy */
HashTable_Destroy(&table);
}
static void TestHashTable2()
{
HashTable table;
int r;
size_t i;
const size_t N = 10000;
/* Create the hash table */
r = HashTable_Init(&table, 63, TestHash, TestEqual, TestRelease);
UT_ASSERT(r == 0);
/* Insert N buckets into hash table */
for (i = 0; i < N; i++)
{
char buf[32];
TestBucket* b;
Szprintf(buf, sizeof(buf), "%u", (unsigned int)i);
b = (TestBucket*)calloc(1, sizeof(TestBucket));
UT_ASSERT(b != 0);
b->key = strdup(buf);
b->data = (long)i;
r = HashTable_Insert(&table, (HashBucket*)b);
UT_ASSERT(r == 0);
}
/* Verify that each number is in the hash table */
for (i = 0; i < N; i++)
{
char buf[32];
TestBucket* b;
TestBucket kb;
kb.key = buf;
Szprintf(buf, sizeof(buf), "%u", (unsigned int)i);
/* Find it */
b = (TestBucket*)HashTable_Find(&table, (const HashBucket*)&kb);
UT_ASSERT(b != 0);
/* Check it */
UT_ASSERT(strcmp(b->key, buf) == 0);
}
/* Delete all the buckets */
for (i = 0; i < N; i++)
{
char buf[32];
TestBucket kb;
int r;
kb.key = buf;
Szprintf(buf, sizeof(buf), "%u", (unsigned int)i);
/* Find it */
r = HashTable_Remove(&table, (const HashBucket*)&kb);
UT_ASSERT(r == 0);
}
/* Release all the memroy */
HashTable_Destroy(&table);
}
static void RunTests()
{
UT_TEST(TestHashTable1);
UT_TEST(TestHashTable2);
UT_TEST(TestAllocator1);
UT_TEST(TestAllocator2);
UT_TEST(TestAllocator3);
UT_TEST(TestGetName);
UT_TEST(TestGetSize);
UT_TEST(TestStringArray1);
UT_TEST(TestStringArray2);
UT_TEST(TestMessages);
UT_TEST(TestMessages2);
UT_TEST(TestStrings);
UT_TEST(TestList);
UT_TEST(TestFindClassDecl);
UT_TEST(TestAllTypes);
#if 0
UT_TEST(TestLib1);
UT_TEST(TestLib2);
#endif
UT_TEST(TestInstances);
UT_TEST(TestDynamicInstances);
UT_TEST(TestBuf);
UT_TEST(TestBuf2);
UT_TEST(TestBuf3);
UT_TEST(TestBuf4);
UT_TEST(TestPackInstance);
UT_TEST(TestPage);
UT_TEST(TestBaseCppAllTypes);
UT_TEST(TestDir);
UT_TEST(TestStrArr);
UT_TEST(TestConf1);
UT_TEST(TestConf2);
UT_TEST(TestMkdirhier);
UT_TEST(TestLog);
UT_TEST(TestIntToStr);
UT_TEST(TestGetOpt);
UT_TEST(TestGetOptErr);
UT_TEST(TestMatchKeys);
UT_ENTRY_POINT(TestWSManDatetime);
}
UT_ENTRY_POINT(RunTests);