clear HitEof flag in FileFd::Seek
[ntk/apt.git] / test / libapt / fileutl_test.cc
CommitLineData
453b82a3
DK
1#include <config.h>
2
488011fa
MV
3#include <apt-pkg/error.h>
4#include <apt-pkg/fileutl.h>
f7feb041 5#include <apt-pkg/aptconfiguration.h>
488011fa 6
488011fa
MV
7#include <string>
8#include <vector>
488011fa 9#include <stdlib.h>
f22b65b4 10#include <sys/stat.h>
f7feb041 11#include <string.h>
488011fa 12
453b82a3 13#include "assert.h"
488011fa 14
f7feb041
DK
15static void assertStringEquals(char const * const expect, char const * const got, unsigned long const line) {
16 if (strncmp(expect, got, strlen(expect)) == 0)
17 return;
18 OutputAssertEqual(expect, "==", got, line);
19}
20#define strequals(x,y) assertStringEquals(x, y, __LINE__)
21
f22b65b4 22static bool
f7feb041 23TestFileFd(mode_t const a_umask, mode_t const ExpectedFilePermission, unsigned int const filemode, APT::Configuration::Compressor const &compressor)
f22b65b4
MV
24{
25 FileFd f;
26 struct stat buf;
bb93178b
DK
27 static const char* fname = "apt-filefd-test.txt";
28 if (FileExists(fname) == true)
29 equals(unlink(fname), 0);
f22b65b4
MV
30
31 umask(a_umask);
f7feb041
DK
32 equals(f.Open(fname, filemode, compressor), true);
33 equals(f.IsOpen(), true);
34 equals(f.Failed(), false);
35 equals(umask(a_umask), a_umask);
36
bb93178b 37 std::string test = "This is a test!\n";
f7feb041
DK
38 equals(f.Write(test.c_str(), test.size()), true);
39 equals(f.IsOpen(), true);
40 equals(f.Failed(), false);
41
f22b65b4 42 f.Close();
f7feb041
DK
43 equals(f.IsOpen(), false);
44 equals(f.Failed(), false);
45
46 equals(f.Open(fname, FileFd::ReadOnly, compressor), true);
f7feb041
DK
47 equals(f.IsOpen(), true);
48 equals(f.Failed(), false);
bb93178b
DK
49 equals(f.Eof(), false);
50 equalsNot(f.FileSize(), 0);
51 equals(f.Failed(), false);
52 equalsNot(f.ModificationTime(), 0);
53 equals(f.Failed(), false);
f7feb041 54
bb93178b
DK
55 // ensure the memory is as predictably messed up
56# define APT_INIT_READBACK \
57 char readback[20]; \
58 memset(readback, 'D', sizeof(readback)/sizeof(readback[0])); \
59 readback[19] = '\0';
f7feb041 60 {
bb93178b 61 APT_INIT_READBACK
f7feb041
DK
62 char const * const expect = "This";
63 equals(f.Read(readback, strlen(expect)), true);
64 equals(f.Failed(), false);
65 equals(f.Eof(), false);
66 strequals(expect, readback);
67 equals(strlen(expect), f.Tell());
68 }
69 {
bb93178b
DK
70 APT_INIT_READBACK
71 char const * const expect = "test!\n";
f7feb041
DK
72 equals(f.Skip((test.size() - f.Tell()) - strlen(expect)), true);
73 equals(f.Read(readback, strlen(expect)), true);
74 equals(f.Failed(), false);
75 equals(f.Eof(), false);
76 strequals(expect, readback);
77 equals(test.size(), f.Tell());
78 }
bb93178b
DK
79 {
80 APT_INIT_READBACK
81 equals(f.Seek(0), true);
82 equals(f.Eof(), false);
83 equals(f.Read(readback, 20, true), true);
84 equals(f.Failed(), false);
85 equals(f.Eof(), true);
86 strequals(test.c_str(), readback);
87 equals(f.Size(), f.Tell());
88 }
89 {
90 APT_INIT_READBACK
91 equals(f.Seek(0), true);
92 equals(f.Eof(), false);
93 equals(f.Read(readback, test.size(), true), true);
94 equals(f.Failed(), false);
95 equals(f.Eof(), false);
96 strequals(test.c_str(), readback);
97 equals(f.Size(), f.Tell());
98 }
99 {
100 APT_INIT_READBACK
101 equals(f.Seek(0), true);
102 equals(f.Eof(), false);
103 unsigned long long actual;
104 equals(f.Read(readback, 20, &actual), true);
105 equals(f.Failed(), false);
106 equals(f.Eof(), true);
107 equals(test.size(), actual);
108 strequals(test.c_str(), readback);
109 equals(f.Size(), f.Tell());
110 }
111 {
112 APT_INIT_READBACK
113 equals(f.Seek(0), true);
114 equals(f.Eof(), false);
115 f.ReadLine(readback, 20);
116 equals(f.Failed(), false);
117 equals(f.Eof(), false);
118 equals(test, readback);
119 equals(f.Size(), f.Tell());
120 }
121 {
122 APT_INIT_READBACK
123 equals(f.Seek(0), true);
124 equals(f.Eof(), false);
125 char const * const expect = "This";
126 f.ReadLine(readback, strlen(expect) + 1);
127 equals(f.Failed(), false);
128 equals(f.Eof(), false);
129 strequals(expect, readback);
130 equals(strlen(expect), f.Tell());
131 }
132#undef APT_INIT_READBACK
f7feb041
DK
133
134 f.Close();
135 equals(f.IsOpen(), false);
136 equals(f.Failed(), false);
137
138 // regression test for permission bug LP: #1304657
f22b65b4
MV
139 if (stat(fname, &buf) < 0)
140 {
141 _error->Errno("stat", "failed to stat");
f22b65b4
MV
142 return false;
143 }
bb93178b 144 equals(unlink(fname), 0);
f22b65b4
MV
145 equals(buf.st_mode & 0777, ExpectedFilePermission);
146 return true;
147}
148
f7feb041 149static bool TestFileFd(unsigned int const filemode)
488011fa 150{
bb93178b
DK
151 std::vector<APT::Configuration::Compressor> compressors = APT::Configuration::getCompressors();
152
153 // testing the (un)compress via pipe, as the 'real' compressors are usually built in via libraries
154 compressors.push_back(APT::Configuration::Compressor("rev", ".reversed", "rev", NULL, NULL, 42));
155 //compressors.push_back(APT::Configuration::Compressor("cat", ".ident", "cat", NULL, NULL, 42));
156
f7feb041
DK
157 for (std::vector<APT::Configuration::Compressor>::const_iterator c = compressors.begin(); c != compressors.end(); ++c)
158 {
159 if ((filemode & FileFd::ReadWrite) == FileFd::ReadWrite &&
160 (c->Name.empty() != true && c->Binary.empty() != true))
161 continue;
162 if (TestFileFd(0002, 0664, filemode, *c) == false ||
163 TestFileFd(0022, 0644, filemode, *c) == false ||
164 TestFileFd(0077, 0600, filemode, *c) == false ||
165 TestFileFd(0026, 0640, filemode, *c) == false)
166 {
167 _error->DumpErrors();
168 return false;
169 }
170 }
171 return true;
172}
488011fa 173
bb93178b 174int main(int const argc, char const * const * const argv)
f7feb041 175{
bb93178b
DK
176 std::string startdir;
177 if (argc > 1 && DirectoryExists(argv[1]) == true) {
178 startdir = SafeGetCWD();
179 equals(chdir(argv[1]), 0);
180 }
f7feb041
DK
181 if (TestFileFd(FileFd::WriteOnly | FileFd::Create) == false ||
182 TestFileFd(FileFd::WriteOnly | FileFd::Create | FileFd::Empty) == false ||
183 TestFileFd(FileFd::WriteOnly | FileFd::Create | FileFd::Exclusive) == false ||
184 TestFileFd(FileFd::WriteOnly | FileFd::Atomic) == false ||
185 TestFileFd(FileFd::WriteOnly | FileFd::Create | FileFd::Atomic) == false ||
186 // short-hands for ReadWrite with these modes
187 TestFileFd(FileFd::WriteEmpty) == false ||
188 TestFileFd(FileFd::WriteAny) == false ||
189 TestFileFd(FileFd::WriteTemp) == false ||
190 TestFileFd(FileFd::WriteAtomic) == false)
f22b65b4
MV
191 {
192 return 1;
193 }
bb93178b
DK
194 if (startdir.empty() == false)
195 equals(chdir(startdir.c_str()), 0);
f22b65b4 196
f7feb041 197 std::vector<std::string> files;
488011fa
MV
198 // normal match
199 files = Glob("*.lst");
200 if (files.size() != 1)
201 {
202 _error->DumpErrors();
203 return 1;
204 }
205
206 // not there
207 files = Glob("xxxyyyzzz");
208 if (files.size() != 0 || _error->PendingError())
209 {
210 _error->DumpErrors();
211 return 1;
212 }
213
214 // many matches (number is a bit random)
215 files = Glob("*.cc");
216 if (files.size() < 10)
217 {
218 _error->DumpErrors();
219 return 1;
220 }
221
a077861a
MV
222 // GetTempDir()
223 unsetenv("TMPDIR");
224 equals(GetTempDir(), "/tmp");
225
226 setenv("TMPDIR", "", 1);
227 equals(GetTempDir(), "/tmp");
228
229 setenv("TMPDIR", "/not-there-no-really-not", 1);
230 equals(GetTempDir(), "/tmp");
231
232 setenv("TMPDIR", "/usr", 1);
233 equals(GetTempDir(), "/usr");
234
488011fa
MV
235 return 0;
236}