blob: c503a99bbc85a05cf76330afafce7b68b8c68131 [file] [log] [blame]
William A. Kennington IIIaa4fcfc2022-08-23 16:35:10 -07001#include <stdplus/fd/atomic.hpp>
2#include <stdplus/fd/ops.hpp>
3#include <stdplus/gtest/tmp.hpp>
Patrick Williamsd1984dd2023-05-10 16:12:44 -05004
5#include <filesystem>
William A. Kennington III6417c632023-07-17 02:56:52 -07006#include <format>
Patrick Williamsd1984dd2023-05-10 16:12:44 -05007#include <memory>
William A. Kennington IIIaa4fcfc2022-08-23 16:35:10 -07008#include <string_view>
9
10namespace stdplus
11{
12namespace fd
13{
14
15using std::literals::string_view_literals::operator""sv;
16
17class AtomicWriterTest : public gtest::TestWithTmp
18{
19 protected:
20 std::string filename;
21 std::unique_ptr<AtomicWriter> file;
22
William A. Kennington III6417c632023-07-17 02:56:52 -070023 AtomicWriterTest() : filename(std::format("{}/out", CaseTmpDir())) {}
William A. Kennington IIIaa4fcfc2022-08-23 16:35:10 -070024
25 ~AtomicWriterTest() noexcept
26 {
27 if (file)
28 {
29 auto tmpname = file->getTmpname();
30 file.reset();
31 if (!tmpname.empty())
32 {
33 EXPECT_FALSE(std::filesystem::exists(tmpname));
34 }
35 }
36 }
37};
38
39TEST_F(AtomicWriterTest, NoCommit)
40{
41 ASSERT_NO_THROW(file = std::make_unique<AtomicWriter>(filename, 0644));
42 writeExact(*file, "hi\n"sv);
43 EXPECT_FALSE(std::filesystem::exists(filename));
44 EXPECT_TRUE(std::filesystem::exists(file->getTmpname()));
45}
46
47TEST_F(AtomicWriterTest, BadCommit)
48{
William A. Kennington III6417c632023-07-17 02:56:52 -070049 auto tmp = std::format("{}/tmp.XXXXXX", CaseTmpDir());
Patrick Williamsd1984dd2023-05-10 16:12:44 -050050 ASSERT_NO_THROW(
51 file = std::make_unique<AtomicWriter>("/dev/null", 0644, tmp));
William A. Kennington IIIaa4fcfc2022-08-23 16:35:10 -070052 writeExact(*file, "hi\n"sv);
53 EXPECT_TRUE(std::filesystem::exists(file->getTmpname()));
54 EXPECT_THROW(file->commit(), std::filesystem::filesystem_error);
55 EXPECT_EQ(file->getTmpname(), ""sv);
56}
57
58TEST_F(AtomicWriterTest, Basic)
59{
60 ASSERT_NO_THROW(file = std::make_unique<AtomicWriter>(filename, 0644));
61 writeExact(*file, "hi\n"sv);
62 EXPECT_TRUE(std::filesystem::exists(file->getTmpname()));
63 EXPECT_NO_THROW(file->commit());
64 EXPECT_EQ(file->getTmpname(), ""sv);
65 std::error_code ec;
66 EXPECT_EQ(3, std::filesystem::file_size(filename, ec));
67 EXPECT_EQ(std::errc{}, ec);
68}
69
70} // namespace fd
71} // namespace stdplus