Skip to content

Commit

Permalink
Make tests support treatments and profile collections
Browse files Browse the repository at this point in the history
  • Loading branch information
mddub committed Aug 19, 2016
1 parent 286ce0f commit f224607
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 28 deletions.
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
flask==0.10.1
pytest==2.6.1
python-dateutil==2.5.3
requests==2.3.0
simplejson==3.8.0
watchdog==0.8.3
Expand Down
31 changes: 22 additions & 9 deletions test/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,16 @@

app = Flask(__name__)

def _get_post_data(request):
return request.data or request.form.keys()[0]
def _get_post_json(request):
return json.loads(request.data or request.form.keys()[0])

@app.route('/api/v1/<coll>.json')
def get_collection(coll):
coll = _collection_from_test(coll, args.test_class) if args.test_class else _collection_from_cache(coll)
if coll is not None:
return coll
elements = _collection_from_test(coll, args.test_class) if args.test_class else _collection_from_cache(coll)
if coll == 'treatments':
return json.dumps(_filter_treatments(elements, request.args))
elif elements is not None:
return json.dumps(elements)
else:
raise NotFound

Expand All @@ -53,16 +55,27 @@ def _collection_from_test(coll, test_class_name):
# XXX this is very fragile, but for now makes iterating much faster
reload(test_screenshots)
if coll == 'entries':
return json.dumps(getattr(test_screenshots, test_class_name)().sgvs())
elif coll in COLLECTIONS:
return []
return getattr(test_screenshots, test_class_name)().sgvs()
elif coll == 'treatments':
return getattr(test_screenshots, test_class_name)().treatments()
elif coll == 'profile':
return getattr(test_screenshots, test_class_name)().profile()
else:
return None

def _filter_treatments(treatments, query):
# XXX hard-coding the queries performed by the JS
if query.get('find[eventType]') == 'Temp Basal':
return [t for t in treatments if 'duration' in t]
elif query.get('find[insulin][$exists]'):
return [t for t in treatments if 'insulin' in t]
else:
return treatments

@app.route('/set-<coll>', methods=['post'])
def set_collection(coll):
if coll in COLLECTIONS:
cache.set(coll, _get_post_data(request))
cache.set(coll, _get_post_json(request))
return ''
else:
raise NotFound
Expand Down
65 changes: 46 additions & 19 deletions test/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from datetime import datetime

import requests
from dateutil import parser
from dateutil.tz import tzlocal
from libpebble2.communication.transports.websocket import MessageTargetPhone
from libpebble2.communication.transports.websocket.protocol import AppConfigResponse
from libpebble2.communication.transports.websocket.protocol import AppConfigSetup
Expand All @@ -21,10 +23,7 @@
)
BASE_CONFIG = CONSTANTS['DEFAULT_CONFIG']

def set_sgvs(sgvs):
_post_mock_server('/set-sgv', sgvs)

def _post_mock_server(url, data):
def post_mock_server(url, data):
requests.post(MOCK_HOST + url, data=json.dumps(data))

def pebble_install_and_run(platforms):
Expand Down Expand Up @@ -126,6 +125,12 @@ def ensure_environment(cls):
def sgvs(self):
raise NotImplementedError

def treatments(self):
return []

def profile(self):
return []

def test_screenshot(self):
if not hasattr(self, 'config'):
self.config = {}
Expand All @@ -137,8 +142,16 @@ def test_screenshot(self):

self.ensure_environment()

# XXX this should all be run in a single process, e.g. with Tornado
self.test_sgvs = self.sgvs()
set_sgvs(self.test_sgvs)
post_mock_server('/set-sgv', self.test_sgvs)

self.test_treatments = self.treatments()
post_mock_server('/set-treatments', self.test_treatments)

self.test_profile = self.profile()
post_mock_server('/set-profile', self.test_profile)

set_config(dict(BASE_CONFIG, nightscout_url=MOCK_HOST, __CLEAR_CACHE__=True, **self.config), PLATFORMS)

fails = []
Expand Down Expand Up @@ -201,25 +214,32 @@ def write(self):
""".format(json.dumps(self.base_config)))

def add_test_result(self, test_instance, platform, passed):
details = """
<strong>{classname} [{platform}]</strong> {doc}
<code>{config}</code>
<code>{sgvs}</code>
""".format(
classname=test_instance.__class__.__name__,
platform=platform,
doc=test_instance.__class__.__doc__ or '',
config=json.dumps(test_instance.config),
sgvs=json.dumps(self.formatted_sgvs(test_instance.test_sgvs))
)
if test_instance.test_treatments:
details += "<code>{treatments}</code>".format(treatments=self.formatted_treatments(test_instance.test_treatments))
if test_instance.test_profile:
details += "<code>{profile}</code>".format(profile=test_instance.test_profile)
result = """
<tr>
<td><img src="{test_filename}" class="{klass}"></td>
<td><img src="{diff_filename}"></td>
<td>
<strong>{classname} [{platform}]</strong> {doc}
<code>{config}</code>
<code>{sgvs}</code>
</td>
<td>{details}</td>
</tr>
""".format(
test_filename=self.relative_path(test_instance.test_filename(platform)),
klass=('pass' if passed else 'fail'),
diff_filename=self.relative_path(test_instance.diff_filename(platform)),
classname=test_instance.__class__.__name__,
platform=platform,
doc=test_instance.__class__.__doc__ or '',
config=json.dumps(test_instance.config),
sgvs=json.dumps(self.printed_sgvs(test_instance.test_sgvs))
details=details,
)
if passed:
self.passes += result
Expand All @@ -230,21 +250,28 @@ def add_test_result(self, test_instance, platform, passed):
def relative_path(self, filename):
return os.path.relpath(filename, os.path.dirname(self.out_file))

def printed_sgvs(self, sgvs):
def formatted_sgvs(self, sgvs):
return [
s
if i == 0
else {
'sgv': s.get('sgv'),
'ago': self.format_ago(s['date'])
'ago': self.format_ago(datetime.fromtimestamp(s['date'] / 1000).replace(tzinfo=tzlocal())),
}
for i, s in enumerate(sgvs)
]

def formatted_treatments(self, treatments):
out = []
for t in [_t.copy() for _t in treatments]:
t['ago'] = self.format_ago(parser.parse(t['created_at']))
del t['created_at']
out.append(t)
return out

@staticmethod
def format_ago(time):
now = int(datetime.now().strftime('%s'))
minutes = int(round((now - time / 1000) / 60))
minutes = int((datetime.now().replace(tzinfo=tzlocal()) - time).total_seconds() / 60)
if minutes < 60:
return '{}m'.format(minutes)
else:
Expand Down

0 comments on commit f224607

Please sign in to comment.