blob: c67ce410d2557473b323c1c952d6e000b7161c7a [file] [log] [blame]
William A. Kennington IIIaa4fcfc2022-08-23 16:35:10 -07001#include <filesystem>
2#include <memory>
3#include <stdplus/fd/atomic.hpp>
4#include <stdplus/fd/ops.hpp>
5#include <stdplus/gtest/tmp.hpp>
6#include <string_view>
7
8namespace stdplus
9{
10namespace fd
11{
12
13using std::literals::string_view_literals::operator""sv;
14
15class AtomicWriterTest : public gtest::TestWithTmp
16{
17 protected:
18 std::string filename;
19 std::unique_ptr<AtomicWriter> file;
20
21 AtomicWriterTest() : filename(fmt::format("{}/out", CaseTmpDir()))
22 {
23 }
24
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{
49 auto tmp = fmt::format("{}/tmp.XXXXXX", CaseTmpDir());
50 ASSERT_NO_THROW(file =
51 std::make_unique<AtomicWriter>("/dev/null", 0644, tmp));
52 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