Merge lp:~laurynas-biveinis/percona-server/bug1183625-5.5 into lp:percona-server/5.5
- bug1183625-5.5
- Merge into 5.5
Proposed by
Laurynas Biveinis
Status: | Merged |
---|---|
Approved by: | Stewart Smith |
Approved revision: | no longer in the source branch. |
Merged at revision: | 527 |
Proposed branch: | lp:~laurynas-biveinis/percona-server/bug1183625-5.5 |
Merge into: | lp:percona-server/5.5 |
Prerequisite: | lp:~laurynas-biveinis/percona-server/tree-fixes-5.5 |
Diff against target: |
19430 lines (+18482/-463) (has conflicts) 91 files modified
COPYING.show_temp_51 (+0/-13) Percona-Server/mysql-test/include/have_response_time_distribution.inc (+4/-0) Percona-Server/mysql-test/include/percona_query_cache_with_comments_end.inc (+3/-0) Percona-Server/mysql-test/include/query_response_time.inc (+0/-43) Percona-Server/mysql-test/r/percona_innodb_deadlock_count.result (+0/-28) Percona-Server/mysql-test/r/percona_innodb_use_sys_stats_table.result (+0/-3) Percona-Server/mysql-test/r/percona_log_connection_error.result (+16/-0) Percona-Server/mysql-test/r/percona_log_slow_admin_statements-config_foo.result (+0/-7) Percona-Server/mysql-test/r/percona_query_cache_with_comments_crash.result (+0/-21) Percona-Server/mysql-test/r/percona_query_response_time.result (+1307/-0) Percona-Server/mysql-test/r/percona_userstat.result (+80/-10) Percona-Server/mysql-test/r/percona_xtradb_admin_command.result (+0/-6) Percona-Server/mysql-test/r/percona_xtradb_bug317074.result (+5/-0) Percona-Server/mysql-test/t/percona_bug643149.test (+49/-0) Percona-Server/mysql-test/t/percona_bug933969.test (+0/-42) Percona-Server/mysql-test/t/percona_log_slow_verbosity-cl.test (+2/-0) Percona-Server/mysql-test/t/percona_query_cache_with_comments_prepared_statements.test (+208/-0) Percona-Server/mysql-test/t/percona_server_variables_debug.test (+0/-2) Percona-Server/mysql-test/t/percona_server_variables_release.test (+2/-0) Percona-Server/mysql-test/t/percona_sql_no_fcache.test (+11/-0) Percona-Server/mysql-test/t/percona_userstat.test (+81/-6) build/debian/copyright (+0/-86) doc/source/compatibility.rst (+27/-0) doc/source/diagnostics/innodb_stats.rst (+234/-0) doc/source/flexibility/innodb_fast_shutdown.rst (+0/-36) doc/source/management/innodb_expand_import.rst (+0/-160) python-for-subunit2junitxml/BytesIO.py (+136/-0) python-for-subunit2junitxml/iso8601/LICENSE (+20/-0) python-for-subunit2junitxml/iso8601/README (+26/-0) python-for-subunit2junitxml/iso8601/README.subunit (+5/-0) python-for-subunit2junitxml/iso8601/setup.py (+58/-0) python-for-subunit2junitxml/iso8601/test_iso8601.py (+111/-0) python-for-subunit2junitxml/junitxml/__init__.py (+221/-0) python-for-subunit2junitxml/junitxml/tests/__init__.py (+16/-0) python-for-subunit2junitxml/junitxml/tests/test_junitxml.py (+327/-0) python-for-subunit2junitxml/subunit/__init__.py (+1250/-0) python-for-subunit2junitxml/subunit/chunked.py (+185/-0) python-for-subunit2junitxml/subunit/details.py (+119/-0) python-for-subunit2junitxml/subunit/iso8601.py (+133/-0) python-for-subunit2junitxml/subunit/progress_model.py (+106/-0) python-for-subunit2junitxml/subunit/run.py (+73/-0) python-for-subunit2junitxml/subunit/test_results.py (+492/-0) python-for-subunit2junitxml/subunit/tests/TestUtil.py (+80/-0) python-for-subunit2junitxml/subunit/tests/__init__.py (+41/-0) python-for-subunit2junitxml/subunit/tests/sample-script.py (+21/-0) python-for-subunit2junitxml/subunit/tests/sample-two-script.py (+7/-0) python-for-subunit2junitxml/subunit/tests/test_chunked.py (+152/-0) python-for-subunit2junitxml/subunit/tests/test_details.py (+112/-0) python-for-subunit2junitxml/subunit/tests/test_progress_model.py (+118/-0) python-for-subunit2junitxml/subunit/tests/test_subunit_filter.py (+208/-0) python-for-subunit2junitxml/subunit/tests/test_subunit_stats.py (+84/-0) python-for-subunit2junitxml/subunit/tests/test_subunit_tags.py (+69/-0) python-for-subunit2junitxml/subunit/tests/test_tap2subunit.py (+445/-0) python-for-subunit2junitxml/subunit/tests/test_test_protocol.py (+1299/-0) python-for-subunit2junitxml/subunit/tests/test_test_results.py (+300/-0) python-for-subunit2junitxml/testtools/__init__.py (+80/-0) python-for-subunit2junitxml/testtools/_spinner.py (+316/-0) python-for-subunit2junitxml/testtools/compat.py (+286/-0) python-for-subunit2junitxml/testtools/content.py (+238/-0) python-for-subunit2junitxml/testtools/content_type.py (+33/-0) python-for-subunit2junitxml/testtools/deferredruntest.py (+335/-0) python-for-subunit2junitxml/testtools/distutilscmd.py (+62/-0) python-for-subunit2junitxml/testtools/helpers.py (+64/-0) python-for-subunit2junitxml/testtools/matchers.py (+785/-0) python-for-subunit2junitxml/testtools/monkey.py (+97/-0) python-for-subunit2junitxml/testtools/run.py (+332/-0) python-for-subunit2junitxml/testtools/runtest.py (+200/-0) python-for-subunit2junitxml/testtools/testcase.py (+724/-0) python-for-subunit2junitxml/testtools/testresult/__init__.py (+19/-0) python-for-subunit2junitxml/testtools/testresult/doubles.py (+111/-0) python-for-subunit2junitxml/testtools/testresult/real.py (+621/-0) python-for-subunit2junitxml/testtools/tests/__init__.py (+44/-0) python-for-subunit2junitxml/testtools/tests/helpers.py (+72/-0) python-for-subunit2junitxml/testtools/tests/test_compat.py (+257/-0) python-for-subunit2junitxml/testtools/tests/test_content.py (+223/-0) python-for-subunit2junitxml/testtools/tests/test_content_type.py (+46/-0) python-for-subunit2junitxml/testtools/tests/test_deferredruntest.py (+738/-0) python-for-subunit2junitxml/testtools/tests/test_distutilscmd.py (+90/-0) python-for-subunit2junitxml/testtools/tests/test_fixturesupport.py (+79/-0) python-for-subunit2junitxml/testtools/tests/test_helpers.py (+106/-0) python-for-subunit2junitxml/testtools/tests/test_matchers.py (+695/-0) python-for-subunit2junitxml/testtools/tests/test_monkey.py (+167/-0) python-for-subunit2junitxml/testtools/tests/test_run.py (+77/-0) python-for-subunit2junitxml/testtools/tests/test_runtest.py (+300/-0) python-for-subunit2junitxml/testtools/tests/test_spinner.py (+332/-0) python-for-subunit2junitxml/testtools/tests/test_testresult.py (+1372/-0) python-for-subunit2junitxml/testtools/tests/test_testsuite.py (+53/-0) python-for-subunit2junitxml/testtools/tests/test_testtools.py (+1143/-0) python-for-subunit2junitxml/testtools/tests/test_with_with.py (+42/-0) python-for-subunit2junitxml/testtools/testsuite.py (+87/-0) python-for-subunit2junitxml/testtools/utils.py (+13/-0) Conflict: can't delete UDF.moved because it is not empty. Not deleting. Conflict adding file UDF. Moved existing file to UDF.moved. Conflict because UDF.moved is not versioned, but has versioned children. Versioned directory. Conflict adding file doc/source/performance/innodb_lazy_drop_table.rst. Moved existing file to doc/source/performance/innodb_lazy_drop_table.rst.moved. |
To merge this branch: | bzr merge lp:~laurynas-biveinis/percona-server/bug1183625-5.5 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Stewart Smith (community) | Approve | ||
Review via email: mp+165967@code.launchpad.net |
Commit message
Description of the change
Merge percona_userstat testcase from 5.1, partially addressing bug
1179534, and containing the testcase for bug 1183625.
http://
To post a comment you must log in.
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
Revision history for this message
Stewart Smith (stewart) wrote : | # |
I used "bzr merge" and "bzr diff" locally to review, as LP seems to have gotten it really wrong with the diff.
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === removed file 'COPYING.show_temp_51' |
2 | --- COPYING.show_temp_51 2013-05-28 06:50:44 +0000 |
3 | +++ COPYING.show_temp_51 1970-01-01 00:00:00 +0000 |
4 | @@ -1,13 +0,0 @@ |
5 | -Portions of this software contain modifications contributed by Venu Anuganti. |
6 | -These contributions are used with the following license: |
7 | - |
8 | -Copyright (c) 2010, Venu Anuganti, http://venublog.com/ |
9 | -All rights reserved. |
10 | - |
11 | -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: |
12 | - |
13 | - * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. |
14 | - * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. |
15 | - * Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. |
16 | - |
17 | -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
18 | |
19 | === added file 'Percona-Server/mysql-test/include/have_response_time_distribution.inc' |
20 | --- Percona-Server/mysql-test/include/have_response_time_distribution.inc 1970-01-01 00:00:00 +0000 |
21 | +++ Percona-Server/mysql-test/include/have_response_time_distribution.inc 2013-05-28 06:50:46 +0000 |
22 | @@ -0,0 +1,4 @@ |
23 | +-- require r/have_response_time_distribution.require |
24 | +disable_query_log; |
25 | +show variables like 'have_response_time_distribution'; |
26 | +enable_query_log; |
27 | |
28 | === added file 'Percona-Server/mysql-test/include/percona_query_cache_with_comments_end.inc' |
29 | --- Percona-Server/mysql-test/include/percona_query_cache_with_comments_end.inc 1970-01-01 00:00:00 +0000 |
30 | +++ Percona-Server/mysql-test/include/percona_query_cache_with_comments_end.inc 2013-05-28 06:50:46 +0000 |
31 | @@ -0,0 +1,3 @@ |
32 | +DROP TABLE t1; |
33 | +SET GLOBAL query_cache_size=default; |
34 | +set global query_cache_strip_comments=OFF; |
35 | |
36 | === removed file 'Percona-Server/mysql-test/include/query_response_time.inc' |
37 | --- Percona-Server/mysql-test/include/query_response_time.inc 2013-05-28 06:50:44 +0000 |
38 | +++ Percona-Server/mysql-test/include/query_response_time.inc 1970-01-01 00:00:00 +0000 |
39 | @@ -1,43 +0,0 @@ |
40 | -SET SESSION query_exec_time=0.1; |
41 | - |
42 | -SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; |
43 | -EVAL SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=$base; |
44 | -FLUSH QUERY_RESPONSE_TIME; |
45 | -# Following two queries check works of FLUSH and |
46 | -# respecting of "QUERY_RESPONSE_TIME_STATS" variable (see launchpad bug #855312) |
47 | -SHOW QUERY_RESPONSE_TIME; |
48 | -SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; |
49 | -SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; |
50 | - |
51 | -SET SESSION query_exec_time=0.31; SELECT 1; |
52 | -SET SESSION query_exec_time=0.32; SELECT 1; |
53 | -SET SESSION query_exec_time=0.33; SELECT 1; |
54 | -SET SESSION query_exec_time=0.34; SELECT 1; |
55 | -SET SESSION query_exec_time=0.35; SELECT 1; |
56 | -SET SESSION query_exec_time=0.36; SELECT 1; |
57 | -SET SESSION query_exec_time=0.37; SELECT 1; |
58 | -SET SESSION query_exec_time=0.38; SELECT 1; |
59 | -SET SESSION query_exec_time=0.39; SELECT 1; |
60 | -SET SESSION query_exec_time=0.4; SELECT 1; |
61 | -SET SESSION query_exec_time=1.1; SELECT 1; |
62 | -SET SESSION query_exec_time=1.2; SELECT 1; |
63 | -SET SESSION query_exec_time=1.3; SELECT 1; |
64 | -SET SESSION query_exec_time=1.5; SELECT 1; |
65 | -SET SESSION query_exec_time=1.4; SELECT 1; |
66 | -SET SESSION query_exec_time=0.5; SELECT 1; |
67 | -SET SESSION query_exec_time=2.1; SELECT 1; |
68 | -SET SESSION query_exec_time=2.3; SELECT 1; |
69 | -SET SESSION query_exec_time=2.5; SELECT 1; |
70 | -SET SESSION query_exec_time=3.1; SELECT 1; |
71 | -SET SESSION query_exec_time=4.1; SELECT 1; |
72 | -SET SESSION query_exec_time=5.1; SELECT 1; |
73 | - |
74 | -SET SESSION query_exec_time=0.1; |
75 | - |
76 | -SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; |
77 | - |
78 | -SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; |
79 | -SHOW QUERY_RESPONSE_TIME; |
80 | -SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; |
81 | - |
82 | -SET SESSION query_exec_time=default; |
83 | |
84 | === removed file 'Percona-Server/mysql-test/r/percona_innodb_deadlock_count.result' |
85 | --- Percona-Server/mysql-test/r/percona_innodb_deadlock_count.result 2013-05-28 06:50:44 +0000 |
86 | +++ Percona-Server/mysql-test/r/percona_innodb_deadlock_count.result 1970-01-01 00:00:00 +0000 |
87 | @@ -1,28 +0,0 @@ |
88 | -# Establish connection con1 (user=root) |
89 | -# Establish connection con2 (user=root) |
90 | -# Establish connection con3 (user=root) |
91 | -# Drop test table |
92 | -drop table if exists t; |
93 | -# Create test table |
94 | -create table t(a INT PRIMARY KEY, b INT) engine=InnoDB; |
95 | -# Insert two rows to test table |
96 | -insert into t values(2,1); |
97 | -insert into t values(1,2); |
98 | -# Switch to connection con1 |
99 | -BEGIN; |
100 | -SELECT b FROM t WHERE a=1 FOR UPDATE; |
101 | -# Switch to connection con2 |
102 | -BEGIN; |
103 | -SELECT b FROM t WHERE a=2 FOR UPDATE; |
104 | -# Switch to connection con1 |
105 | -SELECT b FROM t WHERE a=2 FOR UPDATE; |
106 | -# Switch to connection con2 |
107 | -SELECT b FROM t WHERE a=1 FOR UPDATE; |
108 | -# Switch to connection con1 |
109 | -ROLLBACK; |
110 | -# Switch to connection con2 |
111 | -ROLLBACK; |
112 | -# Switch to connection con3 |
113 | -Deadlocks: 1 |
114 | -# Drop test table |
115 | -drop table t; |
116 | |
117 | === removed file 'Percona-Server/mysql-test/r/percona_innodb_use_sys_stats_table.result' |
118 | --- Percona-Server/mysql-test/r/percona_innodb_use_sys_stats_table.result 2013-05-28 06:50:44 +0000 |
119 | +++ Percona-Server/mysql-test/r/percona_innodb_use_sys_stats_table.result 1970-01-01 00:00:00 +0000 |
120 | @@ -1,3 +0,0 @@ |
121 | -show variables like 'innodb_use_sys_stats%'; |
122 | -Variable_name Value |
123 | -innodb_use_sys_stats_table ON |
124 | |
125 | === added file 'Percona-Server/mysql-test/r/percona_log_connection_error.result' |
126 | --- Percona-Server/mysql-test/r/percona_log_connection_error.result 1970-01-01 00:00:00 +0000 |
127 | +++ Percona-Server/mysql-test/r/percona_log_connection_error.result 2013-05-28 06:50:46 +0000 |
128 | @@ -0,0 +1,16 @@ |
129 | +SET @old_max_connections = @@max_connections; |
130 | +SET @old_log_warnings = @@log_warnings; |
131 | +SET GLOBAL max_connections=2; |
132 | +SET GLOBAL LOG_WARNINGS = 0; |
133 | +connect(localhost,root,,test,port,socket); |
134 | +ERROR HY000: Too many connections |
135 | +SET GLOBAL LOG_WARNINGS = 1; |
136 | +connect(localhost,root,,test,port,socket); |
137 | +ERROR HY000: Too many connections |
138 | +SET GLOBAL LOG_WARNINGS = 0; |
139 | +connect(localhost,root,,test,port,socket); |
140 | +ERROR HY000: Too many connections |
141 | +SET GLOBAL max_connections = @old_max_connections; |
142 | +SET GLOBAL log_warnings = @old_log_warnings; |
143 | +[log_grep.inc] file: percona.log_connection_error.err pattern: Too many connections |
144 | +[log_grep.inc] lines: 1 |
145 | |
146 | === removed file 'Percona-Server/mysql-test/r/percona_log_slow_admin_statements-config_foo.result' |
147 | --- Percona-Server/mysql-test/r/percona_log_slow_admin_statements-config_foo.result 2013-05-28 06:50:44 +0000 |
148 | +++ Percona-Server/mysql-test/r/percona_log_slow_admin_statements-config_foo.result 1970-01-01 00:00:00 +0000 |
149 | @@ -1,7 +0,0 @@ |
150 | -call mtr.add_suppression("option 'log_slow_admin_statements': boolean value 'foo' wasn't recognized. Set to OFF."); |
151 | -SHOW GLOBAL VARIABLES like 'log_slow_admin_statements'; |
152 | -Variable_name Value |
153 | -log_slow_admin_statements OFF |
154 | -SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='log_slow_admin_statements'; |
155 | -VARIABLE_NAME VARIABLE_VALUE |
156 | -LOG_SLOW_ADMIN_STATEMENTS OFF |
157 | |
158 | === removed file 'Percona-Server/mysql-test/r/percona_query_cache_with_comments_crash.result' |
159 | --- Percona-Server/mysql-test/r/percona_query_cache_with_comments_crash.result 2013-05-28 06:50:44 +0000 |
160 | +++ Percona-Server/mysql-test/r/percona_query_cache_with_comments_crash.result 1970-01-01 00:00:00 +0000 |
161 | @@ -1,21 +0,0 @@ |
162 | -set GLOBAL query_cache_size=1355776; |
163 | -drop table if exists t1; |
164 | -create table t1 (a int not null); |
165 | -insert into t1 values (1),(2),(3); |
166 | -flush query cache; |
167 | -flush query cache; |
168 | -reset query cache; |
169 | -flush status; |
170 | -( select * from t1 ); |
171 | -a |
172 | -1 |
173 | -2 |
174 | -3 |
175 | -/*!40101 SET @OLD_SQL_MODE := @@SQL_MODE, @@SQL_MODE := REPLACE(REPLACE(@@SQL_MODE, 'ANSI_QUOTES', ''), ',,', ','), @OLD_QUOTE := @@SQL_QUOTE_SHOW_CREATE, @@SQL_QUOTE_SHOW_CREATE := 1 */; |
176 | -/* only comment */; |
177 | -# only comment |
178 | -; |
179 | --- only comment |
180 | -; |
181 | -DROP TABLE t1; |
182 | -SET GLOBAL query_cache_size= default; |
183 | |
184 | === added file 'Percona-Server/mysql-test/r/percona_query_response_time.result' |
185 | --- Percona-Server/mysql-test/r/percona_query_response_time.result 1970-01-01 00:00:00 +0000 |
186 | +++ Percona-Server/mysql-test/r/percona_query_response_time.result 2013-05-28 06:50:46 +0000 |
187 | @@ -0,0 +1,1307 @@ |
188 | +SET SESSION query_exec_time=0.1; |
189 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; |
190 | +SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=1; |
191 | +Warnings: |
192 | +Warning 1292 Truncated incorrect query_response_time_range_base value: '1' |
193 | +FLUSH QUERY_RESPONSE_TIME; |
194 | +SHOW QUERY_RESPONSE_TIME; |
195 | + |
196 | + 0.000001 0 0.000000 |
197 | + 0.000003 0 0.000000 |
198 | + 0.000007 0 0.000000 |
199 | + 0.000015 0 0.000000 |
200 | + 0.000030 0 0.000000 |
201 | + 0.000061 0 0.000000 |
202 | + 0.000122 0 0.000000 |
203 | + 0.000244 0 0.000000 |
204 | + 0.000488 0 0.000000 |
205 | + 0.000976 0 0.000000 |
206 | + 0.001953 0 0.000000 |
207 | + 0.003906 0 0.000000 |
208 | + 0.007812 0 0.000000 |
209 | + 0.015625 0 0.000000 |
210 | + 0.031250 0 0.000000 |
211 | + 0.062500 0 0.000000 |
212 | + 0.125000 0 0.000000 |
213 | + 0.250000 0 0.000000 |
214 | + 0.500000 0 0.000000 |
215 | + 1.000000 0 0.000000 |
216 | + 2.000000 0 0.000000 |
217 | + 4.000000 0 0.000000 |
218 | + 8.000000 0 0.000000 |
219 | + 16.000000 0 0.000000 |
220 | + 32.000000 0 0.000000 |
221 | + 64.000000 0 0.000000 |
222 | + 128.000000 0 0.000000 |
223 | + 256.000000 0 0.000000 |
224 | + 512.000000 0 0.000000 |
225 | + 1024.000000 0 0.000000 |
226 | + 2048.000000 0 0.000000 |
227 | + 4096.000000 0 0.000000 |
228 | + 8192.000000 0 0.000000 |
229 | + 16384.000000 0 0.000000 |
230 | + 32768.000000 0 0.000000 |
231 | + 65536.000000 0 0.000000 |
232 | + 131072.000000 0 0.000000 |
233 | + 262144.000000 0 0.000000 |
234 | + 524288.000000 0 0.000000 |
235 | +1048576.000000 0 0.000000 |
236 | +2097152.000000 0 0.000000 |
237 | +4194304.000000 0 0.000000 |
238 | +8388608.000000 0 0.000000 |
239 | +TOO LONG 0 TOO LONG |
240 | +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; |
241 | +time count total |
242 | + 0.000001 0 0.000000 |
243 | + 0.000003 0 0.000000 |
244 | + 0.000007 0 0.000000 |
245 | + 0.000015 0 0.000000 |
246 | + 0.000030 0 0.000000 |
247 | + 0.000061 0 0.000000 |
248 | + 0.000122 0 0.000000 |
249 | + 0.000244 0 0.000000 |
250 | + 0.000488 0 0.000000 |
251 | + 0.000976 0 0.000000 |
252 | + 0.001953 0 0.000000 |
253 | + 0.003906 0 0.000000 |
254 | + 0.007812 0 0.000000 |
255 | + 0.015625 0 0.000000 |
256 | + 0.031250 0 0.000000 |
257 | + 0.062500 0 0.000000 |
258 | + 0.125000 0 0.000000 |
259 | + 0.250000 0 0.000000 |
260 | + 0.500000 0 0.000000 |
261 | + 1.000000 0 0.000000 |
262 | + 2.000000 0 0.000000 |
263 | + 4.000000 0 0.000000 |
264 | + 8.000000 0 0.000000 |
265 | + 16.000000 0 0.000000 |
266 | + 32.000000 0 0.000000 |
267 | + 64.000000 0 0.000000 |
268 | + 128.000000 0 0.000000 |
269 | + 256.000000 0 0.000000 |
270 | + 512.000000 0 0.000000 |
271 | + 1024.000000 0 0.000000 |
272 | + 2048.000000 0 0.000000 |
273 | + 4096.000000 0 0.000000 |
274 | + 8192.000000 0 0.000000 |
275 | + 16384.000000 0 0.000000 |
276 | + 32768.000000 0 0.000000 |
277 | + 65536.000000 0 0.000000 |
278 | + 131072.000000 0 0.000000 |
279 | + 262144.000000 0 0.000000 |
280 | + 524288.000000 0 0.000000 |
281 | +1048576.000000 0 0.000000 |
282 | +2097152.000000 0 0.000000 |
283 | +4194304.000000 0 0.000000 |
284 | +8388608.000000 0 0.000000 |
285 | +TOO LONG 0 TOO LONG |
286 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; |
287 | +SET SESSION query_exec_time=0.31; |
288 | +SELECT 1; |
289 | +1 |
290 | +1 |
291 | +SET SESSION query_exec_time=0.32; |
292 | +SELECT 1; |
293 | +1 |
294 | +1 |
295 | +SET SESSION query_exec_time=0.33; |
296 | +SELECT 1; |
297 | +1 |
298 | +1 |
299 | +SET SESSION query_exec_time=0.34; |
300 | +SELECT 1; |
301 | +1 |
302 | +1 |
303 | +SET SESSION query_exec_time=0.35; |
304 | +SELECT 1; |
305 | +1 |
306 | +1 |
307 | +SET SESSION query_exec_time=0.36; |
308 | +SELECT 1; |
309 | +1 |
310 | +1 |
311 | +SET SESSION query_exec_time=0.37; |
312 | +SELECT 1; |
313 | +1 |
314 | +1 |
315 | +SET SESSION query_exec_time=0.38; |
316 | +SELECT 1; |
317 | +1 |
318 | +1 |
319 | +SET SESSION query_exec_time=0.39; |
320 | +SELECT 1; |
321 | +1 |
322 | +1 |
323 | +SET SESSION query_exec_time=0.4; |
324 | +SELECT 1; |
325 | +1 |
326 | +1 |
327 | +SET SESSION query_exec_time=1.1; |
328 | +SELECT 1; |
329 | +1 |
330 | +1 |
331 | +SET SESSION query_exec_time=1.2; |
332 | +SELECT 1; |
333 | +1 |
334 | +1 |
335 | +SET SESSION query_exec_time=1.3; |
336 | +SELECT 1; |
337 | +1 |
338 | +1 |
339 | +SET SESSION query_exec_time=1.5; |
340 | +SELECT 1; |
341 | +1 |
342 | +1 |
343 | +SET SESSION query_exec_time=1.4; |
344 | +SELECT 1; |
345 | +1 |
346 | +1 |
347 | +SET SESSION query_exec_time=0.5; |
348 | +SELECT 1; |
349 | +1 |
350 | +1 |
351 | +SET SESSION query_exec_time=2.1; |
352 | +SELECT 1; |
353 | +1 |
354 | +1 |
355 | +SET SESSION query_exec_time=2.3; |
356 | +SELECT 1; |
357 | +1 |
358 | +1 |
359 | +SET SESSION query_exec_time=2.5; |
360 | +SELECT 1; |
361 | +1 |
362 | +1 |
363 | +SET SESSION query_exec_time=3.1; |
364 | +SELECT 1; |
365 | +1 |
366 | +1 |
367 | +SET SESSION query_exec_time=4.1; |
368 | +SELECT 1; |
369 | +1 |
370 | +1 |
371 | +SET SESSION query_exec_time=5.1; |
372 | +SELECT 1; |
373 | +1 |
374 | +1 |
375 | +SET SESSION query_exec_time=0.1; |
376 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; |
377 | +SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; |
378 | +Variable_name Value |
379 | +query_response_time_range_base 2 |
380 | +SHOW QUERY_RESPONSE_TIME; |
381 | + |
382 | + 0.000001 24 0.000000 |
383 | + 0.000003 0 0.000000 |
384 | + 0.000007 0 0.000000 |
385 | + 0.000015 0 0.000000 |
386 | + 0.000030 0 0.000000 |
387 | + 0.000061 0 0.000000 |
388 | + 0.000122 0 0.000000 |
389 | + 0.000244 0 0.000000 |
390 | + 0.000488 0 0.000000 |
391 | + 0.000976 0 0.000000 |
392 | + 0.001953 0 0.000000 |
393 | + 0.003906 0 0.000000 |
394 | + 0.007812 0 0.000000 |
395 | + 0.015625 0 0.000000 |
396 | + 0.031250 0 0.000000 |
397 | + 0.062500 0 0.000000 |
398 | + 0.125000 0 0.000000 |
399 | + 0.250000 0 0.000000 |
400 | + 0.500000 10 3.550000 |
401 | + 1.000000 1 0.500000 |
402 | + 2.000000 5 6.500000 |
403 | + 4.000000 4 10.000000 |
404 | + 8.000000 2 9.199999 |
405 | + 16.000000 0 0.000000 |
406 | + 32.000000 0 0.000000 |
407 | + 64.000000 0 0.000000 |
408 | + 128.000000 0 0.000000 |
409 | + 256.000000 0 0.000000 |
410 | + 512.000000 0 0.000000 |
411 | + 1024.000000 0 0.000000 |
412 | + 2048.000000 0 0.000000 |
413 | + 4096.000000 0 0.000000 |
414 | + 8192.000000 0 0.000000 |
415 | + 16384.000000 0 0.000000 |
416 | + 32768.000000 0 0.000000 |
417 | + 65536.000000 0 0.000000 |
418 | + 131072.000000 0 0.000000 |
419 | + 262144.000000 0 0.000000 |
420 | + 524288.000000 0 0.000000 |
421 | +1048576.000000 0 0.000000 |
422 | +2097152.000000 0 0.000000 |
423 | +4194304.000000 0 0.000000 |
424 | +8388608.000000 0 0.000000 |
425 | +TOO LONG 0 TOO LONG |
426 | +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; |
427 | +time count total |
428 | + 0.000001 24 0.000000 |
429 | + 0.000003 0 0.000000 |
430 | + 0.000007 0 0.000000 |
431 | + 0.000015 0 0.000000 |
432 | + 0.000030 0 0.000000 |
433 | + 0.000061 0 0.000000 |
434 | + 0.000122 0 0.000000 |
435 | + 0.000244 0 0.000000 |
436 | + 0.000488 0 0.000000 |
437 | + 0.000976 0 0.000000 |
438 | + 0.001953 0 0.000000 |
439 | + 0.003906 0 0.000000 |
440 | + 0.007812 0 0.000000 |
441 | + 0.015625 0 0.000000 |
442 | + 0.031250 0 0.000000 |
443 | + 0.062500 0 0.000000 |
444 | + 0.125000 0 0.000000 |
445 | + 0.250000 0 0.000000 |
446 | + 0.500000 10 3.550000 |
447 | + 1.000000 1 0.500000 |
448 | + 2.000000 5 6.500000 |
449 | + 4.000000 4 10.000000 |
450 | + 8.000000 2 9.199999 |
451 | + 16.000000 0 0.000000 |
452 | + 32.000000 0 0.000000 |
453 | + 64.000000 0 0.000000 |
454 | + 128.000000 0 0.000000 |
455 | + 256.000000 0 0.000000 |
456 | + 512.000000 0 0.000000 |
457 | + 1024.000000 0 0.000000 |
458 | + 2048.000000 0 0.000000 |
459 | + 4096.000000 0 0.000000 |
460 | + 8192.000000 0 0.000000 |
461 | + 16384.000000 0 0.000000 |
462 | + 32768.000000 0 0.000000 |
463 | + 65536.000000 0 0.000000 |
464 | + 131072.000000 0 0.000000 |
465 | + 262144.000000 0 0.000000 |
466 | + 524288.000000 0 0.000000 |
467 | +1048576.000000 0 0.000000 |
468 | +2097152.000000 0 0.000000 |
469 | +4194304.000000 0 0.000000 |
470 | +8388608.000000 0 0.000000 |
471 | +TOO LONG 0 TOO LONG |
472 | +SET SESSION query_exec_time=default; |
473 | +SET SESSION query_exec_time=0.1; |
474 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; |
475 | +SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=2; |
476 | +FLUSH QUERY_RESPONSE_TIME; |
477 | +SHOW QUERY_RESPONSE_TIME; |
478 | + |
479 | + 0.000001 0 0.000000 |
480 | + 0.000003 0 0.000000 |
481 | + 0.000007 0 0.000000 |
482 | + 0.000015 0 0.000000 |
483 | + 0.000030 0 0.000000 |
484 | + 0.000061 0 0.000000 |
485 | + 0.000122 0 0.000000 |
486 | + 0.000244 0 0.000000 |
487 | + 0.000488 0 0.000000 |
488 | + 0.000976 0 0.000000 |
489 | + 0.001953 0 0.000000 |
490 | + 0.003906 0 0.000000 |
491 | + 0.007812 0 0.000000 |
492 | + 0.015625 0 0.000000 |
493 | + 0.031250 0 0.000000 |
494 | + 0.062500 0 0.000000 |
495 | + 0.125000 0 0.000000 |
496 | + 0.250000 0 0.000000 |
497 | + 0.500000 0 0.000000 |
498 | + 1.000000 0 0.000000 |
499 | + 2.000000 0 0.000000 |
500 | + 4.000000 0 0.000000 |
501 | + 8.000000 0 0.000000 |
502 | + 16.000000 0 0.000000 |
503 | + 32.000000 0 0.000000 |
504 | + 64.000000 0 0.000000 |
505 | + 128.000000 0 0.000000 |
506 | + 256.000000 0 0.000000 |
507 | + 512.000000 0 0.000000 |
508 | + 1024.000000 0 0.000000 |
509 | + 2048.000000 0 0.000000 |
510 | + 4096.000000 0 0.000000 |
511 | + 8192.000000 0 0.000000 |
512 | + 16384.000000 0 0.000000 |
513 | + 32768.000000 0 0.000000 |
514 | + 65536.000000 0 0.000000 |
515 | + 131072.000000 0 0.000000 |
516 | + 262144.000000 0 0.000000 |
517 | + 524288.000000 0 0.000000 |
518 | +1048576.000000 0 0.000000 |
519 | +2097152.000000 0 0.000000 |
520 | +4194304.000000 0 0.000000 |
521 | +8388608.000000 0 0.000000 |
522 | +TOO LONG 0 TOO LONG |
523 | +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; |
524 | +time count total |
525 | + 0.000001 0 0.000000 |
526 | + 0.000003 0 0.000000 |
527 | + 0.000007 0 0.000000 |
528 | + 0.000015 0 0.000000 |
529 | + 0.000030 0 0.000000 |
530 | + 0.000061 0 0.000000 |
531 | + 0.000122 0 0.000000 |
532 | + 0.000244 0 0.000000 |
533 | + 0.000488 0 0.000000 |
534 | + 0.000976 0 0.000000 |
535 | + 0.001953 0 0.000000 |
536 | + 0.003906 0 0.000000 |
537 | + 0.007812 0 0.000000 |
538 | + 0.015625 0 0.000000 |
539 | + 0.031250 0 0.000000 |
540 | + 0.062500 0 0.000000 |
541 | + 0.125000 0 0.000000 |
542 | + 0.250000 0 0.000000 |
543 | + 0.500000 0 0.000000 |
544 | + 1.000000 0 0.000000 |
545 | + 2.000000 0 0.000000 |
546 | + 4.000000 0 0.000000 |
547 | + 8.000000 0 0.000000 |
548 | + 16.000000 0 0.000000 |
549 | + 32.000000 0 0.000000 |
550 | + 64.000000 0 0.000000 |
551 | + 128.000000 0 0.000000 |
552 | + 256.000000 0 0.000000 |
553 | + 512.000000 0 0.000000 |
554 | + 1024.000000 0 0.000000 |
555 | + 2048.000000 0 0.000000 |
556 | + 4096.000000 0 0.000000 |
557 | + 8192.000000 0 0.000000 |
558 | + 16384.000000 0 0.000000 |
559 | + 32768.000000 0 0.000000 |
560 | + 65536.000000 0 0.000000 |
561 | + 131072.000000 0 0.000000 |
562 | + 262144.000000 0 0.000000 |
563 | + 524288.000000 0 0.000000 |
564 | +1048576.000000 0 0.000000 |
565 | +2097152.000000 0 0.000000 |
566 | +4194304.000000 0 0.000000 |
567 | +8388608.000000 0 0.000000 |
568 | +TOO LONG 0 TOO LONG |
569 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; |
570 | +SET SESSION query_exec_time=0.31; |
571 | +SELECT 1; |
572 | +1 |
573 | +1 |
574 | +SET SESSION query_exec_time=0.32; |
575 | +SELECT 1; |
576 | +1 |
577 | +1 |
578 | +SET SESSION query_exec_time=0.33; |
579 | +SELECT 1; |
580 | +1 |
581 | +1 |
582 | +SET SESSION query_exec_time=0.34; |
583 | +SELECT 1; |
584 | +1 |
585 | +1 |
586 | +SET SESSION query_exec_time=0.35; |
587 | +SELECT 1; |
588 | +1 |
589 | +1 |
590 | +SET SESSION query_exec_time=0.36; |
591 | +SELECT 1; |
592 | +1 |
593 | +1 |
594 | +SET SESSION query_exec_time=0.37; |
595 | +SELECT 1; |
596 | +1 |
597 | +1 |
598 | +SET SESSION query_exec_time=0.38; |
599 | +SELECT 1; |
600 | +1 |
601 | +1 |
602 | +SET SESSION query_exec_time=0.39; |
603 | +SELECT 1; |
604 | +1 |
605 | +1 |
606 | +SET SESSION query_exec_time=0.4; |
607 | +SELECT 1; |
608 | +1 |
609 | +1 |
610 | +SET SESSION query_exec_time=1.1; |
611 | +SELECT 1; |
612 | +1 |
613 | +1 |
614 | +SET SESSION query_exec_time=1.2; |
615 | +SELECT 1; |
616 | +1 |
617 | +1 |
618 | +SET SESSION query_exec_time=1.3; |
619 | +SELECT 1; |
620 | +1 |
621 | +1 |
622 | +SET SESSION query_exec_time=1.5; |
623 | +SELECT 1; |
624 | +1 |
625 | +1 |
626 | +SET SESSION query_exec_time=1.4; |
627 | +SELECT 1; |
628 | +1 |
629 | +1 |
630 | +SET SESSION query_exec_time=0.5; |
631 | +SELECT 1; |
632 | +1 |
633 | +1 |
634 | +SET SESSION query_exec_time=2.1; |
635 | +SELECT 1; |
636 | +1 |
637 | +1 |
638 | +SET SESSION query_exec_time=2.3; |
639 | +SELECT 1; |
640 | +1 |
641 | +1 |
642 | +SET SESSION query_exec_time=2.5; |
643 | +SELECT 1; |
644 | +1 |
645 | +1 |
646 | +SET SESSION query_exec_time=3.1; |
647 | +SELECT 1; |
648 | +1 |
649 | +1 |
650 | +SET SESSION query_exec_time=4.1; |
651 | +SELECT 1; |
652 | +1 |
653 | +1 |
654 | +SET SESSION query_exec_time=5.1; |
655 | +SELECT 1; |
656 | +1 |
657 | +1 |
658 | +SET SESSION query_exec_time=0.1; |
659 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; |
660 | +SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; |
661 | +Variable_name Value |
662 | +query_response_time_range_base 2 |
663 | +SHOW QUERY_RESPONSE_TIME; |
664 | + |
665 | + 0.000001 24 0.000000 |
666 | + 0.000003 0 0.000000 |
667 | + 0.000007 0 0.000000 |
668 | + 0.000015 0 0.000000 |
669 | + 0.000030 0 0.000000 |
670 | + 0.000061 0 0.000000 |
671 | + 0.000122 0 0.000000 |
672 | + 0.000244 0 0.000000 |
673 | + 0.000488 0 0.000000 |
674 | + 0.000976 0 0.000000 |
675 | + 0.001953 0 0.000000 |
676 | + 0.003906 0 0.000000 |
677 | + 0.007812 0 0.000000 |
678 | + 0.015625 0 0.000000 |
679 | + 0.031250 0 0.000000 |
680 | + 0.062500 0 0.000000 |
681 | + 0.125000 0 0.000000 |
682 | + 0.250000 0 0.000000 |
683 | + 0.500000 10 3.550000 |
684 | + 1.000000 1 0.500000 |
685 | + 2.000000 5 6.500000 |
686 | + 4.000000 4 10.000000 |
687 | + 8.000000 2 9.199999 |
688 | + 16.000000 0 0.000000 |
689 | + 32.000000 0 0.000000 |
690 | + 64.000000 0 0.000000 |
691 | + 128.000000 0 0.000000 |
692 | + 256.000000 0 0.000000 |
693 | + 512.000000 0 0.000000 |
694 | + 1024.000000 0 0.000000 |
695 | + 2048.000000 0 0.000000 |
696 | + 4096.000000 0 0.000000 |
697 | + 8192.000000 0 0.000000 |
698 | + 16384.000000 0 0.000000 |
699 | + 32768.000000 0 0.000000 |
700 | + 65536.000000 0 0.000000 |
701 | + 131072.000000 0 0.000000 |
702 | + 262144.000000 0 0.000000 |
703 | + 524288.000000 0 0.000000 |
704 | +1048576.000000 0 0.000000 |
705 | +2097152.000000 0 0.000000 |
706 | +4194304.000000 0 0.000000 |
707 | +8388608.000000 0 0.000000 |
708 | +TOO LONG 0 TOO LONG |
709 | +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; |
710 | +time count total |
711 | + 0.000001 24 0.000000 |
712 | + 0.000003 0 0.000000 |
713 | + 0.000007 0 0.000000 |
714 | + 0.000015 0 0.000000 |
715 | + 0.000030 0 0.000000 |
716 | + 0.000061 0 0.000000 |
717 | + 0.000122 0 0.000000 |
718 | + 0.000244 0 0.000000 |
719 | + 0.000488 0 0.000000 |
720 | + 0.000976 0 0.000000 |
721 | + 0.001953 0 0.000000 |
722 | + 0.003906 0 0.000000 |
723 | + 0.007812 0 0.000000 |
724 | + 0.015625 0 0.000000 |
725 | + 0.031250 0 0.000000 |
726 | + 0.062500 0 0.000000 |
727 | + 0.125000 0 0.000000 |
728 | + 0.250000 0 0.000000 |
729 | + 0.500000 10 3.550000 |
730 | + 1.000000 1 0.500000 |
731 | + 2.000000 5 6.500000 |
732 | + 4.000000 4 10.000000 |
733 | + 8.000000 2 9.199999 |
734 | + 16.000000 0 0.000000 |
735 | + 32.000000 0 0.000000 |
736 | + 64.000000 0 0.000000 |
737 | + 128.000000 0 0.000000 |
738 | + 256.000000 0 0.000000 |
739 | + 512.000000 0 0.000000 |
740 | + 1024.000000 0 0.000000 |
741 | + 2048.000000 0 0.000000 |
742 | + 4096.000000 0 0.000000 |
743 | + 8192.000000 0 0.000000 |
744 | + 16384.000000 0 0.000000 |
745 | + 32768.000000 0 0.000000 |
746 | + 65536.000000 0 0.000000 |
747 | + 131072.000000 0 0.000000 |
748 | + 262144.000000 0 0.000000 |
749 | + 524288.000000 0 0.000000 |
750 | +1048576.000000 0 0.000000 |
751 | +2097152.000000 0 0.000000 |
752 | +4194304.000000 0 0.000000 |
753 | +8388608.000000 0 0.000000 |
754 | +TOO LONG 0 TOO LONG |
755 | +SET SESSION query_exec_time=default; |
756 | +SET SESSION query_exec_time=0.1; |
757 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; |
758 | +SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=10; |
759 | +FLUSH QUERY_RESPONSE_TIME; |
760 | +SHOW QUERY_RESPONSE_TIME; |
761 | + |
762 | + 0.000001 0 0.000000 |
763 | + 0.000010 0 0.000000 |
764 | + 0.000100 0 0.000000 |
765 | + 0.001000 0 0.000000 |
766 | + 0.010000 0 0.000000 |
767 | + 0.100000 0 0.000000 |
768 | + 1.000000 0 0.000000 |
769 | + 10.000000 0 0.000000 |
770 | + 100.000000 0 0.000000 |
771 | + 1000.000000 0 0.000000 |
772 | + 10000.000000 0 0.000000 |
773 | + 100000.000000 0 0.000000 |
774 | +1000000.000000 0 0.000000 |
775 | +TOO LONG 0 TOO LONG |
776 | +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; |
777 | +time count total |
778 | + 0.000001 0 0.000000 |
779 | + 0.000010 0 0.000000 |
780 | + 0.000100 0 0.000000 |
781 | + 0.001000 0 0.000000 |
782 | + 0.010000 0 0.000000 |
783 | + 0.100000 0 0.000000 |
784 | + 1.000000 0 0.000000 |
785 | + 10.000000 0 0.000000 |
786 | + 100.000000 0 0.000000 |
787 | + 1000.000000 0 0.000000 |
788 | + 10000.000000 0 0.000000 |
789 | + 100000.000000 0 0.000000 |
790 | +1000000.000000 0 0.000000 |
791 | +TOO LONG 0 TOO LONG |
792 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; |
793 | +SET SESSION query_exec_time=0.31; |
794 | +SELECT 1; |
795 | +1 |
796 | +1 |
797 | +SET SESSION query_exec_time=0.32; |
798 | +SELECT 1; |
799 | +1 |
800 | +1 |
801 | +SET SESSION query_exec_time=0.33; |
802 | +SELECT 1; |
803 | +1 |
804 | +1 |
805 | +SET SESSION query_exec_time=0.34; |
806 | +SELECT 1; |
807 | +1 |
808 | +1 |
809 | +SET SESSION query_exec_time=0.35; |
810 | +SELECT 1; |
811 | +1 |
812 | +1 |
813 | +SET SESSION query_exec_time=0.36; |
814 | +SELECT 1; |
815 | +1 |
816 | +1 |
817 | +SET SESSION query_exec_time=0.37; |
818 | +SELECT 1; |
819 | +1 |
820 | +1 |
821 | +SET SESSION query_exec_time=0.38; |
822 | +SELECT 1; |
823 | +1 |
824 | +1 |
825 | +SET SESSION query_exec_time=0.39; |
826 | +SELECT 1; |
827 | +1 |
828 | +1 |
829 | +SET SESSION query_exec_time=0.4; |
830 | +SELECT 1; |
831 | +1 |
832 | +1 |
833 | +SET SESSION query_exec_time=1.1; |
834 | +SELECT 1; |
835 | +1 |
836 | +1 |
837 | +SET SESSION query_exec_time=1.2; |
838 | +SELECT 1; |
839 | +1 |
840 | +1 |
841 | +SET SESSION query_exec_time=1.3; |
842 | +SELECT 1; |
843 | +1 |
844 | +1 |
845 | +SET SESSION query_exec_time=1.5; |
846 | +SELECT 1; |
847 | +1 |
848 | +1 |
849 | +SET SESSION query_exec_time=1.4; |
850 | +SELECT 1; |
851 | +1 |
852 | +1 |
853 | +SET SESSION query_exec_time=0.5; |
854 | +SELECT 1; |
855 | +1 |
856 | +1 |
857 | +SET SESSION query_exec_time=2.1; |
858 | +SELECT 1; |
859 | +1 |
860 | +1 |
861 | +SET SESSION query_exec_time=2.3; |
862 | +SELECT 1; |
863 | +1 |
864 | +1 |
865 | +SET SESSION query_exec_time=2.5; |
866 | +SELECT 1; |
867 | +1 |
868 | +1 |
869 | +SET SESSION query_exec_time=3.1; |
870 | +SELECT 1; |
871 | +1 |
872 | +1 |
873 | +SET SESSION query_exec_time=4.1; |
874 | +SELECT 1; |
875 | +1 |
876 | +1 |
877 | +SET SESSION query_exec_time=5.1; |
878 | +SELECT 1; |
879 | +1 |
880 | +1 |
881 | +SET SESSION query_exec_time=0.1; |
882 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; |
883 | +SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; |
884 | +Variable_name Value |
885 | +query_response_time_range_base 10 |
886 | +SHOW QUERY_RESPONSE_TIME; |
887 | + |
888 | + 0.000001 24 0.000000 |
889 | + 0.000010 0 0.000000 |
890 | + 0.000100 0 0.000000 |
891 | + 0.001000 0 0.000000 |
892 | + 0.010000 0 0.000000 |
893 | + 0.100000 0 0.000000 |
894 | + 1.000000 11 4.050000 |
895 | + 10.000000 11 25.699999 |
896 | + 100.000000 0 0.000000 |
897 | + 1000.000000 0 0.000000 |
898 | + 10000.000000 0 0.000000 |
899 | + 100000.000000 0 0.000000 |
900 | +1000000.000000 0 0.000000 |
901 | +TOO LONG 0 TOO LONG |
902 | +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; |
903 | +time count total |
904 | + 0.000001 24 0.000000 |
905 | + 0.000010 0 0.000000 |
906 | + 0.000100 0 0.000000 |
907 | + 0.001000 0 0.000000 |
908 | + 0.010000 0 0.000000 |
909 | + 0.100000 0 0.000000 |
910 | + 1.000000 11 4.050000 |
911 | + 10.000000 11 25.699999 |
912 | + 100.000000 0 0.000000 |
913 | + 1000.000000 0 0.000000 |
914 | + 10000.000000 0 0.000000 |
915 | + 100000.000000 0 0.000000 |
916 | +1000000.000000 0 0.000000 |
917 | +TOO LONG 0 TOO LONG |
918 | +SET SESSION query_exec_time=default; |
919 | +SET SESSION query_exec_time=0.1; |
920 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; |
921 | +SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=7; |
922 | +FLUSH QUERY_RESPONSE_TIME; |
923 | +SHOW QUERY_RESPONSE_TIME; |
924 | + |
925 | + 0.000001 0 0.000000 |
926 | + 0.000008 0 0.000000 |
927 | + 0.000059 0 0.000000 |
928 | + 0.000416 0 0.000000 |
929 | + 0.002915 0 0.000000 |
930 | + 0.020408 0 0.000000 |
931 | + 0.142857 0 0.000000 |
932 | + 1.000000 0 0.000000 |
933 | + 7.000000 0 0.000000 |
934 | + 49.000000 0 0.000000 |
935 | + 343.000000 0 0.000000 |
936 | + 2401.000000 0 0.000000 |
937 | + 16807.000000 0 0.000000 |
938 | + 117649.000000 0 0.000000 |
939 | + 823543.000000 0 0.000000 |
940 | +5764801.000000 0 0.000000 |
941 | +TOO LONG 0 TOO LONG |
942 | +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; |
943 | +time count total |
944 | + 0.000001 0 0.000000 |
945 | + 0.000008 0 0.000000 |
946 | + 0.000059 0 0.000000 |
947 | + 0.000416 0 0.000000 |
948 | + 0.002915 0 0.000000 |
949 | + 0.020408 0 0.000000 |
950 | + 0.142857 0 0.000000 |
951 | + 1.000000 0 0.000000 |
952 | + 7.000000 0 0.000000 |
953 | + 49.000000 0 0.000000 |
954 | + 343.000000 0 0.000000 |
955 | + 2401.000000 0 0.000000 |
956 | + 16807.000000 0 0.000000 |
957 | + 117649.000000 0 0.000000 |
958 | + 823543.000000 0 0.000000 |
959 | +5764801.000000 0 0.000000 |
960 | +TOO LONG 0 TOO LONG |
961 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; |
962 | +SET SESSION query_exec_time=0.31; |
963 | +SELECT 1; |
964 | +1 |
965 | +1 |
966 | +SET SESSION query_exec_time=0.32; |
967 | +SELECT 1; |
968 | +1 |
969 | +1 |
970 | +SET SESSION query_exec_time=0.33; |
971 | +SELECT 1; |
972 | +1 |
973 | +1 |
974 | +SET SESSION query_exec_time=0.34; |
975 | +SELECT 1; |
976 | +1 |
977 | +1 |
978 | +SET SESSION query_exec_time=0.35; |
979 | +SELECT 1; |
980 | +1 |
981 | +1 |
982 | +SET SESSION query_exec_time=0.36; |
983 | +SELECT 1; |
984 | +1 |
985 | +1 |
986 | +SET SESSION query_exec_time=0.37; |
987 | +SELECT 1; |
988 | +1 |
989 | +1 |
990 | +SET SESSION query_exec_time=0.38; |
991 | +SELECT 1; |
992 | +1 |
993 | +1 |
994 | +SET SESSION query_exec_time=0.39; |
995 | +SELECT 1; |
996 | +1 |
997 | +1 |
998 | +SET SESSION query_exec_time=0.4; |
999 | +SELECT 1; |
1000 | +1 |
1001 | +1 |
1002 | +SET SESSION query_exec_time=1.1; |
1003 | +SELECT 1; |
1004 | +1 |
1005 | +1 |
1006 | +SET SESSION query_exec_time=1.2; |
1007 | +SELECT 1; |
1008 | +1 |
1009 | +1 |
1010 | +SET SESSION query_exec_time=1.3; |
1011 | +SELECT 1; |
1012 | +1 |
1013 | +1 |
1014 | +SET SESSION query_exec_time=1.5; |
1015 | +SELECT 1; |
1016 | +1 |
1017 | +1 |
1018 | +SET SESSION query_exec_time=1.4; |
1019 | +SELECT 1; |
1020 | +1 |
1021 | +1 |
1022 | +SET SESSION query_exec_time=0.5; |
1023 | +SELECT 1; |
1024 | +1 |
1025 | +1 |
1026 | +SET SESSION query_exec_time=2.1; |
1027 | +SELECT 1; |
1028 | +1 |
1029 | +1 |
1030 | +SET SESSION query_exec_time=2.3; |
1031 | +SELECT 1; |
1032 | +1 |
1033 | +1 |
1034 | +SET SESSION query_exec_time=2.5; |
1035 | +SELECT 1; |
1036 | +1 |
1037 | +1 |
1038 | +SET SESSION query_exec_time=3.1; |
1039 | +SELECT 1; |
1040 | +1 |
1041 | +1 |
1042 | +SET SESSION query_exec_time=4.1; |
1043 | +SELECT 1; |
1044 | +1 |
1045 | +1 |
1046 | +SET SESSION query_exec_time=5.1; |
1047 | +SELECT 1; |
1048 | +1 |
1049 | +1 |
1050 | +SET SESSION query_exec_time=0.1; |
1051 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; |
1052 | +SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; |
1053 | +Variable_name Value |
1054 | +query_response_time_range_base 7 |
1055 | +SHOW QUERY_RESPONSE_TIME; |
1056 | + |
1057 | + 0.000001 24 0.000000 |
1058 | + 0.000008 0 0.000000 |
1059 | + 0.000059 0 0.000000 |
1060 | + 0.000416 0 0.000000 |
1061 | + 0.002915 0 0.000000 |
1062 | + 0.020408 0 0.000000 |
1063 | + 0.142857 0 0.000000 |
1064 | + 1.000000 11 4.050000 |
1065 | + 7.000000 11 25.699999 |
1066 | + 49.000000 0 0.000000 |
1067 | + 343.000000 0 0.000000 |
1068 | + 2401.000000 0 0.000000 |
1069 | + 16807.000000 0 0.000000 |
1070 | + 117649.000000 0 0.000000 |
1071 | + 823543.000000 0 0.000000 |
1072 | +5764801.000000 0 0.000000 |
1073 | +TOO LONG 0 TOO LONG |
1074 | +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; |
1075 | +time count total |
1076 | + 0.000001 24 0.000000 |
1077 | + 0.000008 0 0.000000 |
1078 | + 0.000059 0 0.000000 |
1079 | + 0.000416 0 0.000000 |
1080 | + 0.002915 0 0.000000 |
1081 | + 0.020408 0 0.000000 |
1082 | + 0.142857 0 0.000000 |
1083 | + 1.000000 11 4.050000 |
1084 | + 7.000000 11 25.699999 |
1085 | + 49.000000 0 0.000000 |
1086 | + 343.000000 0 0.000000 |
1087 | + 2401.000000 0 0.000000 |
1088 | + 16807.000000 0 0.000000 |
1089 | + 117649.000000 0 0.000000 |
1090 | + 823543.000000 0 0.000000 |
1091 | +5764801.000000 0 0.000000 |
1092 | +TOO LONG 0 TOO LONG |
1093 | +SET SESSION query_exec_time=default; |
1094 | +SET SESSION query_exec_time=0.1; |
1095 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; |
1096 | +SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=156; |
1097 | +FLUSH QUERY_RESPONSE_TIME; |
1098 | +SHOW QUERY_RESPONSE_TIME; |
1099 | + |
1100 | + 0.000041 0 0.000000 |
1101 | + 0.006410 0 0.000000 |
1102 | + 1.000000 0 0.000000 |
1103 | + 156.000000 0 0.000000 |
1104 | + 24336.000000 0 0.000000 |
1105 | +3796416.000000 0 0.000000 |
1106 | +TOO LONG 0 TOO LONG |
1107 | +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; |
1108 | +time count total |
1109 | + 0.000041 0 0.000000 |
1110 | + 0.006410 0 0.000000 |
1111 | + 1.000000 0 0.000000 |
1112 | + 156.000000 0 0.000000 |
1113 | + 24336.000000 0 0.000000 |
1114 | +3796416.000000 0 0.000000 |
1115 | +TOO LONG 0 TOO LONG |
1116 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; |
1117 | +SET SESSION query_exec_time=0.31; |
1118 | +SELECT 1; |
1119 | +1 |
1120 | +1 |
1121 | +SET SESSION query_exec_time=0.32; |
1122 | +SELECT 1; |
1123 | +1 |
1124 | +1 |
1125 | +SET SESSION query_exec_time=0.33; |
1126 | +SELECT 1; |
1127 | +1 |
1128 | +1 |
1129 | +SET SESSION query_exec_time=0.34; |
1130 | +SELECT 1; |
1131 | +1 |
1132 | +1 |
1133 | +SET SESSION query_exec_time=0.35; |
1134 | +SELECT 1; |
1135 | +1 |
1136 | +1 |
1137 | +SET SESSION query_exec_time=0.36; |
1138 | +SELECT 1; |
1139 | +1 |
1140 | +1 |
1141 | +SET SESSION query_exec_time=0.37; |
1142 | +SELECT 1; |
1143 | +1 |
1144 | +1 |
1145 | +SET SESSION query_exec_time=0.38; |
1146 | +SELECT 1; |
1147 | +1 |
1148 | +1 |
1149 | +SET SESSION query_exec_time=0.39; |
1150 | +SELECT 1; |
1151 | +1 |
1152 | +1 |
1153 | +SET SESSION query_exec_time=0.4; |
1154 | +SELECT 1; |
1155 | +1 |
1156 | +1 |
1157 | +SET SESSION query_exec_time=1.1; |
1158 | +SELECT 1; |
1159 | +1 |
1160 | +1 |
1161 | +SET SESSION query_exec_time=1.2; |
1162 | +SELECT 1; |
1163 | +1 |
1164 | +1 |
1165 | +SET SESSION query_exec_time=1.3; |
1166 | +SELECT 1; |
1167 | +1 |
1168 | +1 |
1169 | +SET SESSION query_exec_time=1.5; |
1170 | +SELECT 1; |
1171 | +1 |
1172 | +1 |
1173 | +SET SESSION query_exec_time=1.4; |
1174 | +SELECT 1; |
1175 | +1 |
1176 | +1 |
1177 | +SET SESSION query_exec_time=0.5; |
1178 | +SELECT 1; |
1179 | +1 |
1180 | +1 |
1181 | +SET SESSION query_exec_time=2.1; |
1182 | +SELECT 1; |
1183 | +1 |
1184 | +1 |
1185 | +SET SESSION query_exec_time=2.3; |
1186 | +SELECT 1; |
1187 | +1 |
1188 | +1 |
1189 | +SET SESSION query_exec_time=2.5; |
1190 | +SELECT 1; |
1191 | +1 |
1192 | +1 |
1193 | +SET SESSION query_exec_time=3.1; |
1194 | +SELECT 1; |
1195 | +1 |
1196 | +1 |
1197 | +SET SESSION query_exec_time=4.1; |
1198 | +SELECT 1; |
1199 | +1 |
1200 | +1 |
1201 | +SET SESSION query_exec_time=5.1; |
1202 | +SELECT 1; |
1203 | +1 |
1204 | +1 |
1205 | +SET SESSION query_exec_time=0.1; |
1206 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; |
1207 | +SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; |
1208 | +Variable_name Value |
1209 | +query_response_time_range_base 156 |
1210 | +SHOW QUERY_RESPONSE_TIME; |
1211 | + |
1212 | + 0.000041 24 0.000000 |
1213 | + 0.006410 0 0.000000 |
1214 | + 1.000000 11 4.050000 |
1215 | + 156.000000 11 25.699999 |
1216 | + 24336.000000 0 0.000000 |
1217 | +3796416.000000 0 0.000000 |
1218 | +TOO LONG 0 TOO LONG |
1219 | +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; |
1220 | +time count total |
1221 | + 0.000041 24 0.000000 |
1222 | + 0.006410 0 0.000000 |
1223 | + 1.000000 11 4.050000 |
1224 | + 156.000000 11 25.699999 |
1225 | + 24336.000000 0 0.000000 |
1226 | +3796416.000000 0 0.000000 |
1227 | +TOO LONG 0 TOO LONG |
1228 | +SET SESSION query_exec_time=default; |
1229 | +SET SESSION query_exec_time=0.1; |
1230 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; |
1231 | +SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=1000; |
1232 | +FLUSH QUERY_RESPONSE_TIME; |
1233 | +SHOW QUERY_RESPONSE_TIME; |
1234 | + |
1235 | + 0.000001 0 0.000000 |
1236 | + 0.001000 0 0.000000 |
1237 | + 1.000000 0 0.000000 |
1238 | + 1000.000000 0 0.000000 |
1239 | +1000000.000000 0 0.000000 |
1240 | +TOO LONG 0 TOO LONG |
1241 | +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; |
1242 | +time count total |
1243 | + 0.000001 0 0.000000 |
1244 | + 0.001000 0 0.000000 |
1245 | + 1.000000 0 0.000000 |
1246 | + 1000.000000 0 0.000000 |
1247 | +1000000.000000 0 0.000000 |
1248 | +TOO LONG 0 TOO LONG |
1249 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; |
1250 | +SET SESSION query_exec_time=0.31; |
1251 | +SELECT 1; |
1252 | +1 |
1253 | +1 |
1254 | +SET SESSION query_exec_time=0.32; |
1255 | +SELECT 1; |
1256 | +1 |
1257 | +1 |
1258 | +SET SESSION query_exec_time=0.33; |
1259 | +SELECT 1; |
1260 | +1 |
1261 | +1 |
1262 | +SET SESSION query_exec_time=0.34; |
1263 | +SELECT 1; |
1264 | +1 |
1265 | +1 |
1266 | +SET SESSION query_exec_time=0.35; |
1267 | +SELECT 1; |
1268 | +1 |
1269 | +1 |
1270 | +SET SESSION query_exec_time=0.36; |
1271 | +SELECT 1; |
1272 | +1 |
1273 | +1 |
1274 | +SET SESSION query_exec_time=0.37; |
1275 | +SELECT 1; |
1276 | +1 |
1277 | +1 |
1278 | +SET SESSION query_exec_time=0.38; |
1279 | +SELECT 1; |
1280 | +1 |
1281 | +1 |
1282 | +SET SESSION query_exec_time=0.39; |
1283 | +SELECT 1; |
1284 | +1 |
1285 | +1 |
1286 | +SET SESSION query_exec_time=0.4; |
1287 | +SELECT 1; |
1288 | +1 |
1289 | +1 |
1290 | +SET SESSION query_exec_time=1.1; |
1291 | +SELECT 1; |
1292 | +1 |
1293 | +1 |
1294 | +SET SESSION query_exec_time=1.2; |
1295 | +SELECT 1; |
1296 | +1 |
1297 | +1 |
1298 | +SET SESSION query_exec_time=1.3; |
1299 | +SELECT 1; |
1300 | +1 |
1301 | +1 |
1302 | +SET SESSION query_exec_time=1.5; |
1303 | +SELECT 1; |
1304 | +1 |
1305 | +1 |
1306 | +SET SESSION query_exec_time=1.4; |
1307 | +SELECT 1; |
1308 | +1 |
1309 | +1 |
1310 | +SET SESSION query_exec_time=0.5; |
1311 | +SELECT 1; |
1312 | +1 |
1313 | +1 |
1314 | +SET SESSION query_exec_time=2.1; |
1315 | +SELECT 1; |
1316 | +1 |
1317 | +1 |
1318 | +SET SESSION query_exec_time=2.3; |
1319 | +SELECT 1; |
1320 | +1 |
1321 | +1 |
1322 | +SET SESSION query_exec_time=2.5; |
1323 | +SELECT 1; |
1324 | +1 |
1325 | +1 |
1326 | +SET SESSION query_exec_time=3.1; |
1327 | +SELECT 1; |
1328 | +1 |
1329 | +1 |
1330 | +SET SESSION query_exec_time=4.1; |
1331 | +SELECT 1; |
1332 | +1 |
1333 | +1 |
1334 | +SET SESSION query_exec_time=5.1; |
1335 | +SELECT 1; |
1336 | +1 |
1337 | +1 |
1338 | +SET SESSION query_exec_time=0.1; |
1339 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; |
1340 | +SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; |
1341 | +Variable_name Value |
1342 | +query_response_time_range_base 1000 |
1343 | +SHOW QUERY_RESPONSE_TIME; |
1344 | + |
1345 | + 0.000001 24 0.000000 |
1346 | + 0.001000 0 0.000000 |
1347 | + 1.000000 11 4.050000 |
1348 | + 1000.000000 11 25.699999 |
1349 | +1000000.000000 0 0.000000 |
1350 | +TOO LONG 0 TOO LONG |
1351 | +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; |
1352 | +time count total |
1353 | + 0.000001 24 0.000000 |
1354 | + 0.001000 0 0.000000 |
1355 | + 1.000000 11 4.050000 |
1356 | + 1000.000000 11 25.699999 |
1357 | +1000000.000000 0 0.000000 |
1358 | +TOO LONG 0 TOO LONG |
1359 | +SET SESSION query_exec_time=default; |
1360 | +SET SESSION query_exec_time=0.1; |
1361 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; |
1362 | +SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=1001; |
1363 | +Warnings: |
1364 | +Warning 1292 Truncated incorrect query_response_time_range_base value: '1001' |
1365 | +FLUSH QUERY_RESPONSE_TIME; |
1366 | +SHOW QUERY_RESPONSE_TIME; |
1367 | + |
1368 | + 0.000001 0 0.000000 |
1369 | + 0.001000 0 0.000000 |
1370 | + 1.000000 0 0.000000 |
1371 | + 1000.000000 0 0.000000 |
1372 | +1000000.000000 0 0.000000 |
1373 | +TOO LONG 0 TOO LONG |
1374 | +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; |
1375 | +time count total |
1376 | + 0.000001 0 0.000000 |
1377 | + 0.001000 0 0.000000 |
1378 | + 1.000000 0 0.000000 |
1379 | + 1000.000000 0 0.000000 |
1380 | +1000000.000000 0 0.000000 |
1381 | +TOO LONG 0 TOO LONG |
1382 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=1; |
1383 | +SET SESSION query_exec_time=0.31; |
1384 | +SELECT 1; |
1385 | +1 |
1386 | +1 |
1387 | +SET SESSION query_exec_time=0.32; |
1388 | +SELECT 1; |
1389 | +1 |
1390 | +1 |
1391 | +SET SESSION query_exec_time=0.33; |
1392 | +SELECT 1; |
1393 | +1 |
1394 | +1 |
1395 | +SET SESSION query_exec_time=0.34; |
1396 | +SELECT 1; |
1397 | +1 |
1398 | +1 |
1399 | +SET SESSION query_exec_time=0.35; |
1400 | +SELECT 1; |
1401 | +1 |
1402 | +1 |
1403 | +SET SESSION query_exec_time=0.36; |
1404 | +SELECT 1; |
1405 | +1 |
1406 | +1 |
1407 | +SET SESSION query_exec_time=0.37; |
1408 | +SELECT 1; |
1409 | +1 |
1410 | +1 |
1411 | +SET SESSION query_exec_time=0.38; |
1412 | +SELECT 1; |
1413 | +1 |
1414 | +1 |
1415 | +SET SESSION query_exec_time=0.39; |
1416 | +SELECT 1; |
1417 | +1 |
1418 | +1 |
1419 | +SET SESSION query_exec_time=0.4; |
1420 | +SELECT 1; |
1421 | +1 |
1422 | +1 |
1423 | +SET SESSION query_exec_time=1.1; |
1424 | +SELECT 1; |
1425 | +1 |
1426 | +1 |
1427 | +SET SESSION query_exec_time=1.2; |
1428 | +SELECT 1; |
1429 | +1 |
1430 | +1 |
1431 | +SET SESSION query_exec_time=1.3; |
1432 | +SELECT 1; |
1433 | +1 |
1434 | +1 |
1435 | +SET SESSION query_exec_time=1.5; |
1436 | +SELECT 1; |
1437 | +1 |
1438 | +1 |
1439 | +SET SESSION query_exec_time=1.4; |
1440 | +SELECT 1; |
1441 | +1 |
1442 | +1 |
1443 | +SET SESSION query_exec_time=0.5; |
1444 | +SELECT 1; |
1445 | +1 |
1446 | +1 |
1447 | +SET SESSION query_exec_time=2.1; |
1448 | +SELECT 1; |
1449 | +1 |
1450 | +1 |
1451 | +SET SESSION query_exec_time=2.3; |
1452 | +SELECT 1; |
1453 | +1 |
1454 | +1 |
1455 | +SET SESSION query_exec_time=2.5; |
1456 | +SELECT 1; |
1457 | +1 |
1458 | +1 |
1459 | +SET SESSION query_exec_time=3.1; |
1460 | +SELECT 1; |
1461 | +1 |
1462 | +1 |
1463 | +SET SESSION query_exec_time=4.1; |
1464 | +SELECT 1; |
1465 | +1 |
1466 | +1 |
1467 | +SET SESSION query_exec_time=5.1; |
1468 | +SELECT 1; |
1469 | +1 |
1470 | +1 |
1471 | +SET SESSION query_exec_time=0.1; |
1472 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=0; |
1473 | +SHOW GLOBAL VARIABLES where Variable_name like 'QUERY_RESPONSE_TIME_RANGE_BASE'; |
1474 | +Variable_name Value |
1475 | +query_response_time_range_base 1000 |
1476 | +SHOW QUERY_RESPONSE_TIME; |
1477 | + |
1478 | + 0.000001 24 0.000000 |
1479 | + 0.001000 0 0.000000 |
1480 | + 1.000000 11 4.050000 |
1481 | + 1000.000000 11 25.699999 |
1482 | +1000000.000000 0 0.000000 |
1483 | +TOO LONG 0 TOO LONG |
1484 | +SELECT * FROM INFORMATION_SCHEMA.QUERY_RESPONSE_TIME; |
1485 | +time count total |
1486 | + 0.000001 24 0.000000 |
1487 | + 0.001000 0 0.000000 |
1488 | + 1.000000 11 4.050000 |
1489 | + 1000.000000 11 25.699999 |
1490 | +1000000.000000 0 0.000000 |
1491 | +TOO LONG 0 TOO LONG |
1492 | +SET SESSION query_exec_time=default; |
1493 | +SET GLOBAL QUERY_RESPONSE_TIME_RANGE_BASE=default; |
1494 | +SET GLOBAL QUERY_RESPONSE_TIME_STATS=default; |
1495 | |
1496 | === renamed file 'Percona-Server/mysql-test/r/userstat_bug602047.result' => 'Percona-Server/mysql-test/r/percona_userstat.result' |
1497 | --- Percona-Server/mysql-test/r/userstat_bug602047.result 2012-12-19 09:23:15 +0000 |
1498 | +++ Percona-Server/mysql-test/r/percona_userstat.result 2013-05-28 06:50:46 +0000 |
1499 | @@ -1,19 +1,89 @@ |
1500 | DROP TABLE IF EXISTS t1; |
1501 | +SET GLOBAL userstat=OFF; |
1502 | +FLUSH CLIENT_STATISTICS; |
1503 | +FLUSH INDEX_STATISTICS; |
1504 | +FLUSH TABLE_STATISTICS; |
1505 | +FLUSH THREAD_STATISTICS; |
1506 | FLUSH USER_STATISTICS; |
1507 | -FLUSH TABLE_STATISTICS; |
1508 | -FLUSH INDEX_STATISTICS; |
1509 | +SELECT * FROM INFORMATION_SCHEMA.CLIENT_STATISTICS; |
1510 | +CLIENT TOTAL_CONNECTIONS CONCURRENT_CONNECTIONS CONNECTED_TIME BUSY_TIME CPU_TIME BYTES_RECEIVED BYTES_SENT BINLOG_BYTES_WRITTEN ROWS_FETCHED ROWS_UPDATED TABLE_ROWS_READ SELECT_COMMANDS UPDATE_COMMANDS OTHER_COMMANDS COMMIT_TRANSACTIONS ROLLBACK_TRANSACTIONS DENIED_CONNECTIONS LOST_CONNECTIONS ACCESS_DENIED EMPTY_QUERIES TOTAL_SSL_CONNECTIONS |
1511 | +SELECT * FROM INFORMATION_SCHEMA.INDEX_STATISTICS; |
1512 | +TABLE_SCHEMA TABLE_NAME INDEX_NAME ROWS_READ |
1513 | +SELECT * FROM INFORMATION_SCHEMA.TABLE_STATISTICS; |
1514 | +TABLE_SCHEMA TABLE_NAME ROWS_READ ROWS_CHANGED ROWS_CHANGED_X_INDEXES |
1515 | +SELECT * FROM INFORMATION_SCHEMA.THREAD_STATISTICS; |
1516 | +THREAD_ID TOTAL_CONNECTIONS CONCURRENT_CONNECTIONS CONNECTED_TIME BUSY_TIME CPU_TIME BYTES_RECEIVED BYTES_SENT BINLOG_BYTES_WRITTEN ROWS_FETCHED ROWS_UPDATED TABLE_ROWS_READ SELECT_COMMANDS UPDATE_COMMANDS OTHER_COMMANDS COMMIT_TRANSACTIONS ROLLBACK_TRANSACTIONS DENIED_CONNECTIONS LOST_CONNECTIONS ACCESS_DENIED EMPTY_QUERIES TOTAL_SSL_CONNECTIONS |
1517 | +SELECT * FROM INFORMATION_SCHEMA.USER_STATISTICS; |
1518 | +USER TOTAL_CONNECTIONS CONCURRENT_CONNECTIONS CONNECTED_TIME BUSY_TIME CPU_TIME BYTES_RECEIVED BYTES_SENT BINLOG_BYTES_WRITTEN ROWS_FETCHED ROWS_UPDATED TABLE_ROWS_READ SELECT_COMMANDS UPDATE_COMMANDS OTHER_COMMANDS COMMIT_TRANSACTIONS ROLLBACK_TRANSACTIONS DENIED_CONNECTIONS LOST_CONNECTIONS ACCESS_DENIED EMPTY_QUERIES TOTAL_SSL_CONNECTIONS |
1519 | +SHOW CLIENT_STATISTICS; |
1520 | +Client Total_connections Concurrent_connections Connected_time Busy_time Cpu_time Bytes_received Bytes_sent Binlog_bytes_written Rows_fetched Rows_updated Table_rows_read Select_commands Update_commands Other_commands Commit_transactions Rollback_transactions Denied_connections Lost_connections Access_denied Empty_queries Total_ssl_connections |
1521 | +SHOW INDEX_STATISTICS; |
1522 | +Table_schema Table_name Index_name Rows_read |
1523 | +SHOW TABLE_STATISTICS; |
1524 | +Table_schema Table_name Rows_read Rows_changed Rows_changed_x_#indexes |
1525 | +SHOW THREAD_STATISTICS; |
1526 | +Thread_id Total_connections Concurrent_connections Connected_time Busy_time Cpu_time Bytes_received Bytes_sent Binlog_bytes_written Rows_fetched Rows_updated Table_rows_read Select_commands Update_commands Other_commands Commit_transactions Rollback_transactions Denied_connections Lost_connections Access_denied Empty_queries Total_ssl_connections |
1527 | +SHOW USER_STATISTICS; |
1528 | +User Total_connections Concurrent_connections Connected_time Busy_time Cpu_time Bytes_received Bytes_sent Binlog_bytes_written Rows_fetched Rows_updated Table_rows_read Select_commands Update_commands Other_commands Commit_transactions Rollback_transactions Denied_connections Lost_connections Access_denied Empty_queries Total_ssl_connections |
1529 | SET @userstat_old= @@userstat; |
1530 | SET GLOBAL userstat=ON; |
1531 | -CREATE TABLE t1 ( id int(10), PRIMARY KEY (id)) ENGINE=InnoDB; |
1532 | +SELECT * FROM INFORMATION_SCHEMA.CLIENT_STATISTICS; |
1533 | +CLIENT TOTAL_CONNECTIONS CONCURRENT_CONNECTIONS CONNECTED_TIME BUSY_TIME CPU_TIME BYTES_RECEIVED BYTES_SENT BINLOG_BYTES_WRITTEN ROWS_FETCHED ROWS_UPDATED TABLE_ROWS_READ SELECT_COMMANDS UPDATE_COMMANDS OTHER_COMMANDS COMMIT_TRANSACTIONS ROLLBACK_TRANSACTIONS DENIED_CONNECTIONS LOST_CONNECTIONS ACCESS_DENIED EMPTY_QUERIES TOTAL_SSL_CONNECTIONS |
1534 | +localhost 1 CONNECTED_TIME BUSY_TIME CPU_TIME 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 |
1535 | +SELECT * FROM INFORMATION_SCHEMA.INDEX_STATISTICS; |
1536 | +TABLE_SCHEMA TABLE_NAME INDEX_NAME ROWS_READ |
1537 | +SELECT * FROM INFORMATION_SCHEMA.TABLE_STATISTICS; |
1538 | +TABLE_SCHEMA TABLE_NAME ROWS_READ ROWS_CHANGED ROWS_CHANGED_X_INDEXES |
1539 | +SELECT * FROM INFORMATION_SCHEMA.THREAD_STATISTICS; |
1540 | +THREAD_ID TOTAL_CONNECTIONS CONCURRENT_CONNECTIONS CONNECTED_TIME BUSY_TIME CPU_TIME BYTES_RECEIVED BYTES_SENT BINLOG_BYTES_WRITTEN ROWS_FETCHED ROWS_UPDATED TABLE_ROWS_READ SELECT_COMMANDS UPDATE_COMMANDS OTHER_COMMANDS COMMIT_TRANSACTIONS ROLLBACK_TRANSACTIONS DENIED_CONNECTIONS LOST_CONNECTIONS ACCESS_DENIED EMPTY_QUERIES TOTAL_SSL_CONNECTIONS |
1541 | +SELECT * FROM INFORMATION_SCHEMA.USER_STATISTICS; |
1542 | +USER TOTAL_CONNECTIONS CONCURRENT_CONNECTIONS CONNECTED_TIME BUSY_TIME CPU_TIME BYTES_RECEIVED BYTES_SENT BINLOG_BYTES_WRITTEN ROWS_FETCHED ROWS_UPDATED TABLE_ROWS_READ SELECT_COMMANDS UPDATE_COMMANDS OTHER_COMMANDS COMMIT_TRANSACTIONS ROLLBACK_TRANSACTIONS DENIED_CONNECTIONS LOST_CONNECTIONS ACCESS_DENIED EMPTY_QUERIES TOTAL_SSL_CONNECTIONS |
1543 | +root 1 CONNECTED_TIME BUSY_TIME CPU_TIME 0 218 0 0 1 0 0 4 0 0 0 0 0 0 0 3 0 |
1544 | +SHOW CLIENT_STATISTICS; |
1545 | +Client Total_connections Concurrent_connections Connected_time Busy_time Cpu_time Bytes_received Bytes_sent Binlog_bytes_written Rows_fetched Rows_updated Table_rows_read Select_commands Update_commands Other_commands Commit_transactions Rollback_transactions Denied_connections Lost_connections Access_denied Empty_queries Total_ssl_connections |
1546 | +localhost 1 CONNECTED_TIME BUSY_TIME CPU_TIME 0 271 0 0 2 0 0 5 0 0 0 0 0 0 0 3 0 |
1547 | +SHOW INDEX_STATISTICS; |
1548 | +Table_schema Table_name Index_name Rows_read |
1549 | +SHOW TABLE_STATISTICS; |
1550 | +Table_schema Table_name Rows_read Rows_changed Rows_changed_x_#indexes |
1551 | +SHOW THREAD_STATISTICS; |
1552 | +Thread_id Total_connections Concurrent_connections Connected_time Busy_time Cpu_time Bytes_received Bytes_sent Binlog_bytes_written Rows_fetched Rows_updated Table_rows_read Select_commands Update_commands Other_commands Commit_transactions Rollback_transactions Denied_connections Lost_connections Access_denied Empty_queries Total_ssl_connections |
1553 | +SHOW USER_STATISTICS; |
1554 | +User Total_connections Concurrent_connections Connected_time Busy_time Cpu_time Bytes_received Bytes_sent Binlog_bytes_written Rows_fetched Rows_updated Table_rows_read Select_commands Update_commands Other_commands Commit_transactions Rollback_transactions Denied_connections Lost_connections Access_denied Empty_queries Total_ssl_connections |
1555 | +root 1 CONNECTED_TIME BUSY_TIME CPU_TIME 0 377 0 0 3 0 0 9 0 0 0 0 0 0 0 6 0 |
1556 | +CREATE TABLE t1 (id int(10), PRIMARY KEY (id)) ENGINE=InnoDB; |
1557 | INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); |
1558 | SELECT COUNT(*) FROM t1; |
1559 | COUNT(*) |
1560 | 10 |
1561 | -SELECT ROWS_READ FROM information_schema.table_statistics WHERE TABLE_NAME='t1'; |
1562 | -ROWS_READ |
1563 | -10 |
1564 | -SELECT ROWS_READ FROM information_schema.index_statistics WHERE TABLE_NAME='t1'; |
1565 | -ROWS_READ |
1566 | -10 |
1567 | +SELECT ROWS_READ FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_NAME='t1'; |
1568 | +ROWS_READ |
1569 | +10 |
1570 | +SELECT ROWS_READ FROM INFORMATION_SCHEMA.INDEX_STATISTICS WHERE TABLE_NAME='t1'; |
1571 | +ROWS_READ |
1572 | +10 |
1573 | +FLUSH TABLE_STATISTICS; |
1574 | +SELECT ROWS_READ FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_NAME='t1'; |
1575 | +ROWS_READ |
1576 | +SELECT ROWS_READ FROM INFORMATION_SCHEMA.INDEX_STATISTICS WHERE TABLE_NAME='t1'; |
1577 | +ROWS_READ |
1578 | +10 |
1579 | +FLUSH INDEX_STATISTICS; |
1580 | +SELECT ROWS_READ FROM INFORMATION_SCHEMA.INDEX_STATISTICS WHERE TABLE_NAME='t1'; |
1581 | +ROWS_READ |
1582 | +SELECT COUNT(*) FROM t1; |
1583 | +COUNT(*) |
1584 | +10 |
1585 | +SELECT ROWS_READ FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_NAME='t1'; |
1586 | +ROWS_READ |
1587 | +10 |
1588 | +SELECT ROWS_READ FROM INFORMATION_SCHEMA.INDEX_STATISTICS WHERE TABLE_NAME='t1'; |
1589 | +ROWS_READ |
1590 | +10 |
1591 | +DROP TABLE t1; |
1592 | +CREATE TABLE t2 (c1 INT UNSIGNED) ENGINE=InnoDB; |
1593 | +ALTER TABLE t2 MODIFY c1 FLOAT; |
1594 | +SELECT * FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_NAME='t2'; |
1595 | +TABLE_SCHEMA TABLE_NAME ROWS_READ ROWS_CHANGED ROWS_CHANGED_X_INDEXES |
1596 | +DROP TABLE t2; |
1597 | SET GLOBAL userstat= @userstat_old; |
1598 | -DROP TABLE t1; |
1599 | |
1600 | === removed file 'Percona-Server/mysql-test/r/percona_xtradb_admin_command.result' |
1601 | --- Percona-Server/mysql-test/r/percona_xtradb_admin_command.result 2013-05-28 06:50:44 +0000 |
1602 | +++ Percona-Server/mysql-test/r/percona_xtradb_admin_command.result 1970-01-01 00:00:00 +0000 |
1603 | @@ -1,6 +0,0 @@ |
1604 | -select * from information_schema.XTRADB_ADMIN_COMMAND; |
1605 | -result_message |
1606 | -No XTRA_* command in the SQL statement. Please add /*!XTRA_xxxx*/ to the SQL. |
1607 | -select * from information_schema.XTRADB_ADMIN_COMMAND /*!XTRA_HELLO*/; |
1608 | -result_message |
1609 | -Hello! |
1610 | |
1611 | === added file 'Percona-Server/mysql-test/r/percona_xtradb_bug317074.result' |
1612 | --- Percona-Server/mysql-test/r/percona_xtradb_bug317074.result 1970-01-01 00:00:00 +0000 |
1613 | +++ Percona-Server/mysql-test/r/percona_xtradb_bug317074.result 2013-05-28 06:50:46 +0000 |
1614 | @@ -0,0 +1,5 @@ |
1615 | +SET @old_innodb_file_format=@@innodb_file_format; |
1616 | +SET @old_innodb_file_format_max=@@innodb_file_format_max; |
1617 | +SET @old_innodb_file_per_table=@@innodb_file_per_table; |
1618 | +SET GLOBAL innodb_file_format='Barracuda'; |
1619 | +SET GLOBAL innodb_file_per_table=ON; |
1620 | |
1621 | === added file 'Percona-Server/mysql-test/t/percona_bug643149.test' |
1622 | --- Percona-Server/mysql-test/t/percona_bug643149.test 1970-01-01 00:00:00 +0000 |
1623 | +++ Percona-Server/mysql-test/t/percona_bug643149.test 2013-05-28 06:50:46 +0000 |
1624 | @@ -0,0 +1,49 @@ |
1625 | +# |
1626 | +# This test suffers from server |
1627 | +# Bug#38124 "general_log_file" variable silently unset when using expression |
1628 | +# In short: |
1629 | +# SET GLOBAL general_log_file = @<whatever> |
1630 | +# SET GLOBAL slow_query_log = @<whatever> |
1631 | +# cause that the value of these server system variables is set to default |
1632 | +# instead of the assigned values. There comes no error message or warning. |
1633 | +# If this bug is fixed please |
1634 | +# 1. try this test with "let $fixed_bug38124 = 0;" |
1635 | +# 2. remove all workarounds if 1. was successful. |
1636 | +--source include/have_profiling.inc |
1637 | +let $fixed_bug38124 = 0; |
1638 | + |
1639 | +SET @old_slow_query_log_file=@@global.slow_query_log_file; |
1640 | +SET GLOBAL slow_query_log=on; |
1641 | +SET LOCAL log_slow_verbosity='profiling'; |
1642 | +SET LOCAL long_query_time=0; |
1643 | + |
1644 | +let slogfile=$MYSQLTEST_VARDIR/percona_bug643149_slow.log; |
1645 | +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR |
1646 | +--eval SET GLOBAL slow_query_log_file='$slogfile'; |
1647 | + |
1648 | +SELECT 1; |
1649 | + |
1650 | +perl; |
1651 | + $slogfile= $ENV{'slogfile'}; |
1652 | + |
1653 | + open(FILE, "$slogfile") or |
1654 | + die("Unable to read slow query log file $slogfile: $!\n"); |
1655 | + while(<FILE>) { |
1656 | + next if (!/^#/); |
1657 | + next if (/^# Time:/); |
1658 | + s/[0-9]+/X/g; |
1659 | + print; |
1660 | + } |
1661 | + |
1662 | + close(FILE); |
1663 | +EOF |
1664 | + |
1665 | +SET GLOBAL slow_query_log_file=@old_slow_query_log_file; |
1666 | + |
1667 | +if(!$fixed_bug38124) |
1668 | +{ |
1669 | + --disable_query_log |
1670 | + let $my_var = `SELECT @old_slow_query_log_file`; |
1671 | + eval SET @@global.slow_query_log_file = '$my_var'; |
1672 | + --enable_query_log |
1673 | +} |
1674 | |
1675 | === removed file 'Percona-Server/mysql-test/t/percona_bug933969.test' |
1676 | --- Percona-Server/mysql-test/t/percona_bug933969.test 2013-05-28 06:50:44 +0000 |
1677 | +++ Percona-Server/mysql-test/t/percona_bug933969.test 1970-01-01 00:00:00 +0000 |
1678 | @@ -1,42 +0,0 @@ |
1679 | -###################### percona_bug933969.test ######################## |
1680 | -# Bug #933969: mysqlbinlog doesn't accept stdin # |
1681 | -# # |
1682 | -# The goal of this testcase is to test that mysqlbinlog handle # |
1683 | -# stdin correctly when stdin is pipe. # |
1684 | -# i.e. "cat log | mysqlbinlog -" don't cause mysqlbinlog failure # |
1685 | -###################################################################### |
1686 | --- source include/have_log_bin.inc |
1687 | --- source include/not_windows.inc |
1688 | --- source include/not_embedded.inc |
1689 | - |
1690 | -# deletes all the binary logs |
1691 | -RESET MASTER; |
1692 | - |
1693 | ---disable_warnings |
1694 | -DROP TABLE IF EXISTS t1; |
1695 | ---enable_warnings |
1696 | - |
1697 | -# produce some statements for binlog |
1698 | - |
1699 | -CREATE TABLE t1 (word VARCHAR(20)); |
1700 | - |
1701 | -INSERT INTO t1 VALUES ("hamite"); |
1702 | -INSERT INTO t1 VALUES ("hoho"); |
1703 | -INSERT INTO t1 VALUES ("znamenito"); |
1704 | -INSERT INTO t1 VALUES ("mrachny"); |
1705 | -INSERT INTO t1 VALUES ("mrak"); |
1706 | -INSERT INTO t1 VALUES ("zhut"); |
1707 | -INSERT INTO t1 VALUES ("parnisha"); |
1708 | -INSERT INTO t1 VALUES ("krrasota!"); |
1709 | -INSERT INTO t1 VALUES ("podumayesh"); |
1710 | -INSERT INTO t1 VALUES ("ogo!"); |
1711 | - |
1712 | -FLUSH LOGS; |
1713 | - |
1714 | -# run mysqlbinlog and make sure it ends normally |
1715 | - |
1716 | -let $MYSQLD_DATADIR= `SELECT @@datadir`; |
1717 | ---system cat $MYSQLD_DATADIR/master-bin.000001 | $MYSQL_BINLOG - >/dev/null |
1718 | - |
1719 | -DROP TABLE t1; |
1720 | -RESET MASTER; |
1721 | |
1722 | === added file 'Percona-Server/mysql-test/t/percona_log_slow_verbosity-cl.test' |
1723 | --- Percona-Server/mysql-test/t/percona_log_slow_verbosity-cl.test 1970-01-01 00:00:00 +0000 |
1724 | +++ Percona-Server/mysql-test/t/percona_log_slow_verbosity-cl.test 2013-05-28 06:50:46 +0000 |
1725 | @@ -0,0 +1,2 @@ |
1726 | +SHOW VARIABLES LIKE 'log_slow_verbosity'; |
1727 | +SHOW GLOBAL VARIABLES LIKE 'log_slow_verbosity'; |
1728 | |
1729 | === added file 'Percona-Server/mysql-test/t/percona_query_cache_with_comments_prepared_statements.test' |
1730 | --- Percona-Server/mysql-test/t/percona_query_cache_with_comments_prepared_statements.test 1970-01-01 00:00:00 +0000 |
1731 | +++ Percona-Server/mysql-test/t/percona_query_cache_with_comments_prepared_statements.test 2013-05-28 06:50:46 +0000 |
1732 | @@ -0,0 +1,208 @@ |
1733 | +-- source include/have_query_cache.inc |
1734 | + |
1735 | +set GLOBAL query_cache_size=1355776; |
1736 | + |
1737 | +# Reset query cache variables. |
1738 | +flush query cache; # This crashed in some versions |
1739 | +flush query cache; # This crashed in some versions |
1740 | +reset query cache; |
1741 | +flush status; |
1742 | +--disable_warnings |
1743 | +drop table if exists t1; |
1744 | +--enable_warnings |
1745 | + |
1746 | +# |
1747 | +# First simple test |
1748 | +# |
1749 | + |
1750 | +create table t1 (a int not null); |
1751 | +insert into t1 values (1),(2),(3); |
1752 | + |
1753 | +set global query_cache_strip_comments=ON; |
1754 | + |
1755 | +show status like "Qcache_queries_in_cache"; |
1756 | +show status like "Qcache_inserts"; |
1757 | +show status like "Qcache_hits"; |
1758 | + |
1759 | +prepare stmt from '/* with comment */ select * from t1'; |
1760 | +execute stmt; |
1761 | + |
1762 | +show status like "Qcache_queries_in_cache"; |
1763 | +show status like "Qcache_inserts"; |
1764 | +show status like "Qcache_hits"; |
1765 | + |
1766 | +execute stmt; |
1767 | +execute stmt; |
1768 | +execute stmt; |
1769 | +execute stmt; |
1770 | +execute stmt; |
1771 | + |
1772 | +show status like "Qcache_queries_in_cache"; |
1773 | +show status like "Qcache_inserts"; |
1774 | +show status like "Qcache_hits"; |
1775 | + |
1776 | +prepare stmt from 'select * from t1'; |
1777 | +execute stmt; |
1778 | + |
1779 | +show status like "Qcache_queries_in_cache"; |
1780 | +show status like "Qcache_inserts"; |
1781 | +show status like "Qcache_hits"; |
1782 | + |
1783 | +prepare stmt from 'select * /*internal comment*/from t1'; |
1784 | +execute stmt; |
1785 | + |
1786 | +show status like "Qcache_queries_in_cache"; |
1787 | +show status like "Qcache_inserts"; |
1788 | +show status like "Qcache_hits"; |
1789 | + |
1790 | +prepare stmt from 'select * /*internal comment*/ from t1'; |
1791 | +execute stmt; |
1792 | + |
1793 | +show status like "Qcache_queries_in_cache"; |
1794 | +show status like "Qcache_inserts"; |
1795 | +show status like "Qcache_hits"; |
1796 | + |
1797 | +prepare stmt from 'select * from t1 /* at the end */'; |
1798 | +execute stmt; |
1799 | + |
1800 | +show status like "Qcache_queries_in_cache"; |
1801 | +show status like "Qcache_inserts"; |
1802 | +show status like "Qcache_hits"; |
1803 | + |
1804 | +prepare stmt from 'select * from t1 /* with "quote" */'; |
1805 | +execute stmt; |
1806 | + |
1807 | +show status like "Qcache_queries_in_cache"; |
1808 | +show status like "Qcache_inserts"; |
1809 | +show status like "Qcache_hits"; |
1810 | + |
1811 | +prepare stmt from 'select * from t1 /* with \'quote\' */'; |
1812 | +execute stmt; |
1813 | + |
1814 | +show status like "Qcache_queries_in_cache"; |
1815 | +show status like "Qcache_inserts"; |
1816 | +show status like "Qcache_hits"; |
1817 | + |
1818 | +prepare stmt from 'select * from t1 # 123 |
1819 | +'; |
1820 | +execute stmt; |
1821 | + |
1822 | +show status like "Qcache_queries_in_cache"; |
1823 | +show status like "Qcache_inserts"; |
1824 | +show status like "Qcache_hits"; |
1825 | + |
1826 | +prepare stmt from 'select * from t1 # 123 with "quote" |
1827 | +'; |
1828 | +execute stmt; |
1829 | + |
1830 | +show status like "Qcache_queries_in_cache"; |
1831 | +show status like "Qcache_inserts"; |
1832 | +show status like "Qcache_hits"; |
1833 | + |
1834 | +prepare stmt from 'select * from t1 # 123 with \'quote\' |
1835 | +'; |
1836 | +execute stmt; |
1837 | + |
1838 | +show status like "Qcache_queries_in_cache"; |
1839 | +show status like "Qcache_inserts"; |
1840 | +show status like "Qcache_hits"; |
1841 | + |
1842 | +prepare stmt from 'select * from t1 |
1843 | +# 123 |
1844 | +'; |
1845 | +execute stmt; |
1846 | + |
1847 | +show status like "Qcache_queries_in_cache"; |
1848 | +show status like "Qcache_inserts"; |
1849 | +show status like "Qcache_hits"; |
1850 | + |
1851 | +prepare stmt from '#456 |
1852 | +select * from t1 |
1853 | +# 123 |
1854 | +'; |
1855 | +execute stmt; |
1856 | + |
1857 | +show status like "Qcache_queries_in_cache"; |
1858 | +show status like "Qcache_inserts"; |
1859 | +show status like "Qcache_hits"; |
1860 | + |
1861 | +prepare stmt from 'select * from t1 -- 123 |
1862 | +'; |
1863 | +execute stmt; |
1864 | + |
1865 | +show status like "Qcache_queries_in_cache"; |
1866 | +show status like "Qcache_inserts"; |
1867 | +show status like "Qcache_hits"; |
1868 | + |
1869 | +prepare stmt from 'select * from t1 |
1870 | +-- 123 |
1871 | +'; |
1872 | +execute stmt; |
1873 | + |
1874 | +show status like "Qcache_queries_in_cache"; |
1875 | +show status like "Qcache_inserts"; |
1876 | +show status like "Qcache_hits"; |
1877 | + |
1878 | +prepare stmt from '-- comment in first |
1879 | +select * from t1 |
1880 | +# 123 |
1881 | +'; |
1882 | +execute stmt; |
1883 | + |
1884 | +show status like "Qcache_queries_in_cache"; |
1885 | +show status like "Qcache_inserts"; |
1886 | +show status like "Qcache_hits"; |
1887 | + |
1888 | +prepare stmt from '(#456( |
1889 | +select * from t1 |
1890 | +# 123( |
1891 | +)'; |
1892 | +execute stmt; |
1893 | + |
1894 | +show status like "Qcache_queries_in_cache"; |
1895 | +show status like "Qcache_inserts"; |
1896 | +show status like "Qcache_hits"; |
1897 | + |
1898 | +prepare stmt from '/*test*/(-- comment in first( |
1899 | +select * from t1 |
1900 | +-- 123 asdasd |
1901 | +/* test */)'; |
1902 | +execute stmt; |
1903 | + |
1904 | +show status like "Qcache_queries_in_cache"; |
1905 | +show status like "Qcache_inserts"; |
1906 | +show status like "Qcache_hits"; |
1907 | + |
1908 | +prepare stmt from 'select "test",a from t1'; |
1909 | +execute stmt; |
1910 | +execute stmt; |
1911 | + |
1912 | +show status like "Qcache_queries_in_cache"; |
1913 | +show status like "Qcache_inserts"; |
1914 | +show status like "Qcache_hits"; |
1915 | + |
1916 | +prepare stmt from 'select "test /* internal \'comment\' */",a from t1'; |
1917 | +execute stmt; |
1918 | + |
1919 | +show status like "Qcache_queries_in_cache"; |
1920 | +show status like "Qcache_inserts"; |
1921 | +show status like "Qcache_hits"; |
1922 | + |
1923 | +prepare stmt from 'select "test #internal comment" ,a from t1'; |
1924 | +execute stmt; |
1925 | + |
1926 | +show status like "Qcache_queries_in_cache"; |
1927 | +show status like "Qcache_inserts"; |
1928 | +show status like "Qcache_hits"; |
1929 | + |
1930 | +prepare stmt from 'select "test #internal comment" #external comment |
1931 | +,a from t1'; |
1932 | +execute stmt; |
1933 | + |
1934 | +show status like "Qcache_queries_in_cache"; |
1935 | +show status like "Qcache_inserts"; |
1936 | +show status like "Qcache_hits"; |
1937 | + |
1938 | +DROP TABLE t1; |
1939 | +SET GLOBAL query_cache_size= default; |
1940 | +set global query_cache_strip_comments=OFF; |
1941 | |
1942 | === removed file 'Percona-Server/mysql-test/t/percona_server_variables_debug.test' |
1943 | --- Percona-Server/mysql-test/t/percona_server_variables_debug.test 2013-05-28 06:50:44 +0000 |
1944 | +++ Percona-Server/mysql-test/t/percona_server_variables_debug.test 1970-01-01 00:00:00 +0000 |
1945 | @@ -1,2 +0,0 @@ |
1946 | ---source include/have_debug.inc |
1947 | ---source include/percona_server_variables.inc |
1948 | |
1949 | === added file 'Percona-Server/mysql-test/t/percona_server_variables_release.test' |
1950 | --- Percona-Server/mysql-test/t/percona_server_variables_release.test 1970-01-01 00:00:00 +0000 |
1951 | +++ Percona-Server/mysql-test/t/percona_server_variables_release.test 2013-05-28 06:50:46 +0000 |
1952 | @@ -0,0 +1,2 @@ |
1953 | +--source include/have_nodebug.inc |
1954 | +--source include/percona_server_variables.inc |
1955 | |
1956 | === added file 'Percona-Server/mysql-test/t/percona_sql_no_fcache.test' |
1957 | --- Percona-Server/mysql-test/t/percona_sql_no_fcache.test 1970-01-01 00:00:00 +0000 |
1958 | +++ Percona-Server/mysql-test/t/percona_sql_no_fcache.test 2013-05-28 06:50:46 +0000 |
1959 | @@ -0,0 +1,11 @@ |
1960 | +--disable_warnings |
1961 | +drop table if exists t1; |
1962 | +--enable_warnings |
1963 | + |
1964 | +create table t (a int not null); |
1965 | +insert into t values (1),(2),(3); |
1966 | + |
1967 | +SELECT SQL_NO_FCACHE SLEEP(0); |
1968 | +SELECT /*!40001 SQL_NO_CACHE */ /*!50084 SQL_NO_FCACHE */ * FROM t; |
1969 | + |
1970 | +DROP TABLE t; |
1971 | |
1972 | === renamed file 'Percona-Server/mysql-test/t/userstat_bug602047.test' => 'Percona-Server/mysql-test/t/percona_userstat.test' |
1973 | --- Percona-Server/mysql-test/t/userstat_bug602047.test 2012-12-19 09:23:15 +0000 |
1974 | +++ Percona-Server/mysql-test/t/percona_userstat.test 2013-05-28 06:50:46 +0000 |
1975 | @@ -1,16 +1,91 @@ |
1976 | --source include/have_innodb.inc |
1977 | + |
1978 | --disable_warnings |
1979 | DROP TABLE IF EXISTS t1; |
1980 | --enable_warnings |
1981 | + |
1982 | +# Test that FLUSH works with userstat disabled |
1983 | +SET GLOBAL userstat=OFF; |
1984 | + |
1985 | +FLUSH CLIENT_STATISTICS; |
1986 | +FLUSH INDEX_STATISTICS; |
1987 | +FLUSH TABLE_STATISTICS; |
1988 | +FLUSH THREAD_STATISTICS; |
1989 | FLUSH USER_STATISTICS; |
1990 | -FLUSH TABLE_STATISTICS; |
1991 | -FLUSH INDEX_STATISTICS; |
1992 | + |
1993 | +# Test that I_S and SHOW queries work with userstat disabled |
1994 | +SELECT * FROM INFORMATION_SCHEMA.CLIENT_STATISTICS; |
1995 | +SELECT * FROM INFORMATION_SCHEMA.INDEX_STATISTICS; |
1996 | +SELECT * FROM INFORMATION_SCHEMA.TABLE_STATISTICS; |
1997 | +SELECT * FROM INFORMATION_SCHEMA.THREAD_STATISTICS; |
1998 | +SELECT * FROM INFORMATION_SCHEMA.USER_STATISTICS; |
1999 | + |
2000 | +SHOW CLIENT_STATISTICS; |
2001 | +SHOW INDEX_STATISTICS; |
2002 | +SHOW TABLE_STATISTICS; |
2003 | +SHOW THREAD_STATISTICS; |
2004 | +SHOW USER_STATISTICS; |
2005 | + |
2006 | SET @userstat_old= @@userstat; |
2007 | SET GLOBAL userstat=ON; |
2008 | -CREATE TABLE t1 ( id int(10), PRIMARY KEY (id)) ENGINE=InnoDB; |
2009 | + |
2010 | +# Test that statistics start at empty state |
2011 | + |
2012 | +--replace_column 3 CONNECTED_TIME 4 BUSY_TIME 5 CPU_TIME |
2013 | +SELECT * FROM INFORMATION_SCHEMA.CLIENT_STATISTICS; |
2014 | +SELECT * FROM INFORMATION_SCHEMA.INDEX_STATISTICS; |
2015 | +SELECT * FROM INFORMATION_SCHEMA.TABLE_STATISTICS; |
2016 | +--replace_column 3 CONNECTED_TIME 4 BUSY_TIME 5 CPU_TIME |
2017 | +SELECT * FROM INFORMATION_SCHEMA.THREAD_STATISTICS; |
2018 | +--replace_column 3 CONNECTED_TIME 4 BUSY_TIME 5 CPU_TIME |
2019 | +SELECT * FROM INFORMATION_SCHEMA.USER_STATISTICS; |
2020 | + |
2021 | +--replace_column 3 CONNECTED_TIME 4 BUSY_TIME 5 CPU_TIME |
2022 | +SHOW CLIENT_STATISTICS; |
2023 | +SHOW INDEX_STATISTICS; |
2024 | +SHOW TABLE_STATISTICS; |
2025 | +--replace_column 3 CONNECTED_TIME 4 BUSY_TIME 5 CPU_TIME |
2026 | +SHOW THREAD_STATISTICS; |
2027 | +--replace_column 3 CONNECTED_TIME 4 BUSY_TIME 5 CPU_TIME |
2028 | +SHOW USER_STATISTICS; |
2029 | + |
2030 | +# Bug 602047 (wrong rows_read value) |
2031 | + |
2032 | +CREATE TABLE t1 (id int(10), PRIMARY KEY (id)) ENGINE=InnoDB; |
2033 | INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); |
2034 | SELECT COUNT(*) FROM t1; |
2035 | -SELECT ROWS_READ FROM information_schema.table_statistics WHERE TABLE_NAME='t1'; |
2036 | -SELECT ROWS_READ FROM information_schema.index_statistics WHERE TABLE_NAME='t1'; |
2037 | +SELECT ROWS_READ FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_NAME='t1'; |
2038 | +SELECT ROWS_READ FROM INFORMATION_SCHEMA.INDEX_STATISTICS WHERE TABLE_NAME='t1'; |
2039 | + |
2040 | +# Test that FLUSH clears one table but not another |
2041 | + |
2042 | +FLUSH TABLE_STATISTICS; |
2043 | + |
2044 | +SELECT ROWS_READ FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_NAME='t1'; |
2045 | +SELECT ROWS_READ FROM INFORMATION_SCHEMA.INDEX_STATISTICS WHERE TABLE_NAME='t1'; |
2046 | + |
2047 | +# Test that FLUSH clears both tables now |
2048 | + |
2049 | +FLUSH INDEX_STATISTICS; |
2050 | + |
2051 | +SELECT ROWS_READ FROM INFORMATION_SCHEMA.INDEX_STATISTICS WHERE TABLE_NAME='t1'; |
2052 | + |
2053 | +# Test that stats are collected after the FLUSH again |
2054 | + |
2055 | +SELECT COUNT(*) FROM t1; |
2056 | +SELECT ROWS_READ FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_NAME='t1'; |
2057 | +SELECT ROWS_READ FROM INFORMATION_SCHEMA.INDEX_STATISTICS WHERE TABLE_NAME='t1'; |
2058 | + |
2059 | +DROP TABLE t1; |
2060 | + |
2061 | +# Bug 1183625 (handler::update_global_table_stats crash). |
2062 | + |
2063 | +CREATE TABLE t2 (c1 INT UNSIGNED) ENGINE=InnoDB; |
2064 | + |
2065 | +ALTER TABLE t2 MODIFY c1 FLOAT; |
2066 | + |
2067 | +SELECT * FROM INFORMATION_SCHEMA.TABLE_STATISTICS WHERE TABLE_NAME='t2'; |
2068 | + |
2069 | +DROP TABLE t2; |
2070 | + |
2071 | SET GLOBAL userstat= @userstat_old; |
2072 | -DROP TABLE t1; |
2073 | |
2074 | === removed file 'build/debian/copyright' |
2075 | --- build/debian/copyright 2013-05-28 06:50:44 +0000 |
2076 | +++ build/debian/copyright 1970-01-01 00:00:00 +0000 |
2077 | @@ -1,86 +0,0 @@ |
2078 | -This work was packaged for Debian by: |
2079 | - |
2080 | - Aleksandr Kuzminsky <aleksandr.kuzminsky@percona.com> on Tue, 11 Jan 2011 07:17:08 -0800 |
2081 | - |
2082 | -It was downloaded from: |
2083 | - |
2084 | - http://www.percona.com/downloads/ |
2085 | - |
2086 | -Upstream Author(s): |
2087 | - |
2088 | - mysql-dev@percona.com |
2089 | - |
2090 | -Copyright: |
2091 | - |
2092 | - Copyright (C) 2006-2011 Percona Inc. |
2093 | - |
2094 | -License: |
2095 | - |
2096 | - This package is free software; you can redistribute it and/or modify |
2097 | - it under the terms of the GNU General Public License version 2 as |
2098 | - published by the Free Software Foundation. |
2099 | - |
2100 | - This package is distributed in the hope that it will be useful, |
2101 | - but WITHOUT ANY WARRANTY; without even the implied warranty of |
2102 | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2103 | - GNU General Public License for more details. |
2104 | - |
2105 | - You should have received a copy of the GNU General Public License |
2106 | - along with this program. If not, see <http://www.gnu.org/licenses/> |
2107 | - |
2108 | -On Debian systems, the complete text of the GNU General |
2109 | -Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". |
2110 | - |
2111 | -The Debian packaging is: |
2112 | - |
2113 | - Copyright (C) 2011 Aleksandr Kuzminsky <aleksandr.kuzminsky@percona.com> |
2114 | - |
2115 | -you can redistribute it and/or modify |
2116 | -it under the terms of the GNU General Public License as published by |
2117 | -the Free Software Foundation; either version 2 of the License, or |
2118 | -(at your option) any later version. |
2119 | - |
2120 | -Other copyrights: |
2121 | - |
2122 | -Patch innodb-deadlock-count-patch |
2123 | - |
2124 | -Copyright: |
2125 | - |
2126 | - COPYING.innodb-deadlock-count-patch |
2127 | - |
2128 | -Patch show_temp |
2129 | - |
2130 | -Copyright: |
2131 | - |
2132 | - COPYING.show_temp_51 |
2133 | - |
2134 | -== innotop == |
2135 | - |
2136 | -Author: Baron Schwartz <baron@xaprb.com> |
2137 | -URL: http://innotop.sourceforge.net |
2138 | - |
2139 | -License: |
2140 | -> This software is dual licensed, either GPL version 2 or Artistic License. |
2141 | -> |
2142 | -> This package is free software; you can redistribute it and/or modify |
2143 | -> it under the terms of the GNU General Public License as published by |
2144 | -> the Free Software Foundation; either version 2 of the License, or |
2145 | -> (at your option) any later version. |
2146 | -> |
2147 | -> This package is distributed in the hope that it will be useful, |
2148 | -> but WITHOUT ANY WARRANTY; without even the implied warranty of |
2149 | -> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2150 | -> GNU General Public License for more details. |
2151 | -> |
2152 | -> You should have received a copy of the GNU General Public License |
2153 | -> along with this package; if not, write to the Free Software |
2154 | -> Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
2155 | - |
2156 | -On Debian systems, the complete text of the GNU General Public License and the |
2157 | -Artistic License can be found in `/usr/share/common-licenses/'. |
2158 | - |
2159 | -The upstream author explained here: http://bugs.gentoo.org/show_bug.cgi?id=14760 |
2160 | -that these licenses also apply to the following files: |
2161 | -- innotop.html |
2162 | -- InnoDBParser.pm |
2163 | - |
2164 | |
2165 | === added directory 'doc/source/_static' |
2166 | === added file 'doc/source/compatibility.rst' |
2167 | --- doc/source/compatibility.rst 1970-01-01 00:00:00 +0000 |
2168 | +++ doc/source/compatibility.rst 2013-05-28 06:50:46 +0000 |
2169 | @@ -0,0 +1,27 @@ |
2170 | +.. _compatibility: |
2171 | + |
2172 | +============================================================== |
2173 | +Options that make XtraDB tablespaces not compatible with MySQL |
2174 | +============================================================== |
2175 | + |
2176 | +Fast checksums |
2177 | +============== |
2178 | + |
2179 | +Enabling :variable:`innodb_fast_checksum` will use more CPU-efficient algorithm, based on 4-byte words which can be beneficial for some workloads. Once enabled, turning it off will require table to be dump/imported again, since |Percona Server| will fail to start on data files created when :variable:`innodb_fast_checksums` was enabled. |
2180 | + |
2181 | +In case you've migrated from |Percona Server| to |MySQL| you could get the "corrupted checksum" error message. In order to recover that table you'll need to: |
2182 | + |
2183 | + 1) Reinstall Percona Server to read your tables that were created with fast checksums. |
2184 | + 2) Dump the tables (or temporarily convert them to MyISAM). |
2185 | + 3) Install stock MySQL (or at least disable fast checksums). |
2186 | + 4) Restore the InnoDB tables (or convert back from MyISAM). |
2187 | + |
2188 | +Page sizes other than 16KiB |
2189 | +=========================== |
2190 | + |
2191 | +This is controlled by variable :variable:`innodb_page_size`. Changing the page size for an existing database is not supported. Table will need to be dumped/imported again if compatibility with |MySQL| is required. |
2192 | + |
2193 | +Relocation of the doublewrite buffer |
2194 | +==================================== |
2195 | + |
2196 | +Variable :variable:`innodb_doublewrite_file` provides an option to put the buffer on a dedicated disk in order to parallelize I/O activity on the buffer and on the tablespace. Only in case of crash recovery this variable cannot be changed, in all other cases it can be turned on/off without breaking the compatibility. |
2197 | |
2198 | === added file 'doc/source/diagnostics/innodb_stats.rst' |
2199 | --- doc/source/diagnostics/innodb_stats.rst 1970-01-01 00:00:00 +0000 |
2200 | +++ doc/source/diagnostics/innodb_stats.rst 2013-05-28 06:50:46 +0000 |
2201 | @@ -0,0 +1,234 @@ |
2202 | +.. _innodb_stats: |
2203 | + |
2204 | +===================== |
2205 | + |InnoDB| Statistics |
2206 | +===================== |
2207 | + |
2208 | +This feature provides new startup options (control method and collection of index statistics estimation) and information schema views to confirm the statistics. |
2209 | + |
2210 | +Version Specific Information |
2211 | +============================ |
2212 | + |
2213 | + * :rn:`5.5.8-20.0`: |
2214 | + Renamed three fields in :table:`INNODB_INDEX_STATS` table. |
2215 | + |
2216 | + |
2217 | +System Variables |
2218 | +================ |
2219 | + |
2220 | +Four new system variables were introduced by this feature. |
2221 | + |
2222 | +.. variable:: innodb_stats_method |
2223 | + |
2224 | + :cli: YES |
2225 | + :configfile: YES |
2226 | + :scope: GLOBAL |
2227 | + :dyn: YES |
2228 | + :type: STRING |
2229 | + :default: ``nulls_equal`` |
2230 | + :allowed: ``nulls_equal``, ``nulls_unequal``, ``nulls_ignored`` |
2231 | + |
2232 | +The values and meanings are almost same to ``myisam_stats_method`` option of native |MySQL| (``nulls_equal``, ``nulls_unequal``, ``nulls_ignored``). But |InnoDB| doesn't have several patterns of statistics currently. Even though this option can be changed dynamically, statistics needs to be re-calculated to change the method for the table. |
2233 | + |
2234 | +(reference: `MyISAM Index Statistics Collection <http://dev.mysql.com/doc/refman/5.5/en/myisam-index-statistics.html>`_) |
2235 | + |
2236 | +.. variable:: innodb_stats_auto_update |
2237 | + |
2238 | + :type: BOOLEAN |
2239 | + :default: 1 |
2240 | + |
2241 | +|InnoDB| updates the each index statistics automatically (many updates were done, some information_schema is accessed, table monitor, etc.). Setting this option 0 can stop these automatic recalculation of the statistics except for "first open" and "ANALYZE TABLE command". |
2242 | + |
2243 | + |
2244 | +.. variable:: innodb_stats_update_need_lock |
2245 | + |
2246 | + :type: BOOLEAN |
2247 | + :default: 1 |
2248 | + |
2249 | +If you meet contention of ``&dict_operation_lock``, setting 0 reduces the contention. But 0 disables to update ``Data_free:`` of ``SHOW TABLE STATUS``. |
2250 | + |
2251 | + |
2252 | +.. variable:: innodb_use_sys_stats_table |
2253 | + |
2254 | + :type: BOOLEAN |
2255 | + :default: 0 |
2256 | + |
2257 | + |
2258 | +If this option is enabled, |XtraDB| uses the ``SYS_STATS`` system table to store statistics of table indexes. Also, when |InnoDB| opens a table for the first time, it loads the statistics from ``SYS_STATS`` instead of sampling index pages. If you use a high ``stats_sample_pages`` value, the first open of a table is expensive. In such a case, this option will help. Intended behavior is to never update statistics unless an explicit ``ANALYZE TABLE`` is issued. |
2259 | + |
2260 | +INFORMATION_SCHEMA Tables |
2261 | +========================= |
2262 | + |
2263 | +.. table:: INFORMATION_SCHEMA.INNODB_SYS_STATS |
2264 | + |
2265 | + Shows statistics of table indexes. |
2266 | + |
2267 | + :column INDEX_ID: Index ID |
2268 | + :column KEY_COLS: Number of key columns |
2269 | + :column DIFF_VALS: Number of Different Values |
2270 | + :column NON_NULL_VALS: Number of Non ``NULL`` Values |
2271 | + |
2272 | +.. table:: INFORMATION_SCHEMA.INNODB_SYS_TABLES |
2273 | + |
2274 | + Shows the information about |InnoDB| tables |
2275 | + |
2276 | + :column TABLE_ID: Table ID |
2277 | + :column SCHEMA: Database (schema) name |
2278 | + :column NAME: Table name |
2279 | + :column FLAG: Contains `0` if it is a InnoDB system table or `1` it is a user table |
2280 | + :column N_COLS: Number of columns in the table |
2281 | + :column SPACE: Tablespace ID |
2282 | + |
2283 | +.. table:: INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS |
2284 | + |
2285 | + Shows the information about the performance statistics of |InnoDB| tables. |
2286 | + |
2287 | + :column TABLE_ID: Table ID |
2288 | + :column SCHEMA: Database (schema) Name |
2289 | + :column NAME: Table Name |
2290 | + :column STATS_INITIALIZED: Contains ``Initialized`` value if the statistics are collected or ``Uninitialized`` if they are not collected. |
2291 | + :column NUM_ROWS: Estimated number of rows in the table. |
2292 | + :column CLUST_INDEX_SIZE: Number of pages on disk that store the clustered index. |
2293 | + :column OTHER_INDEX_SIZE: Number of pages on disk that store all secondary indexes. |
2294 | + :column MODIFIED_COUNTER: Number of rows modified by DML operations. |
2295 | + :column AUTOINC: |
2296 | + :column MYSQL_HANDLES_OPENED: |
2297 | + |
2298 | +.. table:: INFORMATION_SCHEMA.INNODB_SYS_INDEXES |
2299 | + |
2300 | + Shows the information about |InnoDB| indexes |
2301 | + |
2302 | + :column INDEX_ID: Index ID |
2303 | + :column NAME: Index Name |
2304 | + :column TABLE_ID: Table ID |
2305 | + :column TYPE: Numeric identifier signifying the index type |
2306 | + :column N_FIELDS: Number of columns in the index |
2307 | + :column PAGE_NO: Page offset within its tablespace |
2308 | + :column SPACE: Tablespace ID |
2309 | + |
2310 | +.. table:: INFORMATION_SCHEMA.INNODB_SYS_COLUMNS |
2311 | + |
2312 | + Shows the information about the |InnoDB| table columns |
2313 | + |
2314 | + :column TABLE_ID: Table ID |
2315 | + :column NAME: Column Name |
2316 | + :column POS: Position of the column inside the table. |
2317 | + :column MTYPE: Numeric identifier for the column type. |
2318 | + :column PRTYPE: Binary value with bits representing data type, character set code and nullability. |
2319 | + :column LEN: Column length. |
2320 | + |
2321 | +.. table:: INFORMATION_SCHEMA.INNODB_SYS_FIELDS |
2322 | + |
2323 | + Shows the information about the |InnoDB| index key fields. |
2324 | + |
2325 | + :column INDEX_ID: Index ID |
2326 | + :column NAME: Index Name |
2327 | + :column POS: Position of the field inside the index. |
2328 | + |
2329 | +.. table:: INFORMATION_SCHEMA.INNODB_SYS_FOREIGN |
2330 | + |
2331 | + Shows the information about the |InnoDB| foreign keys. |
2332 | + |
2333 | + :column ID: Foreign Key ID |
2334 | + :column FOR_NAME: Database/Table which contains the Foreign Key |
2335 | + :column FOR_REF: Database/Table being referenced by the Foreign Key |
2336 | + :column N_COLS: Number of columns in the foreign key. |
2337 | + :column TYPE: Type of foreign key, represented by the bit flags. |
2338 | + |
2339 | +.. table:: INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS |
2340 | + |
2341 | + Shows the information about the columns of the |InnoDB| foreign keys. |
2342 | + |
2343 | + :column ID: Foreign Key ID |
2344 | + :column FOR_COL_NAME: Foreign Key Column Name |
2345 | + :column FOR_REF: Referenced Column Name |
2346 | + :column POS: Position of the field inside the index. |
2347 | + |
2348 | +.. table:: INFORMATION_SCHEMA.INNODB_TABLE_STATS |
2349 | + |
2350 | + Shows table statistics information of dictionary cached. |
2351 | + |
2352 | + :column table_schema: Database name of the table. |
2353 | + :column table_name: Table name. |
2354 | + :column rows: estimated number of all rows. |
2355 | + :column clust_size: cluster index (table/primary key) size in number of pages. |
2356 | + :column other_size: Other index (non primary key) size in number of pages. |
2357 | + :column modified: Internal counter to judge whether statistics recalculation should be done. |
2358 | + |
2359 | +If the value of modified column exceeds "rows / 16" or 2000000000, the statistics recalculation is done when ``innodb_stats_auto_update == 1``. We can estimate the oldness of the statistics by this value. |
2360 | + |
2361 | +.. table:: INFORMATION_SCHEMA.INNODB_INDEX_STATS |
2362 | + |
2363 | + Shows index statistics information of dictionary cached. |
2364 | + |
2365 | + :column table_schema: Database name of the table. |
2366 | + :column table_name: Table name. |
2367 | + :column index_name: Index name. |
2368 | + :column fields: How many fields the index key has. (it is internal structure of |InnoDB|, it may be larger than the ``CREATE TABLE``). |
2369 | + :column rows_per_key: Estimate rows per 1 key value. ([1 column value], [2 columns value], [3 columns value], ...). |
2370 | + :column index_total_pages: Number of index pages. |
2371 | + :column index_leaf_pages: Number of leaf pages. |
2372 | + |
2373 | +In releases before 5.5.8-20.0, these fields had different names: |
2374 | + |
2375 | + * ``rows_per_key`` was ``row_per_keys`` |
2376 | + |
2377 | + * ``index_total_pages`` was ``index_size`` |
2378 | + |
2379 | + * ``index_leaf_pages`` was ``leaf_pages`` |
2380 | + |
2381 | +Example |
2382 | +======= |
2383 | + |
2384 | +``[innodb_stats_method = nulls_equal (default behavior of InnoDB)]`` :: |
2385 | + |
2386 | + mysql> explain SELECT COUNT(*), 0 FROM orgs2 orgs LEFT JOIN sa_opportunities2 sa_opportunities ON orgs.org_id=sa_opportunities.org_id LEFT JOIN contacts2 contacts ON orgs.org_id=contacts.org_id; |
2387 | + +----+-------------+------------------+-------+-----------------+-----------------+---------+-------------------+-------+-------------+ |
2388 | + | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | |
2389 | + +----+-------------+------------------+-------+-----------------+-----------------+---------+-------------------+-------+-------------+ |
2390 | + | 1 | SIMPLE | orgs | index | NULL | orgs$org_id | 4 | NULL | 128 | Using index | |
2391 | + | 1 | SIMPLE | sa_opportunities | ref | sa_opp$org_id | sa_opp$org_id | 5 | test2.orgs.org_id | 5751 | Using index | |
2392 | + | 1 | SIMPLE | contacts | ref | contacts$org_id | contacts$org_id | 5 | test2.orgs.org_id | 23756 | Using index | |
2393 | + +----+-------------+------------------+-------+-----------------+-----------------+---------+-------------------+-------+-------------+ |
2394 | + 3 rows in set (0.00 sec) |
2395 | + |
2396 | +``[innodb_stats_method = nulls_unequal or nulls_ignored]`` :: |
2397 | + |
2398 | + mysql> explain SELECT COUNT(*), 0 FROM orgs2 orgs LEFT JOIN sa_opportunities2 sa_opportunities ON orgs.org_id=sa_opportunities.org_id LEFT JOIN contacts2 contacts ON orgs.org_id=contacts.org_id; |
2399 | + +----+-------------+------------------+-------+-----------------+-----------------+---------+-------------------+------+-------------+ |
2400 | + | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | |
2401 | + +----+-------------+------------------+-------+-----------------+-----------------+---------+-------------------+------+-------------+ |
2402 | + | 1 | SIMPLE | orgs | index | NULL | orgs$org_id | 4 | NULL | 128 | Using index | |
2403 | + | 1 | SIMPLE | sa_opportunities | ref | sa_opp$org_id | sa_opp$org_id | 5 | test2.orgs.org_id | 1 | Using index | |
2404 | + | 1 | SIMPLE | contacts | ref | contacts$org_id | contacts$org_id | 5 | test2.orgs.org_id | 1 | Using index | |
2405 | + +----+-------------+------------------+-------+-----------------+-----------------+---------+-------------------+------+-------------+ |
2406 | + 3 rows in set (0.00 sec) |
2407 | + <example of information_schema> |
2408 | + |
2409 | + mysql> select * from information_schema.innodb_table_stats; |
2410 | + +------------------------+-------+------------+------------+----------+ |
2411 | + | table_name | rows | clust_size | other_size | modified | |
2412 | + +------------------------+-------+------------+------------+----------+ |
2413 | + | test/sa_opportunities2 | 11175 | 21 | 11 | 0 | |
2414 | + | test/orgs2 | 128 | 1 | 0 | 0 | |
2415 | + | test/contacts2 | 47021 | 97 | 97 | 0 | |
2416 | + +------------------------+-------+------------+------------+----------+ |
2417 | + 3 rows in set (0.00 sec) |
2418 | + |
2419 | + mysql> select * from information_schema.innodb_index_stats; |
2420 | + +------------------------+-----------------+--------+--------------+------------+------------+ |
2421 | + | table_name | index_name | fields | row_per_keys | index_size | leaf_pages | |
2422 | + +------------------------+-----------------+--------+--------------+------------+------------+ |
2423 | + | test/sa_opportunities2 | GEN_CLUST_INDEX | 1 | 1 | 21 | 20 | |
2424 | + | test/sa_opportunities2 | sa_opp$org_id | 2 | 338, 1 | 11| 10 | |
2425 | + | test/orgs2 | orgs$org_id | 1 | 1 | 1 | 1 | |
2426 | + | test/contacts2 | GEN_CLUST_INDEX | 1 | 1 | 97 | 80 | |
2427 | + | test/contacts2 | contacts$org_id | 2 | 516, 0 | 97 | 37 | |
2428 | + +------------------------+-----------------+--------+--------------+------------+------------+ |
2429 | + 5 rows in set (0.00 sec) |
2430 | + |
2431 | +Other reading |
2432 | +============= |
2433 | + |
2434 | + * `InnoDB Table/Index stats <http://www.mysqlperformanceblog.com/2010/03/20/InnoDB-tableindex-stats/>`_ |
2435 | + |
2436 | |
2437 | === removed file 'doc/source/flexibility/innodb_fast_shutdown.rst' |
2438 | --- doc/source/flexibility/innodb_fast_shutdown.rst 2013-05-28 06:50:44 +0000 |
2439 | +++ doc/source/flexibility/innodb_fast_shutdown.rst 1970-01-01 00:00:00 +0000 |
2440 | @@ -1,36 +0,0 @@ |
2441 | -.. _innodb_fast_shutdown: |
2442 | - |
2443 | -=============== |
2444 | - Fast Shutdown |
2445 | -=============== |
2446 | - |
2447 | -Some |InnoDB| / |XtraDB| threads which perform various background activities are in the sleep state most of the time. They only wake up every few seconds to perform their tasks. They also check whether the server is in the shutdown phase, and if not, they go to the sleep state again. That means there could be a noticeable delay (up to 10 seconds) after a shutdown command and before all |InnoDB| / |XtraDB| threads actually notice this and terminate. This is not a big problem for most production servers, because a shutdown of a heavily loaded server normally takes much longer than 10 seconds. |
2448 | - |
2449 | -The problem, however, had a significant impact on running the regression test suite, because it performs a lot of server restarts during its execution and also because there is not so much to do when shutting a test server. So it makes even less sense to wait up to 10 seconds. |
2450 | - |
2451 | -This change modifies that behavior to make the sleep waiting interruptible, so that when the server is told to shutdown, threads no longer wait until the end of their sleep interval. This results in a measurably faster test suite execution (~40% in some cases). |
2452 | - |
2453 | -The change was contributed by Kristian Nielsen. |
2454 | - |
2455 | -Version Specific Information |
2456 | -============================ |
2457 | - |
2458 | - * :rn:`5.5.8-20.0` |
2459 | - Full functionality available. |
2460 | - |
2461 | -Other Information |
2462 | -================= |
2463 | - |
2464 | - * Author / Origin: |
2465 | - Kristian Nielsen |
2466 | - |
2467 | - * Bugs fixed: |
2468 | - :bug:`643463` |
2469 | - |
2470 | -Other reading |
2471 | -============= |
2472 | - |
2473 | - * `How to decrease InnoDB shutdown times <http://www.mysqlperformanceblog.com/2009/04/15/how-to-decrease-innodb-shutdown-times/>`_ |
2474 | - |
2475 | - * `How long InnoDB shutdown may take <http://www.mysqlperformanceblog.com/2010/09/02/how-long-innodb-shutdown-may-take/>`_ |
2476 | - |
2477 | |
2478 | === removed file 'doc/source/management/innodb_expand_import.rst' |
2479 | --- doc/source/management/innodb_expand_import.rst 2013-05-28 06:50:44 +0000 |
2480 | +++ doc/source/management/innodb_expand_import.rst 1970-01-01 00:00:00 +0000 |
2481 | @@ -1,160 +0,0 @@ |
2482 | -.. _innodb_expand_import_page: |
2483 | - |
2484 | -=================== |
2485 | -Expand Table Import |
2486 | -=================== |
2487 | - |
2488 | -Unlike MyISAM, |InnoDB| does not allow users to copy datafiles for a single table between servers. If exported with XtraBackup, a table can now be imported on another server running |XtraDB|. |
2489 | - |
2490 | -This feature implements the abililty to import arbitrary .ibd files exported using the XtraBackup ``--export`` option. The :variable:`innodb_expand_import` variable makes to convert ``.ibd`` file during import process. |
2491 | - |
2492 | -The normal version can import only the backed-up .ibd file at the same place. |
2493 | - |
2494 | -.. note:: |
2495 | - |
2496 | - This feature is unsupported with InnoDB data files created with MySQL 5.0 and MySQL 5.1 prior to version 5.1.7 due to InnoDB file format limitation. It may work in some cases, but may result in crashes on import as well, see bug :bug:`1000221` and bug :bug:`727704` for examples and details. |
2497 | - |
2498 | -|Percona Server| :rn:`5.5.28-29.2` extended the ``innochecksum`` with an option :option:`-f` to read the file format information from a given |InnoDB| data file. As only the first page needs to be read to detect the format/version information, it can also be used on a running server. Example of the output should look like this: :: |
2499 | - |
2500 | - $ innochecksum -f ibdata1 |
2501 | - Detected file format: Antelope (5.1.7 or newer). |
2502 | - |
2503 | -Example |
2504 | -======= |
2505 | - |
2506 | -Assuming that: |
2507 | - |
2508 | - * :variable:`innodb_expand_import` is set to ``1``. |
2509 | - |
2510 | - * the files (``.ibd`` and ``.exp``) are prepared by the ``xtrabackup --prepare --export`` command. |
2511 | - |
2512 | -First create “exactly same” structured tables to the target database. |
2513 | - |
2514 | -Then discard the tables as preparation of import, for example, :: |
2515 | - |
2516 | - mysql> set FOREIGN_KEY_CHECKS=0; |
2517 | - Query OK, 0 rows affected (0.00 sec) |
2518 | - |
2519 | - mysql> alter table customer discard tablespace; |
2520 | - Query OK, 0 rows affected (0.01 sec) |
2521 | - |
2522 | - mysql> alter table district discard tablespace; |
2523 | - Query OK, 0 rows affected (0.01 sec) |
2524 | - |
2525 | - mysql> alter table history discard tablespace; |
2526 | - Query OK, 0 rows affected (0.00 sec) |
2527 | - |
2528 | - ... |
2529 | - put the .ibd and .exp files at the same place to .frm file. |
2530 | - import the tables |
2531 | - (command example) |
2532 | - mysql> set FOREIGN_KEY_CHECKS=0; |
2533 | - Query OK, 0 rows affected (0.00 sec) |
2534 | - |
2535 | - mysql> set global innodb_expand_import=1; |
2536 | - Query OK, 0 rows affected (0.00 sec) |
2537 | - |
2538 | - mysql> alter table customer import tablespace; |
2539 | - Query OK, 0 rows affected (0.17 sec) |
2540 | - |
2541 | - mysql> alter table district import tablespace; |
2542 | - Query OK, 0 rows affected (0.00 sec) |
2543 | - |
2544 | - mysql> alter table history import tablespace; |
2545 | - Query OK, 0 rows affected (0.04 sec) |
2546 | - |
2547 | - ... |
2548 | - (.err file example) |
2549 | - InnoDB: import: extended import of tpcc2/customer is started. |
2550 | - InnoDB: import: 2 indexes are detected. |
2551 | - InnoDB: Progress in %: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 done. |
2552 | - InnoDB: import: extended import of tpcc2/district is started. |
2553 | - InnoDB: import: 1 indexes are detected. |
2554 | - InnoDB: Progress in %: 16 33 50 66 83 100 done. |
2555 | - InnoDB: import: extended import of tpcc2/history is started. |
2556 | - InnoDB: import: 3 indexes are detected. |
2557 | - InnoDB: Progress in %: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 done. |
2558 | - ... |
2559 | - |
2560 | -Version Specific Information |
2561 | -============================ |
2562 | - |
2563 | - * 5.5.10-20.1: |
2564 | - Renamed variable :variable:`innodb_expand_import` to :variable:`innodb_import_table_from_xtrabackup`. |
2565 | - |
2566 | -System Variables |
2567 | -================ |
2568 | - |
2569 | -.. variable:: innodb_expand_import |
2570 | - |
2571 | - :version 5.5.10-20.1: Renamed. |
2572 | - :cli: Yes |
2573 | - :conf: Yes |
2574 | - :scope: Global |
2575 | - :dyn: Yes |
2576 | - :vartype: ULONG |
2577 | - :default: 0 |
2578 | - :range: 0-1 |
2579 | - |
2580 | -If set to 1, ``.ibd`` file is converted (``space id``, ``index id``, etc.) with index information in ``.exp`` file during the import process (``ALTER TABLE ... IMPORT TABLESPACE`` command). |
2581 | - |
2582 | - This variable was renamed to :variable:`innodb_import_table_from_xtrabackup`, beginning in release 5.5.10-20.1. It still exists as :variable:`innodb_expand_import` in versions prior to that. |
2583 | - |
2584 | - |
2585 | -.. variable:: innodb_import_table_from_xtrabackup |
2586 | - |
2587 | - :version 5.5.10-20.1: Introduced. |
2588 | - :cli: Yes |
2589 | - :conf: Yes |
2590 | - :scope: Global |
2591 | - :dyn: Yes |
2592 | - :vartype: ULONG |
2593 | - :default: 0 |
2594 | - :range: 0-1 |
2595 | - |
2596 | -If set to 1, ``.ibd`` file is converted (``space id``, ``index id``, etc.) with index information in .exp file during the import process (``ALTER TABLE ... IMPORT TABLESPACE`` command). |
2597 | - |
2598 | - This variable was added in release 5.5.10-20.1. Prior to that, it was named :variable:`innodb_expand_import`, which still exists in earlier versions. |
2599 | - |
2600 | - |
2601 | -.. Other Information |
2602 | - |
2603 | - |
2604 | -.. TODO |
2605 | - |
2606 | -.. Make |XtraDB| to be enable to export .exp file by itself. |
2607 | - |
2608 | -.. Suggestion 2 (expand "alter table ... discard tablespace") |
2609 | -.. New variable “innodb_export_at_discard = [0|1]”. When 1, |XtraDB| close the tablespace cleanly (no data in insertbuffer or to purge) and output .exp file at the same place to the .ibd file instead of deleting .ibd file only (default behavior), when “ALTER TABLE … DISCARD TABLESPACE”. |
2610 | - |
2611 | -.. I think The default value should be 1 for safety, because 0 deletes the table data… LOCK TABLE also may be needed before the operation (error when doesn``t have LOCK?). |
2612 | - |
2613 | -.. (example: move database named ``example``) |
2614 | - |
2615 | -.. Source: (innodb_export_at_discard should be 1) |
2616 | - |
2617 | -.. lock all tables in the database ``example`` |
2618 | -.. "ALTER TABLE ... DISCARD TABLESPACE" for all tables in ``exmple`` |
2619 | -.. unlock all tables in the database ``example`` |
2620 | -.. (and we need to get all create table clause (e.g. "mysqldump --no-data")) |
2621 | -.. obtain *.ibd *.exp as exported files |
2622 | -.. Target: (innodb_expand_import should be 1) |
2623 | - |
2624 | -.. create all tables in ``example`` |
2625 | -.. "ALTER TABLE ... DISCARD TABLESPACE" for all tables in ``exmple`` |
2626 | -.. overwrite *.ibd and put *.exp from the Target |
2627 | -.. "ALTER TABLE ... IMPORT TABLESPACE" for all tables in ``exmple`` |
2628 | -.. I think making the shell to do the above operations automatically is much easier than implement the new SQLs to do them… |
2629 | - |
2630 | -.. Suggestion 1 (at shutdown [too simple... **rejected**...]) |
2631 | -.. New variable “innodb_export_exp_at_shutdown = [0|1]”. When 1, |XtraDB| outputs .exp files for all |InnoDB| tables at clean shutdown. (works file_per_table mode inly) |
2632 | - |
2633 | -.. XtraDB must treat also .exp files along with .ibd files. (e.g. delete files when delete table) |
2634 | - |
2635 | - |
2636 | -Other reading |
2637 | -============= |
2638 | - |
2639 | - * `Moving InnoDB tables between servers <http://www.mysqlperformanceblog.com/2009/06/08/impossible-possible-moving-innodb-tables-between-servers/>`_ |
2640 | - |
2641 | - * `Copying InnoDB tables between servers <http://www.mysqlperformanceblog.com/2009/07/31/copying-innodb-tables-between-servers/>`_ |
2642 | |
2643 | === removed file 'doc/source/percona-xtradb.png' |
2644 | Binary files doc/source/percona-xtradb.png 2013-05-28 06:50:44 +0000 and doc/source/percona-xtradb.png 1970-01-01 00:00:00 +0000 differ |
2645 | === added directory 'python-for-subunit2junitxml' |
2646 | === added file 'python-for-subunit2junitxml/BytesIO.py' |
2647 | --- python-for-subunit2junitxml/BytesIO.py 1970-01-01 00:00:00 +0000 |
2648 | +++ python-for-subunit2junitxml/BytesIO.py 2013-05-28 06:50:46 +0000 |
2649 | @@ -0,0 +1,136 @@ |
2650 | + |
2651 | +# http://wiki.python.org/moin/BytesIO |
2652 | +# |
2653 | +# A skeleton one used for systems that don't have BytesIO. |
2654 | +# |
2655 | +# It's enough for subunit at least.... |
2656 | + |
2657 | +class BytesIO(object): |
2658 | + """ A file-like API for reading and writing bytes objects. |
2659 | + |
2660 | + Mostly like StringIO, but write() calls modify the underlying |
2661 | + bytes object. |
2662 | + |
2663 | + >>> b = bytes() |
2664 | + >>> f = BytesIO(b, 'w') |
2665 | + >>> f.write(bytes.fromhex('ca fe ba be')) |
2666 | + >>> f.write(bytes.fromhex('57 41 56 45')) |
2667 | + >>> b |
2668 | + bytes([202, 254, 186, 190, 87, 65, 86, 69]) |
2669 | + """ |
2670 | + |
2671 | + def __init__(self, buf, mode='r'): |
2672 | + """ Create a new BytesIO for reading or writing the given buffer. |
2673 | + |
2674 | + buf - Back-end buffer for this BytesIO. A bytes object. |
2675 | + Actually, anything that supports len(), slice-assignment, |
2676 | + and += will work. |
2677 | + mode - One of 'r', 'w', 'a'. |
2678 | + An optional 'b' is also allowed, but it doesn't do anything. |
2679 | + """ |
2680 | + # XXX many 'mode' possibilities aren't allowed yet: 'rw+Ut' |
2681 | + if len(mode) == 2 and mode[-1] == 'b': |
2682 | + mode = mode[:-1] # binary mode goes without saying |
2683 | + if mode not in ('r', 'w', 'a'): |
2684 | + raise ValueError("mode must be 'r', 'w', or 'a'") |
2685 | + |
2686 | + self._buf = buf |
2687 | + self.mode = mode |
2688 | + self.closed = False |
2689 | + if self.mode == 'w': |
2690 | + del buf[:] |
2691 | + self._point = 0 |
2692 | + elif self.mode == 'r': |
2693 | + self._point = 0 |
2694 | + else: # 'a' |
2695 | + self._point = len(buf) |
2696 | + |
2697 | + def close(self): |
2698 | + self.closed = True |
2699 | + |
2700 | + def _check_closed(self): |
2701 | + if self.closed: |
2702 | + raise ValueError("file is closed") |
2703 | + |
2704 | + def flush(self): |
2705 | + self._check_closed() |
2706 | + |
2707 | + def next(self): |
2708 | + line = self.readline() |
2709 | + if len(line) == 0: |
2710 | + raise StopIteration |
2711 | + return line |
2712 | + |
2713 | + def read(self, size=None): |
2714 | + self._check_closed() |
2715 | + if size is None: |
2716 | + e = len(self._buf) |
2717 | + else: |
2718 | + e = min(self._point + size, len(self._buf)) |
2719 | + r = self._buf[self._point:e] |
2720 | + self._point = e |
2721 | + return r |
2722 | + |
2723 | + def readline(self, size=None): |
2724 | + self._check_closed() |
2725 | + die # XXX TODO - assume ascii and read a line |
2726 | + |
2727 | + def readlines(self, sizehint=None): |
2728 | + # XXX TODO handle sizehint |
2729 | + return list(self) |
2730 | + |
2731 | + def seek(self, offset, whence=0): |
2732 | + self._check_closed() |
2733 | + |
2734 | + if whence == 0: |
2735 | + self._point = offset |
2736 | + elif whence == 1: |
2737 | + self._point += offset |
2738 | + elif whence == 2: |
2739 | + self._point = len(self._buf) + offset |
2740 | + else: |
2741 | + raise ValueError("whence must be 0, 1, or 2") |
2742 | + |
2743 | + if self._point < 0: |
2744 | + self._point = 0 # XXX is this right? |
2745 | + |
2746 | + def tell(self): |
2747 | + self._check_closed() |
2748 | + return self._point |
2749 | + |
2750 | + def truncate(self, size=None): |
2751 | + self._check_closed() |
2752 | + if size is None: |
2753 | + size = self.tell() |
2754 | + del self._buf[size:] |
2755 | + |
2756 | + def write(self, data): |
2757 | + self._check_closed() |
2758 | + amt = len(data) |
2759 | + size = len(self._buf) |
2760 | + if self.mode == 'a': |
2761 | + self._point = size |
2762 | + |
2763 | + if self._point > size: |
2764 | + if isinstance(b, bytes): |
2765 | + blank = bytes([0]) |
2766 | + else: |
2767 | + # Don't know what default value to insert, unfortunately |
2768 | + raise ValueError("can't write past the end of this object") |
2769 | + self._buf += blank * (self._point - size) + data |
2770 | + self._point = len(self._buf) |
2771 | + else: |
2772 | + p = self._point |
2773 | + self._buf[p:p + amt] = data |
2774 | + self._point = min(p + amt, len(self._buf)) |
2775 | + |
2776 | + def writelines(self, seq): |
2777 | + for line in seq: |
2778 | + self.write(line) |
2779 | + |
2780 | + def __iter__(self): |
2781 | + return self |
2782 | + |
2783 | + @property |
2784 | + def name(self): |
2785 | + return repr(self) |
2786 | |
2787 | === added directory 'python-for-subunit2junitxml/iso8601' |
2788 | === added file 'python-for-subunit2junitxml/iso8601/LICENSE' |
2789 | --- python-for-subunit2junitxml/iso8601/LICENSE 1970-01-01 00:00:00 +0000 |
2790 | +++ python-for-subunit2junitxml/iso8601/LICENSE 2013-05-28 06:50:46 +0000 |
2791 | @@ -0,0 +1,20 @@ |
2792 | +Copyright (c) 2007 Michael Twomey |
2793 | + |
2794 | +Permission is hereby granted, free of charge, to any person obtaining a |
2795 | +copy of this software and associated documentation files (the |
2796 | +"Software"), to deal in the Software without restriction, including |
2797 | +without limitation the rights to use, copy, modify, merge, publish, |
2798 | +distribute, sublicense, and/or sell copies of the Software, and to |
2799 | +permit persons to whom the Software is furnished to do so, subject to |
2800 | +the following conditions: |
2801 | + |
2802 | +The above copyright notice and this permission notice shall be included |
2803 | +in all copies or substantial portions of the Software. |
2804 | + |
2805 | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
2806 | +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
2807 | +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
2808 | +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
2809 | +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
2810 | +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
2811 | +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
2812 | |
2813 | === added file 'python-for-subunit2junitxml/iso8601/README' |
2814 | --- python-for-subunit2junitxml/iso8601/README 1970-01-01 00:00:00 +0000 |
2815 | +++ python-for-subunit2junitxml/iso8601/README 2013-05-28 06:50:46 +0000 |
2816 | @@ -0,0 +1,26 @@ |
2817 | +A simple package to deal with ISO 8601 date time formats. |
2818 | + |
2819 | +ISO 8601 defines a neutral, unambiguous date string format, which also |
2820 | +has the property of sorting naturally. |
2821 | + |
2822 | +e.g. YYYY-MM-DDTHH:MM:SSZ or 2007-01-25T12:00:00Z |
2823 | + |
2824 | +Currently this covers only the most common date formats encountered, not |
2825 | +all of ISO 8601 is handled. |
2826 | + |
2827 | +Currently the following formats are handled: |
2828 | + |
2829 | +* 2006-01-01T00:00:00Z |
2830 | +* 2006-01-01T00:00:00[+-]00:00 |
2831 | + |
2832 | +I'll add more as I encounter them in my day to day life. Patches with |
2833 | +new formats and tests will be gratefully accepted of course :) |
2834 | + |
2835 | +References: |
2836 | + |
2837 | +* http://www.cl.cam.ac.uk/~mgk25/iso-time.html - simple overview |
2838 | + |
2839 | +* http://hydracen.com/dx/iso8601.htm - more detailed enumeration of |
2840 | + valid formats. |
2841 | + |
2842 | +See the LICENSE file for the license this package is released under. |
2843 | |
2844 | === added file 'python-for-subunit2junitxml/iso8601/README.subunit' |
2845 | --- python-for-subunit2junitxml/iso8601/README.subunit 1970-01-01 00:00:00 +0000 |
2846 | +++ python-for-subunit2junitxml/iso8601/README.subunit 2013-05-28 06:50:46 +0000 |
2847 | @@ -0,0 +1,5 @@ |
2848 | +This is a [slightly rearranged] import of http://pypi.python.org/pypi/iso8601/ |
2849 | +version 0.1.4. The OS X hidden files have been stripped, and the package |
2850 | +turned into a single module, to simplify installation. The remainder of the |
2851 | +source distribution is included in the subunit source tree at python/iso8601 |
2852 | +for reference. |
2853 | |
2854 | === added file 'python-for-subunit2junitxml/iso8601/setup.py' |
2855 | --- python-for-subunit2junitxml/iso8601/setup.py 1970-01-01 00:00:00 +0000 |
2856 | +++ python-for-subunit2junitxml/iso8601/setup.py 2013-05-28 06:50:46 +0000 |
2857 | @@ -0,0 +1,58 @@ |
2858 | +try: |
2859 | + from setuptools import setup |
2860 | +except ImportError: |
2861 | + from distutils import setup |
2862 | + |
2863 | +long_description="""Simple module to parse ISO 8601 dates |
2864 | + |
2865 | +This module parses the most common forms of ISO 8601 date strings (e.g. |
2866 | +2007-01-14T20:34:22+00:00) into datetime objects. |
2867 | + |
2868 | +>>> import iso8601 |
2869 | +>>> iso8601.parse_date("2007-01-25T12:00:00Z") |
2870 | +datetime.datetime(2007, 1, 25, 12, 0, tzinfo=<iso8601.iso8601.Utc ...>) |
2871 | +>>> |
2872 | + |
2873 | +Changes |
2874 | +======= |
2875 | + |
2876 | +0.1.4 |
2877 | +----- |
2878 | + |
2879 | +* The default_timezone argument wasn't being passed through correctly, |
2880 | + UTC was being used in every case. Fixes issue 10. |
2881 | + |
2882 | +0.1.3 |
2883 | +----- |
2884 | + |
2885 | +* Fixed the microsecond handling, the generated microsecond values were |
2886 | + way too small. Fixes issue 9. |
2887 | + |
2888 | +0.1.2 |
2889 | +----- |
2890 | + |
2891 | +* Adding ParseError to __all__ in iso8601 module, allows people to import it. |
2892 | + Addresses issue 7. |
2893 | +* Be a little more flexible when dealing with dates without leading zeroes. |
2894 | + This violates the spec a little, but handles more dates as seen in the |
2895 | + field. Addresses issue 6. |
2896 | +* Allow date/time separators other than T. |
2897 | + |
2898 | +0.1.1 |
2899 | +----- |
2900 | + |
2901 | +* When parsing dates without a timezone the specified default is used. If no |
2902 | + default is specified then UTC is used. Addresses issue 4. |
2903 | +""" |
2904 | + |
2905 | +setup( |
2906 | + name="iso8601", |
2907 | + version="0.1.4", |
2908 | + description=long_description.split("\n")[0], |
2909 | + long_description=long_description, |
2910 | + author="Michael Twomey", |
2911 | + author_email="micktwomey+iso8601@gmail.com", |
2912 | + url="http://code.google.com/p/pyiso8601/", |
2913 | + packages=["iso8601"], |
2914 | + license="MIT", |
2915 | +) |
2916 | |
2917 | === added file 'python-for-subunit2junitxml/iso8601/test_iso8601.py' |
2918 | --- python-for-subunit2junitxml/iso8601/test_iso8601.py 1970-01-01 00:00:00 +0000 |
2919 | +++ python-for-subunit2junitxml/iso8601/test_iso8601.py 2013-05-28 06:50:46 +0000 |
2920 | @@ -0,0 +1,111 @@ |
2921 | +import iso8601 |
2922 | + |
2923 | +def test_iso8601_regex(): |
2924 | + assert iso8601.ISO8601_REGEX.match("2006-10-11T00:14:33Z") |
2925 | + |
2926 | +def test_timezone_regex(): |
2927 | + assert iso8601.TIMEZONE_REGEX.match("+01:00") |
2928 | + assert iso8601.TIMEZONE_REGEX.match("+00:00") |
2929 | + assert iso8601.TIMEZONE_REGEX.match("+01:20") |
2930 | + assert iso8601.TIMEZONE_REGEX.match("-01:00") |
2931 | + |
2932 | +def test_parse_date(): |
2933 | + d = iso8601.parse_date("2006-10-20T15:34:56Z") |
2934 | + assert d.year == 2006 |
2935 | + assert d.month == 10 |
2936 | + assert d.day == 20 |
2937 | + assert d.hour == 15 |
2938 | + assert d.minute == 34 |
2939 | + assert d.second == 56 |
2940 | + assert d.tzinfo == iso8601.UTC |
2941 | + |
2942 | +def test_parse_date_fraction(): |
2943 | + d = iso8601.parse_date("2006-10-20T15:34:56.123Z") |
2944 | + assert d.year == 2006 |
2945 | + assert d.month == 10 |
2946 | + assert d.day == 20 |
2947 | + assert d.hour == 15 |
2948 | + assert d.minute == 34 |
2949 | + assert d.second == 56 |
2950 | + assert d.microsecond == 123000 |
2951 | + assert d.tzinfo == iso8601.UTC |
2952 | + |
2953 | +def test_parse_date_fraction_2(): |
2954 | + """From bug 6 |
2955 | + |
2956 | + """ |
2957 | + d = iso8601.parse_date("2007-5-7T11:43:55.328Z'") |
2958 | + assert d.year == 2007 |
2959 | + assert d.month == 5 |
2960 | + assert d.day == 7 |
2961 | + assert d.hour == 11 |
2962 | + assert d.minute == 43 |
2963 | + assert d.second == 55 |
2964 | + assert d.microsecond == 328000 |
2965 | + assert d.tzinfo == iso8601.UTC |
2966 | + |
2967 | +def test_parse_date_tz(): |
2968 | + d = iso8601.parse_date("2006-10-20T15:34:56.123+02:30") |
2969 | + assert d.year == 2006 |
2970 | + assert d.month == 10 |
2971 | + assert d.day == 20 |
2972 | + assert d.hour == 15 |
2973 | + assert d.minute == 34 |
2974 | + assert d.second == 56 |
2975 | + assert d.microsecond == 123000 |
2976 | + assert d.tzinfo.tzname(None) == "+02:30" |
2977 | + offset = d.tzinfo.utcoffset(None) |
2978 | + assert offset.days == 0 |
2979 | + assert offset.seconds == 60 * 60 * 2.5 |
2980 | + |
2981 | +def test_parse_invalid_date(): |
2982 | + try: |
2983 | + iso8601.parse_date(None) |
2984 | + except iso8601.ParseError: |
2985 | + pass |
2986 | + else: |
2987 | + assert 1 == 2 |
2988 | + |
2989 | +def test_parse_invalid_date2(): |
2990 | + try: |
2991 | + iso8601.parse_date("23") |
2992 | + except iso8601.ParseError: |
2993 | + pass |
2994 | + else: |
2995 | + assert 1 == 2 |
2996 | + |
2997 | +def test_parse_no_timezone(): |
2998 | + """issue 4 - Handle datetime string without timezone |
2999 | + |
3000 | + This tests what happens when you parse a date with no timezone. While not |
3001 | + strictly correct this is quite common. I'll assume UTC for the time zone |
3002 | + in this case. |
3003 | + """ |
3004 | + d = iso8601.parse_date("2007-01-01T08:00:00") |
3005 | + assert d.year == 2007 |
3006 | + assert d.month == 1 |
3007 | + assert d.day == 1 |
3008 | + assert d.hour == 8 |
3009 | + assert d.minute == 0 |
3010 | + assert d.second == 0 |
3011 | + assert d.microsecond == 0 |
3012 | + assert d.tzinfo == iso8601.UTC |
3013 | + |
3014 | +def test_parse_no_timezone_different_default(): |
3015 | + tz = iso8601.FixedOffset(2, 0, "test offset") |
3016 | + d = iso8601.parse_date("2007-01-01T08:00:00", default_timezone=tz) |
3017 | + assert d.tzinfo == tz |
3018 | + |
3019 | +def test_space_separator(): |
3020 | + """Handle a separator other than T |
3021 | + |
3022 | + """ |
3023 | + d = iso8601.parse_date("2007-06-23 06:40:34.00Z") |
3024 | + assert d.year == 2007 |
3025 | + assert d.month == 6 |
3026 | + assert d.day == 23 |
3027 | + assert d.hour == 6 |
3028 | + assert d.minute == 40 |
3029 | + assert d.second == 34 |
3030 | + assert d.microsecond == 0 |
3031 | + assert d.tzinfo == iso8601.UTC |
3032 | |
3033 | === added directory 'python-for-subunit2junitxml/junitxml' |
3034 | === added file 'python-for-subunit2junitxml/junitxml/__init__.py' |
3035 | --- python-for-subunit2junitxml/junitxml/__init__.py 1970-01-01 00:00:00 +0000 |
3036 | +++ python-for-subunit2junitxml/junitxml/__init__.py 2013-05-28 06:50:46 +0000 |
3037 | @@ -0,0 +1,221 @@ |
3038 | +# |
3039 | +# junitxml: extensions to Python unittest to get output junitxml |
3040 | +# Copyright (C) 2009 Robert Collins <robertc@robertcollins.net> |
3041 | +# |
3042 | +# Copying permitted under the LGPL-3 licence, included with this library. |
3043 | + |
3044 | +"""unittest compatible JUnit XML output.""" |
3045 | + |
3046 | + |
3047 | +import datetime |
3048 | +import re |
3049 | +import time |
3050 | +import unittest |
3051 | + |
3052 | +# same format as sys.version_info: "A tuple containing the five components of |
3053 | +# the version number: major, minor, micro, releaselevel, and serial. All |
3054 | +# values except releaselevel are integers; the release level is 'alpha', |
3055 | +# 'beta', 'candidate', or 'final'. The version_info value corresponding to the |
3056 | +# Python version 2.0 is (2, 0, 0, 'final', 0)." Additionally we use a |
3057 | +# releaselevel of 'dev' for unreleased under-development code. |
3058 | +# |
3059 | +# If the releaselevel is 'alpha' then the major/minor/micro components are not |
3060 | +# established at this point, and setup.py will use a version of next-$(revno). |
3061 | +# If the releaselevel is 'final', then the tarball will be major.minor.micro. |
3062 | +# Otherwise it is major.minor.micro~$(revno). |
3063 | +__version__ = (0, 7, 0, 'alpha', 0) |
3064 | + |
3065 | + |
3066 | +def test_suite(): |
3067 | + import junitxml.tests |
3068 | + return junitxml.tests.test_suite() |
3069 | + |
3070 | + |
3071 | +class LocalTimezone(datetime.tzinfo): |
3072 | + |
3073 | + def __init__(self): |
3074 | + self._offset = None |
3075 | + |
3076 | + # It seems that the minimal possible implementation is to just return all |
3077 | + # None for every function, but then it breaks... |
3078 | + def utcoffset(self, dt): |
3079 | + if self._offset is None: |
3080 | + t = 1260423030 # arbitrary, but doesn't handle dst very well |
3081 | + dt = datetime.datetime |
3082 | + self._offset = (dt.fromtimestamp(t) - dt.utcfromtimestamp(t)) |
3083 | + return self._offset |
3084 | + |
3085 | + def dst(self, dt): |
3086 | + return datetime.timedelta(0) |
3087 | + |
3088 | + def tzname(self, dt): |
3089 | + return None |
3090 | + |
3091 | + |
3092 | +def _error_name(eclass): |
3093 | + module = eclass.__module__ |
3094 | + if module not in ("__main__", "builtins", "exceptions"): |
3095 | + return ".".join([module, eclass.__name__]) |
3096 | + return eclass.__name__ |
3097 | + |
3098 | + |
3099 | +_non_cdata = "[\0-\b\x0B-\x1F\uD800-\uDFFF\uFFFE\uFFFF]+" |
3100 | +if "\\u" in _non_cdata: |
3101 | + _non_cdata = _non_cdata.decode("unicode-escape") |
3102 | + def _strip_invalid_chars(s, _sub=re.compile(_non_cdata, re.UNICODE).sub): |
3103 | + if not isinstance(s, unicode): |
3104 | + try: |
3105 | + s = s.decode("utf-8") |
3106 | + except UnicodeDecodeError: |
3107 | + s = s.decode("ascii", "replace") |
3108 | + return _sub("", s).encode("utf-8") |
3109 | +else: |
3110 | + def _strip_invalid_chars(s, _sub=re.compile(_non_cdata, re.UNICODE).sub): |
3111 | + return _sub("", s) |
3112 | +def _escape_content(s): |
3113 | + return (_strip_invalid_chars(s) |
3114 | + .replace("&", "&") |
3115 | + .replace("<", "<") |
3116 | + .replace("]]>", "]]>")) |
3117 | +def _escape_attr(s): |
3118 | + return (_strip_invalid_chars(s) |
3119 | + .replace("&", "&") |
3120 | + .replace("<", "<") |
3121 | + .replace("]]>", "]]>") |
3122 | + .replace('"', """) |
3123 | + .replace("\t", "	") |
3124 | + .replace("\n", "
")) |
3125 | + |
3126 | + |
3127 | +class JUnitXmlResult(unittest.TestResult): |
3128 | + """A TestResult which outputs JUnit compatible XML.""" |
3129 | + |
3130 | + def __init__(self, stream): |
3131 | + """Create a JUnitXmlResult. |
3132 | + |
3133 | + :param stream: A stream to write results to. Note that due to the |
3134 | + nature of JUnit XML output, nnothing will be written to the stream |
3135 | + until stopTestRun() is called. |
3136 | + """ |
3137 | + self.__super = super(JUnitXmlResult, self) |
3138 | + self.__super.__init__() |
3139 | + # GZ 2010-09-03: We have a problem if passed a text stream in Python 3 |
3140 | + # as really we want to write raw UTF-8 to ensure that |
3141 | + # the encoding is not mangled later |
3142 | + self._stream = stream |
3143 | + self._results = [] |
3144 | + self._set_time = None |
3145 | + self._test_start = None |
3146 | + self._run_start = None |
3147 | + self._tz_info = None |
3148 | + |
3149 | + def startTestRun(self): |
3150 | + """Start a test run.""" |
3151 | + self._run_start = self._now() |
3152 | + |
3153 | + def _get_tzinfo(self): |
3154 | + if self._tz_info is None: |
3155 | + self._tz_info = LocalTimezone() |
3156 | + return self._tz_info |
3157 | + |
3158 | + def _now(self): |
3159 | + if self._set_time is not None: |
3160 | + return self._set_time |
3161 | + else: |
3162 | + return datetime.datetime.now(self._get_tzinfo()) |
3163 | + |
3164 | + def time(self, a_datetime): |
3165 | + self._set_time = a_datetime |
3166 | + if (self._run_start is not None and |
3167 | + self._run_start > a_datetime): |
3168 | + self._run_start = a_datetime |
3169 | + |
3170 | + def startTest(self, test): |
3171 | + self.__super.startTest(test) |
3172 | + self._test_start = self._now() |
3173 | + |
3174 | + def _duration(self, from_datetime): |
3175 | + try: |
3176 | + delta = self._now() - from_datetime |
3177 | + except TypeError: |
3178 | + n = self._now() |
3179 | + delta = datetime.timedelta(-1) |
3180 | + seconds = delta.days * 3600*24 + delta.seconds |
3181 | + return seconds + 0.000001 * delta.microseconds |
3182 | + |
3183 | + def _test_case_string(self, test): |
3184 | + duration = self._duration(self._test_start) |
3185 | + test_id = test.id() |
3186 | + # Split on the last dot not inside a parameter |
3187 | + class_end = test_id.rfind(".", 0, test_id.find("(")) |
3188 | + if class_end == -1: |
3189 | + classname, name = "", test_id |
3190 | + else: |
3191 | + classname, name = test_id[:class_end], test_id[class_end+1:] |
3192 | + self._results.append('<testcase classname="%s" name="%s" ' |
3193 | + 'time="%0.3f"' % (_escape_attr(classname), _escape_attr(name), duration)) |
3194 | + |
3195 | + def stopTestRun(self): |
3196 | + """Stop a test run. |
3197 | + |
3198 | + This allows JUnitXmlResult to output the XML representation of the test |
3199 | + run. |
3200 | + """ |
3201 | + duration = self._duration(self._run_start) |
3202 | + self._stream.write('<testsuite errors="%d" failures="%d" name="" ' |
3203 | + 'tests="%d" time="%0.3f">\n' % (len(self.errors), |
3204 | + len(self.failures) + len(getattr(self, "unexpectedSuccesses", ())), |
3205 | + self.testsRun, duration)) |
3206 | + self._stream.write(''.join(self._results)) |
3207 | + self._stream.write('</testsuite>\n') |
3208 | + |
3209 | + def addError(self, test, error): |
3210 | + self.__super.addError(test, error) |
3211 | + self._test_case_string(test) |
3212 | + self._results.append('>\n') |
3213 | + self._results.append('<error type="%s">%s</error>\n</testcase>\n' % ( |
3214 | + _escape_attr(_error_name(error[0])), |
3215 | + _escape_content(self._exc_info_to_string(error, test)))) |
3216 | + |
3217 | + def addFailure(self, test, error): |
3218 | + self.__super.addFailure(test, error) |
3219 | + self._test_case_string(test) |
3220 | + self._results.append('>\n') |
3221 | + self._results.append('<failure type="%s">%s</failure>\n</testcase>\n' % |
3222 | + (_escape_attr(_error_name(error[0])), |
3223 | + _escape_content(self._exc_info_to_string(error, test)))) |
3224 | + |
3225 | + def addSuccess(self, test): |
3226 | + self.__super.addSuccess(test) |
3227 | + self._test_case_string(test) |
3228 | + self._results.append('/>\n') |
3229 | + |
3230 | + def addSkip(self, test, reason): |
3231 | + try: |
3232 | + self.__super.addSkip(test, reason) |
3233 | + except AttributeError: |
3234 | + # Python < 2.7|3.1 |
3235 | + pass |
3236 | + self._test_case_string(test) |
3237 | + self._results.append('>\n') |
3238 | + self._results.append('<skip>%s</skip>\n</testcase>\n'% _escape_attr(reason)) |
3239 | + |
3240 | + def addUnexpectedSuccess(self, test): |
3241 | + try: |
3242 | + self.__super.addUnexpectedSuccess(test) |
3243 | + except AttributeError: |
3244 | + # Python < 2.7|3.1 |
3245 | + pass |
3246 | + self._test_case_string(test) |
3247 | + self._results.append('>\n') |
3248 | + self._results.append('<failure type="unittest.case._UnexpectedSuccess"/>\n</testcase>\n') |
3249 | + |
3250 | + def addExpectedFailure(self, test, error): |
3251 | + try: |
3252 | + self.__super.addExpectedFailure(test, error) |
3253 | + except AttributeError: |
3254 | + # Python < 2.7|3.1 |
3255 | + pass |
3256 | + self._test_case_string(test) |
3257 | + self._results.append('/>\n') |
3258 | + |
3259 | |
3260 | === added directory 'python-for-subunit2junitxml/junitxml/tests' |
3261 | === added file 'python-for-subunit2junitxml/junitxml/tests/__init__.py' |
3262 | --- python-for-subunit2junitxml/junitxml/tests/__init__.py 1970-01-01 00:00:00 +0000 |
3263 | +++ python-for-subunit2junitxml/junitxml/tests/__init__.py 2013-05-28 06:50:46 +0000 |
3264 | @@ -0,0 +1,16 @@ |
3265 | +# |
3266 | +# junitxml: extensions to Python unittest to get output junitxml |
3267 | +# Copyright (C) 2009 Robert Collins <robertc@robertcollins.net> |
3268 | +# |
3269 | +# Copying permitted under the LGPL-3 licence, included with this library. |
3270 | + |
3271 | +import unittest |
3272 | + |
3273 | +from junitxml.tests import ( |
3274 | + test_junitxml, |
3275 | + ) |
3276 | + |
3277 | +def test_suite(): |
3278 | + return unittest.TestLoader().loadTestsFromNames([ |
3279 | + 'junitxml.tests.test_junitxml', |
3280 | + ]) |
3281 | |
3282 | === added file 'python-for-subunit2junitxml/junitxml/tests/test_junitxml.py' |
3283 | --- python-for-subunit2junitxml/junitxml/tests/test_junitxml.py 1970-01-01 00:00:00 +0000 |
3284 | +++ python-for-subunit2junitxml/junitxml/tests/test_junitxml.py 2013-05-28 06:50:46 +0000 |
3285 | @@ -0,0 +1,327 @@ |
3286 | +# |
3287 | +# junitxml: extensions to Python unittest to get output junitxml |
3288 | +# Copyright (C) 2009 Robert Collins <robertc@robertcollins.net> |
3289 | +# |
3290 | +# Copying permitted under the LGPL-3 licence, included with this library. |
3291 | + |
3292 | + |
3293 | +try: |
3294 | + from cStringIO import StringIO |
3295 | +except ImportError: |
3296 | + from io import StringIO |
3297 | +import datetime |
3298 | +import re |
3299 | +import sys |
3300 | +import unittest |
3301 | +import xml.dom.minidom |
3302 | + |
3303 | +import junitxml |
3304 | + |
3305 | +class TestImports(unittest.TestCase): |
3306 | + |
3307 | + def test_result(self): |
3308 | + from junitxml import JUnitXmlResult |
3309 | + |
3310 | + |
3311 | +class TestJUnitXmlResult__init__(unittest.TestCase): |
3312 | + |
3313 | + def test_with_stream(self): |
3314 | + result = junitxml.JUnitXmlResult(StringIO()) |
3315 | + |
3316 | + |
3317 | +class TestJUnitXmlResult(unittest.TestCase): |
3318 | + |
3319 | + def setUp(self): |
3320 | + self.output = StringIO() |
3321 | + self.result = junitxml.JUnitXmlResult(self.output) |
3322 | + |
3323 | + def get_output(self): |
3324 | + output = self.output.getvalue() |
3325 | + # Collapse detailed regions into specific strings we can match on |
3326 | + return re.sub(r'(?s)<failure (.*?)>.*?</failure>', |
3327 | + r'<failure \1>failure</failure>', re.sub( |
3328 | + r'(?s)<error (.*?)>.*?</error>', r'<error \1>error</error>', |
3329 | + re.sub(r'time="\d+\.\d+"', 'time="0.000"', output))) |
3330 | + |
3331 | + def run_test_or_simulate(self, test, method_name, manual_method, |
3332 | + *manual_args): |
3333 | + if getattr(test, method_name, None): |
3334 | + test.run(self.result) |
3335 | + else: |
3336 | + # older python - manually execute |
3337 | + self.result.startTest(test) |
3338 | + manual_method(test, *manual_args) |
3339 | + self.result.stopTest(test) |
3340 | + |
3341 | + def test_run_duration_handles_datestamping_in_the_past(self): |
3342 | + # When used via subunit2junitxml, startTestRun is called before |
3343 | + # any tz info in the test stream has been seen. |
3344 | + # So, we use the earliest reported timestamp as the start time, |
3345 | + # replacing _test_start if needed. |
3346 | + self.result.startTestRun() # the time is now. |
3347 | + # Lose an hour (peeks inside, a little naughty but not very). |
3348 | + self.result.time(self.result._run_start - datetime.timedelta(0, 3600)) |
3349 | + self.result.stopTestRun() |
3350 | + self.assertEqual("""<testsuite errors="0" failures="0" name="" tests="0" time="0.000"> |
3351 | +</testsuite> |
3352 | +""", self.get_output()) |
3353 | + |
3354 | + def test_startTestRun_no_output(self): |
3355 | + # startTestRun doesn't output anything, because JUnit wants an up-front |
3356 | + # summary. |
3357 | + self.result.startTestRun() |
3358 | + self.assertEqual('', self.get_output()) |
3359 | + |
3360 | + def test_stopTestRun_outputs(self): |
3361 | + # When stopTestRun is called, everything is output. |
3362 | + self.result.startTestRun() |
3363 | + self.result.stopTestRun() |
3364 | + self.assertEqual("""<testsuite errors="0" failures="0" name="" tests="0" time="0.000"> |
3365 | +</testsuite> |
3366 | +""", self.get_output()) |
3367 | + |
3368 | + def test_test_count(self): |
3369 | + class Passes(unittest.TestCase): |
3370 | + def test_me(self): |
3371 | + pass |
3372 | + self.result.startTestRun() |
3373 | + Passes("test_me").run(self.result) |
3374 | + Passes("test_me").run(self.result) |
3375 | + self.result.stopTestRun() |
3376 | + # When tests are run, the number of tests is counted. |
3377 | + output = self.get_output() |
3378 | + self.assertTrue('tests="2"' in output) |
3379 | + |
3380 | + def test_test_id_with_parameter(self): |
3381 | + class Passes(unittest.TestCase): |
3382 | + def id(self): |
3383 | + return unittest.TestCase.id(self) + '(version_1.6)' |
3384 | + def test_me(self): |
3385 | + pass |
3386 | + self.result.startTestRun() |
3387 | + Passes("test_me").run(self.result) |
3388 | + self.result.stopTestRun() |
3389 | + output = self.get_output() |
3390 | + self.assertTrue('Passes" name="test_me(version_1.6)"' in output) |
3391 | + |
3392 | + def test_erroring_test(self): |
3393 | + class Errors(unittest.TestCase): |
3394 | + def test_me(self): |
3395 | + 1/0 |
3396 | + self.result.startTestRun() |
3397 | + Errors("test_me").run(self.result) |
3398 | + self.result.stopTestRun() |
3399 | + self.assertEqual("""<testsuite errors="1" failures="0" name="" tests="1" time="0.000"> |
3400 | +<testcase classname="junitxml.tests.test_junitxml.Errors" name="test_me" time="0.000"> |
3401 | +<error type="ZeroDivisionError">error</error> |
3402 | +</testcase> |
3403 | +</testsuite> |
3404 | +""", self.get_output()) |
3405 | + |
3406 | + def test_failing_test(self): |
3407 | + class Fails(unittest.TestCase): |
3408 | + def test_me(self): |
3409 | + self.fail() |
3410 | + self.result.startTestRun() |
3411 | + Fails("test_me").run(self.result) |
3412 | + self.result.stopTestRun() |
3413 | + self.assertEqual("""<testsuite errors="0" failures="1" name="" tests="1" time="0.000"> |
3414 | +<testcase classname="junitxml.tests.test_junitxml.Fails" name="test_me" time="0.000"> |
3415 | +<failure type="AssertionError">failure</failure> |
3416 | +</testcase> |
3417 | +</testsuite> |
3418 | +""", self.get_output()) |
3419 | + |
3420 | + def test_successful_test(self): |
3421 | + class Passes(unittest.TestCase): |
3422 | + def test_me(self): |
3423 | + pass |
3424 | + self.result.startTestRun() |
3425 | + Passes("test_me").run(self.result) |
3426 | + self.result.stopTestRun() |
3427 | + self.assertEqual("""<testsuite errors="0" failures="0" name="" tests="1" time="0.000"> |
3428 | +<testcase classname="junitxml.tests.test_junitxml.Passes" name="test_me" time="0.000"/> |
3429 | +</testsuite> |
3430 | +""", self.get_output()) |
3431 | + |
3432 | + def test_skip_test(self): |
3433 | + class Skips(unittest.TestCase): |
3434 | + def test_me(self): |
3435 | + self.skipTest("yo") |
3436 | + self.result.startTestRun() |
3437 | + test = Skips("test_me") |
3438 | + self.run_test_or_simulate(test, 'skipTest', self.result.addSkip, 'yo') |
3439 | + self.result.stopTestRun() |
3440 | + output = self.get_output() |
3441 | + expected = """<testsuite errors="0" failures="0" name="" tests="1" time="0.000"> |
3442 | +<testcase classname="junitxml.tests.test_junitxml.Skips" name="test_me" time="0.000"> |
3443 | +<skip>yo</skip> |
3444 | +</testcase> |
3445 | +</testsuite> |
3446 | +""" |
3447 | + self.assertEqual(expected, output) |
3448 | + |
3449 | + def test_unexpected_success_test(self): |
3450 | + class Succeeds(unittest.TestCase): |
3451 | + def test_me(self): |
3452 | + pass |
3453 | + try: |
3454 | + test_me = unittest.expectedFailure(test_me) |
3455 | + except AttributeError: |
3456 | + pass # Older python - just let the test pass |
3457 | + self.result.startTestRun() |
3458 | + Succeeds("test_me").run(self.result) |
3459 | + self.result.stopTestRun() |
3460 | + output = self.get_output() |
3461 | + expected = """<testsuite errors="0" failures="1" name="" tests="1" time="0.000"> |
3462 | +<testcase classname="junitxml.tests.test_junitxml.Succeeds" name="test_me" time="0.000"> |
3463 | +<failure type="unittest.case._UnexpectedSuccess"/> |
3464 | +</testcase> |
3465 | +</testsuite> |
3466 | +""" |
3467 | + expected_old = """<testsuite errors="0" failures="0" name="" tests="1" time="0.000"> |
3468 | +<testcase classname="junitxml.tests.test_junitxml.Succeeds" name="test_me" time="0.000"/> |
3469 | +</testsuite> |
3470 | +""" |
3471 | + if output != expected_old: |
3472 | + self.assertEqual(expected, output) |
3473 | + |
3474 | + def test_expected_failure_test(self): |
3475 | + expected_failure_support = [True] |
3476 | + class ExpectedFail(unittest.TestCase): |
3477 | + def test_me(self): |
3478 | + self.fail("fail") |
3479 | + try: |
3480 | + test_me = unittest.expectedFailure(test_me) |
3481 | + except AttributeError: |
3482 | + # Older python - just let the test fail |
3483 | + expected_failure_support[0] = False |
3484 | + self.result.startTestRun() |
3485 | + ExpectedFail("test_me").run(self.result) |
3486 | + self.result.stopTestRun() |
3487 | + output = self.get_output() |
3488 | + expected = """<testsuite errors="0" failures="0" name="" tests="1" time="0.000"> |
3489 | +<testcase classname="junitxml.tests.test_junitxml.ExpectedFail" name="test_me" time="0.000"/> |
3490 | +</testsuite> |
3491 | +""" |
3492 | + expected_old = """<testsuite errors="0" failures="1" name="" tests="1" time="0.000"> |
3493 | +<testcase classname="junitxml.tests.test_junitxml.ExpectedFail" name="test_me" time="0.000"> |
3494 | +<failure type="AssertionError">failure</failure> |
3495 | +</testcase> |
3496 | +</testsuite> |
3497 | +""" |
3498 | + if expected_failure_support[0]: |
3499 | + self.assertEqual(expected, output) |
3500 | + else: |
3501 | + self.assertEqual(expected_old, output) |
3502 | + |
3503 | + |
3504 | +class TestWellFormedXml(unittest.TestCase): |
3505 | + """XML created should always be well formed even with odd test cases""" |
3506 | + |
3507 | + def _run_and_parse_test(self, case): |
3508 | + output = StringIO() |
3509 | + result = junitxml.JUnitXmlResult(output) |
3510 | + result.startTestRun() |
3511 | + case.run(result) |
3512 | + result.stopTestRun() |
3513 | + return xml.dom.minidom.parseString(output.getvalue()) |
3514 | + |
3515 | + def test_failure_with_amp(self): |
3516 | + """Check the failure element content is escaped""" |
3517 | + class FailWithAmp(unittest.TestCase): |
3518 | + def runTest(self): |
3519 | + self.fail("& should be escaped as &") |
3520 | + doc = self._run_and_parse_test(FailWithAmp()) |
3521 | + self.assertTrue( |
3522 | + doc.getElementsByTagName("failure")[0].firstChild.nodeValue |
3523 | + .endswith("AssertionError: & should be escaped as &\n")) |
3524 | + |
3525 | + def test_quotes_in_test_case_id(self): |
3526 | + """Check that quotes in an attribute are escaped""" |
3527 | + class QuoteId(unittest.TestCase): |
3528 | + def id(self): |
3529 | + return unittest.TestCase.id(self) + '("quotes")' |
3530 | + def runTest(self): |
3531 | + pass |
3532 | + doc = self._run_and_parse_test(QuoteId()) |
3533 | + self.assertEqual('runTest("quotes")', |
3534 | + doc.getElementsByTagName("testcase")[0].getAttribute("name")) |
3535 | + |
3536 | + def test_skip_reason(self): |
3537 | + """Check the skip element content is escaped""" |
3538 | + class SkipWithLt(unittest.TestCase): |
3539 | + def runTest(self): |
3540 | + self.fail("version < 2.7") |
3541 | + try: |
3542 | + runTest = unittest.skip("2.7 <= version")(runTest) |
3543 | + except AttributeError: |
3544 | + self.has_skip = False |
3545 | + else: |
3546 | + self.has_skip = True |
3547 | + doc = self._run_and_parse_test(SkipWithLt()) |
3548 | + if self.has_skip: |
3549 | + self.assertEqual('2.7 <= version', |
3550 | + doc.getElementsByTagName("skip")[0].firstChild.nodeValue) |
3551 | + else: |
3552 | + self.assertTrue( |
3553 | + doc.getElementsByTagName("failure")[0].firstChild.nodeValue |
3554 | + .endswith("AssertionError: version < 2.7\n")) |
3555 | + |
3556 | + def test_error_with_control_characters(self): |
3557 | + """Check C0 control characters are stripped rather than output""" |
3558 | + class ErrorWithC0(unittest.TestCase): |
3559 | + def runTest(self): |
3560 | + raise ValueError("\x1F\x0E\x0C\x0B\x08\x01\x00lost control") |
3561 | + doc = self._run_and_parse_test(ErrorWithC0()) |
3562 | + self.assertTrue( |
3563 | + doc.getElementsByTagName("error")[0].firstChild.nodeValue |
3564 | + .endswith("ValueError: lost control\n")) |
3565 | + |
3566 | + def test_error_with_invalid_cdata(self): |
3567 | + """Check unicode outside the valid cdata range is stripped""" |
3568 | + if len("\uffff") == 1: |
3569 | + # Basic str type supports unicode |
3570 | + exception = ValueError("\ufffe\uffffEOF") |
3571 | + else: |
3572 | + class UTF8_Error(Exception): |
3573 | + def __unicode__(self): |
3574 | + return str(self).decode("UTF-8") |
3575 | + exception = UTF8_Error("\xef\xbf\xbe\xef\xbf\xbfEOF") |
3576 | + class ErrorWithBadUnicode(unittest.TestCase): |
3577 | + def runTest(self): |
3578 | + raise exception |
3579 | + doc = self._run_and_parse_test(ErrorWithBadUnicode()) |
3580 | + self.assertTrue( |
3581 | + doc.getElementsByTagName("error")[0].firstChild.nodeValue |
3582 | + .endswith("Error: EOF\n")) |
3583 | + |
3584 | + def test_error_with_surrogates(self): |
3585 | + """Check unicode surrogates are handled properly, paired or otherwise |
3586 | + |
3587 | + This is a pain due to suboptimal unicode support in Python and the |
3588 | + various changes in Python 3. On UCS-2 builds there is no easy way of |
3589 | + getting rid of unpaired surrogates while leaving valid pairs alone, so |
3590 | + this test doesn't require astral characters are kept there. |
3591 | + """ |
3592 | + if len("\uffff") == 1: |
3593 | + exception = ValueError("paired: \U000201a2" |
3594 | + " unpaired: "+chr(0xD800)+"-"+chr(0xDFFF)) |
3595 | + astral_char = "\U000201a2" |
3596 | + else: |
3597 | + class UTF8_Error(Exception): |
3598 | + def __unicode__(self): |
3599 | + return str(self).decode("UTF-8") |
3600 | + exception = UTF8_Error("paired: \xf0\xa0\x86\xa2" |
3601 | + " unpaired: \xed\xa0\x80-\xed\xbf\xbf") |
3602 | + astral_char = "\U000201a2".decode("unicode-escape") |
3603 | + class ErrorWithSurrogates(unittest.TestCase): |
3604 | + def runTest(self): |
3605 | + raise exception |
3606 | + doc = self._run_and_parse_test(ErrorWithSurrogates()) |
3607 | + traceback = doc.getElementsByTagName("error")[0].firstChild.nodeValue |
3608 | + if sys.maxunicode == 0xFFFF: |
3609 | + pass # would be nice to handle astral characters properly even so |
3610 | + else: |
3611 | + self.assertTrue(astral_char in traceback) |
3612 | + self.assertTrue(traceback.endswith(" unpaired: -\n")) |
3613 | |
3614 | === added directory 'python-for-subunit2junitxml/subunit' |
3615 | === added file 'python-for-subunit2junitxml/subunit/__init__.py' |
3616 | --- python-for-subunit2junitxml/subunit/__init__.py 1970-01-01 00:00:00 +0000 |
3617 | +++ python-for-subunit2junitxml/subunit/__init__.py 2013-05-28 06:50:46 +0000 |
3618 | @@ -0,0 +1,1250 @@ |
3619 | +# |
3620 | +# subunit: extensions to Python unittest to get test results from subprocesses. |
3621 | +# Copyright (C) 2005 Robert Collins <robertc@robertcollins.net> |
3622 | +# |
3623 | +# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause |
3624 | +# license at the users choice. A copy of both licenses are available in the |
3625 | +# project source as Apache-2.0 and BSD. You may not use this file except in |
3626 | +# compliance with one of these two licences. |
3627 | +# |
3628 | +# Unless required by applicable law or agreed to in writing, software |
3629 | +# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT |
3630 | +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
3631 | +# license you chose for the specific language governing permissions and |
3632 | +# limitations under that license. |
3633 | +# |
3634 | + |
3635 | +"""Subunit - a streaming test protocol |
3636 | + |
3637 | +Overview |
3638 | +++++++++ |
3639 | + |
3640 | +The ``subunit`` Python package provides a number of ``unittest`` extensions |
3641 | +which can be used to cause tests to output Subunit, to parse Subunit streams |
3642 | +into test activity, perform seamless test isolation within a regular test |
3643 | +case and variously sort, filter and report on test runs. |
3644 | + |
3645 | + |
3646 | +Key Classes |
3647 | +----------- |
3648 | + |
3649 | +The ``subunit.TestProtocolClient`` class is a ``unittest.TestResult`` |
3650 | +extension which will translate a test run into a Subunit stream. |
3651 | + |
3652 | +The ``subunit.ProtocolTestCase`` class is an adapter between the Subunit wire |
3653 | +protocol and the ``unittest.TestCase`` object protocol. It is used to translate |
3654 | +a stream into a test run, which regular ``unittest.TestResult`` objects can |
3655 | +process and report/inspect. |
3656 | + |
3657 | +Subunit has support for non-blocking usage too, for use with asyncore or |
3658 | +Twisted. See the ``TestProtocolServer`` parser class for more details. |
3659 | + |
3660 | +Subunit includes extensions to the Python ``TestResult`` protocol. These are |
3661 | +all done in a compatible manner: ``TestResult`` objects that do not implement |
3662 | +the extension methods will not cause errors to be raised, instead the extension |
3663 | +will either lose fidelity (for instance, folding expected failures to success |
3664 | +in Python versions < 2.7 or 3.1), or discard the extended data (for extra |
3665 | +details, tags, timestamping and progress markers). |
3666 | + |
3667 | +The test outcome methods ``addSuccess``, ``addError``, ``addExpectedFailure``, |
3668 | +``addFailure``, ``addSkip`` take an optional keyword parameter ``details`` |
3669 | +which can be used instead of the usual python unittest parameter. |
3670 | +When used the value of details should be a dict from ``string`` to |
3671 | +``testtools.content.Content`` objects. This is a draft API being worked on with |
3672 | +the Python Testing In Python mail list, with the goal of permitting a common |
3673 | +way to provide additional data beyond a traceback, such as captured data from |
3674 | +disk, logging messages etc. The reference for this API is in testtools (0.9.0 |
3675 | +and newer). |
3676 | + |
3677 | +The ``tags(new_tags, gone_tags)`` method is called (if present) to add or |
3678 | +remove tags in the test run that is currently executing. If called when no |
3679 | +test is in progress (that is, if called outside of the ``startTest``, |
3680 | +``stopTest`` pair), the the tags apply to all sebsequent tests. If called |
3681 | +when a test is in progress, then the tags only apply to that test. |
3682 | + |
3683 | +The ``time(a_datetime)`` method is called (if present) when a ``time:`` |
3684 | +directive is encountered in a Subunit stream. This is used to tell a TestResult |
3685 | +about the time that events in the stream occured at, to allow reconstructing |
3686 | +test timing from a stream. |
3687 | + |
3688 | +The ``progress(offset, whence)`` method controls progress data for a stream. |
3689 | +The offset parameter is an int, and whence is one of subunit.PROGRESS_CUR, |
3690 | +subunit.PROGRESS_SET, PROGRESS_PUSH, PROGRESS_POP. Push and pop operations |
3691 | +ignore the offset parameter. |
3692 | + |
3693 | + |
3694 | +Python test support |
3695 | +------------------- |
3696 | + |
3697 | +``subunit.run`` is a convenience wrapper to run a Python test suite via |
3698 | +the command line, reporting via Subunit:: |
3699 | + |
3700 | + $ python -m subunit.run mylib.tests.test_suite |
3701 | + |
3702 | +The ``IsolatedTestSuite`` class is a TestSuite that forks before running its |
3703 | +tests, allowing isolation between the test runner and some tests. |
3704 | + |
3705 | +Similarly, ``IsolatedTestCase`` is a base class which can be subclassed to get |
3706 | +tests that will fork() before that individual test is run. |
3707 | + |
3708 | +`ExecTestCase`` is a convenience wrapper for running an external |
3709 | +program to get a Subunit stream and then report that back to an arbitrary |
3710 | +result object:: |
3711 | + |
3712 | + class AggregateTests(subunit.ExecTestCase): |
3713 | + |
3714 | + def test_script_one(self): |
3715 | + './bin/script_one' |
3716 | + |
3717 | + def test_script_two(self): |
3718 | + './bin/script_two' |
3719 | + |
3720 | + # Normally your normal test loading would take of this automatically, |
3721 | + # It is only spelt out in detail here for clarity. |
3722 | + suite = unittest.TestSuite([AggregateTests("test_script_one"), |
3723 | + AggregateTests("test_script_two")]) |
3724 | + # Create any TestResult class you like. |
3725 | + result = unittest._TextTestResult(sys.stdout) |
3726 | + # And run your suite as normal, Subunit will exec each external script as |
3727 | + # needed and report to your result object. |
3728 | + suite.run(result) |
3729 | + |
3730 | +Utility modules |
3731 | +--------------- |
3732 | + |
3733 | +* subunit.chunked contains HTTP chunked encoding/decoding logic. |
3734 | +* subunit.test_results contains TestResult helper classes. |
3735 | +""" |
3736 | + |
3737 | +import os |
3738 | +import re |
3739 | +import subprocess |
3740 | +import sys |
3741 | +import unittest |
3742 | + |
3743 | +from testtools import content, content_type, ExtendedToOriginalDecorator |
3744 | +from testtools.compat import _b, _u, BytesIO, StringIO |
3745 | +try: |
3746 | + from testtools.testresult.real import _StringException |
3747 | + RemoteException = _StringException |
3748 | + # For testing: different pythons have different str() implementations. |
3749 | + if sys.version_info > (3, 0): |
3750 | + _remote_exception_str = "testtools.testresult.real._StringException" |
3751 | + _remote_exception_str_chunked = "34\r\n" + _remote_exception_str |
3752 | + else: |
3753 | + _remote_exception_str = "_StringException" |
3754 | + _remote_exception_str_chunked = "1A\r\n" + _remote_exception_str |
3755 | +except ImportError: |
3756 | + raise ImportError ("testtools.testresult.real does not contain " |
3757 | + "_StringException, check your version.") |
3758 | +from testtools import testresult |
3759 | + |
3760 | +from subunit import chunked, details, iso8601, test_results |
3761 | + |
3762 | + |
3763 | +PROGRESS_SET = 0 |
3764 | +PROGRESS_CUR = 1 |
3765 | +PROGRESS_PUSH = 2 |
3766 | +PROGRESS_POP = 3 |
3767 | + |
3768 | + |
3769 | +def test_suite(): |
3770 | + import subunit.tests |
3771 | + return subunit.tests.test_suite() |
3772 | + |
3773 | + |
3774 | +def join_dir(base_path, path): |
3775 | + """ |
3776 | + Returns an absolute path to C{path}, calculated relative to the parent |
3777 | + of C{base_path}. |
3778 | + |
3779 | + @param base_path: A path to a file or directory. |
3780 | + @param path: An absolute path, or a path relative to the containing |
3781 | + directory of C{base_path}. |
3782 | + |
3783 | + @return: An absolute path to C{path}. |
3784 | + """ |
3785 | + return os.path.join(os.path.dirname(os.path.abspath(base_path)), path) |
3786 | + |
3787 | + |
3788 | +def tags_to_new_gone(tags): |
3789 | + """Split a list of tags into a new_set and a gone_set.""" |
3790 | + new_tags = set() |
3791 | + gone_tags = set() |
3792 | + for tag in tags: |
3793 | + if tag[0] == '-': |
3794 | + gone_tags.add(tag[1:]) |
3795 | + else: |
3796 | + new_tags.add(tag) |
3797 | + return new_tags, gone_tags |
3798 | + |
3799 | + |
3800 | +class DiscardStream(object): |
3801 | + """A filelike object which discards what is written to it.""" |
3802 | + |
3803 | + def write(self, bytes): |
3804 | + pass |
3805 | + |
3806 | + |
3807 | +class _ParserState(object): |
3808 | + """State for the subunit parser.""" |
3809 | + |
3810 | + def __init__(self, parser): |
3811 | + self.parser = parser |
3812 | + self._test_sym = (_b('test'), _b('testing')) |
3813 | + self._colon_sym = _b(':') |
3814 | + self._error_sym = (_b('error'),) |
3815 | + self._failure_sym = (_b('failure'),) |
3816 | + self._progress_sym = (_b('progress'),) |
3817 | + self._skip_sym = _b('skip') |
3818 | + self._success_sym = (_b('success'), _b('successful')) |
3819 | + self._tags_sym = (_b('tags'),) |
3820 | + self._time_sym = (_b('time'),) |
3821 | + self._xfail_sym = (_b('xfail'),) |
3822 | + self._uxsuccess_sym = (_b('uxsuccess'),) |
3823 | + self._start_simple = _u(" [") |
3824 | + self._start_multipart = _u(" [ multipart") |
3825 | + |
3826 | + def addError(self, offset, line): |
3827 | + """An 'error:' directive has been read.""" |
3828 | + self.parser.stdOutLineReceived(line) |
3829 | + |
3830 | + def addExpectedFail(self, offset, line): |
3831 | + """An 'xfail:' directive has been read.""" |
3832 | + self.parser.stdOutLineReceived(line) |
3833 | + |
3834 | + def addFailure(self, offset, line): |
3835 | + """A 'failure:' directive has been read.""" |
3836 | + self.parser.stdOutLineReceived(line) |
3837 | + |
3838 | + def addSkip(self, offset, line): |
3839 | + """A 'skip:' directive has been read.""" |
3840 | + self.parser.stdOutLineReceived(line) |
3841 | + |
3842 | + def addSuccess(self, offset, line): |
3843 | + """A 'success:' directive has been read.""" |
3844 | + self.parser.stdOutLineReceived(line) |
3845 | + |
3846 | + def lineReceived(self, line): |
3847 | + """a line has been received.""" |
3848 | + parts = line.split(None, 1) |
3849 | + if len(parts) == 2 and line.startswith(parts[0]): |
3850 | + cmd, rest = parts |
3851 | + offset = len(cmd) + 1 |
3852 | + cmd = cmd.rstrip(self._colon_sym) |
3853 | + if cmd in self._test_sym: |
3854 | + self.startTest(offset, line) |
3855 | + elif cmd in self._error_sym: |
3856 | + self.addError(offset, line) |
3857 | + elif cmd in self._failure_sym: |
3858 | + self.addFailure(offset, line) |
3859 | + elif cmd in self._progress_sym: |
3860 | + self.parser._handleProgress(offset, line) |
3861 | + elif cmd in self._skip_sym: |
3862 | + self.addSkip(offset, line) |
3863 | + elif cmd in self._success_sym: |
3864 | + self.addSuccess(offset, line) |
3865 | + elif cmd in self._tags_sym: |
3866 | + self.parser._handleTags(offset, line) |
3867 | + self.parser.subunitLineReceived(line) |
3868 | + elif cmd in self._time_sym: |
3869 | + self.parser._handleTime(offset, line) |
3870 | + self.parser.subunitLineReceived(line) |
3871 | + elif cmd in self._xfail_sym: |
3872 | + self.addExpectedFail(offset, line) |
3873 | + elif cmd in self._uxsuccess_sym: |
3874 | + self.addUnexpectedSuccess(offset, line) |
3875 | + else: |
3876 | + self.parser.stdOutLineReceived(line) |
3877 | + else: |
3878 | + self.parser.stdOutLineReceived(line) |
3879 | + |
3880 | + def lostConnection(self): |
3881 | + """Connection lost.""" |
3882 | + self.parser._lostConnectionInTest(_u('unknown state of ')) |
3883 | + |
3884 | + def startTest(self, offset, line): |
3885 | + """A test start command received.""" |
3886 | + self.parser.stdOutLineReceived(line) |
3887 | + |
3888 | + |
3889 | +class _InTest(_ParserState): |
3890 | + """State for the subunit parser after reading a test: directive.""" |
3891 | + |
3892 | + def _outcome(self, offset, line, no_details, details_state): |
3893 | + """An outcome directive has been read. |
3894 | + |
3895 | + :param no_details: Callable to call when no details are presented. |
3896 | + :param details_state: The state to switch to for details |
3897 | + processing of this outcome. |
3898 | + """ |
3899 | + test_name = line[offset:-1].decode('utf8') |
3900 | + if self.parser.current_test_description == test_name: |
3901 | + self.parser._state = self.parser._outside_test |
3902 | + self.parser.current_test_description = None |
3903 | + no_details() |
3904 | + self.parser.client.stopTest(self.parser._current_test) |
3905 | + self.parser._current_test = None |
3906 | + self.parser.subunitLineReceived(line) |
3907 | + elif self.parser.current_test_description + self._start_simple == \ |
3908 | + test_name: |
3909 | + self.parser._state = details_state |
3910 | + details_state.set_simple() |
3911 | + self.parser.subunitLineReceived(line) |
3912 | + elif self.parser.current_test_description + self._start_multipart == \ |
3913 | + test_name: |
3914 | + self.parser._state = details_state |
3915 | + details_state.set_multipart() |
3916 | + self.parser.subunitLineReceived(line) |
3917 | + else: |
3918 | + self.parser.stdOutLineReceived(line) |
3919 | + |
3920 | + def _error(self): |
3921 | + self.parser.client.addError(self.parser._current_test, |
3922 | + details={}) |
3923 | + |
3924 | + def addError(self, offset, line): |
3925 | + """An 'error:' directive has been read.""" |
3926 | + self._outcome(offset, line, self._error, |
3927 | + self.parser._reading_error_details) |
3928 | + |
3929 | + def _xfail(self): |
3930 | + self.parser.client.addExpectedFailure(self.parser._current_test, |
3931 | + details={}) |
3932 | + |
3933 | + def addExpectedFail(self, offset, line): |
3934 | + """An 'xfail:' directive has been read.""" |
3935 | + self._outcome(offset, line, self._xfail, |
3936 | + self.parser._reading_xfail_details) |
3937 | + |
3938 | + def _uxsuccess(self): |
3939 | + self.parser.client.addUnexpectedSuccess(self.parser._current_test) |
3940 | + |
3941 | + def addUnexpectedSuccess(self, offset, line): |
3942 | + """A 'uxsuccess:' directive has been read.""" |
3943 | + self._outcome(offset, line, self._uxsuccess, |
3944 | + self.parser._reading_uxsuccess_details) |
3945 | + |
3946 | + def _failure(self): |
3947 | + self.parser.client.addFailure(self.parser._current_test, details={}) |
3948 | + |
3949 | + def addFailure(self, offset, line): |
3950 | + """A 'failure:' directive has been read.""" |
3951 | + self._outcome(offset, line, self._failure, |
3952 | + self.parser._reading_failure_details) |
3953 | + |
3954 | + def _skip(self): |
3955 | + self.parser.client.addSkip(self.parser._current_test, details={}) |
3956 | + |
3957 | + def addSkip(self, offset, line): |
3958 | + """A 'skip:' directive has been read.""" |
3959 | + self._outcome(offset, line, self._skip, |
3960 | + self.parser._reading_skip_details) |
3961 | + |
3962 | + def _succeed(self): |
3963 | + self.parser.client.addSuccess(self.parser._current_test, details={}) |
3964 | + |
3965 | + def addSuccess(self, offset, line): |
3966 | + """A 'success:' directive has been read.""" |
3967 | + self._outcome(offset, line, self._succeed, |
3968 | + self.parser._reading_success_details) |
3969 | + |
3970 | + def lostConnection(self): |
3971 | + """Connection lost.""" |
3972 | + self.parser._lostConnectionInTest(_u('')) |
3973 | + |
3974 | + |
3975 | +class _OutSideTest(_ParserState): |
3976 | + """State for the subunit parser outside of a test context.""" |
3977 | + |
3978 | + def lostConnection(self): |
3979 | + """Connection lost.""" |
3980 | + |
3981 | + def startTest(self, offset, line): |
3982 | + """A test start command received.""" |
3983 | + self.parser._state = self.parser._in_test |
3984 | + test_name = line[offset:-1].decode('utf8') |
3985 | + self.parser._current_test = RemotedTestCase(test_name) |
3986 | + self.parser.current_test_description = test_name |
3987 | + self.parser.client.startTest(self.parser._current_test) |
3988 | + self.parser.subunitLineReceived(line) |
3989 | + |
3990 | + |
3991 | +class _ReadingDetails(_ParserState): |
3992 | + """Common logic for readin state details.""" |
3993 | + |
3994 | + def endDetails(self): |
3995 | + """The end of a details section has been reached.""" |
3996 | + self.parser._state = self.parser._outside_test |
3997 | + self.parser.current_test_description = None |
3998 | + self._report_outcome() |
3999 | + self.parser.client.stopTest(self.parser._current_test) |
4000 | + |
4001 | + def lineReceived(self, line): |
4002 | + """a line has been received.""" |
4003 | + self.details_parser.lineReceived(line) |
4004 | + self.parser.subunitLineReceived(line) |
4005 | + |
4006 | + def lostConnection(self): |
4007 | + """Connection lost.""" |
4008 | + self.parser._lostConnectionInTest(_u('%s report of ') % |
4009 | + self._outcome_label()) |
4010 | + |
4011 | + def _outcome_label(self): |
4012 | + """The label to describe this outcome.""" |
4013 | + raise NotImplementedError(self._outcome_label) |
4014 | + |
4015 | + def set_simple(self): |
4016 | + """Start a simple details parser.""" |
4017 | + self.details_parser = details.SimpleDetailsParser(self) |
4018 | + |
4019 | + def set_multipart(self): |
4020 | + """Start a multipart details parser.""" |
4021 | + self.details_parser = details.MultipartDetailsParser(self) |
4022 | + |
4023 | + |
4024 | +class _ReadingFailureDetails(_ReadingDetails): |
4025 | + """State for the subunit parser when reading failure details.""" |
4026 | + |
4027 | + def _report_outcome(self): |
4028 | + self.parser.client.addFailure(self.parser._current_test, |
4029 | + details=self.details_parser.get_details()) |
4030 | + |
4031 | + def _outcome_label(self): |
4032 | + return "failure" |
4033 | + |
4034 | + |
4035 | +class _ReadingErrorDetails(_ReadingDetails): |
4036 | + """State for the subunit parser when reading error details.""" |
4037 | + |
4038 | + def _report_outcome(self): |
4039 | + self.parser.client.addError(self.parser._current_test, |
4040 | + details=self.details_parser.get_details()) |
4041 | + |
4042 | + def _outcome_label(self): |
4043 | + return "error" |
4044 | + |
4045 | + |
4046 | +class _ReadingExpectedFailureDetails(_ReadingDetails): |
4047 | + """State for the subunit parser when reading xfail details.""" |
4048 | + |
4049 | + def _report_outcome(self): |
4050 | + self.parser.client.addExpectedFailure(self.parser._current_test, |
4051 | + details=self.details_parser.get_details()) |
4052 | + |
4053 | + def _outcome_label(self): |
4054 | + return "xfail" |
4055 | + |
4056 | + |
4057 | +class _ReadingUnexpectedSuccessDetails(_ReadingDetails): |
4058 | + """State for the subunit parser when reading uxsuccess details.""" |
4059 | + |
4060 | + def _report_outcome(self): |
4061 | + self.parser.client.addUnexpectedSuccess(self.parser._current_test, |
4062 | + details=self.details_parser.get_details()) |
4063 | + |
4064 | + def _outcome_label(self): |
4065 | + return "uxsuccess" |
4066 | + |
4067 | + |
4068 | +class _ReadingSkipDetails(_ReadingDetails): |
4069 | + """State for the subunit parser when reading skip details.""" |
4070 | + |
4071 | + def _report_outcome(self): |
4072 | + self.parser.client.addSkip(self.parser._current_test, |
4073 | + details=self.details_parser.get_details("skip")) |
4074 | + |
4075 | + def _outcome_label(self): |
4076 | + return "skip" |
4077 | + |
4078 | + |
4079 | +class _ReadingSuccessDetails(_ReadingDetails): |
4080 | + """State for the subunit parser when reading success details.""" |
4081 | + |
4082 | + def _report_outcome(self): |
4083 | + self.parser.client.addSuccess(self.parser._current_test, |
4084 | + details=self.details_parser.get_details("success")) |
4085 | + |
4086 | + def _outcome_label(self): |
4087 | + return "success" |
4088 | + |
4089 | + |
4090 | +class TestProtocolServer(object): |
4091 | + """A parser for subunit. |
4092 | + |
4093 | + :ivar tags: The current tags associated with the protocol stream. |
4094 | + """ |
4095 | + |
4096 | + def __init__(self, client, stream=None, forward_stream=None): |
4097 | + """Create a TestProtocolServer instance. |
4098 | + |
4099 | + :param client: An object meeting the unittest.TestResult protocol. |
4100 | + :param stream: The stream that lines received which are not part of the |
4101 | + subunit protocol should be written to. This allows custom handling |
4102 | + of mixed protocols. By default, sys.stdout will be used for |
4103 | + convenience. It should accept bytes to its write() method. |
4104 | + :param forward_stream: A stream to forward subunit lines to. This |
4105 | + allows a filter to forward the entire stream while still parsing |
4106 | + and acting on it. By default forward_stream is set to |
4107 | + DiscardStream() and no forwarding happens. |
4108 | + """ |
4109 | + self.client = ExtendedToOriginalDecorator(client) |
4110 | + if stream is None: |
4111 | + stream = sys.stdout |
4112 | + if sys.version_info > (3, 0): |
4113 | + stream = stream.buffer |
4114 | + self._stream = stream |
4115 | + self._forward_stream = forward_stream or DiscardStream() |
4116 | + # state objects we can switch too |
4117 | + self._in_test = _InTest(self) |
4118 | + self._outside_test = _OutSideTest(self) |
4119 | + self._reading_error_details = _ReadingErrorDetails(self) |
4120 | + self._reading_failure_details = _ReadingFailureDetails(self) |
4121 | + self._reading_skip_details = _ReadingSkipDetails(self) |
4122 | + self._reading_success_details = _ReadingSuccessDetails(self) |
4123 | + self._reading_xfail_details = _ReadingExpectedFailureDetails(self) |
4124 | + self._reading_uxsuccess_details = _ReadingUnexpectedSuccessDetails(self) |
4125 | + # start with outside test. |
4126 | + self._state = self._outside_test |
4127 | + # Avoid casts on every call |
4128 | + self._plusminus = _b('+-') |
4129 | + self._push_sym = _b('push') |
4130 | + self._pop_sym = _b('pop') |
4131 | + |
4132 | + def _handleProgress(self, offset, line): |
4133 | + """Process a progress directive.""" |
4134 | + line = line[offset:].strip() |
4135 | + if line[0] in self._plusminus: |
4136 | + whence = PROGRESS_CUR |
4137 | + delta = int(line) |
4138 | + elif line == self._push_sym: |
4139 | + whence = PROGRESS_PUSH |
4140 | + delta = None |
4141 | + elif line == self._pop_sym: |
4142 | + whence = PROGRESS_POP |
4143 | + delta = None |
4144 | + else: |
4145 | + whence = PROGRESS_SET |
4146 | + delta = int(line) |
4147 | + self.client.progress(delta, whence) |
4148 | + |
4149 | + def _handleTags(self, offset, line): |
4150 | + """Process a tags command.""" |
4151 | + tags = line[offset:].decode('utf8').split() |
4152 | + new_tags, gone_tags = tags_to_new_gone(tags) |
4153 | + self.client.tags(new_tags, gone_tags) |
4154 | + |
4155 | + def _handleTime(self, offset, line): |
4156 | + # Accept it, but do not do anything with it yet. |
4157 | + try: |
4158 | + event_time = iso8601.parse_date(line[offset:-1]) |
4159 | + except TypeError: |
4160 | + raise TypeError(_u("Failed to parse %r, got %r") |
4161 | + % (line, sys.exec_info[1])) |
4162 | + self.client.time(event_time) |
4163 | + |
4164 | + def lineReceived(self, line): |
4165 | + """Call the appropriate local method for the received line.""" |
4166 | + self._state.lineReceived(line) |
4167 | + |
4168 | + def _lostConnectionInTest(self, state_string): |
4169 | + error_string = _u("lost connection during %stest '%s'") % ( |
4170 | + state_string, self.current_test_description) |
4171 | + self.client.addError(self._current_test, RemoteError(error_string)) |
4172 | + self.client.stopTest(self._current_test) |
4173 | + |
4174 | + def lostConnection(self): |
4175 | + """The input connection has finished.""" |
4176 | + self._state.lostConnection() |
4177 | + |
4178 | + def readFrom(self, pipe): |
4179 | + """Blocking convenience API to parse an entire stream. |
4180 | + |
4181 | + :param pipe: A file-like object supporting readlines(). |
4182 | + :return: None. |
4183 | + """ |
4184 | + for line in pipe.readlines(): |
4185 | + self.lineReceived(line) |
4186 | + self.lostConnection() |
4187 | + |
4188 | + def _startTest(self, offset, line): |
4189 | + """Internal call to change state machine. Override startTest().""" |
4190 | + self._state.startTest(offset, line) |
4191 | + |
4192 | + def subunitLineReceived(self, line): |
4193 | + self._forward_stream.write(line) |
4194 | + |
4195 | + def stdOutLineReceived(self, line): |
4196 | + self._stream.write(line) |
4197 | + |
4198 | + |
4199 | +class TestProtocolClient(testresult.TestResult): |
4200 | + """A TestResult which generates a subunit stream for a test run. |
4201 | + |
4202 | + # Get a TestSuite or TestCase to run |
4203 | + suite = make_suite() |
4204 | + # Create a stream (any object with a 'write' method). This should accept |
4205 | + # bytes not strings: subunit is a byte orientated protocol. |
4206 | + stream = file('tests.log', 'wb') |
4207 | + # Create a subunit result object which will output to the stream |
4208 | + result = subunit.TestProtocolClient(stream) |
4209 | + # Optionally, to get timing data for performance analysis, wrap the |
4210 | + # serialiser with a timing decorator |
4211 | + result = subunit.test_results.AutoTimingTestResultDecorator(result) |
4212 | + # Run the test suite reporting to the subunit result object |
4213 | + suite.run(result) |
4214 | + # Close the stream. |
4215 | + stream.close() |
4216 | + """ |
4217 | + |
4218 | + def __init__(self, stream): |
4219 | + testresult.TestResult.__init__(self) |
4220 | + self._stream = stream |
4221 | + _make_stream_binary(stream) |
4222 | + self._progress_fmt = _b("progress: ") |
4223 | + self._bytes_eol = _b("\n") |
4224 | + self._progress_plus = _b("+") |
4225 | + self._progress_push = _b("push") |
4226 | + self._progress_pop = _b("pop") |
4227 | + self._empty_bytes = _b("") |
4228 | + self._start_simple = _b(" [\n") |
4229 | + self._end_simple = _b("]\n") |
4230 | + |
4231 | + def addError(self, test, error=None, details=None): |
4232 | + """Report an error in test test. |
4233 | + |
4234 | + Only one of error and details should be provided: conceptually there |
4235 | + are two separate methods: |
4236 | + addError(self, test, error) |
4237 | + addError(self, test, details) |
4238 | + |
4239 | + :param error: Standard unittest positional argument form - an |
4240 | + exc_info tuple. |
4241 | + :param details: New Testing-in-python drafted API; a dict from string |
4242 | + to subunit.Content objects. |
4243 | + """ |
4244 | + self._addOutcome("error", test, error=error, details=details) |
4245 | + |
4246 | + def addExpectedFailure(self, test, error=None, details=None): |
4247 | + """Report an expected failure in test test. |
4248 | + |
4249 | + Only one of error and details should be provided: conceptually there |
4250 | + are two separate methods: |
4251 | + addError(self, test, error) |
4252 | + addError(self, test, details) |
4253 | + |
4254 | + :param error: Standard unittest positional argument form - an |
4255 | + exc_info tuple. |
4256 | + :param details: New Testing-in-python drafted API; a dict from string |
4257 | + to subunit.Content objects. |
4258 | + """ |
4259 | + self._addOutcome("xfail", test, error=error, details=details) |
4260 | + |
4261 | + def addFailure(self, test, error=None, details=None): |
4262 | + """Report a failure in test test. |
4263 | + |
4264 | + Only one of error and details should be provided: conceptually there |
4265 | + are two separate methods: |
4266 | + addFailure(self, test, error) |
4267 | + addFailure(self, test, details) |
4268 | + |
4269 | + :param error: Standard unittest positional argument form - an |
4270 | + exc_info tuple. |
4271 | + :param details: New Testing-in-python drafted API; a dict from string |
4272 | + to subunit.Content objects. |
4273 | + """ |
4274 | + self._addOutcome("failure", test, error=error, details=details) |
4275 | + |
4276 | + def _addOutcome(self, outcome, test, error=None, details=None, |
4277 | + error_permitted=True): |
4278 | + """Report a failure in test test. |
4279 | + |
4280 | + Only one of error and details should be provided: conceptually there |
4281 | + are two separate methods: |
4282 | + addOutcome(self, test, error) |
4283 | + addOutcome(self, test, details) |
4284 | + |
4285 | + :param outcome: A string describing the outcome - used as the |
4286 | + event name in the subunit stream. |
4287 | + :param error: Standard unittest positional argument form - an |
4288 | + exc_info tuple. |
4289 | + :param details: New Testing-in-python drafted API; a dict from string |
4290 | + to subunit.Content objects. |
4291 | + :param error_permitted: If True then one and only one of error or |
4292 | + details must be supplied. If False then error must not be supplied |
4293 | + and details is still optional. """ |
4294 | + self._stream.write(_b("%s: %s" % (outcome, test.id()))) |
4295 | + if error_permitted: |
4296 | + if error is None and details is None: |
4297 | + raise ValueError |
4298 | + else: |
4299 | + if error is not None: |
4300 | + raise ValueError |
4301 | + if error is not None: |
4302 | + self._stream.write(self._start_simple) |
4303 | + # XXX: this needs to be made much stricter, along the lines of |
4304 | + # Martin[gz]'s work in testtools. Perhaps subunit can use that? |
4305 | + for line in self._exc_info_to_unicode(error, test).splitlines(): |
4306 | + self._stream.write(("%s\n" % line).encode('utf8')) |
4307 | + elif details is not None: |
4308 | + self._write_details(details) |
4309 | + else: |
4310 | + self._stream.write(_b("\n")) |
4311 | + if details is not None or error is not None: |
4312 | + self._stream.write(self._end_simple) |
4313 | + |
4314 | + def addSkip(self, test, reason=None, details=None): |
4315 | + """Report a skipped test.""" |
4316 | + if reason is None: |
4317 | + self._addOutcome("skip", test, error=None, details=details) |
4318 | + else: |
4319 | + self._stream.write(_b("skip: %s [\n" % test.id())) |
4320 | + self._stream.write(_b("%s\n" % reason)) |
4321 | + self._stream.write(self._end_simple) |
4322 | + |
4323 | + def addSuccess(self, test, details=None): |
4324 | + """Report a success in a test.""" |
4325 | + self._addOutcome("successful", test, details=details, error_permitted=False) |
4326 | + |
4327 | + def addUnexpectedSuccess(self, test, details=None): |
4328 | + """Report an unexpected success in test test. |
4329 | + |
4330 | + Details can optionally be provided: conceptually there |
4331 | + are two separate methods: |
4332 | + addError(self, test) |
4333 | + addError(self, test, details) |
4334 | + |
4335 | + :param details: New Testing-in-python drafted API; a dict from string |
4336 | + to subunit.Content objects. |
4337 | + """ |
4338 | + self._addOutcome("uxsuccess", test, details=details, |
4339 | + error_permitted=False) |
4340 | + |
4341 | + def startTest(self, test): |
4342 | + """Mark a test as starting its test run.""" |
4343 | + super(TestProtocolClient, self).startTest(test) |
4344 | + self._stream.write(_b("test: %s\n" % test.id())) |
4345 | + self._stream.flush() |
4346 | + |
4347 | + def stopTest(self, test): |
4348 | + super(TestProtocolClient, self).stopTest(test) |
4349 | + self._stream.flush() |
4350 | + |
4351 | + def progress(self, offset, whence): |
4352 | + """Provide indication about the progress/length of the test run. |
4353 | + |
4354 | + :param offset: Information about the number of tests remaining. If |
4355 | + whence is PROGRESS_CUR, then offset increases/decreases the |
4356 | + remaining test count. If whence is PROGRESS_SET, then offset |
4357 | + specifies exactly the remaining test count. |
4358 | + :param whence: One of PROGRESS_CUR, PROGRESS_SET, PROGRESS_PUSH, |
4359 | + PROGRESS_POP. |
4360 | + """ |
4361 | + if whence == PROGRESS_CUR and offset > -1: |
4362 | + prefix = self._progress_plus |
4363 | + offset = _b(str(offset)) |
4364 | + elif whence == PROGRESS_PUSH: |
4365 | + prefix = self._empty_bytes |
4366 | + offset = self._progress_push |
4367 | + elif whence == PROGRESS_POP: |
4368 | + prefix = self._empty_bytes |
4369 | + offset = self._progress_pop |
4370 | + else: |
4371 | + prefix = self._empty_bytes |
4372 | + offset = _b(str(offset)) |
4373 | + self._stream.write(self._progress_fmt + prefix + offset + |
4374 | + self._bytes_eol) |
4375 | + |
4376 | + def time(self, a_datetime): |
4377 | + """Inform the client of the time. |
4378 | + |
4379 | + ":param datetime: A datetime.datetime object. |
4380 | + """ |
4381 | + time = a_datetime.astimezone(iso8601.Utc()) |
4382 | + self._stream.write(_b("time: %04d-%02d-%02d %02d:%02d:%02d.%06dZ\n" % ( |
4383 | + time.year, time.month, time.day, time.hour, time.minute, |
4384 | + time.second, time.microsecond))) |
4385 | + |
4386 | + def _write_details(self, details): |
4387 | + """Output details to the stream. |
4388 | + |
4389 | + :param details: An extended details dict for a test outcome. |
4390 | + """ |
4391 | + self._stream.write(_b(" [ multipart\n")) |
4392 | + for name, content in sorted(details.items()): |
4393 | + self._stream.write(_b("Content-Type: %s/%s" % |
4394 | + (content.content_type.type, content.content_type.subtype))) |
4395 | + parameters = content.content_type.parameters |
4396 | + if parameters: |
4397 | + self._stream.write(_b(";")) |
4398 | + param_strs = [] |
4399 | + for param, value in parameters.items(): |
4400 | + param_strs.append("%s=%s" % (param, value)) |
4401 | + self._stream.write(_b(",".join(param_strs))) |
4402 | + self._stream.write(_b("\n%s\n" % name)) |
4403 | + encoder = chunked.Encoder(self._stream) |
4404 | + list(map(encoder.write, content.iter_bytes())) |
4405 | + encoder.close() |
4406 | + |
4407 | + def done(self): |
4408 | + """Obey the testtools result.done() interface.""" |
4409 | + |
4410 | + |
4411 | +def RemoteError(description=_u("")): |
4412 | + return (_StringException, _StringException(description), None) |
4413 | + |
4414 | + |
4415 | +class RemotedTestCase(unittest.TestCase): |
4416 | + """A class to represent test cases run in child processes. |
4417 | + |
4418 | + Instances of this class are used to provide the Python test API a TestCase |
4419 | + that can be printed to the screen, introspected for metadata and so on. |
4420 | + However, as they are a simply a memoisation of a test that was actually |
4421 | + run in the past by a separate process, they cannot perform any interactive |
4422 | + actions. |
4423 | + """ |
4424 | + |
4425 | + def __eq__ (self, other): |
4426 | + try: |
4427 | + return self.__description == other.__description |
4428 | + except AttributeError: |
4429 | + return False |
4430 | + |
4431 | + def __init__(self, description): |
4432 | + """Create a psuedo test case with description description.""" |
4433 | + self.__description = description |
4434 | + |
4435 | + def error(self, label): |
4436 | + raise NotImplementedError("%s on RemotedTestCases is not permitted." % |
4437 | + label) |
4438 | + |
4439 | + def setUp(self): |
4440 | + self.error("setUp") |
4441 | + |
4442 | + def tearDown(self): |
4443 | + self.error("tearDown") |
4444 | + |
4445 | + def shortDescription(self): |
4446 | + return self.__description |
4447 | + |
4448 | + def id(self): |
4449 | + return "%s" % (self.__description,) |
4450 | + |
4451 | + def __str__(self): |
4452 | + return "%s (%s)" % (self.__description, self._strclass()) |
4453 | + |
4454 | + def __repr__(self): |
4455 | + return "<%s description='%s'>" % \ |
4456 | + (self._strclass(), self.__description) |
4457 | + |
4458 | + def run(self, result=None): |
4459 | + if result is None: result = self.defaultTestResult() |
4460 | + result.startTest(self) |
4461 | + result.addError(self, RemoteError(_u("Cannot run RemotedTestCases.\n"))) |
4462 | + result.stopTest(self) |
4463 | + |
4464 | + def _strclass(self): |
4465 | + cls = self.__class__ |
4466 | + return "%s.%s" % (cls.__module__, cls.__name__) |
4467 | + |
4468 | + |
4469 | +class ExecTestCase(unittest.TestCase): |
4470 | + """A test case which runs external scripts for test fixtures.""" |
4471 | + |
4472 | + def __init__(self, methodName='runTest'): |
4473 | + """Create an instance of the class that will use the named test |
4474 | + method when executed. Raises a ValueError if the instance does |
4475 | + not have a method with the specified name. |
4476 | + """ |
4477 | + unittest.TestCase.__init__(self, methodName) |
4478 | + testMethod = getattr(self, methodName) |
4479 | + self.script = join_dir(sys.modules[self.__class__.__module__].__file__, |
4480 | + testMethod.__doc__) |
4481 | + |
4482 | + def countTestCases(self): |
4483 | + return 1 |
4484 | + |
4485 | + def run(self, result=None): |
4486 | + if result is None: result = self.defaultTestResult() |
4487 | + self._run(result) |
4488 | + |
4489 | + def debug(self): |
4490 | + """Run the test without collecting errors in a TestResult""" |
4491 | + self._run(testresult.TestResult()) |
4492 | + |
4493 | + def _run(self, result): |
4494 | + protocol = TestProtocolServer(result) |
4495 | + process = subprocess.Popen(self.script, shell=True, |
4496 | + stdout=subprocess.PIPE) |
4497 | + _make_stream_binary(process.stdout) |
4498 | + output = process.communicate()[0] |
4499 | + protocol.readFrom(BytesIO(output)) |
4500 | + |
4501 | + |
4502 | +class IsolatedTestCase(unittest.TestCase): |
4503 | + """A TestCase which executes in a forked process. |
4504 | + |
4505 | + Each test gets its own process, which has a performance overhead but will |
4506 | + provide excellent isolation from global state (such as django configs, |
4507 | + zope utilities and so on). |
4508 | + """ |
4509 | + |
4510 | + def run(self, result=None): |
4511 | + if result is None: result = self.defaultTestResult() |
4512 | + run_isolated(unittest.TestCase, self, result) |
4513 | + |
4514 | + |
4515 | +class IsolatedTestSuite(unittest.TestSuite): |
4516 | + """A TestSuite which runs its tests in a forked process. |
4517 | + |
4518 | + This decorator that will fork() before running the tests and report the |
4519 | + results from the child process using a Subunit stream. This is useful for |
4520 | + handling tests that mutate global state, or are testing C extensions that |
4521 | + could crash the VM. |
4522 | + """ |
4523 | + |
4524 | + def run(self, result=None): |
4525 | + if result is None: result = testresult.TestResult() |
4526 | + run_isolated(unittest.TestSuite, self, result) |
4527 | + |
4528 | + |
4529 | +def run_isolated(klass, self, result): |
4530 | + """Run a test suite or case in a subprocess, using the run method on klass. |
4531 | + """ |
4532 | + c2pread, c2pwrite = os.pipe() |
4533 | + # fixme - error -> result |
4534 | + # now fork |
4535 | + pid = os.fork() |
4536 | + if pid == 0: |
4537 | + # Child |
4538 | + # Close parent's pipe ends |
4539 | + os.close(c2pread) |
4540 | + # Dup fds for child |
4541 | + os.dup2(c2pwrite, 1) |
4542 | + # Close pipe fds. |
4543 | + os.close(c2pwrite) |
4544 | + |
4545 | + # at this point, sys.stdin is redirected, now we want |
4546 | + # to filter it to escape ]'s. |
4547 | + ### XXX: test and write that bit. |
4548 | + stream = os.fdopen(1, 'wb') |
4549 | + result = TestProtocolClient(stream) |
4550 | + klass.run(self, result) |
4551 | + stream.flush() |
4552 | + sys.stderr.flush() |
4553 | + # exit HARD, exit NOW. |
4554 | + os._exit(0) |
4555 | + else: |
4556 | + # Parent |
4557 | + # Close child pipe ends |
4558 | + os.close(c2pwrite) |
4559 | + # hookup a protocol engine |
4560 | + protocol = TestProtocolServer(result) |
4561 | + fileobj = os.fdopen(c2pread, 'rb') |
4562 | + protocol.readFrom(fileobj) |
4563 | + os.waitpid(pid, 0) |
4564 | + # TODO return code evaluation. |
4565 | + return result |
4566 | + |
4567 | + |
4568 | +def TAP2SubUnit(tap, subunit): |
4569 | + """Filter a TAP pipe into a subunit pipe. |
4570 | + |
4571 | + :param tap: A tap pipe/stream/file object. |
4572 | + :param subunit: A pipe/stream/file object to write subunit results to. |
4573 | + :return: The exit code to exit with. |
4574 | + """ |
4575 | + BEFORE_PLAN = 0 |
4576 | + AFTER_PLAN = 1 |
4577 | + SKIP_STREAM = 2 |
4578 | + state = BEFORE_PLAN |
4579 | + plan_start = 1 |
4580 | + plan_stop = 0 |
4581 | + def _skipped_test(subunit, plan_start): |
4582 | + # Some tests were skipped. |
4583 | + subunit.write('test test %d\n' % plan_start) |
4584 | + subunit.write('error test %d [\n' % plan_start) |
4585 | + subunit.write('test missing from TAP output\n') |
4586 | + subunit.write(']\n') |
4587 | + return plan_start + 1 |
4588 | + # Test data for the next test to emit |
4589 | + test_name = None |
4590 | + log = [] |
4591 | + result = None |
4592 | + def _emit_test(): |
4593 | + "write out a test" |
4594 | + if test_name is None: |
4595 | + return |
4596 | + subunit.write("test %s\n" % test_name) |
4597 | + if not log: |
4598 | + subunit.write("%s %s\n" % (result, test_name)) |
4599 | + else: |
4600 | + subunit.write("%s %s [\n" % (result, test_name)) |
4601 | + if log: |
4602 | + for line in log: |
4603 | + subunit.write("%s\n" % line) |
4604 | + subunit.write("]\n") |
4605 | + del log[:] |
4606 | + for line in tap: |
4607 | + if state == BEFORE_PLAN: |
4608 | + match = re.match("(\d+)\.\.(\d+)\s*(?:\#\s+(.*))?\n", line) |
4609 | + if match: |
4610 | + state = AFTER_PLAN |
4611 | + _, plan_stop, comment = match.groups() |
4612 | + plan_stop = int(plan_stop) |
4613 | + if plan_start > plan_stop and plan_stop == 0: |
4614 | + # skipped file |
4615 | + state = SKIP_STREAM |
4616 | + subunit.write("test file skip\n") |
4617 | + subunit.write("skip file skip [\n") |
4618 | + subunit.write("%s\n" % comment) |
4619 | + subunit.write("]\n") |
4620 | + continue |
4621 | + # not a plan line, or have seen one before |
4622 | + match = re.match("(ok|not ok)(?:\s+(\d+)?)?(?:\s+([^#]*[^#\s]+)\s*)?(?:\s+#\s+(TODO|SKIP|skip|todo)(?:\s+(.*))?)?\n", line) |
4623 | + if match: |
4624 | + # new test, emit current one. |
4625 | + _emit_test() |
4626 | + status, number, description, directive, directive_comment = match.groups() |
4627 | + if status == 'ok': |
4628 | + result = 'success' |
4629 | + else: |
4630 | + result = "failure" |
4631 | + if description is None: |
4632 | + description = '' |
4633 | + else: |
4634 | + description = ' ' + description |
4635 | + if directive is not None: |
4636 | + if directive.upper() == 'TODO': |
4637 | + result = 'xfail' |
4638 | + elif directive.upper() == 'SKIP': |
4639 | + result = 'skip' |
4640 | + if directive_comment is not None: |
4641 | + log.append(directive_comment) |
4642 | + if number is not None: |
4643 | + number = int(number) |
4644 | + while plan_start < number: |
4645 | + plan_start = _skipped_test(subunit, plan_start) |
4646 | + test_name = "test %d%s" % (plan_start, description) |
4647 | + plan_start += 1 |
4648 | + continue |
4649 | + match = re.match("Bail out\!(?:\s*(.*))?\n", line) |
4650 | + if match: |
4651 | + reason, = match.groups() |
4652 | + if reason is None: |
4653 | + extra = '' |
4654 | + else: |
4655 | + extra = ' %s' % reason |
4656 | + _emit_test() |
4657 | + test_name = "Bail out!%s" % extra |
4658 | + result = "error" |
4659 | + state = SKIP_STREAM |
4660 | + continue |
4661 | + match = re.match("\#.*\n", line) |
4662 | + if match: |
4663 | + log.append(line[:-1]) |
4664 | + continue |
4665 | + subunit.write(line) |
4666 | + _emit_test() |
4667 | + while plan_start <= plan_stop: |
4668 | + # record missed tests |
4669 | + plan_start = _skipped_test(subunit, plan_start) |
4670 | + return 0 |
4671 | + |
4672 | + |
4673 | +def tag_stream(original, filtered, tags): |
4674 | + """Alter tags on a stream. |
4675 | + |
4676 | + :param original: The input stream. |
4677 | + :param filtered: The output stream. |
4678 | + :param tags: The tags to apply. As in a normal stream - a list of 'TAG' or |
4679 | + '-TAG' commands. |
4680 | + |
4681 | + A 'TAG' command will add the tag to the output stream, |
4682 | + and override any existing '-TAG' command in that stream. |
4683 | + Specifically: |
4684 | + * A global 'tags: TAG' will be added to the start of the stream. |
4685 | + * Any tags commands with -TAG will have the -TAG removed. |
4686 | + |
4687 | + A '-TAG' command will remove the TAG command from the stream. |
4688 | + Specifically: |
4689 | + * A 'tags: -TAG' command will be added to the start of the stream. |
4690 | + * Any 'tags: TAG' command will have 'TAG' removed from it. |
4691 | + Additionally, any redundant tagging commands (adding a tag globally |
4692 | + present, or removing a tag globally removed) are stripped as a |
4693 | + by-product of the filtering. |
4694 | + :return: 0 |
4695 | + """ |
4696 | + new_tags, gone_tags = tags_to_new_gone(tags) |
4697 | + def write_tags(new_tags, gone_tags): |
4698 | + if new_tags or gone_tags: |
4699 | + filtered.write("tags: " + ' '.join(new_tags)) |
4700 | + if gone_tags: |
4701 | + for tag in gone_tags: |
4702 | + filtered.write("-" + tag) |
4703 | + filtered.write("\n") |
4704 | + write_tags(new_tags, gone_tags) |
4705 | + # TODO: use the protocol parser and thus don't mangle test comments. |
4706 | + for line in original: |
4707 | + if line.startswith("tags:"): |
4708 | + line_tags = line[5:].split() |
4709 | + line_new, line_gone = tags_to_new_gone(line_tags) |
4710 | + line_new = line_new - gone_tags |
4711 | + line_gone = line_gone - new_tags |
4712 | + write_tags(line_new, line_gone) |
4713 | + else: |
4714 | + filtered.write(line) |
4715 | + return 0 |
4716 | + |
4717 | + |
4718 | +class ProtocolTestCase(object): |
4719 | + """Subunit wire protocol to unittest.TestCase adapter. |
4720 | + |
4721 | + ProtocolTestCase honours the core of ``unittest.TestCase`` protocol - |
4722 | + calling a ProtocolTestCase or invoking the run() method will make a 'test |
4723 | + run' happen. The 'test run' will simply be a replay of the test activity |
4724 | + that has been encoded into the stream. The ``unittest.TestCase`` ``debug`` |
4725 | + and ``countTestCases`` methods are not supported because there isn't a |
4726 | + sensible mapping for those methods. |
4727 | + |
4728 | + # Get a stream (any object with a readline() method), in this case the |
4729 | + # stream output by the example from ``subunit.TestProtocolClient``. |
4730 | + stream = file('tests.log', 'rb') |
4731 | + # Create a parser which will read from the stream and emit |
4732 | + # activity to a unittest.TestResult when run() is called. |
4733 | + suite = subunit.ProtocolTestCase(stream) |
4734 | + # Create a result object to accept the contents of that stream. |
4735 | + result = unittest._TextTestResult(sys.stdout) |
4736 | + # 'run' the tests - process the stream and feed its contents to result. |
4737 | + suite.run(result) |
4738 | + stream.close() |
4739 | + |
4740 | + :seealso: TestProtocolServer (the subunit wire protocol parser). |
4741 | + """ |
4742 | + |
4743 | + def __init__(self, stream, passthrough=None, forward=False): |
4744 | + """Create a ProtocolTestCase reading from stream. |
4745 | + |
4746 | + :param stream: A filelike object which a subunit stream can be read |
4747 | + from. |
4748 | + :param passthrough: A stream pass non subunit input on to. If not |
4749 | + supplied, the TestProtocolServer default is used. |
4750 | + :param forward: A stream to pass subunit input on to. If not supplied |
4751 | + subunit input is not forwarded. |
4752 | + """ |
4753 | + self._stream = stream |
4754 | + _make_stream_binary(stream) |
4755 | + self._passthrough = passthrough |
4756 | + self._forward = forward |
4757 | + |
4758 | + def __call__(self, result=None): |
4759 | + return self.run(result) |
4760 | + |
4761 | + def run(self, result=None): |
4762 | + if result is None: |
4763 | + result = self.defaultTestResult() |
4764 | + protocol = TestProtocolServer(result, self._passthrough, self._forward) |
4765 | + line = self._stream.readline() |
4766 | + while line: |
4767 | + protocol.lineReceived(line) |
4768 | + line = self._stream.readline() |
4769 | + protocol.lostConnection() |
4770 | + |
4771 | + |
4772 | +class TestResultStats(testresult.TestResult): |
4773 | + """A pyunit TestResult interface implementation for making statistics. |
4774 | + |
4775 | + :ivar total_tests: The total tests seen. |
4776 | + :ivar passed_tests: The tests that passed. |
4777 | + :ivar failed_tests: The tests that failed. |
4778 | + :ivar seen_tags: The tags seen across all tests. |
4779 | + """ |
4780 | + |
4781 | + def __init__(self, stream): |
4782 | + """Create a TestResultStats which outputs to stream.""" |
4783 | + testresult.TestResult.__init__(self) |
4784 | + self._stream = stream |
4785 | + self.failed_tests = 0 |
4786 | + self.skipped_tests = 0 |
4787 | + self.seen_tags = set() |
4788 | + |
4789 | + @property |
4790 | + def total_tests(self): |
4791 | + return self.testsRun |
4792 | + |
4793 | + def addError(self, test, err, details=None): |
4794 | + self.failed_tests += 1 |
4795 | + |
4796 | + def addFailure(self, test, err, details=None): |
4797 | + self.failed_tests += 1 |
4798 | + |
4799 | + def addSkip(self, test, reason, details=None): |
4800 | + self.skipped_tests += 1 |
4801 | + |
4802 | + def formatStats(self): |
4803 | + self._stream.write("Total tests: %5d\n" % self.total_tests) |
4804 | + self._stream.write("Passed tests: %5d\n" % self.passed_tests) |
4805 | + self._stream.write("Failed tests: %5d\n" % self.failed_tests) |
4806 | + self._stream.write("Skipped tests: %5d\n" % self.skipped_tests) |
4807 | + tags = sorted(self.seen_tags) |
4808 | + self._stream.write("Seen tags: %s\n" % (", ".join(tags))) |
4809 | + |
4810 | + @property |
4811 | + def passed_tests(self): |
4812 | + return self.total_tests - self.failed_tests - self.skipped_tests |
4813 | + |
4814 | + def tags(self, new_tags, gone_tags): |
4815 | + """Accumulate the seen tags.""" |
4816 | + self.seen_tags.update(new_tags) |
4817 | + |
4818 | + def wasSuccessful(self): |
4819 | + """Tells whether or not this result was a success""" |
4820 | + return self.failed_tests == 0 |
4821 | + |
4822 | + |
4823 | +def get_default_formatter(): |
4824 | + """Obtain the default formatter to write to. |
4825 | + |
4826 | + :return: A file-like object. |
4827 | + """ |
4828 | + formatter = os.getenv("SUBUNIT_FORMATTER") |
4829 | + if formatter: |
4830 | + return os.popen(formatter, "w") |
4831 | + else: |
4832 | + stream = sys.stdout |
4833 | + if sys.version_info > (3, 0): |
4834 | + stream = stream.buffer |
4835 | + return stream |
4836 | + |
4837 | + |
4838 | +if sys.version_info > (3, 0): |
4839 | + from io import UnsupportedOperation as _NoFilenoError |
4840 | +else: |
4841 | + _NoFilenoError = AttributeError |
4842 | + |
4843 | +def read_test_list(path): |
4844 | + """Read a list of test ids from a file on disk. |
4845 | + |
4846 | + :param path: Path to the file |
4847 | + :return: Sequence of test ids |
4848 | + """ |
4849 | + f = open(path, 'rb') |
4850 | + try: |
4851 | + return [l.rstrip("\n") for l in f.readlines()] |
4852 | + finally: |
4853 | + f.close() |
4854 | + |
4855 | + |
4856 | +def _make_stream_binary(stream): |
4857 | + """Ensure that a stream will be binary safe. See _make_binary_on_windows.""" |
4858 | + try: |
4859 | + fileno = stream.fileno() |
4860 | + except _NoFilenoError: |
4861 | + return |
4862 | + _make_binary_on_windows(fileno) |
4863 | + |
4864 | +def _make_binary_on_windows(fileno): |
4865 | + """Win32 mangles \r\n to \n and that breaks streams. See bug lp:505078.""" |
4866 | + if sys.platform == "win32": |
4867 | + import msvcrt |
4868 | + msvcrt.setmode(fileno, os.O_BINARY) |
4869 | |
4870 | === added file 'python-for-subunit2junitxml/subunit/chunked.py' |
4871 | --- python-for-subunit2junitxml/subunit/chunked.py 1970-01-01 00:00:00 +0000 |
4872 | +++ python-for-subunit2junitxml/subunit/chunked.py 2013-05-28 06:50:46 +0000 |
4873 | @@ -0,0 +1,185 @@ |
4874 | +# |
4875 | +# subunit: extensions to python unittest to get test results from subprocesses. |
4876 | +# Copyright (C) 2005 Robert Collins <robertc@robertcollins.net> |
4877 | +# Copyright (C) 2011 Martin Pool <mbp@sourcefrog.net> |
4878 | +# |
4879 | +# Licensed under either the Apache License, Version 2.0 or the BSD 3-clause |
4880 | +# license at the users choice. A copy of both licenses are available in the |
4881 | +# project source as Apache-2.0 and BSD. You may not use this file except in |
4882 | +# compliance with one of these two licences. |
4883 | +# |
4884 | +# Unless required by applicable law or agreed to in writing, software |
4885 | +# distributed under these licenses is distributed on an "AS IS" BASIS, WITHOUT |
4886 | +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
4887 | +# license you chose for the specific language governing permissions and |
4888 | +# limitations under that license. |
4889 | +# |
4890 | + |
4891 | +"""Encoder/decoder for http style chunked encoding.""" |
4892 | + |
4893 | +from testtools.compat import _b |
4894 | + |
4895 | +empty = _b('') |
4896 | + |
4897 | +class Decoder(object): |
4898 | + """Decode chunked content to a byte stream.""" |
4899 | + |
4900 | + def __init__(self, output, strict=True): |
4901 | + """Create a decoder decoding to output. |
4902 | + |
4903 | + :param output: A file-like object. Bytes written to the Decoder are |
4904 | + decoded to strip off the chunking and written to the output. |
4905 | + Up to a full write worth of data or a single control line may be |
4906 | + buffered (whichever is larger). The close method should be called |
4907 | + when no more data is available, to detect short streams; the |
4908 | + write method will return none-None when the end of a stream is |
4909 | + detected. The output object must accept bytes objects. |
4910 | + |
4911 | + :param strict: If True (the default), the decoder will not knowingly |
4912 | + accept input that is not conformant to the HTTP specification. |
4913 | + (This does not imply that it will catch every nonconformance.) |
4914 | + If False, it will accept incorrect input that is still |
4915 | + unambiguous. |
4916 | + """ |
4917 | + self.output = output |
4918 | + self.buffered_bytes = [] |
4919 | + self.state = self._read_length |
4920 | + self.body_length = 0 |
4921 | + self.strict = strict |
4922 | + self._match_chars = _b("0123456789abcdefABCDEF\r\n") |
4923 | + self._slash_n = _b('\n') |
4924 | + self._slash_r = _b('\r') |
4925 | + self._slash_rn = _b('\r\n') |
4926 | + self._slash_nr = _b('\n\r') |
4927 | + |
4928 | + def close(self): |
4929 | + """Close the decoder. |
4930 | + |
4931 | + :raises ValueError: If the stream is incomplete ValueError is raised. |
4932 | + """ |
4933 | + if self.state != self._finished: |
4934 | + raise ValueError("incomplete stream") |
4935 | + |
4936 | + def _finished(self): |
4937 | + """Finished reading, return any remaining bytes.""" |
4938 | + if self.buffered_bytes: |
4939 | + buffered_bytes = self.buffered_bytes |
4940 | + self.buffered_bytes = [] |
4941 | + return empty.join(buffered_bytes) |
4942 | + else: |
4943 | + raise ValueError("stream is finished") |
4944 | + |
4945 | + def _read_body(self): |
4946 | + """Pass body bytes to the output.""" |
4947 | + while self.body_length and self.buffered_bytes: |
4948 | + if self.body_length >= len(self.buffered_bytes[0]): |
4949 | + self.output.write(self.buffered_bytes[0]) |
4950 | + self.body_length -= len(self.buffered_bytes[0]) |
4951 | + del self.buffered_bytes[0] |
4952 | + # No more data available. |
4953 | + if not self.body_length: |
4954 | + self.state = self._read_length |
4955 | + else: |
4956 | + self.output.write(self.buffered_bytes[0][:self.body_length]) |
4957 | + self.buffered_bytes[0] = \ |
4958 | + self.buffered_bytes[0][self.body_length:] |
4959 | + self.body_length = 0 |
4960 | + self.state = self._read_length |
4961 | + return self.state() |
4962 | + |
4963 | + def _read_length(self): |
4964 | + """Try to decode a length from the bytes.""" |
4965 | + count_chars = [] |
4966 | + for bytes in self.buffered_bytes: |
4967 | + for pos in range(len(bytes)): |
4968 | + byte = bytes[pos:pos+1] |
4969 | + if byte not in self._match_chars: |
4970 | + break |
4971 | + count_chars.append(byte) |
4972 | + if byte == self._slash_n: |
4973 | + break |
4974 | + if not count_chars: |
4975 | + return |
4976 | + if count_chars[-1] != self._slash_n: |
4977 | + return |
4978 | + count_str = empty.join(count_chars) |
4979 | + if self.strict: |
4980 | + if count_str[-2:] != self._slash_rn: |
4981 | + raise ValueError("chunk header invalid: %r" % count_str) |
4982 | + if self._slash_r in count_str[:-2]: |
4983 | + raise ValueError("too many CRs in chunk header %r" % count_str) |
4984 | + self.body_length = int(count_str.rstrip(self._slash_nr), 16) |
4985 | + excess_bytes = len(count_str) |
4986 | + while excess_bytes: |
4987 | + if excess_bytes >= len(self.buffered_bytes[0]): |
4988 | + excess_bytes -= len(self.buffered_bytes[0]) |
4989 | + del self.buffered_bytes[0] |
4990 | + else: |
4991 | + self.buffered_bytes[0] = self.buffered_bytes[0][excess_bytes:] |
4992 | + excess_bytes = 0 |
4993 | + if not self.body_length: |
4994 | + self.state = self._finished |
4995 | + if not self.buffered_bytes: |
4996 | + # May not call into self._finished with no buffered data. |
4997 | + return empty |
4998 | + else: |
4999 | + self.state = self._read_body |
5000 | + return self.state() |
The diff has been truncated for viewing.
The conflicts will be addressed at the merge time.