| Index: chrome/android/javatests/src/org/chromium/chrome/browser/omaha/ResponseParserTest.java
|
| diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/ResponseParserTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/ResponseParserTest.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6ad87a99c89b773655fd5bbfb546adde854d180d
|
| --- /dev/null
|
| +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omaha/ResponseParserTest.java
|
| @@ -0,0 +1,362 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +package org.chromium.chrome.browser.omaha;
|
| +
|
| +import android.test.InstrumentationTestCase;
|
| +import android.test.suitebuilder.annotation.SmallTest;
|
| +import android.util.Xml;
|
| +
|
| +import org.chromium.base.test.util.Feature;
|
| +import org.xmlpull.v1.XmlSerializer;
|
| +
|
| +import java.io.IOException;
|
| +import java.io.StringWriter;
|
| +
|
| +/**
|
| + * Unit tests for the Omaha ResponseParser.
|
| + */
|
| +public class ResponseParserTest extends InstrumentationTestCase {
|
| + // Note that the Omaha server appends "/" to the end of the URL codebase.
|
| + private static final String STRIPPED_URL =
|
| + "https://play.google.com/store/apps/details?id=com.google.android.apps.chrome";
|
| + private static final String URL = STRIPPED_URL + "/";
|
| + private static final String NEXT_VERSION = "1.2.3.4";
|
| +
|
| + private static final String APP_STATUS_OK = "ok";
|
| + private static final String APP_STATUS_RESTRICTED = "restricted";
|
| + private static final String APP_STATUS_ERROR = "error-whatever-else";
|
| +
|
| + private static final String UPDATE_STATUS_OK = "ok";
|
| + private static final String UPDATE_STATUS_NOUPDATE = "noupdate";
|
| + private static final String UPDATE_STATUS_ERROR = "error-osnotsupported";
|
| + private static final String UPDATE_STATUS_WTF = "omgwtfbbq";
|
| +
|
| + /**
|
| + * Create XML for testing.
|
| + * @param xmlProtocol Version number of the protocol. Expected to be "3.0" for valid XML.
|
| + * @param elapsedSeconds Number of seconds since server midnight.
|
| + * @param appStatus Status to use for the <app> element.
|
| + * @param addInstall Whether or not to add an install event.
|
| + * @param addPing Whether or not to add a ping event.
|
| + * @param updateStatus Status to use for the <updatecheck> element.
|
| + * @return The completed XML.
|
| + */
|
| + private static String createTestXML(String xmlProtocol, String elapsedSeconds,
|
| + String appStatus, boolean addInstall, boolean addPing, String updateStatus,
|
| + String updateUrl) {
|
| + StringWriter writer = new StringWriter();
|
| + try {
|
| + XmlSerializer serializer = Xml.newSerializer();
|
| + serializer.setOutput(writer);
|
| + serializer.startDocument("UTF-8", true);
|
| +
|
| + // Set up <response ...>
|
| + serializer.startTag(null, "response");
|
| + serializer.attribute(null, "server", "prod");
|
| + if (xmlProtocol != null) {
|
| + serializer.attribute(null, "protocol", xmlProtocol);
|
| + }
|
| +
|
| + // Create <daystart> element.
|
| + if (elapsedSeconds != null) {
|
| + serializer.startTag(null, "daystart");
|
| + serializer.attribute(null, "elapsed_seconds", elapsedSeconds);
|
| + serializer.endTag(null, "daystart");
|
| + }
|
| +
|
| + // Create <app> element with unused attribute.
|
| + serializer.startTag(null, "app");
|
| + serializer.attribute(null, "appid", "{APP_ID}");
|
| + serializer.attribute(null, "status", appStatus);
|
| + serializer.attribute(null, "unused", "attribute");
|
| +
|
| + if (addInstall) {
|
| + serializer.startTag(null, "event");
|
| + serializer.attribute(null, "status", "ok");
|
| + serializer.endTag(null, "event");
|
| + }
|
| +
|
| + if (addPing) {
|
| + serializer.startTag(null, "ping");
|
| + serializer.attribute(null, "status", "ok");
|
| + serializer.endTag(null, "ping");
|
| + }
|
| +
|
| + if (updateStatus != null) {
|
| + serializer.startTag(null, "updatecheck");
|
| + serializer.attribute(null, "status", updateStatus);
|
| + if (UPDATE_STATUS_OK.equals(updateStatus)) {
|
| + createUpdateXML(serializer, updateUrl);
|
| + }
|
| + serializer.endTag(null, "updatecheck");
|
| + }
|
| + serializer.endTag(null, "app");
|
| +
|
| + // Create extraneous tag.
|
| + serializer.startTag(null, "extraneous");
|
| + serializer.attribute(null, "useless", "yes");
|
| + serializer.endTag(null, "extraneous");
|
| +
|
| + serializer.endTag(null, "response");
|
| + serializer.endDocument();
|
| + } catch (IOException e) {
|
| + fail("Caught an IOException creating the XML: " + e);
|
| + } catch (IllegalArgumentException e) {
|
| + fail("Caught an IllegalArgumentException creating the XML: " + e);
|
| + } catch (IllegalStateException e) {
|
| + fail("Caught an IllegalStateException creating the XML: " + e);
|
| + }
|
| +
|
| + return writer.toString();
|
| + }
|
| +
|
| + private static void createUpdateXML(XmlSerializer serializer, String updateUrl)
|
| + throws IOException {
|
| + // End result should look something like:
|
| + // <updatecheck status="ok">
|
| + // <urls>
|
| + // <url codebase="URL" />
|
| + // </urls>
|
| + // <manifest garbage="attribute" version="NEXT_VERSION">
|
| + // <packages>
|
| + // <package hash="0" name="dummy.apk" required="true" size="0" />
|
| + // </packages>
|
| + // <actions>
|
| + // <action event="install" run="dummy.apk" />
|
| + // <action event="postinstall" />
|
| + // </actions>
|
| + // </manifest>
|
| + // <better be="ignored" />
|
| + //</updatecheck>
|
| +
|
| + // Create <urls> and its descendants.
|
| + serializer.startTag(null, "urls");
|
| + if (updateUrl != null) {
|
| + serializer.startTag(null, "url");
|
| + serializer.attribute(null, "codebase", updateUrl);
|
| + serializer.endTag(null, "url");
|
| + }
|
| + serializer.endTag(null, "urls");
|
| +
|
| + // Create <manifest> and its descendants.
|
| + serializer.startTag(null, "manifest");
|
| + serializer.attribute(null, "garbage", "attribute");
|
| + serializer.attribute(null, "version", NEXT_VERSION);
|
| +
|
| + // Create <packages> and its children.
|
| + serializer.startTag(null, "packages");
|
| + serializer.startTag(null, "package");
|
| + serializer.attribute(null, "hash", "0");
|
| + serializer.attribute(null, "name", "dummy.apk");
|
| + serializer.attribute(null, "required", "true");
|
| + serializer.attribute(null, "size", "0");
|
| + serializer.endTag(null, "package");
|
| + serializer.endTag(null, "packages");
|
| +
|
| + // Create <actions> and its children.
|
| + serializer.startTag(null, "actions");
|
| + serializer.startTag(null, "action");
|
| + serializer.attribute(null, "event", "install");
|
| + serializer.attribute(null, "run", "dummy.apk");
|
| + serializer.endTag(null, "action");
|
| +
|
| + serializer.startTag(null, "action");
|
| + serializer.attribute(null, "event", "postinstall");
|
| + serializer.endTag(null, "action");
|
| + serializer.endTag(null, "actions");
|
| + serializer.endTag(null, "manifest");
|
| +
|
| + // Create a dummy element for testing to make sure it's ignored.
|
| + serializer.startTag(null, "dummy");
|
| + serializer.attribute(null, "hopefully", "ignored");
|
| + serializer.endTag(null, "dummy");
|
| + }
|
| +
|
| + /**
|
| + * Runs a test that is expected to pass.
|
| + * @param appStatus Status to use for the <app> element.
|
| + * @param addInstall Whether or not to add an install event.
|
| + * @param addPing Whether or not to add a ping.
|
| + * @param updateStatus Status to use for the <updatecheck> element.
|
| + * @throws RequestFailureException Thrown if the test fails.
|
| + */
|
| + private static void runSuccessTest(String appStatus, boolean addInstall, boolean addPing,
|
| + String updateStatus) throws RequestFailureException {
|
| + String xml =
|
| + createTestXML("3.0", "12345", appStatus, addInstall, addPing, updateStatus, URL);
|
| + ResponseParser parser =
|
| + new ResponseParser(true, "{APP_ID}", addInstall, addPing, updateStatus != null);
|
| + parser.parseResponse(xml);
|
| +
|
| + assertEquals("elapsed_seconds doesn't match.", 12345, parser.getDaystartSeconds());
|
| + assertEquals("<app> status doesn't match.", appStatus, parser.getAppStatus());
|
| + assertEquals("<updatecheck> status doesn't match.", updateStatus, parser.getUpdateStatus());
|
| + if (UPDATE_STATUS_OK.equals(updateStatus)) {
|
| + assertEquals("Version number doesn't match.", "1.2.3.4", parser.getNewVersion());
|
| + assertEquals("Market URL doesn't match.", STRIPPED_URL, parser.getURL());
|
| + } else {
|
| + assertEquals("Version number doesn't match.", null, parser.getNewVersion());
|
| + assertEquals("Market URL doesn't match.", null, parser.getURL());
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Runs a test that is expected to fail in a particular way.
|
| + * @param xml XML to parse.
|
| + * @param expectedErrorCode Expected error code.
|
| + * @param expectInstall Whether or not the parser should expect an install event.
|
| + * @param expectPing Whether or not the parser should expect a ping element.
|
| + * @param expectUpdate Whether or not the parser should expect an update check.
|
| + */
|
| + private static void runFailureTest(String xml, int expectedErrorCode,
|
| + boolean expectInstall, boolean expectPing, boolean expectUpdate) {
|
| + ResponseParser parser =
|
| + new ResponseParser(true, "{APP_ID}", expectInstall, expectPing, expectUpdate);
|
| +
|
| + try {
|
| + parser.parseResponse(xml);
|
| + } catch (RequestFailureException e) {
|
| + assertEquals("Incorrect error code received.", expectedErrorCode, e.errorCode);
|
| + return;
|
| + }
|
| +
|
| + fail("Failed to throw RequestFailureException for bad XML.");
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testValidAllTypes() throws RequestFailureException {
|
| + runSuccessTest(APP_STATUS_OK, true, true, UPDATE_STATUS_OK);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testValidNoInstall() throws RequestFailureException {
|
| + runSuccessTest(APP_STATUS_OK, false, true, UPDATE_STATUS_OK);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testValidNoPing() throws RequestFailureException {
|
| + runSuccessTest(APP_STATUS_OK, true, false, UPDATE_STATUS_OK);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testValidNoUpdatecheck() throws RequestFailureException {
|
| + runSuccessTest(APP_STATUS_OK, true, true, null);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testValidUpdatecheckNoUpdate() throws RequestFailureException {
|
| + runSuccessTest(APP_STATUS_OK, false, false, UPDATE_STATUS_NOUPDATE);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testValidUpdatecheckError() throws RequestFailureException {
|
| + runSuccessTest(APP_STATUS_OK, false, false, UPDATE_STATUS_ERROR);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testValidUpdatecheckUnknown() throws RequestFailureException {
|
| + runSuccessTest(APP_STATUS_OK, false, false, UPDATE_STATUS_WTF);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testValidAppStatusRestricted() throws RequestFailureException {
|
| + runSuccessTest(APP_STATUS_RESTRICTED, false, false, null);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testFailBogusResponse() {
|
| + String xml = "Bogus";
|
| + runFailureTest(xml, RequestFailureException.ERROR_MALFORMED_XML, false, false, false);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testBadResponseProtocol() {
|
| + String xml =
|
| + createTestXML("2.0", "12345", APP_STATUS_OK, false, false, UPDATE_STATUS_OK, URL);
|
| + runFailureTest(xml, RequestFailureException.ERROR_PARSE_RESPONSE, false, false, false);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testFailMissingDaystart() {
|
| + String xml =
|
| + createTestXML("3.0", null, APP_STATUS_OK, false, false, UPDATE_STATUS_OK, URL);
|
| + runFailureTest(xml, RequestFailureException.ERROR_PARSE_DAYSTART, false, false, true);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testAppTagMissingUpdatecheck() {
|
| + String xml =
|
| + createTestXML("3.0", "12345", APP_STATUS_OK, true, false, null, URL);
|
| + runFailureTest(xml, RequestFailureException.ERROR_PARSE_UPDATECHECK, true, false, true);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testAppTagUnexpectedUpdatecheck() {
|
| + String xml =
|
| + createTestXML("3.0", "12345", APP_STATUS_OK, true, false, UPDATE_STATUS_OK, URL);
|
| + runFailureTest(xml, RequestFailureException.ERROR_PARSE_UPDATECHECK, true, false, false);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testAppTagMissingPing() {
|
| + String xml =
|
| + createTestXML("3.0", "12345", APP_STATUS_OK, false, false, UPDATE_STATUS_OK, URL);
|
| + runFailureTest(xml, RequestFailureException.ERROR_PARSE_PING, false, true, true);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testAppTagUnexpectedPing() {
|
| + String xml =
|
| + createTestXML("3.0", "12345", APP_STATUS_OK, false, true, UPDATE_STATUS_OK, URL);
|
| + runFailureTest(xml, RequestFailureException.ERROR_PARSE_PING, false, false, true);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testAppTagMissingInstall() {
|
| + String xml =
|
| + createTestXML("3.0", "12345", APP_STATUS_OK, false, false, UPDATE_STATUS_OK, URL);
|
| + runFailureTest(xml, RequestFailureException.ERROR_PARSE_EVENT, true, false, true);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testAppTagUnexpectedInstall() {
|
| + String xml =
|
| + createTestXML("3.0", "12345", APP_STATUS_OK, true, false, UPDATE_STATUS_OK, URL);
|
| + runFailureTest(xml, RequestFailureException.ERROR_PARSE_EVENT, false, false, true);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testAppTagStatusError() {
|
| + String xml =
|
| + createTestXML("3.0", "12345", APP_STATUS_ERROR, false, false, null, URL);
|
| + runFailureTest(xml, RequestFailureException.ERROR_PARSE_APP, false, false, false);
|
| + }
|
| +
|
| + @SmallTest
|
| + @Feature({"Omaha"})
|
| + public void testUpdatecheckMissingUrl() {
|
| + String xml = createTestXML(
|
| + "3.0", "12345", APP_STATUS_OK, false, false, UPDATE_STATUS_OK, null);
|
| + runFailureTest(xml, RequestFailureException.ERROR_PARSE_URLS, false, false, true);
|
| + }
|
| +}
|
|
|