1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

WL#3206 (Adding unit tests):

Moving mytap library into unittest/
Adding 'test' target to make and run unit tests.
Minor fixes.


unittest/mytap/Doxyfile:
  mvdir
unittest/mytap/t/basic.t.c:
  mvdir
unittest/mytap/tap.c:
  mvdir
unittest/mytap/tap.h:
  mvdir
Makefile.am:
  Correcting after moving mytap/
configure.in:
  Correcting after moving mytap/
unittest/Makefile.am:
  Adding 'test' target to build and execute unit tests.
unittest/examples/Makefile.am:
  Correcting after moving mytap/
unittest/mysys/Makefile.am:
  Correcting after moving mytap/
unittest/mysys/bitmap.t.c:
  Adding copyright notice.
unittest/mytap/Makefile.am:
  Correcting after moving mytap/
unittest/mytap/t/Makefile.am:
  Correcting after moving mytap/
unittest/mysys/base64.t.c:
  New BitKeeper file ``unittest/mysys/base64.t.c''
This commit is contained in:
unknown
2006-04-06 17:18:12 +02:00
parent b0d2b6588b
commit 3f9e35d3f3
13 changed files with 149 additions and 20 deletions

View File

@ -1 +1,21 @@
SUBDIRS = mysys examples
SUBDIRS = mytap . mysys examples
.PHONY: mytap mysys examples test
noinst_SCRIPTS = unit
test: mytap mysys examples
./unit run $^
mytap:
cd mytap && $(MAKE)
mysys:
cd mysys && $(MAKE)
examples:
cd examples && $(MAKE)
unit: unit.pl
cp $< $@
chmod +x $@

View File

@ -1,9 +1,9 @@
AM_CPPFLAGS = -I$(srcdir) -I$(top_builddir)/include
AM_CPPFLAGS += -I$(top_builddir)/mytap
AM_CPPFLAGS += -I$(top_builddir)/unittest/mytap
AM_LDFLAGS = -L$(top_builddir)/mytap
AM_LDFLAGS = -L$(top_builddir)/unittest/mytap
AM_CFLAGS = -Wall -ansi -pedantic
AM_CFLAGS = -W -Wall -ansi -pedantic
LDADD = -lmytap

View File

@ -1,14 +1,15 @@
AM_CPPFLAGS = -I$(srcdir) -I$(top_builddir)/include
AM_CPPFLAGS += -I$(top_builddir)/mytap
AM_CPPFLAGS = @ZLIB_INCLUDES@ -I$(top_builddir)/include
AM_CPPFLAGS += -I$(top_srcdir)/include -I$(top_builddir)/unittest/mytap
AM_CFLAGS = -Wall -ansi -pedantic
AM_LDFLAGS = -L$(top_builddir)/unittest/mytap -L$(top_builddir)/mysys
AM_LDFLAGS += -L$(top_builddir)/strings -L$(top_builddir)/dbug
AM_LDFLAGS = -L$(top_builddir)/mytap -L$(top_builddir)/mysys
AM_LDFLAGS += -L$(top_builddir)/strings
LDADD = -lmytap -lmysys -lmystrings -ldbug
LDADD = -lmytap -lmysys -lmystrings
noinst_PROGRAMS = bitmap.t
noinst_PROGRAMS = bitmap.t base64.t
bitmap_t_SOURCES = bitmap.t.c
base64_t_SOURCES = base64.t.c

89
unittest/mysys/base64.t.c Normal file
View File

@ -0,0 +1,89 @@
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA */
#include <base64.h>
#include <tap.h>
#include <stdlib.h>
#include <string.h>
int
main(void)
{
int i;
size_t j, k, l, dst_len, needed_length;
for (i= 0; i < 500; i++)
{
/* Create source data */
const size_t src_len= rand() % 1000 + 1;
char * src= (char *) malloc(src_len);
char * s= src;
char * str;
char * dst;
for (j= 0; j<src_len; j++)
{
char c= rand();
*s++= c;
}
/* Encode */
needed_length= base64_needed_encoded_length(src_len);
str= (char *) malloc(needed_length);
for (k= 0; k < needed_length; k++)
str[k]= 0xff; /* Fill memory to check correct NUL termination */
ok(base64_encode(src, src_len, str) == 0,
"base64_encode: size %d", i);
ok(needed_length == strlen(str) + 1,
"base64_needed_encoded_length: size %d", i);
/* Decode */
dst= (char *) malloc(base64_needed_decoded_length(strlen(str)));
dst_len= base64_decode(str, strlen(str), dst);
ok(dst_len == src_len, "Comparing lengths");
int cmp= memcmp(src, dst, src_len);
ok(cmp == 0, "Comparing encode-decode result");
if (cmp != 0)
{
diag(" --------- src --------- --------- dst ---------");
char buf[80];
for (k= 0; k<src_len; k+=8)
{
sprintf(buf, "%.4x ", (uint) k);
for (l=0; l<8 && k+l<src_len; l++)
{
unsigned char c= src[k+l];
sprintf(buf, "%.2x ", (unsigned)c);
}
sprintf(buf, " ");
for (l=0; l<8 && k+l<dst_len; l++)
{
unsigned char c= dst[k+l];
sprintf(buf, "%.2x ", (unsigned)c);
}
diag(buf);
}
diag("src length: %.8x, dst length: %.8x\n",
(uint) src_len, (uint) dst_len);
}
}
return exit_status();
}

