1 /* 2 * Copyright (C) 2010 The Android Open Source Project 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 17 package com.android.gallery3d.common; 18 19 import com.android.gallery3d.common.BlobCache; 20 21 import android.test.AndroidTestCase; 22 import android.test.suitebuilder.annotation.SmallTest; 23 import android.test.suitebuilder.annotation.MediumTest; 24 import android.test.suitebuilder.annotation.LargeTest; 25 import android.util.Log; 26 27 import java.io.File; 28 import java.io.IOException; 29 import java.io.RandomAccessFile; 30 import java.util.Random; 31 32 public class BlobCacheTest extends AndroidTestCase { 33 private static final String TAG = "BlobCacheTest"; 34 35 @SmallTest 36 public void testReadIntLong() { 37 byte[] buf = new byte[9]; 38 assertEquals(0, BlobCache.readInt(buf, 0)); 39 assertEquals(0, BlobCache.readLong(buf, 0)); 40 buf[0] = 1; 41 assertEquals(1, BlobCache.readInt(buf, 0)); 42 assertEquals(1, BlobCache.readLong(buf, 0)); 43 buf[3] = 0x7f; 44 assertEquals(0x7f000001, BlobCache.readInt(buf, 0)); 45 assertEquals(0x7f000001, BlobCache.readLong(buf, 0)); 46 assertEquals(0x007f0000, BlobCache.readInt(buf, 1)); 47 assertEquals(0x007f0000, BlobCache.readLong(buf, 1)); 48 buf[3] = (byte) 0x80; 49 buf[7] = (byte) 0xA0; 50 buf[0] = 0; 51 assertEquals(0x80000000, BlobCache.readInt(buf, 0)); 52 assertEquals(0xA000000080000000L, BlobCache.readLong(buf, 0)); 53 for (int i = 0; i < 8; i++) { 54 buf[i] = (byte) (0x11 * (i+8)); 55 } 56 assertEquals(0xbbaa9988, BlobCache.readInt(buf, 0)); 57 assertEquals(0xffeeddccbbaa9988L, BlobCache.readLong(buf, 0)); 58 buf[8] = 0x33; 59 assertEquals(0x33ffeeddccbbaa99L, BlobCache.readLong(buf, 1)); 60 } 61 62 @SmallTest 63 public void testWriteIntLong() { 64 byte[] buf = new byte[8]; 65 BlobCache.writeInt(buf, 0, 0x12345678); 66 assertEquals(0x78, buf[0]); 67 assertEquals(0x56, buf[1]); 68 assertEquals(0x34, buf[2]); 69 assertEquals(0x12, buf[3]); 70 assertEquals(0x00, buf[4]); 71 BlobCache.writeLong(buf, 0, 0xffeeddccbbaa9988L); 72 for (int i = 0; i < 8; i++) { 73 assertEquals((byte) (0x11 * (i+8)), buf[i]); 74 } 75 } 76 77 @MediumTest 78 public void testChecksum() throws IOException { 79 BlobCache bc = new BlobCache(TEST_FILE_NAME, MAX_ENTRIES, MAX_BYTES, true); 80 byte[] buf = new byte[0]; 81 assertEquals(0x1, bc.checkSum(buf)); 82 buf = new byte[1]; 83 assertEquals(0x10001, bc.checkSum(buf)); 84 buf[0] = 0x47; 85 assertEquals(0x480048, bc.checkSum(buf)); 86 buf = new byte[3]; 87 buf[0] = 0x10; 88 buf[1] = 0x30; 89 buf[2] = 0x01; 90 assertEquals(0x940042, bc.checkSum(buf)); 91 assertEquals(0x310031, bc.checkSum(buf, 1, 1)); 92 assertEquals(0x1, bc.checkSum(buf, 1, 0)); 93 assertEquals(0x630032, bc.checkSum(buf, 1, 2)); 94 buf = new byte[1024]; 95 for (int i = 0; i < buf.length; i++) { 96 buf[i] = (byte)(i*i); 97 } 98 assertEquals(0x3574a610, bc.checkSum(buf)); 99 bc.close(); 100 } 101 102 private static final int HEADER_SIZE = 32; 103 private static final int DATA_HEADER_SIZE = 4; 104 private static final int BLOB_HEADER_SIZE = 20; 105 106 private static final String TEST_FILE_NAME = "/sdcard/btest"; 107 private static final int MAX_ENTRIES = 100; 108 private static final int MAX_BYTES = 1000; 109 private static final int INDEX_SIZE = HEADER_SIZE + MAX_ENTRIES * 12 * 2; 110 private static final long KEY_0 = 0x1122334455667788L; 111 private static final long KEY_1 = 0x1122334455667789L; 112 private static final long KEY_2 = 0x112233445566778AL; 113 private static byte[] DATA_0 = new byte[10]; 114 private static byte[] DATA_1 = new byte[10]; 115 116 @MediumTest 117 public void testBasic() throws IOException { 118 String name = TEST_FILE_NAME; 119 BlobCache bc; 120 File idxFile = new File(name + ".idx"); 121 File data0File = new File(name + ".0"); 122 File data1File = new File(name + ".1"); 123 124 // Create a brand new cache. 125 bc = new BlobCache(name, MAX_ENTRIES, MAX_BYTES, true); 126 bc.close(); 127 128 // Make sure the initial state is correct. 129 assertTrue(idxFile.exists()); 130 assertTrue(data0File.exists()); 131 assertTrue(data1File.exists()); 132 assertEquals(INDEX_SIZE, idxFile.length()); 133 assertEquals(DATA_HEADER_SIZE, data0File.length()); 134 assertEquals(DATA_HEADER_SIZE, data1File.length()); 135 assertEquals(0, bc.getActiveCount()); 136 137 // Re-open it. 138 bc = new BlobCache(name, MAX_ENTRIES, MAX_BYTES, false); 139 assertNull(bc.lookup(KEY_0)); 140 141 // insert one blob 142 genData(DATA_0, 1); 143 bc.insert(KEY_0, DATA_0); 144 assertSameData(DATA_0, bc.lookup(KEY_0)); 145 assertEquals(1, bc.getActiveCount()); 146 bc.close(); 147 148 // Make sure the file size is right. 149 assertEquals(INDEX_SIZE, idxFile.length()); 150 assertEquals(DATA_HEADER_SIZE + BLOB_HEADER_SIZE + DATA_0.length, 151 data0File.length()); 152 assertEquals(DATA_HEADER_SIZE, data1File.length()); 153 154 // Re-open it and make sure we can get the old data 155 bc = new BlobCache(name, MAX_ENTRIES, MAX_BYTES, false); 156 assertSameData(DATA_0, bc.lookup(KEY_0)); 157 158 // insert with the same key (but using a different blob) 159 genData(DATA_0, 2); 160 bc.insert(KEY_0, DATA_0); 161 assertSameData(DATA_0, bc.lookup(KEY_0)); 162 assertEquals(1, bc.getActiveCount()); 163 bc.close(); 164 165 // Make sure the file size is right. 166 assertEquals(INDEX_SIZE, idxFile.length()); 167 assertEquals(DATA_HEADER_SIZE + 2 * (BLOB_HEADER_SIZE + DATA_0.length), 168 data0File.length()); 169 assertEquals(DATA_HEADER_SIZE, data1File.length()); 170 171 // Re-open it and make sure we can get the old data 172 bc = new BlobCache(name, MAX_ENTRIES, MAX_BYTES, false); 173 assertSameData(DATA_0, bc.lookup(KEY_0)); 174 175 // insert another key and make sure we can get both key. 176 assertNull(bc.lookup(KEY_1)); 177 genData(DATA_1, 3); 178 bc.insert(KEY_1, DATA_1); 179 assertSameData(DATA_0, bc.lookup(KEY_0)); 180 assertSameData(DATA_1, bc.lookup(KEY_1)); 181 assertEquals(2, bc.getActiveCount()); 182 bc.close(); 183 184 // Make sure the file size is right. 185 assertEquals(INDEX_SIZE, idxFile.length()); 186 assertEquals(DATA_HEADER_SIZE + 3 * (BLOB_HEADER_SIZE + DATA_0.length), 187 data0File.length()); 188 assertEquals(DATA_HEADER_SIZE, data1File.length()); 189 190 // Re-open it and make sure we can get the old data 191 bc = new BlobCache(name, 100, 1000, false); 192 assertSameData(DATA_0, bc.lookup(KEY_0)); 193 assertSameData(DATA_1, bc.lookup(KEY_1)); 194 assertEquals(2, bc.getActiveCount()); 195 bc.close(); 196 } 197 198 @MediumTest 199 public void testNegativeKey() throws IOException { 200 BlobCache bc = new BlobCache(TEST_FILE_NAME, MAX_ENTRIES, MAX_BYTES, true); 201 202 // insert one blob 203 genData(DATA_0, 1); 204 bc.insert(-123, DATA_0); 205 assertSameData(DATA_0, bc.lookup(-123)); 206 bc.close(); 207 } 208 209 @MediumTest 210 public void testEmptyBlob() throws IOException { 211 BlobCache bc = new BlobCache(TEST_FILE_NAME, MAX_ENTRIES, MAX_BYTES, true); 212 213 byte[] data = new byte[0]; 214 bc.insert(123, data); 215 assertSameData(data, bc.lookup(123)); 216 bc.close(); 217 } 218 219 @MediumTest 220 public void testLookupRequest() throws IOException { 221 BlobCache bc = new BlobCache(TEST_FILE_NAME, MAX_ENTRIES, MAX_BYTES, true); 222 223 // insert one blob 224 genData(DATA_0, 1); 225 bc.insert(1, DATA_0); 226 assertSameData(DATA_0, bc.lookup(1)); 227 228 // the same size buffer 229 byte[] buf = new byte[DATA_0.length]; 230 BlobCache.LookupRequest req = new BlobCache.LookupRequest(); 231 req.key = 1; 232 req.buffer = buf; 233 assertTrue(bc.lookup(req)); 234 assertEquals(1, req.key); 235 assertSame(buf, req.buffer); 236 assertEquals(DATA_0.length, req.length); 237 238 // larger buffer 239 buf = new byte[DATA_0.length + 22]; 240 req = new BlobCache.LookupRequest(); 241 req.key = 1; 242 req.buffer = buf; 243 assertTrue(bc.lookup(req)); 244 assertEquals(1, req.key); 245 assertSame(buf, req.buffer); 246 assertEquals(DATA_0.length, req.length); 247 248 // smaller buffer 249 buf = new byte[DATA_0.length - 1]; 250 req = new BlobCache.LookupRequest(); 251 req.key = 1; 252 req.buffer = buf; 253 assertTrue(bc.lookup(req)); 254 assertEquals(1, req.key); 255 assertNotSame(buf, req.buffer); 256 assertEquals(DATA_0.length, req.length); 257 assertSameData(DATA_0, req.buffer, DATA_0.length); 258 259 // null buffer 260 req = new BlobCache.LookupRequest(); 261 req.key = 1; 262 req.buffer = null; 263 assertTrue(bc.lookup(req)); 264 assertEquals(1, req.key); 265 assertNotNull(req.buffer); 266 assertEquals(DATA_0.length, req.length); 267 assertSameData(DATA_0, req.buffer, DATA_0.length); 268 269 bc.close(); 270 } 271 272 @MediumTest 273 public void testKeyCollision() throws IOException { 274 BlobCache bc = new BlobCache(TEST_FILE_NAME, MAX_ENTRIES, MAX_BYTES, true); 275 276 for (int i = 0; i < MAX_ENTRIES / 2; i++) { 277 genData(DATA_0, i); 278 long key = KEY_1 + i * MAX_ENTRIES; 279 bc.insert(key, DATA_0); 280 } 281 282 for (int i = 0; i < MAX_ENTRIES / 2; i++) { 283 genData(DATA_0, i); 284 long key = KEY_1 + i * MAX_ENTRIES; 285 assertSameData(DATA_0, bc.lookup(key)); 286 } 287 bc.close(); 288 } 289 290 @MediumTest 291 public void testRegionFlip() throws IOException { 292 String name = TEST_FILE_NAME; 293 BlobCache bc; 294 File idxFile = new File(name + ".idx"); 295 File data0File = new File(name + ".0"); 296 File data1File = new File(name + ".1"); 297 298 // Create a brand new cache. 299 bc = new BlobCache(name, MAX_ENTRIES, MAX_BYTES, true); 300 301 // This is the number of blobs fits into a region. 302 int maxFit = (MAX_BYTES - DATA_HEADER_SIZE) / 303 (BLOB_HEADER_SIZE + DATA_0.length); 304 305 for (int k = 0; k < maxFit; k++) { 306 genData(DATA_0, k); 307 bc.insert(k, DATA_0); 308 } 309 assertEquals(maxFit, bc.getActiveCount()); 310 311 // Make sure the file size is right. 312 assertEquals(INDEX_SIZE, idxFile.length()); 313 assertEquals(DATA_HEADER_SIZE + maxFit * (BLOB_HEADER_SIZE + DATA_0.length), 314 data0File.length()); 315 assertEquals(DATA_HEADER_SIZE, data1File.length()); 316 317 // Now insert another one and let it flip. 318 genData(DATA_0, 777); 319 bc.insert(KEY_1, DATA_0); 320 assertEquals(1, bc.getActiveCount()); 321 322 assertEquals(INDEX_SIZE, idxFile.length()); 323 assertEquals(DATA_HEADER_SIZE + maxFit * (BLOB_HEADER_SIZE + DATA_0.length), 324 data0File.length()); 325 assertEquals(DATA_HEADER_SIZE + 1 * (BLOB_HEADER_SIZE + DATA_0.length), 326 data1File.length()); 327 328 // Make sure we can find the new data 329 assertSameData(DATA_0, bc.lookup(KEY_1)); 330 331 // Now find an old blob 332 int old = maxFit / 2; 333 genData(DATA_0, old); 334 assertSameData(DATA_0, bc.lookup(old)); 335 assertEquals(2, bc.getActiveCount()); 336 337 // Observed data is copied. 338 assertEquals(INDEX_SIZE, idxFile.length()); 339 assertEquals(DATA_HEADER_SIZE + maxFit * (BLOB_HEADER_SIZE + DATA_0.length), 340 data0File.length()); 341 assertEquals(DATA_HEADER_SIZE + 2 * (BLOB_HEADER_SIZE + DATA_0.length), 342 data1File.length()); 343 344 // Now copy everything over (except we should have no space for the last one) 345 assertTrue(old < maxFit - 1); 346 for (int k = 0; k < maxFit; k++) { 347 genData(DATA_0, k); 348 assertSameData(DATA_0, bc.lookup(k)); 349 } 350 assertEquals(maxFit, bc.getActiveCount()); 351 352 // Now both file should be full. 353 assertEquals(INDEX_SIZE, idxFile.length()); 354 assertEquals(DATA_HEADER_SIZE + maxFit * (BLOB_HEADER_SIZE + DATA_0.length), 355 data0File.length()); 356 assertEquals(DATA_HEADER_SIZE + maxFit * (BLOB_HEADER_SIZE + DATA_0.length), 357 data1File.length()); 358 359 // Now insert one to make it flip. 360 genData(DATA_0, 888); 361 bc.insert(KEY_2, DATA_0); 362 assertEquals(1, bc.getActiveCount()); 363 364 // Check the size after the second flip. 365 assertEquals(INDEX_SIZE, idxFile.length()); 366 assertEquals(DATA_HEADER_SIZE + 1 * (BLOB_HEADER_SIZE + DATA_0.length), 367 data0File.length()); 368 assertEquals(DATA_HEADER_SIZE + maxFit * (BLOB_HEADER_SIZE + DATA_0.length), 369 data1File.length()); 370 371 // Now the last key should be gone. 372 assertNull(bc.lookup(maxFit - 1)); 373 374 // But others should remain 375 for (int k = 0; k < maxFit - 1; k++) { 376 genData(DATA_0, k); 377 assertSameData(DATA_0, bc.lookup(k)); 378 } 379 380 assertEquals(maxFit, bc.getActiveCount()); 381 genData(DATA_0, 777); 382 assertSameData(DATA_0, bc.lookup(KEY_1)); 383 genData(DATA_0, 888); 384 assertSameData(DATA_0, bc.lookup(KEY_2)); 385 assertEquals(maxFit, bc.getActiveCount()); 386 387 // Now two files should be full. 388 assertEquals(INDEX_SIZE, idxFile.length()); 389 assertEquals(DATA_HEADER_SIZE + maxFit * (BLOB_HEADER_SIZE + DATA_0.length), 390 data0File.length()); 391 assertEquals(DATA_HEADER_SIZE + maxFit * (BLOB_HEADER_SIZE + DATA_0.length), 392 data1File.length()); 393 394 bc.close(); 395 } 396 397 @MediumTest 398 public void testEntryLimit() throws IOException { 399 String name = TEST_FILE_NAME; 400 BlobCache bc; 401 File idxFile = new File(name + ".idx"); 402 File data0File = new File(name + ".0"); 403 File data1File = new File(name + ".1"); 404 int maxEntries = 10; 405 int maxFit = maxEntries / 2; 406 int indexSize = HEADER_SIZE + maxEntries * 12 * 2; 407 408 // Create a brand new cache with a small entry limit. 409 bc = new BlobCache(name, maxEntries, MAX_BYTES, true); 410 411 // Fill to just before flipping 412 for (int i = 0; i < maxFit; i++) { 413 genData(DATA_0, i); 414 bc.insert(i, DATA_0); 415 } 416 assertEquals(maxFit, bc.getActiveCount()); 417 418 // Check the file size. 419 assertEquals(indexSize, idxFile.length()); 420 assertEquals(DATA_HEADER_SIZE + maxFit * (BLOB_HEADER_SIZE + DATA_0.length), 421 data0File.length()); 422 assertEquals(DATA_HEADER_SIZE, data1File.length()); 423 424 // Insert one and make it flip 425 genData(DATA_0, 777); 426 bc.insert(777, DATA_0); 427 assertEquals(1, bc.getActiveCount()); 428 429 // Check the file size. 430 assertEquals(indexSize, idxFile.length()); 431 assertEquals(DATA_HEADER_SIZE + maxFit * (BLOB_HEADER_SIZE + DATA_0.length), 432 data0File.length()); 433 assertEquals(DATA_HEADER_SIZE + 1 * (BLOB_HEADER_SIZE + DATA_0.length), 434 data1File.length()); 435 bc.close(); 436 } 437 438 @LargeTest 439 public void testDataIntegrity() throws IOException { 440 String name = TEST_FILE_NAME; 441 File idxFile = new File(name + ".idx"); 442 File data0File = new File(name + ".0"); 443 File data1File = new File(name + ".1"); 444 RandomAccessFile f; 445 446 Log.v(TAG, "It should be readable if the content is not changed."); 447 prepareNewCache(); 448 f = new RandomAccessFile(data0File, "rw"); 449 f.seek(1); 450 byte b = f.readByte(); 451 f.seek(1); 452 f.write(b); 453 f.close(); 454 assertReadable(); 455 456 Log.v(TAG, "Change the data file magic field"); 457 prepareNewCache(); 458 f = new RandomAccessFile(data0File, "rw"); 459 f.seek(1); 460 f.write(0xFF); 461 f.close(); 462 assertUnreadable(); 463 464 prepareNewCache(); 465 f = new RandomAccessFile(data1File, "rw"); 466 f.write(0xFF); 467 f.close(); 468 assertUnreadable(); 469 470 Log.v(TAG, "Change the blob key"); 471 prepareNewCache(); 472 f = new RandomAccessFile(data0File, "rw"); 473 f.seek(4); 474 f.write(0x00); 475 f.close(); 476 assertUnreadable(); 477 478 Log.v(TAG, "Change the blob checksum"); 479 prepareNewCache(); 480 f = new RandomAccessFile(data0File, "rw"); 481 f.seek(4 + 8); 482 f.write(0x00); 483 f.close(); 484 assertUnreadable(); 485 486 Log.v(TAG, "Change the blob offset"); 487 prepareNewCache(); 488 f = new RandomAccessFile(data0File, "rw"); 489 f.seek(4 + 12); 490 f.write(0x20); 491 f.close(); 492 assertUnreadable(); 493 494 Log.v(TAG, "Change the blob length: some other value"); 495 prepareNewCache(); 496 f = new RandomAccessFile(data0File, "rw"); 497 f.seek(4 + 16); 498 f.write(0x20); 499 f.close(); 500 assertUnreadable(); 501 502 Log.v(TAG, "Change the blob length: -1"); 503 prepareNewCache(); 504 f = new RandomAccessFile(data0File, "rw"); 505 f.seek(4 + 16); 506 f.writeInt(0xFFFFFFFF); 507 f.close(); 508 assertUnreadable(); 509 510 Log.v(TAG, "Change the blob length: big value"); 511 prepareNewCache(); 512 f = new RandomAccessFile(data0File, "rw"); 513 f.seek(4 + 16); 514 f.writeInt(0xFFFFFF00); 515 f.close(); 516 assertUnreadable(); 517 518 Log.v(TAG, "Change the blob content"); 519 prepareNewCache(); 520 f = new RandomAccessFile(data0File, "rw"); 521 f.seek(4 + 20); 522 f.write(0x01); 523 f.close(); 524 assertUnreadable(); 525 526 Log.v(TAG, "Change the index magic"); 527 prepareNewCache(); 528 f = new RandomAccessFile(idxFile, "rw"); 529 f.seek(1); 530 f.write(0x00); 531 f.close(); 532 assertUnreadable(); 533 534 Log.v(TAG, "Change the active region"); 535 prepareNewCache(); 536 f = new RandomAccessFile(idxFile, "rw"); 537 f.seek(12); 538 f.write(0x01); 539 f.close(); 540 assertUnreadable(); 541 542 Log.v(TAG, "Change the reserved data"); 543 prepareNewCache(); 544 f = new RandomAccessFile(idxFile, "rw"); 545 f.seek(24); 546 f.write(0x01); 547 f.close(); 548 assertUnreadable(); 549 550 Log.v(TAG, "Change the checksum"); 551 prepareNewCache(); 552 f = new RandomAccessFile(idxFile, "rw"); 553 f.seek(29); 554 f.write(0x00); 555 f.close(); 556 assertUnreadable(); 557 558 Log.v(TAG, "Change the key"); 559 prepareNewCache(); 560 f = new RandomAccessFile(idxFile, "rw"); 561 f.seek(32 + 12 * (KEY_1 % MAX_ENTRIES)); 562 f.write(0x00); 563 f.close(); 564 assertUnreadable(); 565 566 Log.v(TAG, "Change the offset"); 567 prepareNewCache(); 568 f = new RandomAccessFile(idxFile, "rw"); 569 f.seek(32 + 12 * (KEY_1 % MAX_ENTRIES) + 8); 570 f.write(0x05); 571 f.close(); 572 assertUnreadable(); 573 574 Log.v(TAG, "Change the offset"); 575 prepareNewCache(); 576 f = new RandomAccessFile(idxFile, "rw"); 577 f.seek(32 + 12 * (KEY_1 % MAX_ENTRIES) + 8 + 3); 578 f.write(0xFF); 579 f.close(); 580 assertUnreadable(); 581 582 Log.v(TAG, "Garbage index"); 583 prepareNewCache(); 584 f = new RandomAccessFile(idxFile, "rw"); 585 int n = (int) idxFile.length(); 586 f.seek(32); 587 byte[] garbage = new byte[1024]; 588 for (int i = 0; i < garbage.length; i++) { 589 garbage[i] = (byte) 0x80; 590 } 591 int i = 32; 592 while (i < n) { 593 int todo = Math.min(garbage.length, n - i); 594 f.write(garbage, 0, todo); 595 i += todo; 596 } 597 f.close(); 598 assertUnreadable(); 599 } 600 601 // Create a brand new cache and put one entry into it. 602 private void prepareNewCache() throws IOException { 603 BlobCache bc = new BlobCache(TEST_FILE_NAME, MAX_ENTRIES, MAX_BYTES, true); 604 genData(DATA_0, 777); 605 bc.insert(KEY_1, DATA_0); 606 bc.close(); 607 } 608 609 private void assertReadable() throws IOException { 610 BlobCache bc = new BlobCache(TEST_FILE_NAME, MAX_ENTRIES, MAX_BYTES, false); 611 genData(DATA_0, 777); 612 assertSameData(DATA_0, bc.lookup(KEY_1)); 613 bc.close(); 614 } 615 616 private void assertUnreadable() throws IOException { 617 BlobCache bc = new BlobCache(TEST_FILE_NAME, MAX_ENTRIES, MAX_BYTES, false); 618 genData(DATA_0, 777); 619 assertNull(bc.lookup(KEY_1)); 620 bc.close(); 621 } 622 623 @LargeTest 624 public void testRandomSize() throws IOException { 625 BlobCache bc = new BlobCache(TEST_FILE_NAME, MAX_ENTRIES, MAX_BYTES, true); 626 627 // Random size test 628 Random rand = new Random(0); 629 for (int i = 0; i < 100; i++) { 630 byte[] data = new byte[rand.nextInt(MAX_BYTES*12/10)]; 631 try { 632 bc.insert(rand.nextLong(), data); 633 if (data.length > MAX_BYTES - 4 - 20) fail(); 634 } catch (RuntimeException ex) { 635 if (data.length <= MAX_BYTES - 4 - 20) fail(); 636 } 637 } 638 639 bc.close(); 640 } 641 642 @LargeTest 643 public void testBandwidth() throws IOException { 644 BlobCache bc = new BlobCache(TEST_FILE_NAME, 1000, 10000000, true); 645 646 // Write 647 int count = 0; 648 byte[] data = new byte[20000]; 649 long t0 = System.nanoTime(); 650 for (int i = 0; i < 1000; i++) { 651 bc.insert(i, data); 652 count += data.length; 653 } 654 bc.syncAll(); 655 float delta = (System.nanoTime() - t0) * 1e-3f; 656 Log.v(TAG, "write bandwidth = " + (count / delta) + " M/s"); 657 658 // Copy over 659 BlobCache.LookupRequest req = new BlobCache.LookupRequest(); 660 count = 0; 661 t0 = System.nanoTime(); 662 for (int i = 0; i < 1000; i++) { 663 req.key = i; 664 req.buffer = data; 665 if (bc.lookup(req)) { 666 count += req.length; 667 } 668 } 669 bc.syncAll(); 670 delta = (System.nanoTime() - t0) * 1e-3f; 671 Log.v(TAG, "copy over bandwidth = " + (count / delta) + " M/s"); 672 673 // Read 674 count = 0; 675 t0 = System.nanoTime(); 676 for (int i = 0; i < 1000; i++) { 677 req.key = i; 678 req.buffer = data; 679 if (bc.lookup(req)) { 680 count += req.length; 681 } 682 } 683 bc.syncAll(); 684 delta = (System.nanoTime() - t0) * 1e-3f; 685 Log.v(TAG, "read bandwidth = " + (count / delta) + " M/s"); 686 687 bc.close(); 688 } 689 690 @LargeTest 691 public void testSmallSize() throws IOException { 692 BlobCache bc = new BlobCache(TEST_FILE_NAME, MAX_ENTRIES, 40, true); 693 694 // Small size test 695 Random rand = new Random(0); 696 for (int i = 0; i < 100; i++) { 697 byte[] data = new byte[rand.nextInt(3)]; 698 bc.insert(rand.nextLong(), data); 699 } 700 701 bc.close(); 702 } 703 704 @LargeTest 705 public void testManyEntries() throws IOException { 706 BlobCache bc = new BlobCache(TEST_FILE_NAME, 1, MAX_BYTES, true); 707 708 // Many entries test 709 Random rand = new Random(0); 710 for (int i = 0; i < 100; i++) { 711 byte[] data = new byte[rand.nextInt(10)]; 712 } 713 714 bc.close(); 715 } 716 717 private void genData(byte[] data, int seed) { 718 for(int i = 0; i < data.length; i++) { 719 data[i] = (byte) (seed * i); 720 } 721 } 722 723 private void assertSameData(byte[] data1, byte[] data2) { 724 if (data1 == null && data2 == null) return; 725 if (data1 == null || data2 == null) fail(); 726 if (data1.length != data2.length) fail(); 727 for (int i = 0; i < data1.length; i++) { 728 if (data1[i] != data2[i]) fail(); 729 } 730 } 731 732 private void assertSameData(byte[] data1, byte[] data2, int n) { 733 if (data1 == null || data2 == null) fail(); 734 for (int i = 0; i < n; i++) { 735 if (data1[i] != data2[i]) fail(); 736 } 737 } 738 } 739