Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: components/cronet/android/test/javatests/src/org/chromium/net/TestDrivenDataProvider.java

Issue 849903002: [Cronet] Upload support for async APIs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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.os.ConditionVariable;
8
9 import java.nio.ByteBuffer;
10 import java.util.List;
11 import java.util.concurrent.Executor;
12
13 /**
14 * An UploadDataProvider that allows tests to invoke {@code onReadSucceeded}
15 * and {@code onRewindSucceeded} on the UploadDataSink directly.
16 * Chunked mode is not supported here, since the main interest is to test
17 * different order of init/read/rewind calls.
18 */
19 class TestDrivenDataProvider implements UploadDataProvider {
20 private final Executor mExecutor;
21 private final List<byte[]> mReads;
22 private final ConditionVariable mWaitForReadRequest =
23 new ConditionVariable();
24 private final ConditionVariable mWaitForRewindRequest =
25 new ConditionVariable();
26 // Lock used to synchronize access to mReadPending and mRewindPending.
27 private final Object mLock = new Object();
28
29 private int mNextRead = 0;
30
31 // Only accessible when holding mLock.
32
33 private boolean mReadPending = false;
34 private boolean mRewindPending = false;
35 private int mNumRewindCalls = 0;
36 private int mNumReadCalls = 0;
37
38 /**
39 * Constructor.
40 * @param Executor executor. Executor to run callbacks of UploadDataSink.
41 * @param List<byte[]> reads. Results to be returned by successful read
42 * requests. Returned bytes must all fit within the read buffer
43 * provided by Cronet. After a rewind, if there is one, all reads
44 * will be repeated.
45 */
46 TestDrivenDataProvider(Executor executor, List<byte[]> reads) {
47 mExecutor = executor;
48 mReads = reads;
49 }
50
51 @Override
52 // Called by UploadDataSink on the main thread.
53 public long getLength() {
54 long length = 0;
55 for (byte[] read : mReads) {
56 length += read.length;
57 }
58 return length;
59 }
60
61 @Override
62 // Called by UploadDataSink on the executor thread.
63 public void read(final UploadDataSink uploadDataSink,
64 final ByteBuffer byteBuffer) {
65 synchronized (mLock) {
66 ++mNumReadCalls;
67 assertIdle();
68
69 mReadPending = true;
70 if (mNextRead != mReads.size()) {
71 if ((byteBuffer.limit() - byteBuffer.position())
72 < mReads.get(mNextRead).length) {
73 throw new IllegalStateException("Read buffer smaller than ex pected.");
74 }
75 byteBuffer.put(mReads.get(mNextRead));
76 ++mNextRead;
77 } else {
78 throw new IllegalStateException("Too many reads: " + mNextRead);
79 }
80 mWaitForReadRequest.open();
81 }
82 }
83
84 @Override
85 // Called by UploadDataSink on the executor thread.
86 public void rewind(final UploadDataSink uploadDataSink) {
87 synchronized (mLock) {
88 ++mNumRewindCalls;
89 assertIdle();
90
91 if (mNextRead == 0) {
92 // Should never try and rewind when rewinding does nothing.
93 throw new IllegalStateException(
94 "Unexpected rewind when already at beginning");
95 }
96 mRewindPending = true;
97 mNextRead = 0;
98 mWaitForRewindRequest.open();
99 }
100 }
101
102 // Called by test fixture on the main thread.
103 public void onReadSucceeded(final UploadDataSink uploadDataSink) {
104 Runnable completeRunnable = new Runnable() {
105 @Override
106 public void run() {
107 synchronized (mLock) {
108 if (!mReadPending) {
109 throw new IllegalStateException("No read pending.");
110 }
111 mReadPending = false;
112 uploadDataSink.onReadSucceeded(false);
113 }
114 }
115 };
116 mExecutor.execute(completeRunnable);
117 }
118
119
120 // Called by test fixture on the main thread.
121 public void onRewindSucceeded(final UploadDataSink uploadDataSink) {
122 Runnable completeRunnable = new Runnable() {
123 @Override
124 public void run() {
125 synchronized (mLock) {
126 if (!mRewindPending) {
127 throw new IllegalStateException("No rewind pending.");
128 }
129 mRewindPending = false;
130 uploadDataSink.onRewindSucceeded();
131 }
132 }
133 };
134 mExecutor.execute(completeRunnable);
135 }
136
137 // Called by test fixture on the main thread.
138 public int getNumReadCalls() {
139 synchronized (mLock) {
140 return mNumReadCalls;
141 }
142 }
143
144 // Called by test fixture on the main thread.
145 public int getNumRewindCalls() {
146 synchronized (mLock) {
147 return mNumRewindCalls;
148 }
149 }
150
151 // Called by test fixture on the main thread.
152 public void waitForReadRequest() {
153 mWaitForReadRequest.block();
154 }
155
156 // Called by test fixture on the main thread.
157 public void resetWaitForReadRequest() {
158 mWaitForReadRequest.close();
159 }
160
161 // Called by test fixture on the main thread.
162 public void waitForRewindRequest() {
163 mWaitForRewindRequest.block();
164 }
165
166 // Called by test fixture on the main thread.
167 public void assertReadNotPending() {
168 synchronized (mLock) {
169 if (mReadPending) {
170 throw new IllegalStateException("Read is pending.");
171 }
172 }
173 }
174
175 // Called by test fixture on the main thread.
176 public void assertRewindNotPending() {
177 synchronized (mLock) {
178 if (mRewindPending) {
179 throw new IllegalStateException("Rewind is pending.");
180 }
181 }
182 }
183
184 /**
185 * Helper method to ensure no read or rewind is in progress.
186 */
187 private void assertIdle() {
188 assertReadNotPending();
189 assertRewindNotPending();
190 }
191 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698