// Copyright 2013 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. #include "components/update_client/protocol_parser.h" #include "testing/gtest/include/gtest/gtest.h" namespace update_client { const char* kValidXml = "" "" " " " " " " " " " " " " " " " " " " " " " " " " " " ""; const char* valid_xml_with_hash = "" "" " " " " " " " " " " " " " " " " " " " " " " " " ""; const char* valid_xml_with_invalid_sizes = "" "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " ""; const char* kInvalidValidXmlMissingCodebase = "" "" " " " " " " " " " " " " " " " " " " " " " " " " ""; const char* kInvalidValidXmlMissingManifest = "" "" " " " " " " " " " " " " " " ""; const char* kMissingAppId = "" "" " " " " " " ""; const char* kInvalidCodebase = "" "" " " " " " " ""; const char* kMissingVersion = "" "" " " " " " " ""; const char* kInvalidVersion = "" "" " " " " " " ""; // The v3 version of the protocol is not using namespaces. However, the parser // must be able to parse responses that include namespaces. const char* kUsesNamespacePrefix = "" "" " " " " " " " " " " " " " " " " " " " " " " " " ""; // Includes unrelated tags from other xml namespaces - this should // not cause problems. const char* kSimilarTagnames = "" "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " ""; // Includes a tag. const char* kWithDaystart = "" "" " " " " " " " " " " " " " " " " " " " " " " " " " " ""; // Indicates no updates available - this should not be a parse error. const char* kNoUpdate = "" "" " " " " " " ""; // Includes two tags, one with an error. const char* kTwoAppsOneError = "" "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " ""; // Includes two tags, both of which set the cohort. const char* kTwoAppsSetCohort = "" "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " ""; // Includes a run action for an update check with status='ok'. const char* kUpdateCheckStatusOkWithRunAction = "" "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " ""; // Includes a run action for an update check with status='noupdate'. const char* kUpdateCheckStatusNoUpdateWithRunAction = "" "" " " " " " " " " " " " " " " ""; // Includes a run action for an update check with status='error'. const char* kUpdateCheckStatusErrorWithRunAction = "" "" " " " " " " " " " " " " " " ""; TEST(ComponentUpdaterProtocolParserTest, Parse) { ProtocolParser parser; // Test parsing of a number of invalid xml cases EXPECT_FALSE(parser.Parse(std::string())); EXPECT_FALSE(parser.errors().empty()); EXPECT_TRUE(parser.Parse(kMissingAppId)); EXPECT_TRUE(parser.results().list.empty()); EXPECT_FALSE(parser.errors().empty()); EXPECT_TRUE(parser.Parse(kInvalidCodebase)); EXPECT_TRUE(parser.results().list.empty()); EXPECT_FALSE(parser.errors().empty()); EXPECT_TRUE(parser.Parse(kMissingVersion)); EXPECT_TRUE(parser.results().list.empty()); EXPECT_FALSE(parser.errors().empty()); EXPECT_TRUE(parser.Parse(kInvalidVersion)); EXPECT_TRUE(parser.results().list.empty()); EXPECT_FALSE(parser.errors().empty()); EXPECT_TRUE(parser.Parse(kInvalidValidXmlMissingCodebase)); EXPECT_TRUE(parser.results().list.empty()); EXPECT_FALSE(parser.errors().empty()); EXPECT_TRUE(parser.Parse(kInvalidValidXmlMissingManifest)); EXPECT_TRUE(parser.results().list.empty()); EXPECT_FALSE(parser.errors().empty()); // Parse some valid XML, and check that all params came out as expected EXPECT_TRUE(parser.Parse(kValidXml)); EXPECT_TRUE(parser.errors().empty()); EXPECT_EQ(1u, parser.results().list.size()); const ProtocolParser::Result* firstResult = &parser.results().list[0]; EXPECT_STREQ("ok", firstResult->status.c_str()); EXPECT_EQ(1u, firstResult->crx_urls.size()); EXPECT_EQ(GURL("http://example.com/"), firstResult->crx_urls[0]); EXPECT_EQ(GURL("http://diff.example.com/"), firstResult->crx_diffurls[0]); EXPECT_EQ("1.2.3.4", firstResult->manifest.version); EXPECT_EQ("2.0.143.0", firstResult->manifest.browser_min_version); EXPECT_EQ(1u, firstResult->manifest.packages.size()); EXPECT_EQ("extension_1_2_3_4.crx", firstResult->manifest.packages[0].name); // Parse some xml that uses namespace prefixes. EXPECT_TRUE(parser.Parse(kUsesNamespacePrefix)); EXPECT_TRUE(parser.errors().empty()); EXPECT_TRUE(parser.Parse(kSimilarTagnames)); EXPECT_TRUE(parser.errors().empty()); // Parse xml with hash value EXPECT_TRUE(parser.Parse(valid_xml_with_hash)); EXPECT_TRUE(parser.errors().empty()); EXPECT_FALSE(parser.results().list.empty()); firstResult = &parser.results().list[0]; EXPECT_FALSE(firstResult->manifest.packages.empty()); EXPECT_EQ("1234", firstResult->manifest.packages[0].hash_sha256); EXPECT_EQ("5678", firstResult->manifest.packages[0].hashdiff_sha256); // Parse xml with package size value EXPECT_TRUE(parser.Parse(valid_xml_with_invalid_sizes)); EXPECT_TRUE(parser.errors().empty()); EXPECT_FALSE(parser.results().list.empty()); firstResult = &parser.results().list[0]; EXPECT_FALSE(firstResult->manifest.packages.empty()); EXPECT_EQ(1234, firstResult->manifest.packages[0].size); EXPECT_EQ(-1234, firstResult->manifest.packages[1].size); EXPECT_EQ(0, firstResult->manifest.packages[2].size); EXPECT_EQ(0, firstResult->manifest.packages[3].size); EXPECT_EQ(0, firstResult->manifest.packages[4].size); EXPECT_EQ(0, firstResult->manifest.packages[5].size); // Parse xml with a element. EXPECT_TRUE(parser.Parse(kWithDaystart)); EXPECT_TRUE(parser.errors().empty()); EXPECT_FALSE(parser.results().list.empty()); EXPECT_EQ(parser.results().daystart_elapsed_seconds, 456); // Parse a no-update response. EXPECT_TRUE(parser.Parse(kNoUpdate)); EXPECT_TRUE(parser.errors().empty()); EXPECT_FALSE(parser.results().list.empty()); firstResult = &parser.results().list[0]; EXPECT_STREQ("noupdate", firstResult->status.c_str()); EXPECT_EQ(firstResult->extension_id, "12345"); EXPECT_EQ(firstResult->manifest.version, ""); // Parse xml with one error and one success tag. EXPECT_TRUE(parser.Parse(kTwoAppsOneError)); EXPECT_FALSE(parser.errors().empty()); EXPECT_EQ(1u, parser.results().list.size()); firstResult = &parser.results().list[0]; EXPECT_EQ(firstResult->extension_id, "bbbbbbbb"); EXPECT_STREQ("ok", firstResult->status.c_str()); EXPECT_EQ("1.2.3.4", firstResult->manifest.version); // Parse xml with two apps setting the cohort info. EXPECT_TRUE(parser.Parse(kTwoAppsSetCohort)); EXPECT_TRUE(parser.errors().empty()); EXPECT_EQ(2u, parser.results().list.size()); firstResult = &parser.results().list[0]; EXPECT_EQ(firstResult->extension_id, "aaaaaaaa"); EXPECT_NE(firstResult->cohort_attrs.find("cohort"), firstResult->cohort_attrs.end()); EXPECT_EQ(firstResult->cohort_attrs.find("cohort")->second, "1:2q3/"); EXPECT_EQ(firstResult->cohort_attrs.find("cohortname"), firstResult->cohort_attrs.end()); EXPECT_EQ(firstResult->cohort_attrs.find("cohorthint"), firstResult->cohort_attrs.end()); const ProtocolParser::Result* secondResult = &parser.results().list[1]; EXPECT_EQ(secondResult->extension_id, "bbbbbbbb"); EXPECT_NE(secondResult->cohort_attrs.find("cohort"), secondResult->cohort_attrs.end()); EXPECT_EQ(secondResult->cohort_attrs.find("cohort")->second, "1:33z@0.33"); EXPECT_NE(secondResult->cohort_attrs.find("cohortname"), secondResult->cohort_attrs.end()); EXPECT_EQ(secondResult->cohort_attrs.find("cohortname")->second, "cname"); EXPECT_EQ(secondResult->cohort_attrs.find("cohorthint"), secondResult->cohort_attrs.end()); EXPECT_TRUE(parser.Parse(kUpdateCheckStatusOkWithRunAction)); EXPECT_TRUE(parser.errors().empty()); EXPECT_FALSE(parser.results().list.empty()); firstResult = &parser.results().list[0]; EXPECT_STREQ("ok", firstResult->status.c_str()); EXPECT_EQ(firstResult->extension_id, "12345"); EXPECT_STREQ("this", firstResult->action_run.c_str()); EXPECT_TRUE(parser.Parse(kUpdateCheckStatusNoUpdateWithRunAction)); EXPECT_TRUE(parser.errors().empty()); EXPECT_FALSE(parser.results().list.empty()); firstResult = &parser.results().list[0]; EXPECT_STREQ("noupdate", firstResult->status.c_str()); EXPECT_EQ(firstResult->extension_id, "12345"); EXPECT_STREQ("this", firstResult->action_run.c_str()); EXPECT_TRUE(parser.Parse(kUpdateCheckStatusErrorWithRunAction)); EXPECT_FALSE(parser.errors().empty()); EXPECT_TRUE(parser.results().list.empty()); } } // namespace update_client