99
1010use Magento \Framework \App \ResourceConnection ;
1111use Magento \Framework \DB \Adapter \AdapterInterface ;
12- use Magento \Framework \DB \Logger \File ;
1312use Magento \Framework \DB \Logger \QueryAnalyzerException ;
1413use Magento \Framework \DB \Logger \QueryAnalyzerInterface ;
1514use Magento \Framework \DB \Logger \QueryIndexAnalyzer ;
16- use Magento \Framework \DB \LoggerInterface ;
17- use Magento \Framework \Exception \FileSystemException ;
1815use Magento \Framework \Serialize \Serializer \Json ;
1916use PHPUnit \Framework \MockObject \Exception ;
2017use PHPUnit \Framework \MockObject \MockObject ;
@@ -50,53 +47,87 @@ protected function setUp(): void
5047 }
5148
5249 /**
53- * @param string $sql
54- * @param array $bind
55- * @param int $serializeCall
56- * @param string $explainResult
57- * @param mixed $expectedResult
5850 * @return void
5951 * @throws Exception
6052 * @throws QueryAnalyzerException
6153 * @throws \Zend_Db_Statement_Exception
62- * @testdox $sql with bindings $bind to get $expectedResult
63- * @dataProvider statsDataProvider
6454 */
65- public function testProcess (
66- string $ sql ,
67- array $ bind ,
68- int $ serializeCall ,
69- string $ explainResult ,
70- mixed $ expectedResult
71- ): void {
72- $ this ->serializer ->expects ($ this ->exactly ($ serializeCall ))
55+ public function testQueryException (): void
56+ {
57+ $ sql = "SELECT * FROM `admin_system_messages` " ;
58+ $ bind = [];
59+ $ this ->serializer ->expects ($ this ->once ())
60+ ->method ('serialize ' )
61+ ->with ($ bind )
62+ ->willReturn (json_encode ($ bind ));
63+ $ connection = $ this ->createMock (AdapterInterface::class);
64+ $ connection ->expects ($ this ->once ())
65+ ->method ('query ' )
66+ ->with ('EXPLAIN ' . $ sql )
67+ ->willThrowException (new \Zend_Db_Adapter_Exception ("Query error " ));
68+ $ this ->resource ->expects ($ this ->once ())->method ('getConnection ' )->willReturn ($ connection );
69+
70+ $ this ->expectException (QueryAnalyzerException::class);
71+ $ this ->expectExceptionMessage ("No 'explain' output available " );
72+ $ this ->queryAnalyzer ->process ($ sql , $ bind );
73+ }
74+
75+ /**
76+ * @return void
77+ * @throws Exception
78+ * @throws QueryAnalyzerException
79+ * @throws \Zend_Db_Statement_Exception
80+ */
81+ public function testProcessSmallTable (): void
82+ {
83+ $ sql = "SELECT `main_table`.* FROM `admin_system_messages` AS `main_table`
84+ ORDER BY severity ASC, created_at DESC " ;
85+ $ bind = [];
86+ $ explainResult = '[{"id":"1","select_type":"SIMPLE","table":"admin_system_messages","partitions":null,"type":"ALL",
87+ "possible_keys":null,"key":null,"key_len":null,"ref":null,"rows":"1","filtered":"100.00",
88+ "Extra":"Using filesort"}] ' ;
89+
90+ $ this ->serializer ->expects ($ this ->once ())
7391 ->method ('serialize ' )
7492 ->with ($ bind )
7593 ->willReturn (json_encode ($ bind ));
7694 $ statement = $ this ->createMock (\Zend_Db_Statement_Interface::class);
77- $ statement ->expects ($ this ->any ())->method ('fetchAll ' )->willReturn (json_decode ($ explainResult , true ));
95+ $ statement ->expects ($ this ->once ())
96+ ->method ('fetchAll ' )
97+ ->willReturn (json_decode ($ explainResult , true ));
7898 $ connection = $ this ->createMock (AdapterInterface::class);
79- $ connection ->expects ($ this ->any ())
99+ $ connection ->expects ($ this ->once ())
80100 ->method ('query ' )
81101 ->with ('EXPLAIN ' . $ sql )
82102 ->willReturn ($ statement );
83- $ this ->resource ->expects ($ this ->any ())->method ('getConnection ' )->willReturn ($ connection );
103+ $ this ->resource ->expects ($ this ->once ())->method ('getConnection ' )->willReturn ($ connection );
84104
85- if ($ expectedResult instanceof \Exception) {
86- $ this ->expectException (\Exception::class);
87- $ this ->expectExceptionMessage ($ expectedResult ->getMessage ());
88- $ this ->queryAnalyzer ->process ($ sql , $ bind );
89- } else {
90- $ result = $ this ->queryAnalyzer ->process ($ sql , $ bind );
91- $ this ->assertSame ($ expectedResult , $ result );
92- }
105+ $ this ->expectException (QueryAnalyzerException::class);
106+ $ this ->expectExceptionMessage ("Small table " );
107+ $ this ->queryAnalyzer ->process ($ sql , $ bind );
93108 }
94109
95110 /**
96- * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
97- * @return array
111+ * @param string $sql
112+ * @param array $bind
113+ * @return void
114+ * @throws QueryAnalyzerException
115+ * @throws \Zend_Db_Statement_Exception
116+ * @dataProvider statsNonSelectDataProvider
117+ * @testdox $sql with bindings $bind to get $expectedResult
98118 */
99- public static function statsDataProvider (): array
119+ public function testProcessThrowsExceptionForNonSelectQuery (string $ sql , array $ bind ): void {
120+ $ this ->expectException (QueryAnalyzerException::class);
121+ $ this ->expectExceptionMessage ("Can't process query type " );
122+ $ this ->serializer ->expects ($ this ->never ())->method ('serialize ' );
123+
124+ $ this ->queryAnalyzer ->process ($ sql , $ bind );
125+ }
126+
127+ /**
128+ * @return array[]
129+ */
130+ public static function statsNonSelectDataProvider (): array
100131 {
101132 return [
102133 'no-stats-for-update-query ' => [
@@ -123,17 +154,57 @@ public static function statsDataProvider(): array
123154 0 ,
124155 '{} ' ,
125156 new QueryAnalyzerException ("Can't process query type " )
126- ],
127- 'small-table-query ' => [
128- "SELECT `main_table`.* FROM `admin_system_messages` AS `main_table`
129- ORDER BY severity ASC, created_at DESC " ,
130- [],
131- 1 ,
132- '[{"id":"1","select_type":"SIMPLE","table":"admin_system_messages","partitions":null,"type":"ALL",
133- "possible_keys":null,"key":null,"key_len":null,"ref":null,"rows":"1","filtered":"100.00",
134- "Extra":"Using filesort"}] ' ,
135- new QueryAnalyzerException ("Small table " )
136- ],
157+ ]
158+ ];
159+ }
160+
161+ /**
162+ * @param string $sql
163+ * @param array $bind
164+ * @param string $explainResult
165+ * @param mixed $expectedResult
166+ * @return void
167+ * @throws Exception
168+ * @throws QueryAnalyzerException
169+ * @throws \Zend_Db_Statement_Exception
170+ * @testdox $sql with bindings $bind to get $expectedResult
171+ * @dataProvider statsDataProvider
172+ */
173+ public function testProcess (
174+ string $ sql ,
175+ array $ bind ,
176+ string $ explainResult ,
177+ mixed $ expectedResult
178+ ): void {
179+ $ this ->serializer ->expects ($ this ->once ())
180+ ->method ('serialize ' )
181+ ->with ($ bind )
182+ ->willReturn (json_encode ($ bind ));
183+ $ statement = $ this ->createMock (\Zend_Db_Statement_Interface::class);
184+ $ statement ->expects ($ this ->any ())->method ('fetchAll ' )->willReturn (json_decode ($ explainResult , true ));
185+ $ connection = $ this ->createMock (AdapterInterface::class);
186+ $ connection ->expects ($ this ->once ())
187+ ->method ('query ' )
188+ ->with ('EXPLAIN ' . $ sql )
189+ ->willReturn ($ statement );
190+ $ this ->resource ->expects ($ this ->once ())->method ('getConnection ' )->willReturn ($ connection );
191+
192+ if ($ expectedResult instanceof \Exception) {
193+ $ this ->expectException (\Exception::class);
194+ $ this ->expectExceptionMessage ($ expectedResult ->getMessage ());
195+ $ this ->queryAnalyzer ->process ($ sql , $ bind );
196+ } else {
197+ $ result = $ this ->queryAnalyzer ->process ($ sql , $ bind );
198+ $ this ->assertSame ($ expectedResult , $ result );
199+ }
200+ }
201+
202+ /**
203+ * @return array
204+ */
205+ public static function statsDataProvider (): array
206+ {
207+ return [
137208 'subselect-with-dependent-query ' => [
138209 "SELECT `main_table`.*, (IF(
139210 (SELECT count(*)
@@ -145,7 +216,6 @@ public static function statsDataProvider(): array
145216 )) AS `status` FROM `magento_bulk` AS `main_table` WHERE (`user_id` = '1')
146217 ORDER BY FIELD(status, 2,3,0,4,1), start_time DESC " ,
147218 [],
148- 1 ,
149219 '[{"id":"1","select_type":"PRIMARY","table":"main_table","partitions":null,"type":"ref",
150220 "possible_keys":"MAGENTO_BULK_USER_ID","key":"MAGENTO_BULK_USER_ID","key_len":"5","ref":"const",
151221 "rows":"1","filtered":"100.00","Extra":"Using filesort"},{"id":"3","select_type":"DEPENDENT SUBQUERY",
@@ -168,7 +238,6 @@ public static function statsDataProvider(): array
168238 ('simple', 'virtual', 'bundle', 'downloadable', 'configurable', 'grouped')))
169239 GROUP BY `o`.`product_type` " ,
170240 [],
171- 1 ,
172241 '[{"id":1,"select_type":"SIMPLE","table":"o","partitions":null,"type":"ref","possible_keys":
173242 "SALES_ORDER_ITEM_ORDER_ID","key":"SALES_ORDER_ITEM_ORDER_ID","key_len":"4","ref":"const",
174243 "rows":2,"filtered":45,"Extra":"Using where; Using temporary"}] ' ,
@@ -186,7 +255,6 @@ public static function statsDataProvider(): array
186255 OR (`is_visible_in_advanced_search` = '1') OR (((`is_filterable` = '1') OR (`is_filterable` = '2')))
187256 OR (`is_filterable_in_search` = '1')) " ,
188257 [],
189- 1 ,
190258 '[{"id":1,"select_type":"SIMPLE","table":"additional_table","partitions":null,"type":"ALL",
191259 "possible_keys":"PRIMARY","key":null,"key_len":null,"ref":null,"rows":170,"filtered":40.95,"Extra":
192260 "Using where"},{"id":1,"select_type":"SIMPLE","table":"main_table","partitions":null,"type":"eq_ref",
0 commit comments