Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop 1.1 markusjm #5

Merged
merged 5 commits into from Dec 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 15 additions & 1 deletion maxscale-cdc-adapter/mxs_adapter.cpp
Expand Up @@ -25,6 +25,7 @@
#include <unistd.h>
#include <signal.h>
#include <assert.h>
#include <execinfo.h>

bool processTable(mcsapi::ColumnStoreDriver *driver, CDC::Connection * cdcConnection, std::string dbName,
std::string tblName);
Expand Down Expand Up @@ -143,12 +144,25 @@ static void signalHandler(int sig)
}
}

static void fatalHandler(int sig)
{
void* addrs[128];
logger() << "Received fatal signal " << sig << endl;
int count = backtrace(addrs, sizeof(addrs) / sizeof(addrs[0]));
backtrace_symbols_fd(addrs, count, STDOUT_FILENO);
setSignal(sig, SIG_DFL);
raise(sig);
}

static void configureSignals()
{
std::map<int, void(*)(int)> signals =
{
std::make_pair(SIGTERM, signalHandler),
std::make_pair(SIGINT, signalHandler)
std::make_pair(SIGINT, signalHandler),
std::make_pair(SIGSEGV, fatalHandler),
std::make_pair(SIGABRT, fatalHandler),
std::make_pair(SIGFPE, fatalHandler)
};

for (auto a : signals)
Expand Down
4 changes: 1 addition & 3 deletions maxscale-cdc-adapter/test/docker/maxscale/Dockerfile
@@ -1,8 +1,6 @@
FROM centos:7
RUN yum install -y http://max-tst-01.mariadb.com/ci-repository/2.1-extra-debug/mariadb-maxscale/centos/7/x86_64/maxscale-2.1.10-1.centos.7.x86_64.rpm

# A fix from 2.1.11 is required for the adapter, we must use a custom build
#RUN yum install -y https://downloads.mariadb.com/MaxScale/2.1.10/centos/7/x86_64/maxscale-2.1.10-1.centos.7.x86_64.rpm
RUN yum install -y https://downloads.mariadb.com/MaxScale/2.1.11/centos/7/x86_64/maxscale-2.1.11-1.centos.7.x86_64.rpm

ADD maxscale.cnf /etc/maxscale.cnf
ADD master.ini /var/lib/mysql/master.ini
Expand Down
18 changes: 11 additions & 7 deletions maxscale-cdc-adapter/test/src/core.py
Expand Up @@ -3,11 +3,13 @@
import json
import time
import subprocess
import os

def getContainerIP(container):
p = subprocess.run(['docker', 'inspect', container, '-f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}"'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
return p.stdout.strip()[1:-1]
p = subprocess.check_output(['docker', 'inspect', '-f', '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}', container],
universal_newlines=True)
p = p.strip()
return p[1:-1] if p[0] == '"' else p

class MyTestCase(unittest.TestCase):
"""The base class for all tests, creates a connection to both the master and ColumnStore"""
Expand Down Expand Up @@ -62,9 +64,11 @@ def runAdapter(self, args, sleep = 5, should_work = True):


def restartContainer(self, container):
wd = self.config['environment']['docker-compose']
subprocess.run(['docker-compose', 'rm', '-vfs', container], cwd=wd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
subprocess.run(['docker-compose', 'up', '-d'], cwd=wd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
old_wd = os.getcwd()
os.chdir(self.config['environment']['docker-compose'])
subprocess.check_output(['docker-compose', 'rm', '-vf', container])
subprocess.check_output(['docker-compose', 'up', '-d'])
os.chdir(old_wd)

def connect(self, target):
wait_max = 30
Expand All @@ -85,7 +89,7 @@ def setUp(self):
"""Perform test case setup"""

# Remove old state tracking files
subprocess.run(['docker', 'exec', '-i', 'mxs_adapter', 'bash', '-c', 'rm -f /test.*'])
subprocess.check_output(['docker', 'exec', '-i', 'mxs_adapter', 'bash', '-c', 'rm -f /test.*'])

self.master = self.connect('master')
self.cs = self.connect('columnstore')
Expand Down
41 changes: 38 additions & 3 deletions maxscale-cdc-adapter/test/src/test_startup.py
Expand Up @@ -3,13 +3,15 @@

class StartupTest(core.MyTestCase):

def test_startup_no_table(self):
def test_no_table(self):
# The first error should be about missing Avro file for this table
self.startAdapter(['test', 't1'])
output, errs = self.adapter.communicate(timeout=15)
self.assertNotEqual(self.stopAdapter(), 0, msg=output)
self.assertTrue('test.t1' in output, msg="Output should have 'test.t1' in it: %s" % output)


def test_table_only_in_master(self):
# Create a table in master and insert some data
with self.master.cursor() as a:
values = range(1, 10)
Expand Down Expand Up @@ -43,12 +45,45 @@ def test_startup_no_table(self):


def test_already_existing_table(self):

""" Check that adapter works properly when both tables already exist """
with self.master.cursor() as a, self.cs.cursor() as b:
a.execute('CREATE TABLE test.t2 (id int)')
a.execute('INSERT INTO test.t2 VALUES (1), (2), (3)')
b.execute('CREATE TABLE test.t2 (id int)')
b.execute('CREATE TABLE test.t2 (id int) ENGINE=ColumnStore')

time.sleep(5)
output = self.runAdapter(['-n', 'test', 't2'], should_work=True, sleep=5)
self.assertTrue(len(output) >= 3, msg="Output should be at least three lines: " + '\n'.join(output))


def test_wrong_table_type(self):
""" Create the table as InnoDB instead of ColumnStore """
with self.master.cursor() as a, self.cs.cursor() as b:
a.execute('CREATE TABLE test.t2 (id int)')
b.execute('CREATE TABLE test.t2 (id int) ENGINE=InnoDB')
a.execute('INSERT INTO test.t2 VALUES (1), (2), (3)')

time.sleep(5)
output = '\n'.join(self.runAdapter(['-n', 'test', 't2'], should_work=True, sleep=5))
self.assertTrue('Table not found, create with' in output, msg=output)


def test_stored_position(self):
""" Check that the last GTID position is properly stored """
with self.master.cursor() as a, self.cs.cursor() as b:
a.execute('CREATE TABLE test.t3 (id int)')
b.execute('CREATE TABLE test.t3 (id int) ENGINE=ColumnStore')
for i in range(0, 3):
a.execute('INSERT INTO test.t3 VALUES (%d)' % i)

time.sleep(5)
output = self.runAdapter(['-n', 'test', 't3'], should_work=True, sleep=5)
self.assertTrue(len(output) >= 3, msg="Output should be at least three lines: " + '\n'.join(output))

with self.master.cursor() as a:
for i in range(0, 3):
a.execute('INSERT INTO test.t3 VALUES (%d)' % i)

output = self.runAdapter(['-n', 'test', 't3'], should_work=True, sleep=5)
self.assertTrue('continuing' in '\n'.join(output), msg="adapter shoud continue from previous GTID: " + '\n'.join(output))
self.assertTrue(len(output) >= 3, msg="Output should be at least three lines: " + '\n'.join(output))