diff options
Diffstat (limited to 'unittest')
-rw-r--r-- | unittest/mysys/CMakeLists.txt | 3 | ||||
-rw-r--r-- | unittest/mysys/aes-t.c | 99 | ||||
-rw-r--r-- | unittest/mysys/base64-t.c | 1 | ||||
-rw-r--r-- | unittest/mysys/lf-t.c | 23 | ||||
-rw-r--r-- | unittest/mysys/my_atomic-t.c | 34 | ||||
-rw-r--r-- | unittest/mysys/my_getopt-t.c | 390 | ||||
-rw-r--r-- | unittest/mysys/thr_template.c | 8 | ||||
-rw-r--r-- | unittest/mysys/waiting_threads-t.c | 2 | ||||
-rw-r--r-- | unittest/sql/CMakeLists.txt | 7 | ||||
-rw-r--r-- | unittest/sql/mf_iocache-t.cc | 398 | ||||
-rw-r--r-- | unittest/sql/my_apc-t.cc | 2 | ||||
-rw-r--r-- | unittest/strings/strings-t.c | 670 |
12 files changed, 1554 insertions, 83 deletions
diff --git a/unittest/mysys/CMakeLists.txt b/unittest/mysys/CMakeLists.txt index 41822b1e195..ad5195a843e 100644 --- a/unittest/mysys/CMakeLists.txt +++ b/unittest/mysys/CMakeLists.txt @@ -14,9 +14,12 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA MY_ADD_TESTS(bitmap base64 my_atomic my_rdtsc lf my_malloc my_getopt dynstring + aes LINK_LIBRARIES mysys) MY_ADD_TESTS(my_vsnprintf LINK_LIBRARIES strings mysys) +ADD_DEFINITIONS(${SSL_DEFINES}) + MY_ADD_TESTS(ma_dyncol LINK_LIBRARIES mysqlclient) diff --git a/unittest/mysys/aes-t.c b/unittest/mysys/aes-t.c new file mode 100644 index 00000000000..2d65b434cc3 --- /dev/null +++ b/unittest/mysys/aes-t.c @@ -0,0 +1,99 @@ +/* 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 + 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_crypt.h> +#include <tap.h> +#include <string.h> +#include <ctype.h> + +#define DO_TEST(mode, nopad, slen, fill, dlen, hash) \ + SKIP_BLOCK_IF(mode == 0xDEADBEAF, nopad ? 4 : 5, #mode " not supported") \ + { \ + memset(src, fill, src_len= slen); \ + ok(my_aes_crypt(mode, nopad | ENCRYPTION_FLAG_ENCRYPT, \ + src, src_len, dst, &dst_len, \ + key, sizeof(key), iv, sizeof(iv)) == MY_AES_OK, \ + "encrypt " #mode " %u %s", src_len, nopad ? "nopad" : "pad"); \ + if (!nopad) \ + ok (dst_len == my_aes_get_size(mode, src_len), "my_aes_get_size");\ + my_md5(md5, (char*)dst, dst_len); \ + ok(dst_len == dlen && memcmp(md5, hash, sizeof(md5)) == 0, "md5"); \ + ok(my_aes_crypt(mode, nopad | ENCRYPTION_FLAG_DECRYPT, \ + dst, dst_len, ddst, &ddst_len, \ + key, sizeof(key), iv, sizeof(iv)) == MY_AES_OK, \ + "decrypt " #mode " %u", dst_len); \ + ok(ddst_len == src_len && memcmp(src, ddst, src_len) == 0, "memcmp"); \ + } + +#define DO_TEST_P(M,S,F,D,H) DO_TEST(M,0,S,F,D,H) +#define DO_TEST_N(M,S,F,D,H) DO_TEST(M,ENCRYPTION_FLAG_NOPAD,S,F,D,H) + +/* useful macro for debugging */ +#define PRINT_MD5() \ + do { \ + uint i; \ + printf("\""); \ + for (i=0; i < sizeof(md5); i++) \ + printf("\\x%02x", md5[i]); \ + printf("\"\n"); \ + } while(0); + +#ifndef HAVE_EncryptAes128Ctr +const uint MY_AES_CTR=0xDEADBEAF; +#endif +#ifndef HAVE_EncryptAes128Gcm +const uint MY_AES_GCM=0xDEADBEAF; +#endif + +int +main(int argc __attribute__((unused)),char *argv[]) +{ + uchar key[16]= {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6}; + uchar iv[16]= {2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7}; + uchar src[1000], dst[1100], ddst[1000]; + uchar md5[MY_MD5_HASH_SIZE]; + uint src_len, dst_len, ddst_len; + + MY_INIT(argv[0]); + + plan(87); + DO_TEST_P(MY_AES_ECB, 200, '.', 208, "\xd8\x73\x8e\x3a\xbc\x66\x99\x13\x7f\x90\x23\x52\xee\x97\x6f\x9a"); + DO_TEST_P(MY_AES_ECB, 128, '?', 144, "\x19\x58\x33\x85\x4c\xaa\x7f\x06\xd1\xb2\xec\xd7\xb7\x6a\xa9\x5b"); + DO_TEST_P(MY_AES_CBC, 159, '%', 160, "\x4b\x03\x18\x3d\xf1\xa7\xcd\xa1\x46\xb3\xc6\x8a\x92\xc0\x0f\xc9"); + DO_TEST_P(MY_AES_CBC, 192, '@', 208, "\x54\xc4\x75\x1d\xff\xe0\xf6\x80\xf0\x85\xbb\x8b\xda\x07\x21\x17"); + DO_TEST_N(MY_AES_ECB, 200, '.', 200, "\xbf\xec\x43\xd1\x66\x8d\x01\xad\x3a\x25\xee\xa6\x3d\xc6\xc4\x68"); + DO_TEST_N(MY_AES_ECB, 128, '?', 128, "\x5b\x44\x20\xf3\xd9\xb4\x9d\x74\x5e\xb7\x5a\x0a\xe7\x32\x35\xc3"); + DO_TEST_N(MY_AES_CBC, 159, '%', 159, "\xf3\x6e\x40\x00\x3c\x08\xa0\xb1\x2d\x1f\xcf\xce\x54\xc9\x73\x83"); + DO_TEST_N(MY_AES_CBC, 192, '@', 192, "\x30\xe5\x28\x8c\x4a\x3b\x02\xd7\x56\x40\x59\x25\xac\x58\x09\x22"); + DO_TEST_P(MY_AES_CTR, 200, '.', 200, "\x5a\x77\x19\xea\x67\x50\xe3\xab\x7f\x39\x6f\xc4\xa8\x09\xc5\x88"); + DO_TEST_P(MY_AES_GCM, 128, '?', 144, "\x54\x6a\x7c\xa2\x04\xdc\x6e\x80\x1c\xcd\x5f\x7a\x7b\x08\x9e\x9d"); + + /* test short inputs (less that one block) */ + DO_TEST_P(MY_AES_ECB, 1, '.', 16, "\x6c\xd7\x66\x5b\x1b\x1e\x3a\x04\xfd\xb1\x91\x8d\x0e\xfd\xf1\x86"); + DO_TEST_P(MY_AES_ECB, 2, '?', 16, "\xdb\x84\x9e\xaf\x5f\xcc\xdb\x6b\xf2\x1c\xeb\x53\x75\xa3\x53\x5e"); + DO_TEST_P(MY_AES_CBC, 3, '%', 16, "\x60\x8e\x45\x9a\x07\x39\x63\xce\x02\x19\xdd\x52\xe3\x09\x2a\x66"); + DO_TEST_P(MY_AES_CBC, 4, '@', 16, "\x90\xc2\x6b\xf8\x84\x79\x83\xbd\xc1\x60\x71\x04\x55\x6a\xce\x9e"); + DO_TEST_N(MY_AES_ECB, 5, '.', 5, "\x6b\x60\xdc\xa4\x24\x9b\x02\xbb\x24\x41\x9b\xb0\xd1\x01\xcd\xba"); + DO_TEST_N(MY_AES_ECB, 6, '?', 6, "\x35\x8f\xb7\x9d\xd9\x61\x21\xcf\x25\x66\xd5\x9e\x91\xc1\x42\x7e"); + DO_TEST_N(MY_AES_CBC, 7, '%', 7, "\x94\x5e\x80\x71\x41\x7a\x64\x5d\x6f\x2e\x5b\x66\x9b\x5a\x3d\xda"); + DO_TEST_N(MY_AES_CBC, 8, '@', 8, "\xb8\x53\x97\xb9\x40\xa6\x98\xaf\x0c\x7b\x9a\xac\xad\x7e\x3c\xe0"); + DO_TEST_P(MY_AES_GCM, 9, '?', 25, "\x5e\x05\xfd\xb2\x8e\x17\x04\x1e\xff\x6d\x71\x81\xcd\x85\x8d\xb5"); + + my_end(0); + return exit_status(); +} diff --git a/unittest/mysys/base64-t.c b/unittest/mysys/base64-t.c index 60be4434150..a3a37976da6 100644 --- a/unittest/mysys/base64-t.c +++ b/unittest/mysys/base64-t.c @@ -16,7 +16,6 @@ #include <my_global.h> #include <my_sys.h> -#include <base64.h> #include <tap.h> #include <string.h> diff --git a/unittest/mysys/lf-t.c b/unittest/mysys/lf-t.c index c1c89f60864..80f58856940 100644 --- a/unittest/mysys/lf-t.c +++ b/unittest/mysys/lf-t.c @@ -109,11 +109,18 @@ pthread_handler_t test_lf_alloc(void *arg) return 0; } +my_bool do_sum(void *num, void *acc) +{ + *(int *)acc += *(int *)num; + 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; + int32 x,y,z,sum= 0, ins= 0, scans= 0; LF_PINS *pins; if (with_my_thread_init) @@ -134,6 +141,12 @@ pthread_handler_t test_lf_hash(void *arg) sum+= z; ins++; } + else + { + int unused= 0; + lf_hash_iterate(&lf_hash, pins, do_sum, &unused); + scans++; + } } for (i= 0; i < N_TLH; i++) { @@ -150,9 +163,9 @@ pthread_handler_t test_lf_hash(void *arg) if (--N == 0) { - diag("%d mallocs, %d pins in stack, %d hash size, %d inserts", + diag("%d mallocs, %d pins in stack, %d hash size, %d inserts, %d scans", lf_hash.alloc.mallocs, lf_hash.alloc.pinbox.pins_in_array, - lf_hash.size, inserts); + lf_hash.size, inserts, scans); bad|= lf_hash.count; } pthread_mutex_unlock(&mutex); @@ -176,12 +189,12 @@ void do_tests() 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); + test_concurrently("lf_hash (with my_thread_init)", test_lf_hash, N= THREADS, CYCLES); 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); + test_concurrently("lf_hash (without my_thread_init)", test_lf_hash, N= THREADS, CYCLES); 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 index 5eb988e2e15..3198da6836d 100644 --- a/unittest/mysys/my_atomic-t.c +++ b/unittest/mysys/my_atomic-t.c @@ -17,7 +17,6 @@ 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) @@ -27,13 +26,8 @@ pthread_handler_t test_atomic_add(void *arg) 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); } return 0; } @@ -47,13 +41,8 @@ pthread_handler_t test_atomic_add64(void *arg) 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); } return 0; } @@ -72,31 +61,17 @@ 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); return 0; } @@ -112,19 +87,13 @@ pthread_handler_t test_atomic_cas(void *arg) 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) ; } return 0; @@ -138,7 +107,6 @@ void do_tests() 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); @@ -163,6 +131,4 @@ void do_tests() a64=0; test_concurrently("my_atomic_add64", test_atomic_add64, THREADS, CYCLES); bad= (a64 != 0); - - my_atomic_rwlock_destroy(&rwl); } diff --git a/unittest/mysys/my_getopt-t.c b/unittest/mysys/my_getopt-t.c index afdb5e8b3b8..39814d76690 100644 --- a/unittest/mysys/my_getopt-t.c +++ b/unittest/mysys/my_getopt-t.c @@ -1,59 +1,386 @@ -/* Copyright (C) 2015 MariaDB +/* Copyright (c) 2015, MariaDB Corporation - 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. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: - 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. + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. - 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 */ + 2. Redistributions in binary form must the following disclaimer in + the documentation and/or other materials provided with the + distribution. -#include <tap.h> + THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +*/ + +#include <my_global.h> #include <my_getopt.h> +#include <mysys_err.h> #include <stdarg.h> +#include <tap.h> ulonglong opt_ull; ulong opt_ul; -int argc, res; -char **argv, *args[100]; +int arg_c, res; +char **arg_v, *arg_s[100]; -struct my_option my_long_options[]= +ulong mopts_num; +char *mopts_str; +my_bool mopts_bool; +static struct my_option mopts_options[]= { + {"str", 0, + "Something numeric.", + &mopts_str, &mopts_str, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"bool", 0, + "Something true or false", + &mopts_bool, &mopts_bool, 0, GET_BOOL, + OPT_ARG, FALSE, 0, 0, 0, 0, 0}, + {"num", 0, + "Something numeric.", + &mopts_num, &mopts_num, 0, GET_ULONG, + REQUIRED_ARG, 1000000L, 1, ULONG_MAX, 0, 2, 0}, {"ull", 0, "ull", &opt_ull, &opt_ull, 0, GET_ULL, REQUIRED_ARG, 1, 0, ~0ULL, 0, 0, 0}, {"ul", 0, "ul", &opt_ul, &opt_ul, 0, GET_ULONG, REQUIRED_ARG, 1, 0, 0xFFFFFFFF, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; void run(const char *arg, ...) { va_list ap; va_start(ap, arg); - argv= args; - *argv++= (char*)"<skipped>"; + arg_v= arg_s; + *arg_v++= (char*)"<skipped>"; while (arg) { - *argv++= (char*)arg; + *arg_v++= (char*)arg; arg= va_arg(ap, char*); } va_end(ap); - argc= argv - args; - argv= args; - res= handle_options(&argc, &argv, my_long_options, 0); + arg_c= arg_v - arg_s; + arg_v= arg_s; + res= handle_options(&arg_c, &arg_v, mopts_options, 0); +} + +int mopts1_argc= 4; +const char *mopts1_argv[]= {"mopts1", "--num=123", "--str=str", "--bool"}; +void test_mopts1() +{ + int rc; + char **av= (char **)mopts1_argv; + + rc= handle_options(&mopts1_argc, &av, mopts_options, NULL); + ok( (rc == 0), "%s", "test_mopts1 call"); + ok( (mopts_num == 122), "%s", "test_mopts1 num"); + ok( (strncmp(mopts_str, "str", 4) == 0), "%s", "test_mopts1 str"); + ok( (mopts_bool == 1), "%s", "test_mopts1 bool"); +} + +int mopts2_argc= 4; +const char *mopts2_argv[]= {"mopts2", "--num=123", "--num=124", "--bool=0"}; +void test_mopts2() +{ + int rc; + char **av= (char **)mopts2_argv; + + rc= handle_options(&mopts2_argc, &av, mopts_options, NULL); + ok( (rc == 0), "%s", "test_mopts2 call"); + ok( (mopts_num == 124), "%s", "test_mopts2 num"); + ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts2 str"); + ok( (mopts_bool == 0), "%s", "test_mopts2 bool"); +} + +int mopts3_argc= 4; +const char *mopts3_argv[]= {"mopts3", "--loose-foo", "--loose-loose-foo", "--enable-bool"}; +void test_mopts3() +{ + int rc; + char **av= (char **)mopts3_argv; + + rc= handle_options(&mopts3_argc, &av, mopts_options, NULL); + ok( (rc == 0), "%s", "test_mopts3 call"); + ok( (mopts_num == 1000000L), "%s", "test_mopts3 num"); + ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts3 str"); + ok( (mopts_bool == 1), "%s", "test_mopts3 bool"); +} + +int mopts4_argc= 3; +const char *mopts4_argv[]= {"mopts4", "--loose-str=aa", "--skip-bool"}; +void test_mopts4() +{ + int rc; + char **av= (char **)mopts4_argv; + + rc= handle_options(&mopts4_argc, &av, mopts_options, NULL); + ok( (rc == 0), "%s", "test_mopts4 call"); + ok( (mopts_num == 1000000L), "%s", "test_mopts4 num"); + ok( (strncmp(mopts_str, "aa", 3) == 0), "%s", "test_mopts4 str"); + ok( (mopts_bool == 0), "%s", "test_mopts4 bool"); +} + +int mopts5_argc= 2; +const char *mopts5_argv[]= {"mopts5", "--loose-skip-bool"}; +void test_mopts5() +{ + int rc; + char **av= (char **)mopts5_argv; + + rc= handle_options(&mopts5_argc, &av, mopts_options, NULL); + ok( (rc == 0), "%s", "test_mopts5 call"); + ok( (mopts_num == 1000000L), "%s", "test_mopts5 num"); + ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts5 str"); + ok( (mopts_bool == 0), "%s", "test_mopts5 bool"); +} + +int mopts6_argc= 2; +const char *mopts6_argv[]= {"mopts6", "--loose-skip-skip-bool"}; +void test_mopts6() +{ + int rc; + char **av= (char **)mopts6_argv; + + rc= handle_options(&mopts6_argc, &av, mopts_options, NULL); + ok( (rc == 0), "%s", "test_mopts6 call"); + ok( (mopts_num == 1000000L), "%s", "test_mopts6 num"); + ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts6 str"); + ok( (mopts_bool == 0), "%s", "test_mopts6 bool"); +} + +int mopts7_argc= 2; +const char *mopts7_argv[]= {"mopts7", "--loose-disable-skip-bool"}; +void test_mopts7() +{ + int rc; + char **av= (char **)mopts7_argv; + + rc= handle_options(&mopts7_argc, &av, mopts_options, NULL); + ok( (rc == 0), "%s", "test_mopts7 call"); + ok( (mopts_num == 1000000L), "%s", "test_mopts7 num"); + ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts7 str"); + ok( (mopts_bool == 0), "%s", "test_mopts7 bool"); +} + +int mopts8_argc= 2; +const char *mopts8_argv[]= {"mopts8", "--loose-disable-enable-bool"}; +void test_mopts8() +{ + int rc; + char **av= (char **)mopts8_argv; + + rc= handle_options(&mopts8_argc, &av, mopts_options, NULL); + ok( (rc == 0), "%s", "test_mopts8 call"); + ok( (mopts_num == 1000000L), "%s", "test_mopts7 num"); + ok( (strncmp(mopts_str, "ddd", 4) == 0), "%s", "test_mopts7 str"); + ok( (mopts_bool == 1), "%s", "test_mopts7 bool"); +} + +int mopts9_argc= 2; +const char *mopts9_argv[]= {"mopts9", "--foo"}; +void test_mopts9() +{ + int rc; + char **av= (char **)mopts9_argv; + + rc= handle_options(&mopts9_argc, &av, mopts_options, NULL); + ok( (rc != 0), "%s", "test_mopts9 call"); +} + +int mopts10_argc= 2; +const char *mopts10_argv[]= {"mopts10", "--skip-foo"}; +void test_mopts10() +{ + int rc; + char **av= (char **)mopts10_argv; + + rc= handle_options(&mopts10_argc, &av, mopts_options, NULL); + ok( (rc != 0), "%s", "test_mopts10 call"); +} + +ulong auto_num; +static struct my_option auto_options[]= +{ + {"anum", 0, + "Something numeric.", + &auto_num, &auto_num, 0, GET_ULONG | GET_AUTO, + REQUIRED_ARG, 1000000L, 1, ULONG_MAX, 0, 1, 0}, + {"num", 0, + "Something numeric.", + &mopts_num, &mopts_num, 0, GET_ULONG, + REQUIRED_ARG, 1000000L, 1, ULONG_MAX, 0, 1, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} +}; + + + +my_bool auto_get_one_option(int optid __attribute__((unused)), + const struct my_option *opt, + char *argument) +{ + if (argument == autoset_my_option) + { + *((ulong*)opt->value)= 111; + } + return FALSE; +} + +int auto1_argc= 3; +const char *auto1_argv[]= {"auto1", "--anum=123", "--autoset-anum"}; +void test_auto1() +{ + int rc; + char **av= (char **)auto1_argv; + + rc= handle_options(&auto1_argc, &av, auto_options, NULL); + ok( (rc == EXIT_ARGUMENT_INVALID), "%s", "test_auto1 call"); +} + +int auto2_argc= 3; +const char *auto2_argv[]= {"auto2", "--num=123", "--autoset-num"}; +void test_auto2() +{ + int rc; + char **av= (char **)auto2_argv; + + rc= handle_options(&auto2_argc, &av, auto_options, &auto_get_one_option); + ok( (rc == EXIT_ARGUMENT_INVALID), "%s", "test_auto2 call"); +} + +int auto3_argc= 3; +const char *auto3_argv[]= {"auto3", "--anum=123", "--autoset-anum"}; +void test_auto3() +{ + int rc; + char **av= (char **)auto3_argv; + + rc= handle_options(&auto3_argc, &av, auto_options, &auto_get_one_option); + ok( (rc == 0), "%s", "test_auto3 call"); + ok( (mopts_num == 1000000L), "%s", "test_auto3 num"); + ok( (auto_num == 111), "%s", "test_auto3 anum"); +} + +int auto4_argc= 3; +const char *auto4_argv[]= {"auto4", "--loose-autoset-num", "--loose-autoset-anum"}; +void test_auto4() +{ + int rc; + char **av= (char **)auto4_argv; + + rc= handle_options(&auto4_argc, &av, auto_options, &auto_get_one_option); + ok( (rc == 0), "%s", "test_auto4 call"); + ok( (mopts_num == 1000000L), "%s", "test_auto4 num"); + ok( (auto_num == 111), "%s", "test_auto4 anum"); +} + +int auto5_argc= 3; +const char *auto5_argv[]= {"auto5", "--autoset-loose-num", "--autoset-loose-anum"}; +void test_auto5() +{ + int rc; + char **av= (char **)auto5_argv; + + rc= handle_options(&auto5_argc, &av, auto_options, &auto_get_one_option); + ok( (rc == 0), "%s", "test_auto5 call"); + ok( (mopts_num == 1000000L), "%s", "test_auto5 num"); + ok( (auto_num == 111), "%s", "test_auto5 anum"); +} + +int auto6_argc= 3; +const char *auto6_argv[]= {"auto6", "--autoset-anum", "--anum=123"}; +void test_auto6() +{ + int rc; + char **av= (char **)auto6_argv; + + rc= handle_options(&auto6_argc, &av, auto_options, &auto_get_one_option); + ok( (rc == 0), "%s", "test_auto6 call"); + ok( (mopts_num == 1000000L), "%s", "test_auto6 num"); + ok( (auto_num == 123), "%s", "test_auto6 anum"); +} + + +ulong max_num= ULONG_MAX; +static struct my_option max_options[]= +{ + {"num", 0, + "Something numeric.", + &mopts_num, &max_num, 0, GET_ULONG, + REQUIRED_ARG, 1000000L, 1, 1000001L, 0, 1, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} +}; + +int max1_argc= 3; +const char *max1_argv[]= {"max1", "--num=100", "--num=200"}; +void test_max1() +{ + int rc; + char **av= (char **)max1_argv; + + rc= handle_options(&max1_argc, &av, max_options, NULL); + ok( (rc == 0), "%s", "test_max1 call"); + ok( (mopts_num == 200), "%s", "test_max1 num"); + ok( (max_num == 1000001L), "%s", "test_max1 max_num"); +} +int max2_argc= 3; +const char *max2_argv[]= {"max2", "--maximum-num=100", "--num=200"}; +void test_max2() +{ + int rc; + char **av= (char **)max2_argv; + + rc= handle_options(&max2_argc, &av, max_options, NULL); + ok( (rc == 0), "%s", "test_max2 call"); + ok( (mopts_num == 200), "%s", "test_max2 num"); + ok( (max_num == 100), "%s", "test_max2 max_num"); } -int main() { - plan(3); +int main(int argc __attribute__((unused)), char **argv) +{ + MY_INIT(argv[0]); + plan(4*8 + 1*4 + 3*4 + 3*2 + 3); + + /* gcc 4.1.2 doesn't want it in the initializer, we have to do it run-time */ + mopts_options[0].def_value= (intptr)"ddd"; + + test_mopts1(); + test_mopts2(); + test_mopts3(); + test_mopts4(); + test_mopts5(); + test_mopts6(); + test_mopts7(); + test_mopts8(); + + test_mopts9(); + test_mopts10(); + test_auto1(); + test_auto2(); + + test_auto3(); + test_auto4(); + test_auto5(); + test_auto6(); + + test_max1(); + test_max2(); run("--ull=100", NULL); - ok(res==0 && argc==0 && opt_ull==100, - "res:%d, argc:%d, opt_ull:%llu", res, argc, opt_ull); + ok(res==0 && arg_c==0 && opt_ull==100, + "res:%d, argc:%d, opt_ull:%llu", res, arg_c, opt_ull); /* negative numbers are wrapped. this is kinda questionable, @@ -61,11 +388,12 @@ int main() { users might've got used to "-1" meaning "max possible value" */ run("--ull=-100", NULL); - ok(res==0 && argc==0 && opt_ull==18446744073709551516ULL, - "res:%d, argc:%d, opt_ull:%llu", res, argc, opt_ull); + ok(res==0 && arg_c==0 && opt_ull==18446744073709551516ULL, + "res:%d, argc:%d, opt_ull:%llu", res, arg_c, opt_ull); run("--ul=-100", NULL); - ok(res==0 && argc==0 && opt_ul==4294967295UL, - "res:%d, argc:%d, opt_ul:%lu", res, argc, opt_ul); + ok(res==0 && arg_c==0 && opt_ul==4294967295UL, + "res:%d, argc:%d, opt_ul:%lu", res, arg_c, opt_ul); + + my_end(0); return exit_status(); } - diff --git a/unittest/mysys/thr_template.c b/unittest/mysys/thr_template.c index d1bc0868ca0..de68aca6d36 100644 --- a/unittest/mysys/thr_template.c +++ b/unittest/mysys/thr_template.c @@ -60,15 +60,7 @@ int main(int argc __attribute__((unused)), char **argv) pthread_mutex_init(&mutex, 0); -#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); diff --git a/unittest/mysys/waiting_threads-t.c b/unittest/mysys/waiting_threads-t.c index eca6ba408c3..ac481e0fe99 100644 --- a/unittest/mysys/waiting_threads-t.c +++ b/unittest/mysys/waiting_threads-t.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #include "thr_template.c" #include <waiting_threads.h> diff --git a/unittest/sql/CMakeLists.txt b/unittest/sql/CMakeLists.txt index 1c9df7b1fa4..cd2ba9b3d2f 100644 --- a/unittest/sql/CMakeLists.txt +++ b/unittest/sql/CMakeLists.txt @@ -28,4 +28,9 @@ ELSE() ENDIF() TARGET_LINK_LIBRARIES(explain_filename-t sql mytap) -ADD_TEST(explain_filename explain_filename-t) +MY_ADD_TEST(explain_filename) + +ADD_EXECUTABLE(mf_iocache-t mf_iocache-t.cc ../../sql/mf_iocache_encr.cc) +TARGET_LINK_LIBRARIES(mf_iocache-t mysys mytap) +ADD_DEPENDENCIES(mf_iocache-t GenError) +MY_ADD_TEST(mf_iocache) diff --git a/unittest/sql/mf_iocache-t.cc b/unittest/sql/mf_iocache-t.cc new file mode 100644 index 00000000000..1eef8365074 --- /dev/null +++ b/unittest/sql/mf_iocache-t.cc @@ -0,0 +1,398 @@ +/* Copyright (C) 2015 MariaDB + + 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 Street, Fifth Floor, Boston, MA 02111-1301 USA */ + +#include <my_sys.h> +#include <my_crypt.h> +#include <tap.h> + +/*** tweaks and stubs for encryption code to compile ***************/ +#define KEY_SIZE (128/8) + +my_bool encrypt_tmp_files; +int init_io_cache_encryption(); + +uint encryption_key_get_latest_version_func(uint) +{ + return 1; +} + +uint encryption_key_id_exists_func(uint) +{ + return 1; +} + +uint encryption_key_version_exists_func(uint, uint) +{ + return 1; +} + +uint encryption_key_get_func(uint, uint, uchar* key, uint* size) +{ + if (*size < KEY_SIZE) + { + *size= KEY_SIZE; + return ENCRYPTION_KEY_BUFFER_TOO_SMALL; + } + memset(key, KEY_SIZE, *size= KEY_SIZE); + return 0; +} + +#ifdef HAVE_EncryptAes128Gcm +enum my_aes_mode aes_mode= MY_AES_GCM; +#else +enum my_aes_mode aes_mode= MY_AES_CBC; +#endif + +int encryption_ctx_init_func(void *ctx, const unsigned char* key, unsigned int klen, + const unsigned char* iv, unsigned int ivlen, + int flags, unsigned int key_id, + unsigned int key_version) +{ + return my_aes_crypt_init(ctx, aes_mode, flags, key, klen, iv, ivlen); +} + +uint encryption_encrypted_length_func(unsigned int slen, unsigned int key_id, unsigned int key_version) +{ + return my_aes_get_size(aes_mode, slen); +} + +struct encryption_service_st encryption_handler= +{ + encryption_key_get_latest_version_func, + encryption_key_get_func, + (uint (*)(unsigned int, unsigned int))my_aes_ctx_size, + encryption_ctx_init_func, + my_aes_crypt_update, + my_aes_crypt_finish, + encryption_encrypted_length_func +}; + +void sql_print_information(const char *format, ...) +{ +} + +void sql_print_error(const char *format, ...) +{ +} + +/*** end of encryption tweaks and stubs ****************************/ + +IO_CACHE info; +#define CACHE_SIZE 16384 + +#define INFO_TAIL ", pos_in_file = %llu, pos_in_mem = %td", \ + info.pos_in_file, *info.current_pos - info.request_pos + +#define FILL 0x5A + +int data_bad(const uchar *buf, size_t len) +{ + const uchar *end= buf + len; + while (buf < end) + if (*buf++ != FILL) + return 1; + return 0; +} + +void temp_io_cache() +{ + int res; + uchar buf[CACHE_SIZE + 200]; + memset(buf, FILL, sizeof(buf)); + + diag("temp io_cache with%s encryption", encrypt_tmp_files?"":"out"); + + init_io_cache_encryption(); + + res= open_cached_file(&info, 0, 0, CACHE_SIZE, 0); + ok(res == 0, "open_cached_file" INFO_TAIL); + + res= my_b_write(&info, buf, 100); + ok(res == 0 && info.pos_in_file == 0, "small write" INFO_TAIL ); + + res= my_b_write(&info, buf, sizeof(buf)); + ok(res == 0 && info.pos_in_file == CACHE_SIZE, "large write" INFO_TAIL); + + res= reinit_io_cache(&info, WRITE_CACHE, 250, 0, 0); + ok(res == 0, "reinit with rewind" INFO_TAIL); + + res= my_b_write(&info, buf, sizeof(buf)); + ok(res == 0, "large write" INFO_TAIL); + + res= my_b_flush_io_cache(&info, 1); + ok(res == 0, "flush" INFO_TAIL); + + res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0); + ok(res == 0, "reinit READ_CACHE" INFO_TAIL); + + res= my_pread(info.file, buf, 50, 50, MYF(MY_NABP)); + ok(res == 0 && data_bad(buf, 50) == encrypt_tmp_files, + "file must be %sreadable", encrypt_tmp_files ?"un":""); + + res= my_b_read(&info, buf, 50) || data_bad(buf, 50); + ok(res == 0 && info.pos_in_file == 0, "small read" INFO_TAIL); + + res= my_b_read(&info, buf, sizeof(buf)) || data_bad(buf, sizeof(buf)); + ok(res == 0 && info.pos_in_file == CACHE_SIZE, "large read" INFO_TAIL); + + close_cached_file(&info); +} + +void mdev9044() +{ + int res; + uchar buf[CACHE_SIZE + 200]; + + diag("MDEV-9044 Binlog corruption in Galera"); + + res= open_cached_file(&info, 0, 0, CACHE_SIZE, 0); + ok(res == 0, "open_cached_file" INFO_TAIL); + + res= my_b_write(&info, USTRING_WITH_LEN("first write\0")); + ok(res == 0, "first write" INFO_TAIL); + + res= my_b_flush_io_cache(&info, 1); + ok(res == 0, "flush" INFO_TAIL); + + res= reinit_io_cache(&info, WRITE_CACHE, 0, 0, 0); + ok(res == 0, "reinit WRITE_CACHE" INFO_TAIL); + + res= my_b_write(&info, USTRING_WITH_LEN("second write\0")); + ok(res == 0, "second write" INFO_TAIL ); + + res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0); + ok(res == 0, "reinit READ_CACHE" INFO_TAIL); + + res= my_b_fill(&info); + ok(res == 0, "fill" INFO_TAIL); + + res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0); + ok(res == 0, "reinit READ_CACHE" INFO_TAIL); + + res= my_b_read(&info, buf, sizeof(buf)); + ok(res == 1 && strcmp((char*)buf, "second write") == 0, "read '%s'", buf); + + close_cached_file(&info); +} + +/* 2 Reads (with my_b_fill) in cache makes second read to fail */ +void mdev10259() +{ + int res; + uchar buf[200]; + memset(buf, FILL, sizeof(buf)); + + diag("MDEV-10259- mysqld crash with certain statement length and order with" + " Galera and encrypt-tmp-files=1"); + + init_io_cache_encryption(); + + res= open_cached_file(&info, 0, 0, CACHE_SIZE, 0); + ok(res == 0, "open_cached_file" INFO_TAIL); + + res= my_b_write(&info, buf, sizeof(buf)); + ok(res == 0 && info.pos_in_file == 0, "200 write" INFO_TAIL); + + res= my_b_flush_io_cache(&info, 1); + ok(res == 0, "flush" INFO_TAIL); + + ulong saved_pos= my_b_tell(&info); + res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0); + ok(res == 0, "reinit READ_CACHE" INFO_TAIL); + + res= my_b_fill(&info); + ok(res == 200, "fill" INFO_TAIL); + + res= my_b_fill(&info); + ok(res == 0, "fill" INFO_TAIL); + + res= my_b_fill(&info); + ok(res == 0, "fill" INFO_TAIL); + + res= reinit_io_cache(&info, WRITE_CACHE, saved_pos, 0, 0); + ok(res == 0, "reinit WRITE_CACHE" INFO_TAIL); + + res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0); + ok(res == 0, "reinit READ_CACHE" INFO_TAIL); + + ok(200 == my_b_bytes_in_cache(&info),"my_b_bytes_in_cache == 200"); + + res= my_b_fill(&info); + ok(res == 0, "fill" INFO_TAIL); + + res= my_b_fill(&info); + ok(res == 0, "fill" INFO_TAIL); + + res= my_b_fill(&info); + ok(res == 0, "fill" INFO_TAIL); + + res= reinit_io_cache(&info, WRITE_CACHE, saved_pos, 0, 0); + ok(res == 0, "reinit WRITE_CACHE" INFO_TAIL); + + res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0); + ok(res == 0, "reinit READ_CACHE" INFO_TAIL); + + ok(200 == my_b_bytes_in_cache(&info),"my_b_bytes_in_cache == 200"); + + res= my_b_read(&info, buf, sizeof(buf)) || data_bad(buf, sizeof(buf)); + ok(res == 0 && info.pos_in_file == 0, "large read" INFO_TAIL); + + close_cached_file(&info); + +} + +void mdev14014() +{ + int res; + uchar buf_o[200]; + uchar buf_i[200]; + memset(buf_i, 0, sizeof( buf_i)); + memset(buf_o, FILL, sizeof(buf_o)); + + diag("MDEV-14014 Dump thread reads past last 'officially' written byte"); + + init_io_cache_encryption(); + + res= open_cached_file(&info, 0, 0, CACHE_SIZE, 0); + ok(res == 0, "open_cached_file" INFO_TAIL); + + res= my_b_write(&info, buf_o, sizeof(buf_o)); + ok(res == 0, "buffer is written" INFO_TAIL); + + res= my_b_flush_io_cache(&info, 1); + ok(res == 0, "flush" INFO_TAIL); + + res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0); + ok(res == 0, "reinit READ_CACHE" INFO_TAIL); + + info.end_of_file= 100; + res= my_b_read(&info, buf_i, sizeof(buf_i)); + ok(res == 1 && buf_i[100] == 0 && buf_i[200-1] == 0, + "short read leaves buf_i[100..200-1] == 0"); + + close_cached_file(&info); +} + +void mdev17133() +{ + int res, k; + const int eof_iter=4, read_iter= 4; + uchar buf_i[1024*256]; // read + uchar buf_o[sizeof(buf_i)]; // write + const size_t eof_block_size= sizeof(buf_o) / eof_iter; + const size_t read_size= eof_block_size / read_iter; + size_t total; + + srand((uint) time(NULL)); + memset(buf_i, 0, sizeof( buf_i)); + memset(buf_o, FILL, sizeof(buf_o)); + + diag("MDEV-17133 Dump thread reads from the past"); + + init_io_cache_encryption(); + + res= open_cached_file(&info, 0, 0, CACHE_SIZE, 0); + ok(res == 0, "open_cached_file" INFO_TAIL); + + res= my_b_write(&info, buf_o, sizeof(buf_o)); + ok(res == 0, "buffer is written" INFO_TAIL); + res= my_b_tell(&info); + ok(res == sizeof(buf_o), "cache size as expected"); + + res= my_b_flush_io_cache(&info, 1); + ok(res == 0, "flush" INFO_TAIL); + res= reinit_io_cache(&info, READ_CACHE, 0, 0, 0); + ok(res == 0, "reinit READ_CACHE" INFO_TAIL); + + // read the written data by chunks of variable size eof_iter times + for (k= eof_iter, info.end_of_file=0, total= 0; k; k--) + { + int i; + size_t curr_read_size; + info.end_of_file= + k == 1 ? sizeof(buf_o) : + MY_MIN(sizeof(buf_o), + info.end_of_file + eof_block_size + + // plus 25% of block for randomization to the average + eof_block_size/4 - rand() % (eof_block_size/2)); + + // read a chunk by blocks of variable size read_iter times + // the last block completes the current chunk + for (i= 0; i < read_iter; i++, total += curr_read_size) + { + char buf_check[eof_block_size]; + uint a,b; + + a= info.end_of_file - total; + b= read_size + read_size/4 - rand() % (read_size/2); + curr_read_size= (i == read_iter - 1) ? info.end_of_file - total : + MY_MIN(a, b); + + DBUG_ASSERT(curr_read_size <= info.end_of_file - total); + + res= my_b_read(&info, buf_i + total, MY_MIN(19, curr_read_size)); + ok(res == 0, "read of 19"); + // mark read bytes in the used part of the cache buffer + memset(info.buffer, 0, info.read_pos - info.buffer); + + // random size 2nd read + res= my_b_read(&info, buf_i + total + MY_MIN(19, curr_read_size), + 19 >= curr_read_size ? 0 : curr_read_size - 19); + ok(res == 0, "rest of read %lu", curr_read_size - 19); + // mark read bytes in the used part of the cache buffer + memset(info.buffer, 0, info.read_pos - info.buffer); + + // check that no marked bytes are read + memset(buf_check, FILL, curr_read_size); + ok(memcmp(buf_i + total, buf_check, curr_read_size) == 0, + "read correct data"); + } + ok(info.pos_in_file + (info.read_end - info.buffer) == info.end_of_file, + "cache is read up to eof"); + ok(total == info.end_of_file, "total matches eof"); + } + ok(total == sizeof(buf_i), "read total size match"); + ok(buf_i[sizeof(buf_i) - 1] == FILL, "data read correctly"); + + close_cached_file(&info); +} + + +int main(int argc __attribute__((unused)),char *argv[]) +{ + MY_INIT(argv[0]); + plan(114); + + /* temp files with and without encryption */ + encrypt_tmp_files= 1; + temp_io_cache(); + + encrypt_tmp_files= 0; + temp_io_cache(); + + /* regression tests */ + mdev9044(); + + encrypt_tmp_files= 1; + mdev10259(); + encrypt_tmp_files= 0; + + mdev14014(); + mdev17133(); + + my_end(0); + return exit_status(); +} + diff --git a/unittest/sql/my_apc-t.cc b/unittest/sql/my_apc-t.cc index 80bbc6b6e56..6d44859d164 100644 --- a/unittest/sql/my_apc-t.cc +++ b/unittest/sql/my_apc-t.cc @@ -12,7 +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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ /* This file does standalone APC system tests. diff --git a/unittest/strings/strings-t.c b/unittest/strings/strings-t.c index 6baef0417a8..fe595a5c303 100644 --- a/unittest/strings/strings-t.c +++ b/unittest/strings/strings-t.c @@ -95,11 +95,674 @@ static CHARSET_INFO *charset_list[]= }; +typedef struct +{ + const char *a; + size_t alen; + const char *b; + size_t blen; + int res; +} STRNNCOLL_PARAM; + + +#define CSTR(x) (x),(sizeof(x)-1) + +/* + Byte sequence types used in the tests: + 8BIT - a 8 bit byte (>=00x80) which makes a single byte characters + MB2 - two bytes that make a valid character + H2 - a byte which is a valid MB2 head byte + T2 - a byte which is a valid MB2 tail byte + ILSEQ - a byte which makes an illegal sequence + H2+ILSEQ - a sequence that starts with a valid H2 byte, + but not followed by a valid T2 byte. + + Charset H2 T2 8BIT + ------- ---------------- --------------- -------- + big5 [A1..F9] [40..7E,A1..FE] + euckr [81..FE] [41..5A,61..7A,81..FE] + gb2312 [A1..F7] [A1..FE] + gbk [81..FE] [40..7E,80..FE] + + cp932 [81..9F,E0..FC] [40..7E,80..FC] [A1..DF] + sjis [81..9F,E0..FC] [40..7E,80..FC] [A1..DF] + + + Essential byte sequences in various character sets: + + Sequence big5 cp932 euckr gb2312 gbk sjis + -------- ---- ----- ----- ------ --- ---- + 80 ILSEQ ILSEQ ILSEQ ILSEQ ILSEQ ILSEQ + 81 ILSEQ H2 H2 ILSEQ H2 H2 + A1 H2 8BIT H2 H2 H2 8BIT + A1A1 MB2 8BIT+8BIT MB2 MB2 MB2 8BIT+8BIT + E0E0 MB2 MB2 MB2 MB2 MB2 MB2 + F9FE MB2 H2+ILSEQ MB2 ILSEQ+T2 MB2 H2+ILSEQ +*/ + + +/* + For character sets that have the following byte sequences: + 80 - ILSEQ + 81 - ILSEQ or H2 + F9 - ILSEQ or H2 + A1A1 - MB2 or 8BIT+8BIT + E0E0 - MB2 +*/ +static STRNNCOLL_PARAM strcoll_mb2_common[]= +{ + /* Compare two good sequences */ + {CSTR(""), CSTR(""), 0}, + {CSTR(""), CSTR(" "), 0}, + {CSTR(""), CSTR("A"), -1}, + {CSTR(""), CSTR("a"), -1}, + {CSTR(""), CSTR("\xA1\xA1"), -1}, + {CSTR(""), CSTR("\xE0\xE0"), -1}, + + {CSTR(" "), CSTR(""), 0}, + {CSTR(" "), CSTR(" "), 0}, + {CSTR(" "), CSTR("A"), -1}, + {CSTR(" "), CSTR("a"), -1}, + {CSTR(" "), CSTR("\xA1\xA1"), -1}, + {CSTR(" "), CSTR("\xE0\xE0"), -1}, + + {CSTR("a"), CSTR(""), 1}, + {CSTR("a"), CSTR(" "), 1}, + {CSTR("a"), CSTR("a"), 0}, + {CSTR("a"), CSTR("\xA1\xA1"), -1}, + {CSTR("a"), CSTR("\xE0\xE0"), -1}, + + {CSTR("\xA1\xA1"), CSTR("\xA1\xA1"), 0}, + {CSTR("\xA1\xA1"), CSTR("\xE0\xE0"), -1}, + + /* Compare a good character to an illegal or an incomplete sequence */ + {CSTR(""), CSTR("\x80"), -1}, + {CSTR(""), CSTR("\x81"), -1}, + {CSTR(""), CSTR("\xF9"), -1}, + + {CSTR(" "), CSTR("\x80"), -1}, + {CSTR(" "), CSTR("\x81"), -1}, + {CSTR(" "), CSTR("\xF9"), -1}, + + {CSTR("a"), CSTR("\x80"), -1}, + {CSTR("a"), CSTR("\x81"), -1}, + {CSTR("a"), CSTR("\xF9"), -1}, + + {CSTR("\xA1\xA1"), CSTR("\x80"), -1}, + {CSTR("\xA1\xA1"), CSTR("\x81"), -1}, + {CSTR("\xA1\xA1"), CSTR("\xF9"), -1}, + + {CSTR("\xE0\xE0"), CSTR("\x80"), -1}, + {CSTR("\xE0\xE0"), CSTR("\x81"), -1}, + {CSTR("\xE0\xE0"), CSTR("\xF9"), -1}, + + /* Compare two bad/incomplete sequences */ + {CSTR("\x80"), CSTR("\x80"), 0}, + {CSTR("\x80"), CSTR("\x81"), -1}, + {CSTR("\x80"), CSTR("\xF9"), -1}, + {CSTR("\x81"), CSTR("\x81"), 0}, + {CSTR("\x81"), CSTR("\xF9"), -1}, + + {NULL, 0, NULL, 0, 0} +}; + + +/* + For character sets that have good mb2 characters A1A1 and F9FE +*/ +static STRNNCOLL_PARAM strcoll_mb2_A1A1_mb2_F9FE[]= +{ + /* Compare two good characters */ + {CSTR(""), CSTR("\xF9\xFE"), -1}, + {CSTR(" "), CSTR("\xF9\xFE"), -1}, + {CSTR("a") , CSTR("\xF9\xFE"), -1}, + {CSTR("\xA1\xA1"), CSTR("\xF9\xFE"), -1}, + {CSTR("\xF9\xFE"), CSTR("\xF9\xFE"), 0}, + + /* Compare a good character to an illegal or an incomplete sequence */ + {CSTR(""), CSTR("\xA1"), -1}, + {CSTR(""), CSTR("\xF9"), -1}, + {CSTR("a"), CSTR("\xA1"), -1}, + {CSTR("a"), CSTR("\xF9"), -1}, + + {CSTR("\xA1\xA1"), CSTR("\xA1"), -1}, + {CSTR("\xA1\xA1"), CSTR("\xF9"), -1}, + + {CSTR("\xF9\xFE"), CSTR("\x80"), -1}, + {CSTR("\xF9\xFE"), CSTR("\x81"), -1}, + {CSTR("\xF9\xFE"), CSTR("\xA1"), -1}, + {CSTR("\xF9\xFE"), CSTR("\xF9"), -1}, + + /* Compare two bad/incomplete sequences */ + {CSTR("\x80"), CSTR("\xA1"), -1}, + {CSTR("\x80"), CSTR("\xF9"), -1}, + + {NULL, 0, NULL, 0, 0} +}; + + +/* + For character sets that have: + A1A1 - a good mb2 character + F9FE - a bad sequence +*/ +static STRNNCOLL_PARAM strcoll_mb2_A1A1_bad_F9FE[]= +{ + /* Compare a good character to an illegal or an incomplete sequence */ + {CSTR(""), CSTR("\xF9\xFE"), -1}, + {CSTR(" "), CSTR("\xF9\xFE"), -1}, + {CSTR("a") , CSTR("\xF9\xFE"), -1}, + {CSTR("\xA1\xA1"), CSTR("\xF9\xFE"), -1}, + + {CSTR(""), CSTR("\xA1"), -1}, + {CSTR(""), CSTR("\xF9"), -1}, + {CSTR("a"), CSTR("\xA1"), -1}, + {CSTR("a"), CSTR("\xF9"), -1}, + + {CSTR("\xA1\xA1"), CSTR("\xA1"), -1}, + {CSTR("\xA1\xA1"), CSTR("\xF9"), -1}, + + /* Compare two bad/incomplete sequences */ + {CSTR("\xF9\xFE"), CSTR("\x80"), 1}, + {CSTR("\xF9\xFE"), CSTR("\x81"), 1}, + {CSTR("\xF9\xFE"), CSTR("\xA1"), 1}, + {CSTR("\xF9\xFE"), CSTR("\xF9"), 1}, + {CSTR("\x80"), CSTR("\xA1"), -1}, + {CSTR("\x80"), CSTR("\xF9"), -1}, + {CSTR("\xF9\xFE"), CSTR("\xF9\xFE"), 0}, + + {NULL, 0, NULL, 0, 0} +}; + + +/* + For character sets that have: + 80 - ILSEQ or H2 + 81 - ILSEQ or H2 + A1 - 8BIT + F9 - ILSEQ or H2 + F9FE - a bad sequence (ILSEQ+XX or H2+ILSEQ) +*/ +static STRNNCOLL_PARAM strcoll_mb1_A1_bad_F9FE[]= +{ + /* Compare two good characters */ + {CSTR(""), CSTR("\xA1"), -1}, + {CSTR("\xA1\xA1"), CSTR("\xA1"), 1}, + + /* Compare a good character to an illegal or an incomplete sequence */ + {CSTR(""), CSTR("\xF9"), -1}, + {CSTR(""), CSTR("\xF9\xFE"), -1}, + {CSTR(" "), CSTR("\xF9\xFE"), -1}, + {CSTR("a"), CSTR("\xF9\xFE"), -1}, + {CSTR("a"), CSTR("\xA1"), -1}, + {CSTR("a"), CSTR("\xF9"), -1}, + + {CSTR("\xA1\xA1"), CSTR("\xF9"), -1}, + {CSTR("\xA1\xA1"), CSTR("\xF9\xFE"), -1}, + + {CSTR("\xF9\xFE"), CSTR("\x80"), 1}, + {CSTR("\xF9\xFE"), CSTR("\x81"), 1}, + {CSTR("\xF9\xFE"), CSTR("\xA1"), 1}, + {CSTR("\xF9\xFE"), CSTR("\xF9"), 1}, + + {CSTR("\x80"), CSTR("\xA1"), 1}, + + /* Compare two bad/incomplete sequences */ + {CSTR("\x80"), CSTR("\xF9"), -1}, + {CSTR("\xF9\xFE"), CSTR("\xF9\xFE"), 0}, + + {NULL, 0, NULL, 0, 0} +}; + + +/* + For character sets (e.g. cp932 and sjis) that have: + 8181 - a valid MB2 character + A1 - a valid 8BIT character + E0E0 - a valid MB2 character + and sort in this order: + 8181 < A1 < E0E0 +*/ +static STRNNCOLL_PARAM strcoll_8181_A1_E0E0[]= +{ + {CSTR("\x81\x81"), CSTR("\xA1"), -1}, + {CSTR("\x81\x81"), CSTR("\xE0\xE0"), -1}, + {CSTR("\xA1"), CSTR("\xE0\xE0"), -1}, + + {NULL, 0, NULL, 0, 0} +}; + + +/* + A shared test for eucjpms and ujis. +*/ +static STRNNCOLL_PARAM strcoll_ujis[]= +{ + {CSTR("\x8E\xA1"), CSTR("\x8E"), -1}, /* Good MB2 vs incomplete MB2 */ + {CSTR("\x8E\xA1"), CSTR("\x8F\xA1"), -1}, /* Good MB2 vs incomplete MB3 */ + {CSTR("\x8E\xA1"), CSTR("\x8F\xA1\xA1"), -1}, /* Good MB2 vs good MB3 */ + {CSTR("\xA1\xA1"), CSTR("\x8F\xA1\xA1"), 1}, /* Good MB2 vs good MB3 */ + {CSTR("\x8E"), CSTR("\x8F\xA1"), -1}, /* Incomplete MB2 vs incomplete MB3 */ + {NULL, 0, NULL, 0, 0} +}; + + +static STRNNCOLL_PARAM strcoll_utf8mb3_common[]= +{ + {CSTR("\xC0"), CSTR("\xC1"), -1}, /* Unused byte vs unused byte */ + {CSTR("\xC0"), CSTR("\xFF"), -1}, /* Unused byte vs unused byte */ + {CSTR("\xC2\xA1"), CSTR("\xC0"), -1}, /* MB2 vs unused byte */ + {CSTR("\xC2\xA1"), CSTR("\xC2"), -1}, /* MB2 vs incomplete MB2 */ + {CSTR("\xC2\xA1"), CSTR("\xC2\xA2"), -1}, /* MB2 vs MB2 */ + {CSTR("\xC2\xA1"), CSTR("\xE0\xA0\x7F"),-1}, /* MB2 vs broken MB3 */ + {CSTR("\xC2\xA1"), CSTR("\xE0\xA0\x80"),-1}, /* MB2 vs MB3 */ + {CSTR("\xC2\xA1"), CSTR("\xE0\xA0\xBF"),-1}, /* MB2 vs MB3 */ + {CSTR("\xC2\xA1"), CSTR("\xE0\xA0\xC0"),-1}, /* MB2 vs broken MB3 */ + {CSTR("\xC2\xA1"), CSTR("\xE0\xA0"), -1}, /* MB2 vs incomplete MB3 */ + {CSTR("\xE0\xA0\x7E"), CSTR("\xE0\xA0\x7F"),-1},/* Broken MB3 vs broken MB3 */ + {CSTR("\xE0\xA0\x80"), CSTR("\xE0\xA0"), -1},/* MB3 vs incomplete MB3 */ + {CSTR("\xE0\xA0\x80"), CSTR("\xE0\xA0\x7F"),-1},/* MB3 vs broken MB3 */ + {CSTR("\xE0\xA0\x80"), CSTR("\xE0\xA0\xBF"),-1},/* MB3 vs MB3 */ + {CSTR("\xE0\xA0\x80"), CSTR("\xE0\xA0\xC0"),-1},/* MB3 vs broken MB3 */ + {CSTR("\xE0\xA0\xC0"), CSTR("\xE0\xA0\xC1"),-1},/* Broken MB3 vs broken MB3 */ + {NULL, 0, NULL, 0, 0} +}; + + +static STRNNCOLL_PARAM strcoll_utf8mb4_common[]= +{ + /* Minimum four-byte character: U+10000 == _utf8 0xF0908080 */ + {CSTR("\xF0\x90\x80\x80"), CSTR("\xC0"), -1}, /* MB4 vs unused byte */ + {CSTR("\xF0\x90\x80\x80"), CSTR("\xC2"), -1}, /* MB4 vs incomplete MB2 */ + {CSTR("\xF0\x90\x80\x80"), CSTR("\xE0\xA0\x7F"),-1}, /* MB4 vs broken MB3 */ + {CSTR("\xF0\x90\x80\x80"), CSTR("\xE0\xA0\xC0"),-1}, /* MB4 vs broken MB3 */ + {CSTR("\xF0\x90\x80\x80"), CSTR("\xE0\xA0"), -1}, /* MB4 vs incomplete MB3 */ + {CSTR("\xF0\x90\x80\x80"), CSTR("\xF0\x90\x80"),-1}, /* MB4 vs incomplete MB4 */ + {CSTR("\xF0\x90\x80\x80"), CSTR("\xF0\x90\x80\x7F"),-1},/* MB4 vs broken MB4 */ + {CSTR("\xF0\x90\x80\x80"), CSTR("\xF0\x90\x80\xC0"),-1},/* MB4 vs broken MB4 */ + + /* Maximum four-byte character: U+10FFFF == _utf8 0xF48FBFBF */ + {CSTR("\xF4\x8F\xBF\xBF"), CSTR("\xC0"), -1}, /* MB4 vs unused byte */ + {CSTR("\xF4\x8F\xBF\xBF"), CSTR("\xC2"), -1}, /* MB4 vs incomplete MB2 */ + {CSTR("\xF4\x8F\xBF\xBF"), CSTR("\xE0\xA0\x7F"),-1}, /* MB4 vs broken MB3 */ + {CSTR("\xF4\x8F\xBF\xBF"), CSTR("\xE0\xA0\xC0"),-1}, /* MB4 vs broken MB3 */ + {CSTR("\xF4\x8F\xBF\xBF"), CSTR("\xE0\xA0"), -1}, /* MB4 vs incomplete MB3 */ + {CSTR("\xF4\x8F\xBF\xBF"), CSTR("\xF0\x90\x80"),-1}, /* MB4 vs incomplete MB4 */ + {CSTR("\xF4\x8F\xBF\xBF"), CSTR("\xF0\x90\x80\x7F"),-1},/* MB4 vs broken MB4 */ + {CSTR("\xF4\x8F\xBF\xBF"), CSTR("\xF0\x90\x80\xC0"),-1},/* MB4 vs broken MB4 */ + + /* Broken MB4 vs incomplete/broken MB3 */ + {CSTR("\xF0\x90\x80\x7F"), CSTR("\xE0\xA0"), 1}, /* Broken MB4 vs incomplete MB3 */ + {CSTR("\xF0\x90\x80\x7F"), CSTR("\xE0\xA0\x7F"),1}, /* Broken MB4 vs broken MB3 */ + {CSTR("\xF0\x90\x80\x7F"), CSTR("\xE0\xA0\xC0"),1}, /* Broken MB4 vs broken MB3 */ + + /* + Broken MB4 vs incomplete MB4: + The three leftmost bytes are compared binary, the fourth byte is compared + to auto-padded space. + */ + {CSTR("\xF0\x90\x80\x1F"), CSTR("\xF0\x90\x80"),-1}, /* Broken MB4 vs incomplete MB4 */ + {CSTR("\xF0\x90\x80\x7E"), CSTR("\xF0\x90\x80"),1}, /* Broken MB4 vs incomplete MB4 */ + + /* Broken MB4 vs broken MB4 */ + {CSTR("\xF0\x90\x80\x7E"), CSTR("\xF0\x90\x80\x7F"),-1},/* Broken MB4 vs broken MB4 */ + {CSTR("\xF0\x90\x80\x7E"), CSTR("\xF0\x90\x80\xC0"),-1},/* Broken MB4 vs broken MB4 */ + + {NULL, 0, NULL, 0, 0} +}; + + +static STRNNCOLL_PARAM strcoll_utf8mb4_general_ci[]= +{ + /* All non-BMP characters are equal in utf8mb4_general_ci */ + {CSTR("\xF0\x90\x80\x80"), CSTR("\xF0\x90\x80\x81"),0},/* Non-BMB MB4 vs non-BMP MB4 */ + {CSTR("\xF0\x90\x80\x80"), CSTR("\xF4\x8F\xBF\xBF"),0},/* Non-BMB MB4 vs non-BMP MB4 */ + {CSTR("\x00"), CSTR("\xF0\x90\x80\x80"),-1},/* U+0000 vs non-BMP MB4 */ + {CSTR("\x00"), CSTR("\xF0\x90\x80\x81"),-1},/* U+0000 vs non-BMP MB4 */ + {CSTR("\x00"), CSTR("\xF4\x8F\xBF\xBF"),-1},/* U+0000 vs non-BMP MB4 */ + {NULL, 0, NULL, 0, 0} +}; + + +static STRNNCOLL_PARAM strcoll_ucs2_common[]= +{ + {CSTR("\xC0"), CSTR("\xC1"), -1}, /* Incomlete MB2 vs incomplete MB2 */ + {CSTR("\xC0"), CSTR("\xFF"), -1}, /* Incomlete MB2 vs incomplete MB2 */ + {CSTR("\xC2\xA1"), CSTR("\xC0"), -1}, /* MB2 vs incomplete MB2 */ + {CSTR("\xC2\xA1"), CSTR("\xC2"), -1}, /* MB2 vs incomplete MB2 */ + {CSTR("\xC2\xA0"), CSTR("\xC2\xA1"), -1}, /* MB2 vs MB2 */ + {CSTR("\xC2\xA1"), CSTR("\xC2\xA2"), -1}, /* MB2 vs MB2 */ + + {CSTR("\xFF\xFF"), CSTR("\x00"),-1}, /* MB2 vs incomplete */ + {CSTR("\xFF\xFF\xFF\xFF"), CSTR("\x00"),-1}, /* MB2+MB2 vs incomplete */ + {CSTR("\xFF\xFF\xFF\xFF"), CSTR("\x00\x00\x00"), 1},/* MB2+MB2 vs MB2+incomplete */ + + {NULL, 0, NULL, 0, 0} +}; + + +/* Tests that involve comparison to SPACE (explicit, or padded) */ +static STRNNCOLL_PARAM strcoll_ucs2_space[]= +{ + {CSTR("\x00\x1F"), CSTR("\x00\x20"), -1}, /* MB2 vs MB2 */ + {CSTR("\x00\x20"), CSTR("\x00\x21"), -1}, /* MB2 vs MB2 */ + {CSTR("\x00\x1F"), CSTR(""), -1}, /* MB2 vs empty */ + {CSTR("\x00\x20"), CSTR(""), 0}, /* MB2 vs empty */ + {CSTR("\x00\x21"), CSTR(""), 1}, /* MB2 vs empty */ + + {NULL, 0, NULL, 0, 0} +}; + + +/* Tests that involve comparison to SPACE (explicit, or padded) */ +static STRNNCOLL_PARAM strcoll_utf16le_space[]= +{ + {CSTR("\x1F\x00"), CSTR("\x20\x00"), -1}, /* MB2 vs MB2 */ + {CSTR("\x20\x00"), CSTR("\x21\x00"), -1}, /* MB2 vs MB2 */ + {CSTR("\x1F\x00"), CSTR(""), -1}, /* MB2 vs empty */ + {CSTR("\x20\x00"), CSTR(""), 0}, /* MB2 vs empty */ + {CSTR("\x21\x00"), CSTR(""), 1}, /* MB2 vs empty */ + + {NULL, 0, NULL, 0, 0} +}; + + +static STRNNCOLL_PARAM strcoll_utf16_common[]= +{ + /* Minimum four-byte character: U+10000 == _utf16 0xD800DC00 */ + {CSTR("\xD8\x00\xDC\x00"), CSTR("\xC0"), -1},/* MB4 vs incomplete MB2 */ + {CSTR("\xD8\x00\xDC\x00"), CSTR("\xC2"), -1},/* MB4 vs incomplete MB2 */ + {CSTR("\xD8\x00\xDC\x00"), CSTR("\xD8\x00\xDB\x00"),-1},/* MB4 vs broken MB4 */ + {CSTR("\xD8\x00\xDC\x00"), CSTR("\xD8\x00\xE0\x00"),-1},/* MB4 vs broken MB4 */ + {CSTR("\xD8\x00\xDC\x00"), CSTR("\xDC\x00"), -1},/* MB4 vs broken MB2 */ + {CSTR("\xD8\x00\xDC\x00"), CSTR("\xD8\x00\xDC"), -1},/* MB4 vs incomplete MB4 */ + + /* Maximum four-byte character: U+10FFFF == _utf8 0xF48FBFBF */ + {CSTR("\xDB\xFF\xDF\xFF"), CSTR("\xC0"), -1},/* MB4 vs incomplete MB2 */ + {CSTR("\xDB\xFF\xDF\xFF"), CSTR("\xC2"), -1},/* MB4 vs incomplete MB2 */ + {CSTR("\xDB\xFF\xDF\xFF"), CSTR("\xD8\x00\xDB\x00"),-1},/* MB4 vs broken MB4 */ + {CSTR("\xDB\xFF\xDF\xFF"), CSTR("\xD8\x00\xE0\x00"),-1},/* MB4 vs broken MB4 */ + {CSTR("\xDB\xFF\xDF\xFF"), CSTR("\xDC\x00"), -1},/* MB4 vs broken MB2 */ + {CSTR("\xDB\xFF\xDF\xFF"), CSTR("\xDC\xFF\xDF"), -1},/* MB4 vs incomplete MB4 */ + + /* Broken MB4 vs broken MB4 */ + {CSTR("\xD8\x00\xDC\x00"), CSTR("\xD8\x00\xDB\x01"),-1},/* Broken MB4 vs broken MB4 */ + {CSTR("\xDB\xFF\xE0\xFE"), CSTR("\xDB\xFF\xE0\xFF"),-1},/* Broken MB4 vs broken MB4 */ + + {NULL, 0, NULL, 0, 0} +}; + + +static STRNNCOLL_PARAM strcoll_utf16_general_ci[]= +{ + /* All non-BMP characters are compared as equal */ + {CSTR("\xD8\x00\xDC\x00"), CSTR("\xD8\x00\xDC\x01"), 0},/* Non-BMP MB4 vs non-BMP MB4 */ + {CSTR("\xD8\x00\xDC\x00"), CSTR("\xDB\xFF\xDF\xFF"), 0},/* Non-BMP MB4 vs non-BMP MB4 */ + {CSTR("\x00\x00"), CSTR("\xD8\x00\xDC\x01"),-1},/* U+0000 vs non-BMP MB4 */ + {CSTR("\x00\x00"), CSTR("\xDB\xFF\xDF\xFF"),-1},/* U+0000 vs non-BMP MB4 */ + {NULL, 0, NULL, 0, 0} +}; + + +static STRNNCOLL_PARAM strcoll_utf16le_common[]= +{ + /* Minimum four-byte character: U+10000 == _utf16 0xD800DC00 */ + {CSTR("\x00\xD8\x00\xDC"), CSTR("\xC0"), -1},/* MB4 vs incomplete MB2 */ + {CSTR("\x00\xD8\x00\xDC"), CSTR("\xC2"), -1},/* MB4 vs incomplete MB2 */ + {CSTR("\x00\xD8\x00\xDC"), CSTR("\x00\xD8\x00\xDB"),-1},/* MB4 vs broken MB4 */ + {CSTR("\x00\xD8\x00\xDC"), CSTR("\x00\xD8\x00\xD0"),-1},/* MB4 vs broken MB4 */ + {CSTR("\x00\xD8\x00\xDC"), CSTR("\x00\xDC"), -1},/* MB4 vs broken MB2 */ + {CSTR("\x00\xD8\x00\xDC"), CSTR("\x00\xD8\x00"), -1},/* MB4 vs incomplete MB4 */ + + /* Maximum four-byte character: U+10FFFF == _utf8 0xF48FBFBF */ + {CSTR("\xFF\xDB\xFF\xDF"), CSTR("\xC0"), -1},/* MB4 vs incomplete MB2 */ + {CSTR("\xFF\xDB\xFF\xDF"), CSTR("\xC2"), -1},/* MB4 vs incomplete MB2 */ + {CSTR("\xFF\xDB\xFF\xDF"), CSTR("\x00\xD8\x00\xDB"),-1},/* MB4 vs broken MB4 */ + {CSTR("\xFF\xDB\xFF\xDF"), CSTR("\x00\xD8\x00\xE0"),-1},/* MB4 vs broken MB4 */ + {CSTR("\xFF\xDB\xFF\xDF"), CSTR("\x00\xDC"), -1},/* MB4 vs broken MB2 */ + {CSTR("\xFF\xDB\xFF\xDF"), CSTR("\xFF\xDC\x00"), -1},/* MB4 vs incomplete MB4 */ + + /* Broken MB4 vs broken MB4 */ + {CSTR("\x00\xD8\x00\xDC"), CSTR("\x00\xD8\x01\xDB"),-1},/* Broken MB4 vs broken MB4 */ + {CSTR("\xFF\xDB\xFE\xE0"), CSTR("\xFF\xDB\xFF\xE0"),-1},/* Broken MB4 vs broken MB4 */ + + {NULL, 0, NULL, 0, 0} +}; + + +static STRNNCOLL_PARAM strcoll_utf16le_general_ci[]= +{ + /* All non-BMP characters are compared as equal */ + {CSTR("\x00\xD8\x00\xDC"), CSTR("\x00\xD8\x01\xDC"), 0},/* Non-BMP MB4 vs non-BMP MB4 */ + {CSTR("\x00\xD8\x00\xDC"), CSTR("\xFF\xDB\xFF\xDF"), 0},/* Non-BMP MB4 vs non-BMP MB4 */ + {CSTR("\x00\x00"), CSTR("\x00\xD8\x01\xDC"), -1},/* U+0000 vs non-BMP MB4 */ + {CSTR("\x00\x00"), CSTR("\xFF\xDB\xFF\xDF"), -1},/* U+0000 vs non-BMP MB4 */ + + {NULL, 0, NULL, 0, 0} +}; + + +static STRNNCOLL_PARAM strcoll_utf32_common[]= +{ + /* Minimum character: U+0000 == _utf32 0x00000000 */ + {CSTR("\x00\x00\x00\x00"), CSTR("\x00"), -1}, /* MB4 vs incomplete MB4 */ + {CSTR("\x00\x00\x00\x00"), CSTR("\xFF"), -1}, /* MB4 vs incomplete MB4 */ + {CSTR("\x00\x00\x00\x00"), CSTR("\x00\x00"), -1}, /* MB4 vs incomplete MB4 */ + {CSTR("\x00\x00\x00\x00"), CSTR("\x00\x00\x00"),-1}, /* MB4 vs incomplete MB4 */ + {CSTR("\x00\x00\x00\x00"), CSTR("\x00\x20\x00\x00"),-1},/* MB4 vs broken MB4 */ + {CSTR("\x00\x00\x00\x00"), CSTR("\xFF\xFF\xFF\xFF"),-1},/* MB4 vs broken MB4 */ + + /* Minimum non-BMP character: U+10000 == _utf32 0x00010000 */ + {CSTR("\x00\x01\x00\x00"), CSTR("\x00"), -1}, /* MB4 vs incomplete MB4 */ + {CSTR("\x00\x01\x00\x00"), CSTR("\xFF"), -1}, /* MB4 vs incomplete MB4 */ + {CSTR("\x00\x01\x00\x00"), CSTR("\x00\x00"), -1}, /* MB4 vs incomplete MB4 */ + {CSTR("\x00\x01\x00\x00"), CSTR("\x00\x00\x00"),-1}, /* MB4 vs incomplete MB4 */ + {CSTR("\x00\x01\x00\x00"), CSTR("\x00\x20\x00\x00"),-1},/* MB4 vs broken MB4 */ + {CSTR("\x00\x01\x00\x00"), CSTR("\xFF\xFF\xFF\xFF"),-1},/* MB4 vs broken MB4 */ + + /* Maximum character: U+10FFFF == _utf32 0x0010FFFF */ + {CSTR("\x00\x10\xFF\xFF"), CSTR("\x00"), -1}, /* MB4 vs incomplete MB4 */ + {CSTR("\x00\x10\xFF\xFF"), CSTR("\xFF"), -1}, /* MB4 vs incomplete MB4 */ + {CSTR("\x00\x10\xFF\xFF"), CSTR("\x00\x00"), -1}, /* MB4 vs incomplete MB4 */ + {CSTR("\x00\x10\xFF\xFF"), CSTR("\x00\x00\x00"), -1}, /* MB4 vs incomplete MB4 */ + {CSTR("\x00\x10\xFF\xFF"), CSTR("\x20\x00\x00\x00"),-1},/* MB4 vs broken MB3 */ + {CSTR("\x00\x10\xFF\xFF"), CSTR("\xFF\xFF\xFF\xFF"),-1},/* MB4 vs broken MB4 */ + + + /* Broken MB4 vs incomplete/broken MB3 */ + {CSTR("\x00\x20\x00\x00"), CSTR("\x00"), 1}, /* Broken MB4 vs incomplete MB4 */ + {CSTR("\x00\x20\x00\x00"), CSTR("\x00\x00"), 1}, /* Broken MB4 vs incomplete MB4 */ + {CSTR("\x00\x20\x00\x00"), CSTR("\x00\x00\x00"), 1}, /* Broken MB4 vs incomplete MB4 */ + {CSTR("\x00\x20\x00\x00"), CSTR("\x00\x20\x00\x01"),-1},/* Broken MB4 vs broken MB4 */ + + {NULL, 0, NULL, 0, 0} +}; + + +static STRNNCOLL_PARAM strcoll_utf32_general_ci[]= +{ + /* Two non-BMP characters are compared as equal */ + {CSTR("\x00\x01\x00\x00"), CSTR("\x00\x01\x00\x01"), 0}, /* non-BMP MB4 vs non-BMP MB4 */ + {CSTR("\x00\x00\x00\x00"), CSTR("\x00\x01\x00\x00"), -1}, /* U+0000 vs non-BMP MB4 */ + {CSTR("\x00\x00\x00\x00"), CSTR("\x00\x01\x00\x01"), -1}, /* U+0000 vs non-BMP MB4 */ + + {NULL, 0, NULL, 0, 0} +}; + + +static void +str2hex(char *dst, size_t dstlen, const char *src, size_t srclen) +{ + char *dstend= dst + dstlen; + const char *srcend= src + srclen; + for (*dst= '\0' ; dst + 3 < dstend && src < srcend; ) + { + sprintf(dst, "%02X", (unsigned char) src[0]); + dst+=2; + src++; + } +} + + +/* + Check if the two comparison result are semantically equal: + both are negative, both are positive, or both are zero. +*/ +static int +eqres(int ares, int bres) +{ + return (ares < 0 && bres < 0) || + (ares > 0 && bres > 0) || + (ares == 0 && bres == 0); +} + + +static int +strcollsp(CHARSET_INFO *cs, const STRNNCOLL_PARAM *param) +{ + int failed= 0; + const STRNNCOLL_PARAM *p; + diag("%-20s %-10s %-10s %10s %10s", "Collation", "a", "b", "ExpectSign", "Actual"); + for (p= param; p->a; p++) + { + char ahex[64], bhex[64]; + int res= cs->coll->strnncollsp(cs, (uchar *) p->a, p->alen, + (uchar *) p->b, p->blen, 0); + str2hex(ahex, sizeof(ahex), p->a, p->alen); + str2hex(bhex, sizeof(bhex), p->b, p->blen); + diag("%-20s %-10s %-10s %10d %10d%s", + cs->name, ahex, bhex, p->res, res, + eqres(res, p->res) ? "" : " FAILED"); + if (!eqres(res, p->res)) + { + failed++; + } + else + { + /* Test in reverse order */ + res= cs->coll->strnncollsp(cs, (uchar *) p->b, p->blen, + (uchar *) p->a, p->alen, 0); + if (!eqres(res, -p->res)) + { + diag("Comparison in reverse order failed. Expected %d, got %d", + -p->res, res); + failed++; + } + } + } + return failed; +} + + +static int +test_strcollsp() +{ + int failed= 0; +#ifdef HAVE_CHARSET_big5 + failed+= strcollsp(&my_charset_big5_chinese_ci, strcoll_mb2_common); + failed+= strcollsp(&my_charset_big5_chinese_ci, strcoll_mb2_A1A1_mb2_F9FE); + failed+= strcollsp(&my_charset_big5_bin, strcoll_mb2_common); + failed+= strcollsp(&my_charset_big5_bin, strcoll_mb2_A1A1_mb2_F9FE); +#endif +#ifdef HAVE_CHARSET_cp932 + failed+= strcollsp(&my_charset_cp932_japanese_ci, strcoll_mb2_common); + failed+= strcollsp(&my_charset_cp932_japanese_ci, strcoll_mb1_A1_bad_F9FE); + failed+= strcollsp(&my_charset_cp932_bin, strcoll_mb2_common); + failed+= strcollsp(&my_charset_cp932_bin, strcoll_mb1_A1_bad_F9FE); + failed+= strcollsp(&my_charset_cp932_japanese_ci, strcoll_8181_A1_E0E0); + failed+= strcollsp(&my_charset_cp932_bin, strcoll_8181_A1_E0E0); +#endif +#ifdef HAVE_CHARSET_eucjpms + failed+= strcollsp(&my_charset_eucjpms_japanese_ci, strcoll_mb2_common); + failed+= strcollsp(&my_charset_eucjpms_bin, strcoll_mb2_common); + failed+= strcollsp(&my_charset_eucjpms_japanese_ci, strcoll_mb2_A1A1_mb2_F9FE); + failed+= strcollsp(&my_charset_eucjpms_bin, strcoll_mb2_A1A1_mb2_F9FE); + failed+= strcollsp(&my_charset_eucjpms_japanese_ci, strcoll_ujis); + failed+= strcollsp(&my_charset_eucjpms_bin, strcoll_ujis); +#endif +#ifdef HAVE_CHARSET_euckr + failed+= strcollsp(&my_charset_euckr_korean_ci, strcoll_mb2_common); + failed+= strcollsp(&my_charset_euckr_korean_ci, strcoll_mb2_A1A1_mb2_F9FE); + failed+= strcollsp(&my_charset_euckr_bin, strcoll_mb2_common); + failed+= strcollsp(&my_charset_euckr_bin, strcoll_mb2_A1A1_mb2_F9FE); +#endif +#ifdef HAVE_CHARSET_gb2312 + failed+= strcollsp(&my_charset_gb2312_chinese_ci, strcoll_mb2_common); + failed+= strcollsp(&my_charset_gb2312_chinese_ci, strcoll_mb2_A1A1_bad_F9FE); + failed+= strcollsp(&my_charset_gb2312_bin, strcoll_mb2_common); + failed+= strcollsp(&my_charset_gb2312_bin, strcoll_mb2_A1A1_bad_F9FE); +#endif +#ifdef HAVE_CHARSET_gbk + failed+= strcollsp(&my_charset_gbk_chinese_ci, strcoll_mb2_common); + failed+= strcollsp(&my_charset_gbk_chinese_ci, strcoll_mb2_A1A1_mb2_F9FE); + failed+= strcollsp(&my_charset_gbk_bin, strcoll_mb2_common); + failed+= strcollsp(&my_charset_gbk_bin, strcoll_mb2_A1A1_mb2_F9FE); +#endif +#ifdef HAVE_CHARSET_sjis + failed+= strcollsp(&my_charset_sjis_japanese_ci, strcoll_mb2_common); + failed+= strcollsp(&my_charset_sjis_bin, strcoll_mb2_common); + failed+= strcollsp(&my_charset_sjis_japanese_ci, strcoll_mb1_A1_bad_F9FE); + failed+= strcollsp(&my_charset_sjis_bin, strcoll_mb1_A1_bad_F9FE); + failed+= strcollsp(&my_charset_sjis_japanese_ci, strcoll_8181_A1_E0E0); + failed+= strcollsp(&my_charset_sjis_bin, strcoll_8181_A1_E0E0); +#endif +#ifdef HAVE_CHARSET_ucs2 + failed+= strcollsp(&my_charset_ucs2_general_ci, strcoll_ucs2_common); + failed+= strcollsp(&my_charset_ucs2_general_ci, strcoll_ucs2_space); + failed+= strcollsp(&my_charset_ucs2_bin, strcoll_ucs2_common); + failed+= strcollsp(&my_charset_ucs2_bin, strcoll_ucs2_space); +#endif +#ifdef HAVE_CHARSET_ujis + failed+= strcollsp(&my_charset_ujis_japanese_ci, strcoll_mb2_common); + failed+= strcollsp(&my_charset_ujis_bin, strcoll_mb2_common); + failed+= strcollsp(&my_charset_ujis_japanese_ci, strcoll_mb2_A1A1_mb2_F9FE); + failed+= strcollsp(&my_charset_ujis_bin, strcoll_mb2_A1A1_mb2_F9FE); + failed+= strcollsp(&my_charset_ujis_japanese_ci, strcoll_ujis); + failed+= strcollsp(&my_charset_ujis_bin, strcoll_ujis); +#endif +#ifdef HAVE_CHARSET_utf16 + failed+= strcollsp(&my_charset_utf16_general_ci, strcoll_ucs2_common); + failed+= strcollsp(&my_charset_utf16_general_ci, strcoll_ucs2_space); + failed+= strcollsp(&my_charset_utf16_general_ci, strcoll_utf16_common); + failed+= strcollsp(&my_charset_utf16_general_ci, strcoll_utf16_general_ci); + failed+= strcollsp(&my_charset_utf16_bin, strcoll_ucs2_common); + failed+= strcollsp(&my_charset_utf16_bin, strcoll_ucs2_space); + failed+= strcollsp(&my_charset_utf16_bin, strcoll_utf16_common); + + failed+= strcollsp(&my_charset_utf16le_general_ci,strcoll_ucs2_common); + failed+= strcollsp(&my_charset_utf16le_general_ci,strcoll_utf16le_space); + failed+= strcollsp(&my_charset_utf16le_general_ci,strcoll_utf16le_common); + failed+= strcollsp(&my_charset_utf16le_general_ci,strcoll_utf16le_general_ci); + failed+= strcollsp(&my_charset_utf16le_bin, strcoll_ucs2_common); + failed+= strcollsp(&my_charset_utf16le_bin, strcoll_utf16le_space); + failed+= strcollsp(&my_charset_utf16le_bin, strcoll_utf16le_common); +#endif +#ifdef HAVE_CHARSET_utf32 + failed+= strcollsp(&my_charset_utf32_general_ci, strcoll_utf32_common); + failed+= strcollsp(&my_charset_utf32_general_ci, strcoll_utf32_general_ci); + failed+= strcollsp(&my_charset_utf32_bin, strcoll_utf32_common); +#endif +#ifdef HAVE_CHARSET_utf8 + failed+= strcollsp(&my_charset_utf8_general_ci, strcoll_utf8mb3_common); + failed+= strcollsp(&my_charset_utf8_general_mysql500_ci, strcoll_utf8mb3_common); + failed+= strcollsp(&my_charset_utf8_bin, strcoll_utf8mb3_common); +#endif +#ifdef HAVE_CHARSET_utf8mb4 + failed+= strcollsp(&my_charset_utf8mb4_general_ci, strcoll_utf8mb3_common); + failed+= strcollsp(&my_charset_utf8mb4_bin, strcoll_utf8mb3_common); + failed+= strcollsp(&my_charset_utf8mb4_general_ci, strcoll_utf8mb4_common); + failed+= strcollsp(&my_charset_utf8mb4_general_ci, strcoll_utf8mb4_general_ci); + failed+= strcollsp(&my_charset_utf8mb4_bin, strcoll_utf8mb4_common); +#endif + return failed; +} + + int main() { size_t i, failed= 0; - plan(1); + plan(2); diag("Testing my_like_range_xxx() functions"); for (i= 0; i < array_elements(charset_list); i++) @@ -112,5 +775,10 @@ int main() } } ok(failed == 0, "Testing my_like_range_xxx() functions"); + + diag("Testing cs->coll->strnncollsp()"); + failed= test_strcollsp(); + ok(failed == 0, "Testing cs->coll->strnncollsp()"); + return exit_status(); } |