| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.net; |
| 6 |
| 7 import android.test.suitebuilder.annotation.SmallTest; |
| 8 |
| 9 import org.chromium.base.test.util.Feature; |
| 10 |
| 11 import java.util.Arrays; |
| 12 import java.util.List; |
| 13 import java.util.concurrent.ExecutorService; |
| 14 import java.util.concurrent.Executors; |
| 15 |
| 16 /** |
| 17 * Tests that directly drive {@code CronetUploadDataStream} and |
| 18 * {@code UploadDataProvider} to simulate different ordering of reset, init, |
| 19 * read, and rewind calls. |
| 20 */ |
| 21 public class CronetUploadTest extends CronetTestBase { |
| 22 private TestDrivenDataProvider mDataProvider; |
| 23 private CronetUploadDataStream mUploadDataStream; |
| 24 private UploadDataStreamHandler mHandler; |
| 25 // Address of native CronetUploadDataStreamAdapter object. |
| 26 private long mAdapter = 0; |
| 27 |
| 28 @Override |
| 29 protected void setUp() throws Exception { |
| 30 super.setUp(); |
| 31 launchCronetTestApp(); |
| 32 ExecutorService executor = Executors.newSingleThreadExecutor(); |
| 33 List<byte[]> reads = Arrays.asList("hello".getBytes()); |
| 34 mDataProvider = new TestDrivenDataProvider(executor, reads); |
| 35 mUploadDataStream = new CronetUploadDataStream(mDataProvider, executor); |
| 36 mAdapter = mUploadDataStream.createAdapterForTesting(); |
| 37 mHandler = new UploadDataStreamHandler(mAdapter); |
| 38 } |
| 39 |
| 40 @Override |
| 41 protected void tearDown() throws Exception { |
| 42 // Destroy handler's native objects. |
| 43 mHandler.destroyNativeObjects(); |
| 44 super.tearDown(); |
| 45 } |
| 46 |
| 47 /** |
| 48 * Tests that after some data is read, init triggers a rewind, and that |
| 49 * before the rewind completes, init blocks. |
| 50 */ |
| 51 @SmallTest |
| 52 @Feature({"Cronet"}) |
| 53 public void testInitTriggersRewindAndInitBeforeRewindCompletes() |
| 54 throws Exception { |
| 55 // Init completes synchronously and read succeeds. |
| 56 assertTrue(mHandler.init()); |
| 57 mHandler.read(); |
| 58 mDataProvider.waitForReadRequest(); |
| 59 mHandler.checkReadCallbackNotInvoked(); |
| 60 mDataProvider.onReadSucceeded(mUploadDataStream); |
| 61 mHandler.waitForReadComplete(); |
| 62 mDataProvider.assertReadNotPending(); |
| 63 assertEquals(0, mDataProvider.getNumRewindCalls()); |
| 64 assertEquals(1, mDataProvider.getNumReadCalls()); |
| 65 assertEquals("hello", mHandler.getData()); |
| 66 |
| 67 // Reset and then init, which should trigger a rewind. |
| 68 mHandler.reset(); |
| 69 assertEquals("", mHandler.getData()); |
| 70 assertFalse(mHandler.init()); |
| 71 mDataProvider.waitForRewindRequest(); |
| 72 mHandler.checkInitCallbackNotInvoked(); |
| 73 |
| 74 // Before rewind completes, reset and init should block. |
| 75 mHandler.reset(); |
| 76 assertFalse(mHandler.init()); |
| 77 |
| 78 // Signal rewind completes, and wait for init to complete. |
| 79 mHandler.resetWaitForInitComplete(); |
| 80 mDataProvider.onRewindSucceeded(mUploadDataStream); |
| 81 mHandler.waitForInitComplete(); |
| 82 mDataProvider.assertRewindNotPending(); |
| 83 |
| 84 // Read should complete successfully since init has completed. |
| 85 mDataProvider.resetWaitForReadRequest(); |
| 86 mHandler.read(); |
| 87 mDataProvider.waitForReadRequest(); |
| 88 mHandler.checkReadCallbackNotInvoked(); |
| 89 mHandler.resetWaitForReadComplete(); |
| 90 mDataProvider.onReadSucceeded(mUploadDataStream); |
| 91 mHandler.waitForReadComplete(); |
| 92 mDataProvider.assertReadNotPending(); |
| 93 assertEquals(1, mDataProvider.getNumRewindCalls()); |
| 94 assertEquals(2, mDataProvider.getNumReadCalls()); |
| 95 assertEquals("hello", mHandler.getData()); |
| 96 } |
| 97 |
| 98 /** |
| 99 * Tests that after some data is read, init triggers a rewind, and that |
| 100 * after the rewind completes, init does not block. |
| 101 */ |
| 102 @SmallTest |
| 103 @Feature({"Cronet"}) |
| 104 public void testInitTriggersRewindAndInitAfterRewindCompletes() |
| 105 throws Exception { |
| 106 // Init completes synchronously and read succeeds. |
| 107 assertTrue(mHandler.init()); |
| 108 mHandler.read(); |
| 109 mDataProvider.waitForReadRequest(); |
| 110 mHandler.checkReadCallbackNotInvoked(); |
| 111 mDataProvider.onReadSucceeded(mUploadDataStream); |
| 112 mHandler.waitForReadComplete(); |
| 113 mDataProvider.assertReadNotPending(); |
| 114 assertEquals(0, mDataProvider.getNumRewindCalls()); |
| 115 assertEquals(1, mDataProvider.getNumReadCalls()); |
| 116 assertEquals("hello", mHandler.getData()); |
| 117 |
| 118 // Reset and then init, which should trigger a rewind. |
| 119 mHandler.reset(); |
| 120 assertEquals("", mHandler.getData()); |
| 121 assertFalse(mHandler.init()); |
| 122 mDataProvider.waitForRewindRequest(); |
| 123 mHandler.checkInitCallbackNotInvoked(); |
| 124 |
| 125 // Signal rewind completes, and wait for init to complete. |
| 126 mHandler.resetWaitForInitComplete(); |
| 127 mDataProvider.onRewindSucceeded(mUploadDataStream); |
| 128 mHandler.waitForInitComplete(); |
| 129 mDataProvider.assertRewindNotPending(); |
| 130 |
| 131 // Reset and init should not block, since rewind has completed. |
| 132 mHandler.reset(); |
| 133 assertTrue(mHandler.init()); |
| 134 |
| 135 // Read should complete successfully since init has completed. |
| 136 mDataProvider.resetWaitForReadRequest(); |
| 137 mHandler.read(); |
| 138 mDataProvider.waitForReadRequest(); |
| 139 mHandler.checkReadCallbackNotInvoked(); |
| 140 mHandler.resetWaitForReadComplete(); |
| 141 mDataProvider.onReadSucceeded(mUploadDataStream); |
| 142 mHandler.waitForReadComplete(); |
| 143 mDataProvider.assertReadNotPending(); |
| 144 assertEquals(1, mDataProvider.getNumRewindCalls()); |
| 145 assertEquals(2, mDataProvider.getNumReadCalls()); |
| 146 assertEquals("hello", mHandler.getData()); |
| 147 } |
| 148 |
| 149 /** |
| 150 * Tests that if init before read completes, a rewind is triggered when |
| 151 * read completes. |
| 152 */ |
| 153 @SmallTest |
| 154 @Feature({"Cronet"}) |
| 155 public void testReadCompleteTriggerRewind() throws Exception { |
| 156 // Reset and init before read completes. |
| 157 assertTrue(mHandler.init()); |
| 158 mHandler.read(); |
| 159 mDataProvider.waitForReadRequest(); |
| 160 mHandler.checkReadCallbackNotInvoked(); |
| 161 mHandler.reset(); |
| 162 // Init should return asynchronously, since there is a pending read. |
| 163 assertFalse(mHandler.init()); |
| 164 mDataProvider.assertRewindNotPending(); |
| 165 mHandler.checkInitCallbackNotInvoked(); |
| 166 assertEquals(0, mDataProvider.getNumRewindCalls()); |
| 167 assertEquals(1, mDataProvider.getNumReadCalls()); |
| 168 assertEquals("", mHandler.getData()); |
| 169 |
| 170 // Read completes should trigger a rewind. |
| 171 mDataProvider.onReadSucceeded(mUploadDataStream); |
| 172 mDataProvider.waitForRewindRequest(); |
| 173 mHandler.resetWaitForInitComplete(); |
| 174 mDataProvider.onRewindSucceeded(mUploadDataStream); |
| 175 mHandler.waitForInitComplete(); |
| 176 mDataProvider.assertRewindNotPending(); |
| 177 assertEquals(1, mDataProvider.getNumRewindCalls()); |
| 178 assertEquals(1, mDataProvider.getNumReadCalls()); |
| 179 assertEquals("", mHandler.getData()); |
| 180 } |
| 181 |
| 182 /** |
| 183 * Tests that when init again after rewind completes, no additional rewind |
| 184 * is triggered. This test is the same as testReadCompleteTriggerRewind |
| 185 * except that this test invokes reset and init again in the end. |
| 186 */ |
| 187 @SmallTest |
| 188 @Feature({"Cronet"}) |
| 189 public void testReadCompleteTriggerRewindOnlyOneRewind() throws Exception { |
| 190 testReadCompleteTriggerRewind(); |
| 191 // Reset and Init again, no rewind should happen. |
| 192 mHandler.reset(); |
| 193 assertTrue(mHandler.init()); |
| 194 mDataProvider.assertRewindNotPending(); |
| 195 assertEquals(1, mDataProvider.getNumRewindCalls()); |
| 196 assertEquals(1, mDataProvider.getNumReadCalls()); |
| 197 assertEquals("", mHandler.getData()); |
| 198 } |
| 199 |
| 200 /** |
| 201 * Tests that if reset before read completes, no rewind is triggered, and |
| 202 * that a following init triggers rewind. |
| 203 */ |
| 204 @SmallTest |
| 205 @Feature({"Cronet"}) |
| 206 public void testResetBeforeReadCompleteAndInitTriggerRewind() |
| 207 throws Exception { |
| 208 // Reset before read completes. Rewind is not triggered. |
| 209 assertTrue(mHandler.init()); |
| 210 mHandler.read(); |
| 211 mDataProvider.waitForReadRequest(); |
| 212 mHandler.checkReadCallbackNotInvoked(); |
| 213 mHandler.reset(); |
| 214 mDataProvider.onReadSucceeded(mUploadDataStream); |
| 215 mDataProvider.assertRewindNotPending(); |
| 216 assertEquals(0, mDataProvider.getNumRewindCalls()); |
| 217 assertEquals(1, mDataProvider.getNumReadCalls()); |
| 218 assertEquals("", mHandler.getData()); |
| 219 |
| 220 // Init should trigger a rewind. |
| 221 assertFalse(mHandler.init()); |
| 222 mDataProvider.waitForRewindRequest(); |
| 223 mHandler.checkInitCallbackNotInvoked(); |
| 224 mHandler.resetWaitForInitComplete(); |
| 225 mDataProvider.onRewindSucceeded(mUploadDataStream); |
| 226 mHandler.waitForInitComplete(); |
| 227 mDataProvider.assertRewindNotPending(); |
| 228 assertEquals(1, mDataProvider.getNumRewindCalls()); |
| 229 assertEquals(1, mDataProvider.getNumReadCalls()); |
| 230 assertEquals("", mHandler.getData()); |
| 231 } |
| 232 |
| 233 /** |
| 234 * Tests that there is no crash when native CronetUploadDataStreamAdapter is |
| 235 * destroyed while read is pending. The test is racy since read could |
| 236 * complete either before or after onDestroyAdapter() is called in |
| 237 * CronetUploadDataStream. However, the test should pass either way, though |
| 238 * we are interested in the latter case. |
| 239 */ |
| 240 @SmallTest |
| 241 @Feature({"Cronet"}) |
| 242 public void testDestroyAdapterBeforeReadComplete() |
| 243 throws Exception { |
| 244 // Start a read and wait for it to be pending. |
| 245 assertTrue(mHandler.init()); |
| 246 mHandler.read(); |
| 247 mDataProvider.waitForReadRequest(); |
| 248 mHandler.checkReadCallbackNotInvoked(); |
| 249 |
| 250 // Destroy the C++ object, which should trigger the Java |
| 251 // onAdapterDestroyed() which should block until the read completes. |
| 252 mAdapter = 0; |
| 253 |
| 254 // Make the read complete should not encounter a crash. |
| 255 mDataProvider.onReadSucceeded(mUploadDataStream); |
| 256 |
| 257 assertEquals(0, mDataProvider.getNumRewindCalls()); |
| 258 assertEquals(1, mDataProvider.getNumReadCalls()); |
| 259 } |
| 260 |
| 261 /** |
| 262 * Tests that there is no crash when native CronetUploadDataStreamAdapter is |
| 263 * destroyed while rewind is pending. The test is racy since rewind could |
| 264 * complete either before or after onDestroyAdapter() is called in |
| 265 * CronetUploadDataStream. However, the test should pass either way, though |
| 266 * we are interested in the latter case. |
| 267 */ |
| 268 @SmallTest |
| 269 @Feature({"Cronet"}) |
| 270 public void testDestroyAdapterBeforeRewindComplete() |
| 271 throws Exception { |
| 272 // Start a read and wait for it to complete. |
| 273 assertTrue(mHandler.init()); |
| 274 mHandler.read(); |
| 275 mDataProvider.waitForReadRequest(); |
| 276 mHandler.checkReadCallbackNotInvoked(); |
| 277 mDataProvider.onReadSucceeded(mUploadDataStream); |
| 278 mHandler.waitForReadComplete(); |
| 279 mDataProvider.assertReadNotPending(); |
| 280 assertEquals(0, mDataProvider.getNumRewindCalls()); |
| 281 assertEquals(1, mDataProvider.getNumReadCalls()); |
| 282 assertEquals("hello", mHandler.getData()); |
| 283 |
| 284 // Reset and then init, which should trigger a rewind. |
| 285 mHandler.reset(); |
| 286 assertEquals("", mHandler.getData()); |
| 287 assertFalse(mHandler.init()); |
| 288 mDataProvider.waitForRewindRequest(); |
| 289 mHandler.checkInitCallbackNotInvoked(); |
| 290 |
| 291 // Destroy the C++ object, which should trigger the Java |
| 292 // onAdapterDestroyed(). |
| 293 mAdapter = 0; |
| 294 |
| 295 // Signal rewind completes, and wait for init to complete. |
| 296 mHandler.resetWaitForInitComplete(); |
| 297 mDataProvider.onRewindSucceeded(mUploadDataStream); |
| 298 mHandler.waitForInitComplete(); |
| 299 mDataProvider.assertRewindNotPending(); |
| 300 |
| 301 assertEquals(1, mDataProvider.getNumRewindCalls()); |
| 302 assertEquals(1, mDataProvider.getNumReadCalls()); |
| 303 } |
| 304 } |
| OLD | NEW |