package com.qiniu.android; import android.test.InstrumentationTestCase; import android.util.Log; import com.qiniu.android.http.ResponseInfo; import com.qiniu.android.storage.Configuration; import com.qiniu.android.storage.UpCancellationSignal; import com.qiniu.android.storage.UpCompletionHandler; import com.qiniu.android.storage.UpProgressHandler; import com.qiniu.android.storage.UploadManager; import com.qiniu.android.storage.UploadOptions; import com.qiniu.android.storage.persistent.FileRecorder; import com.qiniu.android.utils.Etag; import junit.framework.Assert; import org.json.JSONObject; import java.io.File; import java.io.IOException; import java.security.MessageDigest; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; public class TestFileRecorder extends InstrumentationTestCase { final CountDownLatch signal = new CountDownLatch(1); final CountDownLatch signal2 = new CountDownLatch(1); private volatile boolean cancelled; private volatile boolean failed; private UploadManager uploadManager; private Configuration config; private volatile String key; private volatile ResponseInfo info; private volatile JSONObject resp; private volatile UploadOptions options; @Override protected void setUp() throws Exception { File f = File.createTempFile("qiniutest", "b"); String folder = f.getParent(); FileRecorder fr = new FileRecorder(folder); config = new Configuration.Builder().recorder(fr).build(); uploadManager = new UploadManager(config); ACollectUploadInfoTest.testInit(); } private void template(final int size, final double pos) throws Throwable { final File tempFile = TempFile.createFile(size); final String expectKey = "rc=" + size + "k"; cancelled = false; failed = false; Map<String, String> params = new HashMap<String, String>(); params.put("x:a", "test"); params.put("x:b", "test2"); options = new UploadOptions(params, null, false, new UpProgressHandler() { @Override public void progress(String key, double percent) { if (percent >= pos) { cancelled = true; } Log.i("qiniutest", "progress " + percent); } }, new UpCancellationSignal() { @Override public boolean isCancelled() { return cancelled; } }); runTestOnUiThread(new Runnable() { // THIS IS THE KEY TO SUCCESS public void run() { uploadManager.put(tempFile, expectKey, TestConfig.token_z0, new UpCompletionHandler() { public void complete(String k, ResponseInfo rinfo, JSONObject response) { Log.i("qiniutest", k + rinfo); key = k; info = rinfo; resp = response; signal.countDown(); } }, options); } }); try { signal.await(600, TimeUnit.SECONDS); // wait for callback Assert.assertNotNull("timeout", info); } catch (InterruptedException e) { e.printStackTrace(); } Assert.assertEquals(info.toString(), expectKey, key); Assert.assertTrue(info.toString(), info.isCancelled()); Assert.assertNull(resp); cancelled = false; options = new UploadOptions(null, null, false, new UpProgressHandler() { @Override public void progress(String key, double percent) { if (percent < pos - config.chunkSize / (size * 1024.0)) { failed = true; } Log.i("qiniutest", "continue progress " + percent); } }, null); runTestOnUiThread(new Runnable() { // THIS IS THE KEY TO SUCCESS public void run() { uploadManager.put(tempFile, expectKey, TestConfig.token_z0, new UpCompletionHandler() { public void complete(String k, ResponseInfo rinfo, JSONObject response) { Log.i("qiniutest", k + rinfo); key = k; info = rinfo; resp = response; signal2.countDown(); } }, options); } }); try { signal2.await(1200, TimeUnit.SECONDS); // wait for callback Assert.assertNotNull("timeout", info); } catch (InterruptedException e) { e.printStackTrace(); } Assert.assertEquals(info.toString(), expectKey, key); Assert.assertTrue(info.toString(), info.isOK()); Assert.assertTrue(!failed); Assert.assertNotNull(resp); String hash = resp.getString("hash"); Assert.assertEquals(hash, Etag.file(tempFile)); TempFile.remove(tempFile); ACollectUploadInfoTest.recordFileTest(); } public void test600k() throws Throwable { template(600, 0.7); } public void test700k() throws Throwable { template(700, 0.1); } public void test1M() throws Throwable { template(1024, 0.51); } public void test4M() throws Throwable { template(4 * 1024, 0.9); } public void test8M1K() throws Throwable { template(8 * 1024 + 1, 0.8); } public void testLastModify() throws IOException { File f = File.createTempFile("qiniutest", "b"); String folder = f.getParent(); FileRecorder fr = new FileRecorder(folder); String key = "test_profile_"; byte[] data = new byte[3]; data[0] = 'a'; data[1] = '8'; data[2] = 'b'; fr.set(key, data); byte[] data2 = fr.get(key); File recoderFile = new File(folder, hash(key)); long m1 = recoderFile.lastModified(); assertEquals(3, data2.length); assertEquals('8', data2[1]); recoderFile.setLastModified(new Date().getTime() - 1000 * 3600 * 48 + 2300); data2 = fr.get(key); assertEquals(3, data2.length); assertEquals('8', data2[1]); // 让记录文件过期,两天 recoderFile.setLastModified(new Date().getTime() - 1000 * 3600 * 48 - 2300); long m2 = recoderFile.lastModified(); // 过期后,记录数据作废 byte[] data3 = fr.get(key); assertNull(data3); assertTrue(m1 - m2 > 1000 * 3600 * 48 && m1 - m2 < 1000 * 3600 * 48 + 5500); try { Thread.sleep(2300); } catch (InterruptedException e) { e.printStackTrace(); } fr.set(key, data); long m4 = recoderFile.lastModified(); assertTrue(m4 > m1); } // copy from FileRecorder. private static String hash(String base) { try { MessageDigest digest = MessageDigest.getInstance("SHA-1"); byte[] hash = digest.digest(base.getBytes()); StringBuffer hexString = new StringBuffer(); for (int i = 0; i < hash.length; i++) { hexString.append(Integer.toString((hash[i] & 0xff) + 0x100, 16).substring(1)); } return hexString.toString(); } catch (Exception ex) { ex.printStackTrace(); } return null; } }