chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
import pymysql
|
||||
import sys
|
||||
|
||||
def main():
|
||||
user = sys.argv[1]
|
||||
port = int(sys.argv[2])
|
||||
db = sys.argv[3]
|
||||
expected_version_string = sys.argv[4]
|
||||
|
||||
connection = pymysql.connect(host="127.0.0.1",
|
||||
port=port,
|
||||
user=user,
|
||||
db=db)
|
||||
|
||||
if connection.server_version != expected_version_string:
|
||||
print(f"Unexpected server version, expected {expected_version_string}, got {connection.server_version}")
|
||||
sys.exit(1)
|
||||
|
||||
connection.close()
|
||||
sys.exit(0)
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,81 @@
|
||||
import mariadb
|
||||
import sys
|
||||
|
||||
QUERY_RESPONSE = [
|
||||
{"create table test (pk int, `value` int, primary key(pk))": ()},
|
||||
{"describe test": (
|
||||
('pk', 'int', 'NO', 'PRI', None, ''),
|
||||
('value', 'int', 'YES', '', None, '')
|
||||
)},
|
||||
{"insert into test (pk, `value`) values (0,0)": ()},
|
||||
{"select * from test": ((0, 0),)},
|
||||
{"call dolt_add('-A');": ((0,),)},
|
||||
{"call dolt_commit('-m', 'my commit')": (('',),)},
|
||||
{"select COUNT(*) FROM dolt_log": ((2,),)},
|
||||
{"call dolt_checkout('-b', 'mybranch')": ((0, "Switched to branch 'mybranch'"),)},
|
||||
{"insert into test (pk, `value`) values (1,1)": ()},
|
||||
{"call dolt_commit('-a', '-m', 'my commit2')": (('',),)},
|
||||
{"call dolt_checkout('main')": ((0, "Switched to branch 'main'"),)},
|
||||
{"call dolt_merge('mybranch')": (('',1,0,),)},
|
||||
{"select COUNT(*) FROM dolt_log": ((3,),)},
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
user = sys.argv[1]
|
||||
port = int(sys.argv[2])
|
||||
db = sys.argv[3]
|
||||
|
||||
try:
|
||||
# Connect using MariaDB Connector/Python
|
||||
connection = mariadb.connect(
|
||||
user=user,
|
||||
host="127.0.0.1",
|
||||
port=port,
|
||||
database=db
|
||||
)
|
||||
|
||||
print(f"Connected to MariaDB using MariaDB Connector/Python v{mariadb.__version__}")
|
||||
|
||||
cursor = connection.cursor()
|
||||
|
||||
for query_response in QUERY_RESPONSE:
|
||||
query = list(query_response.keys())[0]
|
||||
exp_results = query_response[query]
|
||||
|
||||
cursor.execute(query)
|
||||
|
||||
try:
|
||||
results = cursor.fetchall()
|
||||
|
||||
# MariaDB Connector/Python returns lists, convert to tuples for comparison
|
||||
results = tuple(tuple(row) if isinstance(row, list) else row for row in results)
|
||||
|
||||
# Skip validation for dolt_commit and dolt_merge as their results vary
|
||||
if ("dolt_commit" not in query) and ("dolt_merge" not in query):
|
||||
if results != exp_results:
|
||||
print("Query:")
|
||||
print(query)
|
||||
print("Expected:")
|
||||
print(exp_results)
|
||||
print("Received:")
|
||||
print(results)
|
||||
sys.exit(1)
|
||||
except mariadb.Error:
|
||||
# This is a write query with no results
|
||||
pass
|
||||
|
||||
cursor.close()
|
||||
connection.close()
|
||||
|
||||
print("All MariaDB Connector/Python tests passed!")
|
||||
sys.exit(0)
|
||||
|
||||
except mariadb.Error as e:
|
||||
print(f"Error connecting to MariaDB: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import mysql.connector
|
||||
import sys
|
||||
|
||||
QUERY_RESPONSE = [
|
||||
{"create table test (pk int, `value` int, primary key(pk))": []},
|
||||
{"describe test": [
|
||||
('pk', 'int', 'NO', 'PRI', None, ''),
|
||||
('value', 'int', 'YES', '', None, '')
|
||||
]},
|
||||
{"insert into test (pk, `value`) values (0,0)": []},
|
||||
{"select * from test": [(0, 0)]},
|
||||
# We used to have a bug where spaces after a semicolon in a query
|
||||
# would cause a client/server disconnect.
|
||||
# https://github.com/dolthub/vitess/pull/65
|
||||
# The following regression tests it.
|
||||
{"select * from test; ": [(0, 0)]},
|
||||
{"select * from test; ": [(0, 0)]},
|
||||
# Test the Dolt SQL functions
|
||||
{"call dolt_add('-A');": [(0,)]},
|
||||
{"call dolt_commit('-m', 'my commit')": [('',)]},
|
||||
{"select COUNT(*) FROM dolt_log": [(2,)]},
|
||||
{"call dolt_checkout('-b', 'mybranch')": [(0, "Switched to branch 'mybranch'")]},
|
||||
{"insert into test (pk, `value`) values (1,1)": []},
|
||||
{"call dolt_commit('-a', '-m', 'my commit2')": [('',)]},
|
||||
{"call dolt_checkout('main')": [(0, "Switched to branch 'main'")]},
|
||||
{"call dolt_merge('mybranch')": [('',1,0,)]},
|
||||
{"select COUNT(*) FROM dolt_log": [(3,)]},
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
user = sys.argv[1]
|
||||
port = sys.argv[2]
|
||||
db = sys.argv[3]
|
||||
|
||||
connection = mysql.connector.connect(user=user,
|
||||
host="127.0.0.1",
|
||||
port=port,
|
||||
database=db)
|
||||
|
||||
for query_response in QUERY_RESPONSE:
|
||||
query = list(query_response.keys())[0]
|
||||
exp_results = query_response[query]
|
||||
cursor = connection.cursor()
|
||||
cursor.execute(query)
|
||||
try:
|
||||
results = cursor.fetchall()
|
||||
print(exp_results)
|
||||
print(results)
|
||||
if (results != exp_results) and ("dolt_commit" not in query) and ("dolt_merge" not in query):
|
||||
print("Query:")
|
||||
print(query)
|
||||
print("Expected:")
|
||||
print(exp_results)
|
||||
print("Received:")
|
||||
print(results)
|
||||
sys.exit(1)
|
||||
except mysql.connector.errors.InterfaceError:
|
||||
|
||||
# This is a write query
|
||||
pass
|
||||
|
||||
cursor.close()
|
||||
|
||||
connection.close()
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,54 @@
|
||||
import pymysql
|
||||
import sys
|
||||
|
||||
QUERY_RESPONSE = [
|
||||
{"create table test (pk int, `value` int, primary key(pk))": ()},
|
||||
{"describe test": (
|
||||
('pk', 'int', 'NO', 'PRI', None, ''),
|
||||
('value', 'int', 'YES', '', None, '')
|
||||
)},
|
||||
{"insert into test (pk, `value`) values (0,0)": ()},
|
||||
{"select * from test": ((0, 0),)},
|
||||
{"call dolt_add('-A');": ((0,),)},
|
||||
{"call dolt_commit('-m', 'my commit')": (('',),)},
|
||||
{"select COUNT(*) FROM dolt_log": ((2,),)},
|
||||
{"call dolt_checkout('-b', 'mybranch')": ((0, "Switched to branch 'mybranch'"),)},
|
||||
{"insert into test (pk, `value`) values (1,1)": ()},
|
||||
{"call dolt_commit('-a', '-m', 'my commit2')": (('',),)},
|
||||
{"call dolt_checkout('main')": ((0, "Switched to branch 'main'"),)},
|
||||
{"call dolt_merge('mybranch')": (('',1,0,),)},
|
||||
{"select COUNT(*) FROM dolt_log": ((3,),)},
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
user = sys.argv[1]
|
||||
port = int(sys.argv[2])
|
||||
db = sys.argv[3]
|
||||
|
||||
connection = pymysql.connect(host="127.0.0.1",
|
||||
port=port,
|
||||
user=user,
|
||||
db=db)
|
||||
|
||||
for query_response in QUERY_RESPONSE:
|
||||
query = list(query_response.keys())[0]
|
||||
exp_results = query_response[query]
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute(query)
|
||||
results = cursor.fetchall()
|
||||
if (results != exp_results) and ("dolt_commit" not in query) and ("dolt_merge" not in query):
|
||||
print("Query:")
|
||||
print(query)
|
||||
print("Expected:")
|
||||
print(exp_results)
|
||||
print("Received:")
|
||||
print(results)
|
||||
sys.exit(1)
|
||||
|
||||
connection.close()
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,131 @@
|
||||
import pymysql
|
||||
import sys
|
||||
import time
|
||||
from typing import List, Optional, Iterable, Type, TypeVar
|
||||
from pymysqlreplication import BinLogStreamReader
|
||||
from pymysqlreplication.event import (
|
||||
RotateEvent,
|
||||
FormatDescriptionEvent,
|
||||
GtidEvent,
|
||||
QueryEvent,
|
||||
HeartbeatLogEvent,
|
||||
)
|
||||
from pymysqlreplication.row_event import WriteRowsEvent
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
def main():
|
||||
user = sys.argv[1]
|
||||
port = int(sys.argv[2])
|
||||
db = sys.argv[3]
|
||||
|
||||
# Connect to the running SQL server to create some test data
|
||||
connection = pymysql.connect(host="127.0.0.1",
|
||||
port=port,
|
||||
user=user,
|
||||
db=db)
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute("CREATE TABLE t (pk int primary key, c1 varchar(100));")
|
||||
cursor.execute("INSERT INTO t VALUES (1, 'foobarbazbar');")
|
||||
|
||||
# Connect to a replication event stream
|
||||
mysql_settings = {'host': '127.0.0.1', 'port': port, 'user': user, 'passwd': ''}
|
||||
stream = BinLogStreamReader(connection_settings=mysql_settings, blocking=True, server_id=100, auto_position='8e66e4f4-955a-4844-909a-33d79f78ddba:1')
|
||||
|
||||
# Grab the first 10 events
|
||||
events = read_events(stream, n=10, timeout_s=15.0)
|
||||
|
||||
# To help debugging a failed test, print out the event data
|
||||
for event in events:
|
||||
event.dump()
|
||||
|
||||
assert_correct_events(events)
|
||||
stream.close()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def assert_correct_events(events):
|
||||
"""
|
||||
Checks the events for expected events and values and raises an AssertionError if unexpected results are found.
|
||||
"""
|
||||
# Assert that a RotateEvent is present and indicates that binlog-main.000001 is the next file
|
||||
rotateEvent = require_event(events, RotateEvent)
|
||||
next_file = getattr(rotateEvent, "next_binlog", None) or getattr(rotateEvent, "next_binlog_file", None)
|
||||
assert next_file == "binlog-main.000001", f"RotateEvent next binlog expected binlog-main.000001, got {next_file!r}"
|
||||
|
||||
# Assert that a FormatDescriptionEvent is present and contains the expected binlog version number
|
||||
formatDescriptionEvent = require_event(events, FormatDescriptionEvent)
|
||||
assert getattr(formatDescriptionEvent, "binlog_version", None) == (4,), f"binlog_version expected 4, got {getattr(formatDescriptionEvent,'binlog_version',None)}"
|
||||
|
||||
# Assert that the QueryEvent for the CREATE TABLE statement is present
|
||||
queryEvent = require_event(events, QueryEvent)
|
||||
query = getattr(queryEvent, "query", None) or getattr(queryEvent, "query_text", None)
|
||||
assert query is not None, "QueryEvent query field was None"
|
||||
if isinstance(query, bytes):
|
||||
query = query.decode("utf-8", errors="replace")
|
||||
assert "CREATE TABLE" in query, f"Query did not contain CREATE TABLE: {query!r}"
|
||||
assert "`t`" in query or " t " in query, f"Query did not appear to create table t: {query!r}"
|
||||
|
||||
# Assert that a WriteRowsEvent is present with the correct row values, and that column names
|
||||
# can be used to access the fields (e.g. @@binlog_row_metadata=FULL is enabled and working).
|
||||
writeRowsEvent = require_event(events, WriteRowsEvent)
|
||||
row0 = writeRowsEvent.rows[0]
|
||||
values = row0.get("values") if isinstance(row0, dict) else getattr(row0, "values", None)
|
||||
assert isinstance(values, dict), f"Expected row values dict, got {type(values).__name__}"
|
||||
assert "pk" in values, f"Missing column 'pk'. Got keys: {sorted(values.keys())}"
|
||||
assert values["pk"] == 1, f"pk expected 1, got {values['pk']!r}"
|
||||
assert "c1" in values, f"Missing column 'c1'. Got keys: {sorted(values.keys())}"
|
||||
assert values["c1"] == "foobarbazbar", f"c1 expected 'foobarbazbar', got {values['c1']!r}"
|
||||
|
||||
def read_events(stream, n: int = 10, timeout_s: float = 30.0) -> List[object]:
|
||||
"""
|
||||
Read up to `n` non-heartbeat events from `stream`, or stop after `timeout_s`.
|
||||
Returns the list of collected events (possibly fewer than n).
|
||||
"""
|
||||
events: List[object] = []
|
||||
deadline = time.monotonic() + timeout_s
|
||||
|
||||
try:
|
||||
for ev in stream:
|
||||
# Timeout check first so we don't hang forever
|
||||
if time.monotonic() >= deadline:
|
||||
break
|
||||
|
||||
# Skip heartbeats (optional: count them, log them, etc.)
|
||||
if isinstance(ev, HeartbeatLogEvent):
|
||||
continue
|
||||
|
||||
events.append(ev)
|
||||
if len(events) >= n:
|
||||
break
|
||||
finally:
|
||||
# Important: stop network/background reading to avoid hangs/leaks
|
||||
try:
|
||||
stream.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return events
|
||||
|
||||
def find_event(events: Iterable[object], event_type: Type[T]) -> Optional[T]:
|
||||
"""
|
||||
Return the first event in `events` that is an instance of `event_type`,
|
||||
or None if no such event exists.
|
||||
"""
|
||||
for event in events:
|
||||
if isinstance(event, event_type):
|
||||
return event
|
||||
return None
|
||||
|
||||
def require_event(events: Iterable[object], event_type: Type[T]) -> T:
|
||||
"""
|
||||
Return the first event in `events` that is an instance of `event_type`,
|
||||
or raise an AssertionError if none is found.
|
||||
"""
|
||||
event = find_event(events, event_type)
|
||||
if event is None:
|
||||
raise AssertionError(f"Expected event of type {event_type.__name__}, but none was found")
|
||||
return event
|
||||
|
||||
|
||||
main()
|
||||
@@ -0,0 +1,67 @@
|
||||
import sqlalchemy
|
||||
|
||||
from sqlalchemy.engine import Engine
|
||||
from sqlalchemy import create_engine
|
||||
|
||||
import sys
|
||||
|
||||
QUERY_RESPONSE = [
|
||||
{"create table test (pk int, `value` int, primary key(pk))": []},
|
||||
{"describe test": [
|
||||
('pk', 'int', 'NO', 'PRI', None, ''),
|
||||
('value', 'int', 'YES', '', None, '')
|
||||
]},
|
||||
{"insert into test (pk, `value`) values (0,0)": ()},
|
||||
{"select * from test": [(0, 0)]},
|
||||
{"call dolt_add('-A');": [(0,)]},
|
||||
{"call dolt_commit('-m', 'my commit')": [('',)]},
|
||||
{"select COUNT(*) FROM dolt_log": [(2,)]},
|
||||
{"call dolt_checkout('-b', 'mybranch')": [(0, "Switched to branch 'mybranch'")]},
|
||||
{"insert into test (pk, `value`) values (1,1)": []},
|
||||
{"call dolt_commit('-a', '-m', 'my commit2')": [('',)]},
|
||||
{"call dolt_checkout('main')": [(0, "Switched to branch 'main'")]},
|
||||
{"call dolt_merge('mybranch')": [('',1,0,)]},
|
||||
{"select COUNT(*) FROM dolt_log": [(3,)]},
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
user = sys.argv[1]
|
||||
port = int(sys.argv[2])
|
||||
db = sys.argv[3]
|
||||
|
||||
conn_string_base = "mysql+mysqlconnector://"
|
||||
|
||||
engine = create_engine(conn_string_base +
|
||||
"{user}@127.0.0.1:{port}/{db}".format(user=user,
|
||||
port=port,
|
||||
db=db)
|
||||
)
|
||||
|
||||
with engine.connect() as con:
|
||||
for query_response in QUERY_RESPONSE:
|
||||
query = list(query_response.keys())[0]
|
||||
exp_results = query_response[query]
|
||||
|
||||
result_proxy = con.execute(query)
|
||||
|
||||
try:
|
||||
results = result_proxy.fetchall()
|
||||
if (results != exp_results) and ("dolt_commit" not in query) and ("dolt_merge" not in query):
|
||||
print("Query:")
|
||||
print(query)
|
||||
print("Expected:")
|
||||
print(exp_results)
|
||||
print("Received:")
|
||||
print(results)
|
||||
sys.exit(1)
|
||||
# You can't call fetchall on an insert
|
||||
# so we'll just ignore the exception
|
||||
except sqlalchemy.exc.ResourceClosedError:
|
||||
pass
|
||||
|
||||
con.close()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user