33namespace React \Tests \MySQL \Io ;
44
55use React \MySQL \Commands \QueryCommand ;
6+ use React \MySQL \Exception ;
67use React \MySQL \Io \Executor ;
78use React \MySQL \Io \Parser ;
9+ use React \Stream \CompositeStream ;
810use React \Stream \ThroughStream ;
911use React \Tests \MySQL \BaseTestCase ;
10- use React \MySQL \Exception ;
1112
1213class ParserTest extends BaseTestCase
1314{
@@ -56,7 +57,7 @@ public function testUnexpectedErrorWithoutCurrentCommandWillBeIgnored()
5657 $ stream ->write ("\x17\0\0\0" . "\xFF" . "\x10\x04" . "Too many connections " );
5758 }
5859
59- public function testSendingErrorFrameDuringHandshakeShouldEmitErrorOnFollowingCommand ()
60+ public function testReceivingErrorFrameDuringHandshakeShouldEmitErrorOnFollowingCommand ()
6061 {
6162 $ stream = new ThroughStream ();
6263
@@ -81,7 +82,74 @@ public function testSendingErrorFrameDuringHandshakeShouldEmitErrorOnFollowingCo
8182 $ this ->assertEquals ('Too many connections ' , $ error ->getMessage ());
8283 }
8384
84- public function testSendingIncompleteErrorFrameDuringHandshakeShouldNotEmitError ()
85+ public function testReceivingErrorFrameForQueryShouldEmitError ()
86+ {
87+ $ stream = new ThroughStream ();
88+
89+ $ command = new QueryCommand ();
90+ $ command ->on ('error ' , $ this ->expectCallableOnce ());
91+
92+ $ error = null ;
93+ $ command ->on ('error ' , function ($ e ) use (&$ error ) {
94+ $ error = $ e ;
95+ });
96+
97+ $ executor = new Executor ();
98+ $ executor ->enqueue ($ command );
99+
100+ $ parser = new Parser ($ stream , $ executor );
101+ $ parser ->start ();
102+
103+ $ stream ->on ('close ' , $ this ->expectCallableNever ());
104+
105+ $ stream ->write ("\x33\0\0\0" . "\x0a" . "mysql \0" . str_repeat ("\0" , 44 ));
106+ $ stream ->write ("\x1E\0\0\1" . "\xFF" . "\x46\x04" . "#abcde " . "Unknown thread id: 42 " );
107+
108+ $ this ->assertTrue ($ error instanceof Exception);
109+ $ this ->assertEquals (1094 , $ error ->getCode ());
110+ $ this ->assertEquals ('Unknown thread id: 42 ' , $ error ->getMessage ());
111+ }
112+
113+ public function testReceivingErrorFrameForQueryAfterResultSetHeadersShouldEmitError ()
114+ {
115+ $ stream = new ThroughStream ();
116+
117+ $ command = new QueryCommand ();
118+ $ command ->on ('error ' , $ this ->expectCallableOnce ());
119+
120+ $ error = null ;
121+ $ command ->on ('error ' , function ($ e ) use (&$ error ) {
122+ $ error = $ e ;
123+ });
124+
125+ $ executor = new Executor ();
126+ $ executor ->enqueue ($ command );
127+
128+ $ parser = new Parser (new CompositeStream ($ stream , new ThroughStream ()), $ executor );
129+ $ parser ->start ();
130+
131+ $ stream ->on ('close ' , $ this ->expectCallableNever ());
132+
133+ $ stream ->write ("\x33\0\0\0" . "\x0a" . "mysql \0" . str_repeat ("\0" , 44 ));
134+ $ stream ->write ("\x01\0\0\1" . "\x01" );
135+ $ stream ->write ("\x1E\0\0\2" . "\x03" . "def " . "\0" . "\0" . "\0" . "\x09" . "sleep(10) " . "\0" . "\xC0" . "\x3F\0" . "\1\0\0\0" . "\3" . "\x81\0" . "\0" . "\0\0" );
136+ $ stream ->write ("\x05\0\0\3" . "\xFE" . "\0\0\2\0" );
137+ $ stream ->write ("\x28\0\0\4" . "\xFF" . "\x25\x05" . "#abcde " . "Query execution was interrupted " );
138+
139+ $ this ->assertTrue ($ error instanceof Exception);
140+ $ this ->assertEquals (1317 , $ error ->getCode ());
141+ $ this ->assertEquals ('Query execution was interrupted ' , $ error ->getMessage ());
142+
143+ $ ref = new \ReflectionProperty ($ parser , 'rsState ' );
144+ $ ref ->setAccessible (true );
145+ $ this ->assertEquals (0 , $ ref ->getValue ($ parser ));
146+
147+ $ ref = new \ReflectionProperty ($ parser , 'resultFields ' );
148+ $ ref ->setAccessible (true );
149+ $ this ->assertEquals ([], $ ref ->getValue ($ parser ));
150+ }
151+
152+ public function testReceivingIncompleteErrorFrameDuringHandshakeShouldNotEmitError ()
85153 {
86154 $ stream = new ThroughStream ();
87155
0 commit comments