Skip to content

Commit 18ee6d5

Browse files
committed
Add proper tests
This commit adds pytest, fixes up the repo structure to support pytest, and adds tests for both configs. Tests use pyfakefs and pytest fixtures to "magically" make ocflib functions refer to testing versions rather than real configs in /etc/ocf.
1 parent 3208974 commit 18ee6d5

11 files changed

+123
-57
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/.tox
22
/venv
3+
__pycache__/

.pre-commit-config.yaml

-7
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,3 @@ repos:
5959
hooks:
6060
- id: remove-tabs
6161
- id: remove-crlf
62-
- repo: local
63-
hooks:
64-
- id: validate-schemas
65-
name: Validate JSON schema on configs
66-
entry: python validate.py
67-
language: python
68-
additional_dependencies: [jsonschema, pyyaml]

Makefile

+4-9
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
11
BIN := venv/bin
22
PYTHON := $(BIN)/python
33

4-
.PHONY: .validate
5-
validate: venv
6-
$(PYTHON) validate.py
7-
84
venv: requirements.txt
9-
python ./vendor/venv-update venv= venv -ppython3 install= -r requirements.txt
5+
python ./vendor/venv-update venv= venv -ppython3 install= -r requirements.txt -r requirements-dev.txt
106

117
.PHONY: install-hooks
128
install-hooks: venv
139
$(BIN)/pre-commit install -f --install-hooks
1410

15-
test: lint validate
16-
17-
.PHONY: lint
18-
lint: venv
11+
.PHONY: test
12+
test: venv
13+
$(BIN)/py.test -v tests/
1914
$(BIN)/pre-commit run --all-files
2015

2116
.PHONY: clean

requirements-dev-minimal.txt

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
jsonschema
2+
ocflib
3+
pre-commit
4+
pyfakefs
5+
PyYAML
6+
requirements-tools

requirements-dev.txt

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
aspy.yaml==1.1.2
2+
atomicwrites==1.3.0
3+
attrs==18.2.0
4+
cached-property==1.5.1
5+
certifi==2018.11.29
6+
cfgv==1.4.0
7+
chardet==3.0.4
8+
cracklib==2.9.3
9+
dnspython==1.16.0
10+
identify==1.2.2
11+
idna==2.8
12+
importlib-metadata==0.8
13+
importlib-resources==1.0.2
14+
Jinja2==2.10
15+
jsonschema==2.6.0
16+
ldap3==2.5.2
17+
MarkupSafe==1.1.0
18+
more-itertools==6.0.0
19+
nodeenv==1.3.3
20+
ocflib==2019.2.20.14.19
21+
pathlib2==2.3.3
22+
pexpect==4.6.0
23+
pluggy==0.8.1
24+
ply==3.11
25+
pre-commit==1.14.4
26+
ptyprocess==0.6.0
27+
py==1.7.0
28+
pyasn1==0.4.5
29+
pycryptodome==3.7.3
30+
pycryptodomex==3.7.3
31+
pyfakefs==3.5.7
32+
PyMySQL==0.9.3
33+
pysmi==0.3.3
34+
pysnmp==4.4.9
35+
pytest==4.3.0
36+
python-dateutil==2.8.0
37+
PyYAML==3.13
38+
redis==3.2.0
39+
requests==2.21.0
40+
requirements-tools==1.2.1
41+
setuptools==40.8.0
42+
six==1.12.0
43+
SQLAlchemy==1.2.18
44+
toml==0.10.0
45+
urllib3==1.24.1
46+
virtualenv==16.4.0
47+
zipp==0.3.3

requirements-minimal.txt

Whitespace-only changes.

requirements.txt

-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +0,0 @@
1-
jsonschema==2.6.0
2-
pre-commit==1.14.0
3-
PyYAML==3.13

tests/conftest.py

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import pytest
2+
3+
4+
@pytest.fixture(autouse=True)
5+
def etc(fs):
6+
"""Use pyfakefs in every test case"""
7+
fs.add_real_directory('configs', target_path='/etc/ocf')

tests/hours_test.py

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from datetime import date
2+
from datetime import datetime
3+
from datetime import time
4+
from datetime import timedelta
5+
6+
from ocflib.lab.hours import read_hours_listing
7+
8+
9+
def test_hours_listing():
10+
hours_listing = read_hours_listing()
11+
12+
today = date.today()
13+
14+
# Make sure that calling functions doesn't cause exceptions, now or in the
15+
# future
16+
for i in range(100):
17+
hours_listing.hours_on_date(today + timedelta(days=i))
18+
hours_listing.hours_on_date(today - timedelta(days=i + 1))
19+
20+
# Try every 10 minute interval on each day
21+
for j in range(timedelta(days=1) // timedelta(minutes=10)):
22+
fake_now = datetime.combine(
23+
today + timedelta(days=i), time(),
24+
) + j * timedelta(minutes=10)
25+
26+
hours_listing.is_open(when=fake_now)
27+
hours_listing.time_to_open(when=fake_now)
28+
hours_listing.time_to_close(when=fake_now)

tests/validate_test.py

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import json
2+
import os
3+
4+
import jsonschema
5+
import pytest
6+
import yaml
7+
8+
# Disable pyfakefs
9+
@pytest.fixture
10+
def etc():
11+
pass
12+
13+
14+
def test_validate():
15+
configs = yaml.safe_load(open('configs/validate.yaml')).items()
16+
17+
for shortname, metadata in configs:
18+
schema_filename = os.path.join('schemas', metadata['schema'])
19+
config_filename = os.path.join('configs', shortname + '.yaml')
20+
21+
# PyYAML reads YAML date objects as Python date objects, which confuses
22+
# jsonschema. To get around this, we convert the object to and from
23+
# JSON, using the str function to convert the date objects to strings.
24+
config = json.loads(
25+
json.dumps(yaml.safe_load(open(config_filename)), default=str),
26+
)
27+
28+
schema = json.load(open(schema_filename))
29+
30+
jsonschema.validate(config, schema)

validate.py

-38
This file was deleted.

0 commit comments

Comments
 (0)