summaryrefslogtreecommitdiff
path: root/unittest
diff options
context:
space:
mode:
Diffstat (limited to 'unittest')
-rw-r--r--unittest/mysys/CMakeLists.txt3
-rw-r--r--unittest/mysys/aes-t.c99
-rw-r--r--unittest/mysys/base64-t.c1
-rw-r--r--unittest/mysys/lf-t.c23
-rw-r--r--unittest/mysys/my_atomic-t.c34
-rw-r--r--unittest/mysys/my_getopt-t.c390
-rw-r--r--unittest/mysys/thr_template.c8
-rw-r--r--unittest/mysys/waiting_threads-t.c2
-rw-r--r--unittest/sql/CMakeLists.txt7
-rw-r--r--unittest/sql/mf_iocache-t.cc398
-rw-r--r--unittest/sql/my_apc-t.cc2
-rw-r--r--unittest/strings/strings-t.c670
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();
}