Skip to content
This repository was archived by the owner on Aug 19, 2019. It is now read-only.

Conversation

@ACEmilG
Copy link
Contributor

@ACEmilG ACEmilG commented Apr 4, 2018

This is a fresh attempt at testing the API server. See PR #123 for previous try.

};

TEST_F(ApiServerTest, BasicDispacher) {
BasicDispatcher();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor Author

@ACEmilG ACEmilG Apr 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very cool, changed, much better.

protected:
MetadataStoreTest() : config(), store(config) {}

std::map<MonitoredResource, MetadataStore::Metadata> GetMetadataMap() const {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed? Isn't GetMetadataMap public?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backed out these changes - sorry about that, I should have remembered before pushing.

};

TEST_F(ApiServerTest, BasicDispacher) {
BasicDispatcher();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you forget to initialize this? Also below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


private:
friend class ApiServerTest;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed


private:
friend class ApiServerTest;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thing we can clean up here is making both operator() and log() const in Dispatcher. Can you please do this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

@igorpeshansky igorpeshansky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking better. Some more comments.

}

void InvokeDispatcher(
const std:: unique_ptr<Dispatcher>& dispatcher,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ::.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry - I should have caught this myself

}
};

TEST_F(ApiServerTest, BasicDispacher) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about better test names? I'd call this one DispatcherMatchesFullPath.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, changed

handler_called = true;
}},
{{"GET", "/badPath/"}, [&handler_called]() {
handler_called = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, added.

EXPECT_TRUE(handler_called);
}

TEST_F(ApiServerTest, DispatcherMethodCheck) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about DispatcherUnmatchedMethod?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, changed

EXPECT_FALSE(handler_called);
}

TEST_F(ApiServerTest, DispatcherSubstringCheck) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this also check that an actual substring does match (e.g., /testPath/subPath/)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, added

Copy link
Contributor

@igorpeshansky igorpeshansky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM :shipit:

Does this need rebasing against master?

Copy link
Contributor

@supriyagarg supriyagarg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A rebase against master is required, but otherwise LGTM.

@ACEmilG ACEmilG force-pushed the ACEmilG-api-server-test-2 branch from 7e9b10a to dab7c88 Compare April 10, 2018 19:39
@ACEmilG
Copy link
Contributor Author

ACEmilG commented Apr 10, 2018

Rebased

@ACEmilG ACEmilG force-pushed the ACEmilG-api-server-test-2 branch from dab7c88 to 40965ca Compare April 10, 2018 19:58
EXPECT_FALSE(handler_called);
InvokeDispatcher(dispatcher, "GET", "/testFooPath/");
EXPECT_FALSE(handler_called);
InvokeDispatcher(dispatcher, "GET", "/testPath/subPath");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this have been "/testPath/subPath/" (note the trailing /)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Copy link
Contributor

@igorpeshansky igorpeshansky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM :shipit:

@igorpeshansky igorpeshansky merged commit 88b5c43 into master Apr 10, 2018
@igorpeshansky igorpeshansky deleted the ACEmilG-api-server-test-2 branch April 10, 2018 20:11
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants