Api server test for dispatch operator#128
Conversation
| }; | ||
|
|
||
| TEST_F(ApiServerTest, BasicDispacher) { | ||
| BasicDispatcher(); |
There was a problem hiding this comment.
Hmm... Do you have to put the whole test into a static function in the fixture? Would it make more sense to add functions to create and invoke the dispatcher instead? Also below.
There was a problem hiding this comment.
The problem is that HttpServer, Handler, HandlerMap, and even Dispatcher, are all declared private. We could attempt to pull out small portions of the test, but that seems confusing and difficult without any gain.
There was a problem hiding this comment.
It should be enough to expose a Dispatcher test factory and an invoker, e.g.:
class ApiServerTest : public ::testing::Test {
protected:
using Dispatcher = MetadataApiServer::Dispatcher;
std::unique_ptr<Dispatcher> CreateDispatcher(
const std::map<std::pair<std::string, std::string>,
std::function<void()>>& handlers) {
Dispatcher::HandlerMap handler_map;
for (const auto& element : handlers) {
std::function<void()> handler = element.second;
handler_map.emplace(element.first, [handler](
const MetadataApiServer::HttpServer::request& request,
std::shared_ptr<MetadataApiServer::HttpServer::connection> conn) {
handler();
});
}
return std::unique_ptr<Dispatcher>(new Dispatcher(handler_map, false));
}
void InvokeDispatcher(
const std:: unique_ptr<Dispatcher>& dispatcher,
const std::string& method, const std::string& path) {
MetadataApiServer::HttpServer::request request;
request.method = method;
request.destination = path;
(*dispatcher)(request, nullptr);
}Then you can use the following in the test, e.g.:
bool handler_called;
std:: unique_ptr<Dispatcher> dispatcher = CreateDispatcher({
{{"GET", "/testPath/"}, [&handler_called]() {
handler_called = true;
}},
});
InvokeDispatcher(dispatcher, "GET", "/testPathFoo/");
EXPECT_FALSE(handler_called);
InvokeDispatcher(dispatcher, "GET", "/test/");
EXPECT_FALSE(handler_called);
InvokeDispatcher(dispatcher, "GET", "/testFooPath/");
EXPECT_FALSE(handler_called);There was a problem hiding this comment.
Very cool, changed, much better.
| protected: | ||
| MetadataStoreTest() : config(), store(config) {} | ||
|
|
||
| std::map<MonitoredResource, MetadataStore::Metadata> GetMetadataMap() const { |
There was a problem hiding this comment.
Why is this needed? Isn't GetMetadataMap public?
There was a problem hiding this comment.
Backed out these changes - sorry about that, I should have remembered before pushing.
| }; | ||
|
|
||
| TEST_F(ApiServerTest, BasicDispacher) { | ||
| BasicDispatcher(); |
There was a problem hiding this comment.
It should be enough to expose a Dispatcher test factory and an invoker, e.g.:
class ApiServerTest : public ::testing::Test {
protected:
using Dispatcher = MetadataApiServer::Dispatcher;
std::unique_ptr<Dispatcher> CreateDispatcher(
const std::map<std::pair<std::string, std::string>,
std::function<void()>>& handlers) {
Dispatcher::HandlerMap handler_map;
for (const auto& element : handlers) {
std::function<void()> handler = element.second;
handler_map.emplace(element.first, [handler](
const MetadataApiServer::HttpServer::request& request,
std::shared_ptr<MetadataApiServer::HttpServer::connection> conn) {
handler();
});
}
return std::unique_ptr<Dispatcher>(new Dispatcher(handler_map, false));
}
void InvokeDispatcher(
const std:: unique_ptr<Dispatcher>& dispatcher,
const std::string& method, const std::string& path) {
MetadataApiServer::HttpServer::request request;
request.method = method;
request.destination = path;
(*dispatcher)(request, nullptr);
}Then you can use the following in the test, e.g.:
bool handler_called;
std:: unique_ptr<Dispatcher> dispatcher = CreateDispatcher({
{{"GET", "/testPath/"}, [&handler_called]() {
handler_called = true;
}},
});
InvokeDispatcher(dispatcher, "GET", "/testPathFoo/");
EXPECT_FALSE(handler_called);
InvokeDispatcher(dispatcher, "GET", "/test/");
EXPECT_FALSE(handler_called);
InvokeDispatcher(dispatcher, "GET", "/testFooPath/");
EXPECT_FALSE(handler_called);| class ApiServerTest : public ::testing::Test { | ||
| protected: | ||
| static void BasicDispatcher() { | ||
| bool handler_called; |
There was a problem hiding this comment.
Did you forget to initialize this? Also below.
|
|
||
| private: | ||
| friend class ApiServerTest; | ||
|
|
There was a problem hiding this comment.
There is actually a bug in line 43 of api_server.cc — reverse iterators should still be incremented with ++. Can you please change --it to ++it?
|
|
||
| private: | ||
| friend class ApiServerTest; | ||
|
|
There was a problem hiding this comment.
Another thing we can clean up here is making both operator() and log() const in Dispatcher. Can you please do this?
igorpeshansky
left a comment
There was a problem hiding this comment.
This is looking better. Some more comments.
| } | ||
|
|
||
| void InvokeDispatcher( | ||
| const std:: unique_ptr<Dispatcher>& dispatcher, |
There was a problem hiding this comment.
Sigh, I thought I've caught them all... That's what I get for typing in code on my phone.
Let's remove the space after the ::.
There was a problem hiding this comment.
Sorry - I should have caught this myself
| } | ||
| }; | ||
|
|
||
| TEST_F(ApiServerTest, BasicDispacher) { |
There was a problem hiding this comment.
How about better test names? I'd call this one DispatcherMatchesFullPath.
| handler_called = true; | ||
| }}, | ||
| {{"GET", "/badPath/"}, [&handler_called]() { | ||
| handler_called = false; |
There was a problem hiding this comment.
There's not enough signal here (e.g., imagine if the implementation accidentally called every handler — if this one got called first, you'd never know). How about adding a bad_handler_called boolean for this one (and setting it to true in the handler)?
There was a problem hiding this comment.
Makes sense, added.
| EXPECT_TRUE(handler_called); | ||
| } | ||
|
|
||
| TEST_F(ApiServerTest, DispatcherMethodCheck) { |
There was a problem hiding this comment.
How about DispatcherUnmatchedMethod?
| EXPECT_FALSE(handler_called); | ||
| } | ||
|
|
||
| TEST_F(ApiServerTest, DispatcherSubstringCheck) { |
There was a problem hiding this comment.
Should this also check that an actual substring does match (e.g., /testPath/subPath/)?
igorpeshansky
left a comment
There was a problem hiding this comment.
LGTM ![]()
Does this need rebasing against master?
supriyagarg
left a comment
There was a problem hiding this comment.
A rebase against master is required, but otherwise LGTM.
7e9b10a to
dab7c88
Compare
|
Rebased |
dab7c88 to
40965ca
Compare
| EXPECT_FALSE(handler_called); | ||
| InvokeDispatcher(dispatcher, "GET", "/testFooPath/"); | ||
| EXPECT_FALSE(handler_called); | ||
| InvokeDispatcher(dispatcher, "GET", "/testPath/subPath"); |
There was a problem hiding this comment.
Should this have been "/testPath/subPath/" (note the trailing /)?
This is a fresh attempt at testing the API server. See PR #123 for previous try.