Esempio n. 1
0
TEST(routeHandleTest, allAsync) {
    vector<std::shared_ptr<TestHandle>> test_handles{
        make_shared<TestHandle>(GetRouteTestData(mc_res_found, "a")),
        make_shared<TestHandle>(GetRouteTestData(mc_res_notfound, "b")),
        make_shared<TestHandle>(GetRouteTestData(mc_res_remote_error, "c"))
    };

    TestFiberManager fm;

    TestRouteHandle<AllAsyncRoute<TestRouteHandleIf>> rh(
                get_route_handles(test_handles));

    fm.runAll(
    {
        [&]() {
            auto op = McOperation<mc_op_get>();
            auto reply = rh.route(McRequest("key"), op);

            /* Check that we got no result back */
            EXPECT_TRUE(reply.result() == mc_res_notfound);
        }
    });

    /* Check that everything is complete in the background */
    for (auto& h : test_handles) {
        EXPECT_TRUE(h->saw_keys == vector<string> {"key"});
    }
}
TEST(routeHandleTest, allMajorityTieTyped) {
  TestFiberManager fm;

  vector<std::shared_ptr<TestHandle>> test_handles{
    make_shared<TestHandle>(GetRouteTestData(mc_res_remote_error, "a")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_notfound, "b")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_notfound, "c")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_remote_error, "d"))
  };

  TestRouteHandle<AllMajorityRoute<TestRouteHandleIf>> rh(
    get_route_handles(test_handles));

  fm.runAll(
    {
      [&]() {
        TypedThriftRequest<cpp2::McGetRequest> req;
        req.setKey("key");

        auto reply = rh.route(req);

        /* Check that we got the _worst_ majority reply */
        EXPECT_TRUE(reply.result() == mc_res_remote_error);
      }
    });

  /* Check that everything is complete */
  for (auto& h : test_handles) {
    EXPECT_EQ(vector<string>{"key"}, h->saw_keys);
  }
}
Esempio n. 3
0
TEST(routeHandleTest, allInitial) {
  vector<std::shared_ptr<TestHandle>> test_handles{
      make_shared<TestHandle>(GetRouteTestData(carbon::Result::FOUND, "a")),
      make_shared<TestHandle>(GetRouteTestData(carbon::Result::NOTFOUND, "b")),
      make_shared<TestHandle>(
          GetRouteTestData(carbon::Result::REMOTE_ERROR, "c")),
  };

  TestFiberManager fm;
  auto routeHandles = get_route_handles(test_handles);
  TestRouteHandle<AllInitialRoute<TestRouteHandleIf>> rh(routeHandles);

  fm.runAll({[&]() {
    auto reply = rh.route(McGetRequest("key"));

    /* Check that we got the initial result back */
    EXPECT_EQ(carbon::Result::FOUND, reply.result());
    EXPECT_EQ("a", carbon::valueRangeSlow(reply).str());
  }});

  /* Check that everything is complete in the background */
  for (auto& h : test_handles) {
    EXPECT_EQ(vector<string>{"key"}, h->saw_keys);
  }

  /* Check that traverse is correct */
  int cnt = 0;
  RouteHandleTraverser<TestRouteHandleIf> t{
      [&cnt](const TestRouteHandleIf&) { ++cnt; }};
  rh.traverse(McGetRequest("key"), t);
  EXPECT_EQ(cnt, routeHandles.size());
}
TEST(routeHandleTest, allSync) {
  vector<std::shared_ptr<TestHandle>> test_handles{
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "a")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_notfound, "b")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_remote_error, "c"))
  };

  TestFiberManager fm;

  TestRouteHandle<AllSyncRoute<TestRouteHandleIf>> rh(
    get_route_handles(test_handles));

  fm.runAll(
    {
      [&]() {
        auto reply = rh.route(McRequestWithMcOp<mc_op_get>("key"));

        /* Check that we got the worst result back */
        EXPECT_TRUE(reply.result() == mc_res_remote_error);
        EXPECT_TRUE(toString(reply.value()) == "c");

        for (auto& h : test_handles) {
          EXPECT_TRUE(h->saw_keys == vector<string>{"key"});
        }
      }
    });
}
TEST(routeHandleTest, hashSalt) {
  vector<std::shared_ptr<TestHandle>> test_handles{
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "a")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "b")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "c")),
  };

  TestFiberManager fm;

  TestRouteHandle<HashRoute<TestRouteHandleIf, HashFunc>> rh(
    get_route_handles(test_handles),
    /* salt= */ "1",
    HashFunc(test_handles.size()));

  fm.run([&]() {
      auto reply = rh.route(McRequestWithMcOp<mc_op_get>("0"));
      /* 01 % 3 == 1 */
      EXPECT_TRUE(toString(reply.value()) == "b");
    });

  fm.run([&]() {
      auto reply = rh.route(McRequestWithMcOp<mc_op_get>("1"));
      /* 11 % 3 == 2 */
      EXPECT_TRUE(toString(reply.value()) == "c");
    });

  fm.run([&]() {
      auto reply = rh.route(McRequestWithMcOp<mc_op_get>("2"));
      /* 21 % 3 == 0 */
      EXPECT_TRUE(toString(reply.value()) == "a");
    });
}
Esempio n. 6
0
TEST(routeHandleTest, allSyncTyped) {
  vector<std::shared_ptr<TestHandle>> test_handles{
      make_shared<TestHandle>(GetRouteTestData(carbon::Result::FOUND, "a")),
      make_shared<TestHandle>(GetRouteTestData(carbon::Result::NOTFOUND, "b")),
      make_shared<TestHandle>(
          GetRouteTestData(carbon::Result::REMOTE_ERROR, "c"))};

  TestFiberManager fm;

  TestRouteHandle<AllSyncRoute<TestRouteHandleIf>> rh(
      get_route_handles(test_handles));

  fm.runAll({[&]() {
    McGetRequest req("key");

    auto reply = rh.route(req);

    /* Check that we got the worst result back */
    EXPECT_EQ(carbon::Result::REMOTE_ERROR, reply.result());
    EXPECT_EQ("c", coalesceAndGetRange(reply.value()).str());

    for (auto& h : test_handles) {
      EXPECT_EQ(vector<string>{"key"}, h->saw_keys);
    }
  }});
}
TEST(ReliablePoolRouteTest, deleteOps) {
  counter = 0;
  vector<std::shared_ptr<TestHandle>> saltedHandle{
    make_shared<TestHandle>(DeleteRouteTestData(mc_res_found)),
    make_shared<TestHandle>(DeleteRouteTestData(mc_res_notfound)),
    make_shared<TestHandle>(DeleteRouteTestData(mc_res_found)),
  };

  TestFiberManager fm;

  fm.runAll(
    {
      [&] () {
        TestRouteHandle<ReliablePoolRoute<TestRouteHandleIf, HashFunc>> rh(
          get_route_handles(saltedHandle),
          HashFunc(saltedHandle.size()),
          "", 5);

        auto reply = rh.routeSimple(McRequest("key"),
                                    McOperation<mc_op_delete>());

        // Get the most awfull reply
        EXPECT_EQ(reply.result(), mc_res_notfound);
      }
    });
  EXPECT_TRUE(saltedHandle[0]->saw_keys == (vector<std::string>{"key", "key"}));
  EXPECT_TRUE(saltedHandle[1]->saw_keys == (vector<std::string>{"key", "key"}));
  EXPECT_TRUE(saltedHandle[2]->saw_keys == (vector<std::string>{"key", "key"}));
}
TEST(routeHandleTest, allInitial) {
  vector<std::shared_ptr<TestHandle>> test_handles{
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "a")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_notfound, "b")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_remote_error, "c")),
  };

  TestFiberManager fm;
  auto routeHandles = get_route_handles(test_handles);
  TestRouteHandle<AllInitialRoute<TestRouteHandleIf>> rh(routeHandles);

  fm.runAll(
    {
      [&]() {
        auto reply = rh.route(McRequestWithMcOp<mc_op_get>("key"));

        /* Check that we got the initial result back */
        EXPECT_TRUE(reply.result() == mc_res_found);
        EXPECT_TRUE(toString(reply.value()) == "a");
      }
    });

  /* Check that everything is complete in the background */
  for (auto& h : test_handles) {
    EXPECT_TRUE(h->saw_keys == vector<string>{"key"});
  }

  /* Check that traverse is correct */
  int cnt = 0;
  RouteHandleTraverser<TestRouteHandleIf> t{
    [&cnt](const TestRouteHandleIf&){ ++cnt; }
  };
  rh.traverse(McRequestWithMcOp<mc_op_get>("key"), t);
  EXPECT_EQ(cnt, routeHandles.size());
}
TEST(routeHandleTest, allMajorityTie) {
  TestFiberManager fm;

  vector<std::shared_ptr<TestHandle>> test_handles{
    make_shared<TestHandle>(GetRouteTestData(mc_res_remote_error, "a")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_notfound, "b")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_notfound, "c")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_remote_error, "d"))
  };

  TestRouteHandle<AllMajorityRoute<TestRouteHandleIf>> rh(
    get_route_handles(test_handles));

  fm.runAll(
    {
      [&]() {
        auto reply = rh.route(McRequestWithMcOp<mc_op_get>("key"));

        /* Check that we got the _worst_ majority reply */
        EXPECT_TRUE(reply.result() == mc_res_remote_error);
      }
    });

  /* Check that everything is complete */
  for (auto& h : test_handles) {
    EXPECT_TRUE(h->saw_keys == vector<string>{"key"});
  }
}
Esempio n. 10
0
TEST(routeHandleTest, allSyncTyped) {
  vector<std::shared_ptr<TestHandle>> test_handles{
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "a")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_notfound, "b")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_remote_error, "c"))
  };

  TestFiberManager fm;

  TestRouteHandle<AllSyncRoute<TestRouteHandleIf>> rh(
    get_route_handles(test_handles));

  fm.runAll(
    {
      [&]() {
        TypedThriftRequest<cpp2::McGetRequest> req;
        req.setKey("key");

        auto reply = rh.route(req);

        /* Check that we got the worst result back */
        EXPECT_EQ(mc_res_remote_error, reply.result());
        EXPECT_EQ("c", toString(*reply->get_value()));

        for (auto& h : test_handles) {
          EXPECT_EQ(vector<string>{"key"}, h->saw_keys);
        }
      }
    });
}
TEST(BigValueRouteTest, smallvalue) {
  // for small values, this route handle simply passes it to child route handle
  vector<std::shared_ptr<TestHandle>> test_handles{
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "a"),
                            UpdateRouteTestData(mc_res_stored),
                            DeleteRouteTestData(mc_res_deleted))
  };
  auto route_handles = get_route_handles(test_handles);
  TestFiberManager fm;

  fm.runAll({
    [&]() {
      McrouterRouteHandle<BigValueRoute> rh(route_handles[0], opts);

      std::string key = "key_get";
      auto msg = createMcMsgRef(key, "value");
      msg->op = mc_op_get;
      McRequestWithMcOp<mc_op_get> req_get(std::move(msg));
      auto f_get = rh.route(req_get);

      EXPECT_EQ("a", toString(f_get.value()));
      EXPECT_EQ(test_handles[0]->saw_keys, vector<std::string>{"key_get"});
      test_handles[0]->saw_keys.clear();

      std::string key_set = "key_set";
      auto msg_set = createMcMsgRef(key_set, "value");
      msg_set->op = mc_op_set;
      McRequestWithMcOp<mc_op_set> req_set(std::move(msg_set));
      auto f_set = rh.route(req_set);
      EXPECT_EQ(mc_res_stored, f_set.result());
      EXPECT_EQ(test_handles[0]->saw_keys, vector<std::string>{"key_set"});
    }
  });
}
Esempio n. 12
0
TEST(routeHandleTest, hashSaltTyped) {
  vector<std::shared_ptr<TestHandle>> test_handles{
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "a")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "b")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "c")),
  };

  TestFiberManager fm;

  TestRouteHandle<HashRoute<TestRouteHandleIf, HashFunc>> rh(
    get_route_handles(test_handles),
    /* salt= */ "1",
    HashFunc(test_handles.size()));

  fm.run([&]() {
      TypedThriftRequest<cpp2::McGetRequest> req;
      req.setKey("0");

      auto reply = rh.route(req);
      /* 01 % 3 == 1 */
      EXPECT_EQ("b", toString(*reply->get_value()));
    });

  fm.run([&]() {
      TypedThriftRequest<cpp2::McGetRequest> req;
      req.setKey("1");

      auto reply = rh.route(req);
      /* 11 % 3 == 2 */
      EXPECT_EQ("c", toString(*reply->get_value()));
    });

  fm.run([&]() {
      TypedThriftRequest<cpp2::McGetRequest> req;
      req.setKey("2");

      auto reply = rh.route(req);
      /* 21 % 3 == 0 */
      EXPECT_EQ("a", toString(*reply->get_value()));
    });
}
Esempio n. 13
0
TEST(routeHandleTest, allFastestTyped) {
  TestFiberManager fm;

  vector<std::shared_ptr<TestHandle>> test_handles{
    make_shared<TestHandle>(GetRouteTestData(mc_res_remote_error, "a")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_notfound, "b")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "c"))
  };

  TestRouteHandle<AllFastestRoute<TestRouteHandleIf>> rh(
    get_route_handles(test_handles));

  test_handles[1]->pause();

  fm.runAll(
    {
      [&]() {
        TypedThriftRequest<cpp2::McGetRequest> req;
        req.setKey("key");

        auto reply = rh.route(req);

        /* Check that we got the fastest non-error result back
           ('b' is paused) */
        EXPECT_EQ(mc_res_found, reply.result());
        EXPECT_EQ("c", toString(*reply->get_value()));

        EXPECT_EQ(vector<string>{"key"}, test_handles[0]->saw_keys);
        EXPECT_EQ(vector<string>{}, test_handles[1]->saw_keys);
        EXPECT_EQ(vector<string>{"key"}, test_handles[2]->saw_keys);

        test_handles[1]->unpause();
     }
    });

  /* Check that everything is complete in the background */
  for (auto& h : test_handles) {
    EXPECT_EQ(vector<string>{"key"}, h->saw_keys);
  }
}
Esempio n. 14
0
TEST(routeHandleTest, allMajorityTyped) {
  TestFiberManager fm;

  vector<std::shared_ptr<TestHandle>> test_handles{
    make_shared<TestHandle>(GetRouteTestData(mc_res_remote_error, "a")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_notfound, "b")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_remote_error, "c"))
  };

  TestRouteHandle<AllMajorityRoute<TestRouteHandleIf>> rh(
    get_route_handles(test_handles));

  test_handles[1]->pause();

  fm.runAll(
    {
      [&]() {
        TypedThriftRequest<cpp2::McGetRequest> req;
        req.setKey("key");

        auto reply = rh.route(req);

        /* Check that we got the majority reply
           without waiting for "b", which is paused */
        EXPECT_TRUE(reply.result() == mc_res_remote_error);

        EXPECT_TRUE(test_handles[0]->saw_keys == vector<string>{"key"});
        EXPECT_TRUE(test_handles[1]->saw_keys == vector<string>{});
        EXPECT_TRUE(test_handles[2]->saw_keys == vector<string>{"key"});

        test_handles[1]->unpause();
      }
    });

  /* Check that everything is complete in the background */
  for (auto& h : test_handles) {
    EXPECT_TRUE(h->saw_keys == vector<string>{"key"});
  }
}
Esempio n. 15
0
TEST(routeHandleTest, allInitialTyped) {
  vector<std::shared_ptr<TestHandle>> test_handles{
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "a")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_notfound, "b")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_remote_error, "c")),
  };

  TestFiberManager fm;
  auto routeHandles = get_route_handles(test_handles);
  TestRouteHandle<AllInitialRoute<TestRouteHandleIf>> rh(routeHandles);

  TypedThriftRequest<cpp2::McGetRequest> req;
  req.setKey("key");

  fm.runAll(
    {
      [&]() {
        auto reply = rh.route(req);

        /* Check that we got the initial result back */
        EXPECT_EQ(mc_res_found, reply.result());
        EXPECT_EQ("a", toString(*reply->get_value()));
      }
    });

  /* Check that everything is complete in the background */
  for (auto& h : test_handles) {
    EXPECT_EQ(vector<string>{"key"}, h->saw_keys);
  }

  /* Check that traverse is correct */
  int cnt = 0;
  RouteHandleTraverser<TestRouteHandleIf> t{
    [&cnt](const TestRouteHandleIf&){ ++cnt; }
  };
  rh.traverse(req, t);
  EXPECT_EQ(cnt, routeHandles.size());
}
Esempio n. 16
0
TEST(routeHandleTest, allFastest) {
  TestFiberManager fm;

  vector<std::shared_ptr<TestHandle>> test_handles{
    make_shared<TestHandle>(GetRouteTestData(mc_res_remote_error, "a")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_notfound, "b")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "c"))
  };

  TestRouteHandle<AllFastestRoute<TestRouteHandleIf>> rh(
    get_route_handles(test_handles));

  test_handles[1]->pause();

  fm.runAll(
    {
      [&]() {
        auto reply = rh.route(McRequestWithMcOp<mc_op_get>("key"));

        /* Check that we got the fastest non-error result back
           ('b' is paused) */
        EXPECT_TRUE(reply.result() == mc_res_found);
        EXPECT_TRUE(toString(reply.value()) == "c");

        EXPECT_TRUE(test_handles[0]->saw_keys == vector<string>{"key"});
        EXPECT_TRUE(test_handles[1]->saw_keys == vector<string>{});
        EXPECT_TRUE(test_handles[2]->saw_keys == vector<string>{"key"});

        test_handles[1]->unpause();
     }
    });

  /* Check that everything is complete in the background */
  for (auto& h : test_handles) {
    EXPECT_TRUE(h->saw_keys == vector<string>{"key"});
  }
}
Esempio n. 17
0
TEST(routeHandleTest, allAsync) {
  vector<std::shared_ptr<TestHandle>> test_handles{
      make_shared<TestHandle>(GetRouteTestData(carbon::Result::FOUND, "a")),
      make_shared<TestHandle>(GetRouteTestData(carbon::Result::NOTFOUND, "b")),
      make_shared<TestHandle>(
          GetRouteTestData(carbon::Result::REMOTE_ERROR, "c"))};

  TestFiberManager fm;

  TestRouteHandle<AllAsyncRoute<TestRouteHandleIf>> rh(
      get_route_handles(test_handles));

  fm.runAll({[&]() {
    auto reply = rh.route(McGetRequest("key"));

    /* Check that we got no result back */
    EXPECT_EQ(carbon::Result::NOTFOUND, reply.result());
  }});

  /* Check that everything is complete in the background */
  for (auto& h : test_handles) {
    EXPECT_EQ(vector<string>{"key"}, h->saw_keys);
  }
}
Esempio n. 18
0
TEST(shadowRouteTest, defaultPolicy) {
  vector<std::shared_ptr<TestHandle>> normalHandle{
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "a")),
  };
  auto normalRh = get_route_handles(normalHandle)[0];

  vector<std::shared_ptr<TestHandle>> shadowHandles{
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "b")),
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "c")),
  };

  TestFiberManager fm;

  auto data = make_shared<proxy_pool_shadowing_policy_t::Data>();
  vector<std::shared_ptr<proxy_pool_shadowing_policy_t>> settings {
    make_shared<proxy_pool_shadowing_policy_t>(data, nullptr),
    make_shared<proxy_pool_shadowing_policy_t>(data, nullptr),
  };

  auto shadowRhs = get_route_handles(shadowHandles);
  ShadowData<TestRouteHandleIf> shadowData = {
    {std::move(shadowRhs[0]), std::move(settings[0])},
    {std::move(shadowRhs[1]), std::move(settings[1])},
  };

  TestRouteHandle<ShadowRoute<TestRouteHandleIf, DefaultShadowPolicy>> rh(
    normalRh,
    std::move(shadowData),
    0,
    DefaultShadowPolicy());

  fm.runAll(
    {
      [&] () {
        auto reply = rh.route(McRequest("key"),
                              McOperation<mc_op_get>());

        EXPECT_TRUE(reply.result() == mc_res_found);
        EXPECT_TRUE(toString(reply.value()) == "a");
      }
    });

  EXPECT_TRUE(shadowHandles[0]->saw_keys.empty());
  EXPECT_TRUE(shadowHandles[1]->saw_keys.empty());
  data->end_index = 1;
  data->end_key_fraction = 1.0;

  fm.runAll(
    {
      [&] () {
        auto reply = rh.route(McRequest("key"),
                              McOperation<mc_op_get>());

        EXPECT_TRUE(reply.result() == mc_res_found);
        EXPECT_TRUE(toString(reply.value()) == "a");
      }
    });

  EXPECT_TRUE(shadowHandles[0]->saw_keys == vector<string>{"key"});
  EXPECT_TRUE(shadowHandles[1]->saw_keys == vector<string>{"key"});
}
Esempio n. 19
0
TEST(warmUpRouteTest, warmUp) {
  vector<std::shared_ptr<TestHandle>> test_handles{
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "a"),
                            UpdateRouteTestData(mc_res_stored),
                            DeleteRouteTestData(mc_res_deleted)),
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "b"),
                            UpdateRouteTestData(mc_res_stored),
                            DeleteRouteTestData(mc_res_notfound)),
    make_shared<TestHandle>(GetRouteTestData(mc_res_notfound, ""),
                            UpdateRouteTestData(mc_res_notstored),
                            DeleteRouteTestData(mc_res_notfound)),
  };
  auto route_handles = get_route_handles(test_handles);

  TestFiberManager fm;

  fm.run([&]() {
    TestRouteHandle<WarmUpRoute<TestRouteHandleIf>> rh(
      route_handles[0], route_handles[1], 1);

    auto reply_get = rh.route(
        McRequestWithMcOp<mc_op_get>("key_get"));
    EXPECT_TRUE("b" == toString(reply_get.value()));
    EXPECT_TRUE(vector<string>{"key_get"} != test_handles[0]->saw_keys);
    EXPECT_TRUE(vector<string>{"key_get"} == test_handles[1]->saw_keys);
    (test_handles[0]->saw_keys).clear();
    (test_handles[1]->saw_keys).clear();

    auto reply_del = rh.route(
        McRequestWithMcOp<mc_op_delete>("key_del"));
    EXPECT_TRUE(mc_res_notfound == reply_del.result());
    EXPECT_TRUE(vector<string>{"key_del"} != test_handles[0]->saw_keys);
    EXPECT_TRUE(vector<string>{"key_del"} == test_handles[1]->saw_keys);
  });
  fm.run([&]() {
    TestRouteHandle<WarmUpRoute<TestRouteHandleIf>> rh(
      route_handles[0], route_handles[2], 1);

    auto reply_get = rh.route(
        McRequestWithMcOp<mc_op_get>("key_get"));
    EXPECT_TRUE("a" == toString(reply_get.value()));
    EXPECT_TRUE(vector<string>{"key_get"} == test_handles[0]->saw_keys);
    EXPECT_TRUE(vector<string>{"key_get"} == test_handles[2]->saw_keys);
  });
  fm.run([&]() {
    EXPECT_TRUE((vector<uint32_t>{0, 1}) == test_handles[2]->sawExptimes);
    (test_handles[0]->saw_keys).clear();
    (test_handles[2]->saw_keys).clear();
    EXPECT_TRUE((vector<mc_op_t>{ mc_op_get, mc_op_add }) ==
              test_handles[2]->sawOperations);
  });
  fm.run([&]() {
    TestRouteHandle<WarmUpRoute<TestRouteHandleIf>> rh(
      route_handles[0], route_handles[2], 1);

    auto reply_del = rh.route(
        McRequestWithMcOp<mc_op_delete>("key_del"));
    EXPECT_TRUE(mc_res_notfound == reply_del.result());
    EXPECT_TRUE(vector<string>{"key_del"} != test_handles[0]->saw_keys);
    EXPECT_TRUE(vector<string>{"key_del"} == test_handles[2]->saw_keys);
  });


}
TEST(migrateRouteTest, migrate) {
  auto curr_time = time(nullptr);
  auto interval = 50;

  auto tp_func = []() {
    return time(nullptr);
  };
  typedef decltype(tp_func) TimeProviderFunc;

  vector<std::shared_ptr<TestHandle>> test_handles{
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "a"),
                            UpdateRouteTestData(),
                            DeleteRouteTestData(mc_res_deleted)),
    make_shared<TestHandle>(GetRouteTestData(mc_res_found, "b"),
                            UpdateRouteTestData(),
                            DeleteRouteTestData(mc_res_notfound)),
  };
  auto route_handles = get_route_handles(test_handles);

  TestFiberManager fm;

  fm.runAll({
    [&]() { // case 1: curr_time < start_time
      TestRouteHandle<MigrateRoute<TestRouteHandleIf, TimeProviderFunc>> rh(
        route_handles[0], route_handles[1], curr_time + 25, interval, tp_func);

      TypedThriftRequest<cpp2::McGetRequest> req_get("key_get");
      int cnt = 0;
      RouteHandleTraverser<TestRouteHandleIf> t{
        [&cnt](const TestRouteHandleIf&) { ++cnt; }
      };
      rh.traverse(req_get, t);
      EXPECT_EQ(1, cnt);

      auto reply_get = rh.route(req_get);
      EXPECT_EQ("a", reply_get.valueRangeSlow().str());
      EXPECT_EQ(vector<string>{"key_get"}, test_handles[0]->saw_keys);
      EXPECT_NE(vector<string>{"key_get"}, test_handles[1]->saw_keys);
      (test_handles[0]->saw_keys).clear();
      (test_handles[1]->saw_keys).clear();

      TypedThriftRequest<cpp2::McDeleteRequest> req_del("key_del");
      cnt = 0;
      rh.traverse(req_del, t);
      EXPECT_EQ(1, cnt);

      auto reply_del = rh.route(req_del);
      EXPECT_EQ(mc_res_deleted, reply_del.result());
      EXPECT_EQ(vector<string>{"key_del"}, test_handles[0]->saw_keys);
      EXPECT_NE(vector<string>{"key_del"}, test_handles[1]->saw_keys);
    },

    [&]() { // case 2: curr_time < start_time + interval
      vector<std::shared_ptr<TestHandle>> test_handles{
        make_shared<TestHandle>(GetRouteTestData(mc_res_found, "a"),
                                UpdateRouteTestData(),
                                DeleteRouteTestData(mc_res_deleted)),
        make_shared<TestHandle>(GetRouteTestData(mc_res_notfound, "b"),
                                UpdateRouteTestData(),
                                DeleteRouteTestData(mc_res_notfound)),
      };
      auto route_handles_c2 = get_route_handles(test_handles);
      TestRouteHandle<MigrateRoute<TestRouteHandleIf, TimeProviderFunc>> rh(
        route_handles_c2[0], route_handles_c2[1],
        curr_time -  25, interval, tp_func);

      TypedThriftRequest<cpp2::McGetRequest> req_get("key_get");
      int cnt = 0;
      RouteHandleTraverser<TestRouteHandleIf> t{
        [&cnt](const TestRouteHandleIf&) { ++cnt; }
      };
      rh.traverse(req_get, t);
      EXPECT_EQ(cnt, 1);

      auto reply_get = rh.route(req_get);
      EXPECT_EQ("a", reply_get.valueRangeSlow().str());
      EXPECT_EQ(vector<string>{"key_get"}, test_handles[0]->saw_keys);
      EXPECT_NE(vector<string>{"key_get"}, test_handles[1]->saw_keys);
      (test_handles[0]->saw_keys).clear();
      (test_handles[1]->saw_keys).clear();

      TypedThriftRequest<cpp2::McDeleteRequest> req_del("key_del");
      cnt = 0;
      rh.traverse(req_del, t);
      EXPECT_EQ(cnt, 2);

      auto reply_del = rh.route(req_del);
      EXPECT_EQ(mc_res_notfound, reply_del.result());
      EXPECT_EQ(vector<string>{"key_del"}, test_handles[0]->saw_keys);
      EXPECT_EQ(vector<string>{"key_del"}, test_handles[1]->saw_keys);
    },

    [&]() { // case 3: curr_time < start_time + 2*interval
      vector<std::shared_ptr<TestHandle>> test_handles{
        make_shared<TestHandle>(GetRouteTestData(mc_res_notfound, "a"),
                                UpdateRouteTestData(),
                                DeleteRouteTestData(mc_res_notfound)),
        make_shared<TestHandle>(GetRouteTestData(mc_res_found, "b"),
                                UpdateRouteTestData(),
                                DeleteRouteTestData(mc_res_deleted)),
      };
      auto route_handles_c3 = get_route_handles(test_handles);
      TestRouteHandle<MigrateRoute<TestRouteHandleIf, TimeProviderFunc>> rh(
        route_handles_c3[0], route_handles_c3[1],
        curr_time - 75, interval, tp_func);

      TypedThriftRequest<cpp2::McGetRequest> req_get("key_get");
      int cnt = 0;
      RouteHandleTraverser<TestRouteHandleIf> t{
        [&cnt](const TestRouteHandleIf&) { ++cnt; }
      };
      rh.traverse(req_get, t);
      EXPECT_EQ(1, cnt);

      auto reply_get = rh.route(req_get);
      EXPECT_EQ("b", reply_get.valueRangeSlow().str());
      EXPECT_NE(vector<string>{"key_get"}, test_handles[0]->saw_keys);
      EXPECT_EQ(vector<string>{"key_get"}, test_handles[1]->saw_keys);
      (test_handles[0]->saw_keys).clear();
      (test_handles[1]->saw_keys).clear();

      TypedThriftRequest<cpp2::McDeleteRequest> req_del("key_del");
      cnt = 0;
      rh.traverse(req_del, t);
      EXPECT_EQ(2, cnt);

      auto reply_del = rh.route(req_del);
      EXPECT_EQ(mc_res_notfound, reply_del.result());
      EXPECT_EQ(vector<string>{"key_del"}, test_handles[0]->saw_keys);
      EXPECT_EQ(vector<string>{"key_del"}, test_handles[1]->saw_keys);
    },

    [&]() { // case 4: curr_time > start_time + 2*interval
      TestRouteHandle<MigrateRoute<TestRouteHandleIf, TimeProviderFunc>> rh(
        route_handles[0], route_handles[1], curr_time - 125, interval, tp_func);

      TypedThriftRequest<cpp2::McGetRequest> req_get("key_get");
      int cnt = 0;
      RouteHandleTraverser<TestRouteHandleIf> t{
        [&cnt](const TestRouteHandleIf&) { ++cnt; }
      };
      rh.traverse(req_get, t);
      EXPECT_EQ(cnt, 1);

      auto reply_get = rh.route(req_get);
      EXPECT_EQ("b", reply_get.valueRangeSlow().str());
      EXPECT_NE(vector<string>{"key_get"}, test_handles[0]->saw_keys);
      EXPECT_EQ(vector<string>{"key_get"}, test_handles[1]->saw_keys);
      (test_handles[0]->saw_keys).clear();
      (test_handles[1]->saw_keys).clear();

      TypedThriftRequest<cpp2::McDeleteRequest> req_del("key_del");
      cnt = 0;
      rh.traverse(req_del, t);
      EXPECT_EQ(1, cnt);

      auto reply_del = rh.route(req_del);
      EXPECT_EQ(mc_res_notfound, reply_del.result());
      EXPECT_NE(vector<string>{"key_del"}, test_handles[0]->saw_keys);
      EXPECT_EQ(vector<string>{"key_del"}, test_handles[1]->saw_keys);
    }
  });
}
Esempio n. 21
0
TEST(RouteHandleFactoryTest, sanity) {
  TestFiberManager fm;

  RouteHandleProvider<TestRouteHandleIf> provider;

  RouteHandleFactory<TestRouteHandleIf> factory(provider);

  auto rh = factory.create("AllAsyncRoute|ErrorRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->routeSimple(McRequest("a"), McOperation<mc_op_get>());
    EXPECT_EQ(reply.result(), mc_res_notfound);
  });

  rh = factory.create("AllFastestRoute|ErrorRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->routeSimple(McRequest("a"), McOperation<mc_op_get>());
    EXPECT_TRUE(reply.isError());
  });

  rh = factory.create("AllInitialRoute|ErrorRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->routeSimple(McRequest("a"), McOperation<mc_op_get>());
    EXPECT_TRUE(reply.isError());
  });

  rh = factory.create("AllMajorityRoute|ErrorRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->routeSimple(McRequest("a"), McOperation<mc_op_get>());
    EXPECT_TRUE(reply.isError());
  });

  rh = factory.create("AllSyncRoute|ErrorRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->routeSimple(McRequest("a"), McOperation<mc_op_get>());
    EXPECT_TRUE(reply.isError());
  });

  rh = factory.create("FailoverRoute|NullRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->routeSimple(McRequest("a"), McOperation<mc_op_get>());
    EXPECT_EQ(reply.result(), mc_res_notfound);
  });

  rh = factory.create("HashRoute|ErrorRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->routeSimple(McRequest("a"), McOperation<mc_op_get>());
    EXPECT_TRUE(reply.isError());
  });

  rh = factory.create("HostIdRoute|ErrorRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->routeSimple(McRequest("a"), McOperation<mc_op_get>());
    EXPECT_TRUE(reply.isError());
  });

  rh = factory.create("LatestRoute|NullRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->routeSimple(McRequest("a"), McOperation<mc_op_get>());
    EXPECT_EQ(reply.result(), mc_res_notfound);
  });

  rh = factory.create("MissFailoverRoute|NullRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->routeSimple(McRequest("a"), McOperation<mc_op_get>());
    EXPECT_EQ(reply.result(), mc_res_notfound);
  });

  rh = factory.create("RandomRoute|ErrorRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->routeSimple(McRequest("a"), McOperation<mc_op_get>());
    EXPECT_TRUE(reply.isError());
  });
}
TEST(BigValueRouteTest, bigvalue) {
  // for big values, used saw_keys of test route handle to verify that
  // get path and set path saw original key and chunk keys in correct sequesne.

  std::string rand_suffix_get ("123456");
  int num_chunks = 10;
  // initial reply of the form version-num_chunks-rand_suffix for get path
  std::string init_reply =
    folly::format("{}-{}-{}", version, num_chunks, rand_suffix_get).str();
  std::string init_reply_error =
    folly::format("{}-{}", version, num_chunks).str();
  vector<std::shared_ptr<TestHandle>> test_handles{
    make_shared<TestHandle>(GetRouteTestData(
          mc_res_found, init_reply, MC_MSG_FLAG_BIG_VALUE)),
    make_shared<TestHandle>(GetRouteTestData(
          mc_res_found, init_reply_error, MC_MSG_FLAG_BIG_VALUE)),
    make_shared<TestHandle>(UpdateRouteTestData(mc_res_stored)),
    make_shared<TestHandle>(UpdateRouteTestData(mc_res_stored))
  };
  auto route_handles = get_route_handles(test_handles);

  TestFiberManager fm;
  std::shared_ptr<ProxyRequestContext> ctx;

  fm.runAll({
    [&]() {
      { // Test Get Like path with init_reply in corect format
        McrouterRouteHandle<BigValueRoute> rh(route_handles[0], opts);

        auto msg = createMcMsgRef("key_get");
        msg->op = mc_op_get;
        ProxyMcRequest req_get(std::move(msg));

        auto f_get = rh.route(req_get, McOperation<mc_op_get>(), ctx);
        auto keys_get = test_handles[0]->saw_keys;
        EXPECT_TRUE(keys_get.size() == num_chunks + 1);
        // first get the result for original key
        EXPECT_TRUE(keys_get.front() == "key_get");

        std::string merged_str;
        // since reply for first key indicated that it is for a big get request,
        // perform get request on chunk keys
        for (int i = 1; i < num_chunks + 1; i++) {
          auto chunk_key = folly::format(
            "key_get|#|{}:{}", i-1, rand_suffix_get).str();
          EXPECT_EQ(chunk_key, keys_get[i]);
          merged_str.append(init_reply);
        }

        // each chunk_key saw value as init_reply.
        // In GetLike path, it gets appended num_chunks time
        EXPECT_TRUE(toString(f_get.value()) == merged_str);
      }

      { // Test Get Like path with init_reply_error
        McrouterRouteHandle<BigValueRoute> rh(route_handles[1], opts);

        auto msg = createMcMsgRef("key_get");
        msg->op = mc_op_get;
        ProxyMcRequest req_get(std::move(msg));

        auto f_get = rh.route(req_get, McOperation<mc_op_get>(), ctx);
        auto keys_get = test_handles[1]->saw_keys;
        EXPECT_TRUE(keys_get.size() == 1);
        // first get the result for original key, then return mc_res_notfound
        EXPECT_TRUE(keys_get.front() == "key_get");
        EXPECT_TRUE(f_get.result() == mc_res_notfound);
        EXPECT_TRUE(toString(f_get.value()) == "");
      }

      { // Test Update Like path with mc_op_set op
        McrouterRouteHandle<BigValueRoute> rh(route_handles[2], opts);

        std::string big_value  = folly::to<std::string>(
          std::string(threshold*(num_chunks/2), 't'),
          std::string(threshold*(num_chunks/2), 's'));
        std::string chunk_type_1 = std::string(threshold, 't');
        std::string chunk_type_2 = std::string(threshold, 's');
        auto msg_set = createMcMsgRef("key_set", big_value);
        msg_set->op = mc_op_set;
        ProxyMcRequest req_set(std::move(msg_set));

        auto f_set = rh.route(req_set, McOperation<mc_op_set>(), ctx);
        auto keys_set = test_handles[2]->saw_keys;
        auto values_set = test_handles[2]->sawValues;
        EXPECT_TRUE(keys_set.size() == num_chunks + 1);
        std::string rand_suffix_set;
        // first set chunk values corresponding to chunk keys
        for(int i = 0; i < num_chunks; i++) {
          auto chunk_key_prefix = folly::format("key_set|#|{}:", i).str();
          auto length = chunk_key_prefix.length();
          auto saw_prefix = keys_set[i].substr(0, length);
          EXPECT_TRUE(saw_prefix == chunk_key_prefix);

          if (rand_suffix_set.empty()) { // rand_suffic same for all chunk_keys
            rand_suffix_set = keys_set[i].substr(length);
          } else {
            EXPECT_TRUE(rand_suffix_set == keys_set[i].substr(length));
          }

          if (i < num_chunks/2) {
            EXPECT_TRUE(values_set[i] == chunk_type_1);
          } else {
            EXPECT_TRUE(values_set[i] == chunk_type_2);
          }
        }

        // if set for chunk keys succeed,
        // set original key with chunks info as modified value
        EXPECT_TRUE(keys_set[num_chunks] == "key_set");
        auto chunks_info = folly::format(
            "{}-{}-{}", version, num_chunks, rand_suffix_set).str();
        EXPECT_TRUE(values_set[num_chunks] == chunks_info);
        EXPECT_TRUE(toString(f_set.value()) == values_set[num_chunks]);
      }

      { // Test Update Like path with mc_op_lease_set op
        McrouterRouteHandle<BigValueRoute> rh(route_handles[3], opts);

        std::string big_value  = folly::to<std::string>(
          std::string(threshold*(num_chunks/2), 't'),
          std::string(threshold*(num_chunks/2), 's'));
        auto msg_set = createMcMsgRef("key_set", big_value);
        msg_set->op = mc_op_lease_set;
        ProxyMcRequest req_set(std::move(msg_set));

        auto f_set = rh.route(req_set, McOperation<mc_op_lease_set>(), ctx);
        auto keys_set = test_handles[3]->saw_keys;
        auto operations_set = test_handles[3]->sawOperations;
        EXPECT_TRUE(keys_set.size() == num_chunks + 1);
        std::string rand_suffix_set;
        // first set chunk values corresponding to chunk keys
        for(int i = 0; i < num_chunks; i++) {
          auto chunk_key_prefix = folly::format("key_set|#|{}:", i).str();
          auto length = chunk_key_prefix.length();
          auto saw_prefix = keys_set[i].substr(0, length);
          EXPECT_TRUE(saw_prefix == chunk_key_prefix);

          EXPECT_TRUE(operations_set[i] == mc_op_set);
        }

        // if set for chunk keys succeed,
        // set original key with chunks info as modified value
        EXPECT_TRUE(keys_set[num_chunks] == "key_set");
        EXPECT_TRUE(operations_set[num_chunks] == mc_op_lease_set);
      }
    }
  });
}
TEST(RouteHandleFactoryTest, sanity) {
  TestFiberManager fm;

  auto router = getTestRouter();
  auto proxy = router->getProxy(0);
  PoolFactory pf(folly::dynamic::object(), router->configApi());
  McRouteHandleProvider provider(*proxy, pf);
  RouteHandleFactory<McrouterRouteHandleIf> factory(provider);

  auto rh = factory.create("AllAsyncRoute|ErrorRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->route(McRequestWithMcOp<mc_op_get>("a"));
    EXPECT_EQ(reply.result(), mc_res_notfound);
  });

  rh = factory.create("AllFastestRoute|ErrorRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->route(McRequestWithMcOp<mc_op_get>("a"));
    EXPECT_TRUE(reply.isError());
  });

  rh = factory.create("AllInitialRoute|ErrorRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->route(McRequestWithMcOp<mc_op_get>("a"));
    EXPECT_TRUE(reply.isError());
  });

  rh = factory.create("AllMajorityRoute|ErrorRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->route(McRequestWithMcOp<mc_op_get>("a"));
    EXPECT_TRUE(reply.isError());
  });

  rh = factory.create("AllSyncRoute|ErrorRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->route(McRequestWithMcOp<mc_op_get>("a"));
    EXPECT_TRUE(reply.isError());
  });

  rh = factory.create("FailoverRoute|NullRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->route(McRequestWithMcOp<mc_op_get>("a"));
    EXPECT_EQ(reply.result(), mc_res_notfound);
  });

  rh = factory.create("HashRoute|ErrorRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->route(McRequestWithMcOp<mc_op_get>("a"));
    EXPECT_TRUE(reply.isError());
  });

  rh = factory.create("HostIdRoute|ErrorRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->route(McRequestWithMcOp<mc_op_get>("a"));
    EXPECT_TRUE(reply.isError());
  });

  rh = factory.create("LatestRoute|NullRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->route(McRequestWithMcOp<mc_op_get>("a"));
    EXPECT_EQ(reply.result(), mc_res_notfound);
  });

  rh = factory.create("LoggingRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    mockFiberContext();
    auto reply = rh->route(McRequestWithMcOp<mc_op_get>("a"));
    EXPECT_EQ(reply.result(), mc_res_notfound);
  });

  rh = factory.create("MissFailoverRoute|NullRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->route(McRequestWithMcOp<mc_op_get>("a"));
    EXPECT_EQ(reply.result(), mc_res_notfound);
  });

  rh = factory.create("RandomRoute|ErrorRoute");
  EXPECT_TRUE(rh != nullptr);
  fm.run([&rh]() {
    auto reply = rh->route(McRequestWithMcOp<mc_op_get>("a"));
    EXPECT_TRUE(reply.isError());
  });
}