View File

@ -1,10 +1,28 @@
/* Copyright (C) 2006 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
This test was copied from the unit test inside the
mysys/my_bitmap.c file and adapted by Mats Kindahl to use the mytap
library.
*/
#include <tap.h>
#include <my_global.h>
#include "my_bitmap.h"
#include <string.h>
#include <my_bitmap.h>
static void bitmap_print(MY_BITMAP *map)
{

1153
unittest/mytap/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include -I$(srcdir)
noinst_LIBRARIES = libmytap.a
noinst_HEADERS = tap.h
libmytap_a_SOURCES = tap.c
SUBDIRS = . t

View File

@ -0,0 +1,15 @@
AM_CPPFLAGS = -I$(srcdir) -I$(top_builddir)/include
AM_CPPFLAGS += -I$(srcdir)/..
AM_LDFLAGS = -L$(srcdir)/..
AM_CFLAGS = -Wall -ansi -pedantic
LDADD = -lmytap
noinst_PROGRAMS = basic.t
basic_t_SOURCES = basic.t.c
all: $(noinst_PROGRAMS)

View File

@ -0,0 +1,17 @@
#include <stdlib.h>
#include <tap.h>
int main() {
plan(5);
ok(1 == 1, "testing basic functions");
ok(2 == 2, "");
ok(3 == 3, NULL);
if (1 == 1)
skip(2, "Sensa fragoli");
else {
ok(1 == 2, "Should not be run at all");
ok(1, "This one neither");
}
return exit_status();
}

171
unittest/mytap/tap.c Normal file
View File

@ -0,0 +1,171 @@
#include "tap.h"
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
/**
Test data structure.
Data structure containing all information about the test suite.
*/
static TEST_DATA g_test = { 0 };
/**
Output stream for test report message.
The macro is just a temporary solution.
*/
#define tapout stdout
/**
Emit a TAP result and optionally a description.
@param pass 'true' if test passed, 'false' otherwise
@param fmt Description of test in printf() format.
@param ap Vararg list for the description string above.
*/
static int
emit_tap(int pass, char const *fmt, va_list ap)
{
fprintf(tapout, "%sok %d%s",
pass ? "" : "not ",
++g_test.last,
(fmt && *fmt) ? " - " : "");
if (fmt && *fmt)
vfprintf(tapout, fmt, ap);
}
static int
emit_dir(const char *dir, const char *exp)
{
fprintf(tapout, " # %s %s", dir, exp);
}
static int
emit_endl()
{
fprintf(tapout, "\n");
}
void
diag(char const *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fprintf(tapout, "# ");
vfprintf(tapout, fmt, ap);
fprintf(tapout, "\n");
va_end(ap);
}
void
plan(int const count)
{
g_test.plan= count;
switch (count)
{
case NO_PLAN:
case SKIP_ALL:
break;
default:
if (plan > 0)
fprintf(tapout, "1..%d\n", count);
break;
}
}
void
skip_all(char const *reason, ...)
{
va_list ap;
va_start(ap, reason);
fprintf(tapout, "1..0 # skip ");
vfprintf(tapout, reason, ap);
va_end(ap);
exit(0);
}
void
ok(int const pass, char const *fmt, ...)
{
if (!pass && *g_test.todo == '\0')
++g_test.failed;
va_list ap;
va_start(ap, fmt);
emit_tap(pass, fmt, ap);
va_end(ap);
if (*g_test.todo != '\0')
emit_dir("TODO", g_test.todo);
emit_endl();
}
void
skip(int how_many, char const *fmt, ...)
{
char reason[80];
if (fmt && *fmt)
{
va_list ap;
va_start(ap, fmt);
vsnprintf(reason, sizeof(reason), fmt, ap);
va_end(ap);
}
else
reason[0] = '\0';
while (how_many-- > 0)
{
va_list ap;
emit_tap(1, NULL, ap);
emit_dir("SKIP", reason);
emit_endl();
}
}
void
todo_start(char const *message, ...)
{
va_list ap;
va_start(ap, message);
vsnprintf(g_test.todo, sizeof(g_test.todo), message, ap);
va_end(ap);
}
void
todo_end()
{
*g_test.todo = '\0';
}
int exit_status() {
/*
If there were no plan, we write one last instead.
*/
if (g_test.plan == NO_PLAN)
plan(g_test.last);
if (g_test.plan != g_test.last)
{
diag("%d tests planned but only %d executed",
g_test.plan, g_test.last);
return EXIT_FAILURE;
}
if (g_test.failed > 0)
{
diag("Failed %d tests!", g_test.failed);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

187
unittest/mytap/tap.h Normal file
View File

@ -0,0 +1,187 @@
#ifndef TAP_H
#define TAP_H
/*
*/
#define NO_PLAN (0)
#define SKIP_ALL (-1)
/**
Data about test plan.
@internal We are using the "typedef struct X { ... } X" idiom to
create class/struct X both in C and C++.
*/
typedef struct TEST_DATA {
/**
Number of tests that is planned to execute.
Can be zero (<code>NO_PLAN</code>) meaning that the plan string
will be printed at the end of test instead.
*/
int plan;
/** Number of last test that was done or skipped. */
int last;
/** Number of tests that failed. */
int failed;
/** Todo reason. */
char todo[128];
} TEST_DATA;
#ifdef __cplusplus
extern "C" {
#endif
/**
Set number of tests that is planned to execute.
The function also accepts the predefined constants SKIP_ALL and
NO_PLAN.
@param count
The planned number of tests to run. Alternatively, the SKIP_ALL
and NO_PLAN can be supplied.
*/
void plan(int count);
/**
Report test result as a TAP line.
Function used to write status of an individual test. Call this
function in the following manner:
@code
ok(ducks == paddling,
"%d ducks did not paddle", ducks - paddling);
@endcode
@param pass Zero if the test failed, non-zero if it passed.
@param fmt Format string in printf() format. NULL is allowed, in
which case nothing is printed.
*/
void ok(int pass, char const *fmt, ...)
__attribute__ ((format(printf,2,3)));
/**
Skip a determined number of tests.
Function to print that <em>how_many</em> tests have been
skipped. The reason is printed for each skipped test. Observe
that this function does not do the actual skipping for you, it just
prints information that tests have been skipped. It shall be used
in the following manner:
@code
if (ducks == 0) {
skip(2, "No ducks in the pond");
} else {
int i;
for (i = 0 ; i < 2 ; ++i)
ok(duck[i] == paddling, "is duck %d paddling?", i);
}
@endcode
@see SKIP_BLOCK_IF
@param how_many Number of tests that are to be skipped.
@param reason A reason for skipping the tests
*/
void skip(int how_many, char const *reason, ...)
__attribute__ ((format(printf,2,3)));
/**
Helper macro to skip a block of code. The macro can be used to
simplify conditionally skipping a block of code. It is used in the
following manner:
@code
SKIP_BLOCK_IF(ducks == 0, 2, "No ducks in the pond")
{
int i;
for (i = 0 ; i < 2 ; ++i)
ok(duck[i] == paddling, "is duck %d paddling?", i);
}
@see skip
@endcode
*/
#define SKIP_BLOCK_IF(SKIP_IF_TRUE, COUNT, REASON) \
if (SKIP_IF_TRUE) skip((COUNT),(REASON)); else
/**
Print a diagnostics message.
@param fmt Diagnostics message in printf() format.
*/
void diag(char const *fmt, ...)
__attribute__ ((format(printf,1,2)));
/**
Print summary report and return exit status.
This function will print a summary report of how many tests passed,
how many were skipped, and how many remains to do. The function
should be called after all tests are executed in the following
manner:
@code
return exit_status();
@endcode
@returns EXIT_SUCCESS if all tests passed, EXIT_FAILURE if one or
more tests failed.
*/
int exit_status(void);
/**
Skip entire test suite.
To skip the entire test suite, use this function. It will
automatically call exit(), so there is no need to have checks
around it.
*/
void skip_all(char const *reason, ...)
__attribute__ ((noreturn, format(printf, 1, 2)));
/**
Start section of tests that are not yet ready.
To start a section of tests that are not ready and are expected to
fail, use this function and todo_end() in the following manner:
@code
todo_start("Not ready yet");
ok(is_rocketeering(duck), "Rocket-propelled ducks");
ok(is_kamikaze(duck), "Kamikaze ducks");
todo_end();
@endcode
@see todo_end
@note
It is not possible to nest todo sections.
@param message Message that will be printed before the todo tests.
*/
void todo_start(char const *message, ...)
__attribute__ ((format (printf, 1, 2)));
/**
End a section of tests that are not yet ready.
*/
void todo_end();
#ifdef __cplusplus
}
#endif
#endif /* TAP_H */