Bug #102042 MySQL Server Mock cannot serve queries
Submitted: 21 Dec 2020 15:58 Modified: 4 May 2022 13:36
Reporter: Natallia Savelyeva Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Router Severity:S6 (Debug Builds)
Version:8.0 OS:Any
Assigned to: CPU Architecture:x86
Tags: mock

[21 Dec 2020 15:58] Natallia Savelyeva
Description:
MySQL Server Mock https://dev.mysql.com/doc/dev/mysql-server/latest/PAGE_MYSQL_SERVER_MOCK.html built from sources results in this error: mysql.connector.errors.InterfaceError: 2013: Lost connection to MySQL server during query
The dump output of MySQL Server Mock:
1) parses database name incorrectly (in the output database value is empty string and auth_plugin='mydb' - but from Python script 'mydb' is the database name); 
2) shows warning on wrong parsed handshake
2020-12-21 15:48:02 mock_server WARNING [7ff3a195a700] Exception caught in connection loop: Handshake response packet: parsed ok, but payload packet size (253 bytes) differs from what we parsed (67 bytes)
(Find full dump listed below). 

Note: it seems it is also needed to update the documentation on the link above and https://github.com/mysql/mysql-server/blob/8.0/router/src/mock_server/src/mysql_server_moc... because at least this command does not work './mysql_server_mock ./simple.json 5500' and according to `mysql_server_mock --help` we need to provide arguments as described at its help page.

Full dump:
--[BEGIN DUMP]----------------------------------------------

  [RAW]
    dd000011 dd22bb00 00000000 dd000000 00000000 00000000 00000000 00000000 00000000 22ffff44 004422ff 112200ee 5522cc44 22aaaa55 9900bb22 cc22dd99 442200dd 993311cc ffee1144 996655ff 00113333 77ff2244 007744ff 00994455 99226666 1199ff00 cc114466 ff22dd66 888866ff 6644ccff 33ff5522 3355ff88 ff334488 ee114411 cccc9911 dd331166 55cc9955 6611eecc ff3311cc ccff33cc 9955ee44 ffee11dd 5566dd99 3311ccdd 33ffeeee 553344ff 22dd0099 4488ffee ffff33cc 9955ee44 ffcc9933 55ee3355 777700cc dd22ee00 ffff33cc 9955ee44 ff665522 3399ffee 6688ee00 ee222233 ffff33dd dd1133ff 33dd1100 ee1155ee 77

  [HEADER] dd0000 11
    size = 253
    seq_nr = 1

  [CAPABILITY FLAGS (all sent by client are listed, * = also sent by server)] dd22 bb00 
    LONG_PASSWORD
    LONG_FLAG
    CONNECT_WITH_DB
  * PROTOCOL_41
    TRANSACTIONS
  * SECURE_CONNECTION
    MULTI_STATEMENTS
    MULTI_RESULTS
  * PLUGIN_AUTH
    CONNECT_ATTRS

  [MAX PACKET SIZE] 00000000 
    max_packet_size = 1073741824

  [CHARACTER SET] dd
    character_set = 45

  [23 RESERVED ZERO BYTES] 00000000 00000000 00000000 00000000 00000000 000000

  [REST] 22ffff44 004422ff 112200ee 5522cc44 22aaaa55 9900bb22 cc22dd99 442200dd 993311cc ffee1144 996655ff 00113333 77ff2244 007744ff 00994455 99226666 1199ff00 cc114466 ff22dd66 888866ff 6644ccff 33ff5522 3355ff88 ff334488 ee114411 cccc9911 dd331166 55cc9955 6611eecc ff3311cc ccff33cc 9955ee44 ffee11dd 5566dd99 3311ccdd 33ffeeee 553344ff 22dd0099 4488ffee ffff33cc 9955ee44 ffcc9933 55ee3355 777700cc dd22ee00 ffff33cc 9955ee44 ff665522 3399ffee 6688ee00 ee222233 ffff33dd dd1133ff 33dd1100 ee1155ee 77
    username = 'root'
    auth_response = (20 bytes) 22ff1122 00ee5522 cc4422aa aa559900 bb22cc22 
    database = ''
    auth_plugin = 'mydb'

--[END DUMP]------------------------------------------------

2020-12-21 15:48:02 mock_server WARNING [7ff3a195a700] Exception caught in connection loop: Handshake response packet: parsed ok, but payload packet size (253 bytes) differs from what we parsed (67 bytes)

How to repeat:
1. Build https://github.com/mysql/mysql-server and https://github.com/mysql/mysql-router from sources using Dockerfile (provided below)
2. Start the docker image using simple.json file with the simple trace-file content taken from 'Simple Demo' section at https://dev.mysql.com/doc/dev/mysql-server/latest/PAGE_MYSQL_SERVER_MOCK.html :
docker run -v $PWD/mock_data:/data -p 5500:5500 -it mysql-router-new /opt/mysql-router/build/stage/bin/mysql_server_mock --filename /data/simple.json --port 5500 --verbose
3. Using MySQL client execute SQL query "SELECT USER()" - I tried Valentina Studio and Python script (provided below), mysql-connector-python==8.0.22

