Merge lp:~jan-kneschke/mysql-proxy/test-suite-refactoring into lp:mysql-proxy
- test-suite-refactoring
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 1137 |
Proposed branch: | lp:~jan-kneschke/mysql-proxy/test-suite-refactoring |
Merge into: | lp:mysql-proxy |
Diff against target: |
2517 lines (+1267/-929) 19 files modified
configure.in (+1/-0) lib/glib2.c (+12/-1) lib/posix.c (+29/-1) src/mysql-proxy-cli.c (+10/-1) tests/suite/Makefile.am (+5/-1) tests/suite/base/r/lineno.result (+1/-1) tests/suite/base/r/pooling.result (+12/-9) tests/suite/base/t/lineno.lua (+14/-1) tests/suite/base/t/lineno.test (+5/-1) tests/suite/base/t/load_multi.test (+9/-9) tests/suite/base/t/pooling-mock.lua (+8/-24) tests/suite/base/t/pooling.test (+19/-11) tests/suite/run-tests.lua (+437/-869) tests/suite/testenv/Makefile.am (+7/-0) tests/suite/testenv/fileutils.lua (+84/-0) tests/suite/testenv/process.lua (+179/-0) tests/suite/testenv/processmanager.lua (+72/-0) tests/suite/testenv/shellutils.lua (+92/-0) tests/suite/testenv/testutils.lua (+271/-0) |
To merge this branch: | bzr merge lp:~jan-kneschke/mysql-proxy/test-suite-refactoring |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Leith (community) | Approve | ||
Registry Administrators | Pending | ||
Review via email: mp+34853@code.launchpad.net |
This proposal supersedes a proposal from 2010-09-08.
Commit message
Description of the change
As a side-effect of fixing http://
This rewrite changes the test-runner to use proper OO-style to store the state of:
* commands it wants to run
* processes that it tracks
* proxy's and their options and environments
The helper functions that check paths, shell, ... are split out into modules under testenv.*
Leith (mleith) wrote : Posted in a previous version of this proposal | # |
Jan Kneschke (jan-kneschke) wrote : Posted in a previous version of this proposal | # |
Am 07.09.2010 um 11:41 schrieb Leith:
> Review: Needs Fixing
> Looks good to me. A few very minor comments (with the first being the only one needing to be resolved):
>
> - No copyright/licenses headers have had the date updated.. Please do that
added the copyright headers to all the testenv/ files.
> - Can we keep this comment on one line:
> + /* only try to delete the PID if we created it
> + */
done.
> - Why hard code the following to MySQLProxy:
> + opts["plugins"] = "proxy"
> + opts["daemon"] = true
because we only want to run the 'proxy' plugin and want to run it all as daemon all the time.
We don't want the admin plugin to be loaded here as it would only make it more complicated to setup the ports for it. As we don't use it, we don't load it for these tests.
> - This looks incomplete, what is the plan here?:
> + if extra_params then
> + -- FIXME: implement me
> + end
I removed it.
> - Bug#38415 has been fixed now (https:/
>
> + -- if we are supposed to listen on a UNIX socket, remove it first, because we don't clean it up on exit!
> + -- TODO: fix the code, instead of hacking around here! Bug#38415
> + if proxy_options[
> + os.remove(
> + end
Will post-pone remove this until #38415 is marked as "closed".
> - I see changes to Makefile.am, but none to any CMakeLists.txt files, I understand that the test suite does not run on Windows yet, however I'd also like us to move towards cmake as the one true source as well. Please consider making it so that cmake can still build all of this on *nix, and opening a new issue to get the test suite working on Windows as well.
Let's move this into an extra task. The current suite has only files for the automake case.
> --
> https:/
> You are the owner of lp:~jan-kneschke/mysql-proxy/test-suite-refactoring.
Jan
Leith (mleith) wrote : Posted in a previous version of this proposal | # |
The current files also need the year updating to 2010 where appropriate as well.
Leith (mleith) wrote : Posted in a previous version of this proposal | # |
OK, still slightly wrong, the copyright header should be:
"Copyright (c) $start, $end, Oracle and/or its affiliates. All rights reserved."
So please change the likes of:
Copyright (c) 2007, 2008, 2010, Oracle and/or its affiliates. All rights reserved.
To:
Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
Preview Diff
1 | === modified file 'configure.in' | |||
2 | --- configure.in 2010-05-25 13:44:43 +0000 | |||
3 | +++ configure.in 2010-09-08 12:58:43 +0000 | |||
4 | @@ -407,6 +407,7 @@ | |||
5 | 407 | lib/proxy/Makefile \ | 407 | lib/proxy/Makefile \ |
6 | 408 | tests/Makefile \ | 408 | tests/Makefile \ |
7 | 409 | tests/suite/Makefile \ | 409 | tests/suite/Makefile \ |
8 | 410 | tests/suite/testenv/Makefile \ | ||
9 | 410 | tests/suite/base/Makefile \ | 411 | tests/suite/base/Makefile \ |
10 | 411 | tests/suite/base/t/Makefile \ | 412 | tests/suite/base/t/Makefile \ |
11 | 412 | tests/suite/base/r/Makefile \ | 413 | tests/suite/base/r/Makefile \ |
12 | 413 | 414 | ||
13 | === modified file 'lib/glib2.c' | |||
14 | --- lib/glib2.c 2010-08-20 15:02:44 +0000 | |||
15 | +++ lib/glib2.c 2010-09-08 12:58:43 +0000 | |||
16 | @@ -1,5 +1,5 @@ | |||
17 | 1 | /* $%BEGINLICENSE%$ | 1 | /* $%BEGINLICENSE%$ |
19 | 2 | Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. | 2 | Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. |
20 | 3 | 3 | ||
21 | 4 | This program is free software; you can redistribute it and/or | 4 | This program is free software; you can redistribute it and/or |
22 | 5 | modify it under the terms of the GNU General Public License as | 5 | modify it under the terms of the GNU General Public License as |
23 | @@ -33,6 +33,16 @@ | |||
24 | 33 | return 0; | 33 | return 0; |
25 | 34 | } | 34 | } |
26 | 35 | 35 | ||
27 | 36 | static int lua_g_setenv (lua_State *L) { | ||
28 | 37 | const char * key = luaL_checkstring (L, 1); | ||
29 | 38 | const char * value = luaL_checkstring (L, 2); | ||
30 | 39 | int overwrite = luaL_optint(L, 3, 1); | ||
31 | 40 | |||
32 | 41 | lua_pushboolean(L, g_setenv(key, value, overwrite)); | ||
33 | 42 | |||
34 | 43 | return 1; | ||
35 | 44 | } | ||
36 | 45 | |||
37 | 36 | static int lua_g_get_current_time (lua_State *L) { | 46 | static int lua_g_get_current_time (lua_State *L) { |
38 | 37 | GTimeVal t; | 47 | GTimeVal t; |
39 | 38 | 48 | ||
40 | @@ -83,6 +93,7 @@ | |||
41 | 83 | {"usleep", lua_g_usleep}, | 93 | {"usleep", lua_g_usleep}, |
42 | 84 | {"md5", lua_g_checksum_md5}, | 94 | {"md5", lua_g_checksum_md5}, |
43 | 85 | {"get_current_time", lua_g_get_current_time}, | 95 | {"get_current_time", lua_g_get_current_time}, |
44 | 96 | {"setenv", lua_g_setenv}, | ||
45 | 86 | {NULL, NULL}, | 97 | {NULL, NULL}, |
46 | 87 | }; | 98 | }; |
47 | 88 | 99 | ||
48 | 89 | 100 | ||
49 | === modified file 'lib/posix.c' | |||
50 | --- lib/posix.c 2008-11-11 17:09:04 +0000 | |||
51 | +++ lib/posix.c 2010-09-08 12:58:43 +0000 | |||
52 | @@ -1,9 +1,28 @@ | |||
54 | 1 | /* Copyright (C) 2008 MySQL AB */ | 1 | /* $%BEGINLICENSE%$ |
55 | 2 | Copyright (c) 2008, 2010 Oracle and/or its affiliates. All rights reserved. | ||
56 | 3 | |||
57 | 4 | This program is free software; you can redistribute it and/or | ||
58 | 5 | modify it under the terms of the GNU General Public License as | ||
59 | 6 | published by the Free Software Foundation; version 2 of the | ||
60 | 7 | License. | ||
61 | 8 | |||
62 | 9 | This program is distributed in the hope that it will be useful, | ||
63 | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
64 | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
65 | 12 | GNU General Public License for more details. | ||
66 | 13 | |||
67 | 14 | You should have received a copy of the GNU General Public License | ||
68 | 15 | along with this program; if not, write to the Free Software | ||
69 | 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
70 | 17 | 02110-1301 USA | ||
71 | 18 | |||
72 | 19 | $%ENDLICENSE%$ */ | ||
73 | 2 | 20 | ||
74 | 3 | #ifdef HAVE_CONFIG_H | 21 | #ifdef HAVE_CONFIG_H |
75 | 4 | #include "config.h" | 22 | #include "config.h" |
76 | 5 | #endif | 23 | #endif |
77 | 6 | 24 | ||
78 | 25 | #include <sys/param.h> | ||
79 | 7 | #include <sys/types.h> | 26 | #include <sys/types.h> |
80 | 8 | #include <unistd.h> | 27 | #include <unistd.h> |
81 | 9 | 28 | ||
82 | @@ -27,6 +46,14 @@ | |||
83 | 27 | return 1; | 46 | return 1; |
84 | 28 | } | 47 | } |
85 | 29 | 48 | ||
86 | 49 | static int lua_getcwd (lua_State *L) { | ||
87 | 50 | char cwd[MAXPATHLEN]; | ||
88 | 51 | |||
89 | 52 | lua_pushstring (L, getcwd(cwd, sizeof(cwd))); | ||
90 | 53 | |||
91 | 54 | return 1; | ||
92 | 55 | } | ||
93 | 56 | |||
94 | 30 | static int lua_getpwuid(lua_State *L) { | 57 | static int lua_getpwuid(lua_State *L) { |
95 | 31 | struct passwd *p; | 58 | struct passwd *p; |
96 | 32 | int uid = luaL_checkinteger (L, 1); | 59 | int uid = luaL_checkinteger (L, 1); |
97 | @@ -76,6 +103,7 @@ | |||
98 | 76 | {"getpid", lua_getpid}, | 103 | {"getpid", lua_getpid}, |
99 | 77 | {"getuid", lua_getuid}, | 104 | {"getuid", lua_getuid}, |
100 | 78 | {"getpwuid", lua_getpwuid}, | 105 | {"getpwuid", lua_getpwuid}, |
101 | 106 | {"getcwd", lua_getcwd}, | ||
102 | 79 | {NULL, NULL}, | 107 | {NULL, NULL}, |
103 | 80 | }; | 108 | }; |
104 | 81 | 109 | ||
105 | 82 | 110 | ||
106 | === modified file 'src/mysql-proxy-cli.c' | |||
107 | --- src/mysql-proxy-cli.c 2010-09-02 12:05:35 +0000 | |||
108 | +++ src/mysql-proxy-cli.c 2010-09-08 12:58:43 +0000 | |||
109 | @@ -56,6 +56,7 @@ | |||
110 | 56 | #endif | 56 | #endif |
111 | 57 | 57 | ||
112 | 58 | #include <glib.h> | 58 | #include <glib.h> |
113 | 59 | #include <glib/gstdio.h> /* g_unlink() */ | ||
114 | 59 | #include <gmodule.h> | 60 | #include <gmodule.h> |
115 | 60 | 61 | ||
116 | 61 | #ifdef HAVE_LUA_H | 62 | #ifdef HAVE_LUA_H |
117 | @@ -115,6 +116,7 @@ | |||
118 | 115 | GOptionEntry *config_entries; | 116 | GOptionEntry *config_entries; |
119 | 116 | 117 | ||
120 | 117 | gchar *pid_file; | 118 | gchar *pid_file; |
121 | 119 | gboolean pid_file_is_created; | ||
122 | 118 | 120 | ||
123 | 119 | gchar *plugin_dir; | 121 | gchar *plugin_dir; |
124 | 120 | gchar **plugin_names; | 122 | gchar **plugin_names; |
125 | @@ -166,7 +168,13 @@ | |||
126 | 166 | if (frontend->user) g_free(frontend->user); | 168 | if (frontend->user) g_free(frontend->user); |
127 | 167 | if (frontend->log_filename) g_free(frontend->log_filename); | 169 | if (frontend->log_filename) g_free(frontend->log_filename); |
128 | 168 | if (frontend->log_config_filename) g_free(frontend->log_config_filename); | 170 | if (frontend->log_config_filename) g_free(frontend->log_config_filename); |
130 | 169 | if (frontend->pid_file) g_free(frontend->pid_file); | 171 | if (frontend->pid_file) { |
131 | 172 | /* only try to delete the PID if we created it */ | ||
132 | 173 | if (frontend->pid_file_is_created) { | ||
133 | 174 | g_unlink(frontend->pid_file); | ||
134 | 175 | } | ||
135 | 176 | g_free(frontend->pid_file); | ||
136 | 177 | } | ||
137 | 170 | if (frontend->log_level) g_free(frontend->log_level); | 178 | if (frontend->log_level) g_free(frontend->log_level); |
138 | 171 | if (frontend->plugin_dir) g_free(frontend->plugin_dir); | 179 | if (frontend->plugin_dir) g_free(frontend->plugin_dir); |
139 | 172 | 180 | ||
140 | @@ -591,6 +599,7 @@ | |||
141 | 591 | 599 | ||
142 | 592 | GOTO_EXIT(EXIT_FAILURE); | 600 | GOTO_EXIT(EXIT_FAILURE); |
143 | 593 | } | 601 | } |
144 | 602 | frontend->pid_file_is_created = TRUE; /* track that we created the PID file successfully and can delete it */ | ||
145 | 594 | } | 603 | } |
146 | 595 | 604 | ||
147 | 596 | /* the message has to be _after_ the g_option_content_parse() to | 605 | /* the message has to be _after_ the g_option_content_parse() to |
148 | 597 | 606 | ||
149 | === modified file 'tests/suite/Makefile.am' | |||
150 | --- tests/suite/Makefile.am 2009-09-22 15:13:32 +0000 | |||
151 | +++ tests/suite/Makefile.am 2010-09-08 12:58:43 +0000 | |||
152 | @@ -1,8 +1,9 @@ | |||
154 | 1 | SUBDIRS=base bugs | 1 | SUBDIRS=testenv base bugs |
155 | 2 | 2 | ||
156 | 3 | TESTS_ENVIRONMENT = \ | 3 | TESTS_ENVIRONMENT = \ |
157 | 4 | MYSQL_TEST_BIN="${MYSQL_TEST_BIN}" \ | 4 | MYSQL_TEST_BIN="${MYSQL_TEST_BIN}" \ |
158 | 5 | LUA_USER_PATH="${top_srcdir}/lib/?.lua" \ | 5 | LUA_USER_PATH="${top_srcdir}/lib/?.lua" \ |
159 | 6 | LUA_PATH="${top_srcdir}/tests/suite/?.lua" \ | ||
160 | 6 | LUA_CPATH=".libs/?.@DYNLIB_LUA_SUFFIX@;${top_builddir}/lib/.libs/?.@DYNLIB_LUA_SUFFIX@" \ | 7 | LUA_CPATH=".libs/?.@DYNLIB_LUA_SUFFIX@;${top_builddir}/lib/.libs/?.@DYNLIB_LUA_SUFFIX@" \ |
161 | 7 | @DYNLIB_PATH_VAR@="${top_builddir}/src/.libs/:${@DYNLIB_PATH_VAR@}" \ | 8 | @DYNLIB_PATH_VAR@="${top_builddir}/src/.libs/:${@DYNLIB_PATH_VAR@}" \ |
162 | 8 | MYSQL_PROXY_VERSION="${PACKAGE_VERSION}" \ | 9 | MYSQL_PROXY_VERSION="${PACKAGE_VERSION}" \ |
163 | @@ -24,6 +25,9 @@ | |||
164 | 24 | 25 | ||
165 | 25 | EXTRA_DIST=\ | 26 | EXTRA_DIST=\ |
166 | 26 | run-tests.lua \ | 27 | run-tests.lua \ |
167 | 28 | fileutils.lua \ | ||
168 | 29 | shellutils.lua \ | ||
169 | 30 | testutils.lua \ | ||
170 | 27 | lua-tests-wrapper.sh.in \ | 31 | lua-tests-wrapper.sh.in \ |
171 | 28 | CMakeLists.txt | 32 | CMakeLists.txt |
172 | 29 | 33 | ||
173 | 30 | 34 | ||
174 | === modified file 'tests/suite/base/r/lineno.result' | |||
175 | --- tests/suite/base/r/lineno.result 2009-09-21 14:34:47 +0000 | |||
176 | +++ tests/suite/base/r/lineno.result 2010-09-08 12:58:43 +0000 | |||
177 | @@ -1,4 +1,4 @@ | |||
178 | 1 | SELECT backtrace; | 1 | SELECT backtrace; |
179 | 2 | backtrace | 2 | backtrace |
180 | 3 | stack traceback: | 3 | stack traceback: |
182 | 4 | [string "/tmp/dummy.lua"]:48: in function <[string "/tmp/dummy.lua"]:32> | 4 | [string "lineno.lua"]:48: in function <[string "lineno.lua"]:32> |
183 | 5 | 5 | ||
184 | === modified file 'tests/suite/base/r/pooling.result' | |||
185 | --- tests/suite/base/r/pooling.result 2008-07-03 15:20:35 +0000 | |||
186 | +++ tests/suite/base/r/pooling.result 2010-09-08 12:58:43 +0000 | |||
187 | @@ -1,15 +1,18 @@ | |||
189 | 1 | SELECT counter; | 1 | SELECT conn_id, stmt_id; |
190 | 2 | conn_id stmt_id | 2 | conn_id stmt_id |
191 | 3 | 2 1 | 3 | 2 1 |
199 | 4 | SELECT counter; | 4 | SELECT conn_id, stmt_id; |
193 | 5 | conn_id stmt_id | ||
194 | 6 | 1 1 | ||
195 | 7 | SELECT counter; | ||
196 | 8 | conn_id stmt_id | ||
197 | 9 | 1 2 | ||
198 | 10 | SELECT counter; | ||
200 | 11 | conn_id stmt_id | 5 | conn_id stmt_id |
201 | 12 | 2 2 | 6 | 2 2 |
203 | 13 | SELECT counter; | 7 | SELECT conn_id, stmt_id; |
204 | 8 | conn_id stmt_id | ||
205 | 9 | 3 1 | ||
206 | 10 | SELECT conn_id, stmt_id; | ||
207 | 11 | conn_id stmt_id | ||
208 | 12 | 2 3 | ||
209 | 13 | SELECT conn_id, stmt_id; | ||
210 | 14 | conn_id stmt_id | ||
211 | 15 | 4 1 | ||
212 | 16 | SELECT conn_id, stmt_id; | ||
213 | 14 | conn_id stmt_id | 17 | conn_id stmt_id |
214 | 15 | 5 1 | 18 | 5 1 |
215 | 16 | 19 | ||
216 | === modified file 'tests/suite/base/t/lineno.lua' | |||
217 | --- tests/suite/base/t/lineno.lua 2010-04-06 15:25:06 +0000 | |||
218 | +++ tests/suite/base/t/lineno.lua 2010-09-08 12:58:43 +0000 | |||
219 | @@ -1,5 +1,5 @@ | |||
220 | 1 | --[[ NEVER change the number of lines of this license header without also changing r/lineno.result. Thus we don't dynamically update the license header, either. | 1 | --[[ NEVER change the number of lines of this license header without also changing r/lineno.result. Thus we don't dynamically update the license header, either. |
222 | 2 | Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. | 2 | Copyright (c) 2009, 2010 Oracle and/or its affiliates. All rights reserved. |
223 | 3 | 3 | ||
224 | 4 | This program is free software; you can redistribute it and/or modify | 4 | This program is free software; you can redistribute it and/or modify |
225 | 5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
226 | @@ -50,6 +50,19 @@ | |||
227 | 50 | 50 | ||
228 | 51 | } | 51 | } |
229 | 52 | } | 52 | } |
230 | 53 | elseif packet:sub(2) == "SELECT current_backtrace_filename" then | ||
231 | 54 | proxy.response = { | ||
232 | 55 | type = proxy.MYSQLD_PACKET_OK, | ||
233 | 56 | resultset = { | ||
234 | 57 | fields = { | ||
235 | 58 | { name = "filename", type = proxy.MYSQL_TYPE_STRING } | ||
236 | 59 | }, | ||
237 | 60 | rows = { | ||
238 | 61 | { debug.getinfo(1, "S").short_src } | ||
239 | 62 | } | ||
240 | 63 | |||
241 | 64 | } | ||
242 | 65 | } | ||
243 | 53 | else | 66 | else |
244 | 54 | proxy.response = { | 67 | proxy.response = { |
245 | 55 | type = proxy.MYSQLD_PACKET_ERR, | 68 | type = proxy.MYSQLD_PACKET_ERR, |
246 | 56 | 69 | ||
247 | === modified file 'tests/suite/base/t/lineno.test' | |||
248 | --- tests/suite/base/t/lineno.test 2010-04-06 14:26:51 +0000 | |||
249 | +++ tests/suite/base/t/lineno.test 2010-09-08 12:58:43 +0000 | |||
250 | @@ -1,5 +1,5 @@ | |||
251 | 1 | # $%BEGINLICENSE%$ | 1 | # $%BEGINLICENSE%$ |
253 | 2 | # Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved. | 2 | # Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. |
254 | 3 | # | 3 | # |
255 | 4 | # This program is free software; you can redistribute it and/or | 4 | # This program is free software; you can redistribute it and/or |
256 | 5 | # modify it under the terms of the GNU General Public License as | 5 | # modify it under the terms of the GNU General Public License as |
257 | @@ -17,4 +17,8 @@ | |||
258 | 17 | # 02110-1301 USA | 17 | # 02110-1301 USA |
259 | 18 | # | 18 | # |
260 | 19 | # $%ENDLICENSE%$ | 19 | # $%ENDLICENSE%$ |
261 | 20 | |||
262 | 21 | # fetch the Lua version of the current file-name | ||
263 | 22 | --let current_backtrace_filename = query_get_value("SELECT current_backtrace_filename", "filename", 1) | ||
264 | 23 | --replace_result $current_backtrace_filename "[string \"lineno.lua\"]" | ||
265 | 20 | SELECT backtrace; | 24 | SELECT backtrace; |
266 | 21 | 25 | ||
267 | === modified file 'tests/suite/base/t/load_multi.test' | |||
268 | --- tests/suite/base/t/load_multi.test 2010-04-06 14:26:51 +0000 | |||
269 | +++ tests/suite/base/t/load_multi.test 2010-09-08 12:58:43 +0000 | |||
270 | @@ -1,5 +1,5 @@ | |||
271 | 1 | # $%BEGINLICENSE%$ | 1 | # $%BEGINLICENSE%$ |
273 | 2 | # Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved. | 2 | # Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. |
274 | 3 | # | 3 | # |
275 | 4 | # This program is free software; you can redistribute it and/or | 4 | # This program is free software; you can redistribute it and/or |
276 | 5 | # modify it under the terms of the GNU General Public License as | 5 | # modify it under the terms of the GNU General Public License as |
277 | @@ -18,14 +18,14 @@ | |||
278 | 18 | # | 18 | # |
279 | 19 | # $%ENDLICENSE%$ | 19 | # $%ENDLICENSE%$ |
280 | 20 | --disable_query_log | 20 | --disable_query_log |
283 | 21 | --replace_result $srcdir <srcdir> | 21 | --replace_result $abs_srcdir <srcdir> |
284 | 22 | --eval pload $srcdir/base/t/lm2.lua | 22 | --eval pload $abs_srcdir/base/t/lm2.lua |
285 | 23 | --enable_query_log | 23 | --enable_query_log |
286 | 24 | connect (conn1,127.0.0.1,$MYSQL_USER,$MYSQL_PASSWORD,test,$PROXY_PORT,); | 24 | connect (conn1,127.0.0.1,$MYSQL_USER,$MYSQL_PASSWORD,test,$PROXY_PORT,); |
287 | 25 | select pload status; | 25 | select pload status; |
288 | 26 | --disable_query_log | 26 | --disable_query_log |
291 | 27 | --replace_result $srcdir <srcdir> | 27 | --replace_result $abs_srcdir <srcdir> |
292 | 28 | --eval pload $srcdir/base/t/lm1.lua | 28 | --eval pload $abs_srcdir/base/t/lm1.lua |
293 | 29 | --enable_query_log | 29 | --enable_query_log |
294 | 30 | connection conn1; | 30 | connection conn1; |
295 | 31 | select 'first' as info; | 31 | select 'first' as info; |
296 | @@ -44,13 +44,13 @@ | |||
297 | 44 | disconnect conn1; | 44 | disconnect conn1; |
298 | 45 | disconnect conn2; | 45 | disconnect conn2; |
299 | 46 | --disable_query_log | 46 | --disable_query_log |
302 | 47 | --replace_result $srcdir <srcdir> | 47 | --replace_result $abs_srcdir <srcdir> |
303 | 48 | --eval pload $srcdir/base/t/lm3.lua | 48 | --eval pload $abs_srcdir/base/t/lm3.lua |
304 | 49 | --enable_query_log | 49 | --enable_query_log |
305 | 50 | select 1000; | 50 | select 1000; |
306 | 51 | --disable_query_log | 51 | --disable_query_log |
309 | 52 | --replace_result $srcdir <srcdir> | 52 | --replace_result $abs_srcdir <srcdir> |
310 | 53 | --eval punload $srcdir/base/t/lm3.lua | 53 | --eval punload $abs_srcdir/base/t/lm3.lua |
311 | 54 | --enable_query_log | 54 | --enable_query_log |
312 | 55 | select 1000; | 55 | select 1000; |
313 | 56 | 56 | ||
314 | 57 | 57 | ||
315 | === modified file 'tests/suite/base/t/pooling-mock.lua' | |||
316 | --- tests/suite/base/t/pooling-mock.lua 2010-04-06 14:26:51 +0000 | |||
317 | +++ tests/suite/base/t/pooling-mock.lua 2010-09-08 12:58:43 +0000 | |||
318 | @@ -1,5 +1,5 @@ | |||
319 | 1 | --[[ $%BEGINLICENSE%$ | 1 | --[[ $%BEGINLICENSE%$ |
321 | 2 | Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. | 2 | Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. |
322 | 3 | 3 | ||
323 | 4 | This program is free software; you can redistribute it and/or | 4 | This program is free software; you can redistribute it and/or |
324 | 5 | modify it under the terms of the GNU General Public License as | 5 | modify it under the terms of the GNU General Public License as |
325 | @@ -23,24 +23,8 @@ | |||
326 | 23 | -- by comparing the statement-ids and the connection ids we can | 23 | -- by comparing the statement-ids and the connection ids we can |
327 | 24 | -- track if the ro-pooling script was reusing a connection | 24 | -- track if the ro-pooling script was reusing a connection |
328 | 25 | -- | 25 | -- |
347 | 26 | function packet_auth(fields) | 26 | |
348 | 27 | fields = fields or { } | 27 | local proto = require("mysql.proto") |
331 | 28 | return "\010" .. -- proto version | ||
332 | 29 | (fields.version or "5.0.45-proxy") .. -- version | ||
333 | 30 | "\000" .. -- term-null | ||
334 | 31 | "\001\000\000\000" .. -- thread-id | ||
335 | 32 | "\065\065\065\065" .. | ||
336 | 33 | "\065\065\065\065" .. -- challenge - part I | ||
337 | 34 | "\000" .. -- filler | ||
338 | 35 | "\001\130" .. -- server cap (long pass, 4.1 proto) | ||
339 | 36 | "\008" .. -- charset | ||
340 | 37 | "\002\000" .. -- status | ||
341 | 38 | ("\000"):rep(13) .. -- filler | ||
342 | 39 | "\065\065\065\065".. | ||
343 | 40 | "\065\065\065\065".. | ||
344 | 41 | "\065\065\065\065".. | ||
345 | 42 | "\000" -- challenge - part II | ||
346 | 43 | end | ||
349 | 44 | 28 | ||
350 | 45 | -- will be called once after connect | 29 | -- will be called once after connect |
351 | 46 | stmt_id = 0 | 30 | stmt_id = 0 |
352 | @@ -60,7 +44,7 @@ | |||
353 | 60 | proxy.response = { | 44 | proxy.response = { |
354 | 61 | type = proxy.MYSQLD_PACKET_RAW, | 45 | type = proxy.MYSQLD_PACKET_RAW, |
355 | 62 | packets = { | 46 | packets = { |
357 | 63 | packet_auth() | 47 | proto.to_challenge_packet({}) |
358 | 64 | } | 48 | } |
359 | 65 | } | 49 | } |
360 | 66 | return proxy.PROXY_SEND_RESULT | 50 | return proxy.PROXY_SEND_RESULT |
361 | @@ -78,15 +62,15 @@ | |||
362 | 78 | stmt_id = stmt_id + 1 | 62 | stmt_id = stmt_id + 1 |
363 | 79 | 63 | ||
364 | 80 | local query = packet:sub(2) | 64 | local query = packet:sub(2) |
366 | 81 | if query == 'SELECT counter' then | 65 | if query == 'SELECT conn_id, stmt_id' then |
367 | 82 | proxy.response = { | 66 | proxy.response = { |
368 | 83 | type = proxy.MYSQLD_PACKET_OK, | 67 | type = proxy.MYSQLD_PACKET_OK, |
369 | 84 | resultset = { | 68 | resultset = { |
370 | 85 | fields = { | 69 | fields = { |
373 | 86 | { name = 'conn_id' }, | 70 | { name = 'conn_id', type = proxy.MYSQLD_TYPE_INT }, |
374 | 87 | { name = 'stmt_id' }, | 71 | { name = 'stmt_id', type = proxy.MYSQLD_TYPE_INT }, |
375 | 88 | }, | 72 | }, |
377 | 89 | rows = { { tostring(conn_id), tostring(stmt_id) } } | 73 | rows = { { conn_id, stmt_id } } |
378 | 90 | } | 74 | } |
379 | 91 | } | 75 | } |
380 | 92 | else | 76 | else |
381 | 93 | 77 | ||
382 | === modified file 'tests/suite/base/t/pooling.test' | |||
383 | --- tests/suite/base/t/pooling.test 2010-04-06 14:26:51 +0000 | |||
384 | +++ tests/suite/base/t/pooling.test 2010-09-08 12:58:43 +0000 | |||
385 | @@ -1,5 +1,5 @@ | |||
386 | 1 | # $%BEGINLICENSE%$ | 1 | # $%BEGINLICENSE%$ |
388 | 2 | # Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. | 2 | # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. |
389 | 3 | # | 3 | # |
390 | 4 | # This program is free software; you can redistribute it and/or | 4 | # This program is free software; you can redistribute it and/or |
391 | 5 | # modify it under the terms of the GNU General Public License as | 5 | # modify it under the terms of the GNU General Public License as |
392 | @@ -17,22 +17,30 @@ | |||
393 | 17 | # 02110-1301 USA | 17 | # 02110-1301 USA |
394 | 18 | # | 18 | # |
395 | 19 | # $%ENDLICENSE%$ | 19 | # $%ENDLICENSE%$ |
398 | 20 | connect (conn1,127.0.0.1,root,,,$PROXY_PORT); | 20 | |
399 | 21 | SELECT counter; | 21 | # open a few connections and test if they reuse connections that |
400 | 22 | # end up in the pool | ||
401 | 23 | |||
402 | 24 | connect (conn1,$PROXY_HOST,root,,,$PROXY_PORT); | ||
403 | 25 | SELECT conn_id, stmt_id; | ||
404 | 22 | disconnect conn1; | 26 | disconnect conn1; |
405 | 23 | 27 | ||
408 | 24 | connect (conn2,127.0.0.1,root,,,$PROXY_PORT); | 28 | connect (conn2,$PROXY_HOST,root,,,$PROXY_PORT); |
409 | 25 | SELECT counter; | 29 | SELECT conn_id, stmt_id; |
410 | 26 | disconnect conn2; | 30 | disconnect conn2; |
411 | 27 | 31 | ||
414 | 28 | connect (conn3,127.0.0.1,root,,,$PROXY_PORT); | 32 | connect (conn3,$PROXY_HOST,root,,,$PROXY_PORT); |
415 | 29 | SELECT counter; | 33 | SELECT conn_id, stmt_id; |
416 | 30 | disconnect conn3; | 34 | disconnect conn3; |
417 | 31 | 35 | ||
420 | 32 | connect (conn4,127.0.0.1,root,,,$PROXY_PORT); | 36 | connect (conn4,$PROXY_HOST,root,,,$PROXY_PORT); |
421 | 33 | SELECT counter; | 37 | SELECT conn_id, stmt_id; |
422 | 34 | disconnect conn4; | 38 | disconnect conn4; |
423 | 35 | 39 | ||
426 | 36 | connect (conn5,127.0.0.1,root,,,$PROXY_PORT); | 40 | connect (conn5,$PROXY_HOST,root,,,$PROXY_PORT); |
427 | 37 | SELECT counter; | 41 | SELECT conn_id, stmt_id; |
428 | 38 | disconnect conn5; | 42 | disconnect conn5; |
429 | 43 | |||
430 | 44 | connect (conn6,$PROXY_HOST,root,,,$PROXY_PORT); | ||
431 | 45 | SELECT conn_id, stmt_id; | ||
432 | 46 | disconnect conn6; | ||
433 | 39 | 47 | ||
434 | === modified file 'tests/suite/run-tests.lua' | |||
435 | --- tests/suite/run-tests.lua 2010-05-05 10:46:53 +0000 | |||
436 | +++ tests/suite/run-tests.lua 2010-09-08 12:58:43 +0000 | |||
437 | @@ -30,46 +30,156 @@ | |||
438 | 30 | require("lfs") | 30 | require("lfs") |
439 | 31 | require("glib2") | 31 | require("glib2") |
440 | 32 | require("posix") | 32 | require("posix") |
473 | 33 | 33 | local fileutils = require("testenv.fileutils") | |
474 | 34 | --- | 34 | local shellutils = require("testenv.shellutils") |
475 | 35 | -- get the directory-name of a path | 35 | local testutils = require("testenv.testutils") |
476 | 36 | -- | 36 | local process = require("testenv.process") |
477 | 37 | -- @param filename path to create the directory name from | 37 | local processmanager = require("testenv.processmanager") |
446 | 38 | function dirname(filename) | ||
447 | 39 | local dirname = filename | ||
448 | 40 | |||
449 | 41 | attr = assert(lfs.attributes(dirname)) | ||
450 | 42 | |||
451 | 43 | if attr.mode == "directory" then | ||
452 | 44 | return dirname | ||
453 | 45 | end | ||
454 | 46 | |||
455 | 47 | dirname = filename:gsub("/[^/]+$", "") | ||
456 | 48 | |||
457 | 49 | attr = assert(lfs.attributes(dirname)) | ||
458 | 50 | |||
459 | 51 | assert(attr.mode == "directory", "dirname("..filename..") failed: is ".. attr.mode) | ||
460 | 52 | |||
461 | 53 | return dirname | ||
462 | 54 | end | ||
463 | 55 | |||
464 | 56 | --- | ||
465 | 57 | -- get the file-name of a path | ||
466 | 58 | -- | ||
467 | 59 | -- @param filename path to create the directory name from | ||
468 | 60 | function basename(filename) | ||
469 | 61 | name = filename:gsub(".*/", "") | ||
470 | 62 | |||
471 | 63 | return name | ||
472 | 64 | end | ||
478 | 65 | 38 | ||
479 | 66 | -- | 39 | -- |
480 | 67 | -- a set of user variables which can be overwritten from the environment | 40 | -- a set of user variables which can be overwritten from the environment |
481 | 68 | -- | 41 | -- |
482 | 69 | 42 | ||
486 | 70 | local testdir = dirname(arg[0]) | 43 | TestRunner = { |
487 | 71 | 44 | num_tests = 0, | |
488 | 72 | local USE_POPEN = os.getenv('USE_POPEN') or 1 | 45 | num_passes = 0, |
489 | 46 | num_skipped = 0, | ||
490 | 47 | num_fails = 0, | ||
491 | 48 | failed_test = {}, | ||
492 | 49 | tests = {}, | ||
493 | 50 | |||
494 | 51 | testenv = { | ||
495 | 52 | }, | ||
496 | 53 | |||
497 | 54 | force_on_error = true, | ||
498 | 55 | tests_to_skip_filename = "tests_to_skip.lua", | ||
499 | 56 | tests_regex = os.getenv("TESTS_REGEX") | ||
500 | 57 | } | ||
501 | 58 | |||
502 | 59 | function TestRunner:new(o) | ||
503 | 60 | -- create a new process object | ||
504 | 61 | -- | ||
505 | 62 | o = o or {} | ||
506 | 63 | setmetatable(o, self) | ||
507 | 64 | self.__index = self | ||
508 | 65 | |||
509 | 66 | local port_base = testutils.get_port_base(os.getenv("MYSQL_PROXY_START_PORT"), os.getenv("MYSQL_PROXY_END_PORT")) | ||
510 | 67 | |||
511 | 68 | self.testenv.testdir = fileutils.dirname(arg[0]) | ||
512 | 69 | self.testenv.srcdir = os.getenv("srcdir") or self.testenv.testdir .. "/" | ||
513 | 70 | self.testenv.top_builddir = os.getenv("top_builddir") or self.testenv.testdir .. "/../" | ||
514 | 71 | self.testenv.builddir = os.getenv("builddir") or self.testenv.testdir .. "/" -- same as srcdir by default | ||
515 | 72 | self.testenv.plugin_dir = self.testenv.top_builddir .. "/plugins/" | ||
516 | 73 | self.testenv.basedir = lfs.currentdir() | ||
517 | 74 | self.testenv.lua_path = self.testenv.basedir .. "/" .. self.testenv.srcdir .. "/../../lib/?.lua" | ||
518 | 75 | self.testenv.lua_cpath = self.testenv.basedir .. "/../../lib/.libs/?.so" | ||
519 | 76 | |||
520 | 77 | self.testenv.PROXY_HOST = os.getenv("PROXY_HOST") or "127.0.0.1" | ||
521 | 78 | self.testenv.PROXY_PORT = os.getenv("PROXY_PORT") or tostring(port_base + 0) | ||
522 | 79 | self.testenv.MYSQL_TEST_BIN = os.getenv("MYSQL_TEST_BIN") or "mysqltest" | ||
523 | 80 | self.testenv.MYSQL_CLIENT_BIN = os.getenv("MYSQL_CLIENT_BIN") or "mysql" | ||
524 | 81 | self.testenv.PROXY_CHAIN_PORT = os.getenv("PROXY_CHAIN_PORT") or tostring(port_base + 30) | ||
525 | 82 | |||
526 | 83 | self.testenv.abs_srcdir = os.getenv("abs_srcdir") | ||
527 | 84 | |||
528 | 85 | if not self.testenv.abs_srcdir then | ||
529 | 86 | if not fileutils.path_is_absolute(self.testenv.srcdir) then | ||
530 | 87 | local abs_srcdir = posix.getcwd() .. "/" .. self.testenv.srcdir | ||
531 | 88 | self.testenv.abs_srcdir = abs_srcdir | ||
532 | 89 | else | ||
533 | 90 | self.testenv.abs_srcdir = self.testenv.srcdir | ||
534 | 91 | end | ||
535 | 92 | glib2.setenv("abs_srcdir", self.testenv.abs_srcdir) -- expose the abs_srcdir again as we run the proxy as --daemon which chdir()s to / | ||
536 | 93 | end | ||
537 | 94 | |||
538 | 95 | return o | ||
539 | 96 | end | ||
540 | 97 | |||
541 | 98 | function TestRunner:register_tests(suites) | ||
542 | 99 | for i, suite in ipairs(suites) do | ||
543 | 100 | local suite_srcdir = self.testenv.srcdir .. '/' .. suite | ||
544 | 101 | local suite_skipfile = suite_srcdir .. '/' .. self.tests_to_skip_filename | ||
545 | 102 | local stat = assert(lfs.attributes(suite_srcdir)) | ||
546 | 103 | |||
547 | 104 | -- if it is a directory, execute all of them | ||
548 | 105 | if stat.mode == "directory" then | ||
549 | 106 | if fileutils.file_exists(suite_skipfile) then | ||
550 | 107 | assert(loadfile(suite_skipfile))() | ||
551 | 108 | end | ||
552 | 109 | |||
553 | 110 | for file in lfs.dir(suite_srcdir .. "/t/") do | ||
554 | 111 | local testname = file:match("(.+)\.test$") | ||
555 | 112 | |||
556 | 113 | if testname then | ||
557 | 114 | local is_skipped = false | ||
558 | 115 | |||
559 | 116 | if (self.tests_regex and not testname:match(self.tests_regex)) or tests_to_skip[testname] then | ||
560 | 117 | is_skipped = true | ||
561 | 118 | end | ||
562 | 119 | |||
563 | 120 | local test = MySQLProxyTest:new() | ||
564 | 121 | test.testname = testname | ||
565 | 122 | test.suite_srcdir = suite_srcdir | ||
566 | 123 | test.testenv = self.testenv | ||
567 | 124 | test.skipped = is_skipped | ||
568 | 125 | |||
569 | 126 | self.tests[#self.tests + 1] = test | ||
570 | 127 | end | ||
571 | 128 | end | ||
572 | 129 | end | ||
573 | 130 | end | ||
574 | 131 | end | ||
575 | 132 | |||
576 | 133 | function TestRunner:run_all() | ||
577 | 134 | local exitcode = 0 | ||
578 | 135 | |||
579 | 136 | for i, test in ipairs(self.tests) do | ||
580 | 137 | shellutils.print_verbose("# >> " .. test.testname .. " started") | ||
581 | 138 | |||
582 | 139 | self.num_tests = self.num_tests + 1 | ||
583 | 140 | local r = test:run() | ||
584 | 141 | if (r == 0) then | ||
585 | 142 | self.num_passes = self.num_passes + 1 | ||
586 | 143 | elseif (r == 77) then | ||
587 | 144 | self.num_skipped = self.num_skipped + 1 | ||
588 | 145 | else | ||
589 | 146 | self.num_fails = self.num_fails + 1 | ||
590 | 147 | table.insert(self.failed_test, test) | ||
591 | 148 | end | ||
592 | 149 | |||
593 | 150 | shellutils.print_verbose("# << (exitcode = " .. r .. ")" ) | ||
594 | 151 | |||
595 | 152 | if r ~= 0 and r ~= 77 and exitcode == 0 then | ||
596 | 153 | exitcode = r | ||
597 | 154 | end | ||
598 | 155 | |||
599 | 156 | if self.num_fails > 0 and (not self.force_on_error) then | ||
600 | 157 | break | ||
601 | 158 | end | ||
602 | 159 | end | ||
603 | 160 | |||
604 | 161 | if self.num_fails > 0 then | ||
605 | 162 | print ("*** ERRORS OCCURRED - The following tests failed") | ||
606 | 163 | for i, test in pairs(self.failed_test) do | ||
607 | 164 | print(test.testname) | ||
608 | 165 | end | ||
609 | 166 | end | ||
610 | 167 | |||
611 | 168 | -- | ||
612 | 169 | -- prints test suite statistics | ||
613 | 170 | shellutils.print_verbose (string.format('tests: %d - skipped: %d (%4.1f%%) - passed: %d (%4.1f%%) - failed: %d (%4.1f%%)', | ||
614 | 171 | self.num_tests, | ||
615 | 172 | self.num_skipped, | ||
616 | 173 | self.num_skipped / self.num_tests * 100, | ||
617 | 174 | self.num_passes, | ||
618 | 175 | self.num_passes / (self.num_tests - self.num_skipped) * 100, | ||
619 | 176 | self.num_fails, | ||
620 | 177 | self.num_fails / (self.num_tests - self.num_skipped) * 100)) | ||
621 | 178 | |||
622 | 179 | return exitcode | ||
623 | 180 | end | ||
624 | 181 | |||
625 | 182 | |||
626 | 73 | 183 | ||
627 | 74 | local VERBOSE = os.getenv('TEST_VERBOSE') or | 184 | local VERBOSE = os.getenv('TEST_VERBOSE') or |
628 | 75 | os.getenv('VERBOSE') or | 185 | os.getenv('VERBOSE') or |
629 | @@ -77,860 +187,318 @@ | |||
630 | 77 | VERBOSE = VERBOSE + 0 | 187 | VERBOSE = VERBOSE + 0 |
631 | 78 | 188 | ||
632 | 79 | local FORCE_ON_ERROR = os.getenv('FORCE_ON_ERROR') or os.getenv('FORCE') | 189 | local FORCE_ON_ERROR = os.getenv('FORCE_ON_ERROR') or os.getenv('FORCE') |
633 | 190 | |||
634 | 191 | |||
635 | 80 | local MYSQL_USER = os.getenv("MYSQL_USER") or "root" | 192 | local MYSQL_USER = os.getenv("MYSQL_USER") or "root" |
636 | 81 | local MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD") or "" | 193 | local MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD") or "" |
637 | 82 | local MYSQL_HOST = os.getenv("MYSQL_HOST") or "127.0.0.1" | 194 | local MYSQL_HOST = os.getenv("MYSQL_HOST") or "127.0.0.1" |
638 | 83 | local MYSQL_PORT = os.getenv("MYSQL_PORT") or "3306" | 195 | local MYSQL_PORT = os.getenv("MYSQL_PORT") or "3306" |
639 | 84 | local MYSQL_DB = os.getenv("MYSQL_DB") or "test" | 196 | local MYSQL_DB = os.getenv("MYSQL_DB") or "test" |
687 | 85 | local MYSQL_TEST_BIN = os.getenv("MYSQL_TEST_BIN") or "mysqltest" | 197 | |
641 | 86 | local MYSQL_CLIENT_BIN = os.getenv("MYSQL_CLIENT_BIN") or "mysql" | ||
642 | 87 | local TESTS_REGEX = os.getenv("TESTS_REGEX") | ||
643 | 88 | |||
644 | 89 | -- | ||
645 | 90 | -- Global variables that can be referenced from .options files | ||
646 | 91 | -- | ||
647 | 92 | -- TODO : add HOST variables for MASTER, SLAVE, CHAIN | ||
648 | 93 | function get_port_base() | ||
649 | 94 | local port_base_start = os.getenv("MYSQL_PROXY_START_PORT") or 32768 | ||
650 | 95 | local port_base_end = os.getenv("MYSQL_PROXY_END_PORT") or 65535 | ||
651 | 96 | local port_interval = 64 -- let's take the base port in steps of ... | ||
652 | 97 | local range = port_base_end - port_base_start - port_interval | ||
653 | 98 | math.randomseed(posix.getpid()) | ||
654 | 99 | local rand = math.floor(math.random() * (math.ceil(range / port_interval))) | ||
655 | 100 | local port_base = port_base_start + (rand * port_interval) | ||
656 | 101 | |||
657 | 102 | print(("... using tcp-port = %d as start port"):format(port_base)) | ||
658 | 103 | |||
659 | 104 | return port_base | ||
660 | 105 | end | ||
661 | 106 | local port_base = get_port_base() | ||
662 | 107 | |||
663 | 108 | PROXY_HOST = os.getenv("PROXY_HOST") or "127.0.0.1" | ||
664 | 109 | PROXY_PORT = os.getenv("PROXY_PORT") or tostring(port_base + 0) | ||
665 | 110 | PROXY_MASTER_PORT = os.getenv("PROXY_MASTER_PORT") or tostring(port_base + 10) | ||
666 | 111 | PROXY_SLAVE_PORT = os.getenv("PROXY_SLAVE_PORT") or tostring(port_base + 20) | ||
667 | 112 | PROXY_CHAIN_PORT = os.getenv("PROXY_CHAIN_PORT") or tostring(port_base + 30) | ||
668 | 113 | ADMIN_PORT = os.getenv("ADMIN_PORT") or tostring(port_base + 15) | ||
669 | 114 | ADMIN_MASTER_PORT = os.getenv("ADMIN_MASTER_PORT") or tostring(port_base + 25) | ||
670 | 115 | ADMIN_SLAVE_PORT = os.getenv("ADMIN_SLAVE_PORT") or tostring(port_base + 35) | ||
671 | 116 | ADMIN_CHAIN_PORT = os.getenv("ADMIN_CHAIN_PORT") or tostring(port_base + 45) | ||
672 | 117 | ADMIN_USER = os.getenv("ADMIN_USER") or "root" | ||
673 | 118 | ADMIN_PASSWORD = os.getenv("ADMIN_PASSWORD") or "" | ||
674 | 119 | ADMIN_DEFAULT_SCRIPT_FILENAME = os.getenv("ADMIN_DEFAULT_SCRIPT_FILENAME") or "" | ||
675 | 120 | -- local PROXY_TMP_LUASCRIPT = os.getenv("PROXY_TMP_LUASCRIPT") or "/tmp/proxy.tmp.lua" | ||
676 | 121 | |||
677 | 122 | local srcdir = os.getenv("srcdir") or testdir .. "/" | ||
678 | 123 | local top_builddir = os.getenv("top_builddir") or testdir .. "/../" | ||
679 | 124 | local builddir = os.getenv("builddir") or testdir .. "/" -- same as srcdir by default | ||
680 | 125 | |||
681 | 126 | local PROXY_TRACE = os.getenv("PROXY_TRACE") or "" -- use it to inject strace or valgrind | ||
682 | 127 | local PROXY_PARAMS = os.getenv("PROXY_PARAMS") or "" -- extra params | ||
683 | 128 | local PROXY_BINPATH = os.getenv("PROXY_BINPATH") or top_builddir .. "/src/mysql-proxy" | ||
684 | 129 | PROXY_LIBPATH = os.getenv("PROXY_LIBPATH") or top_builddir .. "/plugins/" | ||
685 | 130 | |||
686 | 131 | local COVERAGE_LCOV = os.getenv("COVERAGE_LCOV") | ||
688 | 132 | 198 | ||
689 | 133 | -- | 199 | -- |
690 | 134 | -- end of user-vars | 200 | -- end of user-vars |
691 | 135 | -- | 201 | -- |
692 | 136 | 202 | ||
818 | 137 | PROXY_PIDFILE = lfs.currentdir() .. "/mysql-proxy-test.pid" | 203 | -- options for the MySQL Proxy |
819 | 138 | PROXY_MASTER_PIDFILE = lfs.currentdir() .. "/mysql-proxy-test-master.pid" | 204 | MySQLProxy = { |
820 | 139 | PROXY_SLAVE_PIDFILE = lfs.currentdir() .. "/mysql-proxy-test-slave.pid" | 205 | } |
821 | 140 | PROXY_CHAIN_PIDFILE = lfs.currentdir() .. "/mysql-proxy-test-chain.pid" | 206 | function MySQLProxy:new(o) |
822 | 141 | PROXY_BACKEND_PIDFILE = lfs.currentdir() .. "/mysql-proxy-test-backend.pid" | 207 | -- create a new process object |
698 | 142 | PROXY_TEST_BASEDIR = lfs.currentdir() | ||
699 | 143 | |||
700 | 144 | DEFAULT_SCRIPT_FILENAME = "/tmp/dummy.lua" | ||
701 | 145 | default_proxy_options = { | ||
702 | 146 | ["proxy-backend-addresses"] = MYSQL_HOST .. ":" .. MYSQL_PORT, | ||
703 | 147 | ["proxy-address"] = PROXY_HOST .. ":" .. PROXY_PORT, | ||
704 | 148 | ["admin-address"] = PROXY_HOST .. ":" .. ADMIN_PORT, | ||
705 | 149 | ["admin-username"] = ADMIN_USER, | ||
706 | 150 | ["admin-password"] = ADMIN_PASSWORD, | ||
707 | 151 | ["admin-lua-script"] = ADMIN_DEFAULT_SCRIPT_FILENAME, | ||
708 | 152 | ["pid-file"] = PROXY_PIDFILE, | ||
709 | 153 | ["proxy-lua-script"] = DEFAULT_SCRIPT_FILENAME, | ||
710 | 154 | ["plugin-dir"] = PROXY_LIBPATH, | ||
711 | 155 | ["basedir"] = PROXY_TEST_BASEDIR, | ||
712 | 156 | } | ||
713 | 157 | |||
714 | 158 | default_master_options = { | ||
715 | 159 | ["proxy-backend-addresses"] = MYSQL_HOST .. ":" .. MYSQL_PORT, | ||
716 | 160 | ["proxy-address"] = PROXY_HOST .. ":" .. PROXY_MASTER_PORT, | ||
717 | 161 | ["admin-address"] = PROXY_HOST .. ":" .. ADMIN_MASTER_PORT, | ||
718 | 162 | ["admin-username"] = ADMIN_USER, | ||
719 | 163 | ["admin-password"] = ADMIN_PASSWORD, | ||
720 | 164 | ["admin-lua-script"] = ADMIN_DEFAULT_SCRIPT_FILENAME, | ||
721 | 165 | ["pid-file"] = PROXY_MASTER_PIDFILE, | ||
722 | 166 | ["proxy-lua-script"] = DEFAULT_SCRIPT_FILENAME, | ||
723 | 167 | ["plugin-dir"] = PROXY_LIBPATH, | ||
724 | 168 | ["basedir"] = PROXY_TEST_BASEDIR, | ||
725 | 169 | } | ||
726 | 170 | |||
727 | 171 | default_slave_options = { | ||
728 | 172 | ["proxy-backend-addresses"] = MYSQL_HOST .. ":" .. MYSQL_PORT, | ||
729 | 173 | ["proxy-address"] = PROXY_HOST .. ":" .. PROXY_SLAVE_PORT, | ||
730 | 174 | ["admin-address"] = PROXY_HOST .. ":" .. ADMIN_SLAVE_PORT, | ||
731 | 175 | ["admin-username"] = ADMIN_USER, | ||
732 | 176 | ["admin-password"] = ADMIN_PASSWORD, | ||
733 | 177 | ["admin-lua-script"] = ADMIN_DEFAULT_SCRIPT_FILENAME, | ||
734 | 178 | ["pid-file"] = PROXY_SLAVE_PIDFILE, | ||
735 | 179 | ["proxy-lua-script"] = DEFAULT_SCRIPT_FILENAME, | ||
736 | 180 | ["plugin-dir"] = PROXY_LIBPATH, | ||
737 | 181 | ["basedir"] = PROXY_TEST_BASEDIR, | ||
738 | 182 | } | ||
739 | 183 | |||
740 | 184 | |||
741 | 185 | tests_to_skip = {} | ||
742 | 186 | local tests_to_skip_filename = 'tests_to_skip.lua' | ||
743 | 187 | local proxy_list = {} | ||
744 | 188 | default_proxy_name = 'default' | ||
745 | 189 | |||
746 | 190 | local exitcode=0 | ||
747 | 191 | |||
748 | 192 | --- | ||
749 | 193 | -- print_verbose() | ||
750 | 194 | -- | ||
751 | 195 | -- prints a message if either the DEBUG or VERBOSE variables | ||
752 | 196 | -- are set. | ||
753 | 197 | -- | ||
754 | 198 | -- @param msg the message being printed | ||
755 | 199 | -- @param min_level the minimum verbosity level for printing the message (default 1) | ||
756 | 200 | function print_verbose(msg, min_level) | ||
757 | 201 | min_level = min_level or 1 | ||
758 | 202 | if (VERBOSE >= min_level) then | ||
759 | 203 | print (msg) | ||
760 | 204 | end | ||
761 | 205 | end | ||
762 | 206 | --- | ||
763 | 207 | -- check if the file exists and is readable | ||
764 | 208 | function file_exists(f) | ||
765 | 209 | return lfs.attributes(f) | ||
766 | 210 | end | ||
767 | 211 | |||
768 | 212 | --- | ||
769 | 213 | -- create the default option file | ||
770 | 214 | -- | ||
771 | 215 | function make_default_options_file(fname) | ||
772 | 216 | if file_exists(fname) then | ||
773 | 217 | return | ||
774 | 218 | end | ||
775 | 219 | local fd = assert(io.open(fname, "w")) | ||
776 | 220 | fd:write('start_proxy(default_proxy_name, default_proxy_options) \n') | ||
777 | 221 | fd:close(); | ||
778 | 222 | end | ||
779 | 223 | |||
780 | 224 | --- | ||
781 | 225 | -- copy a file | ||
782 | 226 | -- | ||
783 | 227 | -- @param dst filename of the destination | ||
784 | 228 | -- @param src filename of the source | ||
785 | 229 | function file_copy(dst, src) | ||
786 | 230 | -- print_verbose("copying ".. src .. " to " .. dst) | ||
787 | 231 | local src_fd = assert(io.open(src, "rb")) | ||
788 | 232 | local content = src_fd:read("*a") | ||
789 | 233 | src_fd:close(); | ||
790 | 234 | |||
791 | 235 | local dst_fd = assert(io.open(dst, "wb+")) | ||
792 | 236 | dst_fd:write(content); | ||
793 | 237 | dst_fd:close(); | ||
794 | 238 | end | ||
795 | 239 | |||
796 | 240 | --- | ||
797 | 241 | -- create a empty file | ||
798 | 242 | -- | ||
799 | 243 | -- if the file exists, it will be truncated to 0 | ||
800 | 244 | -- | ||
801 | 245 | -- @param dst filename to create and truncate | ||
802 | 246 | function file_empty(dst) | ||
803 | 247 | -- print_verbose("emptying " .. dst) | ||
804 | 248 | local dst_fd = assert(io.open(dst, "wb+")) | ||
805 | 249 | dst_fd:close(); | ||
806 | 250 | end | ||
807 | 251 | |||
808 | 252 | --- | ||
809 | 253 | -- turn a option-table into a string | ||
810 | 254 | -- | ||
811 | 255 | -- the values are encoded and quoted for the shell | ||
812 | 256 | -- | ||
813 | 257 | -- @param tbl a option table | ||
814 | 258 | -- @param sep the seperator, defaults to a space | ||
815 | 259 | function options_tostring(tbl, sep) | ||
816 | 260 | -- default value for sep | ||
817 | 261 | sep = sep or " " | ||
823 | 262 | 208 | ||
886 | 263 | assert(type(tbl) == "table") | 209 | o = o or {} |
887 | 264 | assert(type(sep) == "string") | 210 | setmetatable(o, self) |
888 | 265 | 211 | self.__index = self | |
889 | 266 | local s = "" | 212 | |
890 | 267 | for k, v in pairs(tbl) do | 213 | self.backends = { } |
891 | 268 | local values | 214 | return o |
892 | 269 | -- if the value is a table, repeat the option | 215 | end |
893 | 270 | if type(v) == "table" then | 216 | |
894 | 271 | values = v | 217 | function MySQLProxy:add_backend(addr) |
895 | 272 | else | 218 | self.backends[#self.backends + 1] = addr |
896 | 273 | values = { v } | 219 | end |
897 | 274 | end | 220 | |
898 | 275 | 221 | function MySQLProxy:get_args(opts) | |
899 | 276 | for tk, tv in pairs(values) do | 222 | -- add a default backend |
900 | 277 | local enc_value = tv:gsub("\\", "\\\\"):gsub("\"", "\\\"") | 223 | if #self.backends == 0 then |
901 | 278 | s = s .. "--" .. k .. "=\"" .. enc_value .. "\" " | 224 | self:add_backend(("%s:%d"):format(MYSQL_HOST, MYSQL_PORT)) |
902 | 279 | end | 225 | end |
903 | 280 | end | 226 | |
904 | 281 | -- print_verbose(" option: " .. s) | 227 | opts = opts or { } |
905 | 282 | 228 | opts["plugin-dir"] = self.testenv["plugin_dir"] | |
906 | 283 | return s | 229 | opts["basedir"] = self.testenv["basedir"] |
907 | 284 | end | 230 | opts["pid-file"] = opts["pid-file"] or ("%s/mysql-proxy.pid"):format(self.testenv.basedir) |
908 | 285 | 231 | opts["plugins"] = "proxy" | |
909 | 286 | --- turns an option table into a string of environment variables | 232 | opts["proxy-address"]= opts["proxy-address"] or ("%s:%d"):format(self.testenv.PROXY_HOST, self.testenv.PROXY_PORT) |
910 | 287 | -- | 233 | self.proxy_address = opts["proxy-address"] |
911 | 288 | function env_options_tostring(tbl) | 234 | opts["daemon"] = true |
912 | 289 | assert(type(tbl) == "table") | 235 | opts["lua-path"] = self.testenv.lua_path |
913 | 290 | 236 | opts["lua-cpath"] = self.testenv.lua_cpath | |
914 | 291 | local s = "" | 237 | |
915 | 292 | for k, v in pairs(tbl) do | 238 | opts["proxy-backend-addresses"] = self.backends |
916 | 293 | local enc_value = v:gsub("\\", "\\\\"):gsub("\"", "\\\"") | 239 | |
917 | 294 | s = s .. k .. "=\"" .. enc_value .. "\" " | 240 | return opts |
918 | 295 | end | 241 | end |
919 | 296 | 242 | ||
920 | 297 | return s | 243 | function MySQLProxy:get_env() |
921 | 298 | end | 244 | return {} |
922 | 299 | 245 | end | |
923 | 300 | 246 | ||
924 | 301 | function os_execute(cmdline) | 247 | function MySQLProxy:get_command() |
925 | 302 | print_verbose("$ " .. cmdline) | 248 | return os.getenv("PROXY_BINPATH") or self.testenv.top_builddir .. "/src/mysql-proxy" |
926 | 303 | return os.execute(cmdline) | 249 | end |
927 | 304 | end | 250 | |
928 | 305 | 251 | --- | |
929 | 306 | --- | 252 | -- the backend |
930 | 307 | -- get the PID from the pid file | 253 | MockBackend = MySQLProxy:new() |
931 | 308 | -- | 254 | function MockBackend:chain_with_frontend(frontend) |
932 | 309 | function get_pid(pid_file_name) | 255 | frontend:add_backend(self.proxy_address) |
933 | 310 | -- the file may exist, but the PID may not be written yet | 256 | end |
934 | 311 | local pid | 257 | |
935 | 312 | local rounds = 0 | 258 | Test = { |
936 | 313 | 259 | } | |
937 | 314 | repeat | 260 | |
938 | 315 | local fh = assert(io.open(pid_file_name, 'r')) | 261 | function Test:new(o) |
939 | 316 | pid = fh:read("*n") | 262 | -- create a new process object |
940 | 317 | fh:close() | 263 | -- |
941 | 318 | if not pid then | 264 | o = o or {} |
942 | 319 | glib2.usleep(200 * 1000) -- wait a bit until we get some content | 265 | setmetatable(o, self) |
943 | 320 | rounds = rounds + 1 | 266 | self.__index = self |
944 | 321 | 267 | ||
945 | 322 | if rounds > 10 then | 268 | self.skipped = false |
946 | 323 | error(("reading PID from existing pid-file '%s' failed after waiting 2 sec"):format( | 269 | self.testname = nil |
947 | 324 | pid_file_name)) | 270 | |
948 | 271 | return o | ||
949 | 272 | end | ||
950 | 273 | |||
951 | 274 | --- | ||
952 | 275 | -- @return true[, msg] if test should be skipped, false otherwise | ||
953 | 276 | function Test:is_skipped() | ||
954 | 277 | return self.skipped | ||
955 | 278 | end | ||
956 | 279 | |||
957 | 280 | function Test:setup() | ||
958 | 281 | return true | ||
959 | 282 | end | ||
960 | 283 | |||
961 | 284 | function Test:teardown() | ||
962 | 285 | return true | ||
963 | 286 | end | ||
964 | 287 | |||
965 | 288 | function Test:run() | ||
966 | 289 | local is_skipped, skip_msg = self:is_skipped() | ||
967 | 290 | |||
968 | 291 | if is_skipped then | ||
969 | 292 | print(('skip %s %s'):format( | ||
970 | 293 | self.testname, | ||
971 | 294 | skip_msg or 'no reason given')) | ||
972 | 295 | return 77 | ||
973 | 296 | end | ||
974 | 297 | |||
975 | 298 | self.procs = processmanager:new() | ||
976 | 299 | |||
977 | 300 | local ret, errmsg = self:setup() | ||
978 | 301 | if not ret then | ||
979 | 302 | print(("err %s # setup failed: %s"):format( | ||
980 | 303 | self.testname, | ||
981 | 304 | errmsg)) | ||
982 | 305 | ret = -1 | ||
983 | 306 | else | ||
984 | 307 | ret = self:run_test() | ||
985 | 308 | self:teardown() | ||
986 | 309 | end | ||
987 | 310 | |||
988 | 311 | self.procs:shutdown_all() -- shutdown all the processes we started | ||
989 | 312 | |||
990 | 313 | return ret | ||
991 | 314 | end | ||
992 | 315 | |||
993 | 316 | --- | ||
994 | 317 | -- a Test baseclass that knows about | ||
995 | 318 | -- * mysqltest as test-driver | ||
996 | 319 | -- * starting MySQL Proxies before starting mysqltest | ||
997 | 320 | -- | ||
998 | 321 | -- inherited from Test | ||
999 | 322 | MySQLProxyTest = Test:new() | ||
1000 | 323 | |||
1001 | 324 | --- | ||
1002 | 325 | -- 'test_self' is a hack to pass down the object we test right now to chain_proxy(). | ||
1003 | 326 | -- | ||
1004 | 327 | -- It is set in MySQLProxyTest:setup() | ||
1005 | 328 | test_self = nil | ||
1006 | 329 | |||
1007 | 330 | --- | ||
1008 | 331 | -- setup the backend proxies and wire them together | ||
1009 | 332 | -- | ||
1010 | 333 | -- depends on 'test_self' being a set to the currently running Test-object | ||
1011 | 334 | function chain_proxy(backend_filenames, script_filename) | ||
1012 | 335 | local self = test_self | ||
1013 | 336 | |||
1014 | 337 | if type(backend_filenames) ~= "table" then | ||
1015 | 338 | backend_filenames = { backend_filenames } | ||
1016 | 339 | end | ||
1017 | 340 | |||
1018 | 341 | local backends = { } | ||
1019 | 342 | for backend_ndx, backend_filename in ipairs(backend_filenames) do | ||
1020 | 343 | local mock = MockBackend:new() | ||
1021 | 344 | mock.testenv = self.testenv | ||
1022 | 345 | |||
1023 | 346 | local port = tonumber(self.testenv.PROXY_CHAIN_PORT) + backend_ndx - 1 -- we start with 1 | ||
1024 | 347 | |||
1025 | 348 | local mock_args = mock:get_args({ | ||
1026 | 349 | ["proxy-lua-script"] = ("%s/t/%s"):format(self.suite_srcdir, backend_filename), | ||
1027 | 350 | ["proxy-address"] = ("%s:%d"):format(self.testenv.PROXY_HOST, port), | ||
1028 | 351 | ["pid-file"] = ("%s/chain-%d.pid"):format(self.testenv.basedir, backend_ndx) | ||
1029 | 352 | }) | ||
1030 | 353 | |||
1031 | 354 | local proc = process:new() | ||
1032 | 355 | local ret = proc:execute(mock:get_command(), | ||
1033 | 356 | mock:get_env(), | ||
1034 | 357 | mock_args) | ||
1035 | 358 | if ret ~= 0 then | ||
1036 | 359 | return false, "" | ||
1037 | 360 | end | ||
1038 | 361 | |||
1039 | 362 | if mock_args["pid-file"] then | ||
1040 | 363 | local is_running, errmsg = proc:wait_running(mock_args["pid-file"]) | ||
1041 | 364 | if not is_running then | ||
1042 | 365 | return false, errmsg or "not running" | ||
1043 | 325 | end | 366 | end |
1044 | 326 | end | 367 | end |
1248 | 327 | until pid | 368 | |
1249 | 328 | 369 | self.procs:add(proc) | |
1250 | 329 | -- the PID we get here should be a number | 370 | table.insert(backends, mock) |
1251 | 330 | assert(type(pid) == "number") | 371 | end |
1252 | 331 | 372 | -- all the backends are up, start the middle proxy | |
1253 | 332 | return pid | 373 | |
1254 | 333 | end | 374 | script_filename = ("%s/t/%s"):format(self.suite_srcdir, script_filename) |
1255 | 334 | 375 | ||
1256 | 335 | function wait_proc_up(pid_file) | 376 | local proxy = MySQLProxy:new() |
1257 | 336 | local rounds = 0 | 377 | proxy.testenv = self.testenv |
1258 | 337 | 378 | ||
1259 | 338 | while not file_exists(pid_file) do | 379 | for _, backend in ipairs(backends) do |
1260 | 339 | glib2.usleep(200 * 1000) -- wait until the pid-file is created | 380 | backend:chain_with_frontend(proxy) |
1261 | 340 | 381 | end | |
1262 | 341 | rounds = rounds + 1 | 382 | |
1263 | 342 | print_verbose(("(wait_proc_up) pid-wait: %d rounds, (%s)"):format(rounds, pid_file)) | 383 | local proxy_args = proxy:get_args({ |
1264 | 343 | 384 | ["proxy-lua-script"] = script_filename, | |
1265 | 344 | if rounds > 1000 then error(("proxy failed to start: no pid-file %s"):format(pid_file)) end | 385 | }) |
1266 | 345 | end | 386 | |
1267 | 346 | 387 | local proc = process:new() | |
1268 | 347 | local pid = get_pid(pid_file) | 388 | local ret = proc:execute(proxy:get_command(), |
1269 | 348 | 389 | proxy:get_env(), | |
1270 | 349 | rounds = 0 | 390 | proxy_args) |
1271 | 350 | -- check that the process referenced in the PID-file is still up | 391 | if ret ~= 0 then |
1272 | 351 | while 0 ~= os.execute("kill -0 ".. pid .." 2> /dev/null") do | 392 | return false, "" |
1273 | 352 | glib2.usleep(200 * 1000) -- wait until the pid-file is created | 393 | end |
1274 | 353 | rounds = rounds + 1 | 394 | if proxy_args["pid-file"] then |
1275 | 354 | print_verbose(("(wait_proc_up) kill-wait: %d rounds, pid=%d (%s)"):format(rounds, pid, pid_file)) | 395 | local is_running, errmsg = proc:wait_running(proxy_args["pid-file"]) |
1276 | 355 | 396 | if not is_running then | |
1277 | 356 | if rounds > 5 then error(("proxy seems to have crashed: pid=%d (%s)"):format(pid, pid_file)) end | 397 | return false, errmsg or "not running" |
1278 | 357 | end | 398 | end |
1279 | 358 | end | 399 | end |
1280 | 359 | 400 | ||
1281 | 360 | function proc_is_up(pid) | 401 | self.procs:add(proc) |
1282 | 361 | return os.execute("kill -0 ".. pid .." 2> /dev/null") | 402 | end |
1283 | 362 | end | 403 | |
1284 | 363 | 404 | function MySQLProxyTest:start_proxy(script_filename) | |
1285 | 364 | function proc_stop(pid) | 405 | local proxy = MySQLProxy:new() |
1286 | 365 | return os.execute("kill -TERM ".. pid) | 406 | proxy.testenv = self.testenv |
1287 | 366 | end | 407 | local proxy_args = proxy:get_args({ |
1288 | 367 | 408 | ["proxy-lua-script"] = script_filename, | |
1289 | 368 | function wait_proc_down(pid_file) | 409 | }) |
1290 | 369 | local rounds = 0 | 410 | |
1291 | 370 | local pid = get_pid(pid_file) | 411 | local proc = process:new() |
1292 | 371 | 412 | local ret = proc:execute(proxy:get_command(), | |
1293 | 372 | -- wait until the proc in the pid file is dead | 413 | proxy:get_env(), |
1294 | 373 | -- the shutdown takes at about 500ms | 414 | proxy_args) |
1295 | 374 | while 0 == proc_is_up(pid) do | 415 | if ret ~= 0 then |
1296 | 375 | glib2.usleep(200 * 1000) -- wait until process is gone | 416 | return false, "" |
1297 | 376 | rounds = rounds + 1 | 417 | end |
1298 | 377 | print_verbose(("(wait_proc_down) kill-wait: %d rounds, pid=%d (%s)"):format(rounds, pid, pid_file)) | 418 | if proxy_args["pid-file"] then |
1299 | 378 | end | 419 | local is_running, errmsg = proc:wait_running(proxy_args["pid-file"]) |
1300 | 379 | end | 420 | if not is_running then |
1301 | 380 | 421 | return false, errmsg or "not running" | |
1302 | 381 | function stop_proxy() | 422 | end |
1303 | 382 | -- shut dowm the proxy | 423 | end |
1304 | 383 | -- | 424 | |
1305 | 384 | -- win32 has tasklist and taskkill on the shell | 425 | self.procs:add(proc) |
1306 | 385 | 426 | end | |
1307 | 386 | 427 | ||
1308 | 387 | -- shuts down every proxy in the proxy list | 428 | function MySQLProxyTest:setup() |
1309 | 388 | -- | 429 | local script_filename = ("%s/t/%s.lua"):format(self.suite_srcdir, self.testname) |
1310 | 389 | for proxy_name, proxy_options in pairs(proxy_list) do | 430 | local options_filename = ("%s/t/%s.options"):format(self.suite_srcdir, self.testname) |
1311 | 390 | local pid | 431 | local has_script_file = fileutils.file_exists(script_filename) |
1312 | 391 | pid_file = proxy_options['pid-file'] | 432 | local has_options_file = fileutils.file_exists(options_filename) |
1313 | 392 | print_verbose ('stopping proxy ' .. proxy_name) | 433 | |
1314 | 393 | 434 | -- if we have a options file, run it as part of the setup phases | |
1315 | 394 | pid = get_pid(pid_file) | 435 | -- if not, assume that we want to start a proxy with the script_filename |
1316 | 395 | 436 | if has_options_file then | |
1317 | 396 | if proc_is_up(pid) then | 437 | -- load the options file |
1318 | 397 | proc_stop(pid) | 438 | test_self = self -- expose 'self' so that chain_proxy() can use it |
1319 | 398 | else | 439 | local setup_func, errmsg = loadfile(options_filename) |
1320 | 399 | print("-- process "..proxy_name.." is already down") | 440 | if not setup_func then |
1321 | 400 | exitcode = -1 | 441 | return false, errmsg |
1322 | 401 | end | 442 | end |
1323 | 402 | end | 443 | |
1324 | 403 | 444 | -- try to call the setup func | |
1325 | 404 | -- wait until they are all gone | 445 | local ret, errmsg = pcall(setup_func) |
1326 | 405 | for proxy_name, proxy_options in pairs(proxy_list) do | 446 | if not ret then |
1327 | 406 | pid_file = proxy_options['pid-file'] | 447 | return false, errmsg |
1328 | 407 | 448 | end | |
1329 | 408 | wait_proc_down(pid_file) | 449 | else |
1330 | 409 | 450 | self:start_proxy(script_filename) | |
1331 | 410 | os.remove(pid_file) | 451 | end |
1332 | 411 | end | 452 | return true |
1333 | 412 | 453 | end | |
1334 | 413 | -- | 454 | |
1335 | 414 | -- empties the proxy list | 455 | function MySQLProxyTest:run_test() |
1133 | 415 | -- | ||
1134 | 416 | proxy_list = { } | ||
1135 | 417 | end | ||
1136 | 418 | |||
1137 | 419 | function only_item ( tbl, item) | ||
1138 | 420 | local exists = false | ||
1139 | 421 | for i,v in pairs(tbl) do | ||
1140 | 422 | if i == item then | ||
1141 | 423 | exists = true | ||
1142 | 424 | else | ||
1143 | 425 | return false | ||
1144 | 426 | end | ||
1145 | 427 | end | ||
1146 | 428 | return exists | ||
1147 | 429 | end | ||
1148 | 430 | |||
1149 | 431 | --- | ||
1150 | 432 | -- before_test() | ||
1151 | 433 | -- | ||
1152 | 434 | -- Executes a script with a base name like test_name and extension ".options" | ||
1153 | 435 | -- | ||
1154 | 436 | -- If there is no such file, the default options are used | ||
1155 | 437 | -- | ||
1156 | 438 | function before_test(basedir, test_name) | ||
1157 | 439 | local script_filename = basedir .. "/t/" .. test_name .. ".lua" | ||
1158 | 440 | local options_filename = basedir .. "/t/" .. test_name .. ".options" | ||
1159 | 441 | local has_option_file = file_exists(options_filename) | ||
1160 | 442 | if file_exists( script_filename) then | ||
1161 | 443 | if has_option_file then | ||
1162 | 444 | default_proxy_options['proxy-lua-script'] = script_filename | ||
1163 | 445 | print_verbose('using lua script directly ' .. script_filename) | ||
1164 | 446 | file_empty(DEFAULT_SCRIPT_FILENAME) | ||
1165 | 447 | else | ||
1166 | 448 | default_proxy_options['proxy-lua-script'] = DEFAULT_SCRIPT_FILENAME | ||
1167 | 449 | file_copy(DEFAULT_SCRIPT_FILENAME, script_filename) | ||
1168 | 450 | print_verbose('copying lua script to default ' .. script_filename) | ||
1169 | 451 | end | ||
1170 | 452 | else | ||
1171 | 453 | default_proxy_options['proxy-lua-script'] = DEFAULT_SCRIPT_FILENAME | ||
1172 | 454 | file_empty(DEFAULT_SCRIPT_FILENAME) | ||
1173 | 455 | print_verbose('using empty lua script') | ||
1174 | 456 | end | ||
1175 | 457 | global_basedir = basedir | ||
1176 | 458 | print_verbose ('current_dir ' .. | ||
1177 | 459 | basedir .. | ||
1178 | 460 | ' - script: ' .. | ||
1179 | 461 | default_proxy_options['proxy-lua-script'] ) | ||
1180 | 462 | -- | ||
1181 | 463 | -- executes the content of the options file | ||
1182 | 464 | -- | ||
1183 | 465 | if has_option_file then | ||
1184 | 466 | print_verbose('# using options file ' .. options_filename) | ||
1185 | 467 | stop_proxy() | ||
1186 | 468 | else | ||
1187 | 469 | -- | ||
1188 | 470 | -- if no option file is found, the default options file is executed | ||
1189 | 471 | -- | ||
1190 | 472 | options_filename = basedir .. "/t/default.options" | ||
1191 | 473 | print_verbose('#using default options file' .. options_filename) | ||
1192 | 474 | if only_item(proxy_list,'default') then | ||
1193 | 475 | print_verbose('reusing existing proxy') | ||
1194 | 476 | return | ||
1195 | 477 | end | ||
1196 | 478 | make_default_options_file(options_filename) | ||
1197 | 479 | end | ||
1198 | 480 | assert(loadfile(options_filename))() | ||
1199 | 481 | end | ||
1200 | 482 | |||
1201 | 483 | function after_test() | ||
1202 | 484 | if only_item(proxy_list, 'default') then | ||
1203 | 485 | return | ||
1204 | 486 | end | ||
1205 | 487 | stop_proxy() | ||
1206 | 488 | end | ||
1207 | 489 | |||
1208 | 490 | function alternative_execute (cmd) | ||
1209 | 491 | print_verbose(cmd) | ||
1210 | 492 | |||
1211 | 493 | local fh = io.popen(cmd) | ||
1212 | 494 | assert(fh, 'error executing '.. cmd) | ||
1213 | 495 | local result = '' | ||
1214 | 496 | local line = fh:read() | ||
1215 | 497 | while line do | ||
1216 | 498 | result = result .. line | ||
1217 | 499 | line = fh:read() | ||
1218 | 500 | end | ||
1219 | 501 | fh:close() | ||
1220 | 502 | return result | ||
1221 | 503 | end | ||
1222 | 504 | |||
1223 | 505 | function conditional_execute (cmd) | ||
1224 | 506 | if USE_POPEN then | ||
1225 | 507 | return alternative_execute(cmd) | ||
1226 | 508 | else | ||
1227 | 509 | return os_execute(cmd) | ||
1228 | 510 | end | ||
1229 | 511 | end | ||
1230 | 512 | |||
1231 | 513 | --- | ||
1232 | 514 | -- run a test | ||
1233 | 515 | -- | ||
1234 | 516 | -- @param testname name of the test | ||
1235 | 517 | -- @return exit-code of mysql-test | ||
1236 | 518 | function run_test(filename, basedir) | ||
1237 | 519 | if not basedir then basedir = srcdir end | ||
1238 | 520 | |||
1239 | 521 | local testname = assert(filename:match("t/(.+)\.test")) | ||
1240 | 522 | if tests_to_skip[testname] then | ||
1241 | 523 | print('skip ' .. testname ..' '.. (tests_to_skip[testname] or 'no reason given') ) | ||
1242 | 524 | return 0, 1 | ||
1243 | 525 | end | ||
1244 | 526 | before_test(basedir, testname) | ||
1245 | 527 | if VERBOSE > 1 then | ||
1246 | 528 | os.execute('echo -n "' .. testname .. ' " ; ' ) | ||
1247 | 529 | end | ||
1336 | 530 | local result = 0 | 456 | local result = 0 |
1354 | 531 | local ret = conditional_execute( | 457 | |
1355 | 532 | env_options_tostring({ | 458 | local proc = process:new() |
1356 | 533 | ['MYSQL_USER'] = MYSQL_USER, | 459 | local ret = proc:popen( |
1357 | 534 | ['MYSQL_PASSWORD'] = MYSQL_PASSWORD, | 460 | self.testenv.MYSQL_TEST_BIN, |
1358 | 535 | ['PROXY_HOST'] = PROXY_HOST, | 461 | { |
1359 | 536 | ['PROXY_PORT'] = PROXY_PORT, | 462 | ['MYSQL_USER'] = self.testenv.MYSQL_USER, |
1360 | 537 | ['PROXY_CHAIN_PORT'] = PROXY_CHAIN_PORT, | 463 | ['MYSQL_PASSWORD'] = self.testenv.MYSQL_PASSWORD, |
1361 | 538 | ['MASTER_PORT'] = PROXY_MASTER_PORT, | 464 | ['PROXY_HOST'] = self.testenv.PROXY_HOST, |
1362 | 539 | ['SLAVE_PORT'] = PROXY_SLAVE_PORT, | 465 | ['PROXY_PORT'] = self.testenv.PROXY_PORT, |
1363 | 540 | }) .. ' ' .. | 466 | ['PROXY_CHAIN_PORT'] = self.testenv.PROXY_CHAIN_PORT, |
1364 | 541 | MYSQL_TEST_BIN .. " " .. | 467 | ['MASTER_PORT'] = self.testenv.PROXY_MASTER_PORT, |
1365 | 542 | options_tostring({ | 468 | ['SLAVE_PORT'] = self.testenv.PROXY_SLAVE_PORT, |
1366 | 543 | user = MYSQL_USER, | 469 | }, |
1367 | 544 | password = MYSQL_PASSWORD, | 470 | { |
1368 | 545 | database = MYSQL_DB, | 471 | user = self.testenv.MYSQL_USER, |
1369 | 546 | host = PROXY_HOST, | 472 | password = self.testenv.MYSQL_PASSWORD, |
1370 | 547 | port = PROXY_PORT, | 473 | database = self.testenv.MYSQL_DB, |
1371 | 474 | host = self.testenv.PROXY_HOST, | ||
1372 | 475 | port = self.testenv.PROXY_PORT, | ||
1373 | 548 | verbose = (VERBOSE > 0) and "TRUE" or "FALSE", -- pass down the verbose setting | 476 | verbose = (VERBOSE > 0) and "TRUE" or "FALSE", -- pass down the verbose setting |
1377 | 549 | ["test-file"] = basedir .. "/t/" .. testname .. ".test", | 477 | ["test-file"] = self.suite_srcdir .. "/t/" .. self.testname .. ".test", |
1378 | 550 | ["result-file"] = basedir .. "/r/" .. testname .. ".result", | 478 | ["result-file"] = self.suite_srcdir .. "/r/" .. self.testname .. ".result", |
1379 | 551 | ["logdir"] = builddir, -- the .result dir might not be writable | 479 | ["logdir"] = self.suite_builddir, -- the .result dir might not be writable |
1380 | 552 | }) | 480 | }) |
1757 | 553 | ) | 481 | |
1758 | 554 | if USE_POPEN then | 482 | if (ret == "ok") then |
1759 | 555 | assert(ret == 'ok' or ret =='not ok', 'unexpected result <' .. ret .. '>') | 483 | print(("ok # %s"):format(self.testname)) |
1760 | 556 | if (ret == 'ok') then | 484 | return 0 |
1761 | 557 | result = 0 | 485 | elseif (ret == "not ok") then |
1762 | 558 | elseif ret == 'not ok'then | 486 | print(("not ok # %s"):format(self.testname)) |
1763 | 559 | result = 1 | 487 | return -1 |
1764 | 560 | end | 488 | else |
1765 | 561 | print(ret .. ' ' .. testname) | 489 | print(("not ok # (%s) %s"):format(ret, self.testname)) |
1766 | 562 | else | 490 | return -1 |
1767 | 563 | result = ret | 491 | end |
1768 | 564 | end | 492 | end |
1769 | 565 | after_test() | 493 | |
1770 | 566 | return result, 0 | 494 | local runner = TestRunner:new() |
1771 | 567 | end | 495 | runner:register_tests({"base"}) |
1772 | 568 | 496 | local exitcode = runner:run_all() | |
1397 | 569 | --- | ||
1398 | 570 | --sql_execute() | ||
1399 | 571 | -- | ||
1400 | 572 | -- Executes a SQL query in a given Proxy | ||
1401 | 573 | -- | ||
1402 | 574 | -- If no Proxy is indicated, the query is passed directly to the backend server | ||
1403 | 575 | -- | ||
1404 | 576 | -- @param query A SQL statement to execute, or a table of SQL statements | ||
1405 | 577 | -- @param proxy_name the name of the proxy that executes the query | ||
1406 | 578 | function sql_execute(queries, proxy_name) | ||
1407 | 579 | local ret = 0 | ||
1408 | 580 | assert(type(queries) == 'string' or type(queries) == 'table', 'invalid type for query' ) | ||
1409 | 581 | if type(queries) == 'string' then | ||
1410 | 582 | queries = {queries} | ||
1411 | 583 | end | ||
1412 | 584 | local query = '' | ||
1413 | 585 | for i, q in pairs(queries) do | ||
1414 | 586 | query = query .. ';' .. q | ||
1415 | 587 | end | ||
1416 | 588 | |||
1417 | 589 | if proxy_name then | ||
1418 | 590 | -- | ||
1419 | 591 | -- a Proxy name is passed. | ||
1420 | 592 | -- The query is executed with the given proxy | ||
1421 | 593 | local opts = proxy_list[proxy_name] | ||
1422 | 594 | assert(opts,'proxy '.. proxy_name .. ' not active') | ||
1423 | 595 | assert(opts['proxy-address'],'address for proxy '.. proxy_name .. ' not found') | ||
1424 | 596 | local p_host, p_port = opts['proxy-address']:match('(%S+):(%S+)') | ||
1425 | 597 | ret = os_execute( MYSQL_CLIENT_BIN .. ' ' .. | ||
1426 | 598 | options_tostring({ | ||
1427 | 599 | user = MYSQL_USER, | ||
1428 | 600 | password = MYSQL_PASSWORD, | ||
1429 | 601 | database = MYSQL_DB, | ||
1430 | 602 | host = p_host, | ||
1431 | 603 | port = p_port, | ||
1432 | 604 | execute = query | ||
1433 | 605 | }) | ||
1434 | 606 | ) | ||
1435 | 607 | assert(ret == 0, 'error using mysql client ') | ||
1436 | 608 | else | ||
1437 | 609 | -- | ||
1438 | 610 | -- No proxy name was passed. | ||
1439 | 611 | -- The query is executed in the backend server | ||
1440 | 612 | -- | ||
1441 | 613 | ret = os_execute( MYSQL_CLIENT_BIN .. ' ' .. | ||
1442 | 614 | options_tostring({ | ||
1443 | 615 | user = MYSQL_USER, | ||
1444 | 616 | password = MYSQL_PASSWORD, | ||
1445 | 617 | database = MYSQL_DB, | ||
1446 | 618 | host = PROXY_HOST, | ||
1447 | 619 | port = MYSQL_PORT, | ||
1448 | 620 | execute = query | ||
1449 | 621 | }) | ||
1450 | 622 | ) | ||
1451 | 623 | end | ||
1452 | 624 | return ret | ||
1453 | 625 | end | ||
1454 | 626 | |||
1455 | 627 | stop_proxy() | ||
1456 | 628 | |||
1457 | 629 | -- the proxy needs the lua-script to exist | ||
1458 | 630 | -- file_empty(PROXY_TMP_LUASCRIPT) | ||
1459 | 631 | |||
1460 | 632 | -- if the pid-file is still pointing to a active process, kill it | ||
1461 | 633 | --[[ | ||
1462 | 634 | if file_exists(PROXY_PIDFILE) then | ||
1463 | 635 | os.execute("kill -TERM `cat ".. PROXY_PIDFILE .." `") | ||
1464 | 636 | os.remove(PROXY_PIDFILE) | ||
1465 | 637 | end | ||
1466 | 638 | --]] | ||
1467 | 639 | |||
1468 | 640 | if COVERAGE_LCOV then | ||
1469 | 641 | -- os_execute(COVERAGE_LCOV .. | ||
1470 | 642 | -- " --zerocounters --directory ".. srcdir .. "/../src/" ) | ||
1471 | 643 | end | ||
1472 | 644 | |||
1473 | 645 | -- setting the include path | ||
1474 | 646 | -- | ||
1475 | 647 | |||
1476 | 648 | -- this is the path containing the global Lua modules | ||
1477 | 649 | local GLOBAL_LUA_PATH = os.getenv('LUA_LDIR') or '/usr/share/lua/5.1/?.lua' | ||
1478 | 650 | |||
1479 | 651 | -- this is the path containing the Proxy libraries | ||
1480 | 652 | local PROXY_LUA_PATH = os.getenv('LUA_PATH') or '/usr/local/share/?.lua' | ||
1481 | 653 | |||
1482 | 654 | -- This is the path with specific libraries for the test suite | ||
1483 | 655 | local PRIVATE_LUA_PATH = arg[1] .. '/t/?.lua' | ||
1484 | 656 | |||
1485 | 657 | -- This is the path with additional libraries that the user needs | ||
1486 | 658 | local LUA_USER_PATH = os.getenv('LUA_USER_PATH') or '../lib/?.lua' | ||
1487 | 659 | |||
1488 | 660 | -- Building the final include path | ||
1489 | 661 | local INCLUDE_PATH = | ||
1490 | 662 | LUA_USER_PATH .. ';' .. | ||
1491 | 663 | PRIVATE_LUA_PATH .. ';' .. | ||
1492 | 664 | GLOBAL_LUA_PATH .. ';' .. | ||
1493 | 665 | PROXY_LUA_PATH | ||
1494 | 666 | |||
1495 | 667 | --- | ||
1496 | 668 | -- start_proxy() | ||
1497 | 669 | -- | ||
1498 | 670 | -- starts an instance of MySQL Proxy | ||
1499 | 671 | -- | ||
1500 | 672 | -- @param proxy_name internal name of the proxy instance, for retrieval | ||
1501 | 673 | -- @param proxy_options the options to start the Proxy | ||
1502 | 674 | function start_proxy(proxy_name, proxy_options) | ||
1503 | 675 | -- start the proxy | ||
1504 | 676 | assert(type(proxy_options) == 'table') | ||
1505 | 677 | if not file_exists(proxy_options['proxy-lua-script']) then | ||
1506 | 678 | proxy_options['proxy-lua-script'] = | ||
1507 | 679 | global_basedir .. | ||
1508 | 680 | '/t/' .. proxy_options['proxy-lua-script'] | ||
1509 | 681 | end | ||
1510 | 682 | print_verbose("starting " .. proxy_name .. " with " .. options_tostring(proxy_options)) | ||
1511 | 683 | |||
1512 | 684 | -- remove the old pid-file if it exists | ||
1513 | 685 | os.remove(proxy_options['pid-file']) | ||
1514 | 686 | -- if we are supposed to listen on a UNIX socket, remove it first, because we don't clean it up on exit! | ||
1515 | 687 | -- TODO: fix the code, instead of hacking around here! Bug#38415 | ||
1516 | 688 | if proxy_options['proxy-address'] == '/tmp/mysql-proxy-test.sock' then | ||
1517 | 689 | os.remove(proxy_options['proxy-address']) | ||
1518 | 690 | end | ||
1519 | 691 | -- os.execute("head " .. proxy_options['proxy-lua-script']) | ||
1520 | 692 | assert(os.execute( 'LUA_PATH="' .. INCLUDE_PATH .. '" ' .. | ||
1521 | 693 | PROXY_TRACE .. " " .. PROXY_BINPATH .. " " .. | ||
1522 | 694 | options_tostring( proxy_options) .. " &" | ||
1523 | 695 | )) | ||
1524 | 696 | |||
1525 | 697 | -- wait until the proxy is up | ||
1526 | 698 | wait_proc_up(proxy_options['pid-file']) | ||
1527 | 699 | |||
1528 | 700 | proxy_list[proxy_name] = proxy_options | ||
1529 | 701 | end | ||
1530 | 702 | |||
1531 | 703 | --- | ||
1532 | 704 | -- simulate_replication() | ||
1533 | 705 | -- | ||
1534 | 706 | -- creates a fake master/slave by having two proxies | ||
1535 | 707 | -- pointing at the same backend | ||
1536 | 708 | -- | ||
1537 | 709 | -- you can alter those backends by changing | ||
1538 | 710 | -- the starting parameters | ||
1539 | 711 | -- | ||
1540 | 712 | -- @param master_options options for master | ||
1541 | 713 | -- @param slave_options options for slave | ||
1542 | 714 | function simulate_replication(master_options, slave_options) | ||
1543 | 715 | if not master_options then | ||
1544 | 716 | master_options = default_master_options | ||
1545 | 717 | end | ||
1546 | 718 | if not master_options['pid-file'] then | ||
1547 | 719 | master_options['pid-file'] = PROXY_MASTER_PIDFILE | ||
1548 | 720 | end | ||
1549 | 721 | if not slave_options then | ||
1550 | 722 | slave_options = default_slave_options | ||
1551 | 723 | end | ||
1552 | 724 | if not slave_options['pid-file'] then | ||
1553 | 725 | slave_options['pid-file'] = PROXY_SLAVE_PIDFILE | ||
1554 | 726 | end | ||
1555 | 727 | start_proxy('master', master_options) | ||
1556 | 728 | start_proxy('slave', slave_options) | ||
1557 | 729 | end | ||
1558 | 730 | |||
1559 | 731 | --- | ||
1560 | 732 | -- chain_proxy() | ||
1561 | 733 | -- | ||
1562 | 734 | -- starts two proxy instances, with the first one is pointing to the | ||
1563 | 735 | -- default backend server, and the second one (with default ports) | ||
1564 | 736 | -- is pointing at the first proxy | ||
1565 | 737 | -- | ||
1566 | 738 | -- client -> proxy -> backend_proxy -> [ mysql-backend ] | ||
1567 | 739 | -- | ||
1568 | 740 | -- usually we use it to mock a server with a lua script (...-mock.lua) and | ||
1569 | 741 | -- the script under test in the proxy (...-test.lua) | ||
1570 | 742 | -- | ||
1571 | 743 | -- in case you want to start several backend_proxies, just provide a array | ||
1572 | 744 | -- as first param | ||
1573 | 745 | -- | ||
1574 | 746 | -- @param backend_lua_script | ||
1575 | 747 | -- @param second_lua_script | ||
1576 | 748 | -- @param use_replication uses a master proxy as backend | ||
1577 | 749 | function chain_proxy (backend_lua_scripts, second_lua_script, use_replication) | ||
1578 | 750 | local backends = { } | ||
1579 | 751 | |||
1580 | 752 | if type(backend_lua_scripts) == "table" then | ||
1581 | 753 | backends = backend_lua_scripts | ||
1582 | 754 | else | ||
1583 | 755 | backends = { backend_lua_scripts } | ||
1584 | 756 | end | ||
1585 | 757 | |||
1586 | 758 | local backend_addresses = { } | ||
1587 | 759 | |||
1588 | 760 | for i, backend_lua_script in ipairs(backends) do | ||
1589 | 761 | backend_addresses[i] = PROXY_HOST .. ":" .. (PROXY_CHAIN_PORT + i - 1) | ||
1590 | 762 | |||
1591 | 763 | backend_proxy_options = { | ||
1592 | 764 | ["proxy-backend-addresses"] = MYSQL_HOST .. ":" .. MYSQL_PORT, | ||
1593 | 765 | ["proxy-address"] = backend_addresses[i], | ||
1594 | 766 | ["admin-address"] = PROXY_HOST .. ":" .. (ADMIN_CHAIN_PORT + i - 1), | ||
1595 | 767 | ["admin-username"] = ADMIN_USER, | ||
1596 | 768 | ["admin-password"] = ADMIN_PASSWORD, | ||
1597 | 769 | ["admin-lua-script"] = ADMIN_DEFAULT_SCRIPT_FILENAME, | ||
1598 | 770 | ["pid-file"] = PROXY_CHAIN_PIDFILE .. i, | ||
1599 | 771 | ["proxy-lua-script"] = backend_lua_script or DEFAULT_SCRIPT_FILENAME, | ||
1600 | 772 | ["plugin-dir"] = PROXY_LIBPATH, | ||
1601 | 773 | ["basedir"] = PROXY_TEST_BASEDIR, | ||
1602 | 774 | ["log-level"] = (VERBOSE == 4) and "debug" or "critical", | ||
1603 | 775 | } | ||
1604 | 776 | -- | ||
1605 | 777 | -- if replication was not started, then it is started here | ||
1606 | 778 | -- | ||
1607 | 779 | if use_replication and (use_replication == true) then | ||
1608 | 780 | if (proxy_list['master'] == nil) then | ||
1609 | 781 | simulate_replication() | ||
1610 | 782 | end | ||
1611 | 783 | backend_proxy_options["proxy-backend-addresses"] = PROXY_HOST .. ':' .. PROXY_MASTER_PORT | ||
1612 | 784 | end | ||
1613 | 785 | start_proxy('backend_proxy' .. i, backend_proxy_options) | ||
1614 | 786 | end | ||
1615 | 787 | |||
1616 | 788 | second_proxy_options = { | ||
1617 | 789 | ["proxy-backend-addresses"] = backend_addresses , | ||
1618 | 790 | ["proxy-address"] = PROXY_HOST .. ":" .. PROXY_PORT, | ||
1619 | 791 | ["admin-address"] = PROXY_HOST .. ":" .. ADMIN_PORT, | ||
1620 | 792 | ["admin-username"] = ADMIN_USER, | ||
1621 | 793 | ["admin-password"] = ADMIN_PASSWORD, | ||
1622 | 794 | ["admin-lua-script"] = ADMIN_DEFAULT_SCRIPT_FILENAME, | ||
1623 | 795 | ["pid-file"] = PROXY_PIDFILE, | ||
1624 | 796 | ["proxy-lua-script"] = second_lua_script or DEFAULT_SCRIPT_FILENAME, | ||
1625 | 797 | ["plugin-dir"] = PROXY_LIBPATH, | ||
1626 | 798 | ["basedir"] = PROXY_TEST_BASEDIR, | ||
1627 | 799 | ["log-level"] = (VERBOSE == 3) and "debug" or "critical", | ||
1628 | 800 | } | ||
1629 | 801 | start_proxy('second_proxy',second_proxy_options) | ||
1630 | 802 | end | ||
1631 | 803 | |||
1632 | 804 | local num_tests = 0 | ||
1633 | 805 | local num_passes = 0 | ||
1634 | 806 | local num_skipped = 0 | ||
1635 | 807 | local num_fails = 0 | ||
1636 | 808 | local all_ok = true | ||
1637 | 809 | local failed_test = {} | ||
1638 | 810 | |||
1639 | 811 | file_empty(DEFAULT_SCRIPT_FILENAME) | ||
1640 | 812 | |||
1641 | 813 | -- | ||
1642 | 814 | -- if we have a argument, exectute the named test | ||
1643 | 815 | -- otherwise execute all tests we can find | ||
1644 | 816 | if #arg then | ||
1645 | 817 | for i, a in ipairs(arg) do | ||
1646 | 818 | local stat = assert(lfs.attributes(a)) | ||
1647 | 819 | |||
1648 | 820 | if file_exists(a .. '/' .. tests_to_skip_filename) then | ||
1649 | 821 | assert(loadfile(a .. '/' .. tests_to_skip_filename))() | ||
1650 | 822 | end | ||
1651 | 823 | |||
1652 | 824 | -- if it is a directory, execute all of them | ||
1653 | 825 | if stat.mode == "directory" then | ||
1654 | 826 | for file in lfs.dir(a .. "/t/") do | ||
1655 | 827 | if not TESTS_REGEX or file:match(TESTS_REGEX) then | ||
1656 | 828 | local testname = file:match("(.+\.test)$") | ||
1657 | 829 | |||
1658 | 830 | if testname then | ||
1659 | 831 | print_verbose("# >> " .. testname .. " started") | ||
1660 | 832 | |||
1661 | 833 | num_tests = num_tests + 1 | ||
1662 | 834 | local r, skipped = run_test("t/" .. testname, a) | ||
1663 | 835 | if (r == 0) then | ||
1664 | 836 | num_passes = num_passes + 1 - skipped | ||
1665 | 837 | else | ||
1666 | 838 | num_fails = num_fails + 1 | ||
1667 | 839 | all_ok = false | ||
1668 | 840 | table.insert(failed_test, testname) | ||
1669 | 841 | end | ||
1670 | 842 | num_skipped = num_skipped + skipped | ||
1671 | 843 | |||
1672 | 844 | print_verbose("# << (exitcode = " .. r .. ")" ) | ||
1673 | 845 | |||
1674 | 846 | if r ~= 0 and exitcode == 0 then | ||
1675 | 847 | exitcode = r | ||
1676 | 848 | end | ||
1677 | 849 | end | ||
1678 | 850 | if all_ok == false and (not FORCE_ON_ERROR) then | ||
1679 | 851 | break | ||
1680 | 852 | end | ||
1681 | 853 | end | ||
1682 | 854 | end | ||
1683 | 855 | else | ||
1684 | 856 | -- otherwise just this one test | ||
1685 | 857 | -- | ||
1686 | 858 | -- FIXME: base/ is hard-coded for now | ||
1687 | 859 | exitcode, skipped = run_test(a, "base/") | ||
1688 | 860 | num_skipped = num_skipped + skipped | ||
1689 | 861 | end | ||
1690 | 862 | end | ||
1691 | 863 | else | ||
1692 | 864 | for file in lfs.dir(srcdir .. "/t/") do | ||
1693 | 865 | local testname = file:match("(.+\.test)$") | ||
1694 | 866 | |||
1695 | 867 | if testname then | ||
1696 | 868 | print_verbose("# >> " .. testname .. " started") | ||
1697 | 869 | |||
1698 | 870 | num_tests = num_tests + 1 | ||
1699 | 871 | local r, skipped = run_test("t/" .. testname) | ||
1700 | 872 | num_skipped = num_skipped + skipped | ||
1701 | 873 | |||
1702 | 874 | print_verbose("# << (exitcode = " .. r .. ")" ) | ||
1703 | 875 | if (r == 0) then | ||
1704 | 876 | num_passes = num_passes + 1 - skipped | ||
1705 | 877 | else | ||
1706 | 878 | all_ok = false | ||
1707 | 879 | num_fails = num_fails + 1 | ||
1708 | 880 | table.insert(failed_test, testname) | ||
1709 | 881 | end | ||
1710 | 882 | if r ~= 0 and exitcode == 0 then | ||
1711 | 883 | exitcode = r | ||
1712 | 884 | end | ||
1713 | 885 | if all_ok == false and (not FORCE_ON_ERROR) then | ||
1714 | 886 | break | ||
1715 | 887 | end | ||
1716 | 888 | end | ||
1717 | 889 | end | ||
1718 | 890 | end | ||
1719 | 891 | |||
1720 | 892 | if all_ok ==false then | ||
1721 | 893 | print ("*** ERRORS OCCURRED - The following tests failed") | ||
1722 | 894 | for i,v in pairs(failed_test) do | ||
1723 | 895 | print(v ) | ||
1724 | 896 | end | ||
1725 | 897 | end | ||
1726 | 898 | |||
1727 | 899 | -- | ||
1728 | 900 | -- prints test suite statistics | ||
1729 | 901 | print_verbose (string.format('tests: %d - skipped: %d (%4.1f%%) - passed: %d (%4.1f%%) - failed: %d (%4.1f%%)', | ||
1730 | 902 | num_tests, | ||
1731 | 903 | num_skipped, | ||
1732 | 904 | num_skipped / num_tests * 100, | ||
1733 | 905 | num_passes, | ||
1734 | 906 | num_passes / (num_tests - num_skipped) * 100, | ||
1735 | 907 | num_fails, | ||
1736 | 908 | num_fails / (num_tests - num_skipped) * 100)) | ||
1737 | 909 | |||
1738 | 910 | -- | ||
1739 | 911 | -- stops any remaining active proxy | ||
1740 | 912 | -- | ||
1741 | 913 | stop_proxy() | ||
1742 | 914 | |||
1743 | 915 | if COVERAGE_LCOV then | ||
1744 | 916 | os_execute(COVERAGE_LCOV .. | ||
1745 | 917 | " --quiet " .. | ||
1746 | 918 | " --capture --directory ".. srcdir .. "/../src/" .. | ||
1747 | 919 | " > " .. srcdir .. "/../tests.coverage.info" ) | ||
1748 | 920 | |||
1749 | 921 | os_execute("genhtml " .. | ||
1750 | 922 | "--show-details " .. | ||
1751 | 923 | "--output-directory " .. srcdir .. "/../coverage/ " .. | ||
1752 | 924 | "--keep-descriptions " .. | ||
1753 | 925 | "--frames " .. | ||
1754 | 926 | srcdir .. "/../tests.coverage.info") | ||
1755 | 927 | end | ||
1756 | 928 | |||
1773 | 929 | 497 | ||
1774 | 930 | if exitcode == 0 then | 498 | if exitcode == 0 then |
1775 | 931 | os.exit(0) | 499 | os.exit(0) |
1776 | 932 | else | 500 | else |
1778 | 933 | print_verbose("mysql-test exit-code: " .. exitcode) | 501 | shellutils.print_verbose("mysql-test exit-code: " .. exitcode) |
1779 | 934 | os.exit(-1) | 502 | os.exit(-1) |
1780 | 935 | end | 503 | end |
1781 | 936 | 504 | ||
1782 | 937 | 505 | ||
1783 | === added directory 'tests/suite/testenv' | |||
1784 | === added file 'tests/suite/testenv/Makefile.am' | |||
1785 | --- tests/suite/testenv/Makefile.am 1970-01-01 00:00:00 +0000 | |||
1786 | +++ tests/suite/testenv/Makefile.am 2010-09-08 12:58:43 +0000 | |||
1787 | @@ -0,0 +1,7 @@ | |||
1788 | 1 | EXTRA_DIST=\ | ||
1789 | 2 | fileutils.lua \ | ||
1790 | 3 | shellutils.lua \ | ||
1791 | 4 | testutils.lua \ | ||
1792 | 5 | process.lua \ | ||
1793 | 6 | processmanager.lua | ||
1794 | 7 | |||
1795 | 0 | 8 | ||
1796 | === added file 'tests/suite/testenv/fileutils.lua' | |||
1797 | --- tests/suite/testenv/fileutils.lua 1970-01-01 00:00:00 +0000 | |||
1798 | +++ tests/suite/testenv/fileutils.lua 2010-09-08 12:58:43 +0000 | |||
1799 | @@ -0,0 +1,84 @@ | |||
1800 | 1 | --[[ $%BEGINLICENSE%$ | ||
1801 | 2 | Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. | ||
1802 | 3 | |||
1803 | 4 | This program is free software; you can redistribute it and/or | ||
1804 | 5 | modify it under the terms of the GNU General Public License as | ||
1805 | 6 | published by the Free Software Foundation; version 2 of the | ||
1806 | 7 | License. | ||
1807 | 8 | |||
1808 | 9 | This program is distributed in the hope that it will be useful, | ||
1809 | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1810 | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1811 | 12 | GNU General Public License for more details. | ||
1812 | 13 | |||
1813 | 14 | You should have received a copy of the GNU General Public License | ||
1814 | 15 | along with this program; if not, write to the Free Software | ||
1815 | 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
1816 | 17 | 02110-1301 USA | ||
1817 | 18 | |||
1818 | 19 | $%ENDLICENSE%$ --]] | ||
1819 | 20 | |||
1820 | 21 | require("lfs") | ||
1821 | 22 | |||
1822 | 23 | module("testenv.fileutils", package.seeall) | ||
1823 | 24 | |||
1824 | 25 | --- | ||
1825 | 26 | -- check if the file exists and is readable | ||
1826 | 27 | function file_exists(f) | ||
1827 | 28 | local r = lfs.attributes(f) | ||
1828 | 29 | return (r ~= nil) | ||
1829 | 30 | end | ||
1830 | 31 | |||
1831 | 32 | --- | ||
1832 | 33 | -- check if a path is absolute | ||
1833 | 34 | -- | ||
1834 | 35 | -- FIXME: right now it is Unix only | ||
1835 | 36 | function path_is_absolute(f) | ||
1836 | 37 | return f:byte() == "/" | ||
1837 | 38 | end | ||
1838 | 39 | |||
1839 | 40 | --- | ||
1840 | 41 | -- get the directory-name of a path | ||
1841 | 42 | -- | ||
1842 | 43 | -- @param filename path to create the directory name from | ||
1843 | 44 | function dirname(filename) | ||
1844 | 45 | local dirname = filename | ||
1845 | 46 | |||
1846 | 47 | attr = assert(lfs.attributes(dirname)) | ||
1847 | 48 | |||
1848 | 49 | if attr.mode == "directory" then | ||
1849 | 50 | return dirname | ||
1850 | 51 | end | ||
1851 | 52 | |||
1852 | 53 | dirname = filename:gsub("/[^/]+$", "") | ||
1853 | 54 | |||
1854 | 55 | attr = assert(lfs.attributes(dirname)) | ||
1855 | 56 | |||
1856 | 57 | assert(attr.mode == "directory", "dirname("..filename..") failed: is ".. attr.mode) | ||
1857 | 58 | |||
1858 | 59 | return dirname | ||
1859 | 60 | end | ||
1860 | 61 | |||
1861 | 62 | --- | ||
1862 | 63 | -- get the file-name of a path | ||
1863 | 64 | -- | ||
1864 | 65 | -- @param filename path to create the directory name from | ||
1865 | 66 | function basename(filename) | ||
1866 | 67 | name = filename:gsub(".*/", "") | ||
1867 | 68 | |||
1868 | 69 | return name | ||
1869 | 70 | end | ||
1870 | 71 | |||
1871 | 72 | --- | ||
1872 | 73 | -- create a empty file | ||
1873 | 74 | -- | ||
1874 | 75 | -- if the file exists, it will be truncated to 0 | ||
1875 | 76 | -- | ||
1876 | 77 | -- @param dst filename to create and truncate | ||
1877 | 78 | function create_empty_file(dst) | ||
1878 | 79 | -- print_verbose("emptying " .. dst) | ||
1879 | 80 | local dst_fd = assert(io.open(dst, "wb+")) | ||
1880 | 81 | dst_fd:close(); | ||
1881 | 82 | end | ||
1882 | 83 | |||
1883 | 84 | |||
1884 | 0 | 85 | ||
1885 | === added file 'tests/suite/testenv/process.lua' | |||
1886 | --- tests/suite/testenv/process.lua 1970-01-01 00:00:00 +0000 | |||
1887 | +++ tests/suite/testenv/process.lua 2010-09-08 12:58:43 +0000 | |||
1888 | @@ -0,0 +1,179 @@ | |||
1889 | 1 | --[[ $%BEGINLICENSE%$ | ||
1890 | 2 | Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. | ||
1891 | 3 | |||
1892 | 4 | This program is free software; you can redistribute it and/or | ||
1893 | 5 | modify it under the terms of the GNU General Public License as | ||
1894 | 6 | published by the Free Software Foundation; version 2 of the | ||
1895 | 7 | License. | ||
1896 | 8 | |||
1897 | 9 | This program is distributed in the hope that it will be useful, | ||
1898 | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
1899 | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
1900 | 12 | GNU General Public License for more details. | ||
1901 | 13 | |||
1902 | 14 | You should have received a copy of the GNU General Public License | ||
1903 | 15 | along with this program; if not, write to the Free Software | ||
1904 | 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
1905 | 17 | 02110-1301 USA | ||
1906 | 18 | |||
1907 | 19 | $%ENDLICENSE%$ --]] | ||
1908 | 20 | |||
1909 | 21 | local _G = _G | ||
1910 | 22 | |||
1911 | 23 | local shellutils = require("testenv.shellutils") | ||
1912 | 24 | local glib2 = require("glib2") | ||
1913 | 25 | |||
1914 | 26 | module("testenv.process") | ||
1915 | 27 | |||
1916 | 28 | --- | ||
1917 | 29 | -- life cycle management for processes | ||
1918 | 30 | -- | ||
1919 | 31 | -- * PID files | ||
1920 | 32 | -- * wait until they are started | ||
1921 | 33 | -- * shutting down | ||
1922 | 34 | -- | ||
1923 | 35 | function new(self, o) | ||
1924 | 36 | -- create a new process object | ||
1925 | 37 | -- | ||
1926 | 38 | o = o or {} | ||
1927 | 39 | _G.setmetatable(o, self) | ||
1928 | 40 | self.__index = self | ||
1929 | 41 | return o | ||
1930 | 42 | end | ||
1931 | 43 | |||
1932 | 44 | function get_pid(self) | ||
1933 | 45 | return self.pid | ||
1934 | 46 | end | ||
1935 | 47 | |||
1936 | 48 | function set_pid(self, pid) | ||
1937 | 49 | self.pid = pid | ||
1938 | 50 | end | ||
1939 | 51 | |||
1940 | 52 | --- | ||
1941 | 53 | -- read a PID from a pidfile | ||
1942 | 54 | function set_pid_from_pidfile(self, pid_file_name) | ||
1943 | 55 | local fh, errmsg = _G.io.open(pid_file_name, 'r') | ||
1944 | 56 | if not fh then | ||
1945 | 57 | return false, errmsg | ||
1946 | 58 | end | ||
1947 | 59 | local pid = fh:read("*n") | ||
1948 | 60 | fh:close() | ||
1949 | 61 | |||
1950 | 62 | if _G.type(pid) ~= "number" then | ||
1951 | 63 | return false | ||
1952 | 64 | end | ||
1953 | 65 | if not pid or pid == 0 then | ||
1954 | 66 | return false | ||
1955 | 67 | end | ||
1956 | 68 | |||
1957 | 69 | self:set_pid(pid) | ||
1958 | 70 | |||
1959 | 71 | return true | ||
1960 | 72 | end | ||
1961 | 73 | |||
1962 | 74 | function is_running(self) | ||
1963 | 75 | _G.assert(self.pid) | ||
1964 | 76 | |||
1965 | 77 | local ret = _G.os.execute("kill -0 ".. self.pid .." 2> /dev/null") | ||
1966 | 78 | |||
1967 | 79 | return (ret == 0) | ||
1968 | 80 | end | ||
1969 | 81 | |||
1970 | 82 | --- | ||
1971 | 83 | -- wait until the process is up and running | ||
1972 | 84 | -- | ||
1973 | 85 | function wait_running(self, pid_file_name) | ||
1974 | 86 | -- try to get a PID | ||
1975 | 87 | local rounds = 0 | ||
1976 | 88 | local wait_interval_ms = 100 | ||
1977 | 89 | |||
1978 | 90 | while not self.pid and rounds < 10 do | ||
1979 | 91 | self:set_pid_from_pidfile(pid_file_name) | ||
1980 | 92 | if self.pid then | ||
1981 | 93 | break | ||
1982 | 94 | end | ||
1983 | 95 | |||
1984 | 96 | glib2.usleep(wait_interval_ms * 1000) -- wait until process is gone | ||
1985 | 97 | rounds = rounds + 1 | ||
1986 | 98 | shellutils.print_verbose(("process:wait_running(pid = %s) waited %dms"):format(pid_file_name, wait_interval_ms * rounds)) | ||
1987 | 99 | end | ||
1988 | 100 | |||
1989 | 101 | -- check if the process is actually alive | ||
1990 | 102 | if not self.pid or not self:is_running() then | ||
1991 | 103 | return false | ||
1992 | 104 | end | ||
1993 | 105 | |||
1994 | 106 | return true | ||
1995 | 107 | end | ||
1996 | 108 | |||
1997 | 109 | function wait_down(self) | ||
1998 | 110 | _G.assert(self.pid) | ||
1999 | 111 | local rounds = 0 | ||
2000 | 112 | local wait_interval_ms = 200 | ||
2001 | 113 | |||
2002 | 114 | -- wait until the proc in the pid file is dead | ||
2003 | 115 | -- the shutdown takes at about 500ms | ||
2004 | 116 | while self:is_running() do | ||
2005 | 117 | glib2.usleep(wait_interval_ms * 1000) -- wait until process is gone | ||
2006 | 118 | rounds = rounds + 1 | ||
2007 | 119 | shellutils.print_verbose(("process:wait_down(pid = %d) waited %dms"):format(self.pid, wait_interval_ms * rounds)) | ||
2008 | 120 | end | ||
2009 | 121 | |||
2010 | 122 | return true | ||
2011 | 123 | end | ||
2012 | 124 | |||
2013 | 125 | function shutdown(self) | ||
2014 | 126 | -- shut down the proxy | ||
2015 | 127 | -- | ||
2016 | 128 | -- win32 has tasklist and taskkill on the shell | ||
2017 | 129 | if self.pid then | ||
2018 | 130 | return _G.os.execute("kill -TERM ".. self.pid) | ||
2019 | 131 | end | ||
2020 | 132 | end | ||
2021 | 133 | |||
2022 | 134 | --- | ||
2023 | 135 | -- execute a process | ||
2024 | 136 | function execute(self, cmd, env, opts) | ||
2025 | 137 | local env_str = "" | ||
2026 | 138 | local opts_str = "" | ||
2027 | 139 | |||
2028 | 140 | if env then | ||
2029 | 141 | env_str = shellutils.env_tostring(env) | ||
2030 | 142 | end | ||
2031 | 143 | |||
2032 | 144 | if opts then | ||
2033 | 145 | opts_str = shellutils.options_tostring(opts) | ||
2034 | 146 | end | ||
2035 | 147 | |||
2036 | 148 | local cmdline = env_str .. " " .. cmd .. " " .. opts_str | ||
2037 | 149 | shellutils.print_verbose("$ " .. cmdline) | ||
2038 | 150 | return _G.os.execute(cmdline) | ||
2039 | 151 | end | ||
2040 | 152 | |||
2041 | 153 | function popen(self, cmd, env, opts) | ||
2042 | 154 | local env_str = "" | ||
2043 | 155 | local opts_str = "" | ||
2044 | 156 | |||
2045 | 157 | if env then | ||
2046 | 158 | env_str = shellutils.env_tostring(env) | ||
2047 | 159 | end | ||
2048 | 160 | |||
2049 | 161 | if opts then | ||
2050 | 162 | opts_str = shellutils.options_tostring(opts) | ||
2051 | 163 | end | ||
2052 | 164 | |||
2053 | 165 | local cmdline = env_str .. " " .. cmd .. " " .. opts_str | ||
2054 | 166 | shellutils.print_verbose("$ " .. cmdline) | ||
2055 | 167 | |||
2056 | 168 | local fh = _G.io.popen(cmdline) | ||
2057 | 169 | _G.assert(fh, 'error executing '.. cmdline) | ||
2058 | 170 | local result = '' | ||
2059 | 171 | local line = fh:read() | ||
2060 | 172 | while line do | ||
2061 | 173 | result = result .. line | ||
2062 | 174 | line = fh:read() | ||
2063 | 175 | end | ||
2064 | 176 | fh:close() | ||
2065 | 177 | return result | ||
2066 | 178 | end | ||
2067 | 179 | |||
2068 | 0 | 180 | ||
2069 | === added file 'tests/suite/testenv/processmanager.lua' | |||
2070 | --- tests/suite/testenv/processmanager.lua 1970-01-01 00:00:00 +0000 | |||
2071 | +++ tests/suite/testenv/processmanager.lua 2010-09-08 12:58:43 +0000 | |||
2072 | @@ -0,0 +1,72 @@ | |||
2073 | 1 | --[[ $%BEGINLICENSE%$ | ||
2074 | 2 | Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. | ||
2075 | 3 | |||
2076 | 4 | This program is free software; you can redistribute it and/or | ||
2077 | 5 | modify it under the terms of the GNU General Public License as | ||
2078 | 6 | published by the Free Software Foundation; version 2 of the | ||
2079 | 7 | License. | ||
2080 | 8 | |||
2081 | 9 | This program is distributed in the hope that it will be useful, | ||
2082 | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2083 | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2084 | 12 | GNU General Public License for more details. | ||
2085 | 13 | |||
2086 | 14 | You should have received a copy of the GNU General Public License | ||
2087 | 15 | along with this program; if not, write to the Free Software | ||
2088 | 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
2089 | 17 | 02110-1301 USA | ||
2090 | 18 | |||
2091 | 19 | $%ENDLICENSE%$ --]] | ||
2092 | 20 | |||
2093 | 21 | --- | ||
2094 | 22 | -- manage a set of processes | ||
2095 | 23 | -- | ||
2096 | 24 | -- basicly, all we do is "add a process to the manager" and "shut them all down" | ||
2097 | 25 | -- | ||
2098 | 26 | |||
2099 | 27 | local _G = _G | ||
2100 | 28 | |||
2101 | 29 | module("testenv.processmanager") | ||
2102 | 30 | |||
2103 | 31 | --- | ||
2104 | 32 | -- init a new manager | ||
2105 | 33 | -- | ||
2106 | 34 | function new(self, o) | ||
2107 | 35 | -- create a new processes object | ||
2108 | 36 | -- | ||
2109 | 37 | o = o or {} | ||
2110 | 38 | _G.setmetatable(o, self) | ||
2111 | 39 | self.__index = self | ||
2112 | 40 | |||
2113 | 41 | self.processes = { } | ||
2114 | 42 | |||
2115 | 43 | return o | ||
2116 | 44 | end | ||
2117 | 45 | |||
2118 | 46 | --- | ||
2119 | 47 | -- add a process | ||
2120 | 48 | function add(self, proc) | ||
2121 | 49 | _G.table.insert(self.processes, proc) | ||
2122 | 50 | end | ||
2123 | 51 | |||
2124 | 52 | --- | ||
2125 | 53 | -- stop all monitored processes | ||
2126 | 54 | -- | ||
2127 | 55 | function shutdown_all(self) | ||
2128 | 56 | -- shuts down every proxy in the proxy list | ||
2129 | 57 | -- | ||
2130 | 58 | for proc_name, proc in _G.pairs(self.processes) do | ||
2131 | 59 | if proc.pid then | ||
2132 | 60 | proc:shutdown() | ||
2133 | 61 | end | ||
2134 | 62 | end | ||
2135 | 63 | |||
2136 | 64 | for proc_name, proc in _G.pairs(self.processes) do | ||
2137 | 65 | if proc.pid then | ||
2138 | 66 | proc:wait_down() | ||
2139 | 67 | end | ||
2140 | 68 | self.processes[proc_name] = nil | ||
2141 | 69 | end | ||
2142 | 70 | end | ||
2143 | 71 | |||
2144 | 72 | |||
2145 | 0 | 73 | ||
2146 | === added file 'tests/suite/testenv/shellutils.lua' | |||
2147 | --- tests/suite/testenv/shellutils.lua 1970-01-01 00:00:00 +0000 | |||
2148 | +++ tests/suite/testenv/shellutils.lua 2010-09-08 12:58:43 +0000 | |||
2149 | @@ -0,0 +1,92 @@ | |||
2150 | 1 | --[[ $%BEGINLICENSE%$ | ||
2151 | 2 | Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. | ||
2152 | 3 | |||
2153 | 4 | This program is free software; you can redistribute it and/or | ||
2154 | 5 | modify it under the terms of the GNU General Public License as | ||
2155 | 6 | published by the Free Software Foundation; version 2 of the | ||
2156 | 7 | License. | ||
2157 | 8 | |||
2158 | 9 | This program is distributed in the hope that it will be useful, | ||
2159 | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2160 | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2161 | 12 | GNU General Public License for more details. | ||
2162 | 13 | |||
2163 | 14 | You should have received a copy of the GNU General Public License | ||
2164 | 15 | along with this program; if not, write to the Free Software | ||
2165 | 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
2166 | 17 | 02110-1301 USA | ||
2167 | 18 | |||
2168 | 19 | $%ENDLICENSE%$ --]] | ||
2169 | 20 | |||
2170 | 21 | module("testenv.shellutils", package.seeall) | ||
2171 | 22 | |||
2172 | 23 | VERBOSE = tonumber(os.getenv("VERBOSE")) or 0 | ||
2173 | 24 | |||
2174 | 25 | --- | ||
2175 | 26 | -- turn a option-table into a string | ||
2176 | 27 | -- | ||
2177 | 28 | -- the values are encoded and quoted for the shell | ||
2178 | 29 | -- | ||
2179 | 30 | -- @param tbl a option table | ||
2180 | 31 | -- @param sep the seperator, defaults to a space | ||
2181 | 32 | function options_tostring(tbl, sep) | ||
2182 | 33 | -- default value for sep | ||
2183 | 34 | sep = sep or " " | ||
2184 | 35 | |||
2185 | 36 | assert(type(tbl) == "table") | ||
2186 | 37 | assert(type(sep) == "string") | ||
2187 | 38 | |||
2188 | 39 | local s_tbl = { } | ||
2189 | 40 | for k, v in pairs(tbl) do | ||
2190 | 41 | local values | ||
2191 | 42 | -- if the value is a table, repeat the option | ||
2192 | 43 | if type(v) == "table" then | ||
2193 | 44 | values = v | ||
2194 | 45 | else | ||
2195 | 46 | values = { v } | ||
2196 | 47 | end | ||
2197 | 48 | |||
2198 | 49 | for tk, tv in pairs(values) do | ||
2199 | 50 | if tv == true then | ||
2200 | 51 | table.insert(s_tbl, "--" .. k) | ||
2201 | 52 | else | ||
2202 | 53 | local enc_value = tv:gsub("\\", "\\\\"):gsub("\"", "\\\"") | ||
2203 | 54 | table.insert(s_tbl, "--" .. k .. "=\"" .. enc_value .. "\"") | ||
2204 | 55 | end | ||
2205 | 56 | end | ||
2206 | 57 | end | ||
2207 | 58 | local s = table.concat(s_tbl, " ") | ||
2208 | 59 | -- print_verbose(" option: " .. s) | ||
2209 | 60 | |||
2210 | 61 | return s | ||
2211 | 62 | end | ||
2212 | 63 | |||
2213 | 64 | --- turns an option table into a string of environment variables | ||
2214 | 65 | -- | ||
2215 | 66 | function env_tostring(tbl) | ||
2216 | 67 | assert(type(tbl) == "table") | ||
2217 | 68 | |||
2218 | 69 | local s = "" | ||
2219 | 70 | for k, v in pairs(tbl) do | ||
2220 | 71 | local enc_value = v:gsub("\\", "\\\\"):gsub("\"", "\\\"") | ||
2221 | 72 | s = s .. k .. "=\"" .. enc_value .. "\" " | ||
2222 | 73 | end | ||
2223 | 74 | |||
2224 | 75 | return s | ||
2225 | 76 | end | ||
2226 | 77 | |||
2227 | 78 | --- | ||
2228 | 79 | -- print_verbose() | ||
2229 | 80 | -- | ||
2230 | 81 | -- prints a message if either the DEBUG or VERBOSE variables | ||
2231 | 82 | -- are set. | ||
2232 | 83 | -- | ||
2233 | 84 | -- @param msg the message being printed | ||
2234 | 85 | -- @param min_level the minimum verbosity level for printing the message (default 1) | ||
2235 | 86 | function print_verbose(msg, min_level) | ||
2236 | 87 | min_level = min_level or 1 | ||
2237 | 88 | if (VERBOSE >= min_level) then | ||
2238 | 89 | print (msg) | ||
2239 | 90 | end | ||
2240 | 91 | end | ||
2241 | 92 | |||
2242 | 0 | 93 | ||
2243 | === added file 'tests/suite/testenv/testutils.lua' | |||
2244 | --- tests/suite/testenv/testutils.lua 1970-01-01 00:00:00 +0000 | |||
2245 | +++ tests/suite/testenv/testutils.lua 2010-09-08 12:58:43 +0000 | |||
2246 | @@ -0,0 +1,271 @@ | |||
2247 | 1 | --[[ $%BEGINLICENSE%$ | ||
2248 | 2 | Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. | ||
2249 | 3 | |||
2250 | 4 | This program is free software; you can redistribute it and/or | ||
2251 | 5 | modify it under the terms of the GNU General Public License as | ||
2252 | 6 | published by the Free Software Foundation; version 2 of the | ||
2253 | 7 | License. | ||
2254 | 8 | |||
2255 | 9 | This program is distributed in the hope that it will be useful, | ||
2256 | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
2257 | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
2258 | 12 | GNU General Public License for more details. | ||
2259 | 13 | |||
2260 | 14 | You should have received a copy of the GNU General Public License | ||
2261 | 15 | along with this program; if not, write to the Free Software | ||
2262 | 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
2263 | 17 | 02110-1301 USA | ||
2264 | 18 | |||
2265 | 19 | $%ENDLICENSE%$ --]] | ||
2266 | 20 | |||
2267 | 21 | module("testenv.testutils", package.seeall) | ||
2268 | 22 | |||
2269 | 23 | -- | ||
2270 | 24 | -- Global variables that can be referenced from .options files | ||
2271 | 25 | -- | ||
2272 | 26 | function get_port_base(port_base_start, port_base_end) | ||
2273 | 27 | local port_base_start = port_base_start or 32768 | ||
2274 | 28 | local port_base_end = port_base_end or 65535 | ||
2275 | 29 | local port_interval = 64 -- let's take the base port in steps of ... | ||
2276 | 30 | local range = port_base_end - port_base_start - port_interval | ||
2277 | 31 | math.randomseed(posix.getpid()) | ||
2278 | 32 | local rand = math.floor(math.random() * (math.ceil(range / port_interval))) | ||
2279 | 33 | local port_base = port_base_start + (rand * port_interval) | ||
2280 | 34 | |||
2281 | 35 | print(("... using tcp-port = %d as start port"):format(port_base)) | ||
2282 | 36 | |||
2283 | 37 | return port_base | ||
2284 | 38 | end | ||
2285 | 39 | |||
2286 | 40 | |||
2287 | 41 | -- setting the include path | ||
2288 | 42 | -- | ||
2289 | 43 | |||
2290 | 44 | -- this is the path containing the global Lua modules | ||
2291 | 45 | local GLOBAL_LUA_PATH = os.getenv('LUA_LDIR') or '/usr/share/lua/5.1/?.lua' | ||
2292 | 46 | |||
2293 | 47 | -- this is the path containing the Proxy libraries | ||
2294 | 48 | local PROXY_LUA_PATH = os.getenv('LUA_PATH') or '/usr/local/share/?.lua' | ||
2295 | 49 | |||
2296 | 50 | -- This is the path with specific libraries for the test suite | ||
2297 | 51 | local PRIVATE_LUA_PATH = arg[1] .. '/t/?.lua' | ||
2298 | 52 | |||
2299 | 53 | -- This is the path with additional libraries that the user needs | ||
2300 | 54 | local LUA_USER_PATH = os.getenv('LUA_USER_PATH') or '../lib/?.lua' | ||
2301 | 55 | |||
2302 | 56 | -- Building the final include path | ||
2303 | 57 | local INCLUDE_PATH = | ||
2304 | 58 | LUA_USER_PATH .. ';' .. | ||
2305 | 59 | PRIVATE_LUA_PATH .. ';' .. | ||
2306 | 60 | GLOBAL_LUA_PATH .. ';' .. | ||
2307 | 61 | PROXY_LUA_PATH | ||
2308 | 62 | |||
2309 | 63 | --- | ||
2310 | 64 | -- start_proxy() | ||
2311 | 65 | -- | ||
2312 | 66 | -- starts an instance of MySQL Proxy | ||
2313 | 67 | -- | ||
2314 | 68 | -- @param proxy_name internal name of the proxy instance, for retrieval | ||
2315 | 69 | -- @param proxy_options the options to start the Proxy | ||
2316 | 70 | function start_proxy(proxy_name, proxy_options) | ||
2317 | 71 | -- start the proxy | ||
2318 | 72 | assert(type(proxy_options) == 'table') | ||
2319 | 73 | if not file_exists(proxy_options['proxy-lua-script']) then | ||
2320 | 74 | proxy_options['proxy-lua-script'] = | ||
2321 | 75 | global_basedir .. | ||
2322 | 76 | '/t/' .. proxy_options['proxy-lua-script'] | ||
2323 | 77 | end | ||
2324 | 78 | print_verbose("starting " .. proxy_name .. " with " .. options_tostring(proxy_options)) | ||
2325 | 79 | |||
2326 | 80 | -- remove the old pid-file if it exists | ||
2327 | 81 | os.remove(proxy_options['pid-file']) | ||
2328 | 82 | -- if we are supposed to listen on a UNIX socket, remove it first, because we don't clean it up on exit! | ||
2329 | 83 | -- TODO: fix the code, instead of hacking around here! Bug#38415 | ||
2330 | 84 | if proxy_options['proxy-address'] == '/tmp/mysql-proxy-test.sock' then | ||
2331 | 85 | os.remove(proxy_options['proxy-address']) | ||
2332 | 86 | end | ||
2333 | 87 | -- os.execute("head " .. proxy_options['proxy-lua-script']) | ||
2334 | 88 | assert(os.execute( 'LUA_PATH="' .. INCLUDE_PATH .. '" ' .. | ||
2335 | 89 | PROXY_TRACE .. " " .. PROXY_BINPATH .. " " .. | ||
2336 | 90 | options_tostring( proxy_options) .. " &" | ||
2337 | 91 | )) | ||
2338 | 92 | |||
2339 | 93 | -- wait until the proxy is up | ||
2340 | 94 | proc = Process.new() | ||
2341 | 95 | proc.set_pid_from_pidfile(proxy_options['pid-file']) | ||
2342 | 96 | |||
2343 | 97 | procs[proxy_name] = proc | ||
2344 | 98 | end | ||
2345 | 99 | |||
2346 | 100 | --- | ||
2347 | 101 | -- simulate_replication() | ||
2348 | 102 | -- | ||
2349 | 103 | -- creates a fake master/slave by having two proxies | ||
2350 | 104 | -- pointing at the same backend | ||
2351 | 105 | -- | ||
2352 | 106 | -- you can alter those backends by changing | ||
2353 | 107 | -- the starting parameters | ||
2354 | 108 | -- | ||
2355 | 109 | -- @param master_options options for master | ||
2356 | 110 | -- @param slave_options options for slave | ||
2357 | 111 | function simulate_replication(master_options, slave_options) | ||
2358 | 112 | if not master_options then | ||
2359 | 113 | master_options = default_master_options | ||
2360 | 114 | end | ||
2361 | 115 | if not master_options['pid-file'] then | ||
2362 | 116 | master_options['pid-file'] = PROXY_MASTER_PIDFILE | ||
2363 | 117 | end | ||
2364 | 118 | if not slave_options then | ||
2365 | 119 | slave_options = default_slave_options | ||
2366 | 120 | end | ||
2367 | 121 | if not slave_options['pid-file'] then | ||
2368 | 122 | slave_options['pid-file'] = PROXY_SLAVE_PIDFILE | ||
2369 | 123 | end | ||
2370 | 124 | start_proxy('master', master_options) | ||
2371 | 125 | start_proxy('slave', slave_options) | ||
2372 | 126 | end | ||
2373 | 127 | |||
2374 | 128 | --- | ||
2375 | 129 | -- chain_proxy() | ||
2376 | 130 | -- | ||
2377 | 131 | -- starts two proxy instances, with the first one is pointing to the | ||
2378 | 132 | -- default backend server, and the second one (with default ports) | ||
2379 | 133 | -- is pointing at the first proxy | ||
2380 | 134 | -- | ||
2381 | 135 | -- client -> proxy -> backend_proxy -> [ mysql-backend ] | ||
2382 | 136 | -- | ||
2383 | 137 | -- usually we use it to mock a server with a lua script (...-mock.lua) and | ||
2384 | 138 | -- the script under test in the proxy (...-test.lua) | ||
2385 | 139 | -- | ||
2386 | 140 | -- in case you want to start several backend_proxies, just provide a array | ||
2387 | 141 | -- as first param | ||
2388 | 142 | -- | ||
2389 | 143 | -- @param backend_lua_script | ||
2390 | 144 | -- @param second_lua_script | ||
2391 | 145 | -- @param use_replication uses a master proxy as backend | ||
2392 | 146 | function chain_proxy (backend_lua_scripts, second_lua_script, use_replication) | ||
2393 | 147 | local backends = { } | ||
2394 | 148 | |||
2395 | 149 | if type(backend_lua_scripts) == "table" then | ||
2396 | 150 | backends = backend_lua_scripts | ||
2397 | 151 | else | ||
2398 | 152 | backends = { backend_lua_scripts } | ||
2399 | 153 | end | ||
2400 | 154 | |||
2401 | 155 | local backend_addresses = { } | ||
2402 | 156 | |||
2403 | 157 | for i, backend_lua_script in ipairs(backends) do | ||
2404 | 158 | backend_addresses[i] = PROXY_HOST .. ":" .. (PROXY_CHAIN_PORT + i - 1) | ||
2405 | 159 | |||
2406 | 160 | backend_proxy_options = { | ||
2407 | 161 | ["proxy-backend-addresses"] = MYSQL_HOST .. ":" .. MYSQL_PORT, | ||
2408 | 162 | ["proxy-address"] = backend_addresses[i], | ||
2409 | 163 | ["admin-address"] = PROXY_HOST .. ":" .. (ADMIN_CHAIN_PORT + i - 1), | ||
2410 | 164 | ["admin-username"] = ADMIN_USER, | ||
2411 | 165 | ["admin-password"] = ADMIN_PASSWORD, | ||
2412 | 166 | ["admin-lua-script"] = ADMIN_DEFAULT_SCRIPT_FILENAME, | ||
2413 | 167 | ["pid-file"] = PROXY_CHAIN_PIDFILE .. i, | ||
2414 | 168 | ["proxy-lua-script"] = backend_lua_script or DEFAULT_SCRIPT_FILENAME, | ||
2415 | 169 | ["plugin-dir"] = PROXY_LIBPATH, | ||
2416 | 170 | ["basedir"] = PROXY_TEST_BASEDIR, | ||
2417 | 171 | ["log-level"] = (VERBOSE == 4) and "debug" or "critical", | ||
2418 | 172 | } | ||
2419 | 173 | -- | ||
2420 | 174 | -- if replication was not started, then it is started here | ||
2421 | 175 | -- | ||
2422 | 176 | if use_replication and (use_replication == true) then | ||
2423 | 177 | if (proxy_list['master'] == nil) then | ||
2424 | 178 | simulate_replication() | ||
2425 | 179 | end | ||
2426 | 180 | backend_proxy_options["proxy-backend-addresses"] = PROXY_HOST .. ':' .. PROXY_MASTER_PORT | ||
2427 | 181 | end | ||
2428 | 182 | start_proxy('backend_proxy' .. i, backend_proxy_options) | ||
2429 | 183 | end | ||
2430 | 184 | |||
2431 | 185 | second_proxy_options = { | ||
2432 | 186 | ["proxy-backend-addresses"] = backend_addresses , | ||
2433 | 187 | ["proxy-address"] = PROXY_HOST .. ":" .. PROXY_PORT, | ||
2434 | 188 | ["admin-address"] = PROXY_HOST .. ":" .. ADMIN_PORT, | ||
2435 | 189 | ["admin-username"] = ADMIN_USER, | ||
2436 | 190 | ["admin-password"] = ADMIN_PASSWORD, | ||
2437 | 191 | ["admin-lua-script"] = ADMIN_DEFAULT_SCRIPT_FILENAME, | ||
2438 | 192 | ["pid-file"] = PROXY_PIDFILE, | ||
2439 | 193 | ["proxy-lua-script"] = second_lua_script or DEFAULT_SCRIPT_FILENAME, | ||
2440 | 194 | ["plugin-dir"] = PROXY_LIBPATH, | ||
2441 | 195 | ["basedir"] = PROXY_TEST_BASEDIR, | ||
2442 | 196 | ["log-level"] = (VERBOSE == 3) and "debug" or "critical", | ||
2443 | 197 | } | ||
2444 | 198 | start_proxy('second_proxy',second_proxy_options) | ||
2445 | 199 | end | ||
2446 | 200 | |||
2447 | 201 | |||
2448 | 202 | --- | ||
2449 | 203 | --sql_execute() | ||
2450 | 204 | -- | ||
2451 | 205 | -- Executes a SQL query in a given Proxy | ||
2452 | 206 | -- | ||
2453 | 207 | -- If no Proxy is indicated, the query is passed directly to the backend server | ||
2454 | 208 | -- | ||
2455 | 209 | -- @param query A SQL statement to execute, or a table of SQL statements | ||
2456 | 210 | -- @param proxy_name the name of the proxy that executes the query | ||
2457 | 211 | function sql_execute(queries, proxy_name) | ||
2458 | 212 | local ret = 0 | ||
2459 | 213 | assert(type(queries) == 'string' or type(queries) == 'table', 'invalid type for query' ) | ||
2460 | 214 | if type(queries) == 'string' then | ||
2461 | 215 | queries = {queries} | ||
2462 | 216 | end | ||
2463 | 217 | local query = '' | ||
2464 | 218 | for i, q in pairs(queries) do | ||
2465 | 219 | query = query .. ';' .. q | ||
2466 | 220 | end | ||
2467 | 221 | |||
2468 | 222 | if proxy_name then | ||
2469 | 223 | -- | ||
2470 | 224 | -- a Proxy name is passed. | ||
2471 | 225 | -- The query is executed with the given proxy | ||
2472 | 226 | local opts = proxy_list[proxy_name] | ||
2473 | 227 | assert(opts,'proxy '.. proxy_name .. ' not active') | ||
2474 | 228 | assert(opts['proxy-address'],'address for proxy '.. proxy_name .. ' not found') | ||
2475 | 229 | local p_host, p_port = opts['proxy-address']:match('(%S+):(%S+)') | ||
2476 | 230 | ret = os_execute( MYSQL_CLIENT_BIN .. ' ' .. | ||
2477 | 231 | options_tostring({ | ||
2478 | 232 | user = MYSQL_USER, | ||
2479 | 233 | password = MYSQL_PASSWORD, | ||
2480 | 234 | database = MYSQL_DB, | ||
2481 | 235 | host = p_host, | ||
2482 | 236 | port = p_port, | ||
2483 | 237 | execute = query | ||
2484 | 238 | }) | ||
2485 | 239 | ) | ||
2486 | 240 | assert(ret == 0, 'error using mysql client ') | ||
2487 | 241 | else | ||
2488 | 242 | -- | ||
2489 | 243 | -- No proxy name was passed. | ||
2490 | 244 | -- The query is executed in the backend server | ||
2491 | 245 | -- | ||
2492 | 246 | ret = os_execute( MYSQL_CLIENT_BIN .. ' ' .. | ||
2493 | 247 | options_tostring({ | ||
2494 | 248 | user = MYSQL_USER, | ||
2495 | 249 | password = MYSQL_PASSWORD, | ||
2496 | 250 | database = MYSQL_DB, | ||
2497 | 251 | host = PROXY_HOST, | ||
2498 | 252 | port = MYSQL_PORT, | ||
2499 | 253 | execute = query | ||
2500 | 254 | }) | ||
2501 | 255 | ) | ||
2502 | 256 | end | ||
2503 | 257 | return ret | ||
2504 | 258 | end | ||
2505 | 259 | |||
2506 | 260 | function only_item ( tbl, item) | ||
2507 | 261 | local exists = false | ||
2508 | 262 | for i,v in pairs(tbl) do | ||
2509 | 263 | if i == item then | ||
2510 | 264 | exists = true | ||
2511 | 265 | else | ||
2512 | 266 | return false | ||
2513 | 267 | end | ||
2514 | 268 | end | ||
2515 | 269 | return exists | ||
2516 | 270 | end | ||
2517 | 271 |
Looks good to me. A few very minor comments (with the first being the only one needing to be resolved):
- No copyright/licenses headers have had the date updated.. Please do that
- Can we keep this comment on one line:
+ /* only try to delete the PID if we created it
+ */
- Why hard code the following to MySQLProxy: get_args( )?:
+ opts["plugins"] = "proxy"
+ opts["daemon"] = true
- This looks incomplete, what is the plan here?:
+ if extra_params then
+ -- FIXME: implement me
+ end
- Bug#38415 has been fixed now (https:/ /code.launchpad .net/~schuster/ mysql-proxy/ remove_ unix_socket/ +merge/ 23652), we can just remove the following now:
+ -- if we are supposed to listen on a UNIX socket, remove it first, because we don't clean it up on exit! 'proxy- address' ] == '/tmp/mysql- proxy-test. sock' then proxy_options[ 'proxy- address' ])
+ -- TODO: fix the code, instead of hacking around here! Bug#38415
+ if proxy_options[
+ os.remove(
+ end
- I see changes to Makefile.am, but none to any CMakeLists.txt files, I understand that the test suite does not run on Windows yet, however I'd also like us to move towards cmake as the one true source as well. Please consider making it so that cmake can still build all of this on *nix, and opening a new issue to get the test suite working on Windows as well.