Merge lp:~laurynas-biveinis/percona-server/bug1183625-5.5 into lp:percona-server/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
Reviewer Review Type Date Requested Status
Stewart Smith (community) Approve
Review via email: mp+165967@code.launchpad.net

Description of the change

Merge percona_userstat testcase from 5.1, partially addressing bug
1179534
, and containing the testcase for bug 1183625.

http://jenkins.percona.com/job/percona-server-5.5-param/746/

To post a comment you must log in.
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

The conflicts will be addressed at the merge time.

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'
2644Binary 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("&", "&amp;")
3115+ .replace("<", "&lt;")
3116+ .replace("]]>", "]]&gt;"))
3117+def _escape_attr(s):
3118+ return (_strip_invalid_chars(s)
3119+ .replace("&", "&amp;")
3120+ .replace("<", "&lt;")
3121+ .replace("]]>", "]]&gt;")
3122+ .replace('"', "&quot;")
3123+ .replace("\t", "&#x9;")
3124+ .replace("\n", "&#xA;"))
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 &amp;")
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 &amp;\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.

Subscribers

People subscribed via source and target branches