blob: d4382c45650c7add2caa1034ca522db39fd615b4 [file] [log] [blame]
John Park33858a32018-09-28 23:05:48 -07001#include "aos/util/file.h"
Brian Silverman61175fb2016-03-13 15:35:56 -04002
Tyler Chatowbf0609c2021-07-31 16:13:27 -07003#include <cstdlib>
Brian Silverman61175fb2016-03-13 15:35:56 -04004#include <string>
5
James Kuszmaul0625b0d2022-09-21 11:38:48 -07006#include "aos/realtime.h"
James Kuszmaulfd43f4e2022-12-16 15:19:35 -08007#include "aos/testing/tmpdir.h"
8#include "gtest/gtest.h"
James Kuszmaul0625b0d2022-09-21 11:38:48 -07009
10DECLARE_bool(die_on_malloc);
Brian Silverman61175fb2016-03-13 15:35:56 -040011
Brian Silverman61175fb2016-03-13 15:35:56 -040012namespace aos {
13namespace util {
14namespace testing {
15
Brian Silverman61175fb2016-03-13 15:35:56 -040016// Basic test of reading a normal file.
Alex Perrycb7da4b2019-08-28 19:35:56 -070017TEST(FileTest, ReadNormalFile) {
James Kuszmaulfd43f4e2022-12-16 15:19:35 -080018 const ::std::string tmpdir(aos::testing::TestTmpDir());
Brian Silverman61175fb2016-03-13 15:35:56 -040019 const ::std::string test_file = tmpdir + "/test_file";
20 ASSERT_EQ(0, system(("echo contents > " + test_file).c_str()));
21 EXPECT_EQ("contents\n", ReadFileToStringOrDie(test_file));
22}
23
24// Tests reading a file with 0 size, among other weird things.
Alex Perrycb7da4b2019-08-28 19:35:56 -070025TEST(FileTest, ReadSpecialFile) {
Brian Silverman61175fb2016-03-13 15:35:56 -040026 const ::std::string stat = ReadFileToStringOrDie("/proc/self/stat");
27 EXPECT_EQ('\n', stat[stat.size() - 1]);
28 const ::std::string my_pid = ::std::to_string(getpid());
29 EXPECT_EQ(my_pid, stat.substr(0, my_pid.size()));
30}
31
James Kuszmaulf8178092020-05-10 18:46:45 -070032// Tests that the PathExists function works under normal conditions.
33TEST(FileTest, PathExistsTest) {
James Kuszmaulfd43f4e2022-12-16 15:19:35 -080034 const std::string tmpdir(aos::testing::TestTmpDir());
James Kuszmaulf8178092020-05-10 18:46:45 -070035 const std::string test_file = tmpdir + "/test_file";
36 // Make sure the test_file doesn't exist.
37 unlink(test_file.c_str());
38 EXPECT_FALSE(PathExists(test_file));
39
40 WriteStringToFileOrDie(test_file, "abc");
41
42 EXPECT_TRUE(PathExists(test_file));
43}
44
James Kuszmaul0625b0d2022-09-21 11:38:48 -070045// Basic test of reading a normal file.
46TEST(FileTest, ReadNormalFileNoMalloc) {
James Kuszmaulfd43f4e2022-12-16 15:19:35 -080047 const ::std::string tmpdir(aos::testing::TestTmpDir());
James Kuszmaul0625b0d2022-09-21 11:38:48 -070048 const ::std::string test_file = tmpdir + "/test_file";
James Kuszmaulfd43f4e2022-12-16 15:19:35 -080049 // Make sure to include a string long enough to avoid small string
50 // optimization.
51 ASSERT_EQ(0, system(("echo 123456789 > " + test_file).c_str()));
James Kuszmaul0625b0d2022-09-21 11:38:48 -070052
53 FileReader reader(test_file);
54
James Kuszmaulfd43f4e2022-12-16 15:19:35 -080055 gflags::FlagSaver flag_saver;
James Kuszmaul0625b0d2022-09-21 11:38:48 -070056 FLAGS_die_on_malloc = true;
57 RegisterMallocHook();
58 aos::ScopedRealtime realtime;
James Kuszmaul5a88d412023-01-27 15:55:55 -080059 {
60 std::array<char, 20> contents;
61 absl::Span<char> read_result =
62 reader.ReadContents({contents.data(), contents.size()});
63 EXPECT_EQ("123456789\n",
64 std::string_view(read_result.data(), read_result.size()));
65 }
66 {
67 std::optional<std::array<char, 10>> read_result = reader.ReadString<10>();
68 ASSERT_TRUE(read_result.has_value());
69 EXPECT_EQ("123456789\n",
70 std::string_view(read_result->data(), read_result->size()));
71 }
72 EXPECT_EQ(123456789, reader.ReadInt32());
James Kuszmaulfd43f4e2022-12-16 15:19:35 -080073}
74
75// Tests that we can write to a file without malloc'ing.
76TEST(FileTest, WriteNormalFileNoMalloc) {
77 const ::std::string tmpdir(aos::testing::TestTmpDir());
78 const ::std::string test_file = tmpdir + "/test_file";
79
80 FileWriter writer(test_file);
81
82 gflags::FlagSaver flag_saver;
83 FLAGS_die_on_malloc = true;
84 RegisterMallocHook();
85 FileWriter::WriteResult result;
86 {
87 aos::ScopedRealtime realtime;
88 result = writer.WriteBytes("123456789");
89 }
90 EXPECT_EQ(9, result.bytes_written);
91 EXPECT_EQ(9, result.return_code);
92 EXPECT_EQ("123456789", ReadFileToStringOrDie(test_file));
93}
94
95// Tests that if we fail to write a file that the error code propagates
96// correctly.
97TEST(FileTest, WriteFileError) {
98 const ::std::string tmpdir(aos::testing::TestTmpDir());
99 const ::std::string test_file = tmpdir + "/test_file";
100
101 // Open with only read permissions; this should cause things to fail.
102 FileWriter writer(test_file, S_IRUSR);
103
104 // Mess up the file management by closing the file descriptor.
105 PCHECK(0 == close(writer.fd()));
106
107 gflags::FlagSaver flag_saver;
108 FLAGS_die_on_malloc = true;
109 RegisterMallocHook();
110 FileWriter::WriteResult result;
111 {
112 aos::ScopedRealtime realtime;
113 result = writer.WriteBytes("123456789");
114 }
115 EXPECT_EQ(0, result.bytes_written);
116 EXPECT_EQ(-1, result.return_code);
117 EXPECT_EQ("", ReadFileToStringOrDie(test_file));
James Kuszmaul0625b0d2022-09-21 11:38:48 -0700118}
119
Brian Silverman61175fb2016-03-13 15:35:56 -0400120} // namespace testing
121} // namespace util
122} // namespace aos