MediaWiki REL1_30
TransactionProfilerTest.php
Go to the documentation of this file.
1<?php
2
4use Psr\Log\LoggerInterface;
5
6class TransactionProfilerTest extends PHPUnit_Framework_TestCase {
7 public function testAffected() {
8 $logger = $this->getMockBuilder( LoggerInterface::class )->getMock();
9 $logger->expects( $this->exactly( 3 ) )->method( 'info' );
10
11 $tp = new TransactionProfiler();
12 $tp->setLogger( $logger );
13 $tp->setExpectation( 'maxAffected', 100, __METHOD__ );
14
15 $tp->transactionWritingIn( 'srv1', 'db1', '123' );
16 $tp->recordQueryCompletion( "SQL 1", microtime( true ) - 3, true, 200 );
17 $tp->recordQueryCompletion( "SQL 2", microtime( true ) - 3, true, 200 );
18 $tp->transactionWritingOut( 'srv1', 'db1', '123', 1, 400 );
19 }
20
21 public function testReadTime() {
22 $logger = $this->getMockBuilder( LoggerInterface::class )->getMock();
23 // 1 per query
24 $logger->expects( $this->exactly( 2 ) )->method( 'info' );
25
26 $tp = new TransactionProfiler();
27 $tp->setLogger( $logger );
28 $tp->setExpectation( 'readQueryTime', 5, __METHOD__ );
29
30 $tp->transactionWritingIn( 'srv1', 'db1', '123' );
31 $tp->recordQueryCompletion( "SQL 1", microtime( true ) - 10, false, 1 );
32 $tp->recordQueryCompletion( "SQL 2", microtime( true ) - 10, false, 1 );
33 $tp->transactionWritingOut( 'srv1', 'db1', '123', 0, 0 );
34 }
35
36 public function testWriteTime() {
37 $logger = $this->getMockBuilder( LoggerInterface::class )->getMock();
38 // 1 per query, 1 per trx, and one "sub-optimal trx" entry
39 $logger->expects( $this->exactly( 4 ) )->method( 'info' );
40
41 $tp = new TransactionProfiler();
42 $tp->setLogger( $logger );
43 $tp->setExpectation( 'writeQueryTime', 5, __METHOD__ );
44
45 $tp->transactionWritingIn( 'srv1', 'db1', '123' );
46 $tp->recordQueryCompletion( "SQL 1", microtime( true ) - 10, true, 1 );
47 $tp->recordQueryCompletion( "SQL 2", microtime( true ) - 10, true, 1 );
48 $tp->transactionWritingOut( 'srv1', 'db1', '123', 20, 1 );
49 }
50
51 public function testAffectedTrx() {
52 $logger = $this->getMockBuilder( LoggerInterface::class )->getMock();
53 $logger->expects( $this->exactly( 1 ) )->method( 'info' );
54
55 $tp = new TransactionProfiler();
56 $tp->setLogger( $logger );
57 $tp->setExpectation( 'maxAffected', 100, __METHOD__ );
58
59 $tp->transactionWritingIn( 'srv1', 'db1', '123' );
60 $tp->transactionWritingOut( 'srv1', 'db1', '123', 1, 200 );
61 }
62
63 public function testWriteTimeTrx() {
64 $logger = $this->getMockBuilder( LoggerInterface::class )->getMock();
65 // 1 per trx, and one "sub-optimal trx" entry
66 $logger->expects( $this->exactly( 2 ) )->method( 'info' );
67
68 $tp = new TransactionProfiler();
69 $tp->setLogger( $logger );
70 $tp->setExpectation( 'writeQueryTime', 5, __METHOD__ );
71
72 $tp->transactionWritingIn( 'srv1', 'db1', '123' );
73 $tp->transactionWritingOut( 'srv1', 'db1', '123', 10, 1 );
74 }
75
76 public function testConns() {
77 $logger = $this->getMockBuilder( LoggerInterface::class )->getMock();
78 $logger->expects( $this->exactly( 2 ) )->method( 'info' );
79
80 $tp = new TransactionProfiler();
81 $tp->setLogger( $logger );
82 $tp->setExpectation( 'conns', 2, __METHOD__ );
83
84 $tp->recordConnection( 'srv1', 'db1', false );
85 $tp->recordConnection( 'srv1', 'db2', false );
86 $tp->recordConnection( 'srv1', 'db3', false ); // warn
87 $tp->recordConnection( 'srv1', 'db4', false ); // warn
88 }
89
90 public function testMasterConns() {
91 $logger = $this->getMockBuilder( LoggerInterface::class )->getMock();
92 $logger->expects( $this->exactly( 2 ) )->method( 'info' );
93
94 $tp = new TransactionProfiler();
95 $tp->setLogger( $logger );
96 $tp->setExpectation( 'masterConns', 2, __METHOD__ );
97
98 $tp->recordConnection( 'srv1', 'db1', false );
99 $tp->recordConnection( 'srv1', 'db2', false );
100
101 $tp->recordConnection( 'srv1', 'db1', true );
102 $tp->recordConnection( 'srv1', 'db2', true );
103 $tp->recordConnection( 'srv1', 'db3', true ); // warn
104 $tp->recordConnection( 'srv1', 'db4', true ); // warn
105 }
106
107 public function testReadQueryCount() {
108 $logger = $this->getMockBuilder( LoggerInterface::class )->getMock();
109 $logger->expects( $this->exactly( 2 ) )->method( 'info' );
110
111 $tp = new TransactionProfiler();
112 $tp->setLogger( $logger );
113 $tp->setExpectation( 'queries', 2, __METHOD__ );
114
115 $tp->recordQueryCompletion( "SQL 1", microtime( true ) - 0.01, false, 0 );
116 $tp->recordQueryCompletion( "SQL 2", microtime( true ) - 0.01, false, 0 );
117 $tp->recordQueryCompletion( "SQL 3", microtime( true ) - 0.01, false, 0 ); // warn
118 $tp->recordQueryCompletion( "SQL 4", microtime( true ) - 0.01, false, 0 ); // warn
119 }
120
121 public function testWriteQueryCount() {
122 $logger = $this->getMockBuilder( LoggerInterface::class )->getMock();
123 $logger->expects( $this->exactly( 2 ) )->method( 'info' );
124
125 $tp = new TransactionProfiler();
126 $tp->setLogger( $logger );
127 $tp->setExpectation( 'writes', 2, __METHOD__ );
128
129 $tp->recordQueryCompletion( "SQL 1", microtime( true ) - 0.01, false, 0 );
130 $tp->recordQueryCompletion( "SQL 2", microtime( true ) - 0.01, false, 0 );
131 $tp->recordQueryCompletion( "SQL 3", microtime( true ) - 0.01, false, 0 );
132 $tp->recordQueryCompletion( "SQL 4", microtime( true ) - 0.01, false, 0 );
133
134 $tp->transactionWritingIn( 'srv1', 'db1', '123' );
135 $tp->recordQueryCompletion( "SQL 1w", microtime( true ) - 0.01, true, 2 );
136 $tp->recordQueryCompletion( "SQL 2w", microtime( true ) - 0.01, true, 5 );
137 $tp->recordQueryCompletion( "SQL 3w", microtime( true ) - 0.01, true, 3 );
138 $tp->recordQueryCompletion( "SQL 4w", microtime( true ) - 0.01, true, 1 );
139 $tp->transactionWritingOut( 'srv1', 'db1', '123', 1, 1 );
140 }
141}
Helper class that detects high-contention DB queries via profiling calls.