From 777a4a9be8f909648d05d6644624e822aeca8423 Mon Sep 17 00:00:00 2001 From: Asanka Herath Date: Sun, 26 Jul 2009 10:16:33 -0400 Subject: [PATCH] Windows: Tests for afsd modules Add test routines for internationalization routines. LICENSE MIT Reviewed-on: http://gerrit.openafs.org/218 Tested-by: Jeffrey Altman Reviewed-by: Jeffrey Altman --- src/WINNT/afsd/NTMakefile | 23 ++ src/WINNT/afsd/test/btreetest.c | 258 +++++++++++++++++++++++ src/WINNT/afsd/test/convtest.c | 339 ++++++++++++++++++++++++++++++ src/WINNT/afsd/test/stricmptest.c | 102 +++++++++ 4 files changed, 722 insertions(+) create mode 100644 src/WINNT/afsd/test/btreetest.c create mode 100644 src/WINNT/afsd/test/convtest.c create mode 100644 src/WINNT/afsd/test/stricmptest.c diff --git a/src/WINNT/afsd/NTMakefile b/src/WINNT/afsd/NTMakefile index 5a59510d1..4db2f54cd 100644 --- a/src/WINNT/afsd/NTMakefile +++ b/src/WINNT/afsd/NTMakefile @@ -514,3 +514,26 @@ clean:: $(DEL) $(LOGON_DLLFILE) mkdir: + +############################################################################ +# Tests + +{test}.c{$(OUT)\}.obj: + $(C2OBJ) $< + +test:: + +test:: btreetest + +btreetest: "$(OUT)\btreetest.exe" + "$(OUT)\btreetest.exe" + +$(OUT)\btreetest.exe: \ + $(OUT)\btreetest.obj \ + $(OUT)\cm_btree.obj \ + $(OUT)\cm_nls.obj \ + $(OUT)\cm_utils.obj \ + $(DESTDIR)\lib\libosi.lib + $(EXECONLINK) + $(_VC_MANIFEST_EMBED_EXE) + $(EXEPREP) diff --git a/src/WINNT/afsd/test/btreetest.c b/src/WINNT/afsd/test/btreetest.c new file mode 100644 index 000000000..ebe1e138c --- /dev/null +++ b/src/WINNT/afsd/test/btreetest.c @@ -0,0 +1,258 @@ +#include +#include +#include +#include + +#include "..\afsd.h" + +#define paste(a,b) a ## b +#define _L(a) paste(L,a) + +#define TRACE1 wprintf + +/* Setup and Fakery ... */ +osi_log_t * afsd_logp; + +void cm_SetFid(cm_fid_t *fidp, afs_uint32 cell, afs_uint32 volume, afs_uint32 vnode, afs_uint32 unique) +{ + fidp->cell = cell; + fidp->volume = volume; + fidp->vnode = vnode; + fidp->unique = unique; + fidp->hash = ((cell & 0xF) << 28) | ((volume & 0x3F) << 22) | ((vnode & 0x7FF) << 11) | (unique & 0x7FF); +} + +cm_scache_t *cm_FindSCache(cm_fid_t *fidp) +{ + return NULL; +} + +void cm_ReleaseSCache(cm_scache_t *scp) +{ +} + + +long cm_ApplyDir(cm_scache_t *scp, cm_DirFuncp_t funcp, void *parmp, + osi_hyper_t *startOffsetp, cm_user_t *userp, cm_req_t *reqp, + cm_scache_t **retscp) +{ + return 0; +} + +void +afsi_log(char *pattern, ...) +{ + char s[256], t[100], d[100], u[512]; + va_list ap; + va_start(ap, pattern); + + StringCbVPrintfA(s, sizeof(s), pattern, ap); + GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t)); + GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, d, sizeof(d)); + StringCbPrintfA(u, sizeof(u), "%s %s: %s\r\n", d, t, s); + printf("%s", u); +} + + +static int initialize_tests(void) +{ + osi_Init(); + cm_InitNormalization(); + + if (!cm_InitBPlusDir()) { + TRACE1(L"Can't initialize BPlusDir\n"); + return 1; + } + + afsd_logp = osi_LogCreate("fakelog", 100); + + return 0; +} + +int n_succeeded = 0; +int n_failed = 0; + +int n_subSucceeded = 0; +int n_subFailed = 0; + +static int runtest(wchar_t * testname, int (*f)(void)) +{ + int rv = 0; + + n_subSucceeded = 0; + n_subFailed = 0; + + TRACE1(L"Begin test %s\n", testname); + f(); + TRACE1(L"End test %s\n", testname); + TRACE1(L"Subtests Succeeded %d, Failed %d\n", n_subSucceeded, n_subFailed); + + if (n_subFailed) + n_failed++; + else + n_succeeded++; + + return rv; +} + +#define RUNTEST(f) runtest(_L(#f), f) + +#define IS_NOT_NULL(v) (((v) != NULL)? n_subSucceeded++: (TRACE1(L"Failed %s\n", _L(#v)), n_subFailed++)) +#define IS(e) ((e)? n_subSucceeded++ : (TRACE1(L"Failed %s\n", _L(#e)), n_subFailed++)) +#define CHECK_IF(e) do { if (e) { n_subSucceeded++; } else { TRACE1(L"Failed %s\n", _L(#e)); n_subFailed++; return 1; }} while (0) + +/**************************************************************/ +/* Actual tests */ + +struct strings { + const fschar_t * str; + const clientchar_t * lookup; + int rc; +}; + +struct strings simple[] = { + {"abc", L"ABC", CM_ERROR_INEXACT_MATCH}, + {"A", L"A", 0}, + {".", L".", 0}, + {"567", L"567", 0}, + {"b", L"B", CM_ERROR_INEXACT_MATCH}, + {"d", L"D", CM_ERROR_INEXACT_MATCH}, + {"àáâ", L"\x00c0\x00c1\x00c2", CM_ERROR_INEXACT_MATCH}, + {"Ŷ", L"\x0177", CM_ERROR_INEXACT_MATCH}, + {"a\xef\xac\xb4",L"a\xfb34",0}, + {"b\xd7\x94\xd6\xbc",L"b\xfb34",0}, + {"c\xef\xac\xb4",L"c\x05d4\x05bc",0}, + {"d\xd7\x94\xd6\xbc",L"d\x05d4\x05bc",0}, +}; + +void init_scache(cm_scache_t * scp, cm_fid_t * fidp) +{ + memset(scp, 0, sizeof(cm_scache_t)); + scp->magic = CM_SCACHE_MAGIC; + lock_InitializeRWLock(&scp->rw, "cm_scache_t rw"); + lock_InitializeRWLock(&scp->bufCreateLock, "cm_scache_t bufCreateLock"); + lock_InitializeRWLock(&scp->dirlock, "cm_scache_t dirlock"); + scp->serverLock = -1; + scp->fid = *fidp; + scp->refCount = 1; +} + +int simple_test(void) +{ + Tree * t; + int i; + + t = initBtree(64, MAX_FANOUT, cm_BPlusCompareNormalizedKeys); + CHECK_IF(t != NULL); + + for (i=0; i < lengthof(simple); i++) { + normchar_t * norm; + keyT key; + dataT data; + + norm = cm_FsStringToNormStringAlloc(simple[i].str, -1, NULL); + CHECK_IF(norm != NULL); + + key.name = norm; + + data.cname = cm_FsStringToClientStringAlloc(simple[i].str, -1, NULL); + data.fsname = cm_FsStrDup(simple[i].str); + data.shortform = FALSE; + cm_SetFid(&data.fid, 1, 2, i, 4); + + insert(t, key, data); + + if (!cm_Is8Dot3(data.cname)) { + wchar_t wshortName[13]; + cm_dirFid_t dfid; + + dfid.vnode = i; + dfid.unique = 0; + + cm_Gen8Dot3NameIntW(data.cname, &dfid, wshortName, NULL); + + key.name = wshortName; + data.cname = cm_FsStringToClientStringAlloc(simple[i].str, -1, NULL); + data.fsname = cm_FsStrDup(simple[i].str); + data.shortform = TRUE; + + insert(t, key, data); + } + + free(norm); + } + + for (i=0; i < lengthof(simple); i++) { + int rc = EINVAL; + normchar_t * entry = NULL; + keyT key = {NULL}; + Nptr leafNode = NONODE; + cm_fid_t fid; + cm_fid_t * cfid = &fid; + + TRACE1(L"Test row %d\n", i); + + entry = cm_ClientStringToNormStringAlloc(simple[i].lookup, -1, NULL); + key.name = entry; + + leafNode = bplus_Lookup(t, key); + if (leafNode != NONODE) { + int slot; + Nptr firstDataNode, dataNode, nextDataNode; + int exact = 0; + int count = 0; + + slot = getSlot(t, leafNode); + if (slot <= BTERROR) { + rc = (slot == BTERROR ? EINVAL : ENOENT); + goto done; + } + firstDataNode = getnode(leafNode, slot); + + for ( dataNode = firstDataNode; dataNode; dataNode = nextDataNode) { + count++; + if (!comparekeys(t)(key, getdatakey(dataNode), EXACT_MATCH) ) { + exact = 1; + break; + } + nextDataNode = getdatanext(dataNode); + } + + if (exact) { + *cfid = getdatavalue(dataNode).fid; + rc = 0; + } else if (count == 1) { + *cfid = getdatavalue(firstDataNode).fid; + rc = CM_ERROR_INEXACT_MATCH; + } else { + rc = CM_ERROR_AMBIGUOUS_FILENAME; + } + } else { + rc = ENOENT; + } + + done: + if (entry) + free(entry); + + IS(rc == simple[i].rc); + if (rc == simple[i].rc) + IS(fid.vnode == i); + } +} + + +int wmain(int argc, wchar_t ** argv) +{ + TRACE1(L"\n\nRunning BPLUS tests...\n\n"); + if (initialize_tests()) + return 1; + + RUNTEST(simple_test); + + TRACE1(L"\nDone\n"); + TRACE1(L"# of test Succeeded: %d\n", n_succeeded); + TRACE1(L"# of test Failed: %d\n", n_failed); + + return 0; +} diff --git a/src/WINNT/afsd/test/convtest.c b/src/WINNT/afsd/test/convtest.c new file mode 100644 index 000000000..f30f06182 --- /dev/null +++ b/src/WINNT/afsd/test/convtest.c @@ -0,0 +1,339 @@ +#include +#include +#include "..\cm_nls.h" + +#define elements_in(a) (sizeof(a)/sizeof(a[0])) + +struct norm_pair { + const cm_unichar_t * left; + const cm_normchar_t * right; +}; + +struct norm_pair normalization_pairs[] = { + { L"abcdefghijklmnopq", L"abcdefghijklmnopq" }, + { L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234", + + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" + L"abcdefghijklmnopqrstuvwxyz1234" }, + { L"12839481flalfoo_)()(*&#@(*&", + L"12839481flalfoo_)()(*&#@(*&" } +}; + +void dumputf8(const unsigned char * s) { + while (*s) { + printf("%02X ", (int) *s++); + } +} + +void dumpunicode(const wchar_t * s) { + while (*s) { + printf("%04X ", (int) *s++); + } +} + +int cm_NormalizeStringAllocTest(void) +{ + int i; + + for (i=0; i < elements_in(normalization_pairs); i++) { + cm_normchar_t * nstr; + int cchdest = 0; + + printf ("Test #%d:", i); + + nstr = cm_NormalizeStringAlloc(normalization_pairs[i].left, -1, &cchdest); + + if (nstr == NULL) { + printf ("FAILED! returned a NULL\n"); + return 1; + } + + if (wcscmp(nstr, normalization_pairs[i].right)) { + printf ("FAILED: Expected ["); + dumpunicode(normalization_pairs[i].right); + printf ("] Received ["); + dumpunicode(nstr); + printf ("]\n"); + return 1; + } + + if (wcslen(nstr) != cchdest - 1) { + printf ("FAILED: Length is wrong\n"); + return 1; + } + + printf ("PASS\n"); + + free (nstr); + } + + return 0; +} + +typedef struct norm_test_entry { + const wchar_t * str; + const wchar_t * nfc; + const wchar_t * nfd; + const wchar_t * nfkc; + const wchar_t * nfkd; +} norm_test_entry; + +extern norm_test_entry norm_tests[]; +extern int n_norm_tests; + +int cm_NormalizeStringTest(void) +{ + int i; + int n_failed = 0; + + for (i=0; i < n_norm_tests; i++) { + cm_normchar_t * nfc; + + nfc = cm_NormalizeStringAlloc(norm_tests[i].nfd, -1, NULL); + if (nfc == NULL) { + printf ("FAILED: returned a NULL\n"); + return 1; + } + + if (wcscmp(nfc, norm_tests[i].nfc)) { + printf ("FAILED: Expected ["); + dumpunicode(norm_tests[i].nfc); + printf ("] Received ["); + dumpunicode(nfc); + printf ("]\n"); + n_failed ++; + } + + free(nfc); + } + + if (n_failed) + printf ("Number of failed tests: %d\n", n_failed); + + return 0; +} + +typedef struct conv_test_entry { + const cm_utf8char_t * str; + const cm_unichar_t * wstr; +} conv_test_entry; + +#define CTEST(a) { a, L ## a } + +conv_test_entry conv_tests[] = { + CTEST(""), + CTEST("a"), + CTEST("abcdefghijkl"), + CTEST("osidfja*(2312835"), + {"\xee\x80\x80", L"\xe000"}, + {"\xef\xbf\xbd", L"\xfffd"}, + {"\xf0\x9f\xbf\xbf", L"\xd83f\xdfff"}, /* Surrogates */ + {"\xF1\x9F\xBF\xBE", L"\xD93F\xDFFE"}, + {"\xf0\x90\x80\x80", L"\xd800\xdc00"}, +}; + +int cm_Utf16ToUtf8AllocTest(void) +{ + int i; + + for (i=0; i < sizeof(conv_tests)/sizeof(conv_tests[0]); i++) { + cm_utf8char_t * c; + int len = 0; + + printf ("Test #%d:", i); + + c = cm_Utf16ToUtf8Alloc(conv_tests[i].wstr, -1, &len); + + if (c == NULL) { + printf ("FAILED: returned NULL\n"); + return 1; + } + + if (strlen(c) + 1 != len) { + printf ("FAILED: Returned wrong length [%d]. Actual length [%d]\n", len, + strlen(c) + 1); + return 1; + } + + if (strcmp(c, conv_tests[i].str)) { + printf ("FAILED: Expected ["); + dumputf8(conv_tests[i].str); + printf ("]. Returned ["); + dumputf8(c); + printf ("]\n"); + return 1; + } + + printf("PASS\n"); + + free(c); + } + + return 0; +} + +int cm_Utf16ToUtf8Test(void) +{ + int i; + cm_utf8char_t c[1024]; + + for (i=0; i < sizeof(conv_tests)/sizeof(conv_tests[0]); i++) { + int len; + + printf ("Test #%d:", i); + + len = cm_Utf16ToUtf8(conv_tests[i].wstr, -1, c, sizeof(c)/sizeof(c[0])); + + if (len == 0) { + printf ("FAILED: returned 0\n"); + return 1; + } + + if (strlen(c) + 1 != len) { + printf ("FAILED: Returned wrong length [%d]. Actual length [%d]\n", len, + strlen(c) + 1); + return 1; + } + + if (strcmp(c, conv_tests[i].str)) { + printf ("FAILED: Expected [%s]. Returned [%s]\n", conv_tests[i].str, c); + return 1; + } + + printf("PASS\n"); + } + + return 0; +} + +int cm_Utf8ToUtf16AllocTest(void) +{ + int i; + + for (i=0; i < sizeof(conv_tests)/sizeof(conv_tests[0]); i++) { + cm_unichar_t * c; + int len = 0; + + printf ("Test #%d:", i); + + c = cm_Utf8ToUtf16Alloc(conv_tests[i].str, -1, &len); + + if (c == NULL) { + printf ("FAILED: returned NULL\n"); + return 1; + } + + if (wcslen(c) + 1 != len) { + printf ("FAILED: Returned wrong length [%d]. Actual length [%d]\n", len, + wcslen(c) + 1); + return 1; + } + + if (wcscmp(c, conv_tests[i].wstr)) { + printf ("FAILED: Expected ["); + dumpunicode(conv_tests[i].wstr); + printf ("]. Returned ["); + dumpunicode(c); + printf ("]\n"); + return 1; + } + + printf("PASS\n"); + + free(c); + } + + return 0; +} + +int cm_Utf8ToUtf16Test(void) +{ + int i; + cm_unichar_t c[1024]; + + for (i=0; i < sizeof(conv_tests)/sizeof(conv_tests[0]); i++) { + int len = 0; + + printf ("Test #%d:", i); + + len = cm_Utf8ToUtf16(conv_tests[i].str, -1, c, sizeof(c)/sizeof(c[0])); + + if (len == 0) { + printf ("FAILED: returned 0\n"); + return 1; + } + + if (wcslen(c) + 1 != len) { + printf ("FAILED: Returned wrong length [%d]. Actual length [%d]\n", len, + wcslen(c) + 1); + return 1; + } + + if (wcscmp(c, conv_tests[i].wstr)) { + printf ("FAILED: Expected ["); + dumpunicode(conv_tests[i].wstr); + printf ("]. Returned ["); + dumpunicode(c); + printf ("]\n"); + return 1; + } + + printf("PASS\n"); + } + + return 0; +} + +int main(int argc, char ** argv) +{ + int trv; + + cm_InitNormalization(); + +#define RUNTEST(f) printf("Begin " #f "\n"); trv = f(); printf ("End " #f "\n\n"); if (trv != 0) return trv; + + RUNTEST(cm_NormalizeStringAllocTest); + RUNTEST(cm_NormalizeStringTest); + RUNTEST(cm_Utf16ToUtf8AllocTest); + RUNTEST(cm_Utf16ToUtf8Test); + RUNTEST(cm_Utf8ToUtf16AllocTest); + RUNTEST(cm_Utf8ToUtf16Test); + return 0; +} diff --git a/src/WINNT/afsd/test/stricmptest.c b/src/WINNT/afsd/test/stricmptest.c new file mode 100644 index 000000000..1f13d792d --- /dev/null +++ b/src/WINNT/afsd/test/stricmptest.c @@ -0,0 +1,102 @@ +#include +#include +#include +#include "..\cm_nls.h" + +typedef struct wtest_pair { + const wchar_t * str1; + const wchar_t * str2; + int comparison_result; +} wtest_pair; + +wtest_pair wtest_pairs[] = { + { L"abc", L"aBc", 0 }, + { L"Abc", L"Acb", -1 }, + { L"", L"", 0 }, + { L"", L"", 0 }, + { L"", L"", 0 }, + { L"", L"", 0 }, + { L"", L"", 0 }, + { L"", L"", 0 }, +}; + +typedef struct utf8test_pair { + const char * str1; + const char * str2; + int comparison_result; +} utf8test_pair; + +utf8test_pair utf8test_pairs[] = { + {"abc", "abc", 0}, + {"abc", "AbC", 0}, + {"abc", "ABC", 0}, + {"ÆOn", "æoN", 0}, + {"Ǽaaa", "ǽaaa", 0}, + {"Ằ ", "ằ ", 0}, + {"Ĺ378", "ĺ378", 0}, + {"Abc", "Acb", -1}, + {"ǼaEa", "ǽaaa", 1}, + {"ùÒz±", "ÙòZ±", 0}, + {"ÀÁÂÃÄÅÆÇÈÉÊË", "àáâãäåæçèéêë", 0}, + {"", "", 0}, + {"", "", 0}, +}; + +int wmain(int argc, wchar_t ** argv) +{ + + int i; + + printf("Starting test--\n"); + for (i=0; i= str; p = char_prev_utf8(p)) { + printf ("Char %d at offset %d\n", i--, p-str); + } + + } + printf("End of test\n"); + + printf("Strupr test\n"); + for (i=0; i[%s]", utf8test_pairs[i].str1, tbuf); + + strcpy(tbuf, utf8test_pairs[i].str2); + strupr_utf8(tbuf, sizeof(tbuf)); + printf(" [%s]->[%s]\n", utf8test_pairs[i].str2, tbuf); + } + printf("End of test\n"); + + return 0; +} -- 2.39.5