1 /* 2 * Copyright (C) 2009 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.server; 18 19 import android.content.ContentResolver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.os.DropBoxManager; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 import android.os.ParcelFileDescriptor; 26 import android.os.Process; 27 import android.os.ServiceManager; 28 import android.os.StatFs; 29 import android.provider.Settings; 30 import android.test.AndroidTestCase; 31 32 import com.android.server.DropBoxManagerService; 33 34 import java.io.BufferedReader; 35 import java.io.File; 36 import java.io.FileOutputStream; 37 import java.io.FileWriter; 38 import java.io.IOException; 39 import java.io.InputStream; 40 import java.io.InputStreamReader; 41 import java.util.Random; 42 import java.util.zip.GZIPOutputStream; 43 44 /** Test {@link DropBoxManager} functionality. */ 45 public class DropBoxTest extends AndroidTestCase { tearDown()46 public void tearDown() throws Exception { 47 ContentResolver cr = getContext().getContentResolver(); 48 Settings.Global.putString(cr, Settings.Global.DROPBOX_AGE_SECONDS, ""); 49 Settings.Global.putString(cr, Settings.Global.DROPBOX_MAX_FILES, ""); 50 Settings.Global.putString(cr, Settings.Global.DROPBOX_QUOTA_KB, ""); 51 Settings.Global.putString(cr, Settings.Global.DROPBOX_TAG_PREFIX + "DropBoxTest", ""); 52 } 53 testAddText()54 public void testAddText() throws Exception { 55 DropBoxManager dropbox = (DropBoxManager) getContext().getSystemService( 56 Context.DROPBOX_SERVICE); 57 long before = System.currentTimeMillis(); 58 Thread.sleep(5); 59 dropbox.addText("DropBoxTest", "TEST0"); 60 Thread.sleep(5); 61 long between = System.currentTimeMillis(); 62 Thread.sleep(5); 63 dropbox.addText("DropBoxTest", "TEST1"); 64 dropbox.addText("DropBoxTest", "TEST2"); 65 Thread.sleep(5); 66 long after = System.currentTimeMillis(); 67 68 DropBoxManager.Entry e0 = dropbox.getNextEntry("DropBoxTest", before); 69 DropBoxManager.Entry e1 = dropbox.getNextEntry("DropBoxTest", e0.getTimeMillis()); 70 DropBoxManager.Entry e2 = dropbox.getNextEntry("DropBoxTest", e1.getTimeMillis()); 71 assertTrue(null == dropbox.getNextEntry("DropBoxTest", e2.getTimeMillis())); 72 73 assertTrue(e0.getTimeMillis() > before); 74 assertTrue(e0.getTimeMillis() < between); 75 assertTrue(e1.getTimeMillis() > between); 76 assertTrue(e1.getTimeMillis() < e2.getTimeMillis()); 77 assertTrue(e2.getTimeMillis() < after); 78 79 assertEquals("TEST0", e0.getText(80)); 80 assertEquals("TEST1", e1.getText(80)); 81 assertEquals("TES", e2.getText(3)); 82 83 e0.close(); 84 e1.close(); 85 e2.close(); 86 } 87 88 public void testAddData() throws Exception { 89 DropBoxManager dropbox = (DropBoxManager) getContext().getSystemService( 90 Context.DROPBOX_SERVICE); 91 long before = System.currentTimeMillis(); 92 dropbox.addData("DropBoxTest", "TEST".getBytes(), 0); 93 long after = System.currentTimeMillis(); 94 95 DropBoxManager.Entry e = dropbox.getNextEntry("DropBoxTest", before); 96 assertTrue(null == dropbox.getNextEntry("DropBoxTest", e.getTimeMillis())); 97 98 assertEquals("DropBoxTest", e.getTag()); 99 assertTrue(e.getTimeMillis() >= before); 100 assertEquals(0, e.getFlags()); 101 assertTrue(null == e.getText(80)); 102 103 byte[] buf = new byte[80]; 104 assertEquals("TEST", new String(buf, 0, e.getInputStream().read(buf))); 105 106 e.close(); 107 } 108 109 public void testAddFile() throws Exception { 110 File dir = getEmptyDir("testAddFile"); 111 long before = System.currentTimeMillis(); 112 113 File f0 = new File(dir, "f0.txt"); 114 File f1 = new File(dir, "f1.txt.gz"); 115 File f2 = new File(dir, "f2.dat"); 116 File f3 = new File(dir, "f2.dat.gz"); 117 118 FileWriter w0 = new FileWriter(f0); 119 GZIPOutputStream gz1 = new GZIPOutputStream(new FileOutputStream(f1)); 120 FileOutputStream os2 = new FileOutputStream(f2); 121 GZIPOutputStream gz3 = new GZIPOutputStream(new FileOutputStream(f3)); 122 123 w0.write("FILE0"); 124 gz1.write("FILE1".getBytes()); 125 os2.write("DATA2".getBytes()); 126 gz3.write("DATA3".getBytes()); 127 128 w0.close(); 129 gz1.close(); 130 os2.close(); 131 gz3.close(); 132 133 DropBoxManager dropbox = (DropBoxManager) getContext().getSystemService( 134 Context.DROPBOX_SERVICE); 135 136 dropbox.addFile("DropBoxTest", f0, DropBoxManager.IS_TEXT); 137 dropbox.addFile("DropBoxTest", f1, DropBoxManager.IS_TEXT | DropBoxManager.IS_GZIPPED); 138 dropbox.addFile("DropBoxTest", f2, 0); 139 dropbox.addFile("DropBoxTest", f3, DropBoxManager.IS_GZIPPED); 140 141 DropBoxManager.Entry e0 = dropbox.getNextEntry("DropBoxTest", before); 142 DropBoxManager.Entry e1 = dropbox.getNextEntry("DropBoxTest", e0.getTimeMillis()); 143 DropBoxManager.Entry e2 = dropbox.getNextEntry("DropBoxTest", e1.getTimeMillis()); 144 DropBoxManager.Entry e3 = dropbox.getNextEntry("DropBoxTest", e2.getTimeMillis()); 145 assertTrue(null == dropbox.getNextEntry("DropBoxTest", e3.getTimeMillis())); 146 147 assertTrue(e0.getTimeMillis() > before); 148 assertTrue(e1.getTimeMillis() > e0.getTimeMillis()); 149 assertTrue(e2.getTimeMillis() > e1.getTimeMillis()); 150 assertTrue(e3.getTimeMillis() > e2.getTimeMillis()); 151 152 assertEquals(DropBoxManager.IS_TEXT, e0.getFlags()); 153 assertEquals(DropBoxManager.IS_TEXT, e1.getFlags()); 154 assertEquals(0, e2.getFlags()); 155 assertEquals(0, e3.getFlags()); 156 157 assertEquals("FILE0", e0.getText(80)); 158 159 byte[] buf1 = new byte[80]; 160 assertEquals("FILE1", new String(buf1, 0, e1.getInputStream().read(buf1))); 161 162 assertTrue(null == e2.getText(80)); 163 byte[] buf2 = new byte[80]; 164 assertEquals("DATA2", new String(buf2, 0, e2.getInputStream().read(buf2))); 165 166 assertTrue(null == e3.getText(80)); 167 byte[] buf3 = new byte[80]; 168 assertEquals("DATA3", new String(buf3, 0, e3.getInputStream().read(buf3))); 169 170 e0.close(); 171 e1.close(); 172 e2.close(); 173 e3.close(); 174 } 175 testAddEntriesInTheFuture()176 public void testAddEntriesInTheFuture() throws Exception { 177 File dir = getEmptyDir("testAddEntriesInTheFuture"); 178 long before = System.currentTimeMillis(); 179 180 // Near future: should be allowed to persist 181 FileWriter w0 = new FileWriter(new File(dir, "DropBoxTest@" + (before + 5000) + ".txt")); 182 w0.write("FUTURE0"); 183 w0.close(); 184 185 // Far future: should be collapsed 186 FileWriter w1 = new FileWriter(new File(dir, "DropBoxTest@" + (before + 100000) + ".txt")); 187 w1.write("FUTURE1"); 188 w1.close(); 189 190 // Another far future item, this one gzipped 191 File f2 = new File(dir, "DropBoxTest@" + (before + 100001) + ".txt.gz"); 192 GZIPOutputStream gz2 = new GZIPOutputStream(new FileOutputStream(f2)); 193 gz2.write("FUTURE2".getBytes()); 194 gz2.close(); 195 196 // Tombstone in the far future 197 new FileOutputStream(new File(dir, "DropBoxTest@" + (before + 100002) + ".lost")).close(); 198 199 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); 200 DropBoxManager dropbox = new DropBoxManager(service); 201 202 // Until a write, the timestamps are taken at face value 203 DropBoxManager.Entry e0 = dropbox.getNextEntry(null, before); 204 DropBoxManager.Entry e1 = dropbox.getNextEntry(null, e0.getTimeMillis()); 205 DropBoxManager.Entry e2 = dropbox.getNextEntry(null, e1.getTimeMillis()); 206 DropBoxManager.Entry e3 = dropbox.getNextEntry(null, e2.getTimeMillis()); 207 assertTrue(null == dropbox.getNextEntry(null, e3.getTimeMillis())); 208 209 assertEquals("FUTURE0", e0.getText(80)); 210 assertEquals("FUTURE1", e1.getText(80)); 211 assertEquals("FUTURE2", e2.getText(80)); 212 assertEquals(null, e3.getText(80)); 213 214 assertEquals(before + 5000, e0.getTimeMillis()); 215 assertEquals(before + 100000, e1.getTimeMillis()); 216 assertEquals(before + 100001, e2.getTimeMillis()); 217 assertEquals(before + 100002, e3.getTimeMillis()); 218 219 e0.close(); 220 e1.close(); 221 e2.close(); 222 e3.close(); 223 224 // Write something to force a collapse 225 dropbox.addText("NotDropBoxTest", "FUTURE"); 226 e0 = dropbox.getNextEntry(null, before); 227 e1 = dropbox.getNextEntry(null, e0.getTimeMillis()); 228 e2 = dropbox.getNextEntry(null, e1.getTimeMillis()); 229 e3 = dropbox.getNextEntry(null, e2.getTimeMillis()); 230 assertTrue(null == dropbox.getNextEntry("DropBoxTest", e3.getTimeMillis())); 231 232 assertEquals("FUTURE0", e0.getText(80)); 233 assertEquals("FUTURE1", e1.getText(80)); 234 assertEquals("FUTURE2", e2.getText(80)); 235 assertEquals(null, e3.getText(80)); 236 237 assertEquals(before + 5000, e0.getTimeMillis()); 238 assertEquals(before + 5001, e1.getTimeMillis()); 239 assertEquals(before + 5002, e2.getTimeMillis()); 240 assertEquals(before + 5003, e3.getTimeMillis()); 241 242 e0.close(); 243 e1.close(); 244 e2.close(); 245 e3.close(); 246 service.stop(); 247 } 248 testIsTagEnabled()249 public void testIsTagEnabled() throws Exception { 250 DropBoxManager dropbox = (DropBoxManager) getContext().getSystemService( 251 Context.DROPBOX_SERVICE); 252 long before = System.currentTimeMillis(); 253 dropbox.addText("DropBoxTest", "TEST-ENABLED"); 254 assertTrue(dropbox.isTagEnabled("DropBoxTest")); 255 256 ContentResolver cr = getContext().getContentResolver(); 257 Settings.Global.putString(cr, Settings.Global.DROPBOX_TAG_PREFIX + "DropBoxTest", 258 "disabled"); 259 260 dropbox.addText("DropBoxTest", "TEST-DISABLED"); 261 assertFalse(dropbox.isTagEnabled("DropBoxTest")); 262 263 Settings.Global.putString(cr, Settings.Global.DROPBOX_TAG_PREFIX + "DropBoxTest", 264 ""); 265 266 dropbox.addText("DropBoxTest", "TEST-ENABLED-AGAIN"); 267 assertTrue(dropbox.isTagEnabled("DropBoxTest")); 268 269 DropBoxManager.Entry e0 = dropbox.getNextEntry("DropBoxTest", before); 270 DropBoxManager.Entry e1 = dropbox.getNextEntry("DropBoxTest", e0.getTimeMillis()); 271 assertTrue(null == dropbox.getNextEntry("DropBoxTest", e1.getTimeMillis())); 272 273 assertEquals("TEST-ENABLED", e0.getText(80)); 274 assertEquals("TEST-ENABLED-AGAIN", e1.getText(80)); 275 276 e0.close(); 277 e1.close(); 278 } 279 testGetNextEntry()280 public void testGetNextEntry() throws Exception { 281 File dir = getEmptyDir("testGetNextEntry"); 282 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); 283 DropBoxManager dropbox = new DropBoxManager(service); 284 285 long before = System.currentTimeMillis(); 286 dropbox.addText("DropBoxTest.A", "A0"); 287 dropbox.addText("DropBoxTest.B", "B0"); 288 dropbox.addText("DropBoxTest.A", "A1"); 289 290 DropBoxManager.Entry a0 = dropbox.getNextEntry("DropBoxTest.A", before); 291 DropBoxManager.Entry a1 = dropbox.getNextEntry("DropBoxTest.A", a0.getTimeMillis()); 292 assertTrue(null == dropbox.getNextEntry("DropBoxTest.A", a1.getTimeMillis())); 293 294 DropBoxManager.Entry b0 = dropbox.getNextEntry("DropBoxTest.B", before); 295 assertTrue(null == dropbox.getNextEntry("DropBoxTest.B", b0.getTimeMillis())); 296 297 DropBoxManager.Entry x0 = dropbox.getNextEntry(null, before); 298 DropBoxManager.Entry x1 = dropbox.getNextEntry(null, x0.getTimeMillis()); 299 DropBoxManager.Entry x2 = dropbox.getNextEntry(null, x1.getTimeMillis()); 300 assertTrue(null == dropbox.getNextEntry(null, x2.getTimeMillis())); 301 302 assertEquals("DropBoxTest.A", a0.getTag()); 303 assertEquals("DropBoxTest.A", a1.getTag()); 304 assertEquals("A0", a0.getText(80)); 305 assertEquals("A1", a1.getText(80)); 306 307 assertEquals("DropBoxTest.B", b0.getTag()); 308 assertEquals("B0", b0.getText(80)); 309 310 assertEquals("DropBoxTest.A", x0.getTag()); 311 assertEquals("DropBoxTest.B", x1.getTag()); 312 assertEquals("DropBoxTest.A", x2.getTag()); 313 assertEquals("A0", x0.getText(80)); 314 assertEquals("B0", x1.getText(80)); 315 assertEquals("A1", x2.getText(80)); 316 317 a0.close(); 318 a1.close(); 319 b0.close(); 320 x0.close(); 321 x1.close(); 322 x2.close(); 323 service.stop(); 324 } 325 testSizeLimits()326 public void testSizeLimits() throws Exception { 327 File dir = getEmptyDir("testSizeLimits"); 328 int blockSize = new StatFs(dir.getPath()).getBlockSize(); 329 330 // Limit storage to 10 blocks 331 int kb = blockSize * 10 / 1024; 332 ContentResolver cr = getContext().getContentResolver(); 333 Settings.Global.putString(cr, Settings.Global.DROPBOX_QUOTA_KB, Integer.toString(kb)); 334 335 // Three tags using a total of 12 blocks: 336 // DropBoxTest0 [ ][ ] 337 // DropBoxTest1 [x][ ][ ][ ][xxx(20 blocks)xxx] 338 // DropBoxTest2 [xxxxxxxxxx][ ][ ] 339 // 340 // The blocks marked "x" will be removed due to storage restrictions. 341 // Use random fill (so it doesn't compress), subtract a little for gzip overhead 342 343 final int overhead = 64; 344 long before = System.currentTimeMillis(); 345 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); 346 DropBoxManager dropbox = new DropBoxManager(service); 347 348 addRandomEntry(dropbox, "DropBoxTest0", blockSize - overhead); 349 addRandomEntry(dropbox, "DropBoxTest0", blockSize - overhead); 350 351 addRandomEntry(dropbox, "DropBoxTest1", blockSize - overhead); 352 addRandomEntry(dropbox, "DropBoxTest1", blockSize - overhead); 353 addRandomEntry(dropbox, "DropBoxTest1", blockSize * 2 - overhead); 354 addRandomEntry(dropbox, "DropBoxTest1", blockSize - overhead); 355 addRandomEntry(dropbox, "DropBoxTest1", blockSize * 20 - overhead); 356 357 addRandomEntry(dropbox, "DropBoxTest2", blockSize * 4 - overhead); 358 addRandomEntry(dropbox, "DropBoxTest2", blockSize - overhead); 359 addRandomEntry(dropbox, "DropBoxTest2", blockSize - overhead); 360 361 DropBoxManager.Entry e0 = dropbox.getNextEntry(null, before); 362 DropBoxManager.Entry e1 = dropbox.getNextEntry(null, e0.getTimeMillis()); 363 DropBoxManager.Entry e2 = dropbox.getNextEntry(null, e1.getTimeMillis()); 364 DropBoxManager.Entry e3 = dropbox.getNextEntry(null, e2.getTimeMillis()); 365 DropBoxManager.Entry e4 = dropbox.getNextEntry(null, e3.getTimeMillis()); 366 DropBoxManager.Entry e5 = dropbox.getNextEntry(null, e4.getTimeMillis()); 367 DropBoxManager.Entry e6 = dropbox.getNextEntry(null, e5.getTimeMillis()); 368 DropBoxManager.Entry e7 = dropbox.getNextEntry(null, e6.getTimeMillis()); 369 DropBoxManager.Entry e8 = dropbox.getNextEntry(null, e7.getTimeMillis()); 370 DropBoxManager.Entry e9 = dropbox.getNextEntry(null, e8.getTimeMillis()); 371 assertTrue(null == dropbox.getNextEntry(null, e9.getTimeMillis())); 372 373 assertEquals("DropBoxTest0", e0.getTag()); 374 assertEquals("DropBoxTest0", e1.getTag()); 375 assertEquals(blockSize - overhead, getEntrySize(e0)); 376 assertEquals(blockSize - overhead, getEntrySize(e1)); 377 378 assertEquals("DropBoxTest1", e2.getTag()); 379 assertEquals("DropBoxTest1", e3.getTag()); 380 assertEquals("DropBoxTest1", e4.getTag()); 381 assertEquals("DropBoxTest1", e5.getTag()); 382 assertEquals("DropBoxTest1", e6.getTag()); 383 assertEquals(-1, getEntrySize(e2)); // Tombstone 384 assertEquals(blockSize - overhead, getEntrySize(e3)); 385 assertEquals(blockSize * 2 - overhead, getEntrySize(e4)); 386 assertEquals(blockSize - overhead, getEntrySize(e5)); 387 assertEquals(-1, getEntrySize(e6)); 388 389 assertEquals("DropBoxTest2", e7.getTag()); 390 assertEquals("DropBoxTest2", e8.getTag()); 391 assertEquals("DropBoxTest2", e9.getTag()); 392 assertEquals(-1, getEntrySize(e7)); // Tombstone 393 assertEquals(blockSize - overhead, getEntrySize(e8)); 394 assertEquals(blockSize - overhead, getEntrySize(e9)); 395 396 e0.close(); 397 e1.close(); 398 e2.close(); 399 e3.close(); 400 e4.close(); 401 e5.close(); 402 e6.close(); 403 e7.close(); 404 e8.close(); 405 e9.close(); 406 407 // Specifying a tag name skips tombstone records. 408 409 DropBoxManager.Entry t0 = dropbox.getNextEntry("DropBoxTest1", before); 410 DropBoxManager.Entry t1 = dropbox.getNextEntry("DropBoxTest1", t0.getTimeMillis()); 411 DropBoxManager.Entry t2 = dropbox.getNextEntry("DropBoxTest1", t1.getTimeMillis()); 412 assertTrue(null == dropbox.getNextEntry("DropBoxTest1", t2.getTimeMillis())); 413 414 assertEquals("DropBoxTest1", t0.getTag()); 415 assertEquals("DropBoxTest1", t1.getTag()); 416 assertEquals("DropBoxTest1", t2.getTag()); 417 418 assertEquals(blockSize - overhead, getEntrySize(t0)); 419 assertEquals(blockSize * 2 - overhead, getEntrySize(t1)); 420 assertEquals(blockSize - overhead, getEntrySize(t2)); 421 422 t0.close(); 423 t1.close(); 424 t2.close(); 425 service.stop(); 426 } 427 testAgeLimits()428 public void testAgeLimits() throws Exception { 429 File dir = getEmptyDir("testAgeLimits"); 430 int blockSize = new StatFs(dir.getPath()).getBlockSize(); 431 432 // Limit storage to 10 blocks with an expiration of 1 second 433 int kb = blockSize * 10 / 1024; 434 ContentResolver cr = getContext().getContentResolver(); 435 Settings.Global.putString(cr, Settings.Global.DROPBOX_AGE_SECONDS, "1"); 436 Settings.Global.putString(cr, Settings.Global.DROPBOX_QUOTA_KB, Integer.toString(kb)); 437 438 // Write one normal entry and another so big that it is instantly tombstoned 439 long before = System.currentTimeMillis(); 440 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); 441 DropBoxManager dropbox = new DropBoxManager(service); 442 443 dropbox.addText("DropBoxTest", "TEST"); 444 addRandomEntry(dropbox, "DropBoxTest", blockSize * 20); 445 446 // Verify that things are as expected 447 DropBoxManager.Entry e0 = dropbox.getNextEntry(null, before); 448 DropBoxManager.Entry e1 = dropbox.getNextEntry(null, e0.getTimeMillis()); 449 assertTrue(null == dropbox.getNextEntry(null, e1.getTimeMillis())); 450 451 assertEquals("TEST", e0.getText(80)); 452 assertEquals(null, e1.getText(80)); 453 assertEquals(-1, getEntrySize(e1)); 454 455 e0.close(); 456 e1.close(); 457 458 // Wait a second and write another entry -- old ones should be expunged 459 Thread.sleep(2000); 460 dropbox.addText("DropBoxTest", "TEST1"); 461 462 e0 = dropbox.getNextEntry(null, before); 463 assertTrue(null == dropbox.getNextEntry(null, e0.getTimeMillis())); 464 assertEquals("TEST1", e0.getText(80)); 465 e0.close(); 466 } 467 testFileCountLimits()468 public void testFileCountLimits() throws Exception { 469 File dir = getEmptyDir("testFileCountLimits"); 470 471 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); 472 DropBoxManager dropbox = new DropBoxManager(service); 473 dropbox.addText("DropBoxTest", "TEST0"); 474 dropbox.addText("DropBoxTest", "TEST1"); 475 dropbox.addText("DropBoxTest", "TEST2"); 476 dropbox.addText("DropBoxTest", "TEST3"); 477 dropbox.addText("DropBoxTest", "TEST4"); 478 dropbox.addText("DropBoxTest", "TEST5"); 479 480 // Verify 6 files added 481 DropBoxManager.Entry e0 = dropbox.getNextEntry(null, 0); 482 DropBoxManager.Entry e1 = dropbox.getNextEntry(null, e0.getTimeMillis()); 483 DropBoxManager.Entry e2 = dropbox.getNextEntry(null, e1.getTimeMillis()); 484 DropBoxManager.Entry e3 = dropbox.getNextEntry(null, e2.getTimeMillis()); 485 DropBoxManager.Entry e4 = dropbox.getNextEntry(null, e3.getTimeMillis()); 486 DropBoxManager.Entry e5 = dropbox.getNextEntry(null, e4.getTimeMillis()); 487 assertTrue(null == dropbox.getNextEntry(null, e5.getTimeMillis())); 488 assertEquals("TEST0", e0.getText(80)); 489 assertEquals("TEST5", e5.getText(80)); 490 491 e0.close(); 492 e1.close(); 493 e2.close(); 494 e3.close(); 495 e4.close(); 496 e5.close(); 497 498 // Limit to 3 files and add one more entry 499 ContentResolver cr = getContext().getContentResolver(); 500 Settings.Global.putString(cr, Settings.Global.DROPBOX_MAX_FILES, "3"); 501 dropbox.addText("DropBoxTest", "TEST6"); 502 503 // Verify only 3 files left 504 DropBoxManager.Entry f0 = dropbox.getNextEntry(null, 0); 505 DropBoxManager.Entry f1 = dropbox.getNextEntry(null, f0.getTimeMillis()); 506 DropBoxManager.Entry f2 = dropbox.getNextEntry(null, f1.getTimeMillis()); 507 assertTrue(null == dropbox.getNextEntry(null, f2.getTimeMillis())); 508 assertEquals("TEST4", f0.getText(80)); 509 assertEquals("TEST5", f1.getText(80)); 510 assertEquals("TEST6", f2.getText(80)); 511 512 f0.close(); 513 f1.close(); 514 f2.close(); 515 } 516 testCreateDropBoxManagerWithInvalidDirectory()517 public void testCreateDropBoxManagerWithInvalidDirectory() throws Exception { 518 // If created with an invalid directory, the DropBoxManager should suffer quietly 519 // and fail all operations (this is how it survives a full disk). 520 // Once the directory becomes possible to create, it will start working. 521 522 File dir = new File(getEmptyDir("testCreateDropBoxManagerWith"), "InvalidDirectory"); 523 new FileOutputStream(dir).close(); // Create an empty file 524 DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); 525 DropBoxManager dropbox = new DropBoxManager(service); 526 527 dropbox.addText("DropBoxTest", "should be ignored"); 528 dropbox.addData("DropBoxTest", "should be ignored".getBytes(), 0); 529 assertTrue(null == dropbox.getNextEntry("DropBoxTest", 0)); 530 531 dir.delete(); // Remove the file so a directory can be created 532 dropbox.addText("DropBoxTest", "TEST"); 533 DropBoxManager.Entry e = dropbox.getNextEntry("DropBoxTest", 0); 534 assertTrue(null == dropbox.getNextEntry("DropBoxTest", e.getTimeMillis())); 535 assertEquals("DropBoxTest", e.getTag()); 536 assertEquals("TEST", e.getText(80)); 537 e.close(); 538 service.stop(); 539 } 540 testDropBoxEntrySerialization()541 public void testDropBoxEntrySerialization() throws Exception { 542 // Make sure DropBoxManager.Entry can be serialized to a Parcel and back 543 // under a variety of conditions. 544 545 Parcel parcel = Parcel.obtain(); 546 File dir = getEmptyDir("testDropBoxEntrySerialization"); 547 548 new DropBoxManager.Entry("empty", 1000000).writeToParcel(parcel, 0); 549 new DropBoxManager.Entry("string", 2000000, "String Value").writeToParcel(parcel, 0); 550 new DropBoxManager.Entry("bytes", 3000000, "Bytes Value".getBytes(), 551 DropBoxManager.IS_TEXT).writeToParcel(parcel, 0); 552 new DropBoxManager.Entry("zerobytes", 4000000, new byte[0], 0).writeToParcel(parcel, 0); 553 new DropBoxManager.Entry("emptybytes", 5000000, (byte[]) null, 554 DropBoxManager.IS_EMPTY).writeToParcel(parcel, 0); 555 556 try { 557 new DropBoxManager.Entry("badbytes", 99999, 558 "Bad Bytes Value".getBytes(), 559 DropBoxManager.IS_EMPTY).writeToParcel(parcel, 0); 560 fail("IllegalArgumentException expected for non-null byte[] and IS_EMPTY flags"); 561 } catch (IllegalArgumentException e) { 562 // expected 563 } 564 565 try { 566 new DropBoxManager.Entry("badbytes", 99999, (byte[]) null, 0).writeToParcel(parcel, 0); 567 fail("IllegalArgumentException expected for null byte[] and non-IS_EMPTY flags"); 568 } catch (IllegalArgumentException e) { 569 // expected 570 } 571 572 File f = new File(dir, "file.dat"); 573 FileOutputStream os = new FileOutputStream(f); 574 os.write("File Value".getBytes()); 575 os.close(); 576 577 new DropBoxManager.Entry("file", 6000000, f, DropBoxManager.IS_TEXT).writeToParcel( 578 parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 579 new DropBoxManager.Entry("binfile", 7000000, f, 0).writeToParcel( 580 parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 581 new DropBoxManager.Entry("emptyfile", 8000000, (ParcelFileDescriptor) null, 582 DropBoxManager.IS_EMPTY).writeToParcel(parcel, 0); 583 584 try { 585 new DropBoxManager.Entry("badfile", 99999, new File(dir, "nonexist.dat"), 0); 586 fail("IOException expected for nonexistent file"); 587 } catch (IOException e) { 588 // expected 589 } 590 591 try { 592 new DropBoxManager.Entry("badfile", 99999, f, DropBoxManager.IS_EMPTY).writeToParcel( 593 parcel, 0); 594 fail("IllegalArgumentException expected for non-null file and IS_EMPTY flags"); 595 } catch (IllegalArgumentException e) { 596 // expected 597 } 598 599 try { 600 new DropBoxManager.Entry("badfile", 99999, (ParcelFileDescriptor) null, 0); 601 fail("IllegalArgumentException expected for null PFD and non-IS_EMPTY flags"); 602 } catch (IllegalArgumentException e) { 603 // expected 604 } 605 606 File gz = new File(dir, "file.gz"); 607 GZIPOutputStream gzout = new GZIPOutputStream(new FileOutputStream(gz)); 608 gzout.write("Gzip File Value".getBytes()); 609 gzout.close(); 610 611 new DropBoxManager.Entry("gzipfile", 9000000, gz, 612 DropBoxManager.IS_TEXT | DropBoxManager.IS_GZIPPED).writeToParcel( 613 parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 614 new DropBoxManager.Entry("gzipbinfile", 10000000, gz, 615 DropBoxManager.IS_GZIPPED).writeToParcel( 616 parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 617 618 // 619 // Switch from writing to reading 620 // 621 622 parcel.setDataPosition(0); 623 DropBoxManager.Entry e; 624 625 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 626 assertEquals("empty", e.getTag()); 627 assertEquals(1000000, e.getTimeMillis()); 628 assertEquals(DropBoxManager.IS_EMPTY, e.getFlags()); 629 assertEquals(null, e.getText(100)); 630 assertEquals(null, e.getInputStream()); 631 e.close(); 632 633 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 634 assertEquals("string", e.getTag()); 635 assertEquals(2000000, e.getTimeMillis()); 636 assertEquals(DropBoxManager.IS_TEXT, e.getFlags()); 637 assertEquals("String Value", e.getText(100)); 638 assertEquals("String Value", 639 new BufferedReader(new InputStreamReader(e.getInputStream())).readLine()); 640 e.close(); 641 642 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 643 assertEquals("bytes", e.getTag()); 644 assertEquals(3000000, e.getTimeMillis()); 645 assertEquals(DropBoxManager.IS_TEXT, e.getFlags()); 646 assertEquals("Bytes Value", e.getText(100)); 647 e.close(); 648 649 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 650 assertEquals("zerobytes", e.getTag()); 651 assertEquals(4000000, e.getTimeMillis()); 652 assertEquals(0, e.getFlags()); 653 assertEquals(null, e.getText(100)); 654 assertEquals(null, 655 new BufferedReader(new InputStreamReader(e.getInputStream())).readLine()); 656 e.close(); 657 658 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 659 assertEquals("emptybytes", e.getTag()); 660 assertEquals(5000000, e.getTimeMillis()); 661 assertEquals(DropBoxManager.IS_EMPTY, e.getFlags()); 662 assertEquals(null, e.getText(100)); 663 assertEquals(null, e.getInputStream()); 664 e.close(); 665 666 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 667 assertEquals("file", e.getTag()); 668 assertEquals(6000000, e.getTimeMillis()); 669 assertEquals(DropBoxManager.IS_TEXT, e.getFlags()); 670 assertEquals("File Value", e.getText(100)); 671 e.close(); 672 673 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 674 assertEquals("binfile", e.getTag()); 675 assertEquals(7000000, e.getTimeMillis()); 676 assertEquals(0, e.getFlags()); 677 assertEquals(null, e.getText(100)); 678 assertEquals("File Value", 679 new BufferedReader(new InputStreamReader(e.getInputStream())).readLine()); 680 e.close(); 681 682 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 683 assertEquals("emptyfile", e.getTag()); 684 assertEquals(8000000, e.getTimeMillis()); 685 assertEquals(DropBoxManager.IS_EMPTY, e.getFlags()); 686 assertEquals(null, e.getText(100)); 687 assertEquals(null, e.getInputStream()); 688 e.close(); 689 690 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 691 assertEquals("gzipfile", e.getTag()); 692 assertEquals(9000000, e.getTimeMillis()); 693 assertEquals(DropBoxManager.IS_TEXT, e.getFlags()); 694 assertEquals("Gzip File Value", e.getText(100)); 695 e.close(); 696 697 e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 698 assertEquals("gzipbinfile", e.getTag()); 699 assertEquals(10000000, e.getTimeMillis()); 700 assertEquals(0, e.getFlags()); 701 assertEquals(null, e.getText(100)); 702 assertEquals("Gzip File Value", 703 new BufferedReader(new InputStreamReader(e.getInputStream())).readLine()); 704 e.close(); 705 706 assertEquals(0, parcel.dataAvail()); 707 parcel.recycle(); 708 } 709 testDropBoxEntrySerializationDoesntLeakFileDescriptors()710 public void testDropBoxEntrySerializationDoesntLeakFileDescriptors() throws Exception { 711 File dir = getEmptyDir("testDropBoxEntrySerialization"); 712 File f = new File(dir, "file.dat"); 713 FileOutputStream os = new FileOutputStream(f); 714 os.write("File Value".getBytes()); 715 os.close(); 716 717 int before = countOpenFiles(); 718 assertTrue(before > 0); 719 720 for (int i = 0; i < 1000; i++) { 721 Parcel parcel = Parcel.obtain(); 722 new DropBoxManager.Entry("file", 1000000, f, 0).writeToParcel( 723 parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 724 725 parcel.setDataPosition(0); 726 DropBoxManager.Entry e = DropBoxManager.Entry.CREATOR.createFromParcel(parcel); 727 assertEquals("file", e.getTag()); 728 e.close(); 729 730 parcel.recycle(); 731 } 732 733 int after = countOpenFiles(); 734 assertTrue(after > 0); 735 assertTrue(after < before + 20); 736 } 737 738 private void addRandomEntry(DropBoxManager dropbox, String tag, int size) throws Exception { 739 byte[] bytes = new byte[size]; 740 new Random(System.currentTimeMillis()).nextBytes(bytes); 741 742 File f = new File(getEmptyDir("addRandomEntry"), "random.dat"); 743 FileOutputStream os = new FileOutputStream(f); 744 os.write(bytes); 745 os.close(); 746 747 dropbox.addFile(tag, f, 0); 748 } 749 750 private int getEntrySize(DropBoxManager.Entry e) throws Exception { 751 InputStream is = e.getInputStream(); 752 if (is == null) return -1; 753 int length = 0; 754 while (is.read() != -1) length++; 755 return length; 756 } 757 758 private void recursiveDelete(File file) { 759 if (!file.delete() && file.isDirectory()) { 760 for (File f : file.listFiles()) recursiveDelete(f); 761 file.delete(); 762 } 763 } 764 765 private File getEmptyDir(String name) { 766 File dir = getContext().getDir("DropBoxTest." + name, 0); 767 for (File f : dir.listFiles()) recursiveDelete(f); 768 assertTrue(dir.listFiles().length == 0); 769 return dir; 770 } 771 772 private int countOpenFiles() { 773 return new File("/proc/" + Process.myPid() + "/fd").listFiles().length; 774 } 775 } 776