Skip to content

Commit af374a4

Browse files
committed
Addressing @obi1kenobi's PR
1 parent 135578a commit af374a4

File tree

8 files changed

+67
-38
lines changed

8 files changed

+67
-38
lines changed

Pipfile

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ verify_ssl = true
66
[dev-packages]
77
bandit = "==1.4.0"
88
coveralls = "==1.2.0"
9+
# The Cython dependency of pymssql is not correctly resolved on all systems
10+
# so it is explicitly included here.
911
cython = "==0.29.2"
1012
flake8 = "==3.5.0"
1113
isort = "==4.3.4"

docker-compose.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,4 @@ services:
3737
- "127.0.0.1:1433:1433"
3838
environment:
3939
ACCEPT_EULA: "yes"
40-
MSSQL_SA_PASSWORD: Root-secure1 # password requirements are more stringent for MSSQL image
40+
MSSQL_SA_PASSWORD: Root-secure1 # password requirements are more stringent for MSSQL image

graphql_compiler/tests/conftest.py

+20-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import time
44

55
import pytest
6+
import six
67

78
from .test_data_tools.data_tool import (
89
generate_orient_integration_data, generate_orient_snapshot_data, generate_sql_integration_data,
@@ -61,13 +62,30 @@ def integration_graph_client(request, init_integration_graph_client):
6162
request.cls.graph_client = init_integration_graph_client
6263

6364

64-
@pytest.fixture(scope="class")
65+
@pytest.fixture(scope='class')
6566
def sql_integration_data(request):
6667
"""Generate integration data for SQL backends."""
68+
# initialize each SQL backend, and open a transaction on each one.
6769
sql_test_backends = init_sql_integration_test_backends()
70+
# write fixture test data within the transaction
6871
generate_sql_integration_data(sql_test_backends)
72+
# make sql backends accessible within the test class
6973
request.cls.sql_test_backends = sql_test_backends
7074
# yield the fixture to allow testing class to run
7175
yield
72-
# tear down the fixture after the testing class runs all tests.
76+
# tear down the fixture after the testing class runs all tests
77+
# including rolling back transaction to ensure all fixture data removed.
7378
tear_down_integration_test_backends(sql_test_backends)
79+
80+
81+
@pytest.fixture(scope='function')
82+
def sql_integration_test(request):
83+
"""Open nested transaction before every test function, and rollback transaction afterwards."""
84+
sql_test_backends = request.cls.sql_test_backends
85+
test_transactions = []
86+
for sql_test_backend in six.itervalues(sql_test_backends):
87+
transaction = sql_test_backend.connection.begin_nested()
88+
test_transactions.append(transaction)
89+
yield
90+
for transaction in test_transactions:
91+
transaction.rollback()

graphql_compiler/tests/integration_tests/integration_backend_config.py

+12-12
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
11
# Copyright 2018-present Kensho Technologies, LLC.
22
from collections import namedtuple
33

4-
from ..test_backend import TestBackend
4+
from .. import test_backend
55

66

77
DEFAULT_ROOT_PASSWORD = u'root'
88
MSSQL_ROOT_PASSWORD = u'Root-secure1' # mssql has stricter root password restrictions
99

1010
SQL_BACKENDS = {
11-
TestBackend.POSTGRES,
12-
TestBackend.MYSQL,
13-
TestBackend.MARIADB,
14-
TestBackend.MSSQL,
15-
TestBackend.SQLITE,
11+
test_backend.POSTGRES,
12+
test_backend.MYSQL,
13+
test_backend.MARIADB,
14+
test_backend.MSSQL,
15+
test_backend.SQLITE,
1616
}
1717

1818
MATCH_BACKENDS = {
19-
TestBackend.ORIENTDB,
19+
test_backend.ORIENTDB,
2020
}
2121

2222
SQL_BACKEND_TO_CONNECTION_STRING = {
23-
TestBackend.POSTGRES:
23+
test_backend.POSTGRES:
2424
u'postgresql://postgres:{password}@localhost:5432'.format(password=DEFAULT_ROOT_PASSWORD),
25-
TestBackend.MYSQL:
25+
test_backend.MYSQL:
2626
u'mysql://root:{password}@127.0.0.1:3306'.format(password=DEFAULT_ROOT_PASSWORD),
27-
TestBackend.MARIADB:
27+
test_backend.MARIADB:
2828
u'mysql://root:{password}@127.0.0.1:3307'.format(password=DEFAULT_ROOT_PASSWORD),
29-
TestBackend.MSSQL:
29+
test_backend.MSSQL:
3030
u'mssql+pymssql://SA:{password}@localhost:1433'.format(password=MSSQL_ROOT_PASSWORD),
31-
TestBackend.SQLITE:
31+
test_backend.SQLITE:
3232
u'sqlite:///:memory:',
3333
}
3434

graphql_compiler/tests/integration_tests/integration_test_helpers.py

+10-11
Original file line numberDiff line numberDiff line change
@@ -38,20 +38,19 @@ def compile_and_run_match_query(schema, graphql_query, parameters, graph_client)
3838
def compile_and_run_sql_query(schema, graphql_query, parameters, sql_test_backend):
3939
"""Compiles and runs a SQL query against the supplied SQL backend."""
4040
# TODO: un-mock the SQL compilation once the SQL backend can run queries.
41-
mock_compilation_result = CompilationResult(
42-
query=text('SELECT name AS animal_name FROM animal'),
43-
language=SQL_LANGUAGE,
44-
input_metadata={},
45-
output_metadata={'animal_name': OutputMetadata(GraphQLString, False)}
46-
)
47-
4841
def mock_sql_compilation(schema, graphql_query, parameters, compiler_metadata):
42+
"""Mock out SQL backend compilation for unimplemented SQL backend."""
43+
mock_compilation_result = CompilationResult(
44+
query=text('SELECT name AS animal_name FROM animal'),
45+
language=SQL_LANGUAGE,
46+
input_metadata={},
47+
output_metadata={'animal_name': OutputMetadata(GraphQLString, False)}
48+
)
4949
return mock_compilation_result
5050

5151
compilation_result = mock_sql_compilation(schema, graphql_query, parameters, None)
5252
query = compilation_result.query
53-
results = [
54-
dict(result) for result
55-
in sql_test_backend.connection.execute(query)
56-
]
53+
results = []
54+
for result in sql_test_backend.connection.execute(query):
55+
results.append(dict(result))
5756
return results

graphql_compiler/tests/integration_tests/test_backends_integration.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@
1515
# does not recognize
1616
# pylint: disable=no-member
1717

18+
19+
# Store the typical fixtures required for an integration tests.
20+
# Individual tests can supply the full @pytest.mark.usefixtures to override if necessary.
21+
integration_fixture_decorator = pytest.mark.usefixtures(
22+
'integration_graph_client',
23+
'sql_integration_data',
24+
'sql_integration_test',
25+
)
26+
27+
1828
class IntegrationTests(TestCase):
1929

2030
@classmethod
@@ -39,7 +49,7 @@ def compile_and_run_query(cls, graphql_query, parameters):
3949
4050
Args:
4151
graphql_query: str, GraphQL query string to run against every backend.
42-
parameters: Dict, input parameters to the query.
52+
parameters: Dict[str, Any], input parameters to the query.
4353
4454
Returns:
4555
Dict[str, Dict], dictionary mapping the TestBackend to the results fetched from that
@@ -57,7 +67,7 @@ def compile_and_run_query(cls, graphql_query, parameters):
5767
backend_to_results[backend_name] = results
5868
return backend_to_results
5969

60-
@pytest.mark.usefixtures('integration_graph_client', 'sql_integration_data')
70+
@integration_fixture_decorator
6171
def test_backends(self):
6272
graphql_query = '''
6373
{
+7-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Copyright 2018-present Kensho Technologies, LLC.
2-
class TestBackend(object):
3-
POSTGRES = u'postgresql'
4-
MYSQL = u'mysql'
5-
MARIADB = u'mariadb'
6-
MSSQL = u'mssql'
7-
SQLITE = u'sqlite'
8-
ORIENTDB = u'orientdb'
2+
3+
POSTGRES = u'postgresql'
4+
MYSQL = u'mysql'
5+
MARIADB = u'mariadb'
6+
MSSQL = u'mssql'
7+
SQLITE = u'sqlite'
8+
ORIENTDB = u'orientdb'

graphql_compiler/tests/test_data_tools/data_tool.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
import six
77
from sqlalchemy import Column, Integer, MetaData, String, Table, create_engine, text
88

9+
from .. import test_backend
910
from ..integration_tests.integration_backend_config import (
1011
SQL_BACKEND_TO_CONNECTION_STRING, SqlTestBackend
1112
)
12-
from ..test_backend import TestBackend
1313

1414

1515
def generate_orient_snapshot_data(client):
@@ -46,7 +46,7 @@ def init_sql_integration_test_backends():
4646
for backend_name, connection_string in six.iteritems(SQL_BACKEND_TO_CONNECTION_STRING):
4747
engine = create_engine(connection_string)
4848
# MYSQL and MARIADB do not have a default DB so a DB must be created
49-
if backend_name in {TestBackend.MYSQL, TestBackend.MARIADB}:
49+
if backend_name in {test_backend.MYSQL, test_backend.MARIADB}:
5050
# safely create the DB
5151
engine.execute(text('DROP DATABASE IF EXISTS animals; CREATE DATABASE animals'))
5252
# update the connection string and engine to connect to this DB specifically
@@ -64,7 +64,7 @@ def init_sql_integration_test_backends():
6464

6565

6666
def tear_down_integration_test_backends(sql_test_backends):
67-
"""Rollback backends' transactions and close the active connections."""
67+
"""Rollback backends' transactions to wipe test data and to close the active connections."""
6868
for sql_test_backend in six.itervalues(sql_test_backends):
6969
sql_test_backend.transaction.rollback()
7070
sql_test_backend.connection.close()

0 commit comments

Comments
 (0)