log.flush();
log.stop();
struct stat file_status;
- ASSERT_EQ(lstat(test_file, &file_status), 0);
+ ASSERT_EQ(stat(test_file, &file_status), 0);
ASSERT_GT(file_status.st_size, 2000);
}
{
bool ok;
std::string result = client.ping(&ok);
+#ifndef _WIN32
+// TODO: convert WSA errors.
EXPECT_NE(std::string::npos, result.find("No such file or directory"));
+#endif
ASSERT_FALSE(ok);
}
// file exists but does not allow connections (no process, wrong type...)
- ASSERT_TRUE(::creat(path.c_str(), 0777));
+ int fd = ::creat(path.c_str(), 0777);
+ ASSERT_TRUE(fd);
+ // On Windows, we won't be able to remove the file unless we close it
+ // first.
+ ASSERT_FALSE(::close(fd));
{
bool ok;
std::string result = client.ping(&ok);
+#ifndef _WIN32
#if defined(__APPLE__) || defined(__FreeBSD__)
const char* errmsg = "Socket operation on non-socket";
#else
const char* errmsg = "Connection refused";
#endif
EXPECT_NE(std::string::npos, result.find(errmsg));
+#endif /* _WIN32 */
ASSERT_FALSE(ok);
}
// a daemon is connected to the socket
ASSERT_TRUE(asoct.init(path));
bool ok;
std::string result = client.ping(&ok);
+ #ifndef _WIN32
EXPECT_NE(std::string::npos, result.find("Resource temporarily unavailable"));
+ #endif
ASSERT_FALSE(ok);
{
std::lock_guard l{blocking->_lock};
message = asoct.bind_and_listen(path, &fd);
ASSERT_NE(0, fd);
ASSERT_EQ("", message);
- ASSERT_EQ(0, ::close(fd));
+ ASSERT_EQ(0, ::compat_closesocket(fd));
ASSERT_EQ(0, ::unlink(path.c_str()));
}
// silently discard an existing file
{
int fd = 0;
string message;
- ASSERT_TRUE(::creat(path.c_str(), 0777));
+ int fd2 = ::creat(path.c_str(), 0777);
+ ASSERT_TRUE(fd2);
+ // On Windows, we won't be able to remove the file unless we close it
+ // first.
+ ASSERT_FALSE(::close(fd2));
message = asoct.bind_and_listen(path, &fd);
ASSERT_NE(0, fd);
ASSERT_EQ("", message);
- ASSERT_EQ(0, ::close(fd));
+ ASSERT_EQ(0, ::compat_closesocket(fd));
ASSERT_EQ(0, ::unlink(path.c_str()));
}
// do not take over a live socket
return false;
}
- uint total = 0;
+ unsigned int total = 0;
if ((*iterone)->get_name() == "pgs") {
JSONObjIter iter = (*(*iterone)->find_first())->find_first();
for (; !iter.end(); ++iter) {
#include "include/buffer.h"
#include "include/buffer_raw.h"
+#include "include/compat.h"
#include "include/utime.h"
#include "include/coredumpctl.h"
#include "include/encoding.h"
bufferlist bl;
::unlink(FILENAME);
EXPECT_EQ(-ENOENT, bl.read_file("UNLIKELY", &error));
- snprintf(cmd, sizeof(cmd), "echo ABC > %s ; chmod 0 %s", FILENAME, FILENAME);
+ snprintf(cmd, sizeof(cmd), "echo ABC> %s", FILENAME);
+ EXPECT_EQ(0, ::system(cmd));
+ #ifndef _WIN32
+ snprintf(cmd, sizeof(cmd), "chmod 0 %s", FILENAME);
EXPECT_EQ(0, ::system(cmd));
if (getuid() != 0) {
EXPECT_EQ(-EACCES, bl.read_file(FILENAME, &error));
}
snprintf(cmd, sizeof(cmd), "chmod +r %s", FILENAME);
EXPECT_EQ(0, ::system(cmd));
+ #endif /* _WIN32 */
EXPECT_EQ(0, bl.read_file(FILENAME, &error));
::unlink(FILENAME);
EXPECT_EQ((unsigned)4, bl.length());
struct stat st;
memset(&st, 0, sizeof(st));
ASSERT_EQ(0, ::stat(FILENAME, &st));
+ #ifndef _WIN32
EXPECT_EQ((unsigned)(mode | S_IFREG), st.st_mode);
+ #endif
::unlink(FILENAME);
}
exit(0);
}
-#if GTEST_HAS_DEATH_TEST
+#if GTEST_HAS_DEATH_TEST && !defined(_WIN32)
TEST_F(ForkDeathTest, MD5) {
ASSERT_EXIT(do_simple_crypto(), ::testing::ExitedWithCode(0), "^$");
}
-#endif //GTEST_HAS_DEATH_TEST
+#endif // GTEST_HAS_DEATH_TEST && !defined(_WIN32)
int main(int argc, char **argv) {
std::vector<const char*> args(argv, argv + argc);
<< ", skipping test because env var may or may not be short form"
<< std::endl;
} else {
- ASSERT_EQ(shn, exec("hostname -s")) ;
+ #ifdef _WIN32
+ ASSERT_EQ(shn, exec("hostname"));
+ #else
+ ASSERT_EQ(shn, exec("hostname -s"));
+ #endif
}
}
#include "gtest/gtest.h"
#include "include/buffer.h"
+#if __has_include(<filesystem>)
+#include <filesystem>
+namespace fs = std::filesystem;
+#elif __has_include(<experimental/filesystem>)
+#include <experimental/filesystem>
+namespace fs = std::experimental::filesystem;
+#endif
+
#include <errno.h>
#include <iostream>
#include <stdlib.h>
ostringstream oss;
oss << tmpdir << "/confutils_test_dir." << rand() << "." << getpid();
umask(022);
- int res = mkdir(oss.str().c_str(), 01777);
- if (res) {
- cerr << "failed to create temp directory '" << temp_dir << "'" << std::endl;
- return "";
+ if (!fs::exists(oss.str())) {
+ std::error_code ec;
+ if (!fs::create_directory(oss.str(), ec)) {
+ cerr << "failed to create temp directory '" << temp_dir << "' "
+ << ec.message() << std::endl;
+ return "";
+ }
+ fs::permissions(oss.str(), fs::perms::sticky_bit | fs::perms::all);
}
temp_dir = oss.str();
}
#include <vector>
#include "lazy_omap_stats_test.h"
+#include "include/compat.h"
using namespace std;
namespace bp = boost::process;
#include <regex>
#include <string>
+#include "include/compat.h"
#include "include/rados/librados.hpp"
struct index_t {
#include "test/librados/TestCase.h"
#include "gtest/gtest.h"
#include <sys/time.h>
+#ifndef _WIN32
#include <sys/resource.h>
+#endif
#include <errno.h>
#include <map>
}
}
+#ifndef _WIN32
// See trackers #20988 and #42026
TEST_F(LibRadosMisc, ShutdownRace)
{
threads[i].join();
ASSERT_EQ(setrlimit(RLIMIT_NOFILE, &rold), 0);
}
+#endif /* _WIN32 */
class TestAlarm
{
public:
+ #ifndef _WIN32
TestAlarm() {
alarm(1200);
}
~TestAlarm() {
alarm(0);
}
+ #else
+ // TODO: add a timeout mechanism for Windows as well, possibly by using
+ // CreateTimerQueueTimer.
+ TestAlarm() {
+ }
+ ~TestAlarm() {
+ }
+ #endif
};
template<class Rep, class Period, typename Func, typename... Args,
#include "test/librados_test_stub/TestClassHandler.h"
#include "test/librados_test_stub/TestIoCtxImpl.h"
#include <boost/algorithm/string/predicate.hpp>
-#include <dlfcn.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "common/debug.h"
#include "include/ceph_assert.h"
+#include "include/dlfcn_compat.h"
#define dout_context g_ceph_context
#define dout_subsys ceph_subsys_rados
return;
}
- // clear any existing error
- dlerror();
-
// initialize
void (*cls_init)() = reinterpret_cast<void (*)()>(
dlsym(handle, "__cls_init"));
- char* error = nullptr;
- if ((error = dlerror()) != nullptr) {
- std::cerr << "Error locating initializer: " << error << std::endl;
+ if (!cls_init) {
+ std::cerr << "Error locating initializer: " << dlerror() << std::endl;
} else if (cls_init) {
m_class_handles.push_back(handle);
cls_init();
while ((pde = ::readdir(dir))) {
std::string name(pde->d_name);
if (!boost::algorithm::starts_with(name, "libcls_") ||
- !boost::algorithm::ends_with(name, ".so")) {
+ !boost::algorithm::ends_with(name, SHARED_LIB_SUFFIX)) {
continue;
}
names.insert(name);
#endif
#include <sys/file.h>
#include <sys/stat.h>
+#ifndef _WIN32
#include <sys/mman.h>
+#include <sys/ioctl.h>
+#endif
#if defined(__linux__)
#include <linux/fs.h>
#endif
-#include <sys/ioctl.h>
#ifdef HAVE_ERR_H
#include <err.h>
#endif
#define OP_SKIPPED 101
#undef PAGE_SIZE
-#define PAGE_SIZE getpagesize()
+#define PAGE_SIZE get_page_size()
#undef PAGE_MASK
#define PAGE_MASK (PAGE_SIZE - 1)
goodfile[0] = 0;
logfile[0] = 0;
- page_size = getpagesize();
+ page_size = PAGE_SIZE;
page_mask = page_size - 1;
mmap_mask = page_mask;
fprintf(stdout, "mapped writes DISABLED\n");
break;
case 'Z':
+ #ifdef O_DIRECT
o_direct = O_DIRECT;
+ #endif
break;
default:
usage();
pool = argv[0];
iname = argv[1];
+ #ifndef _WIN32
signal(SIGHUP, cleanup);
signal(SIGINT, cleanup);
signal(SIGPIPE, cleanup);
signal(SIGVTALRM, cleanup);
signal(SIGUSR1, cleanup);
signal(SIGUSR2, cleanup);
+ #endif
random_generator.seed(seed);
#include <errno.h>
#include <semaphore.h>
#include <stdlib.h>
+#ifndef _WIN32
#include <sys/mman.h>
+#endif
#include "include/ceph_assert.h"
int CrossProcessSem::
create(int initial_val, CrossProcessSem** res)
{
+ #ifndef _WIN32
struct cross_process_sem_data_t *data = static_cast < cross_process_sem_data_t*> (
mmap(NULL, sizeof(struct cross_process_sem_data_t),
PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0));
int err = errno;
return err;
}
+ #else
+ // We can't use multiple processes on Windows for the time being.
+ struct cross_process_sem_data_t *data = (cross_process_sem_data_t*)malloc(
+ sizeof(cross_process_sem_data_t));
+ #endif /* _WIN32 */
int ret = sem_init(&data->sem, 1, initial_val);
if (ret) {
return ret;
CrossProcessSem::
~CrossProcessSem()
{
+ #ifndef _WIN32
munmap(m_data, sizeof(struct cross_process_sem_data_t));
+ #else
+ free(m_data);
+ #endif
m_data = NULL;
}
*/
#include "cross_process_sem.h"
+#include "include/ceph_assert.h"
#include "include/rados/librados.h"
#include "st_rados_create_pool.h"
#include "systest_runnable.h"
#include <stdlib.h>
#include <string.h>
#include <string>
+#ifndef _WIN32
#include <sys/syscall.h>
-#include <sys/types.h>
#include <sys/wait.h>
+#endif
+#include <sys/types.h>
#include <unistd.h>
#include <atomic>
#include <limits>
{
#if defined(__linux__)
return static_cast < pid_t >(syscall(SYS_gettid));
+#elif defined(_WIN32)
+ return static_cast < pid_t >(GetCurrentThreadId());
#else
return static_cast < pid_t >(pthread_getthreadid_np());
#endif
return ret;
m_started = true;
} else {
+ #ifdef _WIN32
+ printf("Using separate processes is not supported on Windows.\n");
+ return -1;
+ #else
std::string err_msg;
ret = preforker.prefork(err_msg);
if (ret < 0)
} else {
m_started = true;
}
+ #endif
}
return 0;
}
}
return "";
} else {
+ #ifdef _WIN32
+ return "Using separate processes is not supported on Windows.\n";
+ #else
std::string err_msg;
ret = preforker.parent_wait(err_msg);
return err_msg;
+ #endif
}
}
#include <string>
#include <vector>
+#ifndef _WIN32
#include "common/Preforker.h"
+#endif
#define RETURN1_IF_NOT_VAL(expected, expr) \
do {\
friend void* systest_runnable_pthread_helper(void *arg);
+ #ifndef _WIN32
Preforker preforker;
+ #endif
const char **m_argv_orig;
bool m_started;
int m_id;
bool SysTestSettings::
use_threads() const
{
+ #ifdef _WIN32
+ // We can't use multiple processes on Windows for the time being.
+ // We'd need a mechanism for spawning those procecesses and also handle
+ // the inter-process communication.
+ return true;
+ #else
return m_use_threads;
+ #endif
}
std::string SysTestSettings::
#include "gtest/gtest.h"
#include "common/fork_function.h"
+#ifdef _WIN32
+// Some of the tests expect GNU binaries to be available. We'll just rely on
+// the ones provided by Msys (which also comes with Git for Windows).
+#define SHELL "bash.exe"
+#else
+#define SHELL "/bin/sh"
+#endif
+
bool read_from_fd(int fd, std::string &out) {
out.clear();
char buf[1024];
TEST(SubProcess, NotFound)
{
SubProcess p("NOTEXISTENTBINARY", SubProcess::CLOSE, SubProcess::CLOSE, SubProcess::PIPE);
+ #ifdef _WIN32
+ // Windows will error out early.
+ ASSERT_EQ(p.spawn(), -1);
+ #else
ASSERT_EQ(p.spawn(), 0);
std::string buf;
ASSERT_TRUE(read_from_fd(p.get_stderr(), buf));
ASSERT_EQ(p.join(), 1);
std::cerr << "err: " << p.err() << std::endl;
ASSERT_FALSE(p.err().c_str()[0] == '\0');
+ #endif
}
TEST(SubProcess, Echo)
ASSERT_FALSE(cat.err().c_str()[0] == '\0');
}
+#ifndef _WIN32
TEST(SubProcess, CatWithArgs)
{
SubProcess cat("cat", SubProcess::PIPE, SubProcess::PIPE, SubProcess::PIPE);
std::cerr << "err: " << cat.err() << std::endl;
ASSERT_FALSE(cat.err().c_str()[0] == '\0');
}
+#endif
TEST(SubProcess, Subshell)
{
- SubProcess sh("/bin/sh", SubProcess::PIPE, SubProcess::PIPE, SubProcess::PIPE);
+ SubProcess sh(SHELL, SubProcess::PIPE, SubProcess::PIPE, SubProcess::PIPE);
sh.add_cmd_args("-c",
"sleep 0; "
"cat; "
"echo 'error from subshell' >&2; "
- "/bin/sh -c 'exit 13'", NULL);
+ SHELL " -c 'exit 13'", NULL);
ASSERT_EQ(sh.spawn(), 0);
std::string msg("hello via subshell");
int n = write(sh.get_stdin(), msg.c_str(), msg.size());
ASSERT_EQ(sleep.spawn(), 0);
std::string buf;
ASSERT_TRUE(read_from_fd(sleep.get_stderr(), buf));
+ #ifndef _WIN32
std::cerr << "stderr: " << buf;
ASSERT_FALSE(buf.empty());
+ #endif
ASSERT_EQ(sleep.join(), 128 + SIGKILL);
std::cerr << "err: " << sleep.err() << std::endl;
ASSERT_FALSE(sleep.err().c_str()[0] == '\0');
TEST(SubProcessTimed, SubshellNoTimeout)
{
- SubProcessTimed sh("/bin/sh", SubProcess::PIPE, SubProcess::PIPE, SubProcess::PIPE, 0);
+ SubProcessTimed sh(SHELL, SubProcess::PIPE, SubProcess::PIPE, SubProcess::PIPE, 0);
sh.add_cmd_args("-c", "cat >&2", NULL);
ASSERT_EQ(sh.spawn(), 0);
std::string msg("the quick brown fox jumps over the lazy dog");
TEST(SubProcessTimed, SubshellKilled)
{
- SubProcessTimed sh("/bin/sh", SubProcess::PIPE, SubProcess::PIPE, SubProcess::PIPE, 10);
- sh.add_cmd_args("-c", "sh -c cat", NULL);
+ SubProcessTimed sh(SHELL, SubProcess::PIPE, SubProcess::PIPE, SubProcess::PIPE, 10);
+ sh.add_cmd_args("-c", SHELL "-c cat", NULL);
ASSERT_EQ(sh.spawn(), 0);
std::string msg("etaoin shrdlu");
int n = write(sh.get_stdin(), msg.c_str(), msg.size());
TEST(SubProcessTimed, SubshellTimedout)
{
- SubProcessTimed sh("/bin/sh", SubProcess::PIPE, SubProcess::PIPE, SubProcess::PIPE, 1, SIGTERM);
+ SubProcessTimed sh(SHELL, SubProcess::PIPE, SubProcess::PIPE, SubProcess::PIPE, 1, SIGTERM);
sh.add_cmd_args("-c", "sleep 1000& cat; NEVER REACHED", NULL);
ASSERT_EQ(sh.spawn(), 0);
std::string buf;
+ #ifndef _WIN32
ASSERT_TRUE(read_from_fd(sh.get_stderr(), buf));
std::cerr << "stderr: " << buf;
ASSERT_FALSE(buf.empty());
+ #endif
ASSERT_EQ(sh.join(), 128 + SIGTERM);
std::cerr << "err: " << sh.err() << std::endl;
ASSERT_FALSE(sh.err().c_str()[0] == '\0');
}
+#ifndef _WIN32
TEST(fork_function, normal)
{
ASSERT_EQ(0, fork_function(10, std::cerr, [&]() { return 0; }));
sleep(60);
return -111; }));
}
+#endif