diff options
Diffstat (limited to 'unittest')
24 files changed, 1119 insertions, 179 deletions
diff --git a/unittest/examples/CMakeLists.txt b/unittest/examples/CMakeLists.txt new file mode 100644 index 00000000000..52272bc412e --- /dev/null +++ b/unittest/examples/CMakeLists.txt @@ -0,0 +1,37 @@ +# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# +# 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; version 2 of the License. +# +# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib + ${CMAKE_SOURCE_DIR}/sql + ${CMAKE_SOURCE_DIR}/regex + ${CMAKE_SOURCE_DIR}/extra/yassl/include + ${CMAKE_SOURCE_DIR}/unittest/mytap) +ADD_EXECUTABLE(simple-t simple-t.c) +TARGET_LINK_LIBRARIES(simple-t mytap) + +ADD_EXECUTABLE(skip-t skip-t.c) +TARGET_LINK_LIBRARIES(skip-t mytap) + +ADD_EXECUTABLE(todo-t todo-t.c) +TARGET_LINK_LIBRARIES(todo-t mytap) + +ADD_EXECUTABLE(skip_all-t skip_all-t.c) +TARGET_LINK_LIBRARIES(skip_all-t mytap) + +ADD_EXECUTABLE(no_plan-t no_plan-t.c) +TARGET_LINK_LIBRARIES(no_plan-t mytap) + +ADD_EXECUTABLE(core-t core-t.c) +TARGET_LINK_LIBRARIES(core-t mytap) diff --git a/unittest/examples/Makefile.am b/unittest/examples/Makefile.am deleted file mode 100644 index 77f7cf5bedd..00000000000 --- a/unittest/examples/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. -# -# 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; version 2 of the License. -# -# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -AM_CPPFLAGS = -I$(srcdir) -I$(top_builddir)/include \ - -I$(top_srcdir)/unittest/mytap -I$(top_srcdir)/include - -AM_LDFLAGS = -L$(top_builddir)/unittest/mytap - -LDADD = -lmytap - -# We omit core-t here, since it will always fail. -noinst_PROGRAMS = simple-t skip-t todo-t skip_all-t no_plan-t - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/unittest/examples/core-t.c b/unittest/examples/core-t.c index cafe2df9954..5f49e1cb1d9 100644 --- a/unittest/examples/core-t.c +++ b/unittest/examples/core-t.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2006 MySQL AB +/* Copyright (c) 2006 MySQL AB, 2009 Sun Microsystems, Inc. + Use is subject to license terms. 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 @@ -13,7 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "my_config.h" +#include <my_global.h> #include <stdlib.h> #include <tap.h> diff --git a/unittest/examples/no_plan-t.c b/unittest/examples/no_plan-t.c index f22340ae0d1..9aeb5c7666a 100644 --- a/unittest/examples/no_plan-t.c +++ b/unittest/examples/no_plan-t.c @@ -13,7 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "my_config.h" +#include <my_global.h> #include <stdlib.h> #include <tap.h> diff --git a/unittest/examples/skip-t.c b/unittest/examples/skip-t.c index 429994d55d8..aa105385c17 100644 --- a/unittest/examples/skip-t.c +++ b/unittest/examples/skip-t.c @@ -1,5 +1,4 @@ -/* - Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 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 @@ -12,8 +11,7 @@ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <tap.h> #include <stdlib.h> diff --git a/unittest/examples/skip_all-t.c b/unittest/examples/skip_all-t.c index 1f46af0afab..940d9f0186f 100644 --- a/unittest/examples/skip_all-t.c +++ b/unittest/examples/skip_all-t.c @@ -1,5 +1,4 @@ -/* - Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 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 @@ -12,10 +11,9 @@ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "my_config.h" +#include <my_global.h> #include <stdlib.h> #include <tap.h> diff --git a/unittest/examples/todo-t.c b/unittest/examples/todo-t.c index a457e0c49f9..53aaa1c2813 100644 --- a/unittest/examples/todo-t.c +++ b/unittest/examples/todo-t.c @@ -1,5 +1,4 @@ -/* - Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 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 @@ -12,10 +11,9 @@ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "my_config.h" +#include <my_global.h> #include <stdlib.h> #include <tap.h> diff --git a/unittest/Makefile.am b/unittest/mysys/CMakeLists.txt index d6bc3be979b..7bf046162c5 100644 --- a/unittest/Makefile.am +++ b/unittest/mysys/CMakeLists.txt @@ -1,30 +1,32 @@ # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. -# +# # 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; version 2 of the License. -# +# # 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -SUBDIRS = mytap . mysys examples strings +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/sql + ${CMAKE_SOURCE_DIR}/regex + ${CMAKE_SOURCE_DIR}/extra/yassl/include + ${CMAKE_SOURCE_DIR}/unittest/mytap) -EXTRA_DIST = unit.pl -CLEANFILES = unit -unittests = mytap mysys strings @mysql_se_unittest_dirs@ @mysql_pg_unittest_dirs@ +MACRO (MY_ADD_TEST name) + ADD_EXECUTABLE(${name}-t ${name}-t.c) + TARGET_LINK_LIBRARIES(${name}-t mytap mysys strings) + ADD_TEST(${name} ${name}-t) +ENDMACRO() -test: - perl unit.pl run $(unittests) -test-verbose: - HARNESS_VERBOSE=1 perl unit.pl run $(unittests) - -# Don't update the files from bitkeeper -%::SCCS/s.% +FOREACH(testname bitmap base64 my_vsnprintf my_atomic my_rdtsc lf my_malloc) + MY_ADD_TEST(${testname}) +ENDFOREACH() diff --git a/unittest/mysys/Makefile.am b/unittest/mysys/Makefile.am deleted file mode 100644 index bd6296fb28b..00000000000 --- a/unittest/mysys/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. -# -# 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; version 2 of the License. -# -# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -AM_CPPFLAGS = @ZLIB_INCLUDES@ -I$(top_builddir)/include -AM_CPPFLAGS += -I$(top_srcdir)/include -I$(top_srcdir)/unittest/mytap - -LDADD = $(top_builddir)/unittest/mytap/libmytap.a \ - $(top_builddir)/mysys/libmysys.a \ - $(top_builddir)/dbug/libdbug.a \ - $(top_builddir)/strings/libmystrings.a - -noinst_PROGRAMS = bitmap-t base64-t - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/unittest/mysys/base64-t.c b/unittest/mysys/base64-t.c index f9db4bc4776..c01d7cfdfa6 100644 --- a/unittest/mysys/base64-t.c +++ b/unittest/mysys/base64-t.c @@ -1,5 +1,4 @@ -/* - Copyright (c) 2006, 2007 MySQL AB, 2009 Sun Microsystems, Inc. +/* Copyright (c) 2003, 2006, 2007 MySQL AB, 2009 Sun Microsystems, Inc. Use is subject to license terms. This program is free software; you can redistribute it and/or @@ -13,8 +12,7 @@ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <my_global.h> #include <my_sys.h> diff --git a/unittest/mysys/bitmap-t.c b/unittest/mysys/bitmap-t.c index 1b3ef1ed180..a7bbd663598 100644 --- a/unittest/mysys/bitmap-t.c +++ b/unittest/mysys/bitmap-t.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. +/* + Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. 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 diff --git a/unittest/mysys/lf-t.c b/unittest/mysys/lf-t.c new file mode 100644 index 00000000000..573a56cc1d6 --- /dev/null +++ b/unittest/mysys/lf-t.c @@ -0,0 +1,194 @@ +/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. + + 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; version 2 of the License. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +/** + @file + + Unit tests for lock-free algorithms of mysys +*/ + +#include "thr_template.c" + +#include <lf.h> + +int32 inserts= 0, N; +LF_ALLOCATOR lf_allocator; +LF_HASH lf_hash; + +int with_my_thread_init=0; + +/* + pin allocator - alloc and release an element in a loop +*/ +pthread_handler_t test_lf_pinbox(void *arg) +{ + int m= *(int *)arg; + LF_PINS *pins; + + if (with_my_thread_init) + my_thread_init(); + + pins= lf_pinbox_get_pins(&lf_allocator.pinbox); + + for (; m ; m--) + { + lf_pinbox_put_pins(pins); + pins= lf_pinbox_get_pins(&lf_allocator.pinbox); + } + lf_pinbox_put_pins(pins); + pthread_mutex_lock(&mutex); + if (!--running_threads) pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); + + if (with_my_thread_init) + my_thread_end(); + + return 0; +} + +/* + thread local data area, allocated using lf_alloc. + union is required to enforce the minimum required element size (sizeof(ptr)) +*/ +typedef union { + int32 data; + void *not_used; +} TLA; + +pthread_handler_t test_lf_alloc(void *arg) +{ + int m= (*(int *)arg)/2; + int32 x,y= 0; + LF_PINS *pins; + + if (with_my_thread_init) + my_thread_init(); + + pins= lf_alloc_get_pins(&lf_allocator); + + for (x= ((int)(intptr)(&m)); m ; m--) + { + TLA *node1, *node2; + x= (x*m+0x87654321) & INT_MAX32; + node1= (TLA *)lf_alloc_new(pins); + node1->data= x; + y+= node1->data; + node1->data= 0; + node2= (TLA *)lf_alloc_new(pins); + node2->data= x; + y-= node2->data; + node2->data= 0; + lf_alloc_free(pins, node1); + lf_alloc_free(pins, node2); + } + lf_alloc_put_pins(pins); + pthread_mutex_lock(&mutex); + bad+= y; + + if (--N == 0) + { + diag("%d mallocs, %d pins in stack", + lf_allocator.mallocs, lf_allocator.pinbox.pins_in_array); +#ifdef MY_LF_EXTRA_DEBUG + bad|= lf_allocator.mallocs - lf_alloc_pool_count(&lf_allocator); +#endif + } + if (!--running_threads) pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); + + if (with_my_thread_init) + my_thread_end(); + return 0; +} + +#define N_TLH 1000 +pthread_handler_t test_lf_hash(void *arg) +{ + int m= (*(int *)arg)/(2*N_TLH); + int32 x,y,z,sum= 0, ins= 0; + LF_PINS *pins; + + if (with_my_thread_init) + my_thread_init(); + + pins= lf_hash_get_pins(&lf_hash); + + for (x= ((int)(intptr)(&m)); m ; m--) + { + int i; + y= x; + for (i= 0; i < N_TLH; i++) + { + x= (x*(m+i)+0x87654321) & INT_MAX32; + z= (x<0) ? -x : x; + if (lf_hash_insert(&lf_hash, pins, &z)) + { + sum+= z; + ins++; + } + } + for (i= 0; i < N_TLH; i++) + { + y= (y*(m+i)+0x87654321) & INT_MAX32; + z= (y<0) ? -y : y; + if (lf_hash_delete(&lf_hash, pins, (uchar *)&z, sizeof(z))) + sum-= z; + } + } + lf_hash_put_pins(pins); + pthread_mutex_lock(&mutex); + bad+= sum; + inserts+= ins; + + if (--N == 0) + { + diag("%d mallocs, %d pins in stack, %d hash size, %d inserts", + lf_hash.alloc.mallocs, lf_hash.alloc.pinbox.pins_in_array, + lf_hash.size, inserts); + bad|= lf_hash.count; + } + if (!--running_threads) pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); + if (with_my_thread_init) + my_thread_end(); + return 0; +} + + +void do_tests() +{ + plan(7); + + lf_alloc_init(&lf_allocator, sizeof(TLA), offsetof(TLA, not_used)); + lf_hash_init(&lf_hash, sizeof(int), LF_HASH_UNIQUE, 0, sizeof(int), 0, + &my_charset_bin); + + bad= my_atomic_initialize(); + ok(!bad, "my_atomic_initialize() returned %d", bad); + + with_my_thread_init= 1; + test_concurrently("lf_pinbox (with my_thread_init)", test_lf_pinbox, N= THREADS, CYCLES); + test_concurrently("lf_alloc (with my_thread_init)", test_lf_alloc, N= THREADS, CYCLES); + test_concurrently("lf_hash (with my_thread_init)", test_lf_hash, N= THREADS, CYCLES/10); + + with_my_thread_init= 0; + test_concurrently("lf_pinbox (without my_thread_init)", test_lf_pinbox, N= THREADS, CYCLES); + test_concurrently("lf_alloc (without my_thread_init)", test_lf_alloc, N= THREADS, CYCLES); + test_concurrently("lf_hash (without my_thread_init)", test_lf_hash, N= THREADS, CYCLES/10); + + lf_hash_destroy(&lf_hash); + lf_alloc_destroy(&lf_allocator); +} + diff --git a/unittest/mysys/my_atomic-t.c b/unittest/mysys/my_atomic-t.c new file mode 100644 index 00000000000..35e782eb360 --- /dev/null +++ b/unittest/mysys/my_atomic-t.c @@ -0,0 +1,183 @@ +/* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. + + 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; version 2 of the License. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "thr_template.c" + +volatile uint32 b32; +volatile int32 c32; +my_atomic_rwlock_t rwl; + +/* add and sub a random number in a loop. Must get 0 at the end */ +pthread_handler_t test_atomic_add(void *arg) +{ + int m= (*(int *)arg)/2; + int32 x; + for (x= ((int)(intptr)(&m)); m ; m--) + { + x= (x*m+0x87654321) & INT_MAX32; + my_atomic_rwlock_wrlock(&rwl); + my_atomic_add32(&bad, x); + my_atomic_rwlock_wrunlock(&rwl); + + my_atomic_rwlock_wrlock(&rwl); + my_atomic_add32(&bad, -x); + my_atomic_rwlock_wrunlock(&rwl); + } + pthread_mutex_lock(&mutex); + if (!--running_threads) pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); + return 0; +} + +volatile int64 a64; +/* add and sub a random number in a loop. Must get 0 at the end */ +pthread_handler_t test_atomic_add64(void *arg) +{ + int m= (*(int *)arg)/2; + int64 x; + for (x= ((int64)(intptr)(&m)); m ; m--) + { + x= (x*m+0xfdecba987654321LL) & INT_MAX64; + my_atomic_rwlock_wrlock(&rwl); + my_atomic_add64(&a64, x); + my_atomic_rwlock_wrunlock(&rwl); + + my_atomic_rwlock_wrlock(&rwl); + my_atomic_add64(&a64, -x); + my_atomic_rwlock_wrunlock(&rwl); + } + pthread_mutex_lock(&mutex); + if (!--running_threads) + { + bad= (a64 != 0); + pthread_cond_signal(&cond); + } + pthread_mutex_unlock(&mutex); + return 0; +} + + +/* + 1. generate thread number 0..N-1 from b32 + 2. add it to bad + 3. swap thread numbers in c32 + 4. (optionally) one more swap to avoid 0 as a result + 5. subtract result from bad + must get 0 in bad at the end +*/ +pthread_handler_t test_atomic_fas(void *arg) +{ + int m= *(int *)arg; + int32 x; + + my_atomic_rwlock_wrlock(&rwl); + x= my_atomic_add32(&b32, 1); + my_atomic_rwlock_wrunlock(&rwl); + + my_atomic_rwlock_wrlock(&rwl); + my_atomic_add32(&bad, x); + my_atomic_rwlock_wrunlock(&rwl); + + for (; m ; m--) + { + my_atomic_rwlock_wrlock(&rwl); + x= my_atomic_fas32(&c32, x); + my_atomic_rwlock_wrunlock(&rwl); + } + + if (!x) + { + my_atomic_rwlock_wrlock(&rwl); + x= my_atomic_fas32(&c32, x); + my_atomic_rwlock_wrunlock(&rwl); + } + + my_atomic_rwlock_wrlock(&rwl); + my_atomic_add32(&bad, -x); + my_atomic_rwlock_wrunlock(&rwl); + + pthread_mutex_lock(&mutex); + if (!--running_threads) pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); + return 0; +} + +/* + same as test_atomic_add, but my_atomic_add32 is emulated with + my_atomic_cas32 - notice that the slowdown is proportional to the + number of CPUs +*/ +pthread_handler_t test_atomic_cas(void *arg) +{ + int m= (*(int *)arg)/2, ok= 0; + int32 x, y; + for (x= ((int)(intptr)(&m)); m ; m--) + { + my_atomic_rwlock_wrlock(&rwl); + y= my_atomic_load32(&bad); + my_atomic_rwlock_wrunlock(&rwl); + x= (x*m+0x87654321) & INT_MAX32; + do { + my_atomic_rwlock_wrlock(&rwl); + ok= my_atomic_cas32(&bad, &y, (uint32)y+x); + my_atomic_rwlock_wrunlock(&rwl); + } while (!ok) ; + do { + my_atomic_rwlock_wrlock(&rwl); + ok= my_atomic_cas32(&bad, &y, y-x); + my_atomic_rwlock_wrunlock(&rwl); + } while (!ok) ; + } + pthread_mutex_lock(&mutex); + if (!--running_threads) pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); + return 0; +} + + +void do_tests() +{ + plan(6); + + bad= my_atomic_initialize(); + ok(!bad, "my_atomic_initialize() returned %d", bad); + + my_atomic_rwlock_init(&rwl); + + b32= c32= 0; + test_concurrently("my_atomic_add32", test_atomic_add, THREADS, CYCLES); + b32= c32= 0; + test_concurrently("my_atomic_fas32", test_atomic_fas, THREADS, CYCLES); + b32= c32= 0; + test_concurrently("my_atomic_cas32", test_atomic_cas, THREADS, CYCLES); + + { + /* + If b is not volatile, the wrong assembly code is generated on OSX Lion + as the variable is optimized away as a constant. + See Bug#62533 / Bug#13030056. + Another workaround is to specify architecture explicitly using e.g. + CFLAGS/CXXFLAGS= "-m64". + */ + volatile int64 b=0x1000200030004000LL; + a64=0; + my_atomic_add64(&a64, b); + ok(a64==b, "add64"); + } + a64=0; + test_concurrently("my_atomic_add64", test_atomic_add64, THREADS, CYCLES); + + my_atomic_rwlock_destroy(&rwl); +} diff --git a/unittest/mysys/my_malloc-t.c b/unittest/mysys/my_malloc-t.c new file mode 100644 index 00000000000..00cac0d21b7 --- /dev/null +++ b/unittest/mysys/my_malloc-t.c @@ -0,0 +1,43 @@ +/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + + 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; version 2 of the License. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include <my_global.h> +#include <my_sys.h> +#include "tap.h" + +int main(void) +{ + void *p; + MY_INIT("my_malloc-t"); + + plan(4); + + p= my_malloc(0, MYF(0)); + ok(p != NULL, "Zero-sized block allocation."); + + p= my_realloc(p, 32, MYF(0)); + ok(p != NULL, "Reallocated zero-sized block."); + + p= my_realloc(p, 16, MYF(0)); + ok(p != NULL, "Trimmed block."); + + my_free(p); + p= NULL; + + ok((my_free(p), 1), "Free NULL pointer."); + + return exit_status(); +} + diff --git a/unittest/mysys/my_rdtsc-t.c b/unittest/mysys/my_rdtsc-t.c new file mode 100644 index 00000000000..76a74a6fc09 --- /dev/null +++ b/unittest/mysys/my_rdtsc-t.c @@ -0,0 +1,230 @@ +/* Copyright (c) 2008 MySQL AB, 2009 Sun Microsystems, Inc. + Use is subject to license terms. + + 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; version 2 of the License. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +/* + rdtsc3 -- multi-platform timer code + pgulutzan@mysql.com, 2005-08-29 + modified 2008-11-02 + + When you run rdtsc3, it will print the contents of + "my_timer_info". The display indicates + what timer routine is best for a given platform. + + For example, this is the display on production.mysql.com, + a 2.8GHz Xeon with Linux 2.6.17, gcc 3.3.3: + + cycles nanoseconds microseconds milliseconds ticks +------------- ------------- ------------- ------------- ------------- + 1 11 13 18 17 + 2815019607 1000000000 1000000 1049 102 + 1 1000 1 1 1 + 88 4116 3888 4092 2044 + + The first line shows routines, e.g. 1 = MY_TIMER_ROUTINE_ASM_X86. + The second line shows frequencies, e.g. 2815019607 is nearly 2.8GHz. + The third line shows resolutions, e.g. 1000 = very poor resolution. + The fourth line shows overheads, e.g. ticks takes 2044 cycles. +*/ + +#include "my_global.h" +#include "my_rdtsc.h" +#include "tap.h" + +#define LOOP_COUNT 100 + +MY_TIMER_INFO myt; + +void test_init() +{ + my_timer_init(&myt); + + diag("----- Routine ---------------"); + diag("myt.cycles.routine : %13llu", myt.cycles.routine); + diag("myt.nanoseconds.routine : %13llu", myt.nanoseconds.routine); + diag("myt.microseconds.routine : %13llu", myt.microseconds.routine); + diag("myt.milliseconds.routine : %13llu", myt.milliseconds.routine); + diag("myt.ticks.routine : %13llu", myt.ticks.routine); + + diag("----- Frequency -------------"); + diag("myt.cycles.frequency : %13llu", myt.cycles.frequency); + diag("myt.nanoseconds.frequency : %13llu", myt.nanoseconds.frequency); + diag("myt.microseconds.frequency : %13llu", myt.microseconds.frequency); + diag("myt.milliseconds.frequency : %13llu", myt.milliseconds.frequency); + diag("myt.ticks.frequency : %13llu", myt.ticks.frequency); + + diag("----- Resolution ------------"); + diag("myt.cycles.resolution : %13llu", myt.cycles.resolution); + diag("myt.nanoseconds.resolution : %13llu", myt.nanoseconds.resolution); + diag("myt.microseconds.resolution : %13llu", myt.microseconds.resolution); + diag("myt.milliseconds.resolution : %13llu", myt.milliseconds.resolution); + diag("myt.ticks.resolution : %13llu", myt.ticks.resolution); + + diag("----- Overhead --------------"); + diag("myt.cycles.overhead : %13llu", myt.cycles.overhead); + diag("myt.nanoseconds.overhead : %13llu", myt.nanoseconds.overhead); + diag("myt.microseconds.overhead : %13llu", myt.microseconds.overhead); + diag("myt.milliseconds.overhead : %13llu", myt.milliseconds.overhead); + diag("myt.ticks.overhead : %13llu", myt.ticks.overhead); + + ok(1, "my_timer_init() did not crash"); +} + +void test_cycle() +{ + ulonglong t1= my_timer_cycles(); + ulonglong t2; + int i; + int backward= 0; + int nonzero= 0; + + for (i=0 ; i < LOOP_COUNT ; i++) + { + t2= my_timer_cycles(); + if (t1 >= t2) + backward++; + if (t2 != 0) + nonzero++; + t1= t2; + } + + /* Expect at most 1 backward, the cycle value can overflow */ + ok((backward <= 1), "The cycle timer is strictly increasing"); + + if (myt.cycles.routine != 0) + ok((nonzero != 0), "The cycle timer is implemented"); + else + ok((nonzero == 0), "The cycle timer is not implemented and returns 0"); +} + +void test_nanosecond() +{ + ulonglong t1= my_timer_nanoseconds(); + ulonglong t2; + int i; + int backward= 0; + int nonzero= 0; + + for (i=0 ; i < LOOP_COUNT ; i++) + { + t2= my_timer_nanoseconds(); + if (t1 > t2) + backward++; + if (t2 != 0) + nonzero++; + t1= t2; + } + + ok((backward == 0), "The nanosecond timer is increasing"); + + if (myt.nanoseconds.routine != 0) + ok((nonzero != 0), "The nanosecond timer is implemented"); + else + ok((nonzero == 0), "The nanosecond timer is not implemented and returns 0"); +} + +void test_microsecond() +{ + ulonglong t1= my_timer_microseconds(); + ulonglong t2; + int i; + int backward= 0; + int nonzero= 0; + + for (i=0 ; i < LOOP_COUNT ; i++) + { + t2= my_timer_microseconds(); + if (t1 > t2) + backward++; + if (t2 != 0) + nonzero++; + t1= t2; + } + + ok((backward == 0), "The microsecond timer is increasing"); + + if (myt.microseconds.routine != 0) + ok((nonzero != 0), "The microsecond timer is implemented"); + else + ok((nonzero == 0), "The microsecond timer is not implemented and returns 0"); +} + +void test_millisecond() +{ + ulonglong t1= my_timer_milliseconds(); + ulonglong t2; + int i; + int backward= 0; + int nonzero= 0; + + for (i=0 ; i < LOOP_COUNT ; i++) + { + t2= my_timer_milliseconds(); + if (t1 > t2) + backward++; + if (t2 != 0) + nonzero++; + t1= t2; + } + + ok((backward == 0), "The millisecond timer is increasing"); + + if (myt.milliseconds.routine != 0) + ok((nonzero != 0), "The millisecond timer is implemented"); + else + ok((nonzero == 0), "The millisecond timer is not implemented and returns 0"); +} + +void test_tick() +{ + ulonglong t1= my_timer_ticks(); + ulonglong t2; + int i; + int backward= 0; + int nonzero= 0; + + for (i=0 ; i < LOOP_COUNT ; i++) + { + t2= my_timer_ticks(); + if (t1 > t2) + backward++; + if (t2 != 0) + nonzero++; + t1= t2; + } + + ok((backward == 0), "The tick timer is increasing"); + + if (myt.ticks.routine != 0) + ok((nonzero != 0), "The tick timer is implemented"); + else + ok((nonzero == 0), "The tick timer is not implemented and returns 0"); +} + +int main(int argc __attribute__((unused)), + char ** argv __attribute__((unused))) +{ + plan(11); + + test_init(); + test_cycle(); + test_nanosecond(); + test_microsecond(); + test_millisecond(); + test_tick(); + + return 0; +} + diff --git a/unittest/mysys/my_vsnprintf-t.c b/unittest/mysys/my_vsnprintf-t.c new file mode 100644 index 00000000000..349e7469141 --- /dev/null +++ b/unittest/mysys/my_vsnprintf-t.c @@ -0,0 +1,184 @@ +/* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + + 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; version 2 of the License. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include <my_global.h> +#include <m_string.h> +#include <tap.h> + +char buf[1024]; /* let's hope that's enough */ + +void test1(const char *res, const char *fmt, ...) +{ + va_list args; + size_t len; + va_start(args,fmt); + len= my_vsnprintf(buf, sizeof(buf)-1, fmt, args); + va_end(args); + ok(strlen(res) == len && strcmp(buf, res) == 0, "\"%s\"", buf); +} + +int main(void) +{ + plan(58); + + test1("Constant string", + "Constant string"); + + test1("Format specifier s works", + "Format specifier s %s", "works"); + test1("Format specifier b works (mysql extension)", + "Format specifier b %.5b (mysql extension)", "works!!!"); + test1("Format specifier c !", + "Format specifier c %c", '!'); + test1("Format specifier d 1", + "Format specifier d %d", 1); + test1("Format specifier i 1", + "Format specifier i %i", 1); + test1("Format specifier u 2", + "Format specifier u %u", 2); + test1("Format specifier o 375", + "Format specifier o %o", 0375); + test1("Format specifier x a", + "Format specifier x %x", 10); + test1("Format specifier X B", + "Format specifier X %X", 11); + test1("Format specifier p 0x5", + "Format specifier p %p", 5); + test1("Format specifier f 3.141593", + "Format specifier f %f", 3.1415926); + test1("Format specifier g 3.1416", + "Format specifier g %g", 3.1415926); + + test1("Flag '-' is ignored < 1>", + "Flag '-' is ignored <%-4d>", 1); + test1("Flag '0' works <0006>", + "Flag '0' works <%04d>", 6); + + test1("Width is ignored for strings <x> <y>", + "Width is ignored for strings <%04s> <%5s>", "x", "y"); + + test1("Precision works for strings <abcde>", + "Precision works for strings <%.5s>", "abcdef!"); + + test1("Flag '`' (backtick) works: `abcd` `op``q` (mysql extension)", + "Flag '`' (backtick) works: %`s %`.4s (mysql extension)", + "abcd", "op`qrst"); + + test1("Length modifiers work: 1 * -1 * 2 * 3", + "Length modifiers work: %d * %ld * %lld * %zd", 1, -1L, 2LL, (size_t)3); + + test1("Length modifiers work: 1 * -1 * 2 * 3", + "Length modifiers work: %i * %li * %lli * %zd", 1, -1L, 2LL, (size_t)3); + + test1("long long X: 123456789abcdef0", + "long long X: %llx", 0x123456789abcdef0LL); + + test1("(null) pointer is fine", + "%s pointer is fine", NULL); + + test1("Positional arguments work: on the dark side they are", + "Positional arguments work: %3$s %1$s %2$s", + "they", "are", "on the dark side"); + + test1("Asterisk '*' as a width works: < 4>", + "Asterisk '*' as a width works: <%*d>", 5, 4); + + test1("Asterisk '*' as a precision works: <qwerty>", + "Asterisk '*' as a precision works: <%.*s>", 6, "qwertyuiop"); + + test1("Positional arguments for a width: < 4>", + "Positional arguments for a width: <%1$*2$d>", 4, 5); + + test1("Positional arguments for a precision: <qwerty>", + "Positional arguments for a precision: <%1$.*2$s>", "qwertyuiop", 6); + + test1("Positional arguments and a width: <0000ab>", + "Positional arguments and a width: <%1$06x>", 0xab); + + test1("Positional arguments octal: <7777>", + "Positional arguments octal: <%1$o>", 07777); + + /* Can't use int arguments, as they may be different size from pointers */ + + test1("Padding and %p <0x12> <0x034> <0x0000ab> < 0xcd>", + "Padding and %%p <%04p> <%05p> <%08p> <%8p>", + (void*) 0x12, (void*) 0x34, (void*) 0xab, (void*) 0xcd); + + test1("F with a width (ignored) and precision: <12.34568>", + "F with a width (ignored) and precision: <%10.5f>", 12.3456789); + test1("G with a width (ignored) and precision: <12.35>", + "G with a width (ignored) and precision: <%10.5g>", 12.3456789); + + diag("================================================================"); + + test1("Hello", + "Hello"); + test1("Hello int, 1", + "Hello int, %d", 1); + test1("Hello int, -1", + "Hello int, %d", -1); + test1("Hello int, 1", + "Hello int, %i", 1); + test1("Hello int, -1", + "Hello int, %i", -1); + test1("Hello string 'I am a string'", + "Hello string '%s'", "I am a string"); + test1("Hello hack hack hack hack hack hack hack 1", + "Hello hack hack hack hack hack hack hack %d", 1); + test1("Hello 1 hack 4", + "Hello %d hack %d", 1, 4); + test1("Hello 1 hack hack hack hack hack 4", + "Hello %d hack hack hack hack hack %d", 1, 4); + test1("Hello 'hack' hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", + "Hello '%s' hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh", "hack"); + test1("Hello hhhhhhhhhhhhhh 1 sssssssssssssss", + "Hello hhhhhhhhhhhhhh %d sssssssssssssss", 1); + test1("Hello 1", + "Hello %u", 1); + test1("Hello 4294967295", + "Hello %u", -1); + test1("Hex: 20 ' 41'", + "Hex: %lx '%6lx'", 32, 65); + test1("conn 1 to: '(null)' user: '(null)' host: '(null)' ((null))", + "conn %ld to: '%-.64s' user: '%-.32s' host: '%-.64s' (%-.64s)", + 1L, NULL, NULL, NULL, NULL); +#if defined (__GNUC__) + test1("Hello string `I am a string`", + "Hello string %`s", "I am a string"); +#endif + test1("Hello TEST", + "Hello %05s", "TEST"); + test1("My `Q` test", + "My %1$`-.1s test", "QQQQ"); + test1("My AAAA test done DDDD", + "My %2$s test done %1$s", "DDDD", "AAAA"); + test1("My DDDD test CCCC, DDD", + "My %1$s test %2$s, %1$-.3s", "DDDD", "CCCC"); + test1("My QQQQ test", + "My %1$`-.4b test", "QQQQ"); + test1("My X test", + "My %1$c test", 'X'); + test1("My <0000000010> test1 < a> test2 < A>", + "My <%010d> test1 <%4x> test2 <%4X>", 10, 10, 10); + test1("My <0000000010> test1 < a> test2 < a>", + "My <%1$010d> test1 <%2$4x> test2 <%2$4x>", 10, 10); + test1("My 00010 test", + "My %1$*02$d test", 10, 5); + test1("My `DDDD` test CCCC, `DDD`", + "My %1$`s test %2$s, %1$`-.3s", "DDDD", "CCCC"); + + return exit_status(); +} + diff --git a/unittest/mysys/thr_template.c b/unittest/mysys/thr_template.c new file mode 100644 index 00000000000..ed32bfee5eb --- /dev/null +++ b/unittest/mysys/thr_template.c @@ -0,0 +1,93 @@ +/* Copyright (c) 2006-2008 MySQL AB, 2009 Sun Microsystems, Inc. + Use is subject to license terms. + + 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; version 2 of the License. + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include <my_global.h> +#include <my_sys.h> +#include <my_atomic.h> +#include <tap.h> + +volatile uint32 bad; +pthread_attr_t thr_attr; +pthread_mutex_t mutex; +pthread_cond_t cond; +uint running_threads; + +void do_tests(); + +void test_concurrently(const char *test, pthread_handler handler, int n, int m) +{ + pthread_t t; + ulonglong now= my_getsystime(); + + bad= 0; + + diag("Testing %s with %d threads, %d iterations... ", test, n, m); + for (running_threads= n ; n ; n--) + { + if (pthread_create(&t, &thr_attr, handler, &m) != 0) + { + diag("Could not create thread"); + abort(); + } + } + pthread_mutex_lock(&mutex); + while (running_threads) + pthread_cond_wait(&cond, &mutex); + pthread_mutex_unlock(&mutex); + + now= my_getsystime()-now; + ok(!bad, "tested %s in %g secs (%d)", test, ((double)now)/1e7, bad); +} + +int main(int argc __attribute__((unused)), char **argv) +{ + MY_INIT("thd_template"); + + if (argv[1] && *argv[1]) + DBUG_SET_INITIAL(argv[1]); + + pthread_mutex_init(&mutex, 0); + pthread_cond_init(&cond, 0); + pthread_attr_init(&thr_attr); + pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); + +#ifdef MY_ATOMIC_MODE_RWLOCKS +#if defined(HPUX11) || defined(__POWERPC__) /* showed to be very slow (scheduler-related) */ +#define CYCLES 300 +#else +#define CYCLES 3000 +#endif +#else +#define CYCLES 3000 +#endif +#define THREADS 30 + + diag("N CPUs: %d, atomic ops: %s", my_getncpus(), MY_ATOMIC_MODE); + + do_tests(); + + /* + 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); + my_end(0); + return exit_status(); +} + diff --git a/unittest/mytap/Makefile.am b/unittest/mytap/CMakeLists.txt index 62f38a787fb..c4f213e338a 100644 --- a/unittest/mytap/Makefile.am +++ b/unittest/mytap/CMakeLists.txt @@ -1,26 +1,17 @@ -# Copyright (c) 2006, 2007 MySQL AB -# +# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# # 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; version 2 of the License. -# +# # 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -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 - -# Don't update the files from bitkeeper -%::SCCS/s.% +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +ADD_LIBRARY(mytap tap.c) diff --git a/unittest/mytap/t/Makefile.am b/unittest/mytap/t/Makefile.am deleted file mode 100644 index aa58f5a1d40..00000000000 --- a/unittest/mytap/t/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (c) 2006, 2007 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; version 2 of the License. -# -# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -AM_CPPFLAGS = -I$(srcdir) -I$(top_builddir)/include -I$(srcdir)/.. -I$(top_srcdir)/include - -AM_LDFLAGS = -L$(top_builddir)/unittest/mytap - -LDADD = -lmytap - -noinst_PROGRAMS = basic-t - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/unittest/mytap/t/basic-t.c b/unittest/mytap/t/basic-t.c index bae58143e1a..dcb13b20f11 100644 --- a/unittest/mytap/t/basic-t.c +++ b/unittest/mytap/t/basic-t.c @@ -1,5 +1,4 @@ -/* - Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 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 @@ -12,8 +11,7 @@ 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "my_config.h" diff --git a/unittest/mytap/tap.c b/unittest/mytap/tap.c index ef464c7b302..f7a6d881421 100644 --- a/unittest/mytap/tap.c +++ b/unittest/mytap/tap.c @@ -11,7 +11,7 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Library for providing TAP support for testing C and C++ was written by Mats Kindahl <mats@mysql.com>. @@ -19,7 +19,7 @@ #include "tap.h" -#include "my_config.h" +#include "my_global.h" #include <stdlib.h> #include <stdarg.h> @@ -27,6 +27,16 @@ #include <string.h> #include <signal.h> +/* + Visual Studio 2003 does not know vsnprintf but knows _vsnprintf. + We don't put this #define elsewhere because we prefer my_vsnprintf + everywhere instead, except when linking with libmysys is not + desirable - the case here. +*/ +#if defined(_MSC_VER) && ( _MSC_VER == 1310 ) +#define vsnprintf _vsnprintf +#endif + /** @defgroup MyTAP_Internal MyTAP Internals @@ -153,8 +163,10 @@ static signal_entry install_signal[]= { { SIGILL, handle_core_signal }, { SIGABRT, handle_core_signal }, { SIGFPE, handle_core_signal }, - { SIGSEGV, handle_core_signal }, - { SIGBUS, handle_core_signal } + { SIGSEGV, handle_core_signal } +#ifdef SIGBUS + , { SIGBUS, handle_core_signal } +#endif #ifdef SIGXCPU , { SIGXCPU, handle_core_signal } #endif @@ -169,13 +181,22 @@ static signal_entry install_signal[]= { #endif }; +int skip_big_tests= 1; + void -plan(int const count) +plan(int count) { + char *config= getenv("MYTAP_CONFIG"); + size_t i; + + if (config) + skip_big_tests= strcmp(config, "big"); + + setvbuf(tapout, 0, _IONBF, 0); /* provide output at once */ /* 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); @@ -208,7 +229,7 @@ skip_all(char const *reason, ...) } void -ok(int const pass, char const *fmt, ...) +ok(int pass, char const *fmt, ...) { va_list ap; va_start(ap, fmt); diff --git a/unittest/mytap/tap.h b/unittest/mytap/tap.h index 7e2b7434a3f..60d39c42441 100644 --- a/unittest/mytap/tap.h +++ b/unittest/mytap/tap.h @@ -11,7 +11,7 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Library for providing TAP support for testing C and C++ was written by Mats Kindahl <mats@mysql.com>. @@ -62,6 +62,24 @@ extern "C" { #endif /** + Defines whether "big" tests should be skipped. + + This variable is set by plan() function unless MYTAP_CONFIG environment + variable is set to the string "big". It is supposed to be used as + + @code + if (skip_big_tests) { + skip(1, "Big test skipped"); + } else { + ok(life_universe_and_everything() == 42, "The answer is CORRECT"); + } + @endcode + + @see SKIP_BIG_TESTS +*/ +extern int skip_big_tests; + +/** @defgroup MyTAP_API MyTAP API MySQL support for performing unit tests according to TAP. @@ -80,7 +98,12 @@ extern "C" { 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. + It will also set skip_big_tests variable if MYTAP_CONFIG environment + variable is defined. + + @see skip_big_tests + + @param count The planned number of tests to run. */ void plan(int const count); @@ -145,7 +168,7 @@ void ok1(int const pass); @param reason A reason for skipping the tests */ -void skip(int how_many, char const *reason, ...) +void skip(int how_many, char const *const reason, ...) __attribute__((format(printf,2,3))); @@ -171,6 +194,24 @@ void skip(int how_many, char const *reason, ...) /** + Helper macro to skip a group of "big" tests. It is used in the following + manner: + + @code + SKIP_BIG_TESTS(1) + { + ok(life_universe_and_everything() == 42, "The answer is CORRECT"); + } + @endcode + + @see skip_big_tests + */ + +#define SKIP_BIG_TESTS(COUNT) \ + if (skip_big_tests) skip((COUNT), "big test"); else + + +/** Print a diagnostics message. @param fmt Diagnostics message in printf() format. diff --git a/unittest/strings/Makefile.am b/unittest/strings/Makefile.am deleted file mode 100644 index 263416b94b1..00000000000 --- a/unittest/strings/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. -# -# 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; version 2 of the License. -# -# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -AM_CPPFLAGS = @ZLIB_INCLUDES@ -I$(top_builddir)/include -AM_CPPFLAGS += -I$(top_srcdir)/include -I$(top_srcdir)/unittest/mytap - -LDADD = $(top_builddir)/unittest/mytap/libmytap.a \ - $(top_builddir)/mysys/libmysys.a \ - $(top_builddir)/dbug/libdbug.a \ - $(top_builddir)/strings/libmystrings.a - -noinst_PROGRAMS = strings-t - -# Don't update the files from bitkeeper -%::SCCS/s.% diff --git a/unittest/unit.pl b/unittest/unit.pl index 9d328985012..81941d9fdd8 100644 --- a/unittest/unit.pl +++ b/unittest/unit.pl @@ -1,5 +1,6 @@ #!/usr/bin/perl -# Copyright (C) 2006 MySQL AB +# Copyright (c) 2006 MySQL AB, 2009, 2010 Sun Microsystems, Inc. +# Use is subject to license terms. # # 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 @@ -14,8 +15,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -use Test::Harness qw(&runtests $verbose); use File::Find; +use Getopt::Long; use strict; @@ -31,10 +32,20 @@ unit - Run unit tests in directory =head1 SYNOPSIS - unit run + unit [--[no]big] [--[no]verbose] run [tests to run] =cut +my $big= $ENV{'MYTAP_CONFIG'} eq 'big'; + +my $opt_verbose; +my $result = GetOptions ( + "big!" => \$big, + "verbose!" => \$opt_verbose, +); + +$ENV{'MYTAP_CONFIG'} = $big ? 'big' : ''; + my $cmd = shift; if (defined $cmd && exists $dispatch{$cmd}) { @@ -50,13 +61,26 @@ Run all unit tests in the current directory and all subdirectories. =cut +BEGIN { + # Test::Harness have been extensively rewritten in newer perl + # versions and is now just a backward compatibility wrapper + # (with a bug causing the HARNESS_PERL_SWITCHES to be mangled) + # Prefer to use TAP::Harness directly if available + if (eval "use TAP::Harness; 1") { + eval 'sub NEW_HARNESS { 1 }'; + warn "using TAP::Harness"; + } else { + eval "use Test::Harness; 1" or die "couldn't find Test::Harness!"; + eval 'sub NEW_HARNESS { 0 }'; + } +} sub _find_test_files (@) { my @dirs = @_; my @files; find sub { $File::Find::prune = 1 if /^SCCS$/; - push(@files, $File::Find::name) if -x _ && /-t\z/; + push(@files, $File::Find::name) if -x _ && (/-t\z/ || /-t\.exe\z/); }, @dirs; return @files; } @@ -92,8 +116,19 @@ sub run_cmd (@) { if (@files > 0) { # Removing the first './' from the file names foreach (@files) { s!^\./!! } - $ENV{'HARNESS_PERL_SWITCHES'} .= q" -e 'exec @ARGV'"; - runtests @files; + + if (NEW_HARNESS()) + { + my %args = ( exec => [ ], verbosity => $opt_verbose ); + my $harness = TAP::Harness->new( \%args ); + $harness->runtests(@files); + } + else + { + $ENV{'HARNESS_VERBOSE'} = $opt_verbose; + $ENV{'HARNESS_PERL_SWITCHES'} .= ' -e "exec @ARGV"'; + runtests(@files); + } } } |