diff options
Diffstat (limited to 'unittest')
-rw-r--r-- | unittest/embedded/test-connect.cc | 12 | ||||
-rw-r--r-- | unittest/mysys/CMakeLists.txt | 2 | ||||
-rw-r--r-- | unittest/mysys/my_tzinfo-t.c | 197 |
3 files changed, 205 insertions, 6 deletions
diff --git a/unittest/embedded/test-connect.cc b/unittest/embedded/test-connect.cc index cd122286..0ac128cc 100644 --- a/unittest/embedded/test-connect.cc +++ b/unittest/embedded/test-connect.cc @@ -31,6 +31,8 @@ int main(int argc, char *argv[]) char *passwd; char *porta; unsigned int port; + int ret; + my_bool my_false= 0; if (get_evar(&host, &porta, &user, &passwd)) { @@ -60,19 +62,19 @@ int main(int argc, char *argv[]) return 1; } + mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &my_false); + if (mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "utf8mb4") != 0) { printf("mysql_options MYSQL_SET_CHARSET_NAME utf8mb4 failed: %s\n", mysql_error(mysql)); return 1; } - if (!mysql_real_connect(mysql, host, user, passwd, NULL, port, NULL, CLIENT_FOUND_ROWS | CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS)) { + if ((ret= !mysql_real_connect(mysql, host, user, passwd, NULL, port, NULL, + CLIENT_FOUND_ROWS | CLIENT_MULTI_RESULTS | CLIENT_REMEMBER_OPTIONS))) printf("mysql_real_connect failed: %s\n", mysql_error(mysql)); - return 1; - } mysql_close(mysql); mysql_thread_end(); mysql_library_end(); - return 0; - + return ret; } diff --git a/unittest/mysys/CMakeLists.txt b/unittest/mysys/CMakeLists.txt index 9dd5e5db..03c92e8b 100644 --- a/unittest/mysys/CMakeLists.txt +++ b/unittest/mysys/CMakeLists.txt @@ -14,7 +14,7 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA MY_ADD_TESTS(bitmap base64 my_atomic my_rdtsc lf my_malloc my_getopt dynstring - byte_order + byte_order my_tzinfo queues stacktrace crc32 LINK_LIBRARIES mysys) MY_ADD_TESTS(my_vsnprintf LINK_LIBRARIES strings mysys) MY_ADD_TESTS(aes LINK_LIBRARIES mysys mysys_ssl) diff --git a/unittest/mysys/my_tzinfo-t.c b/unittest/mysys/my_tzinfo-t.c new file mode 100644 index 00000000..b38ebd37 --- /dev/null +++ b/unittest/mysys/my_tzinfo-t.c @@ -0,0 +1,197 @@ +/* + Copyright (c) 2023, 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 02110-1335 USA + */ + +/* + This file tests my_tzset/my_get_tzinfo APIs +*/ +#include <my_global.h> +#include <my_sys.h> +#include "tap.h" +#include <stdlib.h> + +/** + Seconds since epoch used for "summer" timestamp + Corresponds to Jul 22 2023 04:26:40 GMT + Used to test timezone daylight savings UTC offset and DST abbreviation +*/ +#define SUMMER_TIMESTAMP 1690000000 + +/** + Seconds since epoch used for "winter" timestamp + Corresponds to Nov 14 2023 22:13:20 GMT+ + Used to test standard (no daylight savings) UTC offset and abbreviation +*/ +#define WINTER_TIMESTAMP 1700000000 + +#ifdef _WIN32 +#define timegm _mkgmtime +#endif +/** + Check expected offset from UTC, corresponding to specific + timestamp. + + On Windows, it is possible that my_get_tzinfo() is using + ICU to calculate offset.This function rechecks that value is the + same when using C runtime's _mkgmtime(). + + Elsewhere, my_get_tzinfo is taking this value from non-standard glibc + extension struct tm::tm_gmtoff. This function rechecks that the value + is the same if calculated with timegm(). +*/ +static void check_utc_offset(time_t t, long expected, const char *comment) +{ +#if defined _WIN32 || defined __linux__ + struct tm local_time; + long offset; + localtime_r(&t, &local_time); + offset= (long) (timegm(&local_time) - t); + ok(offset == expected, "%s: Offset for timestamp %lld is %ld/%ld", comment, + (long long) t,expected, offset); +#else + skip(1, "no utc offset check"); +#endif +} + +/** + Test my_tzset/my_get_tzinfo functions for a single named timezone. + + @param[in] tz_env. Timezone name, as used for TZ env.variable + + @param[in] expected_tznames. Expected "sytem_timezone" names. + For example, expected names for timezone PST8PDT can + be PST8PDT, PST or PDT + + @param[in] summer_gmt_off. Expected UTC offset, for SUMMER_TIMESTAMP + For timezones with DST savings on northern hemisphere + it is the expected DST offset from UTC + + @param[in] summer_time_abbr . Expected standard abbreviation + corresponding to SUMMER_TIMESTAMP. For example, it is + "PDT" for timezone PST8PDT + + @param[in] winter_gmt_off. Expected UTC offset, for WINTER_TIMESTAMP + + @param[in] winter_time_abbr . Expected standard abbreviation + corresponding to WINTER_TIMESTAMP. For example, it is + "PST" for timezone PST8PDT. +*/ +void test_timezone(const char *tz_env, const char **expected_tznames, + long summer_gmt_off, const char *summer_time_abbr, + long winter_gmt_off, const char *winter_time_abbr) +{ + char timezone_name[64]; + int found; + struct my_tz tz; + + setenv("TZ", tz_env, 1); + my_tzset(); + my_tzname(timezone_name, sizeof(timezone_name)); + + /* Check expected timezone names. */ + found= 0; + for (int i= 0; expected_tznames[i]; i++) + { + if (!strcmp(expected_tznames[i], timezone_name)) + { + found= 1; + break; + } + } + ok(found, "%s: timezone_name = %s", tz_env, timezone_name); + my_tzinfo(SUMMER_TIMESTAMP, &tz); + ok(summer_gmt_off == tz.seconds_offset, "%s: Summer GMT offset %ld", tz_env, tz.seconds_offset); + check_utc_offset(SUMMER_TIMESTAMP,tz.seconds_offset, tz_env); + + ok(!strcmp(summer_time_abbr, tz.abbreviation), "%s: Summer time abbreviation %s", + tz_env, tz.abbreviation); + my_tzinfo(WINTER_TIMESTAMP, &tz); + ok(winter_gmt_off == tz.seconds_offset, "%s: Winter GMT offset %ld", tz_env, tz.seconds_offset); + check_utc_offset(WINTER_TIMESTAMP, tz.seconds_offset, tz_env); + ok(!strcmp(winter_time_abbr, tz.abbreviation), "%s: Winter time abbreviation %s", + tz_env, tz.abbreviation); +} + +/* Check default timezone.*/ +static void test_default_timezone() +{ + char timezone_name[64]; + + time_t timestamps[]= {SUMMER_TIMESTAMP, WINTER_TIMESTAMP, time(NULL)}; + size_t i; + struct my_tz tz; +#ifdef _WIN32 + (void) putenv("TZ="); +#else + unsetenv("TZ"); +#endif + + my_tzset(); + my_tzname(timezone_name, sizeof(timezone_name)); +#ifdef _WIN32 + /* Expect timezone name like Europe/Berlin */ + ok(strstr(timezone_name, "/") != NULL, "Default timezone name %s", + timezone_name); +#else + skip(1, "no test for default timezone name %s", timezone_name); +#endif + + for (i = 0; i < array_elements(timestamps); i++) + { + my_tzinfo(timestamps[i], &tz); + ok(tz.seconds_offset % 60 == 0, + "GMT offset is whole number of minutes %ld", tz.seconds_offset); + check_utc_offset(timestamps[i], tz.seconds_offset, timezone_name); + ok(strlen(tz.abbreviation) < 8, "tz abbreviation %s", tz.abbreviation); + } +} + +int main(int argc __attribute__((unused)), char *argv[]) +{ + const char *PST8PDT_names[]= {"PST", "PDT", "PST8PDT", NULL}; + const char *GMT_names[]= {"GMT", "Etc/UTC", NULL}; + const char *GST_minus1GDT_names[]= {"GST", "GDT", NULL}; + const char *IST_names[]= {"IST",NULL}; + MY_INIT(argv[0]); + + plan(38); + test_default_timezone(); + + /* + Test PST8PDT timezone + Standard timezone, supported everywhere. Note - this one is supported by + ICU, so it would be using ICU for calculation on Windows + */ + test_timezone("PST8PDT", PST8PDT_names, -25200, "PDT", -28800, "PST"); + + /* + Test GMT. Supported by ICU, would be using ICU for calculations + */ + test_timezone("GMT", GMT_names, 0, "GMT", 0, "GMT"); + + /* + Non-standard "Germany" timezone, taken from Windows tzset() documentation + example. Unsupported by ICU, will be using C runtime on Windows for + abbreviations, and offset calculations. + */ + test_timezone("GST-1GDT", GST_minus1GDT_names, 7200, "GDT", 3600, "GST"); + + /* India */ + test_timezone("IST-5:30", IST_names, 19800, "IST", 19800, "IST"); + + my_end(0); + return exit_status(); +} |