#include <string>
#include "flow/flow_stash.h"
+#include "pub_sub/stash_events.h"
#include <CppUTest/CommandLineTestRunner.h>
#include <CppUTest/TestHarness.h>
using namespace snort;
using namespace std;
+
+static DataBus* DB = nullptr;
+
class TestStashObject : public StashGenericObject
{
public:
}
};
+
+template<class Type>
+class DBConsumer : public DataHandler
+{
+public:
+
+ static const char* STASH_EVENT;
+
+ // event we'll be listening to on the DataBus:
+ // static constexpr char STASH_EVENT[] = "foo.stash.event";
+
+ DBConsumer(const char* mod_name) : DataHandler(mod_name) {}
+
+ void handle(DataEvent& e, Flow*) override
+ {
+ const StashEvent* se = static_cast<const StashEvent*>(&e);
+ se->get_item()->get_val(value);
+ }
+
+ Type get_from_stash(FlowStash& stash)
+ {
+ stash.get(STASH_EVENT, value);
+ return value;
+ }
+
+ Type get_value() const { return value; }
+
+private:
+ Type value;
+};
+
+template<class Type>
+const char* DBConsumer<Type>::STASH_EVENT = "foo.stash.event";
+
+
+
+// DataBus mock: most functions are stubs, but _subscribe() and _publish()
+// are (close to) real.
+DataBus::DataBus() = default;
+
+DataBus::~DataBus()
+{
+ for ( auto& p : map )
+ for ( auto* h : p.second )
+ delete h;
+}
+
+void DataBus::add_mapped_module(const char*) {}
+void DataBus::clone(DataBus& ) {}
+void DataBus::subscribe(const char* key, DataHandler* h)
+{
+ DB->_subscribe(key, h);
+}
+void DataBus::subscribe_default(const char* key, DataHandler* h)
+{
+ DB->_subscribe(key, h);
+}
+
+void DataBus::unsubscribe(const char*, DataHandler*) {}
+void DataBus::unsubscribe_default(const char*, DataHandler*) {}
+
+void DataBus::publish(const char* key, DataEvent& e, Flow* f)
+{
+ DB->_publish(key, e, f);
+}
+
+void DataBus::publish(const char*, const uint8_t*, unsigned, Flow*) {}
+void DataBus::publish(const char*, Packet*, Flow*) {}
+void DataBus::publish(const char*, void*, int, const uint8_t*) {}
+
+void DataBus::_subscribe(const char* key, DataHandler* h)
+{
+ DataList& v = map[key];
+ v.emplace_back(h);
+}
+
+void DataBus::_unsubscribe(const char*, DataHandler*) {}
+
+void DataBus::_publish(const char* key, DataEvent& e, Flow* f)
+{
+ auto v = map.find(key);
+
+ if ( v != map.end() )
+ {
+ for ( auto* h : v->second )
+ h->handle(e, f);
+ }
+}
+// end DataBus mock.
+
+
+
TEST_GROUP(stash_tests)
{
+ void setup()
+ {
+ DB = new DataBus();
+ }
+ void teardown()
+ {
+ delete DB;
+ }
};
+// DataBus tests
+TEST(stash_tests, data_bus_publish_test)
+{
+ typedef int32_t value_t;
+
+ // DB deletes the subscribers so make c a pointer, not a local object.
+ DBConsumer<value_t>* c = new DBConsumer<value_t>("foo");
+ DataBus::subscribe(DBConsumer<value_t>::STASH_EVENT, c);
+
+ FlowStash stash;
+ value_t vin, vout;
+
+ // stash/publish 10
+ vin = 10;
+ stash.store(DBConsumer<value_t>::STASH_EVENT, vin);
+ vout = c->get_value();
+ CHECK_EQUAL(vin, vout);
+
+ // stash/publish 20, with the same key as before
+ vin = 20;
+ stash.store(DBConsumer<value_t>::STASH_EVENT, vin);
+ vout = c->get_value();
+ CHECK_EQUAL(vin, vout);
+
+ // do we get some event that we're not listening to?
+ value_t before = c->get_value();
+ stash.store("bar.stash.event", 30);
+ value_t after = c->get_value();
+ CHECK_EQUAL(before, after);
+
+ // do we still get our own STASH_EVENT from the stash, at a later time?
+ vout = c->get_from_stash(stash);
+ CHECK_EQUAL(vin, vout);
+
+}
+
+
+// Stash tests
TEST(stash_tests, new_int32_item)
{
FlowStash stash;
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2019-2019 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation. You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//--------------------------------------------------------------------------
+// stash_events.h author Silviu Minut <sminut@cisco.com>
+
+#ifndef STASH_EVENTS_H
+#define STASH_EVENTS_H
+
+#include "framework/data_bus.h"
+
+using snort::StashItem;
+
+class StashEvent : public snort::DataEvent
+{
+public:
+ StashEvent(const StashItem* it = nullptr) : item(it) {}
+ const StashItem* get_item() const { return item; }
+private:
+ const StashItem* item;
+};
+
+#endif