mirror of
https://github.com/ceph/ceph
synced 2025-02-22 18:47:18 +00:00
crimson/gtest_seastar: add helpers for building seastar gtest unit tests
Also adds unsafe_get methods for errorator for use within unit tests. Signed-off-by: Samuel Just <sjust@redhat.com>
This commit is contained in:
parent
518c43b981
commit
79550342c6
@ -564,6 +564,23 @@ private:
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* unsafe_thread_get
|
||||
*
|
||||
* Only valid within a seastar_thread. Ignores errorator protections
|
||||
* and throws any contained exceptions.
|
||||
*
|
||||
* Should really only be used within test code
|
||||
* (see test/crimson/gtest_seastar.h).
|
||||
*/
|
||||
auto &&unsafe_get() {
|
||||
return seastar::future<ValuesT...>::get();
|
||||
}
|
||||
auto unsafe_get0() {
|
||||
return seastar::future<ValuesT...>::get0();
|
||||
}
|
||||
|
||||
|
||||
template <class FuncT>
|
||||
auto finally(FuncT &&func) {
|
||||
using func_result_t = std::invoke_result_t<FuncT>;
|
||||
|
72
src/test/crimson/gtest_seastar.cc
Normal file
72
src/test/crimson/gtest_seastar.cc
Normal file
@ -0,0 +1,72 @@
|
||||
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
|
||||
// vim: ts=8 sw=2 smarttab
|
||||
|
||||
#include "include/ceph_assert.h"
|
||||
#include "gtest_seastar.h"
|
||||
|
||||
seastar_gtest_env_t seastar_test_suite_t::seastar_env;
|
||||
|
||||
seastar_gtest_env_t::seastar_gtest_env_t() :
|
||||
begin_fd{seastar::file_desc::eventfd(0, 0)} {}
|
||||
|
||||
void seastar_gtest_env_t::init(int _argc, char **_argv)
|
||||
{
|
||||
argc = _argc;
|
||||
argv = new char *[argc];
|
||||
for (int i = 0; i < argc; ++i) argv[i] = strdup(_argv[i]);
|
||||
|
||||
thread = std::thread([this] { reactor(); });
|
||||
eventfd_t result = 0;
|
||||
if (int r = ::eventfd_read(begin_fd.get(), &result); r < 0) {
|
||||
std::cerr << "unable to eventfd_read():" << errno << std::endl;
|
||||
throw std::runtime_error("Cannot start seastar");
|
||||
}
|
||||
}
|
||||
|
||||
void seastar_gtest_env_t::stop()
|
||||
{
|
||||
run([this] {
|
||||
on_end->write_side().signal(1);
|
||||
return seastar::now();
|
||||
});
|
||||
thread.join();
|
||||
}
|
||||
|
||||
seastar_gtest_env_t::~seastar_gtest_env_t()
|
||||
{
|
||||
ceph_assert(argv);
|
||||
for (int i = 0; i < argc; ++i) free(argv[i]);
|
||||
delete[] argv;
|
||||
}
|
||||
|
||||
void seastar_gtest_env_t::reactor()
|
||||
{
|
||||
app.run(argc, argv, [this] {
|
||||
on_end.reset(new seastar::readable_eventfd);
|
||||
return seastar::now().then([this] {
|
||||
::eventfd_write(begin_fd.get(), 1);
|
||||
return seastar::now();
|
||||
}).then([this] {
|
||||
return on_end->wait().then([](size_t){});
|
||||
}).handle_exception([](auto ep) {
|
||||
std::cerr << "Error: " << ep << std::endl;
|
||||
}).finally([this] {
|
||||
on_end.reset();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
seastar_test_suite_t::seastar_env.init(argc, argv);
|
||||
|
||||
seastar::global_logger_registry().set_all_loggers_level(
|
||||
seastar::log_level::debug
|
||||
);
|
||||
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
int ret = RUN_ALL_TESTS();
|
||||
|
||||
seastar_test_suite_t::seastar_env.stop();
|
||||
return ret;
|
||||
}
|
66
src/test/crimson/gtest_seastar.h
Normal file
66
src/test/crimson/gtest_seastar.h
Normal file
@ -0,0 +1,66 @@
|
||||
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
|
||||
// vim: ts=8 sw=2 smarttab
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <thread>
|
||||
|
||||
#include <seastar/core/app-template.hh>
|
||||
#include <seastar/core/future-util.hh>
|
||||
#include <seastar/core/reactor.hh>
|
||||
#include <seastar/core/alien.hh>
|
||||
#include <seastar/core/thread.hh>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
struct seastar_gtest_env_t {
|
||||
seastar::app_template app;
|
||||
seastar::file_desc begin_fd;
|
||||
std::unique_ptr<seastar::readable_eventfd> on_end;
|
||||
|
||||
int argc = 0;
|
||||
char **argv = nullptr;
|
||||
std::thread thread;
|
||||
|
||||
seastar_gtest_env_t();
|
||||
~seastar_gtest_env_t();
|
||||
|
||||
void init(int argc, char **argv);
|
||||
void stop();
|
||||
void reactor();
|
||||
|
||||
template <typename Func>
|
||||
void run(Func &&func) {
|
||||
auto fut = seastar::alien::submit_to(0, std::forward<Func>(func));
|
||||
fut.get();
|
||||
}
|
||||
};
|
||||
|
||||
struct seastar_test_suite_t : public ::testing::Test {
|
||||
static seastar_gtest_env_t seastar_env;
|
||||
|
||||
template <typename Func>
|
||||
void run(Func &&func) {
|
||||
return seastar_env.run(std::forward<Func>(func));
|
||||
}
|
||||
|
||||
template <typename Func>
|
||||
void run_async(Func &&func) {
|
||||
run(
|
||||
[func=std::forward<Func>(func)]() mutable {
|
||||
return seastar::async(std::forward<Func>(func));
|
||||
});
|
||||
}
|
||||
|
||||
virtual seastar::future<> set_up_fut() { return seastar::now(); }
|
||||
void SetUp() final {
|
||||
return run([this] { return set_up_fut(); });
|
||||
}
|
||||
|
||||
virtual seastar::future<> tear_down_fut() { return seastar::now(); }
|
||||
void TearDown() final {
|
||||
return run([this] { return tear_down_fut(); });
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user