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

Side by Side Diff: chrome/android/javatests/src/org/chromium/chrome/browser/omaha/OmahaClientTest.java

Issue 2664253005: [Omaha] Move most functionality to OmahaBase, add JobService (Closed)
Patch Set: [Omaha] Move most functionality to OmahaBase, add JobService Created 3 years, 9 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.chrome.browser.omaha;
6
7 import android.app.Service;
8 import android.content.Context;
9 import android.content.SharedPreferences;
10 import android.support.test.filters.SmallTest;
11 import android.test.InstrumentationTestCase;
12
13 import org.chromium.base.test.util.AdvancedMockContext;
14 import org.chromium.base.test.util.Feature;
15 import org.chromium.chrome.test.omaha.MockRequestGenerator;
16 import org.chromium.chrome.test.omaha.MockRequestGenerator.DeviceType;
17
18 import java.io.ByteArrayInputStream;
19 import java.io.ByteArrayOutputStream;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.OutputStream;
23 import java.net.HttpURLConnection;
24 import java.net.MalformedURLException;
25 import java.net.SocketTimeoutException;
26 import java.net.URL;
27 import java.util.ArrayList;
28 import java.util.LinkedList;
29 import java.util.List;
30
31 /**
32 * Tests for the {@link OmahaClient}.
33 * Tests override the original OmahaClient's functions with the MockOmahaClient, which
34 * provides a way to hook into functions to return values that would normally be provided by the
35 * system, such as whether Chrome was installed through the system image.
36 */
37 public class OmahaClientTest extends InstrumentationTestCase {
38 private static class TimestampPair {
39 public long timestampNextRequest;
40 public long timestampNextPost;
41
42 public TimestampPair(long timestampNextRequest, long timestampNextPost) {
43 this.timestampNextRequest = timestampNextRequest;
44 this.timestampNextPost = timestampNextPost;
45 }
46 }
47
48 private static class MockOmahaDelegate extends OmahaDelegate {
49 private final List<Integer> mPostResults = new ArrayList<Integer>();
50 private final List<Boolean> mGenerateAndPostRequestResults = new ArrayLi st<Boolean>();
51
52 private final boolean mIsOnTablet;
53 private final boolean mIsInForeground;
54 private final boolean mIsInSystemImage;
55 private final MockExponentialBackoffScheduler mMockScheduler;
56 private MockRequestGenerator mMockGenerator;
57
58 private int mNumUUIDsGenerated;
59 private long mNextScheduledTimestamp = -1;
60
61 private boolean mInstallEventWasSent;
62 private TimestampPair mTimestampsOnRegisterNewRequest;
63 private TimestampPair mTimestampsOnSaveState;
64
65 MockOmahaDelegate(Context context, DeviceType deviceType, InstallSource installSource) {
66 super(context);
67 mIsOnTablet = deviceType == DeviceType.TABLET;
68 mIsInForeground = true;
69 mIsInSystemImage = installSource == InstallSource.SYSTEM_IMAGE;
70
71 mMockScheduler = new MockExponentialBackoffScheduler(OmahaBase.PREF_ PACKAGE, context,
72 OmahaClient.MS_POST_BASE_DELAY, OmahaClient.MS_POST_MAX_DELA Y);
73 }
74
75 @Override
76 protected RequestGenerator createRequestGenerator(Context context) {
77 mMockGenerator = new MockRequestGenerator(
78 context, mIsOnTablet ? DeviceType.TABLET : DeviceType.HANDSE T);
79 return mMockGenerator;
80 }
81
82 @Override
83 public boolean isInSystemImage() {
84 return mIsInSystemImage;
85 }
86
87 @Override
88 MockExponentialBackoffScheduler getScheduler() {
89 return mMockScheduler;
90 }
91
92 @Override
93 protected String generateUUID() {
94 mNumUUIDsGenerated += 1;
95 return "UUID" + mNumUUIDsGenerated;
96 }
97
98 @Override
99 protected boolean isChromeBeingUsed() {
100 return mIsInForeground;
101 }
102
103 @Override
104 void scheduleService(Service service, long nextTimestamp) {
105 mNextScheduledTimestamp = nextTimestamp;
106 }
107
108 @Override
109 void onHandlePostRequestDone(int result, boolean installEventWasSent) {
110 mPostResults.add(result);
111 mInstallEventWasSent = installEventWasSent;
112 }
113
114 @Override
115 void onRegisterNewRequestDone(long nextRequestTimestamp, long nextPostTi mestamp) {
116 mTimestampsOnRegisterNewRequest =
117 new TimestampPair(nextRequestTimestamp, nextPostTimestamp);
118 }
119
120 @Override
121 void onGenerateAndPostRequestDone(boolean result) {
122 mGenerateAndPostRequestResults.add(result);
123 }
124
125 @Override
126 void onSaveStateDone(long nextRequestTimestamp, long nextPostTimestamp) {
127 mTimestampsOnSaveState = new TimestampPair(nextRequestTimestamp, nex tPostTimestamp);
128 }
129 }
130
131 private enum InstallSource { SYSTEM_IMAGE, ORGANIC }
132 private enum ServerResponse { SUCCESS, FAILURE }
133 private enum ConnectionStatus { RESPONDS, TIMES_OUT }
134 private enum InstallEvent { SEND, DONT_SEND }
135 private enum PostStatus { DUE, NOT_DUE }
136
137 private AdvancedMockContext mContext;
138 private MockOmahaDelegate mDelegate;
139 private MockOmahaClient mOmahaClient;
140
141 private MockOmahaClient createOmahaClient() {
142 return createOmahaClient(
143 ServerResponse.SUCCESS, ConnectionStatus.RESPONDS, DeviceType.HA NDSET);
144 }
145
146 private MockOmahaClient createOmahaClient(
147 ServerResponse response, ConnectionStatus status, DeviceType deviceT ype) {
148 MockOmahaClient omahaClient = new MockOmahaClient(mContext, response, st atus, deviceType);
149 omahaClient.onCreate();
150 omahaClient.restoreState(mContext);
151 return omahaClient;
152 }
153
154 @Override
155 protected void setUp() throws Exception {
156 super.setUp();
157 Context targetContext = getInstrumentation().getTargetContext();
158 OmahaBase.setIsDisabledForTesting(false);
159 mContext = new AdvancedMockContext(targetContext);
160 }
161
162 @Override
163 public void tearDown() throws Exception {
164 OmahaBase.setIsDisabledForTesting(true);
165 super.tearDown();
166 }
167
168 private class MockOmahaClient extends OmahaClient {
169 private final LinkedList<MockConnection> mMockConnections = new LinkedLi st<>();
170
171 private final boolean mSendValidResponse;
172 private final boolean mConnectionTimesOut;
173 private final boolean mIsOnTablet;
174
175 public MockOmahaClient(Context context, ServerResponse serverResponse,
176 ConnectionStatus connectionStatus, DeviceType deviceType) {
177 attachBaseContext(context);
178 setDelegateForTests(mDelegate);
179
180 mSendValidResponse = serverResponse == ServerResponse.SUCCESS;
181 mConnectionTimesOut = connectionStatus == ConnectionStatus.TIMES_OUT ;
182 mIsOnTablet = deviceType == DeviceType.TABLET;
183 }
184
185 /**
186 * Gets the number of MockConnections created.
187 */
188 public int getNumConnectionsMade() {
189 return mMockConnections.size();
190 }
191
192 /**
193 * Returns a particular connection.
194 */
195 public MockConnection getConnection(int index) {
196 return mMockConnections.get(index);
197 }
198
199 /**
200 * Returns the last MockPingConection used to simulate communication wit h the server.
201 */
202 public MockConnection getLastConnection() {
203 return mMockConnections.getLast();
204 }
205
206 public boolean isSendInstallEvent() {
207 return mSendInstallEvent;
208 }
209
210 public void setSendInstallEvent(boolean state) {
211 mSendInstallEvent = state;
212 }
213
214 @Override
215 protected HttpURLConnection createConnection() throws RequestFailureExce ption {
216 MockConnection connection = null;
217 try {
218 URL url = new URL(mDelegate.getRequestGenerator().getServerUrl() );
219 connection = new MockConnection(url, mIsOnTablet, mSendValidResp onse,
220 mSendInstallEvent, mConnectionTimesOut);
221 mMockConnections.addLast(connection);
222 } catch (MalformedURLException e) {
223 fail("Caught a malformed URL exception: " + e);
224 }
225 return connection;
226 }
227 }
228
229 @SmallTest
230 @Feature({"Omaha"})
231 public void testPipelineFreshInstall() {
232 final long now = 11684;
233
234 mDelegate = new MockOmahaDelegate(mContext, DeviceType.HANDSET, InstallS ource.ORGANIC);
235 mDelegate.getScheduler().setCurrentTime(now);
236
237 // Trigger Omaha.
238 mOmahaClient = createOmahaClient();
239 mOmahaClient.run();
240
241 // A fresh install results in two requests to the Omaha server: one for the install request
242 // and one for the ping request.
243 assertTrue(mDelegate.mInstallEventWasSent);
244 assertEquals(1, mDelegate.mPostResults.size());
245 assertEquals(OmahaClient.POST_RESULT_SENT, mDelegate.mPostResults.get(0) .intValue());
246 assertEquals(2, mDelegate.mGenerateAndPostRequestResults.size());
247 assertTrue(mDelegate.mGenerateAndPostRequestResults.get(0));
248 assertTrue(mDelegate.mGenerateAndPostRequestResults.get(1));
249
250 // Successful requests mean that the next scheduled event should be chec king for when the
251 // user is active.
252 assertEquals(now + OmahaClient.MS_BETWEEN_REQUESTS, mDelegate.mNextSched uledTimestamp);
253 checkTimestamps(now + OmahaClient.MS_BETWEEN_REQUESTS, now + OmahaClient .MS_POST_BASE_DELAY,
254 mDelegate.mTimestampsOnSaveState);
255 }
256
257 @SmallTest
258 @Feature({"Omaha"})
259 public void testPipelineRegularPing() {
260 final long now = 11684;
261
262 mDelegate = new MockOmahaDelegate(mContext, DeviceType.HANDSET, InstallS ource.ORGANIC);
263 mDelegate.getScheduler().setCurrentTime(now);
264
265 // Record that an install event has already been sent and that we're due for a new request.
266 SharedPreferences.Editor editor = OmahaBase.getSharedPreferences(mContex t).edit();
267 editor.putBoolean(OmahaBase.PREF_SEND_INSTALL_EVENT, false);
268 editor.putLong(OmahaBase.PREF_TIMESTAMP_FOR_NEW_REQUEST, now);
269 editor.putLong(OmahaBase.PREF_TIMESTAMP_FOR_NEXT_POST_ATTEMPT, now);
270 editor.apply();
271
272 // Trigger Omaha.
273 mOmahaClient = createOmahaClient();
274 mOmahaClient.run();
275
276 // Only the regular ping should have been sent.
277 assertFalse(mDelegate.mInstallEventWasSent);
278 assertEquals(1, mDelegate.mPostResults.size());
279 assertEquals(OmahaClient.POST_RESULT_SENT, mDelegate.mPostResults.get(0) .intValue());
280 assertEquals(1, mDelegate.mGenerateAndPostRequestResults.size());
281 assertTrue(mDelegate.mGenerateAndPostRequestResults.get(0));
282
283 // Successful requests mean that the next scheduled event should be chec king for when the
284 // user is active.
285 assertEquals(now + OmahaClient.MS_BETWEEN_REQUESTS, mDelegate.mNextSched uledTimestamp);
286 checkTimestamps(now + OmahaClient.MS_BETWEEN_REQUESTS, now + OmahaClient .MS_POST_BASE_DELAY,
287 mDelegate.mTimestampsOnSaveState);
288 }
289
290 @SmallTest
291 @Feature({"Omaha"})
292 public void testTooEarlyToPing() {
293 final long now = 0;
294 final long later = 10000;
295
296 mDelegate = new MockOmahaDelegate(mContext, DeviceType.HANDSET, InstallS ource.ORGANIC);
297 mDelegate.getScheduler().setCurrentTime(now);
298
299 // Put the time for the next request in the future.
300 SharedPreferences prefs = OmahaBase.getSharedPreferences(mContext);
301 prefs.edit().putLong(OmahaBase.PREF_TIMESTAMP_FOR_NEW_REQUEST, later).ap ply();
302
303 // Trigger Omaha.
304 mOmahaClient = createOmahaClient();
305 mOmahaClient.run();
306
307 // Nothing should have been POSTed.
308 assertEquals(0, mDelegate.mPostResults.size());
309 assertEquals(0, mDelegate.mGenerateAndPostRequestResults.size());
310
311 // The next scheduled event is the request generation. Because there wa s nothing to POST,
312 // its timestamp should have remained unchanged and shouldn't have been considered when the
313 // new alarm was scheduled.
314 assertEquals(later, mDelegate.mNextScheduledTimestamp);
315 checkTimestamps(later, now, mDelegate.mTimestampsOnSaveState);
316 }
317
318 @SmallTest
319 @Feature({"Omaha"})
320 public void testTooEarlyToPostExistingRequest() {
321 final long timeGeneratedRequest = 0L;
322 final long now = 10000L;
323 final long timeSendNewPost = 20000L;
324 final long timeSendNewRequest = 50000L;
325
326 mDelegate = new MockOmahaDelegate(mContext, DeviceType.HANDSET, InstallS ource.ORGANIC);
327 mDelegate.getScheduler().setCurrentTime(now);
328
329 SharedPreferences prefs = OmahaBase.getSharedPreferences(mContext);
330 SharedPreferences.Editor editor = prefs.edit();
331
332 // Make it so that a request was generated and is just waiting to be sen t.
333 editor.putLong(OmahaBase.PREF_TIMESTAMP_FOR_NEW_REQUEST, timeSendNewRequ est);
334 editor.putLong(OmahaBase.PREF_TIMESTAMP_OF_REQUEST, timeGeneratedRequest );
335 editor.putString(OmahaBase.PREF_PERSISTED_REQUEST_ID, "persisted_id");
336
337 // Put the time for the next post in the future.
338 editor.putLong(OmahaBase.PREF_TIMESTAMP_FOR_NEXT_POST_ATTEMPT, timeSendN ewPost);
339 editor.apply();
340
341 // Trigger Omaha.
342 mOmahaClient = createOmahaClient();
343 mOmahaClient.run();
344
345 // Request generation code should be skipped.
346 assertNull(mDelegate.mTimestampsOnRegisterNewRequest);
347
348 // Should be too early to post, causing it to be rescheduled.
349 assertEquals(1, mDelegate.mPostResults.size());
350 assertEquals(OmahaClient.POST_RESULT_SCHEDULED, mDelegate.mPostResults.g et(0).intValue());
351 assertEquals(0, mDelegate.mGenerateAndPostRequestResults.size());
352
353 // The next scheduled event is the POST. Because request generation cod e wasn't run, the
354 // timestamp for it shouldn't have changed.
355 assertEquals(timeSendNewPost, mDelegate.mNextScheduledTimestamp);
356 checkTimestamps(timeSendNewRequest, timeSendNewPost, mDelegate.mTimestam psOnSaveState);
357 }
358
359 @SmallTest
360 @Feature({"Omaha"})
361 public void testPostExistingRequestSuccessfully() {
362 final long timeGeneratedRequest = 0L;
363 final long now = 10000L;
364 final long timeSendNewPost = now;
365 final long timeRegisterNewRequest = 20000L;
366
367 mDelegate = new MockOmahaDelegate(mContext, DeviceType.HANDSET, InstallS ource.ORGANIC);
368 mDelegate.getScheduler().setCurrentTime(now);
369
370 SharedPreferences prefs = OmahaBase.getSharedPreferences(mContext);
371 SharedPreferences.Editor editor = prefs.edit();
372
373 // Make it so that a regular <ping> was generated and is just waiting to be sent.
374 editor.putBoolean(OmahaBase.PREF_SEND_INSTALL_EVENT, false);
375 editor.putLong(OmahaBase.PREF_TIMESTAMP_FOR_NEW_REQUEST, timeRegisterNew Request);
376 editor.putLong(OmahaBase.PREF_TIMESTAMP_OF_REQUEST, timeGeneratedRequest );
377 editor.putString(OmahaBase.PREF_PERSISTED_REQUEST_ID, "persisted_id");
378
379 // Send the POST now.
380 editor.putLong(OmahaBase.PREF_TIMESTAMP_FOR_NEXT_POST_ATTEMPT, timeSendN ewPost);
381 editor.apply();
382
383 // Trigger Omaha.
384 mOmahaClient = createOmahaClient();
385 mOmahaClient.run();
386
387 // Registering code shouldn't have fired.
388 assertNull(mDelegate.mTimestampsOnRegisterNewRequest);
389
390 // Because we didn't send an install event, only one POST should have oc curred.
391 assertEquals(1, mDelegate.mPostResults.size());
392 assertEquals(OmahaClient.POST_RESULT_SENT, mDelegate.mPostResults.get(0) .intValue());
393 assertEquals(1, mDelegate.mGenerateAndPostRequestResults.size());
394 assertTrue(mDelegate.mGenerateAndPostRequestResults.get(0));
395
396 // The next scheduled event is the request generation because there is n othing to POST.
397 // A successful POST adjusts all timestamps for the current time.
398 assertEquals(timeRegisterNewRequest, mDelegate.mNextScheduledTimestamp);
399 checkTimestamps(now + OmahaClient.MS_BETWEEN_REQUESTS, now + OmahaClient .MS_POST_BASE_DELAY,
400 mDelegate.mTimestampsOnSaveState);
401 }
402
403 @SmallTest
404 @Feature({"Omaha"})
405 public void testPostExistingButFails() {
406 final long timeGeneratedRequest = 0L;
407 final long now = 10000L;
408 final long timeSendNewPost = now;
409 final long timeRegisterNewRequest = timeGeneratedRequest + OmahaClient.M S_BETWEEN_REQUESTS;
410
411 mDelegate = new MockOmahaDelegate(mContext, DeviceType.HANDSET, InstallS ource.ORGANIC);
412 mDelegate.getScheduler().setCurrentTime(now);
413
414 SharedPreferences prefs = OmahaBase.getSharedPreferences(mContext);
415 SharedPreferences.Editor editor = prefs.edit();
416
417 // Make it so that a regular <ping> was generated and is just waiting to be sent.
418 editor.putBoolean(OmahaBase.PREF_SEND_INSTALL_EVENT, false);
419 editor.putLong(OmahaBase.PREF_TIMESTAMP_FOR_NEW_REQUEST, timeRegisterNew Request);
420 editor.putLong(OmahaBase.PREF_TIMESTAMP_OF_REQUEST, timeGeneratedRequest );
421 editor.putString(OmahaBase.PREF_PERSISTED_REQUEST_ID, "persisted_id");
422
423 // Send the POST now.
424 editor.putLong(OmahaBase.PREF_TIMESTAMP_FOR_NEXT_POST_ATTEMPT, timeSendN ewPost);
425 editor.apply();
426
427 // Trigger Omaha.
428 mOmahaClient = createOmahaClient(
429 ServerResponse.FAILURE, ConnectionStatus.RESPONDS, DeviceType.HA NDSET);
430 mOmahaClient.run();
431
432 // Registering code shouldn't have fired.
433 assertNull(mDelegate.mTimestampsOnRegisterNewRequest);
434
435 // Because we didn't send an install event, only one POST should have oc curred.
436 assertEquals(1, mDelegate.mPostResults.size());
437 assertEquals(OmahaClient.POST_RESULT_FAILED, mDelegate.mPostResults.get( 0).intValue());
438 assertEquals(1, mDelegate.mGenerateAndPostRequestResults.size());
439 assertFalse(mDelegate.mGenerateAndPostRequestResults.get(0));
440
441 // The next scheduled event should be the POST event, which is delayed b y the base delay
442 // because no failures have happened yet.
443 assertEquals(mDelegate.mTimestampsOnSaveState.timestampNextPost,
444 mDelegate.mNextScheduledTimestamp);
445 checkTimestamps(timeRegisterNewRequest, now + OmahaClient.MS_POST_BASE_D ELAY,
446 mDelegate.mTimestampsOnSaveState);
447 }
448
449 @SmallTest
450 @Feature({"Omaha"})
451 public void testTimestampWithinBounds() {
452 final long now = 0L;
453 final long timeRegisterNewRequest = OmahaClient.MS_BETWEEN_REQUESTS + 1;
454
455 mDelegate = new MockOmahaDelegate(mContext, DeviceType.HANDSET, InstallS ource.ORGANIC);
456 mDelegate.getScheduler().setCurrentTime(now);
457
458 SharedPreferences prefs = OmahaBase.getSharedPreferences(mContext);
459 SharedPreferences.Editor editor = prefs.edit();
460
461 // Indicate that the next request should be generated way past an expect ed timeframe.
462 editor.putBoolean(OmahaBase.PREF_SEND_INSTALL_EVENT, false);
463 editor.putLong(OmahaBase.PREF_TIMESTAMP_FOR_NEW_REQUEST, timeRegisterNew Request);
464 editor.apply();
465
466 // Trigger Omaha.
467 mOmahaClient = createOmahaClient();
468 mOmahaClient.run();
469
470 // Request generation code should fire.
471 assertNotNull(mDelegate.mTimestampsOnRegisterNewRequest);
472
473 // Because we didn't send an install event, only one POST should have oc curred.
474 assertEquals(1, mDelegate.mPostResults.size());
475 assertEquals(OmahaClient.POST_RESULT_SENT, mDelegate.mPostResults.get(0) .intValue());
476 assertEquals(1, mDelegate.mGenerateAndPostRequestResults.size());
477 assertTrue(mDelegate.mGenerateAndPostRequestResults.get(0));
478
479 // The next scheduled event should be the timestamp for a new request ge neration.
480 assertEquals(mDelegate.mTimestampsOnSaveState.timestampNextRequest,
481 mDelegate.mNextScheduledTimestamp);
482 checkTimestamps(now + OmahaClient.MS_BETWEEN_REQUESTS, now + OmahaClient .MS_POST_BASE_DELAY,
483 mDelegate.mTimestampsOnSaveState);
484 }
485
486 @SmallTest
487 @Feature({"Omaha"})
488 public void testOverdueRequestCausesNewRegistration() {
489 final long timeGeneratedRequest = 0L;
490 final long now = 10000L;
491 final long timeSendNewPost = now;
492 final long timeRegisterNewRequest =
493 timeGeneratedRequest + OmahaClient.MS_BETWEEN_REQUESTS * 5;
494
495 mDelegate = new MockOmahaDelegate(mContext, DeviceType.HANDSET, InstallS ource.ORGANIC);
496 mDelegate.getScheduler().setCurrentTime(now);
497
498 // Record that a regular <ping> was generated, but not sent, then assign it an invalid
499 // timestamp and try to send it now.
500 SharedPreferences prefs = OmahaBase.getSharedPreferences(mContext);
501 SharedPreferences.Editor editor = prefs.edit();
502 editor.putBoolean(OmahaBase.PREF_SEND_INSTALL_EVENT, false);
503 editor.putLong(OmahaBase.PREF_TIMESTAMP_FOR_NEW_REQUEST, timeRegisterNew Request);
504 editor.putLong(OmahaBase.PREF_TIMESTAMP_OF_REQUEST, timeGeneratedRequest );
505 editor.putString(OmahaBase.PREF_PERSISTED_REQUEST_ID, "persisted_id");
506 editor.putLong(OmahaBase.PREF_TIMESTAMP_FOR_NEXT_POST_ATTEMPT, timeSendN ewPost);
507 editor.apply();
508
509 // Trigger Omaha.
510 mOmahaClient = createOmahaClient();
511 mOmahaClient.run();
512
513 // Registering code shouldn't have fired.
514 checkTimestamps(now + OmahaClient.MS_BETWEEN_REQUESTS, now,
515 mDelegate.mTimestampsOnRegisterNewRequest);
516
517 // Because we didn't send an install event, only one POST should have oc curred.
518 assertEquals(1, mDelegate.mPostResults.size());
519 assertEquals(OmahaClient.POST_RESULT_SENT, mDelegate.mPostResults.get(0) .intValue());
520 assertEquals(1, mDelegate.mGenerateAndPostRequestResults.size());
521 assertTrue(mDelegate.mGenerateAndPostRequestResults.get(0));
522
523 // The next scheduled event should be the registration event.
524 assertEquals(mDelegate.mTimestampsOnSaveState.timestampNextRequest,
525 mDelegate.mNextScheduledTimestamp);
526 checkTimestamps(now + OmahaClient.MS_BETWEEN_REQUESTS, now + OmahaClient .MS_POST_BASE_DELAY,
527 mDelegate.mTimestampsOnSaveState);
528 }
529
530 private void checkTimestamps(
531 long expectedRequestTimestamp, long expectedPostTimestamp, Timestamp Pair timestamps) {
532 assertEquals(expectedRequestTimestamp, timestamps.timestampNextRequest);
533 assertEquals(expectedPostTimestamp, timestamps.timestampNextPost);
534 }
535
536 /**
537 * Simulates communication with the actual Omaha server.
538 */
539 private static class MockConnection extends HttpURLConnection {
540 // Omaha appends a "/" to the URL.
541 private static final String STRIPPED_MARKET_URL =
542 "https://market.android.com/details?id=com.google.android.apps.c hrome";
543 private static final String MARKET_URL = STRIPPED_MARKET_URL + "/";
544
545 private static final String UPDATE_VERSION = "1.2.3.4";
546
547 // Parameters.
548 private final boolean mConnectionTimesOut;
549 private final ByteArrayInputStream mServerResponse;
550 private final ByteArrayOutputStream mOutputStream;
551 private final int mHTTPResponseCode;
552
553 // Result variables.
554 private int mContentLength;
555 private int mNumTimesResponseCodeRetrieved;
556 private boolean mSentRequest;
557 private boolean mGotInputStream;
558 private String mRequestPropertyField;
559 private String mRequestPropertyValue;
560
561 MockConnection(URL url, boolean usingTablet, boolean sendValidResponse,
562 boolean sendInstallEvent, boolean connectionTimesOut) {
563 super(url);
564 assertEquals(MockRequestGenerator.SERVER_URL, url.toString());
565
566 String mockResponse = buildServerResponseString(usingTablet, sendIns tallEvent);
567 mOutputStream = new ByteArrayOutputStream();
568 mServerResponse = new ByteArrayInputStream(mockResponse.getBytes());
569 mConnectionTimesOut = connectionTimesOut;
570
571 if (sendValidResponse) {
572 mHTTPResponseCode = 200;
573 } else {
574 mHTTPResponseCode = 404;
575 }
576 }
577
578 /**
579 * Build a simulated response from the Omaha server indicating an update is available.
580 * The response changes based on the device type.
581 */
582 private String buildServerResponseString(boolean isOnTablet, boolean sen dInstallEvent) {
583 String response = "";
584 response += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
585 response += "<response protocol=\"3.0\" server=\"prod\">";
586 response += "<daystart elapsed_seconds=\"12345\"/>";
587 response += "<app appid=\"";
588 response += (isOnTablet
589 ? MockRequestGenerator.UUID_TABLET : MockRequestGenerator.UU ID_PHONE);
590 response += "\" status=\"ok\">";
591 if (sendInstallEvent) {
592 response += "<event status=\"ok\"/>";
593 } else {
594 response += "<updatecheck status=\"ok\">";
595 response += "<urls><url codebase=\"" + MARKET_URL + "\"/></urls> ";
596 response += "<manifest version=\"" + UPDATE_VERSION + "\">";
597 response += "<packages>";
598 response += "<package hash=\"0\" name=\"dummy.apk\" required=\"t rue\" size=\"0\"/>";
599 response += "</packages>";
600 response += "<actions>";
601 response += "<action event=\"install\" run=\"dummy.apk\"/>";
602 response += "<action event=\"postinstall\"/>";
603 response += "</actions>";
604 response += "</manifest>";
605 response += "</updatecheck>";
606 response += "<ping status=\"ok\"/>";
607 }
608 response += "</app>";
609 response += "</response>";
610 return response;
611 }
612
613 @Override
614 public boolean usingProxy() {
615 return false;
616 }
617
618 @Override
619 public void connect() throws SocketTimeoutException {
620 if (mConnectionTimesOut) {
621 throw new SocketTimeoutException("Connection timed out.");
622 }
623 }
624
625 @Override
626 public void disconnect() {}
627
628 @Override
629 public void setDoOutput(boolean value) throws IllegalAccessError {
630 assertTrue("Told the HTTPUrlConnection to send no request.", value);
631 }
632
633 @Override
634 public void setFixedLengthStreamingMode(int contentLength) {
635 mContentLength = contentLength;
636 }
637
638 @Override
639 public int getResponseCode() {
640 if (mNumTimesResponseCodeRetrieved == 0) {
641 // The output stream should now have the generated XML for the r equest.
642 // Check if its length is correct.
643 assertEquals("Expected OmahaClient to write out certain number o f bytes",
644 mContentLength, mOutputStream.toByteArray().length);
645 }
646 assertTrue("Tried to retrieve response code more than twice",
647 mNumTimesResponseCodeRetrieved < 2);
648 mNumTimesResponseCodeRetrieved++;
649 return mHTTPResponseCode;
650 }
651
652 @Override
653 public OutputStream getOutputStream() throws IOException {
654 mSentRequest = true;
655 connect();
656 return mOutputStream;
657 }
658
659 public String getOutputStreamContents() {
660 return mOutputStream.toString();
661 }
662
663 @Override
664 public InputStream getInputStream() {
665 assertTrue("Tried to read server response without sending request.", mSentRequest);
666 mGotInputStream = true;
667 return mServerResponse;
668 }
669
670 @Override
671 public void addRequestProperty(String field, String newValue) {
672 mRequestPropertyField = field;
673 mRequestPropertyValue = newValue;
674 }
675
676 public int getNumTimesResponseCodeRetrieved() {
677 return mNumTimesResponseCodeRetrieved;
678 }
679
680 public boolean getGotInputStream() {
681 return mGotInputStream;
682 }
683
684 public boolean getSentRequest() {
685 return mSentRequest;
686 }
687
688 public String getRequestPropertyField() {
689 return mRequestPropertyField;
690 }
691
692 public String getRequestPropertyValue() {
693 return mRequestPropertyValue;
694 }
695 }
696 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698