Skip to content

Commit 4985b81

Browse files
committed
Added docker-compose, system tests and dockerize it
1 parent 0961ab6 commit 4985b81

File tree

6 files changed

+168
-4
lines changed

6 files changed

+168
-4
lines changed

.coveragerc

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
[run]
2+
branch = True
3+
4+
[report]
5+
# Regexes for lines to exclude from consideration
6+
exclude_lines =
7+
# Have to re-enable the standard pragma
8+
pragma: no cover
9+
10+
# Don't complain about missing debug-only code:
11+
def __repr__
12+
def __unicode__
13+
if self\.debug
14+
15+
# Don't complain if tests don't hit defensive assertion code:
16+
raise AssertionError
17+
raise NotImplementedError
18+
19+
# Don't complain if non-runnable code isn't run:
20+
if 0:
21+
if __name__ == .__main__.:
22+
23+
include =
24+
pgclient/*
25+
omit =
26+
pgclient/tests.py
27+
28+
ignore_errors = True
29+
30+
[html]
31+
directory = coverage_html_report

Makefile

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
# System variables
22
ENV_DIR=$(CURDIR)/.env
33
PYTHON=$(ENV_DIR)/bin/python
4+
NOSE=$(ENV_DIR)/bin/nosetests
45
COVERAGE=$(ENV_DIR)/bin/coverage
56
PROJECT_NAME=pgclient
7+
CODE_DIR=$(CURDIR)/$(PROJECT_NAME)
8+
69

710
help:
811
# target: help - Display callable targets
@@ -21,16 +24,20 @@ pypi_upload:
2124

2225
.PHONY: test
2326
test: env
24-
# target: test - Run tests
25-
@$(PYTHON) -m unittest discover
27+
@$(NOSE) $(CODE_DIR)/tests.py
28+
29+
.PHONY: system_test
30+
system_test: env
31+
# target: test - Run system_test
32+
@$(NOSE) system_test.py
2633

2734

2835
.PHONY: test_ci
2936
test_ci: env
3037
# target: test_ci - Run tests command adapt for CI systems
31-
@$(PYTHON) -m unittest discover
38+
@$(NOSE) $(CODE_DIR)/tests.py
3239

3340
.PHONY: test_coverage
3441
# target: test_coverage - Run tests with coverage
3542
test_coverage: env
36-
@$(COVERAGE) run --source=$(PROJECT_NAME) $(PYTHON) -m unittest discover
43+
@$(COVERAGE) run --source=$(PROJECT_NAME) $(NOSE) $(CODE_DIR)/tests.py

docker-compose.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
system_test:
2+
build: system_test
3+
ports:
4+
- "5432:5432"
5+
environment:
6+
POSTGRES_PASSWORD: test

pgclient/queryset.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# -*- coding: utf-8 -*-
2+
3+
4+
if __name__ == '__main__':
5+
pass

pgclient/system_test/Dockerfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
FROM postgresql
2+
3+
# Default user is postgres
4+
ENV POSTGRES_PASSWORD: test
5+
6+
# This dir is supported by official postgresql image
7+
ENV PSQL_ENTRYPOINT /docker-entrypoint-initdb.d
8+
9+
MKDIR $PSQL_ENTRYPOINT
10+
RUN echo "CREATE DATABASE test WITH OWNER postgres;" >> $PSQL_ENTRYPOINT/create_db.sql
11+
12+
#CMD python app.py
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# -*- coding: utf-8 -*-
2+
"""Integration system test for database manager"""
3+
4+
import sys
5+
import os.path as op
6+
import psycopg2
7+
8+
sys.path.append(
9+
op.abspath(op.dirname(__file__)) + '/../'
10+
)
11+
12+
import unittest
13+
from pgclient.client import DatabaseManager
14+
import random
15+
16+
17+
NAMES = ['Alex', 'Andrea', 'Ashley', 'Casey', 'Chris', 'Dorian', 'Jerry']
18+
19+
20+
class DatabaseManagerSystemTest(unittest.TestCase):
21+
DB_USER = 'postgres'
22+
DB_PASSWORD = 'test'
23+
DB_NAME = 'test'
24+
TABLE_NAME = 'users'
25+
26+
def setUp(self):
27+
dsn = 'user={} password={} dbname={} host=localhost'.format(
28+
self.DB_USER, self.DB_PASSWORD, self.DB_NAME)
29+
self.db_manager = DatabaseManager(dsn=dsn, pool_size=10)
30+
31+
try:
32+
self._create_table()
33+
except psycopg2.DatabaseError:
34+
self._drop_table()
35+
self._create_table()
36+
37+
# Insert 100 entries
38+
with self.db_manager.cursor as cursor:
39+
for _ in range(100):
40+
insert_str = "INSERT INTO {} (username) VALUES (%s)".format(
41+
self.TABLE_NAME)
42+
cursor.execute(insert_str, (random.choice(NAMES),))
43+
44+
def _create_table(self):
45+
# Init database with test data
46+
with self.db_manager.cursor as cursor:
47+
cursor.execute(
48+
"CREATE TABLE {} "
49+
"(id serial PRIMARY KEY, username VARCHAR NOT NULL );".format(
50+
self.TABLE_NAME))
51+
print('Table {} has been created'.format(self.TABLE_NAME))
52+
53+
def _drop_table(self):
54+
with self.db_manager.cursor as cursor:
55+
cursor.execute('DROP TABLE {}'.format(self.TABLE_NAME))
56+
print('Table {} has been dropped'.format(self.TABLE_NAME))
57+
58+
def tearDown(self):
59+
self._drop_table()
60+
61+
def test_cursor(self):
62+
with self.db_manager.cursor as cursor:
63+
cursor.execute('SELECT * FROM users')
64+
result_set = cursor.fetchall()
65+
self.assertEqual(len(result_set), 100)
66+
67+
def test_dict_cursor(self):
68+
with self.db_manager.dict_cursor as cursor:
69+
cursor.execute('SELECT * FROM users')
70+
result_set = cursor.fetchall()
71+
item = result_set[0]
72+
self.assertIn('id', item)
73+
self.assertIn('username', item)
74+
self.assertIn(item['username'], NAMES)
75+
76+
def test_named_tuple_cursor(self):
77+
with self.db_manager.nt_cursor as cursor:
78+
cursor.execute('SELECT * FROM users')
79+
result_set = cursor.fetchall()
80+
item = result_set[0]
81+
self.assertIsInstance(item.id, int)
82+
self.assertIsInstance(item.username, str)
83+
84+
def test_success_transaction(self):
85+
with self.db_manager.cursor as transaction:
86+
insert_str = "INSERT INTO {} (username) VALUES (%s)".format(
87+
self.TABLE_NAME)
88+
transaction.execute(insert_str, (random.choice(NAMES), ))
89+
transaction.execute('SELECT * FROM users')
90+
result_set = transaction.fetchall()
91+
self.assertEqual(len(result_set), 101)
92+
93+
def test_rollback_transaction(self):
94+
with self.db_manager.cursor as transaction:
95+
with self.assertRaises(psycopg2.DatabaseError) as err:
96+
transaction.execute(
97+
"INSERT INTO {} (username) VALUES (%s)".format(self.TABLE_NAME),
98+
(None, ))
99+
self.assertIn('null value in column', err.exception.message)
100+
101+
102+
if __name__ == '__main__':
103+
unittest.main()

0 commit comments

Comments
 (0)