Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / android / javatests / src / org / chromium / chrome / browser / omaha / ResponseParserTest.java
1 // Copyright 2014 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.test.InstrumentationTestCase;
8 import android.test.suitebuilder.annotation.SmallTest;
9 import android.util.Xml;
10
11 import org.chromium.base.test.util.Feature;
12 import org.xmlpull.v1.XmlSerializer;
13
14 import java.io.IOException;
15 import java.io.StringWriter;
16
17 /**
18  * Unit tests for the Omaha ResponseParser.
19  */
20 public class ResponseParserTest extends InstrumentationTestCase {
21     // Note that the Omaha server appends "/" to the end of the URL codebase.
22     private static final String STRIPPED_URL =
23             "https://play.google.com/store/apps/details?id=com.google.android.apps.chrome";
24     private static final String URL = STRIPPED_URL + "/";
25     private static final String NEXT_VERSION = "1.2.3.4";
26
27     private static final String APP_STATUS_OK = "ok";
28     private static final String APP_STATUS_RESTRICTED = "restricted";
29     private static final String APP_STATUS_ERROR = "error-whatever-else";
30
31     private static final String UPDATE_STATUS_OK = "ok";
32     private static final String UPDATE_STATUS_NOUPDATE = "noupdate";
33     private static final String UPDATE_STATUS_ERROR = "error-osnotsupported";
34     private static final String UPDATE_STATUS_WTF = "omgwtfbbq";
35
36     /**
37      * Create XML for testing.
38      * @param xmlProtocol Version number of the protocol.  Expected to be "3.0" for valid XML.
39      * @param elapsedSeconds Number of seconds since server midnight.
40      * @param appStatus Status to use for the <app> element.
41      * @param addInstall Whether or not to add an install event.
42      * @param addPing Whether or not to add a ping event.
43      * @param updateStatus Status to use for the <updatecheck> element.
44      * @return The completed XML.
45      */
46     private static String createTestXML(String xmlProtocol, String elapsedSeconds,
47             String appStatus, boolean addInstall, boolean addPing, String updateStatus,
48             String updateUrl) {
49         StringWriter writer = new StringWriter();
50         try {
51             XmlSerializer serializer = Xml.newSerializer();
52             serializer.setOutput(writer);
53             serializer.startDocument("UTF-8", true);
54
55             // Set up <response ...>
56             serializer.startTag(null, "response");
57             serializer.attribute(null, "server", "prod");
58             if (xmlProtocol != null) {
59                 serializer.attribute(null, "protocol", xmlProtocol);
60             }
61
62             // Create <daystart> element.
63             if (elapsedSeconds != null) {
64                 serializer.startTag(null, "daystart");
65                 serializer.attribute(null, "elapsed_seconds", elapsedSeconds);
66                 serializer.endTag(null, "daystart");
67             }
68
69             // Create <app> element with unused attribute.
70             serializer.startTag(null, "app");
71             serializer.attribute(null, "appid", "{APP_ID}");
72             serializer.attribute(null, "status", appStatus);
73             serializer.attribute(null, "unused", "attribute");
74
75             if (addInstall) {
76                 serializer.startTag(null, "event");
77                 serializer.attribute(null, "status", "ok");
78                 serializer.endTag(null, "event");
79             }
80
81             if (addPing) {
82                 serializer.startTag(null, "ping");
83                 serializer.attribute(null, "status", "ok");
84                 serializer.endTag(null, "ping");
85             }
86
87             if (updateStatus != null) {
88                 serializer.startTag(null, "updatecheck");
89                 serializer.attribute(null, "status", updateStatus);
90                 if (UPDATE_STATUS_OK.equals(updateStatus)) {
91                     createUpdateXML(serializer, updateUrl);
92                 }
93                 serializer.endTag(null, "updatecheck");
94             }
95             serializer.endTag(null, "app");
96
97             // Create extraneous tag.
98             serializer.startTag(null, "extraneous");
99             serializer.attribute(null, "useless", "yes");
100             serializer.endTag(null, "extraneous");
101
102             serializer.endTag(null, "response");
103             serializer.endDocument();
104         } catch (IOException e) {
105             fail("Caught an IOException creating the XML: " + e);
106         } catch (IllegalArgumentException e) {
107             fail("Caught an IllegalArgumentException creating the XML: " + e);
108         } catch (IllegalStateException e) {
109             fail("Caught an IllegalStateException creating the XML: " + e);
110         }
111
112         return writer.toString();
113     }
114
115     private static void createUpdateXML(XmlSerializer serializer, String updateUrl)
116             throws IOException {
117         // End result should look something like:
118         // <updatecheck status="ok">
119         //  <urls>
120         //    <url codebase="URL" />
121         //  </urls>
122         //  <manifest garbage="attribute" version="NEXT_VERSION">
123         //    <packages>
124         //      <package hash="0" name="dummy.apk" required="true" size="0" />
125         //    </packages>
126         //    <actions>
127         //      <action event="install" run="dummy.apk" />
128         //      <action event="postinstall" />
129         //    </actions>
130         //  </manifest>
131         //  <better be="ignored" />
132         //</updatecheck>
133
134         // Create <urls> and its descendants.
135         serializer.startTag(null, "urls");
136         if (updateUrl != null) {
137             serializer.startTag(null, "url");
138             serializer.attribute(null, "codebase", updateUrl);
139             serializer.endTag(null, "url");
140         }
141         serializer.endTag(null, "urls");
142
143         // Create <manifest> and its descendants.
144         serializer.startTag(null, "manifest");
145         serializer.attribute(null, "garbage", "attribute");
146         serializer.attribute(null, "version", NEXT_VERSION);
147
148         // Create <packages> and its children.
149         serializer.startTag(null, "packages");
150         serializer.startTag(null, "package");
151         serializer.attribute(null, "hash", "0");
152         serializer.attribute(null, "name", "dummy.apk");
153         serializer.attribute(null, "required", "true");
154         serializer.attribute(null, "size", "0");
155         serializer.endTag(null, "package");
156         serializer.endTag(null, "packages");
157
158         // Create <actions> and its children.
159         serializer.startTag(null, "actions");
160         serializer.startTag(null, "action");
161         serializer.attribute(null, "event", "install");
162         serializer.attribute(null, "run", "dummy.apk");
163         serializer.endTag(null, "action");
164
165         serializer.startTag(null, "action");
166         serializer.attribute(null, "event", "postinstall");
167         serializer.endTag(null, "action");
168         serializer.endTag(null, "actions");
169         serializer.endTag(null, "manifest");
170
171         // Create a dummy element for testing to make sure it's ignored.
172         serializer.startTag(null, "dummy");
173         serializer.attribute(null, "hopefully", "ignored");
174         serializer.endTag(null, "dummy");
175     }
176
177     /**
178      * Runs a test that is expected to pass.
179      * @param appStatus Status to use for the <app> element.
180      * @param addInstall Whether or not to add an install event.
181      * @param addPing Whether or not to add a ping.
182      * @param updateStatus Status to use for the <updatecheck> element.
183      * @throws RequestFailureException Thrown if the test fails.
184      */
185     private static void runSuccessTest(String appStatus, boolean addInstall, boolean addPing,
186             String updateStatus) throws RequestFailureException {
187         String xml =
188                 createTestXML("3.0", "12345", appStatus, addInstall, addPing, updateStatus, URL);
189         ResponseParser parser =
190                 new ResponseParser(true, "{APP_ID}", addInstall, addPing, updateStatus != null);
191         parser.parseResponse(xml);
192
193         assertEquals("elapsed_seconds doesn't match.", 12345, parser.getDaystartSeconds());
194         assertEquals("<app> status doesn't match.", appStatus, parser.getAppStatus());
195         assertEquals("<updatecheck> status doesn't match.", updateStatus, parser.getUpdateStatus());
196         if (UPDATE_STATUS_OK.equals(updateStatus)) {
197             assertEquals("Version number doesn't match.", "1.2.3.4", parser.getNewVersion());
198             assertEquals("Market URL doesn't match.", STRIPPED_URL, parser.getURL());
199         } else {
200             assertEquals("Version number doesn't match.", null, parser.getNewVersion());
201             assertEquals("Market URL doesn't match.", null, parser.getURL());
202         }
203     }
204
205     /**
206      * Runs a test that is expected to fail in a particular way.
207      * @param xml XML to parse.
208      * @param expectedErrorCode Expected error code.
209      * @param expectInstall Whether or not the parser should expect an install event.
210      * @param expectPing Whether or not the parser should expect a ping element.
211      * @param expectUpdate Whether or not the parser should expect an update check.
212      */
213     private static void runFailureTest(String xml, int expectedErrorCode,
214             boolean expectInstall, boolean expectPing, boolean expectUpdate) {
215         ResponseParser parser =
216                 new ResponseParser(true, "{APP_ID}", expectInstall, expectPing, expectUpdate);
217
218         try {
219             parser.parseResponse(xml);
220         } catch (RequestFailureException e) {
221             assertEquals("Incorrect error code received.", expectedErrorCode, e.errorCode);
222             return;
223         }
224
225         fail("Failed to throw RequestFailureException for bad XML.");
226     }
227
228     @SmallTest
229     @Feature({"Omaha"})
230     public void testValidAllTypes() throws RequestFailureException {
231         runSuccessTest(APP_STATUS_OK, true, true, UPDATE_STATUS_OK);
232     }
233
234     @SmallTest
235     @Feature({"Omaha"})
236     public void testValidNoInstall() throws RequestFailureException {
237         runSuccessTest(APP_STATUS_OK, false, true, UPDATE_STATUS_OK);
238     }
239
240     @SmallTest
241     @Feature({"Omaha"})
242     public void testValidNoPing() throws RequestFailureException {
243         runSuccessTest(APP_STATUS_OK, true, false, UPDATE_STATUS_OK);
244     }
245
246     @SmallTest
247     @Feature({"Omaha"})
248     public void testValidNoUpdatecheck() throws RequestFailureException {
249         runSuccessTest(APP_STATUS_OK, true, true, null);
250     }
251
252     @SmallTest
253     @Feature({"Omaha"})
254     public void testValidUpdatecheckNoUpdate() throws RequestFailureException {
255         runSuccessTest(APP_STATUS_OK, false, false, UPDATE_STATUS_NOUPDATE);
256     }
257
258     @SmallTest
259     @Feature({"Omaha"})
260     public void testValidUpdatecheckError() throws RequestFailureException {
261         runSuccessTest(APP_STATUS_OK, false, false, UPDATE_STATUS_ERROR);
262     }
263
264     @SmallTest
265     @Feature({"Omaha"})
266     public void testValidUpdatecheckUnknown() throws RequestFailureException {
267         runSuccessTest(APP_STATUS_OK, false, false, UPDATE_STATUS_WTF);
268     }
269
270     @SmallTest
271     @Feature({"Omaha"})
272     public void testValidAppStatusRestricted() throws RequestFailureException {
273         runSuccessTest(APP_STATUS_RESTRICTED, false, false, null);
274     }
275
276     @SmallTest
277     @Feature({"Omaha"})
278     public void testFailBogusResponse() {
279         String xml = "Bogus";
280         runFailureTest(xml, RequestFailureException.ERROR_MALFORMED_XML, false, false, false);
281     }
282
283     @SmallTest
284     @Feature({"Omaha"})
285     public void testBadResponseProtocol() {
286         String xml =
287                 createTestXML("2.0", "12345", APP_STATUS_OK, false, false, UPDATE_STATUS_OK, URL);
288         runFailureTest(xml, RequestFailureException.ERROR_PARSE_RESPONSE, false, false, false);
289     }
290
291     @SmallTest
292     @Feature({"Omaha"})
293     public void testFailMissingDaystart() {
294         String xml =
295                 createTestXML("3.0", null, APP_STATUS_OK, false, false, UPDATE_STATUS_OK, URL);
296         runFailureTest(xml, RequestFailureException.ERROR_PARSE_DAYSTART, false, false, true);
297     }
298
299     @SmallTest
300     @Feature({"Omaha"})
301     public void testAppTagMissingUpdatecheck() {
302         String xml =
303                 createTestXML("3.0", "12345", APP_STATUS_OK, true, false, null, URL);
304         runFailureTest(xml, RequestFailureException.ERROR_PARSE_UPDATECHECK, true, false, true);
305     }
306
307     @SmallTest
308     @Feature({"Omaha"})
309     public void testAppTagUnexpectedUpdatecheck() {
310         String xml =
311                 createTestXML("3.0", "12345", APP_STATUS_OK, true, false, UPDATE_STATUS_OK, URL);
312         runFailureTest(xml, RequestFailureException.ERROR_PARSE_UPDATECHECK, true, false, false);
313     }
314
315     @SmallTest
316     @Feature({"Omaha"})
317     public void testAppTagMissingPing() {
318         String xml =
319                 createTestXML("3.0", "12345", APP_STATUS_OK, false, false, UPDATE_STATUS_OK, URL);
320         runFailureTest(xml, RequestFailureException.ERROR_PARSE_PING, false, true, true);
321     }
322
323     @SmallTest
324     @Feature({"Omaha"})
325     public void testAppTagUnexpectedPing() {
326         String xml =
327                 createTestXML("3.0", "12345", APP_STATUS_OK, false, true, UPDATE_STATUS_OK, URL);
328         runFailureTest(xml, RequestFailureException.ERROR_PARSE_PING, false, false, true);
329     }
330
331     @SmallTest
332     @Feature({"Omaha"})
333     public void testAppTagMissingInstall() {
334         String xml =
335                 createTestXML("3.0", "12345", APP_STATUS_OK, false, false, UPDATE_STATUS_OK, URL);
336         runFailureTest(xml, RequestFailureException.ERROR_PARSE_EVENT, true, false, true);
337     }
338
339     @SmallTest
340     @Feature({"Omaha"})
341     public void testAppTagUnexpectedInstall() {
342         String xml =
343                 createTestXML("3.0", "12345", APP_STATUS_OK, true, false, UPDATE_STATUS_OK, URL);
344         runFailureTest(xml, RequestFailureException.ERROR_PARSE_EVENT, false, false, true);
345     }
346
347     @SmallTest
348     @Feature({"Omaha"})
349     public void testAppTagStatusError() {
350         String xml =
351                 createTestXML("3.0", "12345", APP_STATUS_ERROR, false, false, null, URL);
352         runFailureTest(xml, RequestFailureException.ERROR_PARSE_APP, false, false, false);
353     }
354
355     @SmallTest
356     @Feature({"Omaha"})
357     public void testUpdatecheckMissingUrl() {
358         String xml = createTestXML(
359                 "3.0", "12345", APP_STATUS_OK, false, false, UPDATE_STATUS_OK, null);
360         runFailureTest(xml, RequestFailureException.ERROR_PARSE_URLS, false, false, true);
361     }
362 }