1 #include <cppunit/CompilerOutputter.h>
2 #include <cppunit/TestCaller.h>
3 #include <cppunit/TestFixture.h>
4 #include <cppunit/extensions/TestFactoryRegistry.h>
5 #include <cppunit/ui/text/TestRunner.h>
6
7 #include <fcntl.h>
8 #include <sys/stat.h>
9 #include <sys/types.h>
10 #include <unistd.h>
11 #include <typeinfo>
12
13 #include "fileerror.hh"
14 #include "filehelper.hh"
15 #include "testpaths.h"
16 #include "yapet10file.hh"
17 #include "yapet20file.hh"
18
19 constexpr auto TEST_FILE{BUILDDIR "/yapet-filehelper-test"};
20
21 class FileHelperTest : public CppUnit::TestFixture {
22 public:
suite()23 static CppUnit::TestSuite *suite() {
24 CppUnit::TestSuite *suiteOfTests =
25 new CppUnit::TestSuite("File Helper Test");
26
27 suiteOfTests->addTest(new CppUnit::TestCaller<FileHelperTest>{
28 "reading file identifier should fail on empty file",
29 &FileHelperTest::readEmptyFile});
30
31 suiteOfTests->addTest(new CppUnit::TestCaller<FileHelperTest>{
32 "reading file identifier should fail on unknown file",
33 &FileHelperTest::failReadIdentifierUnknownFile});
34
35 suiteOfTests->addTest(new CppUnit::TestCaller<FileHelperTest>{
36 "should read YAPET 1.0 file identifier",
37 &FileHelperTest::readYapet10FileIdentifier});
38
39 suiteOfTests->addTest(new CppUnit::TestCaller<FileHelperTest>{
40 "should read YAPET 2.0 file identifier",
41 &FileHelperTest::readYapet20FileIdentifier});
42
43 suiteOfTests->addTest(new CppUnit::TestCaller<FileHelperTest>{
44 "should get YAPET 1.0 file", &FileHelperTest::getYapet10File});
45 suiteOfTests->addTest(new CppUnit::TestCaller<FileHelperTest>{
46 "should get YAPET 2.0 file", &FileHelperTest::getYapet20File});
47
48 suiteOfTests->addTest(new CppUnit::TestCaller<FileHelperTest>{
49 "should read YAPET 1.0 meta data",
50 &FileHelperTest::readYapet10MetaData});
51 suiteOfTests->addTest(new CppUnit::TestCaller<FileHelperTest>{
52 "should read YAPET 2.0 meta data",
53 &FileHelperTest::readYapet20MetaData});
54
55 return suiteOfTests;
56 }
57
openFile()58 int openFile() {
59 auto fd = ::open(TEST_FILE, O_CREAT | O_TRUNC | O_RDWR,
60 S_IRWXU | S_IRWXG | S_IRWXO);
61 if (fd < 0) {
62 throw std::runtime_error{"Error creating file"};
63 }
64
65 return fd;
66 }
67
createEmptyFile()68 void createEmptyFile() {
69 auto fd = openFile();
70
71 ::close(fd);
72 }
73
setUp()74 void setUp() { ::unlink(TEST_FILE); }
75
tearDown()76 void tearDown() { ::unlink(TEST_FILE); }
77
readEmptyFile()78 void readEmptyFile() {
79 createEmptyFile();
80
81 CPPUNIT_ASSERT_THROW(yapet::readFileIdentifier(TEST_FILE),
82 yapet::FileFormatError);
83 }
84
failReadIdentifierUnknownFile()85 void failReadIdentifierUnknownFile() {
86 int fd{openFile()};
87
88 write(fd, "bla", 3);
89 close(fd);
90
91 CPPUNIT_ASSERT_THROW(yapet::readFileIdentifier(TEST_FILE),
92 yapet::FileFormatError);
93 }
94
makeYapet10File()95 void makeYapet10File() {
96 int fd{openFile()};
97
98 write(fd, yapet::Yapet10File::RECOGNITION_STRING,
99 yapet::Yapet10File::RECOGNITION_STRING_SIZE);
100 close(fd);
101 }
102
readYapet10FileIdentifier()103 void readYapet10FileIdentifier() {
104 makeYapet10File();
105
106 auto actual{yapet::readFileIdentifier(TEST_FILE)};
107 auto expected{
108 yapet::toSecureArray(yapet::Yapet10File::RECOGNITION_STRING,
109 yapet::Yapet10File::RECOGNITION_STRING_SIZE)};
110
111 CPPUNIT_ASSERT(actual == expected);
112
113 CPPUNIT_ASSERT(yapet::isFileType(expected, TEST_FILE));
114
115 auto unexpected{
116 yapet::toSecureArray(yapet::Yapet20File::RECOGNITION_STRING,
117 yapet::Yapet20File::RECOGNITION_STRING_SIZE)};
118 CPPUNIT_ASSERT(!yapet::isFileType(unexpected, TEST_FILE));
119 }
120
makeYapet20File()121 void makeYapet20File() {
122 int fd{openFile()};
123
124 write(fd, yapet::Yapet20File::RECOGNITION_STRING,
125 yapet::Yapet20File::RECOGNITION_STRING_SIZE);
126 close(fd);
127 }
128
readYapet20FileIdentifier()129 void readYapet20FileIdentifier() {
130 makeYapet20File();
131
132 auto actual{yapet::readFileIdentifier(TEST_FILE)};
133 auto expected{
134 yapet::toSecureArray(yapet::Yapet20File::RECOGNITION_STRING,
135 yapet::Yapet20File::RECOGNITION_STRING_SIZE)};
136
137 CPPUNIT_ASSERT(actual == expected);
138
139 CPPUNIT_ASSERT(yapet::isFileType(expected, TEST_FILE));
140
141 auto unexpected{
142 yapet::toSecureArray(yapet::Yapet10File::RECOGNITION_STRING,
143 yapet::Yapet10File::RECOGNITION_STRING_SIZE)};
144
145 CPPUNIT_ASSERT(!yapet::isFileType(unexpected, TEST_FILE));
146 }
147
getYapet10File()148 void getYapet10File() {
149 yapet::SecureArray metaData{};
150 yapet::SecureArray header{yapet::toSecureArray("Header")};
151 try {
152 yapet::Yapet10File file{TEST_FILE, true, false};
153 file.open();
154 file.writeIdentifier();
155 file.writeUnencryptedMetaData(metaData);
156 file.writeHeader(header);
157 } catch (...) {
158 CPPUNIT_FAIL("Unexpected exception");
159 }
160
161 auto file{yapet::getFile(TEST_FILE, false)};
162 #pragma clang diagnostic push
163 #pragma clang diagnostic ignored "-Wpotentially-evaluated-expression"
164 CPPUNIT_ASSERT(typeid(*file) == typeid(yapet::Yapet10File));
165 #pragma clang diagnostic pop
166 }
167
getYapet20File()168 void getYapet20File() {
169 yapet::SecureArray metaData{yapet::toSecureArray("MetaData")};
170 yapet::SecureArray header{yapet::toSecureArray("Header")};
171 try {
172 yapet::Yapet20File file{TEST_FILE, true, false};
173 file.open();
174 file.writeIdentifier();
175 file.writeUnencryptedMetaData(metaData);
176 file.writeHeader(header);
177 } catch (...) {
178 CPPUNIT_FAIL("Unexpected exception");
179 }
180
181 auto file{yapet::getFile(TEST_FILE, false)};
182 #pragma clang diagnostic push
183 #pragma clang diagnostic ignored "-Wpotentially-evaluated-expression"
184 CPPUNIT_ASSERT(typeid(*file) == typeid(yapet::Yapet20File));
185 #pragma clang diagnostic pop
186 }
187
readYapet10MetaData()188 void readYapet10MetaData() {
189 yapet::MetaData metaData{};
190 yapet::SecureArray header{yapet::toSecureArray("Header")};
191 try {
192 yapet::Yapet10File file{TEST_FILE, true, false};
193 file.open();
194 file.writeIdentifier();
195 file.writeUnencryptedMetaData(metaData.serialize());
196 file.writeHeader(header);
197 } catch (...) {
198 CPPUNIT_FAIL("Unexpected exception");
199 }
200
201 auto actual{yapet::readMetaData(TEST_FILE, false)};
202 CPPUNIT_ASSERT(actual.size() == metaData.size());
203 }
204
readYapet20MetaData()205 void readYapet20MetaData() {
206 yapet::MetaData metaData{};
207 metaData.setValue("a", 42);
208 metaData.setValue("b", 84);
209
210 yapet::SecureArray header{yapet::toSecureArray("Header")};
211 try {
212 yapet::Yapet20File file{TEST_FILE, true, false};
213 file.open();
214 file.writeIdentifier();
215 file.writeUnencryptedMetaData(metaData.serialize());
216 file.writeHeader(header);
217 } catch (...) {
218 CPPUNIT_FAIL("Unexpected exception");
219 }
220
221 auto actual{yapet::readMetaData(TEST_FILE, false)};
222 CPPUNIT_ASSERT(actual.size() == metaData.size());
223 CPPUNIT_ASSERT(actual.getValue("a") == metaData.getValue("a"));
224 CPPUNIT_ASSERT(actual.getValue("b") == metaData.getValue("b"));
225 }
226 };
227
main()228 int main() {
229 CppUnit::TextUi::TestRunner runner;
230 runner.addTest(FileHelperTest::suite());
231 return runner.run() ? 0 : 1;
232 }