/** * Created by Pasin Suriyentrakorn on 9/3/15. * <p/> * Copyright (c) 2015 Couchbase, Inc All rights reserved. * <p/> * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License at * <p/> * http://www.apache.org/licenses/LICENSE-2.0 * <p/> * Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language governing permissions * and limitations under the License. * */ package com.couchbase.lite; import com.couchbase.lite.support.FileDirUtils; import com.couchbase.lite.support.security.SymmetricKey; import com.couchbase.lite.util.Log; import com.couchbase.lite.util.TextUtils; import junit.framework.Assert; import org.apache.commons.io.IOUtils; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; public class BlobStoreTest extends LiteTestCaseWithDB { private boolean encrypt; private File storeFile; private BlobStore store; @Override public void runBare() throws Throwable { encrypt = false; super.runBare(); encrypt = true; super.runBare(); } @Override protected void setUp() throws Exception { super.setUp(); // Create blob store: File storeFile = new File(manager.getDirectory(), "BlobStoreTest"); FileDirUtils.deleteRecursive(storeFile); Assert.assertFalse(storeFile.exists()); if (encrypt) Log.i(TAG, "---- Now enabling attachment encryption ----"); store = new BlobStore(manager.getContext(), storeFile.getPath(), (encrypt ? new SymmetricKey() : null), true); // If using encryption, the encryption marker must exist: File enMarkerFile = new File(storeFile, BlobStore.ENCRYPTION_MARKER_FILENAME); boolean markerExists = enMarkerFile.exists(); Assert.assertEquals(encrypt, markerExists); } @Override protected void tearDown() throws Exception { store = null; if (storeFile != null) FileDirUtils.deleteRecursive(storeFile); super.tearDown(); } private void verifyRawBlob(BlobKey key, byte[] clearText) throws IOException { String path = store.getRawPathForKey(key); byte[] raw; InputStream is = new FileInputStream(path); try { raw = TextUtils.read(is); } finally { is.close(); } Assert.assertNotNull(raw); if (store.getEncryptionKey() == null) { Assert.assertTrue(Arrays.equals(raw, clearText)); } else { Assert.assertTrue(!Arrays.equals(raw, clearText)); } } public void testBasic() throws Exception { if (!isSQLiteDB()) return; byte[] item = "this is an item".getBytes("UTF8"); BlobKey key = new BlobKey(); BlobKey key2 = new BlobKey(); store.storeBlob(item, key); store.storeBlob(item, key2); Assert.assertTrue(Arrays.equals(key.getBytes(), key2.getBytes())); byte[] readItem = store.blobForKey(key); Assert.assertTrue(Arrays.equals(readItem, item)); verifyRawBlob(key, item); String path = store.getBlobPathForKey(key); Assert.assertEquals((path == null), encrypt); // path is returned if not encrypted } public void testReopen() throws Exception { if (!isSQLiteDB()) return; byte[] item = "this is an item".getBytes("UTF8"); BlobKey key = new BlobKey(); Assert.assertTrue(store.storeBlob(item, key)); BlobStore store2 = new BlobStore(manager.getContext(), store.getPath(), store.getEncryptionKey(), true); Assert.assertNotNull("Couldn't re-open store", store2); byte[] readItem = store2.blobForKey(key); Assert.assertTrue(Arrays.equals(readItem, item)); readItem = store.blobForKey(key); Assert.assertTrue(Arrays.equals(readItem, item)); verifyRawBlob(key, item); } public void testBlobStoreWriter() throws Exception { if (!isSQLiteDB()) return; BlobStoreWriter writer = new BlobStoreWriter(store); Assert.assertNotNull(writer); writer.appendData("part 1, ".getBytes("UTF8")); writer.appendData("part 2, ".getBytes("UTF8")); writer.appendData("part 3".getBytes("UTF8")); writer.finish(); Assert.assertTrue(writer.install()); byte[] expectedData = "part 1, part 2, part 3".getBytes("UTF8"); byte[] readItem = store.blobForKey(writer.getBlobKey()); Assert.assertTrue(Arrays.equals(readItem, expectedData)); verifyRawBlob(writer.getBlobKey(), expectedData); } public void testBlobStoreWriterBasicOperation() throws Exception { if (!isSQLiteDB()) return; if (encrypt) return; // Not involve encryption test BlobStore attachments = database.getAttachmentStore(); InputStream attachmentStream = getAsset("attachment.png"); byte[] bytes = IOUtils.toByteArray(attachmentStream); BlobStoreWriter blobStoreWriter = new BlobStoreWriter(attachments); blobStoreWriter.appendData(bytes); blobStoreWriter.finish(); blobStoreWriter.install(); String sha1DigestKey = blobStoreWriter.sHA1DigestString(); assertTrue(sha1DigestKey.contains("LmsoqJJ6LOn4YS60pYnvrKbBd64=")); BlobKey keyFromSha1 = new BlobKey(sha1DigestKey); Assert.assertTrue(attachments.getSizeOfBlob(keyFromSha1) == bytes.length); } public void testBlobStoreWriterForBody() throws Exception { if (!isSQLiteDB()) return; if (encrypt) return; // Not involve encryption test InputStream attachmentStream = getAsset("attachment.png"); BlobStoreWriter blobStoreWriter = Attachment.blobStoreWriterForBody(attachmentStream, database); String sha1DigestKey = blobStoreWriter.sHA1DigestString(); assertTrue(sha1DigestKey.contains("LmsoqJJ6LOn4YS60pYnvrKbBd64=")); } }