Skip to content

Commit f589b37

Browse files
authored
Merge pull request #182 from BCDA-APS/177-test-database
database for unit tests, fixes#177
2 parents 046fbb2 + a08f8e7 commit f589b37

File tree

5 files changed

+192
-12
lines changed

5 files changed

+192
-12
lines changed

apstools/plans.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def addDeviceDataAsStream(devices, label):
7373
7474
"""
7575
yield from bps.create(name=label)
76-
if isinstance(devices, Device): # just in case...
76+
if not isinstance(devices, list): # just in case...
7777
devices = [devices]
7878
for d in devices:
7979
yield from bps.read(d)

apstools/utils.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,28 @@ def json_export(headers, filename, zipfilename=None):
816816
def json_import(filename, zipfilename=None):
817817
"""
818818
read the file exported by :meth:`~json_export()`
819+
820+
RETURNS
821+
822+
datasets : list of documents
823+
list of
824+
`documents <https://blueskyproject.io/bluesky/documents.html/>`_,
825+
such as returned by
826+
`[list(h.documents()) for h in db]`
827+
828+
See:
829+
https://blueskyproject.io/databroker/generated/databroker.Header.documents.html
830+
831+
EXAMPLE
832+
833+
Insert the datasets into the databroker ``db``::
834+
835+
def insert_docs(db, datasets):
836+
for i, h in enumerate(datasets):
837+
print(f"{i+1}/{len(datasets)} : {len(h)} documents")
838+
for k, doc in h:
839+
db.insert(k, doc)
840+
819841
"""
820842
if zipfilename is None:
821843
with open(filename, "r") as fp:

tests/bluesky_data.zip

57.3 KB
Binary file not shown.

tests/test_export_json.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,28 @@
2020
from apstools.utils import json_export, json_import
2121

2222

23+
TEST_JSON_FILE = "data.json"
24+
TEST_ZIP_FILE = os.path.join(_test_path, "bluesky_data.zip")
25+
26+
2327
def get_db():
24-
from databroker import Broker
25-
try:
26-
db = Broker.named("mongodb_config")
27-
except FileNotFoundError:
28-
return
28+
from databroker import Broker, temp_config
29+
conf = temp_config()
30+
conf["metadatastore"]["config"]["timezone"] = "US/Central"
31+
db = Broker.from_config(conf)
32+
datasets = json_import(TEST_JSON_FILE, TEST_ZIP_FILE)
33+
insert_docs(db, datasets)
2934
return db
3035

3136

37+
def insert_docs(db, datasets, verbose=False):
38+
for i, h in enumerate(datasets):
39+
if verbose:
40+
print(f"{i+1}/{len(datasets)} : {len(h)} documents")
41+
for k, doc in h:
42+
db.insert(k, doc)
43+
44+
3245
class Test_JsonExport(unittest.TestCase):
3346

3447
def setUp(self):
@@ -40,9 +53,6 @@ def tearDown(self):
4053

4154
def test_export_import(self):
4255
db = get_db()
43-
if db is None:
44-
self.assertTrue(True, "skipping test: no databroker")
45-
return
4656
headers = db(plan_name="count")
4757
headers = list(headers)[0:1]
4858

@@ -66,9 +76,6 @@ def test_export_import(self):
6676

6777
def test_export_import_zip(self):
6878
db = get_db()
69-
if db is None:
70-
self.assertTrue(True, "skipping test: no databroker")
71-
return
7279
headers = db(plan_name="count")
7380
headers = list(headers)[0:1]
7481

tests/test_plans.py

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
2+
"""
3+
simple unit tests for this package
4+
"""
5+
6+
from io import StringIO
7+
import os
8+
import sys
9+
import unittest
10+
11+
_test_path = os.path.dirname(__file__)
12+
_path = os.path.join(_test_path, '..')
13+
if _path not in sys.path:
14+
sys.path.insert(0, _path)
15+
16+
from apstools import plans as APS_plans
17+
# from apstools import utils as APS_utils
18+
from bluesky.simulators import summarize_plan
19+
import ophyd.sim
20+
21+
class Capture_stdout(list): # lgtm [py/missing-equals]
22+
'''
23+
capture all printed output (to stdout) into list
24+
25+
# http://stackoverflow.com/questions/16571150/how-to-capture-stdout-output-from-a-python-function-call
26+
'''
27+
def __enter__(self):
28+
sys.stdout.flush()
29+
self._stdout = sys.stdout
30+
sys.stdout = self._stringio = StringIO()
31+
return self
32+
33+
def __exit__(self, *args):
34+
self.extend(self._stringio.getvalue().splitlines())
35+
del self._stringio # free up some memory
36+
sys.stdout = self._stdout
37+
38+
39+
class Test_Plans(unittest.TestCase):
40+
41+
def setUp(self):
42+
pass
43+
44+
def tearDown(self):
45+
pass
46+
47+
def test_addDeviceDataAsStream(self):
48+
with Capture_stdout() as received:
49+
summarize_plan(
50+
APS_plans.addDeviceDataAsStream(
51+
ophyd.sim.motor1,
52+
"test-device"))
53+
54+
expected = [" Read ['motor1']"]
55+
self.assertEqual(str(received), str(expected))
56+
57+
with Capture_stdout() as received:
58+
summarize_plan(
59+
APS_plans.addDeviceDataAsStream(
60+
[ophyd.sim.motor2, ophyd.sim.motor3],
61+
"test-device-list"))
62+
63+
expected = [
64+
" Read ['motor2']", # TODO: <-- Why?
65+
" Read ['motor2', 'motor3']",
66+
]
67+
self.assertEqual(str(received), str(expected))
68+
69+
def test_run_command_file(self):
70+
filename = os.path.join(_test_path, "actions.txt")
71+
with Capture_stdout() as received:
72+
summarize_plan(
73+
APS_plans.run_command_file(filename))
74+
75+
# print(f"|{received}|")
76+
expected = [
77+
'Command file: /home/mintadmin/Documents/eclipse/apstools/tests/actions.txt',
78+
'====== ============ ========================',
79+
'line # action parameters ',
80+
'====== ============ ========================',
81+
'5 sample_slits 0, 0, 0.4, 1.2 ',
82+
'7 preusaxstune ',
83+
'10 FlyScan 0, 0, 0, blank ',
84+
'11 FlyScan 5, 2, 0, empty container',
85+
'12 SAXS 0, 0, 0, blank ',
86+
'====== ============ ========================',
87+
'',
88+
'file line 5: sample_slits 0 0 0.4 1.2',
89+
'no handling for line 5: sample_slits 0 0 0.4 1.2',
90+
'file line 7: preusaxstune',
91+
'no handling for line 7: preusaxstune',
92+
'file line 10: FlyScan 0 0 0 blank',
93+
'no handling for line 10: FlyScan 0 0 0 blank',
94+
'file line 11: FlyScan 5 2 0 "empty container"',
95+
'no handling for line 11: FlyScan 5 2 0 "empty container"',
96+
'file line 12: SAXS 0 0 0 blank',
97+
'no handling for line 12: SAXS 0 0 0 blank',
98+
]
99+
self.assertEqual(str(received), str(expected))
100+
101+
filename = os.path.join(_test_path, "actions.xlsx")
102+
with Capture_stdout() as received:
103+
summarize_plan(
104+
APS_plans.run_command_file(filename))
105+
106+
# print(f"|{received}|")
107+
expected = [
108+
'Command file: /home/mintadmin/Documents/eclipse/apstools/tests/actions.xlsx',
109+
'====== ============ =============================',
110+
'line # action parameters ',
111+
'====== ============ =============================',
112+
'1 mono_shutter open ',
113+
'2 USAXSscan 45.07, 98.3, 0.0, Water Blank',
114+
'3 saxsExp 45.07, 98.3, 0.0, Water Blank',
115+
'4 waxwsExp 45.07, 98.3, 0.0, Water Blank',
116+
'5 USAXSscan 12, 12.0, 1.2, plastic ',
117+
'6 USAXSscan 12, 37.0, 0.1, Al foil ',
118+
'7 mono_shutter close ',
119+
'====== ============ =============================',
120+
'',
121+
"file line 1: ['mono_shutter', 'open', None, None, None]",
122+
"no handling for line 1: ['mono_shutter', 'open', None, None, None]",
123+
"file line 2: ['USAXSscan', 45.07, 98.3, 0.0, 'Water Blank']",
124+
"no handling for line 2: ['USAXSscan', 45.07, 98.3, 0.0, 'Water Blank']",
125+
"file line 3: ['saxsExp', 45.07, 98.3, 0.0, 'Water Blank']",
126+
"no handling for line 3: ['saxsExp', 45.07, 98.3, 0.0, 'Water Blank']",
127+
"file line 4: ['waxwsExp', 45.07, 98.3, 0.0, 'Water Blank']",
128+
"no handling for line 4: ['waxwsExp', 45.07, 98.3, 0.0, 'Water Blank']",
129+
"file line 5: ['USAXSscan', 12, 12.0, 1.2, 'plastic']",
130+
"no handling for line 5: ['USAXSscan', 12, 12.0, 1.2, 'plastic']",
131+
"file line 6: ['USAXSscan', 12, 37.0, 0.1, 'Al foil']",
132+
"no handling for line 6: ['USAXSscan', 12, 37.0, 0.1, 'Al foil']",
133+
"file line 7: ['mono_shutter', 'close', None, None, None]",
134+
"no handling for line 7: ['mono_shutter', 'close', None, None, None]"
135+
]
136+
self.assertEqual(str(received), str(expected))
137+
138+
139+
def suite(*args, **kw):
140+
test_list = [
141+
Test_Plans,
142+
]
143+
test_suite = unittest.TestSuite()
144+
for test_case in test_list:
145+
test_suite.addTest(unittest.makeSuite(test_case))
146+
return test_suite
147+
148+
149+
if __name__ == "__main__":
150+
runner=unittest.TextTestRunner()
151+
runner.run(suite())

0 commit comments

Comments
 (0)