uvw/test/uvw/file_req.cpp
Eli Lindsey 1a794772b2
add openbsd support (#204)
* add openbsd support

Renames fileno() so it doesn't clash with OpenBSD's macro expansion.
Makes minor changes to build steps so the test suite compiles and runs
on OpenBSD.

See https://github.com/skypjack/uvw/issues/201 for full context

* drop no-error override

* disable sendfile tests on openbsd

* forgot to commit the new file
2020-06-29 16:37:31 +02:00

524 lines
16 KiB
C++

#include <gtest/gtest.h>
#include <uvw.hpp>
#include <chrono>
#ifdef _WIN32
#define _CRT_DECLARE_NONSTDC_NAMES 1
#include <fcntl.h>
#endif
TEST(FileReq, OpenAndCloseErr) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/err.file"};
auto loop = uvw::Loop::getDefault();
auto openReq = loop->resource<uvw::FileReq>();
auto closeReq = loop->resource<uvw::FileReq>();
bool checkFileOpenErrorEvent = false;
bool checkFileCloseErrorEvent = false;
openReq->on<uvw::ErrorEvent>([&checkFileOpenErrorEvent](const auto &, auto &) {
ASSERT_FALSE(checkFileOpenErrorEvent);
checkFileOpenErrorEvent = true;
});
closeReq->on<uvw::ErrorEvent>([&checkFileCloseErrorEvent](const auto &, auto &) {
ASSERT_FALSE(checkFileCloseErrorEvent);
checkFileCloseErrorEvent = true;
});
auto flags = uvw::Flags<uvw::FileReq::FileOpen>::from<uvw::FileReq::FileOpen::RDONLY>();
openReq->open(filename, flags, 0644);
closeReq->close();
loop->run();
ASSERT_TRUE(checkFileOpenErrorEvent);
ASSERT_TRUE(checkFileCloseErrorEvent);
}
TEST(FileReq, OpenAndCloseErrSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/err.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
ASSERT_FALSE(request->openSync(filename, O_RDONLY, 0644));
ASSERT_FALSE(request->closeSync());
loop->run();
}
TEST(FileReq, OpenAndClose) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
bool checkFileOpenEvent = false;
bool checkFileCloseEvent = false;
request->on<uvw::ErrorEvent>([](const auto &, auto &) { FAIL(); });
request->on<uvw::FsEvent<uvw::FileReq::Type::CLOSE>>([&checkFileCloseEvent](const auto &, auto &) {
ASSERT_FALSE(checkFileCloseEvent);
checkFileCloseEvent = true;
});
request->on<uvw::FsEvent<uvw::FileReq::Type::OPEN>>([&checkFileOpenEvent](const auto &, auto &req) {
ASSERT_FALSE(checkFileOpenEvent);
checkFileOpenEvent = true;
req.close();
});
auto flags = uvw::Flags<uvw::FileReq::FileOpen>::from<uvw::FileReq::FileOpen::CREAT, uvw::FileReq::FileOpen::WRONLY>();
request->open(filename, flags, 0644);
loop->run();
ASSERT_TRUE(checkFileOpenEvent);
ASSERT_TRUE(checkFileCloseEvent);
}
TEST(FileReq, OpenAndCloseSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
ASSERT_TRUE(request->openSync(filename, O_CREAT | O_WRONLY, 0644));
ASSERT_TRUE(request->closeSync());
loop->run();
}
TEST(FileReq, RWChecked) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
bool checkFileWriteEvent = false;
bool checkFileReadEvent = false;
request->on<uvw::ErrorEvent>([](const auto &, auto &) { FAIL(); });
request->on<uvw::FsEvent<uvw::FileReq::Type::READ>>([&checkFileReadEvent](const auto &event, auto &req) {
ASSERT_FALSE(checkFileReadEvent);
ASSERT_EQ(event.data[0], 42);
checkFileReadEvent = true;
req.close();
});
request->on<uvw::FsEvent<uvw::FileReq::Type::WRITE>>([&checkFileWriteEvent](const auto &, auto &req) {
ASSERT_FALSE(checkFileWriteEvent);
checkFileWriteEvent = true;
req.read(0, 1);
});
request->on<uvw::FsEvent<uvw::FileReq::Type::OPEN>>([](const auto &, auto &req) {
req.write(std::unique_ptr<char[]>{new char[1]{ 42 }}, 1, 0);
});
auto flags = uvw::Flags<uvw::FileReq::FileOpen>::from<uvw::FileReq::FileOpen::CREAT, uvw::FileReq::FileOpen::RDWR, uvw::FileReq::FileOpen::TRUNC>();
request->open(filename, flags, 0644);
loop->run();
ASSERT_TRUE(checkFileWriteEvent);
ASSERT_TRUE(checkFileReadEvent);
}
TEST(FileReq, RWUnchecked) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
std::unique_ptr<char[]> data{new char[1]{ 42 }};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
bool checkFileWriteEvent = false;
bool checkFileReadEvent = false;
request->on<uvw::ErrorEvent>([](const auto &, auto &) { FAIL(); });
request->on<uvw::FsEvent<uvw::FileReq::Type::READ>>([&checkFileReadEvent](const auto &event, auto &req) {
ASSERT_FALSE(checkFileReadEvent);
ASSERT_EQ(event.data[0], 42);
checkFileReadEvent = true;
req.close();
});
request->on<uvw::FsEvent<uvw::FileReq::Type::WRITE>>([&checkFileWriteEvent](const auto &, auto &req) {
ASSERT_FALSE(checkFileWriteEvent);
checkFileWriteEvent = true;
req.read(0, 1);
});
request->on<uvw::FsEvent<uvw::FileReq::Type::OPEN>>([&data](const auto &, auto &req) {
req.write(data.get(), 1, 0);
});
auto flags = uvw::Flags<uvw::FileReq::FileOpen>::from<uvw::FileReq::FileOpen::CREAT, uvw::FileReq::FileOpen::RDWR, uvw::FileReq::FileOpen::TRUNC>();
request->open(filename, flags, 0644);
loop->run();
ASSERT_TRUE(checkFileWriteEvent);
ASSERT_TRUE(checkFileReadEvent);
}
TEST(FileReq, RWSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
ASSERT_TRUE(request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644));
auto writeR = request->writeSync(std::unique_ptr<char[]>{new char[1]{ 42 }}, 1, 0);
ASSERT_TRUE(writeR.first);
ASSERT_EQ(writeR.second, std::size_t{1});
auto readR = request->readSync(0, 1);
ASSERT_TRUE(readR.first);
ASSERT_EQ(readR.second.first[0], 42);
ASSERT_EQ(readR.second.second, std::size_t{1});
ASSERT_TRUE(request->closeSync());
loop->run();
}
TEST(FileReq, Stat) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
bool checkFileStatEvent = false;
request->on<uvw::ErrorEvent>([](const auto &, auto &) { FAIL(); });
request->on<uvw::FsEvent<uvw::FileReq::Type::FSTAT>>([&checkFileStatEvent](const auto &, auto &req) {
ASSERT_FALSE(checkFileStatEvent);
checkFileStatEvent = true;
req.close();
});
request->on<uvw::FsEvent<uvw::FileReq::Type::OPEN>>([](const auto &, auto &req) {
req.stat();
});
auto flags = uvw::Flags<uvw::FileReq::FileOpen>::from<uvw::FileReq::FileOpen::CREAT, uvw::FileReq::FileOpen::RDWR, uvw::FileReq::FileOpen::TRUNC>();
request->open(filename, flags, 0644);
loop->run();
ASSERT_TRUE(checkFileStatEvent);
}
TEST(FileReq, StatSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
ASSERT_TRUE(request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644));
auto statR = request->statSync();
ASSERT_TRUE(statR.first);
ASSERT_TRUE(request->closeSync());
loop->run();
}
TEST(FileReq, Sync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
bool checkFileSyncEvent = false;
request->on<uvw::ErrorEvent>([](const auto &, auto &) { FAIL(); });
request->on<uvw::FsEvent<uvw::FileReq::Type::FSYNC>>([&checkFileSyncEvent](const auto &, auto &req) {
ASSERT_FALSE(checkFileSyncEvent);
checkFileSyncEvent = true;
req.close();
});
request->on<uvw::FsEvent<uvw::FileReq::Type::OPEN>>([](const auto &, auto &req) {
req.sync();
});
auto flags = uvw::Flags<uvw::FileReq::FileOpen>::from<uvw::FileReq::FileOpen::CREAT, uvw::FileReq::FileOpen::RDWR, uvw::FileReq::FileOpen::TRUNC>();
request->open(filename, flags, 0644);
loop->run();
ASSERT_TRUE(checkFileSyncEvent);
}
TEST(FileReq, SyncSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
ASSERT_TRUE(request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644));
ASSERT_TRUE(request->syncSync());
ASSERT_TRUE(request->closeSync());
loop->run();
}
TEST(FileReq, Datasync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
bool checkFileDatasyncEvent = false;
request->on<uvw::ErrorEvent>([](const auto &, auto &) { FAIL(); });
request->on<uvw::FsEvent<uvw::FileReq::Type::FDATASYNC>>([&checkFileDatasyncEvent](const auto &, auto &req) {
ASSERT_FALSE(checkFileDatasyncEvent);
checkFileDatasyncEvent = true;
req.close();
});
request->on<uvw::FsEvent<uvw::FileReq::Type::OPEN>>([](const auto &, auto &req) {
req.datasync();
});
auto flags = uvw::Flags<uvw::FileReq::FileOpen>::from<uvw::FileReq::FileOpen::CREAT, uvw::FileReq::FileOpen::RDWR, uvw::FileReq::FileOpen::TRUNC>();
request->open(filename, flags, 0644);
loop->run();
ASSERT_TRUE(checkFileDatasyncEvent);
}
TEST(FileReq, DatasyncSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
ASSERT_TRUE(request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644));
ASSERT_TRUE(request->datasyncSync());
ASSERT_TRUE(request->closeSync());
loop->run();
}
TEST(FileReq, Truncate) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
bool checkFileTruncateEvent = false;
request->on<uvw::ErrorEvent>([](const auto &, auto &) { FAIL(); });
request->on<uvw::FsEvent<uvw::FileReq::Type::FTRUNCATE>>([&checkFileTruncateEvent](const auto &, auto &req) {
ASSERT_FALSE(checkFileTruncateEvent);
checkFileTruncateEvent = true;
req.close();
});
request->on<uvw::FsEvent<uvw::FileReq::Type::OPEN>>([](const auto &, auto &req) {
req.truncate(0);
});
auto flags = uvw::Flags<uvw::FileReq::FileOpen>::from<uvw::FileReq::FileOpen::CREAT, uvw::FileReq::FileOpen::RDWR, uvw::FileReq::FileOpen::TRUNC>();
request->open(filename, flags, 0644);
loop->run();
ASSERT_TRUE(checkFileTruncateEvent);
}
TEST(FileReq, TruncateSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
ASSERT_TRUE(request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644));
ASSERT_TRUE(request->truncateSync(0));
ASSERT_TRUE(request->closeSync());
loop->run();
}
TEST(FileReq, Chmod) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
bool checkFileChmodEvent = false;
request->on<uvw::ErrorEvent>([](const auto &, auto &) { FAIL(); });
request->on<uvw::FsEvent<uvw::FileReq::Type::FCHMOD>>([&checkFileChmodEvent](const auto &, auto &req) {
ASSERT_FALSE(checkFileChmodEvent);
checkFileChmodEvent = true;
req.close();
});
request->on<uvw::FsEvent<uvw::FileReq::Type::OPEN>>([](const auto &, auto &req) {
req.chmod(0644);
});
auto flags = uvw::Flags<uvw::FileReq::FileOpen>::from<uvw::FileReq::FileOpen::CREAT, uvw::FileReq::FileOpen::RDWR, uvw::FileReq::FileOpen::TRUNC>();
request->open(filename, flags, 0644);
loop->run();
ASSERT_TRUE(checkFileChmodEvent);
}
TEST(FileReq, ChmodSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
ASSERT_TRUE(request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644));
ASSERT_TRUE(request->chmodSync(0644));
ASSERT_TRUE(request->closeSync());
loop->run();
}
TEST(FileReq, Futime) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
bool checkFileUtimeEvent = false;
request->on<uvw::ErrorEvent>([](const auto &, auto &) { FAIL(); });
request->on<uvw::FsEvent<uvw::FileReq::Type::FUTIME>>([&checkFileUtimeEvent](const auto &, auto &req) {
ASSERT_FALSE(checkFileUtimeEvent);
checkFileUtimeEvent = true;
req.close();
});
request->on<uvw::FsEvent<uvw::FileReq::Type::OPEN>>([](const auto &, auto &req) {
auto now = std::chrono::system_clock::now();
auto epoch = now.time_since_epoch();
auto value = std::chrono::duration_cast<std::chrono::seconds>(epoch);
req.futime(value, value);
});
auto flags = uvw::Flags<uvw::FileReq::FileOpen>::from<uvw::FileReq::FileOpen::CREAT, uvw::FileReq::FileOpen::RDWR, uvw::FileReq::FileOpen::TRUNC>();
request->open(filename, flags, 0644);
loop->run();
ASSERT_TRUE(checkFileUtimeEvent);
}
TEST(FileReq, FutimeSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
ASSERT_TRUE(request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644));
auto now = std::chrono::system_clock::now();
auto epoch = now.time_since_epoch();
auto value = std::chrono::duration_cast<std::chrono::seconds>(epoch);
ASSERT_TRUE(request->futimeSync(value, value));
ASSERT_TRUE(request->truncateSync(0));
ASSERT_TRUE(request->closeSync());
loop->run();
}
TEST(FileReq, Chown) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
bool checkFileChownEvent = false;
request->on<uvw::ErrorEvent>([](const auto &, auto &) { FAIL(); });
request->on<uvw::FsEvent<uvw::FileReq::Type::FCHOWN>>([&checkFileChownEvent](const auto &, auto &req) {
ASSERT_FALSE(checkFileChownEvent);
checkFileChownEvent = true;
req.close();
});
request->on<uvw::FsEvent<uvw::FileReq::Type::FSTAT>>([](const auto &event, auto &req) {
auto uid = static_cast<uvw::Uid>(event.stat.st_uid);
auto gid = static_cast<uvw::Uid>(event.stat.st_gid);
req.chown(uid, gid);
});
request->on<uvw::FsEvent<uvw::FileReq::Type::OPEN>>([](const auto &, auto &req) {
req.stat();
});
auto flags = uvw::Flags<uvw::FileReq::FileOpen>::from<uvw::FileReq::FileOpen::CREAT, uvw::FileReq::FileOpen::RDWR, uvw::FileReq::FileOpen::TRUNC>();
request->open(filename, flags, 0644);
loop->run();
ASSERT_TRUE(checkFileChownEvent);
}
TEST(FileReq, ChownSync) {
const std::string filename = std::string{TARGET_FILE_REQ_DIR} + std::string{"/test.file"};
auto loop = uvw::Loop::getDefault();
auto request = loop->resource<uvw::FileReq>();
ASSERT_TRUE(request->openSync(filename, O_CREAT | O_RDWR | O_TRUNC, 0644));
auto statR = request->statSync();
ASSERT_TRUE(statR.first);
auto uid = static_cast<uvw::Uid>(statR.second.st_uid);
auto gid = static_cast<uvw::Uid>(statR.second.st_gid);
ASSERT_TRUE(request->chownSync(uid, gid));
ASSERT_TRUE(request->closeSync());
loop->run();
}