blob: df16d5868c5b959149c5ecaa5acbda4460104219 [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>
payton.rehlf8cb3932023-06-13 11:20:44 -07004#include <optional>
Brian Silverman61175fb2016-03-13 15:35:56 -04005#include <string>
6
Philipp Schrader790cb542023-07-05 21:06:52 -07007#include "gtest/gtest.h"
8
James Kuszmaul0625b0d2022-09-21 11:38:48 -07009#include "aos/realtime.h"
James Kuszmaulfd43f4e2022-12-16 15:19:35 -080010#include "aos/testing/tmpdir.h"
James Kuszmaul0625b0d2022-09-21 11:38:48 -070011
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) {
payton.rehlf8cb3932023-06-13 11:20:44 -070018 const std::string tmpdir(aos::testing::TestTmpDir());
19 const std::string test_file = tmpdir + "/test_file";
Brian Silverman61175fb2016-03-13 15:35:56 -040020 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) {
payton.rehlf8cb3932023-06-13 11:20:44 -070026 const std::string stat = ReadFileToStringOrDie("/proc/self/stat");
Brian Silverman61175fb2016-03-13 15:35:56 -040027 EXPECT_EQ('\n', stat[stat.size() - 1]);
payton.rehlf8cb3932023-06-13 11:20:44 -070028 const std::string my_pid = ::std::to_string(getpid());
Brian Silverman61175fb2016-03-13 15:35:56 -040029 EXPECT_EQ(my_pid, stat.substr(0, my_pid.size()));
30}
31
payton.rehlf8cb3932023-06-13 11:20:44 -070032// Basic test of maybe reading a normal file.
33TEST(FileTest, MaybeReadNormalFile) {
34 const std::string tmpdir(aos::testing::TestTmpDir());
35 const std::string test_file = tmpdir + "/test_file";
36 ASSERT_EQ(0, system(("echo contents > " + test_file).c_str()));
37 EXPECT_EQ("contents\n", MaybeReadFileToString(test_file).value());
38}
39
40// Tests maybe reading a file with 0 size, among other weird things.
41TEST(FileTest, MaybeReadSpecialFile) {
42 const std::optional<std::string> stat =
43 MaybeReadFileToString("/proc/self/stat");
44 ASSERT_TRUE(stat.has_value());
45 EXPECT_EQ('\n', (*stat)[stat->size() - 1]);
46 const std::string my_pid = std::to_string(getpid());
47 EXPECT_EQ(my_pid, stat->substr(0, my_pid.size()));
48}
49
50// Tests maybe reading a non-existent file, and not fatally erroring.
51TEST(FileTest, MaybeReadNonexistentFile) {
52 const std::optional<std::string> contents = MaybeReadFileToString("/dne");
53 ASSERT_FALSE(contents.has_value());
54}
55
James Kuszmaulf8178092020-05-10 18:46:45 -070056// Tests that the PathExists function works under normal conditions.
57TEST(FileTest, PathExistsTest) {
James Kuszmaulfd43f4e2022-12-16 15:19:35 -080058 const std::string tmpdir(aos::testing::TestTmpDir());
James Kuszmaulf8178092020-05-10 18:46:45 -070059 const std::string test_file = tmpdir + "/test_file";
60 // Make sure the test_file doesn't exist.
61 unlink(test_file.c_str());
62 EXPECT_FALSE(PathExists(test_file));
63
64 WriteStringToFileOrDie(test_file, "abc");
65
66 EXPECT_TRUE(PathExists(test_file));
67}
68
James Kuszmaul0625b0d2022-09-21 11:38:48 -070069// Basic test of reading a normal file.
70TEST(FileTest, ReadNormalFileNoMalloc) {
James Kuszmaulfd43f4e2022-12-16 15:19:35 -080071 const ::std::string tmpdir(aos::testing::TestTmpDir());
James Kuszmaul0625b0d2022-09-21 11:38:48 -070072 const ::std::string test_file = tmpdir + "/test_file";
James Kuszmaulfd43f4e2022-12-16 15:19:35 -080073 // Make sure to include a string long enough to avoid small string
74 // optimization.
75 ASSERT_EQ(0, system(("echo 123456789 > " + test_file).c_str()));
James Kuszmaul0625b0d2022-09-21 11:38:48 -070076
77 FileReader reader(test_file);
78
James Kuszmaul0625b0d2022-09-21 11:38:48 -070079 aos::ScopedRealtime realtime;
James Kuszmaul5a88d412023-01-27 15:55:55 -080080 {
81 std::array<char, 20> contents;
82 absl::Span<char> read_result =
83 reader.ReadContents({contents.data(), contents.size()});
84 EXPECT_EQ("123456789\n",
85 std::string_view(read_result.data(), read_result.size()));
86 }
87 {
88 std::optional<std::array<char, 10>> read_result = reader.ReadString<10>();
89 ASSERT_TRUE(read_result.has_value());
90 EXPECT_EQ("123456789\n",
91 std::string_view(read_result->data(), read_result->size()));
92 }
93 EXPECT_EQ(123456789, reader.ReadInt32());
James Kuszmaulfd43f4e2022-12-16 15:19:35 -080094}
95
96// Tests that we can write to a file without malloc'ing.
97TEST(FileTest, WriteNormalFileNoMalloc) {
98 const ::std::string tmpdir(aos::testing::TestTmpDir());
99 const ::std::string test_file = tmpdir + "/test_file";
100
101 FileWriter writer(test_file);
102
James Kuszmaulfd43f4e2022-12-16 15:19:35 -0800103 FileWriter::WriteResult result;
104 {
105 aos::ScopedRealtime realtime;
106 result = writer.WriteBytes("123456789");
107 }
108 EXPECT_EQ(9, result.bytes_written);
109 EXPECT_EQ(9, result.return_code);
110 EXPECT_EQ("123456789", ReadFileToStringOrDie(test_file));
111}
112
113// Tests that if we fail to write a file that the error code propagates
114// correctly.
115TEST(FileTest, WriteFileError) {
116 const ::std::string tmpdir(aos::testing::TestTmpDir());
117 const ::std::string test_file = tmpdir + "/test_file";
118
119 // Open with only read permissions; this should cause things to fail.
120 FileWriter writer(test_file, S_IRUSR);
121
122 // Mess up the file management by closing the file descriptor.
123 PCHECK(0 == close(writer.fd()));
124
James Kuszmaulfd43f4e2022-12-16 15:19:35 -0800125 FileWriter::WriteResult result;
126 {
127 aos::ScopedRealtime realtime;
128 result = writer.WriteBytes("123456789");
129 }
130 EXPECT_EQ(0, result.bytes_written);
131 EXPECT_EQ(-1, result.return_code);
132 EXPECT_EQ("", ReadFileToStringOrDie(test_file));
James Kuszmaul0625b0d2022-09-21 11:38:48 -0700133}
134
Brian Silverman61175fb2016-03-13 15:35:56 -0400135} // namespace testing
136} // namespace util
137} // namespace aos