Dockerfile content (here local folder mysql-router is a cloned folder of a frozen repo v8.0 https://github.com/mysql/mysql-router and local folder mysql-server is a cloned repo https://github.com/mysql/mysql-server) - I build it with "docker build -t mysql-router-new ." (I tried the frozen repo separately, same thing):
FROM ubuntu:18.04
ADD mysql-router /opt/mysql-router
ADD mysql-server/router /opt/mysql-server-router
ENV DEBIAN_FRONTEND "noninteractive"
RUN apt-get update -y && \
    apt-get upgrade -y && \
    apt-get install -y git cmake tzdata build-essential libevent-dev doxygen libmysqlclient-dev
RUN cp -rf /opt/mysql-server-router /opt/mysql-router
RUN cd /opt/mysql-router && \
    mkdir build && cd build && \
    cmake .. -DINSTALL_LAYOUT=STANDALONE -DCMAKE_INSTALL_PREFIX=/opt/mysql/router8.0 && \
    make install

Note, it was not possible to build mysql-server neither on Ubuntu 18.04 nor 16.04.
FROM ubuntu:16.04
ADD mysql-server /opt/mysql-server
ENV DEBIAN_FRONTEND "noninteractive"
RUN apt-get update -y && \
    apt-get upgrade -y && \
    apt-get install -y git cmake tzdata build-essential libevent-dev doxygen libmysqlclient-dev
RUN apt-get install -y libncurses5-dev pkg-config libtirpc-dev bison
RUN cd /opt/mysql-server && \
    mkdir build && cd build && \
    cmake ..  -DDOWNLOAD_BOOST=1 -DWITH_BOOST=/opt/boost && \
    make install

Python Script content:
import mysql.connector
mysql_config = {'user': 'root',
        'password': 'userpassword',
        'host': 'localhost',
        'database': 'mydb',
        'port': '5500'}
conn = mysql.connector.connect(**mysql_config)
cursor = conn.cursor()
cursor.execute('SELECT USER()')
result = cursor.fetchone();
print(result)
conn.close()

Suggested fix:
It would be great if there can be an option to build or pull a docker image with only MySQL Server Mock part (without Mysql Server and MySQL Router).
[22 Dec 2020 18:43] Frederic Descamps
Just to confirm that using the js file in router/tests/component/data it works as expected:

$ mysql_server_mock --filename simple-client.js --port 5500 -B 127.0.0.1 --verbose

$ mysql -h 127.0.0.1 -P 5500 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 0
Server version: 8.0.5-mock community

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
[29 Dec 2020 12:05] Natallia Savelyeva
I have built version 8.0.21 from sources but unfortunately I still cannot connect and get the predefined response. 
Maybe this is because I use different options for make when building from sources.
@Frederic Descamps: what make-options did you use? It would be great if you could publish your debug build in the docker image.

Details are listed below.
Connect error:
root@d49827c65f65:/# /usr/local/mysql/bin/mysql -h 127.0.0.1 -P 5500
ERROR 1064 (HY000): #reader error: at /opt/mysql-server/router/src/mock_server/src/duk_module_shim.c:562: Error: Cannot find module: common_statements
    at [anon] (/opt/mysql-server/router/src/mock_server/src/duk_module_shim.c:562) internal
    at [anon] () native strict preventsyield
    at require () native strict preventsyield
    at eval (/opt/mysql-server/router/tests/component/data/simple-client.js:1) preventsyield

Location of the common_statements file:
root@d49827c65f65:/# find / -name common_statements*
/opt/mysql-server/router/tests/component/data/local_modules/common_statements.js

Full Debug output of the mock:
docker run -v $PWD/mock_data:/data -p 5500:5500 -it mymysql:8.0.21 /opt/build/runtime_output_directory/mysql_server_mock --filename /opt/mysql-server/router/tests/component/data/simple-client.js --port 5500 -B 0.0.0.0 --verbose
2020-12-29 11:52:26 main DEBUG [7fa0b7054400]   plugin 'logger' init exit ok
2020-12-29 11:52:26 main DEBUG [7fa0b7054400]   plugin 'router_protobuf' doesn't implement init()
2020-12-29 11:52:26 main DEBUG [7fa0b7054400]   plugin 'mock_server' initializing
2020-12-29 11:52:26 main DEBUG [7fa0b7054400]   plugin 'mock_server' init exit ok
2020-12-29 11:52:26 main DEBUG [7fa0b7054400] Starting all plugins.
2020-12-29 11:52:26 main DEBUG [7fa0b7054400]   plugin 'logger:' doesn't implement start()
2020-12-29 11:52:26 main DEBUG [7fa0b3d37700]   plugin 'mock_server:classic' starting
2020-12-29 11:52:26 main DEBUG [7fa0b7054400]   plugin 'router_protobuf:' doesn't implement start()
2020-12-29 11:52:26 mock_server INFO [7fa0b3d37700] Starting to handle connections on port: 5500
2020-12-29 11:52:26 main DEBUG [7fa0b7054400] Running.
2020-12-29 11:55:16 mock_server ERROR [7fa0b2d35700] at /opt/mysql-server/router/src/mock_server/src/duk_module_shim.c:562: Error: Cannot find module: common_statements
    at [anon] (/opt/mysql-server/router/src/mock_server/src/duk_module_shim.c:562) internal
    at [anon] () native strict preventsyield
    at require () native strict preventsyield
    at eval (/opt/mysql-server/router/tests/component/data/simple-client.js:1) preventsyield

Versions:
root@8de518b01275:/# /opt/build/runtime_output_directory/mysql_server_mock --version
8.0.21
root@8de518b01275:/# /usr/local/mysql/bin/mysql --version
/usr/local/mysql/bin/mysql  Ver 8.0.21 for Linux on x86_64 (Source distribution)