-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from yuvipanda/feat/basic-unit-tests
Add unit tests + CI + code coverage
- Loading branch information
Showing
6 changed files
with
200 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
version: 2 | ||
jobs: | ||
build: | ||
docker: | ||
- image: circleci/python:3.5 | ||
working_directory: ~/repo | ||
|
||
steps: | ||
- checkout | ||
|
||
- restore_cache: | ||
keys: | ||
- v1-dependencies-{{ checksum "dev-requirements.txt" }}-{{ checksum "setup.py" }} | ||
# fallback to using the latest cache if no exact match is found | ||
- v1-dependencies- | ||
|
||
- run: | ||
name: install dependencies | ||
command: | | ||
python3 -m venv venv | ||
. venv/bin/activate | ||
pip install -r dev-requirements.txt | ||
pip install -e . | ||
- save_cache: | ||
paths: | ||
- ./venv | ||
key: v1-dependencies-{{ checksum "dev-requirements.txt" }}-{{ checksum "setup.py" }} | ||
|
||
- run: | ||
name: run tests | ||
command: | | ||
. venv/bin/activate | ||
# Have CircleCI display pretty test result output | ||
mkdir test-reports | ||
py.test --cov=jupyter_telemetry --junitxml=test-reports/junit.xml tests/ | ||
# Upload coverage info to codecov | ||
codecov | ||
- store_test_results: | ||
path: test-reports | ||
- store_artifacts: | ||
path: test-reports |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,6 @@ | ||
# Telemetry | ||
|
||
[![circleci](https://circleci.com/gh/jupyter/telemetry?style=shield)][https://circleci.com/gh/jupyter/telemetry] | ||
[![codecov](https://codecov.io/gh/jupyter/telemetry/branch/master/graph/badge.svg)](https://codecov.io/gh/jupyter/telemetry) | ||
|
||
Telemetry for Jupyter Applications and extensions. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pytest | ||
pytest-cov | ||
codecov |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
from contextlib import redirect_stderr | ||
import json | ||
import jsonschema | ||
import logging | ||
import pytest | ||
import io | ||
|
||
from jupyter_telemetry.eventlog import EventLog | ||
|
||
|
||
def test_register_invalid_schema(): | ||
""" | ||
Invalid JSON Schemas should fail registration | ||
""" | ||
el = EventLog() | ||
with pytest.raises(jsonschema.SchemaError): | ||
el.register_schema({ | ||
# Totally invalid | ||
'properties': True | ||
}) | ||
|
||
def test_missing_required_properties(): | ||
""" | ||
id and $version are required properties in our schemas. | ||
They aren't required by JSON Schema itself | ||
""" | ||
el = EventLog() | ||
with pytest.raises(ValueError): | ||
el.register_schema({ | ||
'properties': {} | ||
}) | ||
|
||
with pytest.raises(ValueError): | ||
el.register_schema({ | ||
'$id': 'something', | ||
'$version': 1, # This should been 'version' | ||
}) | ||
|
||
def test_reserved_properties(): | ||
""" | ||
User schemas can't have properties starting with __ | ||
These are reserved | ||
""" | ||
el = EventLog() | ||
with pytest.raises(ValueError): | ||
el.register_schema({ | ||
'$id': 'test/test', | ||
'version': 1, | ||
'properties': { | ||
'__fail__': { | ||
'type': 'string' | ||
}, | ||
}, | ||
}) | ||
|
||
def test_record_event(): | ||
""" | ||
Simple test for emitting valid events | ||
""" | ||
schema = { | ||
'$id': 'test/test', | ||
'version': 1, | ||
'properties': { | ||
'something': { | ||
'type': 'string' | ||
}, | ||
}, | ||
} | ||
|
||
output = io.StringIO() | ||
handler = logging.StreamHandler(output) | ||
el = EventLog(handlers_maker=lambda el: [handler]) | ||
el.register_schema(schema) | ||
el.allowed_schemas = ['test/test'] | ||
|
||
el.record_event('test/test', 1, { | ||
'something': 'blah', | ||
}) | ||
handler.flush() | ||
|
||
event_capsule = json.loads(output.getvalue()) | ||
|
||
assert '__timestamp__' in event_capsule | ||
# Remove timestamp from capsule when checking equality, since it is gonna vary | ||
del event_capsule['__timestamp__'] | ||
assert event_capsule == { | ||
'__schema__': 'test/test', | ||
'__version__': 1, | ||
'something': 'blah' | ||
} | ||
|
||
|
||
def test_allowed_schemas(): | ||
""" | ||
Events should be emitted only if their schemas are allowed | ||
""" | ||
schema = { | ||
'$id': 'test/test', | ||
'version': 1, | ||
'properties': { | ||
'something': { | ||
'type': 'string' | ||
}, | ||
}, | ||
} | ||
|
||
output = io.StringIO() | ||
handler = logging.StreamHandler(output) | ||
el = EventLog(handlers_maker=lambda el: [handler]) | ||
# Just register schema, but do not mark it as allowed | ||
el.register_schema(schema) | ||
|
||
el.record_event('test/test', 1, { | ||
'something': 'blah', | ||
}) | ||
handler.flush() | ||
|
||
|
||
assert output.getvalue() == '' | ||
|
||
def test_record_event_badschema(): | ||
""" | ||
Fail fast when an event doesn't conform to its schema | ||
""" | ||
schema = { | ||
'$id': 'test/test', | ||
'version': 1, | ||
'properties': { | ||
'something': { | ||
'type': 'string' | ||
}, | ||
'status': { | ||
'enum': ['success', 'failure'] | ||
} | ||
} | ||
} | ||
|
||
el = EventLog(handlers_maker=lambda el: [logging.NullHandler()]) | ||
el.register_schema(schema) | ||
el.allowed_schemas = ['test/test'] | ||
|
||
with pytest.raises(jsonschema.ValidationError): | ||
el.record_event('test/test', 1, { | ||
'something': 'blah', | ||
'status': 'not-in-enum' | ||
}) |