Browse Source

misc: Use python and test with docker

master
rkaneko 3 years ago
parent
commit
b401fe6714
  1. 6
      .gitignore
  2. 15
      Pipfile
  3. 144
      Pipfile.lock
  4. 24
      README.md
  5. 25
      docker-compose.yml
  6. 6
      env/test/.env
  7. 0
      test/__init__.py
  8. 72
      test/dbtest.py
  9. 50
      test/test_example.py

6
.gitignore

@ -1 +1,5 @@
# ignore config
.venv/
__pycache__
.pytest_cache/

15
Pipfile

@ -0,0 +1,15 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
pytest = "*"
[packages]
psycopg2-binary = "*"
[requires]
python_version = "3.7"
[scripts]

144
Pipfile.lock

@ -0,0 +1,144 @@
{
"_meta": {
"hash": {
"sha256": "2732cd143c656d9b3256de0861c4df2eae10e59286513de09a99222ac596599d"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.7"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"psycopg2-binary": {
"hashes": [
"sha256:040234f8a4a8dfd692662a8308d78f63f31a97e1c42d2480e5e6810c48966a29",
"sha256:086f7e89ec85a6704db51f68f0dcae432eff9300809723a6e8782c41c2f48e03",
"sha256:18ca813fdb17bc1db73fe61b196b05dd1ca2165b884dd5ec5568877cabf9b039",
"sha256:19dc39616850342a2a6db70559af55b22955f86667b5f652f40c0e99253d9881",
"sha256:2166e770cb98f02ed5ee2b0b569d40db26788e0bf2ec3ae1a0d864ea6f1d8309",
"sha256:3a2522b1d9178575acee4adf8fd9f979f9c0449b00b4164bb63c3475ea6528ed",
"sha256:3aa773580f85a28ffdf6f862e59cb5a3cc7ef6885121f2de3fca8d6ada4dbf3b",
"sha256:3b5deaa3ee7180585a296af33e14c9b18c218d148e735c7accf78130765a47e3",
"sha256:407af6d7e46593415f216c7f56ba087a9a42bd6dc2ecb86028760aa45b802bd7",
"sha256:4c3c09fb674401f630626310bcaf6cd6285daf0d5e4c26d6e55ca26a2734e39b",
"sha256:4c6717962247445b4f9e21c962ea61d2e884fc17df5ddf5e35863b016f8a1f03",
"sha256:50446fae5681fc99f87e505d4e77c9407e683ab60c555ec302f9ac9bffa61103",
"sha256:5057669b6a66aa9ca118a2a860159f0ee3acf837eda937bdd2a64f3431361a2d",
"sha256:5dd90c5438b4f935c9d01fcbad3620253da89d19c1f5fca9158646407ed7df35",
"sha256:659c815b5b8e2a55193ede2795c1e2349b8011497310bb936da7d4745652823b",
"sha256:69b13fdf12878b10dc6003acc8d0abf3ad93e79813fd5f3812497c1c9fb9be49",
"sha256:7a1cb80e35e1ccea3e11a48afe65d38744a0e0bde88795cc56a4d05b6e4f9d70",
"sha256:7e6e3c52e6732c219c07bd97fff6c088f8df4dae3b79752ee3a817e6f32e177e",
"sha256:7f42a8490c4fe854325504ce7a6e4796b207960dabb2cbafe3c3959cb00d1d7e",
"sha256:84156313f258eafff716b2961644a4483a9be44a5d43551d554844d15d4d224e",
"sha256:8578d6b8192e4c805e85f187bc530d0f52ba86c39172e61cd51f68fddd648103",
"sha256:890167d5091279a27e2505ff0e1fb273f8c48c41d35c5b92adbf4af80e6b2ed6",
"sha256:9aadff9032e967865f9778485571e93908d27dab21d0fdfdec0ca779bb6f8ad9",
"sha256:9f24f383a298a0c0f9b3113b982e21751a8ecde6615494a3f1470eb4a9d70e9e",
"sha256:a73021b44813b5c84eda4a3af5826dd72356a900bac9bd9dd1f0f81ee1c22c2f",
"sha256:afd96845e12638d2c44d213d4810a08f4dc4a563f9a98204b7428e567014b1cd",
"sha256:b73ddf033d8cd4cc9dfed6324b1ad2a89ba52c410ef6877998422fcb9c23e3a8",
"sha256:dbc5cd56fff1a6152ca59445178652756f4e509f672e49ccdf3d79c1043113a4",
"sha256:eac8a3499754790187bb00574ab980df13e754777d346f85e0ff6df929bcd964",
"sha256:eaed1c65f461a959284649e37b5051224f4db6ebdc84e40b5e65f2986f101a08"
],
"index": "pypi",
"version": "==2.8.4"
}
},
"develop": {
"atomicwrites": {
"hashes": [
"sha256:03472c30eb2c5d1ba9227e4c2ca66ab8287fbfbbda3888aa93dc2e28fc6811b4",
"sha256:75a9445bac02d8d058d5e1fe689654ba5a6556a1dfd8ce6ec55a0ed79866cfa6"
],
"version": "==1.3.0"
},
"attrs": {
"hashes": [
"sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c",
"sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72"
],
"version": "==19.3.0"
},
"importlib-metadata": {
"hashes": [
"sha256:aa18d7378b00b40847790e7c27e11673d7fed219354109d0e7b9e5b25dc3ad26",
"sha256:d5f18a79777f3aa179c145737780282e27b508fc8fd688cb17c7a813e8bd39af"
],
"markers": "python_version < '3.8'",
"version": "==0.23"
},
"more-itertools": {
"hashes": [
"sha256:409cd48d4db7052af495b09dec721011634af3753ae1ef92d2b32f73a745f832",
"sha256:92b8c4b06dac4f0611c0729b2f2ede52b2e1bac1ab48f089c7ddc12e26bb60c4"
],
"version": "==7.2.0"
},
"packaging": {
"hashes": [
"sha256:28b924174df7a2fa32c1953825ff29c61e2f5e082343165438812f00d3a7fc47",
"sha256:d9551545c6d761f3def1677baf08ab2a3ca17c56879e70fecba2fc4dde4ed108"
],
"version": "==19.2"
},
"pluggy": {
"hashes": [
"sha256:0db4b7601aae1d35b4a033282da476845aa19185c1e6964b25cf324b5e4ec3e6",
"sha256:fa5fa1622fa6dd5c030e9cad086fa19ef6a0cf6d7a2d12318e10cb49d6d68f34"
],
"version": "==0.13.0"
},
"py": {
"hashes": [
"sha256:64f65755aee5b381cea27766a3a147c3f15b9b6b9ac88676de66ba2ae36793fa",
"sha256:dc639b046a6e2cff5bbe40194ad65936d6ba360b52b3c3fe1d08a82dd50b5e53"
],
"version": "==1.8.0"
},
"pyparsing": {
"hashes": [
"sha256:4acadc9a2b96c19fe00932a38ca63e601180c39a189a696abce1eaab641447e1",
"sha256:61b5ed888beab19ddccab3478910e2076a6b5a0295dffc43021890e136edf764"
],
"version": "==2.4.4"
},
"pytest": {
"hashes": [
"sha256:27abc3fef618a01bebb1f0d6d303d2816a99aa87a5968ebc32fe971be91eb1e6",
"sha256:58cee9e09242937e136dbb3dab466116ba20d6b7828c7620f23947f37eb4dae4"
],
"index": "pypi",
"version": "==5.2.2"
},
"six": {
"hashes": [
"sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd",
"sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66"
],
"version": "==1.13.0"
},
"wcwidth": {
"hashes": [
"sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e",
"sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c"
],
"version": "==0.1.7"
},
"zipp": {
"hashes": [
"sha256:3718b1cbcd963c7d4c5511a8240812904164b7f381b647143a89d3b98f9bcd8e",
"sha256:f06903e9f1f43b12d371004b4ac7b06ab39a44adc747266928ae6debfa7b3335"
],
"version": "==0.6.0"
}
}
}

