blob: 0067f1a3c73c8f769a4ce0483c87c2cbfdd42c8b [file] [log] [blame]
Shawn McCarneyf3633f62020-09-02 10:34:52 -05001/**
2 * Copyright © 2020 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "ffdc_file.hpp"
17#include "test_utils.hpp"
18
19#include <errno.h> // for errno
20#include <fcntl.h> // for fcntl()
21#include <string.h> // for memset(), size_t
22#include <sys/types.h> // for lseek()
23#include <unistd.h> // for read(), write(), lseek(), fcntl(), close()
24
25#include <exception>
26#include <filesystem>
27
28#include <gtest/gtest.h>
29
30using namespace phosphor::power::regulators;
31using namespace phosphor::power::regulators::test_utils;
32namespace fs = std::filesystem;
33
34/**
35 * Returns whether the specified file descriptor is valid/open.
36 *
37 * @param[in] fd - File descriptor
38 * @return true if descriptor is valid/open, false otherwise
39 */
40bool isValid(int fd)
41{
42 return (fcntl(fd, F_GETFL) != -1) || (errno != EBADF);
43}
44
45TEST(FFDCFileTests, Constructor)
46{
47 // Test where only the FFDCFormat parameter is specified
48 {
49 FFDCFile file{FFDCFormat::JSON};
50 EXPECT_NE(file.getFileDescriptor(), -1);
51 EXPECT_TRUE(isValid(file.getFileDescriptor()));
52 EXPECT_EQ(file.getFormat(), FFDCFormat::JSON);
53 EXPECT_FALSE(file.getPath().empty());
54 EXPECT_TRUE(fs::exists(file.getPath()));
55 EXPECT_EQ(file.getSubType(), 0);
56 EXPECT_EQ(file.getVersion(), 0);
57 }
58
59 // Test where all constructor parameters are specified
60 {
61 FFDCFile file{FFDCFormat::Custom, 2, 3};
62 EXPECT_NE(file.getFileDescriptor(), -1);
63 EXPECT_TRUE(isValid(file.getFileDescriptor()));
64 EXPECT_EQ(file.getFormat(), FFDCFormat::Custom);
65 EXPECT_FALSE(file.getPath().empty());
66 EXPECT_TRUE(fs::exists(file.getPath()));
67 EXPECT_EQ(file.getSubType(), 2);
68 EXPECT_EQ(file.getVersion(), 3);
69 }
70
71 // Note: The case where open() fails currently needs to be tested manually
72}
73
74TEST(FFDCFileTests, GetFileDescriptor)
75{
76 FFDCFile file{FFDCFormat::JSON};
77 int fd = file.getFileDescriptor();
78 EXPECT_NE(fd, -1);
79 EXPECT_TRUE(isValid(fd));
80
81 // Write some data to the file
82 char buffer[] = "This is some sample data";
83 size_t count = sizeof(buffer);
84 EXPECT_EQ(write(fd, buffer, count), count);
85
86 // Seek back to the beginning of the file
87 EXPECT_EQ(lseek(fd, 0, SEEK_SET), 0);
88
89 // Clear buffer
90 memset(buffer, '\0', count);
91 EXPECT_STREQ(buffer, "");
92
93 // Read and verify file contents
94 EXPECT_EQ(read(fd, buffer, count), count);
95 EXPECT_STREQ(buffer, "This is some sample data");
96}
97
98TEST(FFDCFileTests, GetFormat)
99{
100 // Test where 'Text' was specified
101 {
102 FFDCFile file{FFDCFormat::Text};
103 EXPECT_EQ(file.getFormat(), FFDCFormat::Text);
104 }
105
106 // Test where 'Custom' was specified
107 {
108 FFDCFile file{FFDCFormat::Custom, 2, 3};
109 EXPECT_EQ(file.getFormat(), FFDCFormat::Custom);
110 }
111}
112
113TEST(FFDCFileTests, GetPath)
114{
115 FFDCFile file{FFDCFormat::JSON};
116 EXPECT_FALSE(file.getPath().empty());
117 EXPECT_TRUE(fs::exists(file.getPath()));
118}
119
120TEST(FFDCFileTests, GetSubType)
121{
122 // Test where subType was not specified
123 {
124 FFDCFile file{FFDCFormat::JSON};
125 EXPECT_EQ(file.getSubType(), 0);
126 }
127
128 // Test where subType was specified
129 {
130 FFDCFile file{FFDCFormat::Custom, 3, 2};
131 EXPECT_EQ(file.getSubType(), 3);
132 }
133}
134
135TEST(FFDCFileTests, GetVersion)
136{
137 // Test where version was not specified
138 {
139 FFDCFile file{FFDCFormat::JSON};
140 EXPECT_EQ(file.getVersion(), 0);
141 }
142
143 // Test where version was specified
144 {
145 FFDCFile file{FFDCFormat::Custom, 2, 5};
146 EXPECT_EQ(file.getVersion(), 5);
147 }
148}
149
150TEST(FFDCFileTests, Remove)
151{
152 // Test where works
153 {
154 FFDCFile file{FFDCFormat::JSON};
155 EXPECT_NE(file.getFileDescriptor(), -1);
156 EXPECT_TRUE(isValid(file.getFileDescriptor()));
157 EXPECT_FALSE(file.getPath().empty());
158 EXPECT_TRUE(fs::exists(file.getPath()));
159
160 int fd = file.getFileDescriptor();
161 fs::path path = file.getPath();
162
163 file.remove();
164 EXPECT_EQ(file.getFileDescriptor(), -1);
165 EXPECT_TRUE(file.getPath().empty());
166
167 EXPECT_FALSE(isValid(fd));
168 EXPECT_FALSE(fs::exists(path));
169 }
170
171 // Test where file was already removed
172 {
173 FFDCFile file{FFDCFormat::JSON};
174 EXPECT_NE(file.getFileDescriptor(), -1);
175 EXPECT_FALSE(file.getPath().empty());
176
177 file.remove();
178 EXPECT_EQ(file.getFileDescriptor(), -1);
179 EXPECT_TRUE(file.getPath().empty());
180
181 file.remove();
182 EXPECT_EQ(file.getFileDescriptor(), -1);
183 EXPECT_TRUE(file.getPath().empty());
184 }
185
186 // Test where closing the file fails
187 {
188 FFDCFile file{FFDCFormat::JSON};
189 int fd = file.getFileDescriptor();
190 EXPECT_TRUE(isValid(fd));
191
192 EXPECT_EQ(close(fd), 0);
193 EXPECT_FALSE(isValid(fd));
194
195 try
196 {
197 file.remove();
198 ADD_FAILURE() << "Should not have reached this line.";
199 }
200 catch (const std::exception& e)
201 {
202 EXPECT_NE(std::string{e.what()}.find("Unable to close FFDC file: "),
203 std::string::npos);
204 }
205 }
206
207 // Test where deleting the file fails
208 {
209 FFDCFile file{FFDCFormat::JSON};
210 fs::path path = file.getPath();
211 EXPECT_TRUE(fs::exists(path));
212
213 makeFileUnRemovable(path);
214 try
215 {
216 file.remove();
217 ADD_FAILURE() << "Should not have reached this line.";
218 }
219 catch (const std::exception& e)
220 {
221 // This is expected. Exception message will vary.
222 }
223 makeFileRemovable(path);
224 }
225}