kopia lustrzana https://github.com/ukhas/habitat-cpp-connector
Use habitat validation on test docs, and fix errors found
rodzic
11b8f1f7aa
commit
280da5c603
|
@ -148,7 +148,7 @@ string Uploader::payload_telemetry(const string &data,
|
|||
{
|
||||
if (metadata.isMember("time_created") ||
|
||||
metadata.isMember("time_uploaded") ||
|
||||
metadata.isMember("latest_listener_info") ||
|
||||
metadata.isMember("latest_listener_information") ||
|
||||
metadata.isMember("latest_listener_telemetry"))
|
||||
{
|
||||
throw invalid_argument("found forbidden key in metadata");
|
||||
|
@ -162,8 +162,9 @@ string Uploader::payload_telemetry(const string &data,
|
|||
throw invalid_argument("metadata must be an object/dict or null");
|
||||
}
|
||||
|
||||
if (latest_listener_info.length())
|
||||
receiver_info["latest_listener_info"] = latest_listener_info;
|
||||
if (latest_listener_information.length())
|
||||
receiver_info["latest_listener_information"] =
|
||||
latest_listener_information;
|
||||
|
||||
if (latest_listener_telemetry.length())
|
||||
receiver_info["latest_listener_telemetry"] = latest_listener_telemetry;
|
||||
|
@ -238,14 +239,14 @@ string Uploader::listener_telemetry(const Json::Value &data,
|
|||
return latest_listener_telemetry;
|
||||
}
|
||||
|
||||
string Uploader::listener_info(const Json::Value &data,
|
||||
long long int time_created)
|
||||
string Uploader::listener_information(const Json::Value &data,
|
||||
long long int time_created)
|
||||
{
|
||||
EZ::MutexLock lock(mutex);
|
||||
|
||||
latest_listener_info =
|
||||
listener_doc("listener_info", data, time_created);
|
||||
return latest_listener_info;
|
||||
latest_listener_information =
|
||||
listener_doc("listener_information", data, time_created);
|
||||
return latest_listener_information;
|
||||
}
|
||||
|
||||
vector<Json::Value> *Uploader::flights()
|
||||
|
|
|
@ -36,7 +36,7 @@ class Uploader
|
|||
CouchDB::Server server;
|
||||
CouchDB::Database database;
|
||||
const int max_merge_attempts;
|
||||
string latest_listener_info;
|
||||
string latest_listener_information;
|
||||
string latest_listener_telemetry;
|
||||
|
||||
string listener_doc(const char *type, const Json::Value &data,
|
||||
|
@ -51,10 +51,11 @@ public:
|
|||
string payload_telemetry(const string &data,
|
||||
const Json::Value &metadata=Json::Value::null,
|
||||
long long int time_created=-1);
|
||||
/* note that latitude, longitude are required properties of data */
|
||||
string listener_telemetry(const Json::Value &data,
|
||||
long long int time_created=-1);
|
||||
string listener_info(const Json::Value &data,
|
||||
long long int time_created=-1);
|
||||
string listener_information(const Json::Value &data,
|
||||
long long int time_created=-1);
|
||||
vector<Json::Value> *flights();
|
||||
vector<Json::Value> *payloads();
|
||||
};
|
||||
|
|
|
@ -80,8 +80,8 @@ string UploaderListenerTelemetry::describe()
|
|||
void UploaderListenerInfo::apply(UploaderThread &uthr)
|
||||
{
|
||||
check(uthr.uploader.get());
|
||||
string result = uthr.uploader->listener_info(data, time_created);
|
||||
uthr.saved_id("listener_info", result);
|
||||
string result = uthr.uploader->listener_information(data, time_created);
|
||||
uthr.saved_id("listener_information", result);
|
||||
}
|
||||
|
||||
string UploaderListenerInfo::describe()
|
||||
|
@ -90,7 +90,7 @@ string UploaderListenerInfo::describe()
|
|||
Json::FastWriter writer;
|
||||
string data_json = writer.write(data);
|
||||
data_json.erase(data_json.length() - 1, 1);
|
||||
ss << "Uploader.listener_info(" << data_json << ", "
|
||||
ss << "Uploader.listener_information(" << data_json << ", "
|
||||
<< time_created << ")";
|
||||
return ss.str();
|
||||
}
|
||||
|
@ -178,8 +178,8 @@ void UploaderThread::listener_telemetry(const Json::Value &data,
|
|||
queue_action(new UploaderListenerTelemetry(data, time_created));
|
||||
}
|
||||
|
||||
void UploaderThread::listener_info(const Json::Value &data,
|
||||
int time_created)
|
||||
void UploaderThread::listener_information(const Json::Value &data,
|
||||
int time_created)
|
||||
{
|
||||
queue_action(new UploaderListenerInfo(data, time_created));
|
||||
}
|
||||
|
|
|
@ -174,7 +174,7 @@ public:
|
|||
const Json::Value &metadata=Json::Value::null,
|
||||
int time_created=-1);
|
||||
void listener_telemetry(const Json::Value &data, int time_created=-1);
|
||||
void listener_info(const Json::Value &data, int time_created=-1);
|
||||
void listener_information(const Json::Value &data, int time_created=-1);
|
||||
void flights();
|
||||
void payloads();
|
||||
void shutdown();
|
||||
|
|
|
@ -17,6 +17,7 @@ import xml.etree.cElementTree as ET
|
|||
import urllib
|
||||
|
||||
from habitat.utils import rfc3339
|
||||
from habitat import views
|
||||
|
||||
class ProxyException:
|
||||
def __init__(self, name, what=None):
|
||||
|
@ -166,8 +167,8 @@ class Proxy:
|
|||
def listener_telemetry(self, data, *args):
|
||||
return self._proxy(["listener_telemetry", data] + list(args))
|
||||
|
||||
def listener_info(self, data, *args):
|
||||
return self._proxy(["listener_info", data] + list(args))
|
||||
def listener_information(self, data, *args):
|
||||
return self._proxy(["listener_information", data] + list(args))
|
||||
|
||||
def flights(self):
|
||||
return self._proxy(["flights"])
|
||||
|
@ -206,7 +207,8 @@ class MockHTTP(BaseHTTPServer.HTTPServer):
|
|||
"method": "GET",
|
||||
"path": "/",
|
||||
"body": None, # string if you expect something from a POST
|
||||
# body_json=object
|
||||
# "body_json": {'object': True}
|
||||
"validate_body_json": True,
|
||||
|
||||
# and respond with:
|
||||
"code": 404,
|
||||
|
@ -220,6 +222,18 @@ class MockHTTP(BaseHTTPServer.HTTPServer):
|
|||
e = self.expect_defaults.copy()
|
||||
e.update(kwargs)
|
||||
|
||||
if "body_json" in e and e["validate_body_json"]:
|
||||
old = e.get("validate_old", None)
|
||||
new = e["body_json"]
|
||||
|
||||
userctx = {'roles': []}
|
||||
secobj = {}
|
||||
|
||||
for mod in [views.flight, views.listener_information,
|
||||
views.listener_telemetry, views.payload_telemetry,
|
||||
views.payload_configuration, views.habitat]:
|
||||
mod.validate(new, old, userctx, secobj)
|
||||
|
||||
self.expect_queue.append(e)
|
||||
|
||||
def run(self):
|
||||
|
@ -377,7 +391,8 @@ class TestCPPConnector:
|
|||
"time_uploaded": self.callbacks.fake_rfc3339(i),
|
||||
"data": {
|
||||
"callsign": "PROXYCALL",
|
||||
"test": 123.356
|
||||
"latitude": 3.12,
|
||||
"longitude": -123.1
|
||||
},
|
||||
"type": "listener_telemetry"
|
||||
}
|
||||
|
@ -386,14 +401,20 @@ class TestCPPConnector:
|
|||
|
||||
self.couchdb.run()
|
||||
|
||||
data = {
|
||||
"latitude": 3.12,
|
||||
"longitude": -123.1
|
||||
}
|
||||
|
||||
for i in xrange(200):
|
||||
doc_id = self.uploader.listener_telemetry({"test": 123.356})
|
||||
doc_id = self.uploader.listener_telemetry(data)
|
||||
assert doc_id == should_use_uuids[i]
|
||||
|
||||
self.couchdb.check()
|
||||
|
||||
def add_sample_listener_docs(self):
|
||||
telemetry_data = {"some_data": 123, "_flag": True}
|
||||
telemetry_data = {"latitude": 1.0, "longitude": 2.0,
|
||||
"some_data": 123, "_flag": True}
|
||||
telemetry_doc = {
|
||||
"_id": self.pop_uuid(),
|
||||
"data": copy.deepcopy(telemetry_data),
|
||||
|
@ -407,7 +428,7 @@ class TestCPPConnector:
|
|||
info_doc = {
|
||||
"_id": self.pop_uuid(),
|
||||
"data": copy.deepcopy(info_data),
|
||||
"type": "listener_info",
|
||||
"type": "listener_information",
|
||||
"time_created": self.callbacks.fake_rfc3339(0),
|
||||
"time_uploaded": self.callbacks.fake_rfc3339(0)
|
||||
}
|
||||
|
@ -419,7 +440,7 @@ class TestCPPConnector:
|
|||
self.couchdb.run()
|
||||
self.sample_telemetry_doc_id = \
|
||||
self.uploader.listener_telemetry(telemetry_data)
|
||||
self.sample_info_doc_id = self.uploader.listener_info(info_data)
|
||||
self.sample_info_doc_id = self.uploader.listener_information(info_data)
|
||||
self.couchdb.check()
|
||||
|
||||
assert self.sample_telemetry_doc_id == telemetry_doc["_id"]
|
||||
|
@ -453,7 +474,7 @@ class TestCPPConnector:
|
|||
info_doc = {
|
||||
"_id": self.pop_uuid(),
|
||||
"data": copy.deepcopy(info_data),
|
||||
"type": "listener_info",
|
||||
"type": "listener_information",
|
||||
"time_created": self.callbacks.fake_rfc3339(409),
|
||||
"time_uploaded": self.callbacks.fake_rfc3339(1005)
|
||||
}
|
||||
|
@ -467,7 +488,7 @@ class TestCPPConnector:
|
|||
telemetry_doc_id = \
|
||||
self.uploader.listener_telemetry(telemetry_data,
|
||||
self.callbacks.fake_timestamp(501))
|
||||
info_doc_id = self.uploader.listener_info(info_data,
|
||||
info_doc_id = self.uploader.listener_information(info_data,
|
||||
self.callbacks.fake_timestamp(409))
|
||||
self.couchdb.check()
|
||||
|
||||
|
@ -523,7 +544,7 @@ class TestCPPConnector:
|
|||
"time_created": self.callbacks.fake_rfc3339(0),
|
||||
"time_uploaded": self.callbacks.fake_rfc3339(0),
|
||||
"latest_listener_telemetry": self.sample_telemetry_doc_id,
|
||||
"latest_listener_info": self.sample_info_doc_id
|
||||
"latest_listener_information": self.sample_info_doc_id
|
||||
}
|
||||
|
||||
doc = copy.deepcopy(self.ptlm_doc)
|
||||
|
@ -583,7 +604,7 @@ class TestCPPConnector:
|
|||
receiver_info["time_uploaded"] = self.callbacks.fake_rfc3339(10)
|
||||
doc_merged["receivers"]["PROXYCALL"].update(receiver_info)
|
||||
|
||||
self.expect_save_doc(doc_merged)
|
||||
self.expect_save_doc(doc_merged, validate_old=self.ptlm_doc_existing)
|
||||
|
||||
self.couchdb.run()
|
||||
self.uploader.payload_telemetry(self.ptlm_string, self.ptlm_metadata)
|
||||
|
@ -668,6 +689,7 @@ class TestCPPConnector:
|
|||
method="PUT",
|
||||
path=self.db_path + self.ptlm_doc_id,
|
||||
body_json=doc_merged,
|
||||
validate_old=doc_existing,
|
||||
code=409,
|
||||
respond_json={"error": "conflict"},
|
||||
advance_time_after=1
|
||||
|
@ -697,7 +719,7 @@ class TestCPPConnector:
|
|||
respond_json=final_doc_existing,
|
||||
)
|
||||
|
||||
self.expect_save_doc(final_doc_merged)
|
||||
self.expect_save_doc(final_doc_merged, validate_old=final_doc_existing)
|
||||
|
||||
self.couchdb.run()
|
||||
self.uploader.payload_telemetry(self.ptlm_string, self.ptlm_metadata)
|
||||
|
@ -787,7 +809,8 @@ class TestCPPConnectorThreaded(TestCPPConnector):
|
|||
command = "tests/cpp_connector_threaded"
|
||||
|
||||
def test_queues_things(self):
|
||||
telemetry_data = {"this was queued": True}
|
||||
telemetry_data = {"this was queued": True,
|
||||
"latitude": 1.0, "longitude": 2.0}
|
||||
telemetry_doc = {
|
||||
"_id": self.pop_uuid(),
|
||||
"data": copy.deepcopy(telemetry_data),
|
||||
|
@ -801,7 +824,7 @@ class TestCPPConnectorThreaded(TestCPPConnector):
|
|||
info_doc = {
|
||||
"_id": self.pop_uuid(),
|
||||
"data": copy.deepcopy(info_data),
|
||||
"type": "listener_info",
|
||||
"type": "listener_information",
|
||||
"time_created": self.callbacks.fake_rfc3339(0),
|
||||
"time_uploaded": self.callbacks.fake_rfc3339(0)
|
||||
}
|
||||
|
@ -818,7 +841,7 @@ class TestCPPConnectorThreaded(TestCPPConnector):
|
|||
self.couchdb.run()
|
||||
|
||||
self.run_unblocked(self.uploader.listener_telemetry, telemetry_data)
|
||||
self.run_unblocked(self.uploader.listener_info, info_data)
|
||||
self.run_unblocked(self.uploader.listener_information, info_data)
|
||||
|
||||
# The complexity of doing this properly justifies this evil hack...
|
||||
# right?
|
||||
|
|
|
@ -70,7 +70,8 @@ static void proxy_constructor(TestSubject *u, Json::Value command);
|
|||
static void proxy_reset(TestSubject *u);
|
||||
#endif
|
||||
|
||||
static r_string proxy_listener_info(TestSubject *u, Json::Value command);
|
||||
static r_string proxy_listener_information(TestSubject *u,
|
||||
Json::Value command);
|
||||
static r_string proxy_listener_telemetry(TestSubject *u, Json::Value command);
|
||||
static r_string proxy_payload_telemetry(TestSubject *u, Json::Value command);
|
||||
static r_json proxy_flights(TestSubject *u);
|
||||
|
@ -122,8 +123,8 @@ int main(int argc, char **argv)
|
|||
|
||||
if (command_name == "init")
|
||||
u.reset(proxy_constructor(command));
|
||||
else if (command_name == "listener_info")
|
||||
return_value = proxy_listener_info(u.get(), command);
|
||||
else if (command_name == "listener_information")
|
||||
return_value = proxy_listener_information(u.get(), command);
|
||||
else if (command_name == "listener_telemetry")
|
||||
return_value = proxy_listener_telemetry(u.get(), command);
|
||||
else if (command_name == "payload_telemetry")
|
||||
|
@ -194,8 +195,8 @@ int main(int argc, char **argv)
|
|||
proxy_constructor(&thread, command);
|
||||
else if (command_name == "reset")
|
||||
proxy_reset(&thread);
|
||||
else if (command_name == "listener_info")
|
||||
proxy_listener_info(&thread, command);
|
||||
else if (command_name == "listener_information")
|
||||
proxy_listener_information(&thread, command);
|
||||
else if (command_name == "listener_telemetry")
|
||||
proxy_listener_telemetry(&thread, command);
|
||||
else if (command_name == "payload_telemetry")
|
||||
|
@ -323,15 +324,15 @@ static void proxy_reset(TestSubject *u)
|
|||
}
|
||||
#endif
|
||||
|
||||
static r_string proxy_listener_info(TestSubject *u, Json::Value command)
|
||||
static r_string proxy_listener_information(TestSubject *u, Json::Value command)
|
||||
{
|
||||
const Json::Value &data = command[1u];
|
||||
const Json::Value &tc = command[2u];
|
||||
|
||||
if (tc.isNull())
|
||||
return u->listener_info(data);
|
||||
return u->listener_information(data);
|
||||
else
|
||||
return u->listener_info(data, tc.asInt());
|
||||
return u->listener_information(data, tc.asInt());
|
||||
}
|
||||
|
||||
static r_string proxy_listener_telemetry(TestSubject *u, Json::Value command)
|
||||
|
|
Ładowanie…
Reference in New Issue