Compare commits
7 Commits
nilmdb-1.2
...
nilmdb-1.2
Author | SHA1 | Date | |
---|---|---|---|
19d27c31bc | |||
28310fe886 | |||
1ccc2bce7e | |||
00237e30b2 | |||
521ff88f7c | |||
64897a1dd1 | |||
41ce8480bb |
@@ -52,12 +52,14 @@ class Client(object):
|
|||||||
as a dictionary."""
|
as a dictionary."""
|
||||||
return self.http.get("dbinfo")
|
return self.http.get("dbinfo")
|
||||||
|
|
||||||
def stream_list(self, path = None, layout = None):
|
def stream_list(self, path = None, layout = None, extent = False):
|
||||||
params = {}
|
params = {}
|
||||||
if path is not None:
|
if path is not None:
|
||||||
params["path"] = path
|
params["path"] = path
|
||||||
if layout is not None:
|
if layout is not None:
|
||||||
params["layout"] = layout
|
params["layout"] = layout
|
||||||
|
if extent:
|
||||||
|
params["extent"] = 1
|
||||||
return self.http.get("stream/list", params)
|
return self.http.get("stream/list", params)
|
||||||
|
|
||||||
def stream_get_metadata(self, path, keys = None):
|
def stream_get_metadata(self, path, keys = None):
|
||||||
|
@@ -62,7 +62,8 @@ class HTTPClient(object):
|
|||||||
try:
|
try:
|
||||||
response = self.session.request(method, url,
|
response = self.session.request(method, url,
|
||||||
params = query_data,
|
params = query_data,
|
||||||
data = body_data)
|
data = body_data,
|
||||||
|
stream = stream)
|
||||||
except requests.RequestException as e:
|
except requests.RequestException as e:
|
||||||
raise ServerError(status = "502 Error", url = url,
|
raise ServerError(status = "502 Error", url = url,
|
||||||
message = str(e.message))
|
message = str(e.message))
|
||||||
|
@@ -6,13 +6,14 @@ from nilmdb.utils import datetime_tz
|
|||||||
import nilmdb.utils.time
|
import nilmdb.utils.time
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
import argparse
|
import argparse
|
||||||
from argparse import ArgumentDefaultsHelpFormatter as def_form
|
from argparse import ArgumentDefaultsHelpFormatter as def_form
|
||||||
|
|
||||||
# Valid subcommands. Defined in separate files just to break
|
# Valid subcommands. Defined in separate files just to break
|
||||||
# things up -- they're still called with Cmdline as self.
|
# things up -- they're still called with Cmdline as self.
|
||||||
subcommands = [ "info", "create", "list", "metadata", "insert", "extract",
|
subcommands = [ "help", "info", "create", "list", "metadata",
|
||||||
"remove", "destroy" ]
|
"insert", "extract", "remove", "destroy" ]
|
||||||
|
|
||||||
# Import the subcommand modules
|
# Import the subcommand modules
|
||||||
subcmd_mods = {}
|
subcmd_mods = {}
|
||||||
@@ -29,6 +30,8 @@ class Cmdline(object):
|
|||||||
def __init__(self, argv = None):
|
def __init__(self, argv = None):
|
||||||
self.argv = argv or sys.argv[1:]
|
self.argv = argv or sys.argv[1:]
|
||||||
self.client = None
|
self.client = None
|
||||||
|
self.def_url = os.environ.get("NILMDB_URL", "http://localhost:12380")
|
||||||
|
self.subcmd = {}
|
||||||
|
|
||||||
def arg_time(self, toparse):
|
def arg_time(self, toparse):
|
||||||
"""Parse a time string argument"""
|
"""Parse a time string argument"""
|
||||||
@@ -50,18 +53,17 @@ class Cmdline(object):
|
|||||||
|
|
||||||
group = self.parser.add_argument_group("Server")
|
group = self.parser.add_argument_group("Server")
|
||||||
group.add_argument("-u", "--url", action="store",
|
group.add_argument("-u", "--url", action="store",
|
||||||
default="http://localhost:12380/",
|
default=self.def_url,
|
||||||
help="NilmDB server URL (default: %(default)s)")
|
help="NilmDB server URL (default: %(default)s)")
|
||||||
|
|
||||||
sub = self.parser.add_subparsers(title="Commands",
|
sub = self.parser.add_subparsers(
|
||||||
dest="command",
|
title="Commands", dest="command",
|
||||||
description="Specify --help after "
|
description="Use 'help command' or 'command --help' for more "
|
||||||
"the command for command-specific "
|
"details on a particular command.")
|
||||||
"options.")
|
|
||||||
|
|
||||||
# Set up subcommands (defined in separate files)
|
# Set up subcommands (defined in separate files)
|
||||||
for cmd in subcommands:
|
for cmd in subcommands:
|
||||||
subcmd_mods[cmd].setup(self, sub)
|
self.subcmd[cmd] = subcmd_mods[cmd].setup(self, sub)
|
||||||
|
|
||||||
def die(self, formatstr, *args):
|
def die(self, formatstr, *args):
|
||||||
fprintf(sys.stderr, formatstr + "\n", *args)
|
fprintf(sys.stderr, formatstr + "\n", *args)
|
||||||
@@ -84,11 +86,13 @@ class Cmdline(object):
|
|||||||
|
|
||||||
self.client = nilmdb.Client(self.args.url)
|
self.client = nilmdb.Client(self.args.url)
|
||||||
|
|
||||||
# Make a test connection to make sure things work
|
# Make a test connection to make sure things work,
|
||||||
try:
|
# unless the particular command requests that we don't.
|
||||||
server_version = self.client.version()
|
if "no_test_connect" not in self.args:
|
||||||
except nilmdb.client.Error as e:
|
try:
|
||||||
self.die("error connecting to server: %s", str(e))
|
server_version = self.client.version()
|
||||||
|
except nilmdb.client.Error as e:
|
||||||
|
self.die("error connecting to server: %s", str(e))
|
||||||
|
|
||||||
# Now dispatch client request to appropriate function. Parser
|
# Now dispatch client request to appropriate function. Parser
|
||||||
# should have ensured that we don't have any unknown commands
|
# should have ensured that we don't have any unknown commands
|
||||||
|
@@ -26,6 +26,7 @@ Layout types are of the format: type_count
|
|||||||
help="Path (in database) of new stream, e.g. /foo/bar")
|
help="Path (in database) of new stream, e.g. /foo/bar")
|
||||||
group.add_argument("layout",
|
group.add_argument("layout",
|
||||||
help="Layout type for new stream, e.g. float32_8")
|
help="Layout type for new stream, e.g. float32_8")
|
||||||
|
return cmd
|
||||||
|
|
||||||
def cmd_create(self):
|
def cmd_create(self):
|
||||||
"""Create new stream"""
|
"""Create new stream"""
|
||||||
|
@@ -16,6 +16,7 @@ def setup(self, sub):
|
|||||||
group = cmd.add_argument_group("Required arguments")
|
group = cmd.add_argument_group("Required arguments")
|
||||||
group.add_argument("path",
|
group.add_argument("path",
|
||||||
help="Path of the stream to delete, e.g. /foo/bar")
|
help="Path of the stream to delete, e.g. /foo/bar")
|
||||||
|
return cmd
|
||||||
|
|
||||||
def cmd_destroy(self):
|
def cmd_destroy(self):
|
||||||
"""Destroy stream"""
|
"""Destroy stream"""
|
||||||
|
@@ -30,6 +30,7 @@ def setup(self, sub):
|
|||||||
help="Show raw timestamps in annotated information")
|
help="Show raw timestamps in annotated information")
|
||||||
group.add_argument("-c", "--count", action="store_true",
|
group.add_argument("-c", "--count", action="store_true",
|
||||||
help="Just output a count of matched data points")
|
help="Just output a count of matched data points")
|
||||||
|
return cmd
|
||||||
|
|
||||||
def cmd_extract_verify(self):
|
def cmd_extract_verify(self):
|
||||||
if self.args.start is not None and self.args.end is not None:
|
if self.args.start is not None and self.args.end is not None:
|
||||||
|
26
nilmdb/cmdline/help.py
Normal file
26
nilmdb/cmdline/help.py
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
from nilmdb.utils.printf import *
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def setup(self, sub):
|
||||||
|
cmd = sub.add_parser("help", help="Show detailed help for a command",
|
||||||
|
description="""
|
||||||
|
Show help for a command. 'help command' is
|
||||||
|
the same as 'command --help'.
|
||||||
|
""")
|
||||||
|
cmd.set_defaults(handler = cmd_help)
|
||||||
|
cmd.set_defaults(no_test_connect = True)
|
||||||
|
cmd.add_argument("command", nargs="?",
|
||||||
|
help="Command to get help about")
|
||||||
|
cmd.add_argument("rest", nargs=argparse.REMAINDER,
|
||||||
|
help=argparse.SUPPRESS)
|
||||||
|
return cmd
|
||||||
|
|
||||||
|
def cmd_help(self):
|
||||||
|
if self.args.command in self.subcmd:
|
||||||
|
self.subcmd[self.args.command].print_help()
|
||||||
|
else:
|
||||||
|
self.parser.print_help()
|
||||||
|
|
||||||
|
return
|
@@ -12,6 +12,7 @@ def setup(self, sub):
|
|||||||
version.
|
version.
|
||||||
""")
|
""")
|
||||||
cmd.set_defaults(handler = cmd_info)
|
cmd.set_defaults(handler = cmd_info)
|
||||||
|
return cmd
|
||||||
|
|
||||||
def cmd_info(self):
|
def cmd_info(self):
|
||||||
"""Print info about the server"""
|
"""Print info about the server"""
|
||||||
|
@@ -47,6 +47,7 @@ def setup(self, sub):
|
|||||||
help="Path of stream, e.g. /foo/bar")
|
help="Path of stream, e.g. /foo/bar")
|
||||||
group.add_argument("file", nargs="*", default=['-'],
|
group.add_argument("file", nargs="*", default=['-'],
|
||||||
help="File(s) to insert (default: - (stdin))")
|
help="File(s) to insert (default: - (stdin))")
|
||||||
|
return cmd
|
||||||
|
|
||||||
def cmd_insert(self):
|
def cmd_insert(self):
|
||||||
# Find requested stream
|
# Find requested stream
|
||||||
|
@@ -24,11 +24,13 @@ def setup(self, sub):
|
|||||||
group.add_argument("-l", "--layout", default="*",
|
group.add_argument("-l", "--layout", default="*",
|
||||||
help="Match only this stream layout")
|
help="Match only this stream layout")
|
||||||
|
|
||||||
|
group = cmd.add_argument_group("Interval extent")
|
||||||
|
group.add_argument("-E", "--extent", action="store_true",
|
||||||
|
help="Show min/max timestamps in this stream")
|
||||||
|
|
||||||
group = cmd.add_argument_group("Interval details")
|
group = cmd.add_argument_group("Interval details")
|
||||||
group.add_argument("-d", "--detail", action="store_true",
|
group.add_argument("-d", "--detail", action="store_true",
|
||||||
help="Show available data time intervals")
|
help="Show available data time intervals")
|
||||||
group.add_argument("-T", "--timestamp-raw", action="store_true",
|
|
||||||
help="Show raw timestamps in time intervals")
|
|
||||||
group.add_argument("-s", "--start",
|
group.add_argument("-s", "--start",
|
||||||
metavar="TIME", type=self.arg_time,
|
metavar="TIME", type=self.arg_time,
|
||||||
help="Starting timestamp (free-form, inclusive)")
|
help="Starting timestamp (free-form, inclusive)")
|
||||||
@@ -36,6 +38,12 @@ def setup(self, sub):
|
|||||||
metavar="TIME", type=self.arg_time,
|
metavar="TIME", type=self.arg_time,
|
||||||
help="Ending timestamp (free-form, noninclusive)")
|
help="Ending timestamp (free-form, noninclusive)")
|
||||||
|
|
||||||
|
group = cmd.add_argument_group("Misc options")
|
||||||
|
group.add_argument("-T", "--timestamp-raw", action="store_true",
|
||||||
|
help="Show raw timestamps in time intervals or extents")
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
|
||||||
def cmd_list_verify(self):
|
def cmd_list_verify(self):
|
||||||
# A hidden "path_positional" argument lets the user leave off the
|
# A hidden "path_positional" argument lets the user leave off the
|
||||||
# "-p" when specifying the path. Handle it here.
|
# "-p" when specifying the path. Handle it here.
|
||||||
@@ -51,28 +59,38 @@ def cmd_list_verify(self):
|
|||||||
if self.args.start >= self.args.end:
|
if self.args.start >= self.args.end:
|
||||||
self.parser.error("start must precede end")
|
self.parser.error("start must precede end")
|
||||||
|
|
||||||
|
if self.args.start is not None or self.args.end is not None:
|
||||||
|
if not self.args.detail:
|
||||||
|
self.parser.error("--start and --end only make sense with --detail")
|
||||||
|
|
||||||
def cmd_list(self):
|
def cmd_list(self):
|
||||||
"""List available streams"""
|
"""List available streams"""
|
||||||
streams = self.client.stream_list()
|
streams = self.client.stream_list(extent = True)
|
||||||
|
|
||||||
if self.args.timestamp_raw:
|
if self.args.timestamp_raw:
|
||||||
time_string = repr
|
time_string = repr
|
||||||
else:
|
else:
|
||||||
time_string = nilmdb.utils.time.format_time
|
time_string = nilmdb.utils.time.format_time
|
||||||
|
|
||||||
for (path, layout) in streams:
|
for (path, layout, extent_min, extent_max) in streams:
|
||||||
if not (fnmatch.fnmatch(path, self.args.path) and
|
if not (fnmatch.fnmatch(path, self.args.path) and
|
||||||
fnmatch.fnmatch(layout, self.args.layout)):
|
fnmatch.fnmatch(layout, self.args.layout)):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
printf("%s %s\n", path, layout)
|
printf("%s %s\n", path, layout)
|
||||||
if not self.args.detail:
|
|
||||||
continue
|
|
||||||
|
|
||||||
printed = False
|
if self.args.extent:
|
||||||
for (start, end) in self.client.stream_intervals(path, self.args.start,
|
if extent_min is None or extent_max is None:
|
||||||
self.args.end):
|
printf(" extent: (no data)\n")
|
||||||
printf(" [ %s -> %s ]\n", time_string(start), time_string(end))
|
else:
|
||||||
printed = True
|
printf(" extent: %s -> %s\n",
|
||||||
if not printed:
|
time_string(extent_min), time_string(extent_max))
|
||||||
printf(" (no intervals)\n")
|
|
||||||
|
if self.args.detail:
|
||||||
|
printed = False
|
||||||
|
for (start, end) in self.client.stream_intervals(
|
||||||
|
path, self.args.start, self.args.end):
|
||||||
|
printf(" [ %s -> %s ]\n", time_string(start), time_string(end))
|
||||||
|
printed = True
|
||||||
|
if not printed:
|
||||||
|
printf(" (no intervals)\n")
|
||||||
|
@@ -26,6 +26,7 @@ def setup(self, sub):
|
|||||||
exc.add_argument("-u", "--update", nargs="+", metavar="key=value",
|
exc.add_argument("-u", "--update", nargs="+", metavar="key=value",
|
||||||
help="Update metadata using provided "
|
help="Update metadata using provided "
|
||||||
"key=value pairs")
|
"key=value pairs")
|
||||||
|
return cmd
|
||||||
|
|
||||||
def cmd_metadata(self):
|
def cmd_metadata(self):
|
||||||
"""Manipulate metadata"""
|
"""Manipulate metadata"""
|
||||||
|
@@ -23,6 +23,7 @@ def setup(self, sub):
|
|||||||
group = cmd.add_argument_group("Output format")
|
group = cmd.add_argument_group("Output format")
|
||||||
group.add_argument("-c", "--count", action="store_true",
|
group.add_argument("-c", "--count", action="store_true",
|
||||||
help="Output number of data points removed")
|
help="Output number of data points removed")
|
||||||
|
return cmd
|
||||||
|
|
||||||
def cmd_remove(self):
|
def cmd_remove(self):
|
||||||
try:
|
try:
|
||||||
|
@@ -269,28 +269,39 @@ class NilmDB(object):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def stream_list(self, path = None, layout = None):
|
def stream_list(self, path = None, layout = None, extent = False):
|
||||||
"""Return list of [path, layout] lists of all streams
|
"""Return list of lists of all streams in the database.
|
||||||
in the database.
|
|
||||||
|
|
||||||
If path is specified, include only streams with a path that
|
If path is specified, include only streams with a path that
|
||||||
matches the given string.
|
matches the given string.
|
||||||
|
|
||||||
If layout is specified, include only streams with a layout
|
If layout is specified, include only streams with a layout
|
||||||
that matches the given string.
|
that matches the given string.
|
||||||
"""
|
|
||||||
where = "WHERE 1=1"
|
|
||||||
params = ()
|
|
||||||
if layout:
|
|
||||||
where += " AND layout=?"
|
|
||||||
params += (layout,)
|
|
||||||
if path:
|
|
||||||
where += " AND path=?"
|
|
||||||
params += (path,)
|
|
||||||
result = self.con.execute("SELECT path, layout "
|
|
||||||
"FROM streams " + where, params).fetchall()
|
|
||||||
|
|
||||||
return sorted(list(x) for x in result)
|
If extent = False, returns a list of lists containing
|
||||||
|
the path and layout: [ path, layout ]
|
||||||
|
|
||||||
|
If extent = True, returns a list of lists containing the
|
||||||
|
path, layout, and min/max extent of the data:
|
||||||
|
[ path, layout, extent_min, extent_max ]
|
||||||
|
"""
|
||||||
|
params = ()
|
||||||
|
query = "SELECT streams.path, streams.layout"
|
||||||
|
if extent:
|
||||||
|
query += ", min(ranges.start_time), max(ranges.end_time)"
|
||||||
|
query += " FROM streams"
|
||||||
|
if extent:
|
||||||
|
query += " LEFT JOIN ranges ON streams.id = ranges.stream_id"
|
||||||
|
query += " WHERE 1=1"
|
||||||
|
if layout is not None:
|
||||||
|
query += " AND streams.layout=?"
|
||||||
|
params += (layout,)
|
||||||
|
if path is not None:
|
||||||
|
query += " AND streams.path=?"
|
||||||
|
params += (path,)
|
||||||
|
query += " GROUP BY streams.id ORDER BY streams.path"
|
||||||
|
result = self.con.execute(query, params).fetchall()
|
||||||
|
return [ list(x) for x in result ]
|
||||||
|
|
||||||
def stream_intervals(self, path, start = None, end = None):
|
def stream_intervals(self, path, start = None, end = None):
|
||||||
"""
|
"""
|
||||||
|
@@ -121,14 +121,22 @@ class Stream(NilmApp):
|
|||||||
|
|
||||||
# /stream/list
|
# /stream/list
|
||||||
# /stream/list?layout=PrepData
|
# /stream/list?layout=PrepData
|
||||||
# /stream/list?path=/newton/prep
|
# /stream/list?path=/newton/prep&extent=1
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
@cherrypy.tools.json_out()
|
@cherrypy.tools.json_out()
|
||||||
def list(self, path = None, layout = None):
|
def list(self, path = None, layout = None, extent = None):
|
||||||
"""List all streams in the database. With optional path or
|
"""List all streams in the database. With optional path or
|
||||||
layout parameter, just list streams that match the given path
|
layout parameter, just list streams that match the given path
|
||||||
or layout"""
|
or layout.
|
||||||
return self.db.stream_list(path, layout)
|
|
||||||
|
If extent is not given, returns a list of lists containing
|
||||||
|
the path and layout: [ path, layout ]
|
||||||
|
|
||||||
|
If extent is provided, returns a list of lists containing the
|
||||||
|
path, layout, and min/max extent of the data:
|
||||||
|
[ path, layout, extent_min, extent_max ]
|
||||||
|
"""
|
||||||
|
return self.db.stream_list(path, layout, bool(extent))
|
||||||
|
|
||||||
# /stream/create?path=/newton/prep&layout=PrepData
|
# /stream/create?path=/newton/prep&layout=PrepData
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
|
@@ -25,7 +25,7 @@ import re
|
|||||||
from testutil.helpers import *
|
from testutil.helpers import *
|
||||||
|
|
||||||
testdb = "tests/client-testdb"
|
testdb = "tests/client-testdb"
|
||||||
testurl = "http://localhost:12380/"
|
testurl = "http://localhost:32180/"
|
||||||
|
|
||||||
def setup_module():
|
def setup_module():
|
||||||
global test_server, test_db
|
global test_server, test_db
|
||||||
@@ -35,7 +35,7 @@ def setup_module():
|
|||||||
# Start web app on a custom port
|
# Start web app on a custom port
|
||||||
test_db = nilmdb.utils.serializer_proxy(nilmdb.NilmDB)(testdb, sync = False)
|
test_db = nilmdb.utils.serializer_proxy(nilmdb.NilmDB)(testdb, sync = False)
|
||||||
test_server = nilmdb.Server(test_db, host = "127.0.0.1",
|
test_server = nilmdb.Server(test_db, host = "127.0.0.1",
|
||||||
port = 12380, stoppable = False,
|
port = 32180, stoppable = False,
|
||||||
fast_shutdown = True,
|
fast_shutdown = True,
|
||||||
force_traceback = False)
|
force_traceback = False)
|
||||||
test_server.start(blocking = False)
|
test_server.start(blocking = False)
|
||||||
@@ -62,13 +62,13 @@ class TestClient(object):
|
|||||||
client.close()
|
client.close()
|
||||||
|
|
||||||
# Then a fake URL on a real host
|
# Then a fake URL on a real host
|
||||||
client = nilmdb.Client(url = "http://localhost:12380/fake/")
|
client = nilmdb.Client(url = "http://localhost:32180/fake/")
|
||||||
with assert_raises(nilmdb.client.ClientError):
|
with assert_raises(nilmdb.client.ClientError):
|
||||||
client.version()
|
client.version()
|
||||||
client.close()
|
client.close()
|
||||||
|
|
||||||
# Now a real URL with no http:// prefix
|
# Now a real URL with no http:// prefix
|
||||||
client = nilmdb.Client(url = "localhost:12380")
|
client = nilmdb.Client(url = "localhost:32180")
|
||||||
version = client.version()
|
version = client.version()
|
||||||
client.close()
|
client.close()
|
||||||
|
|
||||||
@@ -584,7 +584,7 @@ class TestClient(object):
|
|||||||
def connections():
|
def connections():
|
||||||
try:
|
try:
|
||||||
poolmanager = c.http._last_response.connection.poolmanager
|
poolmanager = c.http._last_response.connection.poolmanager
|
||||||
pool = poolmanager.pools[('http','localhost',12380)]
|
pool = poolmanager.pools[('http','localhost',32180)]
|
||||||
return (pool.num_connections, pool.num_requests)
|
return (pool.num_connections, pool.num_requests)
|
||||||
except:
|
except:
|
||||||
raise SkipTest("can't get connection info")
|
raise SkipTest("can't get connection info")
|
||||||
|
@@ -32,7 +32,7 @@ def server_start(max_results = None, bulkdata_args = {}):
|
|||||||
max_results = max_results,
|
max_results = max_results,
|
||||||
bulkdata_args = bulkdata_args)
|
bulkdata_args = bulkdata_args)
|
||||||
test_server = nilmdb.Server(test_db, host = "127.0.0.1",
|
test_server = nilmdb.Server(test_db, host = "127.0.0.1",
|
||||||
port = 12380, stoppable = False,
|
port = 32180, stoppable = False,
|
||||||
fast_shutdown = True,
|
fast_shutdown = True,
|
||||||
force_traceback = False)
|
force_traceback = False)
|
||||||
test_server.start(blocking = False)
|
test_server.start(blocking = False)
|
||||||
@@ -64,6 +64,7 @@ class TestCmdline(object):
|
|||||||
passing the given input. Returns a tuple with the output and
|
passing the given input. Returns a tuple with the output and
|
||||||
exit code"""
|
exit code"""
|
||||||
# printf("TZ=UTC ./nilmtool.py %s\n", arg_string)
|
# printf("TZ=UTC ./nilmtool.py %s\n", arg_string)
|
||||||
|
os.environ['NILMDB_URL'] = "http://localhost:32180/"
|
||||||
class stdio_wrapper:
|
class stdio_wrapper:
|
||||||
def __init__(self, stdin, stdout, stderr):
|
def __init__(self, stdin, stdout, stderr):
|
||||||
self.io = (stdin, stdout, stderr)
|
self.io = (stdin, stdout, stderr)
|
||||||
@@ -174,7 +175,7 @@ class TestCmdline(object):
|
|||||||
self.fail("-u localhost:1 info")
|
self.fail("-u localhost:1 info")
|
||||||
self.contain("error connecting to server")
|
self.contain("error connecting to server")
|
||||||
|
|
||||||
self.ok("-u localhost:12380 info")
|
self.ok("-u localhost:32180 info")
|
||||||
self.ok("info")
|
self.ok("info")
|
||||||
|
|
||||||
# Duplicated arguments should fail, but this isn't implemented
|
# Duplicated arguments should fail, but this isn't implemented
|
||||||
@@ -192,6 +193,20 @@ class TestCmdline(object):
|
|||||||
self.fail("extract --start 2000-01-01 --start 2001-01-02")
|
self.fail("extract --start 2000-01-01 --start 2001-01-02")
|
||||||
self.contain("duplicated argument")
|
self.contain("duplicated argument")
|
||||||
|
|
||||||
|
# Verify that "help command" and "command --help" are identical
|
||||||
|
# for all commands.
|
||||||
|
self.fail("")
|
||||||
|
m = re.search(r"{(.*)}", self.captured)
|
||||||
|
for command in [""] + m.group(1).split(','):
|
||||||
|
self.ok(command + " --help")
|
||||||
|
cap1 = self.captured
|
||||||
|
self.ok("help " + command)
|
||||||
|
cap2 = self.captured
|
||||||
|
self.ok("help " + command + " asdf --url --zxcv -")
|
||||||
|
cap3 = self.captured
|
||||||
|
eq_(cap1, cap2)
|
||||||
|
eq_(cap2, cap3)
|
||||||
|
|
||||||
def test_02_parsetime(self):
|
def test_02_parsetime(self):
|
||||||
os.environ['TZ'] = "America/New_York"
|
os.environ['TZ'] = "America/New_York"
|
||||||
test = datetime_tz.datetime_tz.now()
|
test = datetime_tz.datetime_tz.now()
|
||||||
@@ -210,7 +225,7 @@ class TestCmdline(object):
|
|||||||
|
|
||||||
def test_03_info(self):
|
def test_03_info(self):
|
||||||
self.ok("info")
|
self.ok("info")
|
||||||
self.contain("Server URL: http://localhost:12380/")
|
self.contain("Server URL: http://localhost:32180/")
|
||||||
self.contain("Client version: " + nilmdb.__version__)
|
self.contain("Client version: " + nilmdb.__version__)
|
||||||
self.contain("Server version: " + test_server.version)
|
self.contain("Server version: " + test_server.version)
|
||||||
self.contain("Server database path")
|
self.contain("Server database path")
|
||||||
@@ -418,7 +433,7 @@ class TestCmdline(object):
|
|||||||
# bad start time
|
# bad start time
|
||||||
self.fail("insert --rate 120 --start 'whatever' /newton/prep /dev/null")
|
self.fail("insert --rate 120 --start 'whatever' /newton/prep /dev/null")
|
||||||
|
|
||||||
def test_07_detail(self):
|
def test_07_detail_extent(self):
|
||||||
# Just count the number of lines, it's probably fine
|
# Just count the number of lines, it's probably fine
|
||||||
self.ok("list --detail")
|
self.ok("list --detail")
|
||||||
lines_(self.captured, 8)
|
lines_(self.captured, 8)
|
||||||
@@ -463,6 +478,18 @@ class TestCmdline(object):
|
|||||||
lines_(self.captured, 2)
|
lines_(self.captured, 2)
|
||||||
self.contain("[ 1332497115.612 -> 1332497159.991668 ]")
|
self.contain("[ 1332497115.612 -> 1332497159.991668 ]")
|
||||||
|
|
||||||
|
# Check --extent output
|
||||||
|
self.ok("list --extent")
|
||||||
|
lines_(self.captured, 6)
|
||||||
|
|
||||||
|
self.ok("list -E -T")
|
||||||
|
self.contain(" extent: 1332496800 -> 1332497159.991668")
|
||||||
|
self.contain(" extent: (no data)")
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
self.fail("list --extent --start='23 Mar 2012 10:05:15.50'")
|
||||||
|
self.contain("--start and --end only make sense with --detail")
|
||||||
|
|
||||||
def test_08_extract(self):
|
def test_08_extract(self):
|
||||||
# nonexistent stream
|
# nonexistent stream
|
||||||
self.fail("extract /no/such/foo --start 2000-01-01 --end 2020-01-01")
|
self.fail("extract /no/such/foo --start 2000-01-01 --end 2020-01-01")
|
||||||
|
@@ -119,7 +119,7 @@ class TestBlockingServer(object):
|
|||||||
|
|
||||||
# Start web app on a custom port
|
# Start web app on a custom port
|
||||||
self.server = nilmdb.Server(self.db, host = "127.0.0.1",
|
self.server = nilmdb.Server(self.db, host = "127.0.0.1",
|
||||||
port = 12380, stoppable = True)
|
port = 32180, stoppable = True)
|
||||||
|
|
||||||
# Run it
|
# Run it
|
||||||
event = threading.Event()
|
event = threading.Event()
|
||||||
@@ -131,13 +131,13 @@ class TestBlockingServer(object):
|
|||||||
raise AssertionError("server didn't start in 10 seconds")
|
raise AssertionError("server didn't start in 10 seconds")
|
||||||
|
|
||||||
# Send request to exit.
|
# Send request to exit.
|
||||||
req = urlopen("http://127.0.0.1:12380/exit/", timeout = 1)
|
req = urlopen("http://127.0.0.1:32180/exit/", timeout = 1)
|
||||||
|
|
||||||
# Wait for it
|
# Wait for it
|
||||||
thread.join()
|
thread.join()
|
||||||
|
|
||||||
def geturl(path):
|
def geturl(path):
|
||||||
req = urlopen("http://127.0.0.1:12380" + path, timeout = 10)
|
req = urlopen("http://127.0.0.1:32180" + path, timeout = 10)
|
||||||
return req.read()
|
return req.read()
|
||||||
|
|
||||||
def getjson(path):
|
def getjson(path):
|
||||||
@@ -149,7 +149,7 @@ class TestServer(object):
|
|||||||
# Start web app on a custom port
|
# Start web app on a custom port
|
||||||
self.db = serializer_proxy(nilmdb.NilmDB)(testdb, sync=False)
|
self.db = serializer_proxy(nilmdb.NilmDB)(testdb, sync=False)
|
||||||
self.server = nilmdb.Server(self.db, host = "127.0.0.1",
|
self.server = nilmdb.Server(self.db, host = "127.0.0.1",
|
||||||
port = 12380, stoppable = False)
|
port = 32180, stoppable = False)
|
||||||
self.server.start(blocking = False)
|
self.server.start(blocking = False)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
|
Reference in New Issue
Block a user