You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

215 lines
7.1 KiB

  1. import nilmdb
  2. from nose.tools import *
  3. from nose.tools import assert_raises
  4. import distutils.version
  5. import simplejson as json
  6. import itertools
  7. import os
  8. import shutil
  9. import sys
  10. import cherrypy
  11. import threading
  12. import urllib2
  13. from urllib2 import urlopen, HTTPError
  14. import Queue
  15. import cStringIO
  16. import time
  17. testdb = "tests/testdb"
  18. #@atexit.register
  19. #def cleanup():
  20. # os.unlink(testdb)
  21. from testutil.helpers import *
  22. class Test00Nilmdb(object): # named 00 so it runs first
  23. def test_NilmDB(self):
  24. recursive_unlink(testdb)
  25. with assert_raises(IOError):
  26. nilmdb.NilmDB("/nonexistant-db/foo")
  27. db = nilmdb.NilmDB(testdb)
  28. db.close()
  29. db = nilmdb.NilmDB(testdb, sync=False)
  30. db.close()
  31. # test timer, just to get coverage
  32. capture = cStringIO.StringIO()
  33. old = sys.stdout
  34. sys.stdout = capture
  35. with nilmdb.utils.Timer("test"):
  36. time.sleep(0.01)
  37. sys.stdout = old
  38. in_("test: ", capture.getvalue())
  39. def test_stream(self):
  40. db = nilmdb.NilmDB(testdb, sync=False)
  41. eq_(db.stream_list(), [])
  42. # Bad path
  43. with assert_raises(ValueError):
  44. db.stream_create("foo/bar/baz", "PrepData")
  45. with assert_raises(ValueError):
  46. db.stream_create("/foo", "PrepData")
  47. # Bad layout type
  48. with assert_raises(ValueError):
  49. db.stream_create("/newton/prep", "NoSuchLayout")
  50. db.stream_create("/newton/prep", "PrepData")
  51. db.stream_create("/newton/raw", "RawData")
  52. db.stream_create("/newton/zzz/rawnotch", "RawNotchedData")
  53. # Verify we got 3 streams
  54. eq_(db.stream_list(), [ ["/newton/prep", "PrepData"],
  55. ["/newton/raw", "RawData"],
  56. ["/newton/zzz/rawnotch", "RawNotchedData"]
  57. ])
  58. # Match just one type or one path
  59. eq_(db.stream_list(layout="RawData"), [ ["/newton/raw", "RawData"] ])
  60. eq_(db.stream_list(path="/newton/raw"), [ ["/newton/raw", "RawData"] ])
  61. # Verify that columns were made right (pytables specific)
  62. if "h5file" in db.data.__dict__:
  63. h5file = db.data.h5file
  64. eq_(len(h5file.getNode("/newton/prep").cols), 9)
  65. eq_(len(h5file.getNode("/newton/raw").cols), 7)
  66. eq_(len(h5file.getNode("/newton/zzz/rawnotch").cols), 10)
  67. assert(not h5file.getNode("/newton/prep").colindexed["timestamp"])
  68. assert(not h5file.getNode("/newton/prep").colindexed["c1"])
  69. # Set / get metadata
  70. eq_(db.stream_get_metadata("/newton/prep"), {})
  71. eq_(db.stream_get_metadata("/newton/raw"), {})
  72. meta1 = { "description": "The Data",
  73. "v_scale": "1.234" }
  74. meta2 = { "description": "The Data" }
  75. meta3 = { "v_scale": "1.234" }
  76. db.stream_set_metadata("/newton/prep", meta1)
  77. db.stream_update_metadata("/newton/prep", {})
  78. db.stream_update_metadata("/newton/raw", meta2)
  79. db.stream_update_metadata("/newton/raw", meta3)
  80. eq_(db.stream_get_metadata("/newton/prep"), meta1)
  81. eq_(db.stream_get_metadata("/newton/raw"), meta1)
  82. # fill in some test coverage for start >= end
  83. with assert_raises(nilmdb.server.NilmDBError):
  84. db.stream_remove("/newton/prep", 0, 0)
  85. with assert_raises(nilmdb.server.NilmDBError):
  86. db.stream_remove("/newton/prep", 1, 0)
  87. db.stream_remove("/newton/prep", 0, 1)
  88. db.close()
  89. class TestBlockingServer(object):
  90. def setUp(self):
  91. self.db = nilmdb.utils.serializer_proxy(nilmdb.NilmDB,
  92. testdb, sync=False)
  93. def tearDown(self):
  94. self.db.close()
  95. def test_blocking_server(self):
  96. # Start web app on a custom port
  97. self.server = nilmdb.Server(self.db, host = "127.0.0.1",
  98. port = 12380, stoppable = True)
  99. # Run it
  100. event = threading.Event()
  101. def run_server():
  102. self.server.start(blocking = True, event = event)
  103. thread = threading.Thread(target = run_server)
  104. thread.start()
  105. if not event.wait(timeout = 10):
  106. raise AssertionError("server didn't start in 10 seconds")
  107. # Send request to exit.
  108. req = urlopen("http://127.0.0.1:12380/exit/", timeout = 1)
  109. # Wait for it
  110. thread.join()
  111. def geturl(path):
  112. req = urlopen("http://127.0.0.1:12380" + path, timeout = 10)
  113. return req.read()
  114. def getjson(path):
  115. return json.loads(geturl(path))
  116. class TestServer(object):
  117. def setUp(self):
  118. # Start web app on a custom port
  119. self.db = nilmdb.utils.serializer_proxy(
  120. nilmdb.NilmDB, testdb, sync=False)
  121. self.server = nilmdb.Server(self.db, host = "127.0.0.1",
  122. port = 12380, stoppable = False)
  123. self.server.start(blocking = False)
  124. def tearDown(self):
  125. # Close web app
  126. self.server.stop()
  127. self.db.close()
  128. def test_server(self):
  129. # Make sure we can't force an exit, and test other 404 errors
  130. for url in [ "/exit", "/", "/favicon.ico" ]:
  131. with assert_raises(HTTPError) as e:
  132. geturl(url)
  133. eq_(e.exception.code, 404)
  134. # Check version
  135. eq_(distutils.version.LooseVersion(getjson("/version")),
  136. distutils.version.LooseVersion(nilmdb.__version__))
  137. def test_stream_list(self):
  138. # Known streams that got populated by an earlier test (test_nilmdb)
  139. streams = getjson("/stream/list")
  140. eq_(streams, [
  141. ['/newton/prep', 'PrepData'],
  142. ['/newton/raw', 'RawData'],
  143. ['/newton/zzz/rawnotch', 'RawNotchedData'],
  144. ])
  145. streams = getjson("/stream/list?layout=RawData")
  146. eq_(streams, [['/newton/raw', 'RawData']])
  147. streams = getjson("/stream/list?layout=NoSuchLayout")
  148. eq_(streams, [])
  149. def test_stream_metadata(self):
  150. with assert_raises(HTTPError) as e:
  151. getjson("/stream/get_metadata?path=foo")
  152. eq_(e.exception.code, 404)
  153. data = getjson("/stream/get_metadata?path=/newton/prep")
  154. eq_(data, {'description': 'The Data', 'v_scale': '1.234'})
  155. data = getjson("/stream/get_metadata?path=/newton/prep"
  156. "&key=v_scale")
  157. eq_(data, {'v_scale': '1.234'})
  158. data = getjson("/stream/get_metadata?path=/newton/prep"
  159. "&key=v_scale&key=description")
  160. eq_(data, {'description': 'The Data', 'v_scale': '1.234'})
  161. data = getjson("/stream/get_metadata?path=/newton/prep"
  162. "&key=v_scale&key=foo")
  163. eq_(data, {'foo': None, 'v_scale': '1.234'})
  164. data = getjson("/stream/get_metadata?path=/newton/prep"
  165. "&key=foo")
  166. eq_(data, {'foo': None})
  167. def test_insert(self):
  168. # GET instead of POST (no body)
  169. # (actual POST test is done by client code)
  170. with assert_raises(HTTPError) as e:
  171. getjson("/stream/insert?path=/newton/prep&start=0&end=0")
  172. eq_(e.exception.code, 400)