diff options
author | Arne Juul <arnej@verizonmedia.com> | 2021-08-05 09:29:42 +0000 |
---|---|---|
committer | Arne Juul <arnej@verizonmedia.com> | 2021-08-05 09:31:25 +0000 |
commit | 82f5ee6ef74f0d6a2b97ae72cc40a55fab80d737 (patch) | |
tree | 083dc53089f403795f40f0ac9de12e089a97d59b | |
parent | 138c0bf924b4d4def788d65d418837e0dbd9fbe8 (diff) |
add unit test for UnionServiceMap
-rw-r--r-- | slobrok/CMakeLists.txt | 1 | ||||
-rw-r--r-- | slobrok/src/tests/union_service_map/CMakeLists.txt | 9 | ||||
-rw-r--r-- | slobrok/src/tests/union_service_map/union_service_map_test.cpp | 180 | ||||
-rw-r--r-- | slobrok/src/vespa/slobrok/server/service_mapping.h | 4 | ||||
-rw-r--r-- | slobrok/src/vespa/slobrok/server/union_service_map.cpp | 1 |
5 files changed, 195 insertions, 0 deletions
diff --git a/slobrok/CMakeLists.txt b/slobrok/CMakeLists.txt index 00ddf7296ca..153a029e74d 100644 --- a/slobrok/CMakeLists.txt +++ b/slobrok/CMakeLists.txt @@ -25,4 +25,5 @@ vespa_define_module( src/tests/standalone src/tests/startsome src/tests/startup + src/tests/union_service_map ) diff --git a/slobrok/src/tests/union_service_map/CMakeLists.txt b/slobrok/src/tests/union_service_map/CMakeLists.txt new file mode 100644 index 00000000000..523294742f2 --- /dev/null +++ b/slobrok/src/tests/union_service_map/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(slobrok_union_service_map_test_app TEST + SOURCES + union_service_map_test.cpp + DEPENDS + slobrok_slobrokserver + GTest::GTest +) +vespa_add_test(NAME slobrok_union_service_map_test_app COMMAND slobrok_union_service_map_test_app) diff --git a/slobrok/src/tests/union_service_map/union_service_map_test.cpp b/slobrok/src/tests/union_service_map/union_service_map_test.cpp new file mode 100644 index 00000000000..5f1f70fb9fb --- /dev/null +++ b/slobrok/src/tests/union_service_map/union_service_map_test.cpp @@ -0,0 +1,180 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/slobrok/server/union_service_map.h> +#include <vespa/vespalib/gtest/gtest.h> +#include <vespa/vespalib/util/stringfmt.h> + +using namespace vespalib; +using namespace slobrok; +using vespalib::make_string_short::fmt; + +enum class Event { NONE, ADD, REMOVE, UPDATE }; + +struct MapObserver : public MapListener { + MapObserver(); + virtual ~MapObserver(); + void add(const ServiceMapping &mapping) override; + void remove(const ServiceMapping &mapping) override; + void update(const ServiceMapping &old_mapping, + const ServiceMapping &new_mapping) override; + + Event last_event = Event::NONE; + ServiceMapping last_add = {{}, {}}; + ServiceMapping last_remove = {{}, {}}; + + void clear() { last_event = Event::NONE; } +}; + +MapObserver::MapObserver() = default; +MapObserver::~MapObserver() = default; + +void MapObserver::add(const ServiceMapping &mapping) { + last_event = Event::ADD; + last_add = mapping; +} + +void MapObserver::remove(const ServiceMapping &mapping) { + last_event = Event::REMOVE; + last_remove = mapping; +} + +void MapObserver::update(const ServiceMapping &old_mapping, + const ServiceMapping &new_mapping) +{ + last_event = Event::UPDATE; + last_remove = old_mapping; + last_add = new_mapping; +} + +TEST(UnionServiceMapTest, forwards_simple_requests) { + ProxyMapSource source; + UnionServiceMap unionizer; + MapObserver observer; + unionizer.registerListener(observer); + source.registerListener(unionizer); + + EXPECT_EQ(observer.last_event, Event::NONE); + + ServiceMapping one{"foo/1", "bar/1"}; + source.add(one); + EXPECT_EQ(observer.last_event, Event::ADD); + EXPECT_EQ(observer.last_add, one); + ServiceMapping two{"foo/2", "bar/2"}; + source.add(two); + EXPECT_EQ(observer.last_event, Event::ADD); + EXPECT_EQ(observer.last_add, two); + + source.remove(one); + EXPECT_EQ(observer.last_event, Event::REMOVE); + EXPECT_EQ(observer.last_remove, one); + + ServiceMapping two_q{"foo/2", "qux/2"}; + source.update(two, two_q); + // update implemented ass remove+add: + EXPECT_EQ(observer.last_event, Event::ADD); + EXPECT_EQ(observer.last_remove, two); + EXPECT_EQ(observer.last_add, two_q); +} + +TEST(UnionServiceMapTest, handles_refcount) { + ProxyMapSource source1; + ProxyMapSource source2; + ProxyMapSource source3; + UnionServiceMap unionizer; + MapObserver observer; + unionizer.registerListener(observer); + source1.registerListener(unionizer); + source2.registerListener(unionizer); + source3.registerListener(unionizer); + + EXPECT_EQ(observer.last_event, Event::NONE); + ServiceMapping one{"foo/1", "bar/1"}; + source1.add(one); + EXPECT_EQ(observer.last_event, Event::ADD); + EXPECT_EQ(observer.last_add, one); + observer.clear(); + EXPECT_EQ(observer.last_event, Event::NONE); + source2.add(one); + EXPECT_EQ(observer.last_event, Event::NONE); + source3.add(one); + EXPECT_EQ(observer.last_event, Event::NONE); + ServiceMapping two{"foo/2", "bar/2"}; + source1.add(two); + EXPECT_EQ(observer.last_event, Event::ADD); + EXPECT_EQ(observer.last_add, two); + observer.clear(); + EXPECT_EQ(observer.last_event, Event::NONE); + source2.add(two); + EXPECT_EQ(observer.last_event, Event::NONE); + + source1.remove(one); + EXPECT_EQ(observer.last_event, Event::NONE); + source2.remove(one); + EXPECT_EQ(observer.last_event, Event::NONE); + + source1.remove(two); + EXPECT_EQ(observer.last_event, Event::NONE); + source2.remove(two); + EXPECT_EQ(observer.last_event, Event::REMOVE); + EXPECT_EQ(observer.last_remove, two); + + observer.clear(); + EXPECT_EQ(observer.last_event, Event::NONE); + source3.remove(one); + EXPECT_EQ(observer.last_event, Event::REMOVE); + EXPECT_EQ(observer.last_remove, one); +} + +TEST(UnionServiceMapTest, handles_conflicts) { + ProxyMapSource source1; + ProxyMapSource source2; + ProxyMapSource source3; + UnionServiceMap unionizer; + MapObserver observer; + unionizer.registerListener(observer); + source1.registerListener(unionizer); + source2.registerListener(unionizer); + source3.registerListener(unionizer); + + EXPECT_EQ(observer.last_event, Event::NONE); + ServiceMapping one{"foo/1", "bar/1"}; + source1.add(one); + EXPECT_EQ(observer.last_event, Event::ADD); + EXPECT_EQ(observer.last_add, one); + observer.clear(); + source2.add(one); + EXPECT_EQ(observer.last_event, Event::NONE); + + ServiceMapping two{"foo/2", "bar/2"}; + source1.add(two); + EXPECT_EQ(observer.last_event, Event::ADD); + EXPECT_EQ(observer.last_add, two); + observer.clear(); + source2.add(two); + EXPECT_EQ(observer.last_event, Event::NONE); + + ServiceMapping one_q{"foo/1", "qux/1"}; + source3.add(one_q); + EXPECT_EQ(observer.last_event, Event::REMOVE); + EXPECT_EQ(observer.last_remove, one); + + ServiceMapping two_q{"foo/2", "qux/2"}; + source3.add(two_q); + EXPECT_EQ(observer.last_event, Event::REMOVE); + EXPECT_EQ(observer.last_remove, two); + + source3.remove(one_q); + EXPECT_EQ(observer.last_event, Event::ADD); + EXPECT_EQ(observer.last_add, one); + + observer.clear(); + source1.remove(two); + EXPECT_EQ(observer.last_event, Event::NONE); + source2.remove(two); + EXPECT_EQ(observer.last_event, Event::ADD); + EXPECT_EQ(observer.last_add, two_q); +} + + +GTEST_MAIN_RUN_ALL_TESTS() + diff --git a/slobrok/src/vespa/slobrok/server/service_mapping.h b/slobrok/src/vespa/slobrok/server/service_mapping.h index 6561c120284..6c540b8e9b5 100644 --- a/slobrok/src/vespa/slobrok/server/service_mapping.h +++ b/slobrok/src/vespa/slobrok/server/service_mapping.h @@ -12,6 +12,10 @@ struct ServiceMapping { vespalib::string spec; ServiceMapping(const vespalib::string & name_, const vespalib::string & spec_) noexcept : name(name_), spec(spec_) { } ~ServiceMapping(); + + bool operator== (const ServiceMapping &other) const { + return name == other.name && spec == other.spec; + } }; typedef std::vector<ServiceMapping> ServiceMappingList; diff --git a/slobrok/src/vespa/slobrok/server/union_service_map.cpp b/slobrok/src/vespa/slobrok/server/union_service_map.cpp index 226a0e0fa4b..f3d63f2a087 100644 --- a/slobrok/src/vespa/slobrok/server/union_service_map.cpp +++ b/slobrok/src/vespa/slobrok/server/union_service_map.cpp @@ -74,6 +74,7 @@ void UnionServiceMap::remove(const ServiceMapping &mapping) void UnionServiceMap::update(const ServiceMapping &old_mapping, const ServiceMapping &new_mapping) { + LOG_ASSERT(old_mapping.name == new_mapping.name); remove(old_mapping); add(new_mapping); } |