Browse Source

client: Add context manager functionality, test closing

tags/nilmdb-1.1
Jim Paris 11 years ago
parent
commit
2045e89f24
3 changed files with 41 additions and 7 deletions
  1. +8
    -0
      nilmdb/client/client.py
  2. +2
    -2
      nilmdb/client/httpclient.py
  3. +31
    -5
      tests/test_client.py

+ 8
- 0
nilmdb/client/client.py View File

@@ -19,11 +19,19 @@ class Client(object):
def __init__(self, url): def __init__(self, url):
self.http = nilmdb.client.httpclient.HTTPClient(url) self.http = nilmdb.client.httpclient.HTTPClient(url)


# __enter__/__exit__ allow this class to be a context manager
def __enter__(self):
return self

def __exit__(self, exc_type, exc_value, traceback):
self.close()

def _json_param(self, data): def _json_param(self, data):
"""Return compact json-encoded version of parameter""" """Return compact json-encoded version of parameter"""
return json.dumps(data, separators=(',',':')) return json.dumps(data, separators=(',',':'))


def close(self): def close(self):
"""Close the connection; safe to call multiple times"""
self.http.close() self.http.close()


def geturl(self): def geturl(self):


+ 2
- 2
nilmdb/client/httpclient.py View File

@@ -80,11 +80,11 @@ class HTTPClient(object):
self._status = int(data.split(" ")[1]) self._status = int(data.split(" ")[1])
self._headers += data self._headers += data
self.curl.setopt(pycurl.HEADERFUNCTION, header_callback) self.curl.setopt(pycurl.HEADERFUNCTION, header_callback)
def func(callback):
def perform(callback):
self.curl.setopt(pycurl.WRITEFUNCTION, callback) self.curl.setopt(pycurl.WRITEFUNCTION, callback)
self.curl.perform() self.curl.perform()
try: try:
with nilmdb.utils.Iteratorizer(func, curl_hack = True) as it:
with nilmdb.utils.Iteratorizer(perform, curl_hack = True) as it:
for i in it: for i in it:
if self._status == 200: if self._status == 200:
# If we had a 200 response, yield the data to caller. # If we had a 200 response, yield the data to caller.


+ 31
- 5
tests/test_client.py View File

@@ -18,6 +18,7 @@ import simplejson as json
import unittest import unittest
import warnings import warnings
import resource import resource
import time


from testutil.helpers import * from testutil.helpers import *


@@ -101,8 +102,10 @@ class TestClient(object):
["/newton/zzz/rawnotch", "RawNotchedData"] ["/newton/zzz/rawnotch", "RawNotchedData"]
]) ])
# Match just one type or one path # Match just one type or one path
eq_(client.stream_list(layout="RawData"), [ ["/newton/raw", "RawData"] ])
eq_(client.stream_list(path="/newton/raw"), [ ["/newton/raw", "RawData"] ])
eq_(client.stream_list(layout="RawData"),
[ ["/newton/raw", "RawData"] ])
eq_(client.stream_list(path="/newton/raw"),
[ ["/newton/raw", "RawData"] ])


# Try messing with resource limits to trigger errors and get # Try messing with resource limits to trigger errors and get
# more coverage. Here, make it so we can only create files 1 # more coverage. Here, make it so we can only create files 1
@@ -131,9 +134,10 @@ class TestClient(object):
client.stream_update_metadata("/newton/raw", meta3) client.stream_update_metadata("/newton/raw", meta3)
eq_(client.stream_get_metadata("/newton/prep"), meta1) eq_(client.stream_get_metadata("/newton/prep"), meta1)
eq_(client.stream_get_metadata("/newton/raw"), meta1) eq_(client.stream_get_metadata("/newton/raw"), meta1)
eq_(client.stream_get_metadata("/newton/raw", [ "description" ] ), meta2)
eq_(client.stream_get_metadata("/newton/raw", [ "description",
"v_scale" ] ), meta1)
eq_(client.stream_get_metadata("/newton/raw",
[ "description" ] ), meta2)
eq_(client.stream_get_metadata("/newton/raw",
[ "description", "v_scale" ] ), meta1)


# missing key # missing key
eq_(client.stream_get_metadata("/newton/raw", "descr"), eq_(client.stream_get_metadata("/newton/raw", "descr"),
@@ -356,3 +360,25 @@ class TestClient(object):
eq_(client.stream_get_metadata(raw[0]), meta1) eq_(client.stream_get_metadata(raw[0]), meta1)
eq_(client.stream_get_metadata(raw[0], [ "alpha" ]), meta2) eq_(client.stream_get_metadata(raw[0], [ "alpha" ]), meta2)
eq_(client.stream_get_metadata(raw[0], [ "alpha", "β" ]), meta1) eq_(client.stream_get_metadata(raw[0], [ "alpha", "β" ]), meta1)

def test_client_9_closing(self):
# Make sure we actually close sockets correctly. New
# connections will block for a while if they're not, since the
# server will stop accepting new connections.
for test in [1, 2]:
start = time.time()
for i in range(50):
if time.time() - start > 15:
raise AssertionError("Connections seem to be blocking... "
"probably not closing properly.")
if test == 1:
# explicit close
client = nilmdb.Client(url = "http://localhost:12380/")
with assert_raises(ClientError) as e:
client.stream_remove("/newton/prep", 123, 120)
client.close() # remove this to see the failure
elif test == 2:
# use the context manager
with nilmdb.Client(url = "http://localhost:12380/") as c:
with assert_raises(ClientError) as e:
c.stream_remove("/newton/prep", 123, 120)

Loading…
Cancel
Save