24
README.md

@ -1,6 +1,24 @@
SQL test
===
### Prerequisistes
```bash
$ python3 -m pip install pipenv --user
```
- Use virtualenv
```bash
$ PIPENV_VENV_IN_PROJECT=true pipenv shell
```
- Install dependencies
```bash
$ pipenv install --dev
```
### Usage
- Run up Postgresql server
@ -26,3 +44,9 @@ $ docker-compose exec db psql -U postgres test
```bash
$ docker-compose exec db psql -v ON_ERROR_STOP=1 -U postgres test -a -f "sql/schema.sql"
```
- Testing using database
```bash
$ docker-compose up dbtest
```

25
docker-compose.yml

@ -1,7 +1,17 @@
version: "3.3"
volumes:
dummy:
services:
db:
pipenv: &pipenv
image: "kennethreitz/pipenv"
working_dir: "/app"
volumes:
- ".:/app"
- "dummy:/app/.venv"
db: &db
container_name: "sql_test_db"
image: "mdillon/postgis:10"
volumes:
@ -10,3 +20,16 @@ services:
- "env/local/.env"
ports:
- "5438:5432"
testdb:
<<: *db
container_name: "testdb"
restart: "always"
env_file:
- "env/test/.env"
dbtest:
<<: *pipenv
command: ["bash", "-c", "pipenv install --dev --deploy --system && pytest -s"]
depends_on:
- testdb

