diff --git a/src/comm/Manager.cc b/src/comm/Manager.cc index 9f17878cf6..0b887d4f37 100644 --- a/src/comm/Manager.cc +++ b/src/comm/Manager.cc @@ -408,10 +408,20 @@ double comm::Manager::NextTimestamp(double* local_network_time) struct response_converter { using result_type = RecordVal*; + broker::store::query::tag query_tag; result_type operator()(bool d) { - return comm::make_data_val(broker::data{d}); + switch ( query_tag ) { + case broker::store::query::tag::pop_left: + case broker::store::query::tag::pop_right: + case broker::store::query::tag::lookup: + // A boolean result means the key doesn't exist (if it did, then + // the result would contain the broker::data value, not a bool). + return new RecordVal(BifType::Record::Comm::Data); + default: + return comm::make_data_val(broker::data{d}); + } } result_type operator()(uint64_t d) @@ -446,7 +456,7 @@ struct response_converter { static RecordVal* response_to_val(broker::store::response r) { - return broker::visit(response_converter{}, r.reply.value); + return broker::visit(response_converter{r.request.type}, r.reply.value); } void comm::Manager::Process() diff --git a/src/comm/store.bif b/src/comm/store.bif index fb4c8d57ce..176e55268e 100644 --- a/src/comm/store.bif +++ b/src/comm/store.bif @@ -127,7 +127,7 @@ function Store::clear%(h: opaque of Store::Handle%): bool %} function Store::increment%(h: opaque of Store::Handle, - k: Comm::Data, by: int%): bool + k: Comm::Data, by: int &default = +1%): bool %{ auto handle = static_cast(h); @@ -140,7 +140,7 @@ function Store::increment%(h: opaque of Store::Handle, %} function Store::decrement%(h: opaque of Store::Handle, - k: Comm::Data, by: int%): bool + k: Comm::Data, by: int &default = +1%): bool %{ auto handle = static_cast(h); diff --git a/testing/btest/Baseline/comm.master_store/out b/testing/btest/Baseline/comm.master_store/out new file mode 100644 index 0000000000..defdc9a3e1 --- /dev/null +++ b/testing/btest/Baseline/comm.master_store/out @@ -0,0 +1,14 @@ +lookup(two): [status=Store::SUCCESS, result=[d=broker::data{222}]] +lookup(four): [status=Store::SUCCESS, result=[d=]] +lookup(myset): [status=Store::SUCCESS, result=[d=broker::data{{a, c, d}}]] +lookup(one): [status=Store::SUCCESS, result=[d=broker::data{111}]] +lookup(myvec): [status=Store::SUCCESS, result=[d=broker::data{[delta, alpha, beta, gamma, omega]}]] +exists(one): [status=Store::SUCCESS, result=[d=broker::data{1}]] +exists(two): [status=Store::SUCCESS, result=[d=broker::data{0}]] +exists(myset): [status=Store::SUCCESS, result=[d=broker::data{1}]] +exists(four): [status=Store::SUCCESS, result=[d=broker::data{0}]] +pop_right(myvec): [status=Store::SUCCESS, result=[d=broker::data{omega}]] +pop_left(myvec): [status=Store::SUCCESS, result=[d=broker::data{delta}]] +keys: [status=Store::SUCCESS, result=[d=broker::data{[myvec, myset, one]}]] +size: [status=Store::SUCCESS, result=[d=broker::data{3}]] +size (after clear): [status=Store::SUCCESS, result=[d=broker::data{0}]] diff --git a/testing/btest/comm/master_store.bro b/testing/btest/comm/master_store.bro new file mode 100644 index 0000000000..84b4ee07a1 --- /dev/null +++ b/testing/btest/comm/master_store.bro @@ -0,0 +1,141 @@ +# @TEST-EXEC: bro -b %INPUT >out +# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-sort btest-diff out + +redef exit_only_after_terminate = T; + +global h: opaque of Store::Handle; +global lookup_count = 0; +const lookup_expect_count = 5; +global exists_count = 0; +const exists_expect_count = 4; +global pop_count = 0; +const pop_expect_count = 2; + +global test_size: event(where: string &default = ""); + +event test_clear() + { + Store::clear(h); + event test_size("after clear"); + } + +event test_size(where: string) + { + when ( local res = Store::size(h) ) + { + if ( where == "" ) + { + print fmt("size: %s", res); + event test_clear(); + } + else + { + print fmt("size (%s): %s", where, res); + terminate(); + } + } + timeout 10sec + { print "timeout"; } + } + +event test_keys() + { + when ( local res = Store::keys(h) ) + { + print fmt("keys: %s", res); + event test_size(); + } + timeout 10sec + { print "timeout"; } + } + +event test_pop(key: string) + { + when ( local lres = Store::pop_left(h, Comm::data(key)) ) + { + print fmt("pop_left(%s): %s", key, lres); + ++pop_count; + + if ( pop_count == pop_expect_count ) + event test_keys(); + } + timeout 10sec + { print "timeout"; } + + when ( local rres = Store::pop_right(h, Comm::data(key)) ) + { + print fmt("pop_right(%s): %s", key, rres); + ++pop_count; + + if ( pop_count == pop_expect_count ) + event test_keys(); + } + timeout 10sec + { print "timeout"; } + } + +function do_exists(key: string) + { + when ( local res = Store::exists(h, Comm::data(key)) ) + { + print fmt("exists(%s): %s", key, res); + ++exists_count; + + if ( exists_count == exists_expect_count ) + event test_pop("myvec"); + } + timeout 10sec + { print "timeout"; } + } + +event test_erase() + { + Store::erase(h, Comm::data("two")); + do_exists("one"); + do_exists("two"); + do_exists("myset"); + do_exists("four"); + } + +function do_lookup(key: string) + { + when ( local res = Store::lookup(h, Comm::data(key)) ) + { + print fmt("lookup(%s): %s", key, res); + ++lookup_count; + + if ( lookup_count == lookup_expect_count ) + event test_erase(); + } + timeout 10sec + { print "timeout"; } + } + +function dv(d: Comm::Data): Comm::DataVector + { + local rval: Comm::DataVector; + rval[0] = d; + return rval; + } + +event bro_init() + { + local myset: set[string] = {"a", "b", "c"}; + local myvec: vector of string = {"alpha", "beta", "gamma"}; + h = Store::create_master("master"); + Store::insert(h, Comm::data("one"), Comm::data(110)); + Store::insert(h, Comm::data("two"), Comm::data(223)); + Store::insert(h, Comm::data("myset"), Comm::data(myset)); + Store::insert(h, Comm::data("myvec"), Comm::data(myvec)); + Store::increment(h, Comm::data("one")); + Store::decrement(h, Comm::data("two")); + Store::add_to_set(h, Comm::data("myset"), Comm::data("d")); + Store::remove_from_set(h, Comm::data("myset"), Comm::data("b")); + Store::push_left(h, Comm::data("myvec"), dv(Comm::data("delta"))); + Store::push_right(h, Comm::data("myvec"), dv(Comm::data("omega"))); + do_lookup("one"); + do_lookup("two"); + do_lookup("myset"); + do_lookup("four"); + do_lookup("myvec"); + }