summaryrefslogtreecommitdiff
path: root/unittest
diff options
context:
space:
mode:
Diffstat (limited to 'unittest')
-rw-r--r--unittest/Makefile.am13
-rw-r--r--unittest/README.txt7
-rw-r--r--unittest/examples/Makefile.am2
-rw-r--r--unittest/examples/core-t.c19
-rw-r--r--unittest/mysys/base64-t.c2
-rw-r--r--unittest/mysys/my_atomic-t.c20
-rw-r--r--unittest/mytap/tap.c49
-rw-r--r--unittest/mytap/tap.h48
8 files changed, 143 insertions, 17 deletions
diff --git a/unittest/Makefile.am b/unittest/Makefile.am
index ca3291efde0..7f1dd525d3b 100644
--- a/unittest/Makefile.am
+++ b/unittest/Makefile.am
@@ -1,15 +1,12 @@
SUBDIRS = mytap . mysys examples
-noinst_SCRIPTS = unit
EXTRA_DIST = unit.pl
CLEANFILES = unit
-unittests = mytap mysys
+unittests = mytap mysys @mysql_se_unittest_dirs@ @mysql_pg_unittest_dirs@
-test: unit
- ./unit run $(unittests)
-
-unit: $(srcdir)/unit.pl
- cp $(srcdir)/unit.pl $@
- chmod 700 $@
+test:
+ perl unit.pl run $(unittests)
+test-verbose:
+ HARNESS_VERBOSE=1 perl unit.pl run $(unittests)
diff --git a/unittest/README.txt b/unittest/README.txt
index 72f76c30b67..ea94a50595b 100644
--- a/unittest/README.txt
+++ b/unittest/README.txt
@@ -9,7 +9,9 @@ mytap Source for the MyTAP library
mysys Tests for mysys components
bitmap-t.c Unit test for MY_BITMAP
base64-t.c Unit test for base64 encoding functions
-examples Example unit tests
+examples Example unit tests.
+ core-t.c Example of raising a signal in the middle of the test
+ THIS TEST WILL STOP ALL FURTHER TESTING!
simple-t.c Example of a standard TAP unit test
skip-t.c Example where some test points are skipped
skip_all-t.c Example of a test where the entire test is skipped
@@ -24,6 +26,9 @@ To make and execute all unit tests in the directory:
make test
+Observe that the tests in the examples/ directory are just various
+examples of tests and are not expected to pass.
+
Adding unit tests
-----------------
diff --git a/unittest/examples/Makefile.am b/unittest/examples/Makefile.am
index f3c70b654a1..8aefb351220 100644
--- a/unittest/examples/Makefile.am
+++ b/unittest/examples/Makefile.am
@@ -5,5 +5,5 @@ AM_LDFLAGS = -L$(top_builddir)/unittest/mytap
LDADD = -lmytap
-noinst_PROGRAMS = simple-t skip-t todo-t skip_all-t no_plan-t
+noinst_PROGRAMS = simple-t skip-t todo-t skip_all-t no_plan-t core-t
diff --git a/unittest/examples/core-t.c b/unittest/examples/core-t.c
new file mode 100644
index 00000000000..3572d72868b
--- /dev/null
+++ b/unittest/examples/core-t.c
@@ -0,0 +1,19 @@
+
+#include "my_config.h"
+
+#include <stdlib.h>
+#include <tap.h>
+
+/*
+ This is a simple test to demonstrate what happens if a signal that
+ generates a core is raised.
+
+ Note that this test will stop all further testing!
+ */
+
+int main() {
+ plan(3);
+ ok(1, "First test");
+ abort();
+ return exit_status();
+}
diff --git a/unittest/mysys/base64-t.c b/unittest/mysys/base64-t.c
index 6d85964b20d..ccec0c77086 100644
--- a/unittest/mysys/base64-t.c
+++ b/unittest/mysys/base64-t.c
@@ -54,7 +54,7 @@ main(void)
/* Decode */
dst= (char *) malloc(base64_needed_decoded_length(strlen(str)));
- dst_len= base64_decode(str, strlen(str), dst);
+ dst_len= base64_decode(str, strlen(str), dst, NULL);
ok(dst_len == src_len, "Comparing lengths");
cmp= memcmp(src, dst, src_len);
diff --git a/unittest/mysys/my_atomic-t.c b/unittest/mysys/my_atomic-t.c
index 4e2e496c3b1..fe93b0942ce 100644
--- a/unittest/mysys/my_atomic-t.c
+++ b/unittest/mysys/my_atomic-t.c
@@ -32,7 +32,7 @@ pthread_handler_t test_atomic_add_handler(void *arg)
{
int m=*(int *)arg;
int32 x;
- for (x=((int)(&m)); m ; m--)
+ for (x=((int)((long)(&m))); m ; m--)
{
x=x*m+0x87654321;
my_atomic_rwlock_wrlock(&rwl);
@@ -104,7 +104,7 @@ pthread_handler_t test_atomic_cas_handler(void *arg)
{
int m=*(int *)arg, ok;
int32 x,y;
- for (x=((int)(&m)); m ; m--)
+ for (x=((int)((long)(&m))); m ; m--)
{
my_atomic_rwlock_wrlock(&rwl);
y=my_atomic_load32(&a32);
@@ -140,13 +140,21 @@ void test_atomic(const char *test, pthread_handler handler, int n, int m)
diag("Testing %s with %d threads, %d iterations... ", test, n, m);
for (N=n ; n ; n--)
- pthread_create(&t, &thr_attr, handler, &m);
+ {
+ if (pthread_create(&t, &thr_attr, handler, &m) != 0)
+ {
+ diag("Could not create thread");
+ a32= 1;
+ goto err;
+ }
+ }
pthread_mutex_lock(&mutex);
while (N)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
now=my_getsystime()-now;
+err:
ok(a32 == 0, "tested %s in %g secs", test, ((double)now)/1e7);
}
@@ -170,6 +178,12 @@ int main()
test_atomic("my_atomic_swap32", test_atomic_swap_handler, 100,10000);
test_atomic("my_atomic_cas32", test_atomic_cas_handler, 100,10000);
+ /*
+ workaround until we know why it crashes randomly on some machine
+ (BUG#22320).
+ */
+ sleep(2);
+
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
pthread_attr_destroy(&thr_attr);
diff --git a/unittest/mytap/tap.c b/unittest/mytap/tap.c
index 0bfa4b61094..fceac951aff 100644
--- a/unittest/mytap/tap.c
+++ b/unittest/mytap/tap.c
@@ -20,10 +20,13 @@
#include "tap.h"
+#include "my_config.h"
+
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
+#include <signal.h>
/**
@defgroup MyTAP_Internal MyTAP Internals
@@ -78,7 +81,7 @@ vemit_tap(int pass, char const *fmt, va_list ap)
/**
Emit a TAP directive.
- TAP directives are comments after a have the form
+ TAP directives are comments after that have the form:
@code
ok 1 # skip reason for skipping
@@ -108,6 +111,24 @@ emit_endl()
fprintf(tapout, "\n");
}
+static void
+handle_core_signal(int signo)
+{
+ BAIL_OUT("Signal %d thrown", signo);
+}
+
+void
+BAIL_OUT(char const *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ fprintf(tapout, "Bail out! ");
+ vfprintf(tapout, fmt, ap);
+ emit_endl();
+ va_end(ap);
+ exit(255);
+}
+
void
diag(char const *fmt, ...)
@@ -116,14 +137,38 @@ diag(char const *fmt, ...)
va_start(ap, fmt);
fprintf(tapout, "# ");
vfprintf(tapout, fmt, ap);
- fprintf(tapout, "\n");
+ emit_endl();
va_end(ap);
}
+typedef struct signal_entry {
+ int signo;
+ void (*handler)(int);
+} signal_entry;
+
+static signal_entry install_signal[]= {
+ { SIGQUIT, handle_core_signal },
+ { SIGILL, handle_core_signal },
+ { SIGABRT, handle_core_signal },
+ { SIGFPE, handle_core_signal },
+ { SIGSEGV, handle_core_signal },
+ { SIGBUS, handle_core_signal },
+ { SIGXCPU, handle_core_signal },
+ { SIGXFSZ, handle_core_signal },
+ { SIGSYS, handle_core_signal },
+ { SIGTRAP, handle_core_signal }
+};
void
plan(int const count)
{
+ /*
+ Install signal handler
+ */
+ size_t i;
+ for (i= 0; i < sizeof(install_signal)/sizeof(*install_signal); ++i)
+ signal(install_signal[i].signo, install_signal[i].handler);
+
g_test.plan= count;
switch (count)
{
diff --git a/unittest/mytap/tap.h b/unittest/mytap/tap.h
index ca2aa54a7ba..a47060fa3cc 100644
--- a/unittest/mytap/tap.h
+++ b/unittest/mytap/tap.h
@@ -23,6 +23,11 @@
#include "my_global.h"
+/*
+ @defgroup MyTAP MySQL support for performing unit tests according to
+ the Test Anything Protocol (TAP).
+*/
+
#define NO_PLAN (0)
/**
@@ -33,6 +38,7 @@
@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.
@@ -72,8 +78,13 @@ extern "C" {
it was called with <code>NO_PLAN</code>, i.e., the test plan will
be printed after all the test lines.
+ The plan() function will install signal handlers for all signals
+ that generate a core, so if you want to override these signals, do
+ it <em>after</em> you have called the plan() function.
+
@param count The planned number of tests to run.
*/
+
void plan(int count);
@@ -92,9 +103,11 @@ void plan(int count);
@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.
@@ -122,6 +135,7 @@ void ok(int pass, char const *fmt, ...)
@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)));
@@ -142,17 +156,43 @@ void skip(int how_many, char const *reason, ...)
@see skip
*/
+
#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 a bail out message.
+
+ A bail out message can be issued when no further testing can be
+ done, e.g., when there are missing dependencies.
+
+ The test will exit with status 255. This function does not return.
+
+ @code
+ BAIL_OUT("Lost connection to server %s", server_name);
+ @endcode
+
+ @note A bail out message is printed if a signal that generates a
+ core is raised.
+
+ @param fmt Bail out message in printf() format.
+*/
+
+void BAIL_OUT(char const *fmt, ...)
+ __attribute__((noreturn, format(printf,1,2)));
+
+
/**
Print summary report and return exit status.
@@ -168,6 +208,7 @@ void diag(char const *fmt, ...)
@returns @c EXIT_SUCCESS if all tests passed, @c EXIT_FAILURE if
one or more tests failed.
*/
+
int exit_status(void);
@@ -178,9 +219,11 @@ int exit_status(void);
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.
@@ -201,12 +244,15 @@ void skip_all(char const *reason, ...)
@param message Message that will be printed before the todo tests.
*/
+
void todo_start(char const *message, ...)
- __attribute__((format (printf, 1, 2)));
+ __attribute__((format(printf, 1, 2)));
+
/**
End a section of tests that are not yet ready.
*/
+
void todo_end();
/** @} */