1 7 22 23 package de.schlichtherle.io.rof; 24 25 import de.schlichtherle.crypto.generators.DigestRandom; 26 import de.schlichtherle.crypto.modes.SICSeekableBlockCipher; 27 import de.schlichtherle.io.rof.ReadOnlyFile; 28 import de.schlichtherle.io.rof.SimpleReadOnlyFile; 29 import de.schlichtherle.util.Arrays; 30 31 import java.io.File ; 32 import java.io.FileOutputStream ; 33 import java.io.IOException ; 34 import java.io.OutputStream ; 35 import java.security.SecureRandom ; 36 import java.util.Random ; 37 import java.util.logging.Logger ; 38 39 import junit.framework.*; 40 41 import org.bouncycastle.crypto.digests.SHA256Digest; 42 43 46 public class BufferedReadOnlyFileTest extends TestCase { 47 48 private static final Logger logger = Logger.getLogger( 49 BufferedReadOnlyFileTest.class.getName()); 50 51 52 protected static final Random rnd = new SecureRandom (); 53 54 protected static final String PREFIX = "tmp"; 55 56 60 protected static final String SUFFIX = ".tmp"; 61 62 protected static final java.io.File BASEDIR = new File( 63 System.getProperty("java.io.tmpdir")); 64 65 66 protected static final byte[] data = new byte[1024 * 1024]; 67 static { 68 boolean ea = false; 69 assert ea = true; logger.config("Java assertions " + (ea ? "enabled." : "disabled!")); 71 if (!ea) 72 logger.info("You should enable assertions for additional white box testing."); 73 74 rnd.nextBytes(data); 75 logger.config("Created " + data.length + " bytes of random data."); 76 77 logger.config("Temp dir for unit tests: " + BASEDIR.getPath()); 78 } 79 80 public static Test suite() throws Exception { 81 TestSuite suite = new TestSuite(BufferedReadOnlyFileTest.class); 82 85 86 return suite; 87 } 88 89 90 protected File file; 91 92 private ReadOnlyFile srof; 93 private ReadOnlyFile brof; 94 95 public BufferedReadOnlyFileTest(String testName) throws Exception { 96 super(testName); 97 } 98 99 105 protected void setUp() throws Exception { 106 file = File.createTempFile(PREFIX, SUFFIX, BASEDIR); 108 final OutputStream out = new FileOutputStream (file); 109 out.write(data); 110 out.close(); 111 assertEquals(data.length, file.length()); 112 113 srof = new SimpleReadOnlyFile(file); 115 brof = new BufferedReadOnlyFile(file); 116 } 117 118 protected void tearDown() throws Exception { 119 srof.close(); 120 srof = null; 121 122 brof.close(); 123 brof = null; 124 125 final boolean deleted = file.delete(); 126 if (!deleted && file.exists()) { 127 System.err.println("Warning: " + file + ": Could not delete!"); 128 } 130 file = null; 131 } 132 133 public void testClose() throws IOException { 134 logger.fine("testClose"); 135 136 brof.close(); 137 138 try { 139 brof.length(); 140 fail("This should throw an IOException!"); 141 } catch (IOException expected) { 142 } 144 145 try { 146 brof.getFilePointer(); 147 fail("This should throw an IOException!"); 148 } catch (IOException expected) { 149 } 151 152 try { 153 brof.seek(0); 154 fail("This should throw an IOException!"); 155 } catch (IOException expected) { 156 } 158 159 try { 160 brof.read(); 161 fail("Reading from a closed file should throw an IOException!"); 162 } catch (IOException expected) { 163 } 165 166 assertEquals(0, brof.read(new byte[0])); 167 168 try { 169 brof.read(new byte[1]); 170 fail("Reading from a closed file should throw an IOException!"); 171 } catch (IOException expected) { 172 } 174 175 assertEquals(0, brof.read(new byte[0], 0, 0)); 176 177 try { 178 brof.read(new byte[1], 0, 1); 179 fail("Reading from a closed file should throw an IOException!"); 180 } catch (IOException expected) { 181 } 183 184 brof.readFully(new byte[0]); 185 186 try { 187 brof.readFully(new byte[1]); 188 fail("Reading from a closed file should throw an IOException!"); 189 } catch (IOException expected) { 190 } 192 193 brof.readFully(new byte[0], 0, 0); 194 195 try { 196 brof.readFully(new byte[1], 0, 1); 197 fail("Reading from a closed file should throw an IOException!"); 198 } catch (IOException expected) { 199 } 201 202 assertEquals(0, brof.skipBytes(0)); 203 assertEquals(0, brof.skipBytes(-1)); 204 205 try { 206 brof.skipBytes(1); 207 fail("Skipping bytes in a closed file should throw an IOException!"); 208 } catch (IOException expected) { 209 } 211 212 brof.close(); 213 214 srof.close(); 215 216 try { 217 srof.length(); 218 fail("This should throw an IOException!"); 219 } catch (IOException expected) { 220 } 222 223 try { 224 srof.getFilePointer(); 225 fail("This should throw an IOException!"); 226 } catch (IOException expected) { 227 } 229 230 try { 231 srof.seek(0); 232 fail("This should throw an IOException!"); 233 } catch (IOException expected) { 234 } 236 237 try { 238 srof.read(); 239 fail("Reading from a closed file should throw an IOException!"); 240 } catch (IOException expected) { 241 } 243 244 assertEquals(0, srof.read(new byte[0])); 245 246 try { 247 srof.read(new byte[1]); 248 fail("Reading from a closed file should throw an IOException!"); 249 } catch (IOException expected) { 250 } 252 253 assertEquals(0, srof.read(new byte[0], 0, 0)); 254 255 try { 256 srof.read(new byte[1], 0, 1); 257 fail("Reading from a closed file should throw an IOException!"); 258 } catch (IOException expected) { 259 } 261 262 srof.readFully(new byte[0]); 263 264 try { 265 srof.readFully(new byte[1]); 266 fail("Reading from a closed file should throw an IOException!"); 267 } catch (IOException expected) { 268 } 270 271 srof.readFully(new byte[0], 0, 0); 272 273 try { 274 srof.readFully(new byte[1], 0, 1); 275 fail("Reading from a closed file should throw an IOException!"); 276 } catch (IOException expected) { 277 } 279 280 assertEquals(0, srof.skipBytes(0)); 281 assertEquals(0, srof.skipBytes(-1)); 282 283 try { 284 srof.skipBytes(1); 285 fail("Skipping bytes in a closed file should throw an IOException!"); 286 } catch (IOException expected) { 287 } 289 290 srof.close(); 291 } 292 293 public void testLength() throws Exception { 294 logger.fine("testLength"); 295 296 for (int i = 10; --i >= 0; ) { 297 final ReadOnlyFile rrof 298 = new BufferedReadOnlyFile(file); 299 300 assertEquals(data.length, rrof.length()); 301 assertEquals(data.length, srof.length()); 302 303 rrof.close(); 304 } 305 } 306 307 public void testSeekAndGetFilePointer() throws IOException { 308 logger.fine("testSeekAndGetFilePointer (Monte Carlo algorithm)"); 309 310 assertEquals(0, brof.getFilePointer()); 311 assertEquals(0, srof.getFilePointer()); 312 313 testSeekAndGetFilePointer(brof, 0); 314 testSeekAndGetFilePointer(srof, 0); 315 316 final long length = brof.length(); 317 for (int i = 100; --i >= 0; ) { 318 final long tooSmall = rnd.nextLong() | 0x8000000000000000L; 319 try { 320 testSeekAndGetFilePointer(brof, tooSmall); 321 fail("Seeking to a negative position should throw an IOException!"); 322 } catch (IOException expected) { 323 } 325 try { 326 testSeekAndGetFilePointer(srof, tooSmall); 327 fail("Seeking to a negative position should throw an IOException!"); 328 } catch (IOException expected) { 329 } 331 332 final int off = rnd.nextInt((int) length); 333 testSeekAndGetFilePointer(brof, off); 334 testSeekAndGetFilePointer(srof, off); 335 336 final long tooLarge = Math.max( 337 length + 1, rnd.nextLong() & 0x7fffffffffffffffL); 338 try { 339 testSeekAndGetFilePointer(brof, tooLarge); 340 fail("Seeking past the file length should throw an IOException!"); 341 } catch (IOException expected) { 342 } 344 try { 349 testSeekAndGetFilePointer(brof, tooLarge); 350 } catch (IOException mayHappen) { 351 } 352 } 353 354 testSeekAndGetFilePointer(brof, length); 355 } 356 357 private void testSeekAndGetFilePointer( 358 final ReadOnlyFile rof, 359 final long pos) throws IOException { 360 rof.seek(pos); 361 assertEquals(pos, rof.getFilePointer()); 362 } 363 364 public void testSkipBytes() throws IOException { 365 logger.fine("testSkipBytes (Las Vegas algorithm)"); 366 367 final long length = brof.length(); 368 for (int off = 0; off < (int) length; off++) { 369 assertEquals(data[off], (byte) brof.read()); 370 assertEquals(data[off], (byte) srof.read()); 371 int n = rnd.nextInt((int) (length / 100)); 372 n = brof.skipBytes(n); 373 assertEquals(n, srof.skipBytes(n)); 374 off += n; 375 } 376 assertEquals(-1, brof.read()); 377 assertEquals(-1, srof.read()); 378 assertEquals(0, brof.skipBytes(1)); 379 assertEquals(0, srof.skipBytes(1)); 380 } 381 382 public void testForwardReadBytes() throws IOException { 383 logger.fine("testForwardReadBytes"); 384 385 final long length = brof.length(); 386 for (int off = 0; off < length; off++) { 387 assertEquals(data[off], (byte) brof.read()); 388 assertEquals(data[off], (byte) srof.read()); 389 } 390 assertEquals(-1, brof.read()); 391 assertEquals(-1, srof.read()); 392 } 393 394 public void testBackwardReadBytes() throws IOException { 395 logger.fine("testBackwardReadBytes"); 396 397 final long length = brof.length(); 398 testSeekAndGetFilePointer(brof, length); 399 assertEquals(-1, brof.read()); 400 testSeekAndGetFilePointer(srof, length); 401 assertEquals(-1, srof.read()); 402 403 for (int off = (int) length; --off >= 0; ) { 404 testSeekAndGetFilePointer(brof, off); 405 assertEquals(data[off], (byte) brof.read()); 406 testSeekAndGetFilePointer(srof, off); 407 assertEquals(data[off], (byte) srof.read()); 408 } 409 } 410 411 public void testRandomReadBytes() throws IOException { 412 logger.fine("testRandomReadBytes (Monte Carlo algorithm)"); 413 414 final long length = brof.length(); 415 for (int i = 100; --i >= 0; ) { 416 int off = rnd.nextInt((int) length); 417 testSeekAndGetFilePointer(brof, off); 418 assertEquals(data[off], (byte) brof.read()); 419 testSeekAndGetFilePointer(srof, off); 420 assertEquals(data[off], (byte) srof.read()); 421 } 422 423 testSeekAndGetFilePointer(brof, length); 424 assertEquals(-1, brof.read()); 425 testSeekAndGetFilePointer(srof, length); 426 assertEquals(-1, srof.read()); 427 } 428 429 public void testForwardReadChunks() throws IOException { 430 logger.fine("testForwardReadChunks (Las Vegas algorithm)"); 431 432 final long length = brof.length(); 433 int off = 0; 434 int read; 435 do { 436 final byte[] buf = new byte[rnd.nextInt((int) (length / 100))]; 437 read = brof.read(buf); 438 if (read < 0) 439 break; 440 if (buf.length > 0) { 441 assertTrue(read > 0); 442 assertTrue(Arrays.equals(data, off, buf, 0, read)); 443 assertEquals(read, srof.read(buf)); 444 assertTrue(Arrays.equals(data, off, buf, 0, read)); 445 } else { 446 assertTrue(read == 0); 447 assertEquals(0, srof.read(buf)); 448 } 449 off += read; 450 } while (true); 451 assertEquals(off, length); 452 assertEquals(-1, read); 453 assertEquals(-1, srof.read(new byte[1])); 454 assertEquals( 0, brof.read(new byte[0])); 455 assertEquals( 0, srof.read(new byte[0])); 456 } 457 458 public void testRandomReadChunks() throws IOException { 459 logger.fine("testRandomReadChunks (Monte Carlo algorithm)"); 460 461 final long length = brof.length(); 462 for (int i = 100; --i >= 0; ) { 463 int off = rnd.nextInt((int) length); 464 testSeekAndGetFilePointer(brof, off); 465 testSeekAndGetFilePointer(srof, off); 466 final byte[] buf = new byte[rnd.nextInt((int) (length / 100))]; 467 int read = brof.read(buf); 468 if (buf.length > 0) { 469 assertTrue(read > 0); 470 assertTrue(Arrays.equals(data, off, buf, 0, read)); 471 assertEquals(read, srof.read(buf)); 472 assertTrue(Arrays.equals(data, off, buf, 0, read)); 473 } else { 474 assertTrue(read == 0); 475 assertEquals(0, srof.read(buf)); 476 } 477 } 478 } 479 } 480 | Popular Tags |