root / trunk / hammock / src / net35 / ICSharpCode.SharpZipLib.Silverlight.Tests / Tar / TarTests.cs @ 0eea575a
History | View | Annotate | Download (15.1 kB)
1 |
using System; |
---|---|
2 |
using System.IO; |
3 |
using System.Text; |
4 |
using ICSharpCode.SharpZipLib.Silverlight.Tar; |
5 |
using NUnit.Framework; |
6 |
|
7 |
namespace ICSharpCode.SharpZipLib.Tests.Tar { |
8 |
|
9 |
/// <summary> |
10 |
/// This class contains test cases for Tar archive handling |
11 |
/// </summary> |
12 |
[TestFixture] |
13 |
public class TarTestSuite |
14 |
{ |
15 |
int entryCount; |
16 |
|
17 |
void EntryCounter(TarArchive archive, TarEntry entry, string message) |
18 |
{ |
19 |
entryCount++; |
20 |
} |
21 |
|
22 |
/// <summary> |
23 |
/// Test that an empty archive can be created and when read has 0 entries in it |
24 |
/// </summary> |
25 |
[Test] |
26 |
[Category("Tar")] |
27 |
public void EmptyTar() |
28 |
{ |
29 |
MemoryStream ms = new MemoryStream(); |
30 |
int recordSize = 0; |
31 |
using ( TarArchive tarOut = TarArchive.CreateOutputTarArchive(ms) ) |
32 |
{ |
33 |
recordSize = tarOut.RecordSize; |
34 |
} |
35 |
|
36 |
Assert.IsTrue(ms.GetBuffer().Length > 0, "Archive size must be > zero"); |
37 |
Assert.AreEqual(ms.GetBuffer().Length % recordSize, 0, "Archive size must be a multiple of record size"); |
38 |
|
39 |
MemoryStream ms2 = new MemoryStream(); |
40 |
ms2.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length); |
41 |
ms2.Seek(0, SeekOrigin.Begin); |
42 |
|
43 |
using ( TarArchive tarIn = TarArchive.CreateInputTarArchive(ms2) ) |
44 |
{ |
45 |
entryCount = 0; |
46 |
tarIn.ProgressMessageEvent += new ProgressMessageHandler(EntryCounter); |
47 |
tarIn.ListContents(); |
48 |
Assert.AreEqual(0, entryCount, "Expected 0 tar entries"); |
49 |
} |
50 |
} |
51 |
/// <summary> |
52 |
/// Check that the tar block factor can be varied successfully. |
53 |
/// </summary> |
54 |
[Test] |
55 |
public void BlockFactorHandling() |
56 |
{ |
57 |
const int MinimumBlockFactor = 1; |
58 |
const int MaximumBlockFactor = 64; |
59 |
const int FillFactor = 2; |
60 |
|
61 |
for ( int factor = MinimumBlockFactor; factor < MaximumBlockFactor; ++factor) |
62 |
{ |
63 |
MemoryStream ms = new MemoryStream(); |
64 |
|
65 |
using ( TarOutputStream tarOut = new TarOutputStream(ms, factor) ) |
66 |
{ |
67 |
TarEntry entry = TarEntry.CreateTarEntry("TestEntry"); |
68 |
entry.Size = (TarBuffer.BlockSize * factor * FillFactor); |
69 |
tarOut.PutNextEntry(entry); |
70 |
|
71 |
byte[] buffer = new byte[TarBuffer.BlockSize]; |
72 |
|
73 |
Random r = new Random(); |
74 |
r.NextBytes(buffer); |
75 |
|
76 |
// Last block is a partial one |
77 |
for ( int i = 0; i < factor * FillFactor; ++i) |
78 |
{ |
79 |
tarOut.Write(buffer, 0, buffer.Length); |
80 |
} |
81 |
} |
82 |
|
83 |
byte[] tarData = ms.ToArray(); |
84 |
Assert.IsNotNull(tarData, "Data written is null"); |
85 |
|
86 |
// Blocks = Header + Data Blocks + Zero block + Record trailer |
87 |
int usedBlocks = 1 + (factor * FillFactor) + 1; |
88 |
int totalBlocks = usedBlocks + (factor - 1); |
89 |
totalBlocks /= factor; |
90 |
totalBlocks *= factor; |
91 |
|
92 |
Assert.AreEqual(TarBuffer.BlockSize * totalBlocks, tarData.Length, "Tar file should contain {0} blocks in length", |
93 |
totalBlocks); |
94 |
|
95 |
if ( usedBlocks < totalBlocks ) |
96 |
{ |
97 |
// Start at first byte after header. |
98 |
int byteIndex = TarBuffer.BlockSize * ((factor * FillFactor)+ 1); |
99 |
while ( byteIndex < tarData.Length ) |
100 |
{ |
101 |
int blockNumber = byteIndex / TarBuffer.BlockSize; |
102 |
int offset = blockNumber % TarBuffer.BlockSize; |
103 |
Assert.AreEqual(0, tarData[byteIndex], |
104 |
string.Format("Trailing block data should be null iteration {0} block {1} offset {2} index {3}", |
105 |
factor, |
106 |
blockNumber, offset, byteIndex)); |
107 |
byteIndex += 1; |
108 |
} |
109 |
} |
110 |
} |
111 |
} |
112 |
|
113 |
|
114 |
/// <summary> |
115 |
/// Check that the tar trailer only contains nulls. |
116 |
/// </summary> |
117 |
[Test] |
118 |
public void TrailerContainsNulls() |
119 |
{ |
120 |
const int TestBlockFactor = 3; |
121 |
|
122 |
for ( int iteration = 0; iteration < TestBlockFactor * 2; ++iteration) |
123 |
{ |
124 |
MemoryStream ms = new MemoryStream(); |
125 |
|
126 |
using ( TarOutputStream tarOut = new TarOutputStream(ms, TestBlockFactor) ) |
127 |
{ |
128 |
TarEntry entry = TarEntry.CreateTarEntry("TestEntry"); |
129 |
if ( iteration > 0 ) |
130 |
{ |
131 |
entry.Size = (TarBuffer.BlockSize * (iteration - 1)) + 9; |
132 |
} |
133 |
tarOut.PutNextEntry(entry); |
134 |
|
135 |
byte[] buffer = new byte[TarBuffer.BlockSize]; |
136 |
|
137 |
Random r = new Random(); |
138 |
r.NextBytes(buffer); |
139 |
|
140 |
if ( iteration > 0 ) |
141 |
{ |
142 |
for ( int i = 0; i < iteration - 1; ++i ) |
143 |
{ |
144 |
tarOut.Write(buffer, 0, buffer.Length); |
145 |
} |
146 |
|
147 |
// Last block is a partial one |
148 |
for ( int i = 1; i < 10; ++i) |
149 |
{ |
150 |
tarOut.WriteByte((byte)i); |
151 |
} |
152 |
} |
153 |
} |
154 |
|
155 |
byte[] tarData = ms.ToArray(); |
156 |
Assert.IsNotNull(tarData, "Data written is null"); |
157 |
|
158 |
// Blocks = Header + Data Blocks + Zero block + Record trailer |
159 |
int usedBlocks = 1 + iteration + 1; |
160 |
int totalBlocks = usedBlocks + (TestBlockFactor - 1); |
161 |
totalBlocks /= TestBlockFactor; |
162 |
totalBlocks *= TestBlockFactor; |
163 |
|
164 |
Assert.AreEqual(TarBuffer.BlockSize * totalBlocks, tarData.Length, |
165 |
string.Format("Tar file should be {0} blocks in length", totalBlocks)); |
166 |
|
167 |
if ( usedBlocks < totalBlocks ) |
168 |
{ |
169 |
// Start at first byte after header. |
170 |
int byteIndex = TarBuffer.BlockSize * (iteration + 1); |
171 |
while ( byteIndex < tarData.Length ) |
172 |
{ |
173 |
int blockNumber = byteIndex / TarBuffer.BlockSize; |
174 |
int offset = blockNumber % TarBuffer.BlockSize; |
175 |
Assert.AreEqual(0, tarData[byteIndex], |
176 |
string.Format("Trailing block data should be null iteration {0} block {1} offset {2} index {3}", |
177 |
iteration, |
178 |
blockNumber, offset, byteIndex)); |
179 |
byteIndex += 1; |
180 |
} |
181 |
} |
182 |
} |
183 |
} |
184 |
|
185 |
void TryLongName(string name) |
186 |
{ |
187 |
MemoryStream ms = new MemoryStream(); |
188 |
using ( TarOutputStream tarOut = new TarOutputStream(ms) ) |
189 |
{ |
190 |
DateTime modTime = DateTime.Now; |
191 |
|
192 |
TarEntry entry = TarEntry.CreateTarEntry(name); |
193 |
tarOut.PutNextEntry(entry); |
194 |
} |
195 |
|
196 |
MemoryStream ms2 = new MemoryStream(); |
197 |
ms2.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length); |
198 |
ms2.Seek(0, SeekOrigin.Begin); |
199 |
|
200 |
using (TarInputStream tarIn = new TarInputStream(ms2)) |
201 |
{ |
202 |
TarEntry nextEntry = tarIn.GetNextEntry(); |
203 |
|
204 |
Assert.AreEqual(nextEntry.Name, name, "Name match failure"); |
205 |
} |
206 |
} |
207 |
|
208 |
/// <summary> |
209 |
/// Check that long names are handled correctly for reading and writing. |
210 |
/// </summary> |
211 |
[Test] |
212 |
[Category("Tar")] |
213 |
public void LongNames() |
214 |
{ |
215 |
TryLongName("11111111112222222222333333333344444444445555555555" + |
216 |
"6666666666777777777788888888889999999999000000000"); |
217 |
|
218 |
TryLongName("11111111112222222222333333333344444444445555555555" + |
219 |
"66666666667777777777888888888899999999990000000000"); |
220 |
|
221 |
TryLongName("11111111112222222222333333333344444444445555555555" + |
222 |
"66666666667777777777888888888899999999990000000000" + |
223 |
"1"); |
224 |
|
225 |
TryLongName("11111111112222222222333333333344444444445555555555" + |
226 |
"66666666667777777777888888888899999999990000000000" + |
227 |
"11111111112222222222333333333344444444445555555555" + |
228 |
"66666666667777777777888888888899999999990000000000"); |
229 |
|
230 |
TryLongName("11111111112222222222333333333344444444445555555555" + |
231 |
"66666666667777777777888888888899999999990000000000" + |
232 |
"11111111112222222222333333333344444444445555555555" + |
233 |
"66666666667777777777888888888899999999990000000000" + |
234 |
"11111111112222222222333333333344444444445555555555" + |
235 |
"66666666667777777777888888888899999999990000000000" + |
236 |
"11111111112222222222333333333344444444445555555555" + |
237 |
"66666666667777777777888888888899999999990000000000" + |
238 |
"11111111112222222222333333333344444444445555555555" + |
239 |
"66666666667777777777888888888899999999990000000000"); |
240 |
|
241 |
for (int n = 1; n < 1024; ++n) |
242 |
{ |
243 |
string format = "{0," + n + "}"; |
244 |
string formatted = string.Format(format, "A"); |
245 |
TryLongName(formatted); |
246 |
} |
247 |
} |
248 |
|
249 |
/// <summary> |
250 |
/// Test equals function for tar headers. |
251 |
/// </summary> |
252 |
[Test] |
253 |
[Category("Tar")] |
254 |
public void HeaderEquality() |
255 |
{ |
256 |
TarHeader h1 = new TarHeader(); |
257 |
TarHeader h2 = new TarHeader(); |
258 |
|
259 |
Assert.IsTrue(h1.Equals(h2)); |
260 |
|
261 |
h1.Name = "ABCDEFG"; |
262 |
Assert.IsFalse(h1.Equals(h2)); |
263 |
h2.Name = h1.Name; |
264 |
Assert.IsTrue(h1.Equals(h2)); |
265 |
|
266 |
h1.Mode = 33188; |
267 |
Assert.IsFalse(h1.Equals(h2)); |
268 |
h2.Mode = h1.Mode; |
269 |
Assert.IsTrue(h1.Equals(h2)); |
270 |
|
271 |
h1.UserId = 654; |
272 |
Assert.IsFalse(h1.Equals(h2)); |
273 |
h2.UserId = h1.UserId; |
274 |
Assert.IsTrue(h1.Equals(h2)); |
275 |
|
276 |
h1.GroupId = 654; |
277 |
Assert.IsFalse(h1.Equals(h2)); |
278 |
h2.GroupId = h1.GroupId; |
279 |
Assert.IsTrue(h1.Equals(h2)); |
280 |
|
281 |
h1.Size = 654; |
282 |
Assert.IsFalse(h1.Equals(h2)); |
283 |
h2.Size = h1.Size; |
284 |
Assert.IsTrue(h1.Equals(h2)); |
285 |
|
286 |
h1.ModTime = DateTime.Now; |
287 |
Assert.IsFalse(h1.Equals(h2)); |
288 |
h2.ModTime = h1.ModTime; |
289 |
Assert.IsTrue(h1.Equals(h2)); |
290 |
|
291 |
h1.TypeFlag = 165; |
292 |
Assert.IsFalse(h1.Equals(h2)); |
293 |
h2.TypeFlag = h1.TypeFlag; |
294 |
Assert.IsTrue(h1.Equals(h2)); |
295 |
|
296 |
h1.LinkName = "link"; |
297 |
Assert.IsFalse(h1.Equals(h2)); |
298 |
h2.LinkName = h1.LinkName; |
299 |
Assert.IsTrue(h1.Equals(h2)); |
300 |
|
301 |
h1.Magic = "ustar"; |
302 |
Assert.IsFalse(h1.Equals(h2)); |
303 |
h2.Magic = h1.Magic; |
304 |
Assert.IsTrue(h1.Equals(h2)); |
305 |
|
306 |
h1.Version = "1"; |
307 |
Assert.IsFalse(h1.Equals(h2)); |
308 |
h2.Version = h1.Version; |
309 |
Assert.IsTrue(h1.Equals(h2)); |
310 |
|
311 |
h1.UserName = "user"; |
312 |
Assert.IsFalse(h1.Equals(h2)); |
313 |
h2.UserName = h1.UserName; |
314 |
Assert.IsTrue(h1.Equals(h2)); |
315 |
|
316 |
h1.GroupName = "group"; |
317 |
Assert.IsFalse(h1.Equals(h2)); |
318 |
h2.GroupName = h1.GroupName; |
319 |
Assert.IsTrue(h1.Equals(h2)); |
320 |
|
321 |
|
322 |
h1.DevMajor = 165; |
323 |
Assert.IsFalse(h1.Equals(h2)); |
324 |
h2.DevMajor = h1.DevMajor; |
325 |
Assert.IsTrue(h1.Equals(h2)); |
326 |
|
327 |
h1.DevMinor = 164; |
328 |
Assert.IsFalse(h1.Equals(h2)); |
329 |
h2.DevMinor = h1.DevMinor; |
330 |
Assert.IsTrue(h1.Equals(h2)); |
331 |
|
332 |
} |
333 |
|
334 |
[Test] |
335 |
[Category("Tar")] |
336 |
public void Checksum() |
337 |
{ |
338 |
MemoryStream ms = new MemoryStream(); |
339 |
using ( TarOutputStream tarOut = new TarOutputStream(ms) ) |
340 |
{ |
341 |
DateTime modTime = DateTime.Now; |
342 |
|
343 |
TarEntry entry = TarEntry.CreateTarEntry("TestEntry"); |
344 |
entry.TarHeader.Mode = 12345; |
345 |
|
346 |
tarOut.PutNextEntry(entry); |
347 |
} |
348 |
|
349 |
MemoryStream ms2 = new MemoryStream(); |
350 |
ms2.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length); |
351 |
ms2.Seek(0, SeekOrigin.Begin); |
352 |
TarEntry nextEntry; |
353 |
|
354 |
using (TarInputStream tarIn = new TarInputStream(ms2)) |
355 |
{ |
356 |
nextEntry = tarIn.GetNextEntry(); |
357 |
Assert.IsTrue(nextEntry.TarHeader.IsChecksumValid, "Checksum should be valid"); |
358 |
} |
359 |
|
360 |
MemoryStream ms3 = new MemoryStream(); |
361 |
ms3.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length); |
362 |
ms3.Seek(0, SeekOrigin.Begin); |
363 |
ms3.Write(new byte[1] { 34 }, 0, 1); |
364 |
ms3.Seek(0, SeekOrigin.Begin); |
365 |
|
366 |
using (TarInputStream tarIn = new TarInputStream(ms3)) |
367 |
{ |
368 |
bool trapped = false; |
369 |
|
370 |
try |
371 |
{ |
372 |
nextEntry = tarIn.GetNextEntry(); |
373 |
} |
374 |
catch (TarException) |
375 |
{ |
376 |
trapped = true; |
377 |
} |
378 |
|
379 |
Assert.IsTrue(trapped, "Checksum should be invalid"); |
380 |
} |
381 |
} |
382 |
|
383 |
/// <summary> |
384 |
/// Check that values set are preserved when writing and reading archives. |
385 |
/// </summary> |
386 |
[Test] |
387 |
[Category("Tar")] |
388 |
public void ValuesPreserved() |
389 |
{ |
390 |
MemoryStream ms = new MemoryStream(); |
391 |
TarEntry entry; |
392 |
DateTime modTime = DateTime.Now; |
393 |
|
394 |
using (TarOutputStream tarOut = new TarOutputStream(ms)) |
395 |
{ |
396 |
entry = TarEntry.CreateTarEntry("TestEntry"); |
397 |
entry.GroupId = 12; |
398 |
entry.UserId = 14; |
399 |
entry.ModTime = modTime; |
400 |
entry.UserName = "UserName"; |
401 |
entry.GroupName = "GroupName"; |
402 |
entry.TarHeader.Mode = 12345; |
403 |
|
404 |
tarOut.PutNextEntry(entry); |
405 |
} |
406 |
|
407 |
MemoryStream ms2 = new MemoryStream(); |
408 |
ms2.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length); |
409 |
ms2.Seek(0, SeekOrigin.Begin); |
410 |
|
411 |
using (TarInputStream tarIn = new TarInputStream(ms2)) |
412 |
{ |
413 |
TarEntry nextEntry = tarIn.GetNextEntry(); |
414 |
Assert.AreEqual(entry.TarHeader.Checksum, nextEntry.TarHeader.Checksum, "Checksum"); |
415 |
|
416 |
Assert.IsTrue(nextEntry.Equals(entry), "Entries should be equal"); |
417 |
Assert.IsTrue(nextEntry.TarHeader.Equals(entry.TarHeader), "Headers should match"); |
418 |
|
419 |
// Tar only stores seconds |
420 |
DateTime truncatedTime = new DateTime(modTime.Year, modTime.Month, modTime.Day, |
421 |
modTime.Hour, modTime.Minute, modTime.Second); |
422 |
Assert.AreEqual(truncatedTime, nextEntry.ModTime, "Modtimes should match"); |
423 |
|
424 |
int entryCount = 0; |
425 |
while ( nextEntry != null ) |
426 |
{ |
427 |
++entryCount; |
428 |
nextEntry = tarIn.GetNextEntry(); |
429 |
} |
430 |
|
431 |
Assert.AreEqual(1, entryCount, "Expected 1 entry"); |
432 |
} |
433 |
} |
434 |
|
435 |
/// <summary> |
436 |
/// Check invalid mod times are detected |
437 |
/// </summary> |
438 |
[Test] |
439 |
[ExpectedException(typeof(ArgumentOutOfRangeException))] |
440 |
public void InvalidModTime() |
441 |
{ |
442 |
TarEntry e = TarEntry.CreateTarEntry("test"); |
443 |
e.ModTime = DateTime.MinValue; |
444 |
} |
445 |
|
446 |
|
447 |
/// <summary> |
448 |
/// Check invalid sizes are detected |
449 |
/// </summary> |
450 |
[Test] |
451 |
[ExpectedException(typeof(ArgumentOutOfRangeException))] |
452 |
public void InvalidSize() |
453 |
{ |
454 |
TarEntry e = TarEntry.CreateTarEntry("test"); |
455 |
e.Size = -6; |
456 |
} |
457 |
|
458 |
/// <summary> |
459 |
/// Check invalid names are detected |
460 |
/// </summary> |
461 |
[Test] |
462 |
[ExpectedException(typeof(ArgumentNullException))] |
463 |
public void InvalidName() |
464 |
{ |
465 |
TarEntry e = TarEntry.CreateTarEntry("test"); |
466 |
e.Name = null; |
467 |
} |
468 |
|
469 |
/// <summary> |
470 |
/// Check setting user and group names. |
471 |
/// </summary> |
472 |
[Test] |
473 |
public void UserAndGroupNames() |
474 |
{ |
475 |
TarEntry e = TarEntry.CreateTarEntry("test"); |
476 |
e.UserName = null; |
477 |
Assert.IsNotNull(e.UserName, "Name set to OS default"); |
478 |
e.UserName = ""; |
479 |
Assert.AreEqual(0, e.UserName.Length, "Empty name allowed"); |
480 |
e.GroupName = null; |
481 |
Assert.AreEqual("None", e.GroupName, "default group name is None"); |
482 |
} |
483 |
|
484 |
/// <summary> |
485 |
/// Check invalid magic values are detected |
486 |
/// </summary> |
487 |
[Test] |
488 |
[ExpectedException(typeof(ArgumentNullException))] |
489 |
public void InvalidMagic() |
490 |
{ |
491 |
TarEntry e = TarEntry.CreateTarEntry("test"); |
492 |
e.TarHeader.Magic = null; |
493 |
} |
494 |
|
495 |
/// <summary> |
496 |
/// Check invalid link names are detected |
497 |
/// </summary> |
498 |
[Test] |
499 |
[ExpectedException(typeof(ArgumentNullException))] |
500 |
public void InvalidLinkName() |
501 |
{ |
502 |
TarEntry e = TarEntry.CreateTarEntry("test"); |
503 |
e.TarHeader.LinkName = null; |
504 |
} |
505 |
|
506 |
/// <summary> |
507 |
/// Check invalid version names are detected |
508 |
/// </summary> |
509 |
[Test] |
510 |
[ExpectedException(typeof(ArgumentNullException))] |
511 |
public void InvalidVersionName() |
512 |
{ |
513 |
TarEntry e = TarEntry.CreateTarEntry("test"); |
514 |
e.TarHeader.Version = null; |
515 |
} |
516 |
|
517 |
[Test] |
518 |
public void CloningAndUniqueness() |
519 |
{ |
520 |
// Partial test of cloning for TarHeader and TarEntry |
521 |
TarEntry e = TarEntry.CreateTarEntry("ohsogood"); |
522 |
e.GroupId = 47; |
523 |
e.GroupName = "GroupName"; |
524 |
e.ModTime = DateTime.Now; |
525 |
e.Size = 123234; |
526 |
|
527 |
TarHeader headerE = e.TarHeader; |
528 |
|
529 |
headerE.DevMajor = 99; |
530 |
headerE.DevMinor = 98; |
531 |
headerE.LinkName = "LanceLink"; |
532 |
|
533 |
TarEntry d = (TarEntry)e.Clone(); |
534 |
|
535 |
Assert.AreEqual(d.File, e.File); |
536 |
Assert.AreEqual(d.GroupId, e.GroupId); |
537 |
Assert.AreEqual(d.GroupName, e.GroupName); |
538 |
Assert.AreEqual(d.IsDirectory, e.IsDirectory); |
539 |
Assert.AreEqual(d.ModTime, e.ModTime); |
540 |
Assert.AreEqual(d.Size, e.Size); |
541 |
|
542 |
TarHeader headerD = d.TarHeader; |
543 |
|
544 |
Assert.AreEqual(headerE.Checksum, headerD.Checksum); |
545 |
Assert.AreEqual(headerE.LinkName, headerD.LinkName); |
546 |
|
547 |
Assert.AreEqual(99, headerD.DevMajor); |
548 |
Assert.AreEqual(98, headerD.DevMinor); |
549 |
|
550 |
Assert.AreEqual("LanceLink", headerD.LinkName); |
551 |
|
552 |
TarEntry entryf = new TarEntry(headerD); |
553 |
|
554 |
headerD.LinkName = "Something different"; |
555 |
|
556 |
Assert.AreNotEqual(headerD.LinkName, entryf.TarHeader.LinkName, "Entry headers should be unique"); |
557 |
} |
558 |
} |
559 |
} |