6
env/test/.env

@ -0,0 +1,6 @@
POSTGRES_USER=postgres
POSTGRES_PASSWORD=password
POSTGRES_DB=test
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
# POSTGIS_MAJOR=2.3

0
test/__init__.py

72
test/dbtest.py

@ -0,0 +1,72 @@
import unittest
import functools
import psycopg2
import os
from typing import Any
def dbconnect(func):
@functools.wraps(func)
def inner(*args, **kwargs):
inner.__wrapped__ = func
params = {
"host": "testdb",
"port": 5432,
"dbname": "test",
"user": "postgres",
"password": "password",
}
print(f"Connecting for {params}")
# http://initd.org/psycopg/docs/usage.html#with-statement
conn = None
try:
with psycopg2.connect(**params) as conn:
func(*args, conn=conn, **kwargs)
finally:
if conn:
print(f"Close connection for {params}")
conn.close()
return inner
class DbTest(unittest.TestCase):
@dbconnect
def setUp(self, conn):
print("Invoking setUp")
print("Set up database schema")
path_to_schema = os.path.join(
os.path.dirname(__file__),
"..",
"sql",
"schema.sql"
)
with conn.cursor() as cur:
cur.execute("CREATE SCHEMA IF NOT EXISTS public;")
schema_sql = self.read_file(path_to_schema)
print(f"Loading {path_to_schema}")
cur.execute(schema_sql)
print(f"Loaded {path_to_schema}")
@dbconnect
def tearDown(self, conn):
print("Invoking tearDown")
print("Tore down database schema")
with conn.cursor() as cur:
print("Droping schema")
cur.execute("DROP SCHEMA IF EXISTS public CASCADE;")
print("Dropped schema")
def load_fixtures(self, conn: Any, *path_to_sqls: str) -> None:
for path_to_sql in path_to_sqls:
sql = self.read_file(path_to_sql)
with conn.cursor() as cur:
print(f"Executing {path_to_sql}")
cur.execute(sql)
print(f"Executed {path_to_sql}")
def read_file(self, path_to_file: str) -> str:
with open(path_to_file, "r") as f:
return f.read()

50
test/test_example.py

@ -0,0 +1,50 @@
from .dbtest import (
DbTest,
dbconnect
)
import os
from psycopg2.extras import RealDictCursor
PATH_TO_SQL_DIR = os.path.abspath(
os.path.join(
os.path.dirname(__file__),
"..",
"sql"
)
)
class TestExample(DbTest):
@dbconnect
def test_select_organizations(self, conn):
self.load_fixtures(
conn,
os.path.join(PATH_TO_SQL_DIR, "organizations.sql")
)
sql = """
SELECT * FROM organizations;
"""
with conn.cursor(cursor_factory=RealDictCursor) as cur:
cur.execute(sql)
organizations = cur.fetchall()
assert len(organizations) == 7
@dbconnect
def test_select_addresses(self, conn):
self.load_fixtures(
conn,
os.path.join(PATH_TO_SQL_DIR, "organizations.sql")
)
sql = """
SELECT * FROM addresses;
"""
with conn.cursor(cursor_factory=RealDictCursor) as cur:
cur.execute(sql)
addresses = cur.fetchall()
assert len(addresses) == 7
Loading…
Cancel
Save