/**
 * Simple redis RESP protocol ping test:
 *
 *     1. send a PING command
 *     2. expect a PONG response
 *     3. send a QUIT command
 *
 * @see http://redis.io/topics/protocol
 *
 * @file
 */
void check_redis(Socket_T socket) {
        ASSERT(socket);
        char buf[STRLEN];

        if (Socket_print(socket, "*1\r\n$4\r\nPING\r\n") < 0)
                THROW(IOException, "REDIS: PING command error -- %s", STRERROR);
        if (! Socket_readLine(socket, buf, sizeof(buf)))
                THROW(IOException, "REDIS: PING response error -- %s", STRERROR);
        Str_chomp(buf);
        if (! Str_isEqual(buf, "+PONG") && ! Str_startsWith(buf, "-NOAUTH")) // We accept authentication error (-NOAUTH Authentication required): redis responded to request, but requires authentication => we assume it works
                THROW(IOException, "REDIS: PING error -- %s", buf);
        if (Socket_print(socket, "*1\r\n$4\r\nQUIT\r\n") < 0)
                THROW(IOException, "REDIS: QUIT command error -- %s", STRERROR);
}
int main(void) {
        int fd;
        InputStream_T in = NULL;

        Bootstrap(); // Need to initialize library

        printf("============> Start InputStream Tests\n\n");

        printf("=> Test0: create/destroy the stream\n");
        {
                in = InputStream_new(File_open(DATA, "r"));
                assert(!InputStream_isClosed(in));
                File_close(InputStream_getDescriptor(in));
                InputStream_free(&in);
                assert(in == NULL);
        }
        printf("=> Test0: OK\n\n");

        printf("=> Test1: get/set timeout\n");
        {
                assert((fd = File_open(DATA, "r")) >= 0);
                in = InputStream_new(fd);
                printf("\tCurrent timeout: %lldms\n", (long long)InputStream_getTimeout(in));
                InputStream_setTimeout(in, TIMEOUT);
                assert(InputStream_getTimeout(in) == TIMEOUT);
                printf("\tTimeout set to:  %dms\n", TIMEOUT);
                File_close(fd);
                InputStream_free(&in);
        }
        printf("=> Test1: OK\n\n");

        printf("=> Test2: read file by characters\n");
        {
                int byte;
                int byteno = 0;
                char content[][1] = {"l", "i", "n", "e", "1", "\n",
                                     "l", "i", "n", "e", "2", "\n",
                                     "l", "i", "n", "e", "3", "\n"};
                assert((fd = File_open(DATA, "r")) >= 0);
                in = InputStream_new(fd);
                while ((byte = InputStream_read(in)) > 0) {
                        assert(byte == *content[byteno++]);
                }
                File_close(fd);
                InputStream_free(&in);
        }
        printf("=> Test2: OK\n\n");

        printf("=> Test3: read file by lines\n");
        {
                int lineno = 0;
                char line[STRLEN];
                char content[][STRLEN] = {"line1\n", "line2\n", "line3\n"};
                assert((fd = File_open(DATA, "r")) >= 0);
                in = InputStream_new(fd);
                while (InputStream_readLine(in, line, sizeof(line))) {
                        assert(Str_isEqual(content[lineno++], line));
                }
                File_close(fd);
                InputStream_free(&in);
        }
        printf("=> Test3: OK\n\n");

        printf("=> Test4: read file by bytes\n");
        {
                char array[STRLEN];
                char content[] = "line1\nline2\nline3\n";
                memset(array, 0, STRLEN);
                assert((fd = File_open(DATA, "r")) >= 0);
                in = InputStream_new(fd);
                while (InputStream_readBytes(in, array, sizeof(array)-1)) {
                        assert(Str_isEqual(content, array));
                }
                File_close(fd);
                InputStream_free(&in);
        }
        printf("=> Test4: OK\n\n");

        printf("=> Test5: read a large file\n");
        {
                if ((fd = File_open("/usr/share/dict/words", "r")) >= 0) {
                        int n = 0;
                        char array[2][STRLEN + 1];
                        in = InputStream_new(fd);
                        for (int i = 0; ((n = InputStream_readBytes(in, array[i], STRLEN)) > 0); i = i ? 0 : 1)
                                assert(strncmp(array[0], array[1], STRLEN/2) != 0); // ensure that InputStream buffer is filled anew
                        File_rewind(fd);
                        // Test read data larger than InputStream's internal buffer
                        int filesize = (int)File_size("/usr/share/dict/words");
                        char *bigarray = CALLOC(1, filesize + 1);
                        n = InputStream_readBytes(in, bigarray, filesize);
                        assert(n == filesize);
                        File_close(fd);
                        InputStream_free(&in);
                        FREE(bigarray);
                } else 
                        ERROR("\t/usr/share/dict/words not available -- skipping test\n");
        }
        printf("=> Test5: OK\n\n");

        printf("=> Test6: wrong descriptor - expecting read fail\n");
        {
                in = InputStream_new(999);
                TRY
                        assert(InputStream_read(in) != -1);
                        printf("Test6: Failed");
                        exit(1); // Should not come here
                CATCH(AssertException)
                        // Passed
                END_TRY;
                InputStream_free(&in);
        }
        printf("=> Test6: OK\n\n");


        printf("============> InputStream Tests: OK\n\n");

        return 0;
}
Exemple #3
0
int main(void) {
        List_T L = NULL;

        Bootstrap(); // Need to initialize library

        printf("============> Start List Tests\n\n");

        printf("=> Test0: create\n");
        {
                L = List_new();
                assert(L);
                List_free(&L);
        }
        printf("=> Test0: OK\n\n");

        printf("=> Test1: List_push() & List_length()\n");
        {
                L = List_new();
                List_push(L, "1");
                List_push(L, "2");
                List_push(L, "3");
                List_push(L, "4");
                List_push(L, "5");
                List_push(L, "6");
                List_push(L, "7");
                List_push(L, "8");
                List_push(L, "9");
                List_push(L, "10");
                List_push(L, "11");
                List_push(L, "12");
                List_push(L, "13");
                List_push(L, "14");
                List_push(L, "15");
                assert(Str_isEqual(L->tail->e, "1"));
                assert(Str_isEqual(L->head->e, "15"));
                assert(List_length(L) == 15);
        }
        printf("=> Test1: OK\n\n");

        printf("=> Test2: List_pop()\n");
        {
                int i= 0;
                list_t p;
                while (List_pop(L)) ;
                assert(List_length(L) == 0);
                // Ensure that nodes are retained in the freelist
                for (p= L->freelist; p; p= p->next) i++;
                assert(i == 15);
                List_free(&L);
        }
        printf("=> Test2: OK\n\n");

        printf("=> Test3: List_append()\n");
        {
                L = List_new();
                List_append(L, "1");
                List_append(L, "2");
                List_append(L, "3");
                List_append(L, "4");
                List_append(L, "5");
                List_append(L, "6");
                List_append(L, "7");
                List_append(L, "8");
                List_append(L, "9");
                List_append(L, "10");
                List_append(L, "11");
                List_append(L, "12");
                List_append(L, "13");
                List_append(L, "14");
                List_append(L, "15");
                assert(Str_isEqual(L->tail->e, "15"));
                assert(Str_isEqual(L->head->e, "1"));
                assert(List_length(L) == 15);
        }
        printf("=> Test3: OK\n\n");

        printf("=> Test4: List_cat()\n");
        {
                List_T t= List_new();
                List_append(t, "a");
                List_append(t, "b");
                List_append(t, "c");
                List_append(t, "d");
                List_cat(L, t);
                assert(Str_isEqual(L->tail->e, "d"));
                assert(Str_isEqual(L->head->e, "1"));
                assert(List_length(L) == 19);
        }
        printf("=> Test4: OK\n\n");

        printf("=> Test5: List_reverse()\n");
        {
                list_t p;
                List_T l= List_new();
                List_append(l, "a");
                List_append(l, "b");
                List_append(l, "c");
                List_append(l, "d");
                printf("\tList before reverse: ");
                for (p= l->head; p; p= p->next)
                        printf("%s%s", (char*)p->e, p->next?"->":"\n");
                assert(Str_isEqual(l->head->e, "a"));
                assert(Str_isEqual(l->tail->e, "d"));
                List_reverse(l);
                printf("\tList after reverse: ");
                for (p= l->head; p; p= p->next)
                        printf("%s%s", (char*)p->e, p->next?"->":"\n");
                assert(Str_isEqual(l->head->e, "d"));
                assert(Str_isEqual(l->tail->e, "a"));
                List_free(&l);
        }
        printf("=> Test5: OK\n\n");

        printf("=> Test6: List_map()\n");
        {
                int i = 0;
                List_map(L, apply, &i);
                assert(i == 19);
        }
        printf("=> Test6: OK\n\n");

        printf("=> Test7: List_clear()\n");
        {
                List_clear(L);
                assert(List_length(L) == 0);
                assert(L->freelist);
        }
        printf("=> Test7: OK\n\n");

        List_free(&L);

        printf("=> Test8: List malloc\n");
        {
                L = List_new();
                List_push(L, "1");
                List_push(L, "2");
                List_push(L, "3");
                List_push(L, "4");
                List_push(L, "5");
                List_push(L, "6");
                List_push(L, "7");
                List_push(L, "8");
                List_push(L, "9");
                List_push(L, "10");
                List_push(L, "11");
                List_push(L, "12");
                List_push(L, "13");
                List_push(L, "14");
                List_push(L, "15");
                assert(Str_isEqual(L->tail->e, "1"));
                assert(Str_isEqual(L->head->e, "15"));
                assert(List_length(L) == 15);
                List_clear(L);
                List_append(L, "1");
                List_append(L, "2");
                List_append(L, "3");
                List_append(L, "4");
                List_append(L, "5");
                List_append(L, "6");
                List_append(L, "7");
                List_append(L, "8");
                List_append(L, "9");
                List_append(L, "10");
                List_append(L, "11");
                List_append(L, "12");
                List_append(L, "13");
                List_append(L, "14");
                List_append(L, "15");
                assert(Str_isEqual(L->tail->e, "15"));
                assert(Str_isEqual(L->head->e, "1"));
                assert(List_length(L) == 15);
                List_free(&L);
        }
        printf("=> Test8: OK\n\n");

        printf("=> Test9: List remove\n");
        {
                char *one = "1";
                char *two = "2";
                L = List_new();
                printf("\tRemove from empty list.. ");
                assert(List_remove(L, "1") == NULL);
                printf("OK\n");
                List_push(L, one);
                printf("\tRemove from 1 element list.. ");
                assert(List_remove(L, one) == one);
                assert(List_length(L) == 0);
                printf("OK\n");
                List_push(L, one);
                List_push(L, two);
                printf("\tRemove last from list.. ");
                assert(List_remove(L, two) == two);
                assert(List_length(L) == 1);
                printf("OK\n");
                List_append(L, two);
                List_append(L, two);
                List_append(L, two);
                List_append(L, "5");
                printf("\tRemove first occurrence.. ");
                assert(List_remove(L, two) == two);
                assert(List_length(L) == 4);
                printf("OK\n");
                List_free(&L);
        }
        printf("=> Test9: OK\n\n");

        printf("=> Test10: check pointers\n");
        {
                L = List_new();
                printf("\tCheck pop.. ");
                List_push(L, "1");
                List_push(L, "2");
                List_pop(L);
                List_pop(L);
                List_push(L, "1");
                assert(L->head == L->tail);
                List_pop(L);
                List_append(L, "1");
                assert(L->head == L->tail);
                printf("OK\n");
                printf("\tCheck remove.. ");
                List_push(L, "1");
                List_append(L, "2");
                List_remove(L, "2");
                List_remove(L, "1");
                assert(L->head == L->tail);
                printf("OK\n");
                List_free(&L);
        }
        printf("=> Test10: OK\n\n");

        printf("=> Test11: List_toArray()\n");
        {
                List_T l = List_new();
                List_append(l, "a");
                List_append(l, "b");
                List_append(l, "c");
                List_append(l, "d");
                char **array = (char**)List_toArray(l);
                assert(Str_isEqual(array[0], "a"));
                assert(Str_isEqual(array[1], "b"));
                assert(Str_isEqual(array[2], "c"));
                assert(Str_isEqual(array[3], "d"));
                assert(array[4] == NULL);
                FREE(array);
                List_free(&l);
        }
        printf("=> Test11: OK\n\n");

        printf("============> List Tests: OK\n\n");

        return 0;
}
int main(void) {
        StringBuffer_T sb;

        Bootstrap(); // Need to initialize library

        printf("============> Start StringBuffer Tests\n\n");

        printf("=> Test1: create/destroy\n");
        {
                sb= StringBuffer_new("");
                assert(sb);
                assert(StringBuffer_length(sb)==0);
                StringBuffer_free(&sb);
                assert(sb==NULL);
                sb= StringBuffer_create(1024);
                assert(sb);
                StringBuffer_free(&sb);
                assert(sb==NULL);
        }
        printf("=> Test1: OK\n\n");

        printf("=> Test2: Append NULL value\n");
        {
                sb= StringBuffer_new("");
                assert(sb);
                StringBuffer_append(sb, NULL);
                assert(StringBuffer_length(sb)==0);
                StringBuffer_free(&sb);
                assert(sb==NULL);
        }
        printf("=> Test2: OK\n\n");

        printf("=> Test3: Create with string\n");
        {
                sb= StringBuffer_new("abc");
                assert(sb);
                assert(StringBuffer_length(sb)==3);
                StringBuffer_free(&sb);
                assert(sb==NULL);
        }
        printf("=> Test3: OK\n\n");

        printf("=> Test4: Append string value\n");
        {
                sb= StringBuffer_new("abc");
                assert(sb);
                printf("\tTesting StringBuffer_append:..");
                StringBuffer_append(sb, "def");
                assert(StringBuffer_length(sb)==6);
                printf("ok\n");
                printf("\tTesting StringBuffer_vappend:..");
                append(sb, "%c%s", 'g', "hi");
                assert(StringBuffer_length(sb)==9);
                assert(Str_isEqual(StringBuffer_toString(sb), "abcdefghi"));
                printf("ok\n");
                StringBuffer_free(&sb);
                assert(sb==NULL);
        }
        printf("=> Test4: OK\n\n");

        printf("=> Test5: trim\n");
        {
                sb= StringBuffer_new("\t 'foo bar' \n ");
                assert(Str_isEqual(StringBuffer_toString(StringBuffer_trim(sb)), "'foo bar'"));
                StringBuffer_clear(sb);
                StringBuffer_append(sb, "'foo bar'");
                StringBuffer_trim(sb);
                assert(Str_isEqual(StringBuffer_toString(sb), "'foo bar'"));
                StringBuffer_clear(sb);
                StringBuffer_append(sb, "\t \r \n  ");
                assert(Str_isEqual(StringBuffer_toString(StringBuffer_trim(sb)), ""));
                StringBuffer_free(&sb);
                sb = StringBuffer_create(10);
                StringBuffer_trim(sb);
                assert(StringBuffer_toString(sb)[0] == 0);
                StringBuffer_free(&sb);
        }
        printf("=> Test5: OK\n\n");

        printf("=> Test6: deleteFrom\n");
        {
                sb= StringBuffer_new("abcdefgh");
                assert(sb);
                StringBuffer_delete(sb,3);
                assert(StringBuffer_length(sb)==3);
                StringBuffer_free(&sb);
                assert(sb==NULL);
        }
        printf("=> Test6: OK\n\n");

        printf("=> Test7: indexOf and lastIndexOf\n");
        {
                sb= StringBuffer_new("jan-henrik haukeland");
                assert(sb);
                assert(StringBuffer_indexOf(sb, "henrik")==4);
                assert(StringBuffer_indexOf(sb, "an")==1);
                assert(StringBuffer_indexOf(sb, "-")==3);
                assert(StringBuffer_lastIndexOf(sb, "an")==17);
                assert(StringBuffer_indexOf(sb, "")==-1);
                assert(StringBuffer_indexOf(sb, 0)==-1);
                assert(StringBuffer_indexOf(sb, "d")==19);
                assert(StringBuffer_indexOf(sb, "j")==0);
                assert(StringBuffer_lastIndexOf(sb, "d")==19);
                assert(StringBuffer_lastIndexOf(sb, "j")==0);
                assert(StringBuffer_lastIndexOf(sb, "x")==-1);
                assert(StringBuffer_indexOf(sb, "jane")==-1);
                assert(StringBuffer_indexOf(sb, "jan-henrik haukeland")==0);
                assert(StringBuffer_indexOf(sb, "haukeland")==11);
                StringBuffer_free(&sb);
                assert(sb==NULL);
        }
        printf("=> Test7: OK\n\n");

        printf("=> Test8: length and clear\n");
        {
                sb= StringBuffer_new("jan-henrik haukeland");
                assert(sb);
                assert(StringBuffer_length(sb)==20);
                StringBuffer_clear(sb);
                assert(StringBuffer_length(sb)==0);
                StringBuffer_free(&sb);
                assert(sb==NULL);
        }
        printf("=> Test8: OK\n\n");

        printf("=> Test9: toString value\n");
        {
                sb= StringBuffer_new("abc");
                assert(sb);
                StringBuffer_append(sb, "def");
                assert(Str_isEqual(StringBuffer_toString(sb), "abcdef"));
                StringBuffer_free(&sb);
                assert(sb==NULL);
        }
        printf("=> Test9: OK\n\n");

        printf("=> Test10: internal resize\n");
        {
                int i;
                sb= StringBuffer_new("");
                assert(sb);
                for (i= 0; i<1024; i++)
                        StringBuffer_append(sb, "a");
                assert(StringBuffer_length(sb)==1024);
                assert(StringBuffer_toString(sb)[1023]=='a');
                assert(StringBuffer_toString(sb)[1024]==0);
                StringBuffer_free(&sb);
                assert(sb==NULL);
        }
        printf("=> Test10: OK\n\n");

        printf("=> Test11: substring\n");
        {
                sb= StringBuffer_new("jan-henrik haukeland");
                assert(sb);
                assert(Str_isEqual(StringBuffer_substring(sb, StringBuffer_indexOf(sb, "-")),
                                                 "-henrik haukeland"));
                StringBuffer_free(&sb);
                assert(sb==NULL);
        }
        printf("=> Test11: OK\n\n");

        printf("=> Test12: replace\n");
        {
                printf("\tNothing to replace\n");
                sb= StringBuffer_new("abc?def?");
                assert(sb);
                StringBuffer_replace(sb, "x", "$x");
                assert(Str_isEqual(StringBuffer_toString(sb), "abc?def?"));
                StringBuffer_free(&sb);
                assert(sb==NULL);
                printf("\tReplace and expand\n");
                sb= StringBuffer_new("abc?def?");
                assert(sb);
                StringBuffer_replace(sb, "?", "$x");
                assert(Str_isEqual(StringBuffer_toString(sb), "abc$xdef$x"));
                StringBuffer_free(&sb);
                assert(sb==NULL);
                printf("\tReplace and shrink\n");
                sb= StringBuffer_new("abc$xdef$x");
                assert(sb);
                StringBuffer_replace(sb, "$x", "?");
                assert(Str_isEqual(StringBuffer_toString(sb), "abc?def?"));
                StringBuffer_free(&sb);
                assert(sb==NULL);
                printf("\tReplace with empty string\n");
                sb= StringBuffer_new("abc$xdef$x");
                assert(sb);
                StringBuffer_replace(sb, "$x", "");
                assert(Str_isEqual(StringBuffer_toString(sb), "abcdef"));
                StringBuffer_free(&sb);
                assert(sb==NULL);
                printf("\tReplace with same length\n");
                sb= StringBuffer_new("foo bar baz foo bar baz");
                assert(sb);
                StringBuffer_replace(sb, "baz", "bar");
                assert(Str_isEqual(StringBuffer_toString(sb), "foo bar bar foo bar bar"));
                StringBuffer_free(&sb);
                assert(sb==NULL);
                printf("\tRemove words and test traceback\n");
                sb= StringBuffer_new("foo bar baz foo foo bar baz");
                assert(sb);
                StringBuffer_replace(sb, "baz", "bar");
                assert(Str_isEqual(StringBuffer_toString(sb), "foo bar bar foo foo bar bar"));
                StringBuffer_replace(sb, "foo bar ", "");
                assert(Str_isEqual(StringBuffer_toString(sb), "bar foo bar"));
                StringBuffer_free(&sb);
                assert(sb==NULL);
                printf("\tReplace all elements\n");
                sb= StringBuffer_new("aaaaaaaaaaaaaaaaaaaaaaaa");
                assert(sb);
                StringBuffer_replace(sb, "a", "b");
                assert(Str_isEqual(StringBuffer_toString(sb), "bbbbbbbbbbbbbbbbbbbbbbbb"));
                StringBuffer_free(&sb);
                assert(sb==NULL);
                printf("\tReplace and expand with resize of StringBuffer\n");
                sb= StringBuffer_new("insert into(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) values (1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,01,2,3);");
                assert(sb);
                StringBuffer_replace(sb, "?", "$x");
                assert(Str_isEqual(StringBuffer_toString(sb), "insert into($x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x, $x) values (1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,01,2,3);"));
                StringBuffer_free(&sb);
                assert(sb==NULL);
        }
        printf("=> Test12: OK\n\n");

        printf("============> StringBuffer Tests: OK\n\n");

        return 0;
}
Exemple #5
0
int main(void) {

        setenv("TZ", "CET", 1);
        tzset();
        
        Bootstrap(); // Need to initialize library

        printf("============> Start Time Tests\n\n");


        printf("=> Test1: check string ouput\n");
        {
                char result[30];
                Time_string(1267441200, result); /* 01 Mar 2010 12:00:00 */
                printf("\tResult: unix time 1267441200 to localtime:\n\t %s\n", result);
                assert(Str_isEqual(result, "Mon, 01 Mar 2010 12:00:00"));
                Time_gmtstring(1267441200, result); /* 01 Mar 2010 12:00:00 GMT */
                printf("\tResult: unix time 1267441200 to UTC:\n\t %s\n", result);
                assert(Str_isEqual("Mon, 01 Mar 2010 11:00:00 GMT", result));
        }
        printf("=> Test1: OK\n\n");

        printf("=> Test2: check current time\n");
        {
                struct timeval tv;
                assert(!gettimeofday(&tv, NULL));
                assert(Time_now() == tv.tv_sec);
        }
        printf("=> Test2: OK\n\n");

        printf("=> Test3: sleep 1s\n");
        {
                time_t now;
                now = Time_now();
                Time_usleep(1000000);
                assert((now + 1) == Time_now());
        }
        printf("=> Test3: OK\n\n");

        printf("=> Test4: uptime\n");
        {
                time_t days = 668040;
                time_t hours = 63240;
                time_t min = 2040;
                char result[24];
                printf("\tResult: uptime days: %s\n", Time_uptime(days, result));
                assert(Str_isEqual(result, "7d, 17h, 34m"));
                printf("\tResult: uptime hours: %s\n", Time_uptime(hours, result));
                assert(Str_isEqual(result, "17h, 34m"));
                printf("\tResult: uptime min: %s\n", Time_uptime(min, result));
                assert(Str_isEqual(result, "34m"));
                printf("\tResult: uptime 0: %s\n", Time_uptime(0, result));
                assert(Str_isEqual(result, ""));
                assert(Time_uptime(0, NULL) == NULL);
        }
        printf("=> Test4: OK\n\n");

        printf("=> Test5: Time attributes\n");
        {
                char b[STRLEN];
                time_t time = 730251059; // Sun, 21. Feb 1993 00:30:59
                printf("\tResult: %s (winter time)\n", Time_string(time, b));
                assert(Time_seconds(time) == 59);
                assert(Time_minutes(time) == 30);
                assert(Time_hour(time) == 0);
                assert(Time_weekday(time) == 0);
                assert(Time_day(time) == 21);
                assert(Time_month(time) == 2);
                assert(Time_year(time) == 1993);
                time = 1253045894; // Tue, 15 Sep 2009 22:18:14 +0200
                printf("\tResult: %s (DTS/summer time)\n", Time_string(time, b));
                assert(Str_startsWith(b, "Tue, 15 Sep 2009 22:18:14"));
        }
        printf("=> Test5: OK\n\n");

        printf("=> Test6: Time_build\n");
        {
                time_t time = Time_build(2001, 1, 29, 12, 0, 0);
                assert(Time_seconds(time) == 0);
                assert(Time_minutes(time) == 0);
                assert(Time_hour(time) == 12);
                assert(Time_day(time) == 29);
                assert(Time_month(time) == 1);
                assert(Time_year(time) == 2001);
                // Verify assert on out of range
                TRY
                {
                        Time_build(1969, 1, 29, 12, 0, 0);
                        printf("Test failed\n");
                        exit(1);
                }
                CATCH (AssertException)
                END_TRY;
                TRY
                {
                        Time_build(1970, 0, 29, 12, 0, 0);
                        printf("Test failed\n");
                        exit(1);
                }
                CATCH (AssertException)
                END_TRY;
        }
        printf("=> Test6: OK\n\n");

        printf("=> Test7: Time_incron\n");
        {
                const char *exactmatch = "27 11 5 7 2";
                const char *matchall = "* * * * *";
                const char *invalid1 = "a bc d";
                const char *invalid2 = "* * * *  "; // Too few fields
                const char *invalid3 = "* * * * * * "; // Too many fields
                const char *range1 = "* 10-11 1-5 * 1-5";
                const char *rangeoutside = "1-10 9-10 1-5 * 1-5";
                const char *sequence = "* 10,11 1-3,5,6 * *";
                const char *sequenceoutside = "* 10,11,12 4,5,6 * 0,6";
                time_t time = Time_build(2011, 7, 5, 11, 27, 5);
                assert(Time_incron(exactmatch, time));
                assert(Time_incron(matchall, time));
                assert(! Time_incron(invalid1, time));
                assert(! Time_incron(invalid2, time));
                assert(! Time_incron(invalid3, time));
                assert(Time_incron(range1, time));
                assert(! Time_incron(rangeoutside, time));
                assert(Time_incron(sequence, time));
                assert(! Time_incron(sequenceoutside, time));
        }
        printf("=> Test7: OK\n\n");

        printf("============> Time Tests: OK\n\n");

        return 0;
}
Exemple #6
0
int main(void) {

        Bootstrap(); // Need to initialize library

        printf("============> Start Str Tests\n\n");

        printf("=> Test1: copy\n");
        {
                char s3[STRLEN];
                printf("\tResult: %s\n", Str_copy(s3, "The abc house", 7));
                assert(Str_isEqual(s3, "The abc"));
                printf("\tTesting for NULL argument\n");
                assert(!Str_copy(NULL, NULL, 7));
        }
        printf("=> Test1: OK\n\n");

        printf("=> Test2: dup\n");
        {
                char *s4 = Str_dup("abc123");
                printf("\tResult: %s\n", s4);
                assert(Str_isEqual(s4, "abc123"));
                printf("\tTesting for NULL argument\n");
                assert(!Str_dup(NULL));
                FREE(s4);
        }
        printf("=> Test2: OK\n\n");

        printf("=> Test3: ndup\n");
        {
                char *s5 = Str_ndup("abc123", 3);
                printf("\tResult: %s\n", s5);
                assert(Str_isEqual(s5, "abc"));
                printf("\tTesting for NULL argument\n");
                assert(!Str_ndup(NULL, 3));
                FREE(s5);
        }
        printf("=> Test3: OK\n\n");

        printf("=> Test4: Str_cat & Str_vcat\n");
        {
                char *s6;
                s6 = Str_cat("%s://%s%s?%s", "https", "foo.bar", 
                                   "/uri", "abc=123");
                printf("\tResult: %s\n", s6);
                assert(Str_isEqual(s6, "https://foo.bar/uri?abc=123"));
                FREE(s6);
                printf("\tTesting for NULL arguments\n");
                s6 = Str_cat(NULL);
                assert(s6==NULL);
                FREE(s6);
        }
        printf("=> Test4: OK\n\n");

        printf("=> Test5: chomp\n");
        {
                char s3[] = "abc\r\n123";
                printf("\tResult: %s\n", Str_chomp(s3));
                assert(Str_isEqual(s3, "abc"));
                printf("\tTesting for NULL argument\n");
                assert(!Str_chomp(NULL));
        }
        printf("=> Test5: OK\n\n");

        printf("=> Test6: trim\n");
        {
                char e[] = "   ";
                char o[] = " a ";
                char s[] = "   abcdef";
                char s4[] = "  \t abc \r\n\t ";
                assert(Str_isEqual(Str_ltrim(s), "abcdef"));
                printf("\tResult: %s\n", Str_trim(s4));
                assert(Str_isEqual(s4, "abc"));
                printf("\tTesting for NULL argument\n");
                assert(!Str_trim(NULL));
                assert(Str_isEqual(Str_ltrim(e), ""));
                memcpy(e, "   ", sizeof("   ") - 1);
                assert(Str_isEqual(Str_rtrim(e), ""));
                memcpy(e, "   ", sizeof("   ") - 1);
                assert(Str_isEqual(Str_trim(e), ""));
                assert(Str_isEqual(Str_ltrim(o), "a "));
                memcpy(o, " a ", sizeof(" a ") - 1);
                assert(Str_isEqual(Str_rtrim(o), " a"));
                memcpy(o, " a ", sizeof(" a ") - 1);
                assert(Str_isEqual(Str_trim(o), "a"));
                assert(Str_isEqual(Str_trim(o), "a"));
        }
        printf("=> Test6: OK\n\n");

        printf("=> Test7: trim quotes\n");
        {
                char s5[] = "\"'abc'\"";
                char s5a[] = "\"'abc";
                char s5b[] = "abc'\"";
                char s5c[] = "'\"";
                char s5d[] = " \t abc def '\"  ";
                printf("\tResult: %s\n", Str_unquote(s5));
                assert(Str_isEqual(s5, "abc"));
                printf("\tResult: %s\n", Str_unquote(s5a));
                assert(Str_isEqual(s5, "abc"));
                printf("\tResult: %s\n", Str_unquote(s5b));
                assert(Str_isEqual(s5, "abc"));
                printf("\tResult: %s\n", Str_unquote(s5b));
                assert(Str_isEqual(s5, "abc"));
                printf("\tTesting for NULL argument\n");
                assert(!Str_unquote(NULL));
                printf("\tTesting for quotes-only argument\n");
                assert(Str_isEqual("", Str_unquote(s5c)));
                printf("\tTesting for quotes and white-space removal\n");
                assert(Str_isEqual("abc def", Str_unquote(s5d)));
        }
        printf("=> Test7: OK\n\n");

        printf("=> Test8: toLowerCase\n");
        {
                char s6[] = "AbC";
                printf("\tResult: %s\n", Str_toLower(s6));
                assert(Str_isEqual(s6, "abc"));
                printf("\tTesting for NULL argument\n");
                assert(!Str_toLower(NULL));
        }
        printf("=> Test8: OK\n\n");

        printf("=> Test9: toUpperCase\n");
        {
                char s7[] = "aBc";
                printf("\tResult: %s\n", Str_toUpper(s7));
                assert(Str_isEqual(s7, "ABC"));
                printf("\tTesting for NULL argument\n");
                assert(!Str_toUpper(NULL));
        }
        printf("=> Test9: OK\n\n");

        printf("=> Test10: parseInt, parseLLong, parseDouble\n");
        {
                char i[STRLEN] = "   -2812 bla";
                char ll[STRLEN] = "  2147483642 blabla";
                char d[STRLEN] = "  2.718281828 this is e";
                char de[STRLEN] = "1.495E+08 kilometer = An Astronomical Unit";
                char ie[STRLEN] = " 9999999999999999999999999999999999999999";
                printf("\tResult:\n");
                printf("\tParsed int = %d\n", Str_parseInt(i));
                assert(Str_parseInt(i)==-2812);
                printf("\tParsed long long = %lld\n", Str_parseLLong(ll));
                assert(Str_parseLLong(ll)==2147483642);
                printf("\tParsed double = %.9f\n", Str_parseDouble(d));
                assert(Str_parseDouble(d)==2.718281828);
                printf("\tParsed double exp = %.3e\n", Str_parseDouble(de));
                assert(Str_parseDouble(de)==1.495e+08);
                TRY
                        Str_parseInt(ie);
                        assert(false);
                CATCH(NumberFormatException)
                        printf("=> Test11: OK\n\n");
                END_TRY;
        }
        printf("=> Test10: OK\n\n");

        printf("=> Test11: replace\n");
        {
                char s9[] = "abccba";
                printf("\tResult: %s\n", Str_replaceChar(s9, 'b', 'X'));
                assert(Str_isEqual(s9, "aXccXa"));
                printf("\tTesting for NULL argument\n");
                assert(!Str_replaceChar(NULL, 'b', 'X'));
        }
        printf("=> Test11: OK\n\n");

        printf("=> Test12: startsWith\n");
        {
                char *a = "mysql://*****:*****@ ]+@([-a-zA-Z0-9]+\\.)+[a-zA-Z]{2,}$";
                char *valid_phone1 = "+4797141255";
                char *valid_phone2 = "(47)-97-14-12-55";
                char *invalid_phone1 = "141255";
                char *invalid_phone2 = "(47)971412551234567890123456789012345678901234567890";
                char *invalid_phone3 = "";
                char *invalid_phone4 = "abc123";
                char *valid_email1 = "*****@*****.**";
                char *valid_email2 = "*****@*****.**";
                char *invalid_email1 = "hauktildeslash.com";
                char *invalid_email2 = "";
                char *invalid_email3 = "hauk@tildeslashcom";
                char *invalid_email4 = "hauk@æøåtildeslash.com";
                // phone
                printf("\tResult: match(%s, %s)\n", phone_pattern, valid_phone1);
                assert(Str_match(phone_pattern, valid_phone1));
                printf("\tResult: match(%s, %s)\n", phone_pattern, valid_phone2);
                assert(Str_match(phone_pattern, valid_phone2));
                printf("\tResult: match(%s, %s)\n", phone_pattern, invalid_phone1);
                assert(! Str_match(phone_pattern, invalid_phone1));
                printf("\tResult: match(%s, %s)\n", phone_pattern, invalid_phone2);
                assert(! Str_match(phone_pattern, invalid_phone2));
                printf("\tResult: match(%s, %s)\n", phone_pattern, invalid_phone3);
                assert(! Str_match(phone_pattern, invalid_phone3));
                printf("\tResult: match(%s, %s)\n", phone_pattern, invalid_phone4);
                assert(! Str_match(phone_pattern, invalid_phone4));
                // email
                printf("\tResult: match(%s, %s)\n", email_pattern, valid_email1);
                assert(Str_match(email_pattern, valid_email1));
                printf("\tResult: match(%s, %s)\n", email_pattern, valid_email2);
                assert(Str_match(email_pattern, valid_email2));
                printf("\tResult: match(%s, %s)\n", email_pattern, invalid_email1);
                assert(! Str_match(email_pattern, invalid_email1));
                printf("\tResult: match(%s, %s)\n", email_pattern, invalid_email2);
                assert(! Str_match(email_pattern, invalid_email2));
                printf("\tResult: match(%s, %s)\n", email_pattern, invalid_email3);
                assert(! Str_match(email_pattern, invalid_email3));
                printf("\tResult: match(%s, %s)\n", email_pattern, invalid_email4);
                assert(! Str_match(email_pattern, invalid_email4));
        }
        printf("=> Test17: OK\n\n");

        printf("=> Test18: lim\n");
        {
                char *zero = "";
                char *two = "12";
                char *ten = "1234567890";
                assert(! Str_lim(zero, 0));
                assert(!Str_lim(zero, 1));
                assert(Str_lim(two, 0));
                assert(Str_lim(two, 1));
                assert(!Str_lim(two, 2));
                assert(Str_lim(ten, 0));
                assert(Str_lim(ten, 5));
                assert(Str_lim(ten, 9));
                assert(!Str_lim(ten, 10));
                assert(! Str_lim(ten, 100));
        }
        printf("=> Test18: OK\n\n");

        printf("=> Test19: substring\n");
        {
                assert(Str_sub("foo bar baz", "bar"));
                assert(!  Str_sub("foo bar baz", "barx"));
                assert(Str_isEqual(Str_sub("foo bar baz", "baz"), "baz"));
                assert(Str_sub("foo bar baz", "foo bar baz"));
                assert(Str_sub("a", "a"));
                assert(! Str_sub("a", "b"));
                assert(! Str_sub("", ""));
                assert(! Str_sub("foo", ""));
                assert(! Str_sub("abc", "abcdef"));
                assert(! Str_sub("foo", "foo bar"));
                assert(Str_isEqual(Str_sub("foo foo bar", "foo bar"), "foo bar"));
                assert(Str_sub("foo foo bar foo bar baz fuu", "foo bar baz"));
                assert(Str_isEqual(Str_sub("abcd abcc", "abcc"), "abcc"));
        }
        printf("=> Test19: OK\n\n");

        printf("=> Test20: Str_join\n");
        {
                char *p = NULL;
                char dest[10+1] = "xxxxxxxxx";
                char a[] = "abc";
                char *b  = "def";
                char *c  = "xxx123";
                assert(Str_isEqual(Str_join(dest, 10, a, b, "ghi"), "abcdefghi"));
                assert(Str_isEqual(Str_join(dest, 10, p), ""));
                assert(Str_isEqual(Str_join(dest, 10), ""));
                assert(Str_isEqual(Str_join(dest, 10, "012", "3456789", "0123456789"), "0123456789"));
                assert(Str_isEqual(Str_join(dest, 4, "a", "b", "cd", "ghi", "jklmnopq"), "abcd"));
                assert(Str_isEqual(Str_join(dest, 10, a, c + 3), "abc123"));
                Str_join(dest, 0);
                assert(dest[0]==0);
        }
        printf("=> Test20: OK\n\n");

        printf("=> Test21: Str_has\n");
        {
                char *foo = "'bar' (baz)"; 
                assert(Str_has("(')", foo));
                assert(! Str_has(",;", foo));
        }
        printf("=> Test21: OK\n\n");

        printf("=> Test22: Str_curtail\n");
        {
                char s[] = "<text>Hello World</text>"; 
                assert(Str_isByteEqual(Str_curtail(s, "</text>"), "<text>Hello World"));
                assert(Str_isByteEqual(Str_curtail(s, ">"), "<text"));
                assert(Str_isByteEqual(Str_curtail(s, "@"), "<text"));
        }
        printf("=> Test22: OK\n\n");

        printf("=> Test23: Str_ton\n");
        {
                char str[43];
                long l1 = 42, l2 = 0, l3 = -42, l4 = LONG_MAX, l5 = LONG_MIN;
                assert(Str_isByteEqual("42", Str_ton(42, (char[43]){0})));
                assert(Str_isByteEqual("42", Str_ton(l1, str)));
                assert(Str_isByteEqual("0", Str_ton(l2, str)));
                assert(Str_isByteEqual("-42", Str_ton(l3, str)));
                assert(l4 == Str_parseLLong(Str_ton(l4, str)));
                assert(l5 == Str_parseLLong(Str_ton(l5, str)));
        }
Exemple #7
0
static void testPool(const char *testURL) {
        URL_T url;
        char *schema;
        ConnectionPool_T pool;
        char *data[]= {"Fry", "Leela", "Bender", "Farnsworth",
                "Zoidberg", "Amy", "Hermes", "Nibbler", "Cubert",
                "Zapp", "Joey Mousepad", "ЯΣ༆", 0}; 
        
        if (Str_startsWith(testURL, "mysql")) {
                schema = SCHEMA_MYSQL;
        } else if (Str_startsWith(testURL, "postgresql")) {
                schema = SCHEMA_POSTGRESQL;
        } else if (Str_startsWith(testURL, "sqlite")) {
                schema = SCHEMA_SQLITE;
        } else if (Str_startsWith(testURL, "oracle")) {
                schema = SCHEMA_ORACLE;
        }
        else {
                printf("Unsupported database protocol\n");
                exit(1);
        }

        printf("=> Test1: create/destroy\n");
        {
                pool = ConnectionPool_new(URL_new(testURL));
                assert(pool);
                url = ConnectionPool_getURL(pool);
                ConnectionPool_free(&pool);
                assert(! pool);
                URL_free(&url);
        }
        printf("=> Test1: OK\n\n");
        
        printf("=> Test2: NULL value\n");
        {
                url = URL_new(NULL);
                assert(! url);
                pool = ConnectionPool_new(url);
                assert(! pool);
        }
        printf("=> Test2: OK\n\n");
        
        printf("=> Test3: start/stop\n");
        {
                url = URL_new(testURL);
                pool = ConnectionPool_new(url);
                assert(pool);
                ConnectionPool_start(pool);
                ConnectionPool_stop(pool);
                ConnectionPool_free(&pool);
                assert(pool==NULL);
                URL_free(&url);
                // Test that exception is thrown on start error
                TRY
                {
                        url = URL_new("not://a/database");
                        pool = ConnectionPool_new(url);
                        assert(pool);
                        ConnectionPool_start(pool);
                        printf("\tResult: Test failed -- exception not thrown\n");
                        exit(1);
                }
                CATCH(SQLException) {
                        // OK
                }
                FINALLY {
                        ConnectionPool_free(&pool);
                        assert(pool==NULL);
                        URL_free(&url);
                }
                END_TRY;
        }
        printf("=> Test3: OK\n\n");
        
        printf("=> Test4: Connection execute & transaction\n");
        {
                int i;
                Connection_T con;
                url = URL_new(testURL);
                pool = ConnectionPool_new(url);
                assert(pool);
                ConnectionPool_setAbortHandler(pool, TabortHandler);
                ConnectionPool_start(pool);
                con = ConnectionPool_getConnection(pool);
                assert(con);
                TRY Connection_execute(con, "drop table zild_t;"); ELSE END_TRY;
                Connection_execute(con, "%s", schema);
                Connection_beginTransaction(con);
                /* Insert values into database and assume that auto increment of id works */
                for (i = 0; data[i]; i++) 
                        Connection_execute(con, "insert into zild_t (name, percent) values('%s', %d.%d);", data[i], i+1, i);
                // Assert that the last insert statement added one row
                assert(Connection_rowsChanged(con) == 1);
                /* Assert that last row id works for MySQL and SQLite. Neither Oracle nor PostgreSQL
                 support last row id directly. The way to do this in PostgreSQL is to use 
                 currval() or return the id on insert. */
                if (IS(URL_getProtocol(url), "sqlite") || IS(URL_getProtocol(url), "mysql")) 
                        assert(Connection_lastRowId(con) == 12);
                Connection_commit(con);
                printf("\tResult: table zild_t successfully created\n");
                Connection_close(con);
        }
        printf("=> Test4: OK\n\n");     
        
        
        printf("=> Test5: Prepared Statement\n");
        {
                int i;
                char blob[8192];
                char *images[]= {"Ceci n'est pas une pipe", "Mona Lisa",
                        "Bryllup i Hardanger", "The Scream",
                        "Vampyre", "Balcony", "Cycle", "Day & Night", 
                        "Hand with Reflecting Sphere",
                        "Drawing Hands", "Ascending and Descending", 0}; 
                Connection_T con = ConnectionPool_getConnection(pool);
                assert(con);
                // 1. Prepared statement, perform a nonsense update to test rowsChanged
                PreparedStatement_T p1 = Connection_prepareStatement(con, "update zild_t set image=?;");
                PreparedStatement_setString(p1, 1, "");
                PreparedStatement_execute(p1);
                printf("\tRows changed: %lld\n", PreparedStatement_rowsChanged(p1));
                // Assert that all 12 rows in the data set was changed
                assert(PreparedStatement_rowsChanged(p1) == 12);
                // 2. Prepared statement, update the table proper with "images". 
                PreparedStatement_T pre = Connection_prepareStatement(con, "update zild_t set image=? where id=?;");
                assert(pre);
                for (i = 0; images[i]; i++) {
                        PreparedStatement_setBlob(pre, 1, images[i], (int)strlen(images[i])+1);
                        PreparedStatement_setInt(pre, 2, i + 1);
                        PreparedStatement_execute(pre);
                }
                // The last execute changed one row only
                assert(PreparedStatement_rowsChanged(pre) == 1);
                /* Add a database null blob value */
                PreparedStatement_setBlob(pre, 1, NULL, 0);
                PreparedStatement_setInt(pre, 2, 5);
                PreparedStatement_execute(pre);
                /* Add a database null string value */
                PreparedStatement_setString(pre, 1, NULL);
                PreparedStatement_setInt(pre, 2, 1);
                PreparedStatement_execute(pre);
                /* Add a large blob */
                memset(blob, 'x', 8192);
                blob[8191] = 0;
                /* Mark start and end */
                *blob='S'; blob[8190] = 'E';
                PreparedStatement_setBlob(pre, 1, blob, 8192);
                PreparedStatement_setInt(pre, 2, i + 1);
                PreparedStatement_execute(pre);
                printf("\tResult: prepared statement successfully executed\n");
                Connection_close(con);
        }
        printf("=> Test5: OK\n\n");     
        
        
        printf("=> Test6: Result Sets\n");
        {
                int i;
                int imagesize = 0;
                Connection_T con;
                ResultSet_T rset;
                ResultSet_T names;
                PreparedStatement_T pre;
                con = ConnectionPool_getConnection(pool);
                assert(con);
                rset = Connection_executeQuery(con, "select id, name, percent, image from zild_t where id < %d order by id;", 100);
                assert(rset);
                printf("\tResult:\n");
                printf("\tNumber of columns in resultset: %d\n\t", ResultSet_getColumnCount(rset));
                assert(4==ResultSet_getColumnCount(rset));
                i = 1;
                printf("%-5s", ResultSet_getColumnName(rset, i++));
                printf("%-16s", ResultSet_getColumnName(rset, i++));
                printf("%-10s", ResultSet_getColumnName(rset, i++));
                printf("%-16s", ResultSet_getColumnName(rset, i++));
                printf("\n\t------------------------------------------------------\n");
                while (ResultSet_next(rset)) {
                        int id = ResultSet_getIntByName(rset, "id");
                        const char *name = ResultSet_getString(rset, 2);
                        double percent = ResultSet_getDoubleByName(rset, "percent");
                        const char *blob = (char*)ResultSet_getBlob(rset, 4, &imagesize);
                        printf("\t%-5d%-16s%-10.2f%-16.38s\n", id, name ? name : "null", percent, imagesize ? blob : "");
                }
                rset = Connection_executeQuery(con, "select image from zild_t where id=12;");
                assert(1==ResultSet_getColumnCount(rset));
                // Assert that types are interchangeable (to some degree) and that all data is returned
                while (ResultSet_next(rset)) {
                        const char *image = ResultSet_getStringByName(rset, "image");
                        const void *blob = ResultSet_getBlobByName(rset, "image", &imagesize);
                        assert(image && blob);
                        assert(strlen(image) + 1 == 8192);
                        assert(imagesize == 8192);
                }
                printf("\tResult: check max rows..");
                Connection_setMaxRows(con, 3);
                rset = Connection_executeQuery(con, "select id from zild_t;");
                assert(rset);
                i = 0;
                while (ResultSet_next(rset)) i++;
                assert((i)==3);
                printf("success\n");
                printf("\tResult: check prepared statement resultset..");
                Connection_setMaxRows(con, 0);
                pre = Connection_prepareStatement(con, "select name from zild_t where id=?");
                assert(pre);
                PreparedStatement_setInt(pre, 1, 2);
                names = PreparedStatement_executeQuery(pre);
                assert(names);
                assert(ResultSet_next(names));
                assert(Str_isEqual("Leela", ResultSet_getString(names, 1)));
                printf("success\n");
                printf("\tResult: check prepared statement re-execute..");
                PreparedStatement_setInt(pre, 1, 1);
                names = PreparedStatement_executeQuery(pre);
                assert(names);
                assert(ResultSet_next(names));
                assert(Str_isEqual("Fry", ResultSet_getString(names, 1)));
                printf("success\n");
                printf("\tResult: check prepared statement without in-params..");
                pre = Connection_prepareStatement(con, "select name from zild_t;");
                assert(pre);
                names = PreparedStatement_executeQuery(pre);
                assert(names);
                for (i = 0; ResultSet_next(names); i++);
                assert(i==12);
                printf("success\n");
                /* Need to close and release statements before
                   we can drop the table, sqlite need this */
                Connection_clear(con);
                Connection_execute(con, "drop table zild_t;");
                Connection_close(con);
                ConnectionPool_stop(pool);
                ConnectionPool_free(&pool);
                assert(pool==NULL);
                URL_free(&url);
        }
        printf("=> Test6: OK\n\n");
        
        
        printf("=> Test7: reaper start/stop\n");
        {
                int i;
                Vector_T v = Vector_new(20);
                url = URL_new(testURL);
                pool = ConnectionPool_new(url);
                assert(pool);
                ConnectionPool_setInitialConnections(pool, 4);
                ConnectionPool_setMaxConnections(pool, 20);
                ConnectionPool_setConnectionTimeout(pool, 4);
                ConnectionPool_setReaper(pool, 4);
                ConnectionPool_setAbortHandler(pool, TabortHandler);
                ConnectionPool_start(pool);
                assert(4==ConnectionPool_size(pool));
                printf("Creating 20 Connections..");
                for (i = 0; i<20; i++)
                        Vector_push(v, ConnectionPool_getConnection(pool));
                assert(ConnectionPool_size(pool) == 20);
                assert(ConnectionPool_active(pool) == 20);
                printf("success\n");
                printf("Closing Connections down to initial..");
                while (! Vector_isEmpty(v))
                        Connection_close(Vector_pop(v));
                assert(ConnectionPool_active(pool) == 0);
                assert(ConnectionPool_size(pool) == 20);
                printf("success\n");
                printf("Please wait 10 sec for reaper to harvest closed connections..");
                Connection_T con = ConnectionPool_getConnection(pool); // Activate one connection to verify the reaper does not close any active
                fflush(stdout);
                sleep(10);
                assert(5 == ConnectionPool_size(pool)); // 4 initial connections + the one active we got above
                assert(1 == ConnectionPool_active(pool));
                printf("success\n");
                Connection_close(con);
                ConnectionPool_stop(pool);
                ConnectionPool_free(&pool);
                Vector_free(&v);
                assert(pool==NULL);
                URL_free(&url);
        }
        printf("=> Test7: OK\n\n");

        printf("=> Test8: Exceptions handling\n");
        {
                int i;
                Connection_T con;
                ResultSet_T result;
                url = URL_new(testURL);
                pool = ConnectionPool_new(url);
                assert(pool);
                ConnectionPool_setAbortHandler(pool, TabortHandler);
                ConnectionPool_start(pool);
                con = ConnectionPool_getConnection(pool);
                assert(con);
                /* 
                 * The following should work without throwing exceptions 
                 */
                TRY
                {
                        Connection_execute(con, "%s", schema);
                }
                ELSE
                {
                        printf("\tResult: Creating table zild_t failed -- %s\n", Exception_frame.message);
                        assert(false); // Should not fail
                }
                END_TRY;
                TRY
                {
                        Connection_beginTransaction(con);
                        for (i = 0; data[i]; i++) 
                                Connection_execute(con, "insert into zild_t (name, percent) values('%s', %d.%d);", data[i], i+1, i);
                        Connection_commit(con);
                        printf("\tResult: table zild_t successfully created\n");
                }
                ELSE
                {
                        printf("\tResult: Test failed -- %s\n", Exception_frame.message);
                        assert(false); // Should not fail
                }
                FINALLY
                {
                        Connection_close(con);
                }
                END_TRY;
                assert((con = ConnectionPool_getConnection(pool)));
                TRY
                {
                        int i, j;
                        const char *bg[]= {"Starbuck", "Sharon Valerii",
                                "Number Six", "Gaius Baltar", "William Adama",
                                "Lee \"Apollo\" Adama", "Laura Roslin", 0};
                        PreparedStatement_T p = Connection_prepareStatement
                        (con, "insert into zild_t (name) values(?);");
                        /* If we did not get a statement, an SQLException is thrown
                           and we will not get here. So we can safely use the 
                           statement now. Likewise, below, we do not have to 
                           check return values from the statement since any error
                           will throw an SQLException and transfer the control
                           to the exception handler
                        */
                        for (i = 0, j = 42; bg[i]; i++, j++) {
                                PreparedStatement_setString(p, 1, bg[i]);
                                PreparedStatement_execute(p);
                        }
                }
                CATCH(SQLException)
                {
                        printf("\tResult: prepare statement failed -- %s\n", Exception_frame.message);
                        assert(false);
                }
                END_TRY;
                TRY
                {
                        printf("\t\tBattlestar Galactica: \n");
                        result = Connection_executeQuery(con, "select name from zild_t where id > 12;");
                        while (ResultSet_next(result))
                                printf("\t\t%s\n", ResultSet_getString(result, 1));
                }
                CATCH(SQLException)
                {
                        printf("\tResult: resultset failed -- %s\n", Exception_frame.message);
                       assert(false);
                }
                FINALLY
                {
                        Connection_close(con);
                }
                END_TRY;
                /* 
                 * The following should fail and throw exceptions. The exception error 
                 * message can be obtained with Exception_frame.message, or from 
                 * Connection_getLastError(con). Exception_frame.message contains both
                 * SQL errors or api errors such as prepared statement parameter index
                 * out of range, while Connection_getLastError(con) only has SQL errors
                 */
                TRY
                {
                        assert((con = ConnectionPool_getConnection(pool)));
                        Connection_execute(con, "%s", schema);
                        /* Creating the table again should fail and we 
                        should not come here */
                        printf("\tResult: Test failed -- exception not thrown\n");
                        exit(1);
                }
                CATCH(SQLException)
                {
                        Connection_close(con);
                }
                END_TRY;
                TRY
                {
                        assert((con = ConnectionPool_getConnection(pool)));
                        printf("\tTesting: Query with errors.. ");
                        Connection_executeQuery(con, "blablabala;");
                        printf("\tResult: Test failed -- exception not thrown\n");
                        exit(1);
                }
                CATCH(SQLException)
                {
                        printf("ok\n");
                        Connection_close(con);
                }
                END_TRY;
                TRY
                {
                        printf("\tTesting: Prepared statement query with errors.. ");
                        assert((con = ConnectionPool_getConnection(pool)));
                        PreparedStatement_T p = Connection_prepareStatement(con, "blablabala;");
                        ResultSet_T r = PreparedStatement_executeQuery(p);
                        while(ResultSet_next(r));
                        printf("\tResult: Test failed -- exception not thrown\n");
                        exit(1);
                }
                CATCH(SQLException)
                {
                        printf("ok\n");
                        Connection_close(con);
                }
                END_TRY;
                TRY
                {
                        assert((con = ConnectionPool_getConnection(pool)));
                        printf("\tTesting: Column index out of range.. ");
                        result = Connection_executeQuery(con, "select id, name from zild_t;");
                        while (ResultSet_next(result)) {
                                int id = ResultSet_getInt(result, 1);  
                                const char *name = ResultSet_getString(result, 2);
                                /* So far so good, now, try access an invalid
                                   column, which should throw an SQLException */
                                int bogus = ResultSet_getInt(result, 3);
                                printf("\tResult: Test failed -- exception not thrown\n");
                                printf("%d, %s, %d", id, name, bogus);
                                exit(1);
                        }
                }
                CATCH(SQLException)
                {
                        printf("ok\n");
                        Connection_close(con);
                }
                END_TRY;
                TRY
                {
                        assert((con = ConnectionPool_getConnection(pool)));
                        printf("\tTesting: Invalid column name.. ");
                        result = Connection_executeQuery(con, "select name from zild_t;");
                        while (ResultSet_next(result)) {
                                const char *name = ResultSet_getStringByName(result, "nonexistingcolumnname");
                                printf("%s", name);
                                printf("\tResult: Test failed -- exception not thrown\n");
                                exit(1);
                        }
                }
                CATCH(SQLException)
                {
                        printf("ok\n");
                        Connection_close(con);
                }
                END_TRY;
                TRY
                {
                        assert((con = ConnectionPool_getConnection(pool)));
                        PreparedStatement_T p = Connection_prepareStatement(con, "update zild_t set name = ? where id = ?;");
                        printf("\tTesting: Parameter index out of range.. ");
                        PreparedStatement_setInt(p, 3, 123);
                        printf("\tResult: Test failed -- exception not thrown\n");
                        exit(1);
                }
                CATCH(SQLException)
                {
                        printf("ok\n");
                }
                FINALLY
                {
                        Connection_close(con);
                }
                END_TRY;
                assert((con = ConnectionPool_getConnection(pool)));
                Connection_execute(con, "drop table zild_t;");
                Connection_close(con);
                ConnectionPool_stop(pool);
                ConnectionPool_free(&pool);
                assert(pool==NULL);
                URL_free(&url);
        }
        printf("=> Test8: OK\n\n");
        
        printf("=> Test9: Ensure Capacity\n");
        {
                /* Check that MySQL ensureCapacity works for columns that exceed the preallocated buffer and that no truncation is done */
                if ( Str_startsWith(testURL, "mysql")) {
                        int myimagesize;
                        url = URL_new(testURL);
                        pool = ConnectionPool_new(url);
                        assert(pool);
                        ConnectionPool_start(pool);
                        Connection_T con = ConnectionPool_getConnection(pool);
                        assert(con);
                        Connection_execute(con, "CREATE TABLE zild_t(id INTEGER AUTO_INCREMENT PRIMARY KEY, image BLOB, string TEXT);");
                        PreparedStatement_T p = Connection_prepareStatement(con, "insert into zild_t (image, string) values(?, ?);");
                        char t[4096];
                        memset(t, 'x', 4096);
                        t[4095] = 0;
                        for (int i = 0; i < 4; i++) {
                                PreparedStatement_setBlob(p, 1, t, (i+1)*512); // store successive larger string-blobs to trigger realloc on ResultSet_getBlobByName
                                PreparedStatement_setString(p, 2, t);
                                PreparedStatement_execute(p);
                        }
                        ResultSet_T r = Connection_executeQuery(con, "select image, string from zild_t;");
                        for (int i = 0; ResultSet_next(r); i++) {
                                ResultSet_getBlobByName(r, "image", &myimagesize);
                                const char *image = ResultSet_getStringByName(r, "image"); // Blob as image should be terminated
                                const char *string = ResultSet_getStringByName(r, "string");
                                assert(myimagesize == (i+1)*512);
                                assert(strlen(image) == ((i+1)*512));
                                assert(strlen(string) == 4095);
                        }
                        p = Connection_prepareStatement(con, "select image, string from zild_t;");
                        r = PreparedStatement_executeQuery(p);
                        for (int i = 0; ResultSet_next(r); i++) {
                                ResultSet_getBlobByName(r, "image", &myimagesize);
                                const char *image = ResultSet_getStringByName(r, "image");
                                const char *string = (char*)ResultSet_getStringByName(r, "string");
                                assert(myimagesize == (i+1)*512);
                                assert(strlen(image) == ((i+1)*512));
                                assert(strlen(string) == 4095);
                        }
                        Connection_execute(con, "drop table zild_t;");
                        Connection_close(con);
                        ConnectionPool_stop(pool);
                        ConnectionPool_free(&pool);
                        URL_free(&url);
                }
        }
        printf("=> Test9: OK\n\n");

        printf("============> Connection Pool Tests: OK\n\n");
}
int main(void) {

        setenv("TZ", "CET", 1);
        tzset();
        
        Bootstrap(); // Need to initialize library

        printf("============> Start Time Tests\n\n");


        printf("=> Test1: check string ouput\n");
        {
                char result[STRLEN];
                Time_string(1267441200, result); /* 01 Mar 2010 12:00:00 */
                printf("\tResult: unix time 1267441200 to localtime:\n\t %s\n", result);
                assert(Str_isEqual(result, "Mon, 01 Mar 2010 12:00:00"));
                Time_gmtstring(1267441200, result); /* 01 Mar 2010 12:00:00 GMT */
                printf("\tResult: unix time 1267441200 to UTC:\n\t %s\n", result);
                assert(Str_isEqual("Mon, 01 Mar 2010 11:00:00 GMT", result));
                Time_fmt(result, STRLEN, "%D %T", 1267441200);
                printf("\tResult: 1267441200 -> %s\n", result);
                assert(Str_isEqual(result, "03/01/10 12:00:00"));
                Time_fmt(result, STRLEN, "%D %z", 1267441200);
                printf("\tResult: 1267441200 -> %s\n", result);
#ifdef AIX
                assert(Str_startsWith(result, "03/01/10 CET"));
#else
                assert(Str_startsWith(result, "03/01/10 +"));
#endif
        }
        printf("=> Test1: OK\n\n");

        printf("=> Test2: check current time\n");
        {
                struct timeval tv;
                assert(!gettimeofday(&tv, NULL));
                assert(Time_now() == tv.tv_sec);
        }
        printf("=> Test2: OK\n\n");

        printf("=> Test3: sleep 1s\n");
        {
                time_t now;
                now = Time_now();
                Time_usleep(1000000);
                assert((now + 1) == Time_now());
        }
        printf("=> Test3: OK\n\n");

        printf("=> Test4: uptime\n");
        {
                time_t days = 668040;
                time_t hours = 63240;
                time_t min = 2040;
                char result[24];
                printf("\tResult: uptime days: %s\n", Time_uptime(days, result));
                assert(Str_isEqual(result, "7d, 17h, 34m"));
                printf("\tResult: uptime hours: %s\n", Time_uptime(hours, result));
                assert(Str_isEqual(result, "17h, 34m"));
                printf("\tResult: uptime min: %s\n", Time_uptime(min, result));
                assert(Str_isEqual(result, "34m"));
                printf("\tResult: uptime 0: %s\n", Time_uptime(0, result));
                assert(Str_isEqual(result, ""));
                assert(Time_uptime(0, NULL) == NULL);
        }
        printf("=> Test4: OK\n\n");

        printf("=> Test5: Time attributes\n");
        {
                char b[STRLEN];
                time_t time = 730251059; // Sun, 21. Feb 1993 00:30:59
                printf("\tResult: %s (winter time)\n", Time_string(time, b));
                assert(Time_seconds(time) == 59);
                assert(Time_minutes(time) == 30);
                assert(Time_hour(time) == 0);
                assert(Time_weekday(time) == 0);
                assert(Time_day(time) == 21);
                assert(Time_month(time) == 2);
                assert(Time_year(time) == 1993);
                time = 1253045894; // Tue, 15 Sep 2009 22:18:14 +0200
                printf("\tResult: %s (DTS/summer time)\n", Time_string(time, b));
                assert(Str_startsWith(b, "Tue, 15 Sep 2009 22:18:14"));
        }
        printf("=> Test5: OK\n\n");

        printf("=> Test6: Time_build\n");
        {
                time_t time = Time_build(2001, 1, 29, 12, 0, 0);
                assert(Time_seconds(time) == 0);
                assert(Time_minutes(time) == 0);
                assert(Time_hour(time) == 12);
                assert(Time_day(time) == 29);
                assert(Time_month(time) == 1);
                assert(Time_year(time) == 2001);
                // Verify assert on out of range
                TRY
                {
                        Time_build(1969, 1, 29, 12, 0, 0);
                        printf("Test failed\n");
                        exit(1);
                }
                CATCH (AssertException)
                END_TRY;
                TRY
                {
                        Time_build(1970, 0, 29, 12, 0, 0);
                        printf("Test failed\n");
                        exit(1);
                }
                CATCH (AssertException)
                END_TRY;
        }
        printf("=> Test6: OK\n\n");

        printf("=> Test7: Time_incron\n");
        {
                const char *exactmatch = "27 11 5 7 2";
                const char *matchall = "* * * * *";
                const char *invalid1 = "a bc d";
                const char *invalid2 = "* * * *  "; // Too few fields
                const char *invalid3 = "* * * * * * "; // Too many fields
                const char *range1 = "* 10-11 1-5 * 1-5";
                const char *rangeoutside = "1-10 9-10 1-5 * 1-5";
                const char *sequence = "* 10,11 1-3,5,6 * *";
                const char *sequenceoutside = "* 10,11,12 4,5,6 * 0,6";
                time_t time = Time_build(2011, 7, 5, 11, 27, 5);
                assert(Time_incron(exactmatch, time));
                assert(Time_incron(matchall, time));
                assert(! Time_incron(invalid1, time));
                assert(! Time_incron(invalid2, time));
                assert(! Time_incron(invalid3, time));
                assert(Time_incron(range1, time));
                assert(! Time_incron(rangeoutside, time));
                assert(Time_incron(sequence, time));
                assert(! Time_incron(sequenceoutside, time));
        }
        printf("=> Test7: OK\n\n");

        printf("=> Test8: Time_toDateTime\n");
        {
#if HAVE_STRUCT_TM_TM_GMTOFF
#define TM_GMTOFF tm_gmtoff
#else
#define TM_GMTOFF tm_wday
#endif
                struct tm t;
                // DateTime ISO-8601 format
                assert(Time_toDateTime("2013-12-14T09:38:08Z", &t));
                assert(t.tm_year == 2013);
                assert(t.tm_mon  == 11);
                assert(t.tm_mday == 14);
                assert(t.tm_hour == 9);
                assert(t.tm_min  == 38);
                assert(t.tm_sec  == 8);
                // Date
                assert(Time_toDateTime("2013-12-14", &t));
                assert(t.tm_year == 2013);
                assert(t.tm_mon  == 11);
                assert(t.tm_mday == 14);
                // Time
                assert(Time_toDateTime("09:38:08", &t));
                assert(t.tm_hour == 9);
                assert(t.tm_min  == 38);
                assert(t.tm_sec  == 8);
                // Compressed DateTime
                assert(Time_toDateTime(" 20131214093808", &t));
                assert(t.tm_year == 2013);
                assert(t.tm_mon  == 11);
                assert(t.tm_mday == 14);
                assert(t.tm_hour == 9);
                assert(t.tm_min  == 38);
                assert(t.tm_sec  == 8);
                // Compressed Date
                assert(Time_toDateTime(" 20131214 ", &t));
                assert(t.tm_year == 2013);
                assert(t.tm_mon  == 11);
                assert(t.tm_mday == 14);
                // Compressed Time
                assert(Time_toDateTime("093808", &t));
                assert(t.tm_hour == 9);
                assert(t.tm_min  == 38);
                assert(t.tm_sec  == 8);
                // Reverse DateTime
                assert(Time_toDateTime(" 09:38:08 2013-12-14", &t));
                assert(t.tm_year == 2013);
                assert(t.tm_mon  == 11);
                assert(t.tm_mday == 14);
                assert(t.tm_hour == 9);
                assert(t.tm_min  == 38);
                assert(t.tm_sec  == 8);
                // DateTime with timezone Zulu (UTC)
                assert(Time_toDateTime("The Battle of Stamford Bridge 1066-09-25 12:15:33+00:00", &t));
                assert(t.tm_year == 1066);
                assert(t.tm_mon  == 8);
                assert(t.tm_mday == 25);
                assert(t.tm_hour == 12);
                assert(t.tm_min  == 15);
                assert(t.tm_sec  == 33);
                assert(t.TM_GMTOFF == 0); // offset from UTC in seconds
                // Time with timezone
                assert(Time_toDateTime(" 09:38:08+01:45", &t));
                assert(t.tm_hour == 9);
                assert(t.tm_min  == 38);
                assert(t.tm_sec  == 8);
                assert(t.TM_GMTOFF == 6300);
                // Time with timezone PST compressed
                assert(Time_toDateTime("Pacific Time Zone 09:38:08 -0800 ", &t));
                assert(t.tm_hour == 9);
                assert(t.tm_min  == 38);
                assert(t.tm_sec  == 8);
                assert(t.TM_GMTOFF == -28800);
                // Date without time, tz should not be set
                assert(Time_toDateTime("2013-12-15-0800 ", &t));
                assert(t.TM_GMTOFF == 0);
                // Invalid date
                TRY {
                        Time_toDateTime("1901-123-45", &t);
                        printf("\t Test Failed\n");
                        exit(1);
                } CATCH (AssertException) {
                        // OK
                } ELSE {
                        printf("\t Test Failed with wrong exception\n");
                        exit(1);
                }
                END_TRY;
        }
        printf("=> Test8: OK\n\n");

        printf("=> Test9: Time_toTimestamp\n");
        {
                // Time, fraction of second is ignored. No timezone in string means UTC
                time_t t = Time_toTimestamp("2013-12-15 00:12:58.123456");
                assert(t == 1387066378);
                // TimeZone east
                t = Time_toTimestamp("Tokyo timezone: 2013-12-15 09:12:58+09:00");
                assert(t == 1387066378);
                // TimeZone west
                t = Time_toTimestamp("New York timezone: 2013-12-14 19:12:58-05:00");
                assert(t == 1387066378);
                // TimeZone east with hour and minute offset
                t = Time_toTimestamp("Nepal timezone: 2013-12-15 05:57:58+05:45");
                assert(t == 1387066378);
                // TimeZone Zulu
                t = Time_toTimestamp("Grenwich timezone: 2013-12-15 00:12:58Z");
                assert(t == 1387066378);
                // Compressed
                t = Time_toTimestamp("20131214191258-0500");
                assert(t == 1387066378);
                // Invalid timestamp string
                TRY {
                        Time_toTimestamp("1901-123-45 10:12:14");
                        // Should not come here
                        printf("\t Test Failed\n");
                        exit(1);
                } CATCH (AssertException) {
                        // OK
                } ELSE {
                        printf("\t Test Failed with wrong exception\n");
                        exit(1);
                }
                END_TRY;
        }
        printf("=> Test9: OK\n\n");

        printf("============> Time Tests: OK\n\n");

        return 0;
}
int main(void) {

        Bootstrap(); // Need to initialize library
        
        printf("============> Start Time Tests\n\n");
        
        printf("=> Test1: Parse String\n");
        {
                long r;
                char d1[STRLEN];
                char s[] = " Thu, 17 Oct 2002 19:10:01; ";
                char y[] = "Year: 2011 Day: 14 Month: June";
                printf("\tParsing a null date string: %ld\n", Time_parse(NULL));
                assert(Time_parse(NULL) == -1);
                r = Time_parse(s);
                printf("\tParsed datestring has value: %ld\n", r);
                assert(r == 1034874601);
                printf("\tWhich transform to the local date: %s\n", Time_fmt(d1, STRLEN, "%a, %d %b %Y %H:%M:%S %z", r));
                r = Time_parse(y);
                printf("\tSecond parsed datestring has value: %ld\n", r);
                assert(r == 1308002400);
                printf("\tWhich transform to the local date: %s\n", Time_fmt(d1, STRLEN, "%a, %d %b %Y %H:%M:%S %z", r));
        }
        printf("=> Test1: OK\n\n");
        
        printf("=> Test2: check string ouput\n");
        {
                char result[30];
                Time_string(1267441200, result); /* 01 Mar 2010 12:00:00 */
                printf("\tResult: local unix time 1267441200 to localtime:\n\t %s\n", result);
                assert(Str_isEqual(result, "Mon, 01 Mar 2010 12:00:00"));
                Time_gmtstring(1267441200, result); /* 01 Mar 2010 12:00:00 GMT */
                printf("\tResult: local unix time 1267441200 to UTC:\n\t %s\n", result);
                assert(Str_isEqual("Mon, 01 Mar 2010 11:00:00 GMT", result));
        }
        printf("=> Test2: OK\n\n");
        
        printf("=> Test3: check current time\n");
        {
                struct timeval tv;
                assert(!gettimeofday(&tv, NULL));
                assert(Time_now() == tv.tv_sec);
        }
        printf("=> Test3: OK\n\n");
        
        printf("=> Test4: convert CEST time_t to GMT\n");
        {
                assert(Time_gmt(1267441200) == 1267437600);
        }
        printf("=> Test4: OK\n\n");
        
        printf("=> Test5: sleep 1s\n");
        {
                time_t now;
                now = Time_now();
                Time_usleep(1000000);
                assert((now + 1) == Time_now());
        }
        printf("=> Test5: OK\n\n");
                
        printf("=> Test6: uptime\n");
        {
                time_t days = 668040;
                time_t hours = 63240;
                time_t min = 2040;
                char result[24];
                printf("\tResult: uptime days: %s\n", Time_uptime(days, result));
                assert(Str_isEqual(result, "7d, 17h, 34m"));
                printf("\tResult: uptime hours: %s\n", Time_uptime(hours, result));
                assert(Str_isEqual(result, "17h, 34m"));
                printf("\tResult: uptime min: %s\n", Time_uptime(min, result));
                assert(Str_isEqual(result, "34m"));
                printf("\tResult: uptime 0: %s\n", Time_uptime(0, result));
                assert(Str_isEqual(result, ""));
                assert(Time_uptime(0, NULL) == NULL);
        }
        printf("=> Test6: OK\n\n");
        
        printf("=> Test7: fmt\n");
        {
                
                char result[STRLEN];
                Time_fmt(result, STRLEN, "%D %T", 1267441200);
                printf("\tResult: 1267441200 -> %s\n", result);
                assert(Str_isEqual(result, "03/01/10 12:00:00"));
                Time_fmt(result, STRLEN, "%D", 1267441200);
                printf("\tResult: 1267441200 -> %s\n", result);
                assert(Str_startsWith(result, "03/01/10"));
        }
        printf("=> Test7: OK\n\n");
        
        printf("=> Test8: Time attributes\n");
        {
                char b[STRLEN];
                time_t time = 730251059; // Sun, 21. Feb 1993 00:30:59
                printf("\tResult: %s (winter time)\n", Time_string(time, b));
                assert(Time_seconds(time) == 59);
                assert(Time_minutes(time) == 30);
                assert(Time_hour(time) == 0);
                assert(Time_weekday(time) == 0);
                assert(Time_day(time) == 21);
                assert(Time_month(time) == 2);
                assert(Time_year(time) == 1993);
                time = 1253045894; // Tue, 15 Sep 2009 22:18:14 +0200
                printf("\tResult: %s (DTS/summer time)\n", Time_string(time, b));
                assert(Str_startsWith(b, "Tue, 15 Sep 2009 22:18:14"));
        }
        printf("=> Test8: OK\n\n");

        printf("=> Test9: Time_add\n");
        {
                char b[STRLEN];
                time_t t = 730251059; // Sun, 21. Feb 1993 00:30:59
                time_t time = Time_add(t, -1, -1, 8); // Wed, 29 Jan 1992 00:30:59
                printf("\tResult: %s\n", Time_string(time, b));
                assert(Time_seconds(time) == 59);
                assert(Time_minutes(time) == 30);
                assert(Time_hour(time) == 0);
                assert(Time_day(time) == 29);
                assert(Time_month(time) == 1);
                assert(Time_year(time) == 1992);
        }
        printf("=> Test9: OK\n\n");
        
        printf("=> Test10: Time_build\n");
        {
                time_t time = Time_build(2001, 1, 29, 12, 0, 0);
                assert(Time_seconds(time) == 0);
                assert(Time_minutes(time) == 0);
                assert(Time_hour(time) == 12);
                assert(Time_day(time) == 29);
                assert(Time_month(time) == 1);
                assert(Time_year(time) == 2001);
                // Verify assert on out of range
                TRY
                {
                        Time_build(1969, 1, 29, 12, 0, 0);
                        printf("Test failed\n");
                        exit(1);
                }
                CATCH (AssertException)
                END_TRY;
                TRY
                {
                        Time_build(1970, 0, 29, 12, 0, 0);
                        printf("Test failed\n");
                        exit(1);
                }
                CATCH (AssertException)
                END_TRY;
        }
        printf("=> Test10: OK\n\n");
        
        printf("=> Test11: Time_daysBetween\n");
        {
                time_t from = Time_build(2001, 1, 29, 0, 0, 0);
                time_t to = from;
                assert(Time_daysBetween(from, to) == 0);
                assert(Time_daysBetween(from, Time_build(2001, 1, 30, 0, 0, 0)) == 1);
                assert(Time_daysBetween(from, Time_build(2001, 1, 28, 0, 0, 0)) == 1);
                assert(Time_daysBetween(Time_build(2001, 1, 1, 0, 0, 0), Time_build(2002, 1, 1, 0, 0, 0)) == 365);
        }
        printf("=> Test11: OK\n\n");
        
        printf("=> Test12: Time_incron\n");
        {
                const char *exactmatch = "27 11 5 7 2";
                const char *matchall = "* * * * *";
                const char *invalid1 = "a bc d";
                const char *invalid2 = "* * * *  "; // Too few fields
                const char *invalid3 = "* * * * * * "; // Too many fields
                const char *range1 = "* 10-11 1-5 * 1-5";
                const char *rangeoutside = "1-10 9-10 1-5 * 1-5";
                const char *sequence = "* 10,11 1-3,5,6 * *";
                const char *sequenceoutside = "* 10,11,12 4,5,6 * 0,6";
                time_t time = Time_build(2011, 7, 5, 11, 27, 5);
                assert(Time_incron(exactmatch, time));
                assert(Time_incron(matchall, time));
                assert(! Time_incron(invalid1, time));
                assert(! Time_incron(invalid2, time));
                assert(! Time_incron(invalid3, time));
                assert(Time_incron(range1, time));
                assert(! Time_incron(rangeoutside, time));
                assert(Time_incron(sequence, time));
                assert(! Time_incron(sequenceoutside, time));
        }
        printf("=> Test12: OK\n\n");

        printf("============> Time Tests: OK\n\n");

        return 0;
}