| OLD | NEW |
| (Empty) |
| 1 // Copyright 2007-2010 Google Inc. | |
| 2 // | |
| 3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
| 4 // you may not use this file except in compliance with the License. | |
| 5 // You may obtain a copy of the License at | |
| 6 // | |
| 7 // http://www.apache.org/licenses/LICENSE-2.0 | |
| 8 // | |
| 9 // Unless required by applicable law or agreed to in writing, software | |
| 10 // distributed under the License is distributed on an "AS IS" BASIS, | |
| 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 12 // See the License for the specific language governing permissions and | |
| 13 // limitations under the License. | |
| 14 // ======================================================================== | |
| 15 | |
| 16 #include <windows.h> | |
| 17 #include "base/utils.h" | |
| 18 #include "base/scoped_ptr.h" | |
| 19 #include "omaha/base/error.h" | |
| 20 #include "omaha/common/xml_parser.h" | |
| 21 #include "omaha/goopdate/update_response_utils.h" | |
| 22 #include "omaha/testing/unit_test.h" | |
| 23 | |
| 24 namespace { | |
| 25 | |
| 26 const int kSeedManifestFileCount = 1; | |
| 27 const int kSeedManifestResponseCount = 7; | |
| 28 | |
| 29 const int kExpectedRequestLength = 2048; | |
| 30 | |
| 31 } // namespace | |
| 32 | |
| 33 namespace omaha { | |
| 34 | |
| 35 namespace xml { | |
| 36 | |
| 37 // TODO(omaha): there were many tests related to | |
| 38 // updatedev_check_period_override and policy_check_period_override, which | |
| 39 // the current parser is unaware of. These parameters must be handled outside | |
| 40 // the parser itself. Not sure how we are handling them now. | |
| 41 class XmlParserTest : public testing::Test { | |
| 42 protected: | |
| 43 XmlParserTest() { | |
| 44 } | |
| 45 | |
| 46 ~XmlParserTest() { | |
| 47 } | |
| 48 | |
| 49 virtual void SetUp() { | |
| 50 } | |
| 51 | |
| 52 virtual void TearDown() { | |
| 53 } | |
| 54 | |
| 55 // Allows test fixtures access to implementation details of UpdateRequest. | |
| 56 request::Request& get_xml_request(UpdateRequest* update_request) { | |
| 57 return update_request->request_; | |
| 58 } | |
| 59 }; | |
| 60 | |
| 61 // Creates a machine update request and serializes it. | |
| 62 TEST_F(XmlParserTest, GenerateRequestWithoutUserId_MachineUpdateRequest) { | |
| 63 // The origin URL contains an invalid XML character, the double-quote. The | |
| 64 // expectation is that this character should be escaped to """. | |
| 65 scoped_ptr<UpdateRequest> update_request( | |
| 66 UpdateRequest::Create(true, | |
| 67 _T("unittest_session"), | |
| 68 _T("unittest_install"), | |
| 69 _T("http://go/foo/\""))); | |
| 70 | |
| 71 request::Request& xml_request = get_xml_request(update_request.get()); | |
| 72 | |
| 73 xml_request.omaha_version = _T("1.2.3.4"); | |
| 74 xml_request.test_source = _T("dev"); | |
| 75 xml_request.request_id = _T("{387E2718-B39C-4458-98CC-24B5293C8383}"); | |
| 76 xml_request.os.platform = _T("win"); | |
| 77 xml_request.os.version = _T("6.0"); | |
| 78 xml_request.os.service_pack = _T("Service Pack 1"); | |
| 79 xml_request.os.arch = _T("x86"); | |
| 80 xml_request.check_period_sec = 100000; | |
| 81 xml_request.uid.Empty(); | |
| 82 | |
| 83 request::App app1; | |
| 84 app1.app_id = _T("{8A69D345-D564-463C-AFF1-A69D9E530F96}"); | |
| 85 app1.lang = _T("en"); | |
| 86 app1.iid = GuidToString(GUID_NULL); // Prevents assert. | |
| 87 app1.ap = _T("ap_with_update_check"); | |
| 88 app1.update_check.is_valid = true; | |
| 89 app1.data.install_data_index = _T("verboselogging"); | |
| 90 app1.ping.active = ACTIVE_NOTRUN; | |
| 91 app1.ping.days_since_last_active_ping = -1; | |
| 92 app1.ping.days_since_last_roll_call = 5; | |
| 93 xml_request.apps.push_back(app1); | |
| 94 | |
| 95 request::App app2; | |
| 96 app2.app_id = _T("{AD3D0CC0-AD1E-4b1f-B98E-BAA41DCE396C}"); | |
| 97 app2.lang = _T("en"); | |
| 98 app2.iid = GuidToString(GUID_NULL); // Prevents assert. | |
| 99 app2.version = _T("1.0"); | |
| 100 app2.next_version = _T("2.0"); | |
| 101 app2.ap = _T("ap_with_no_update_check"); | |
| 102 app2.experiments = _T("url_exp_2=a|Fri, 14 Aug 2015 16:13:03 GMT"); | |
| 103 xml_request.apps.push_back(app2); | |
| 104 | |
| 105 CString expected_buffer = _T("<?xml version=\"1.0\" encoding=\"UTF-8\"?><reque
st protocol=\"3.0\" version=\"1.2.3.4\" ismachine=\"1\" sessionid=\"unittest_ses
sion\" installsource=\"unittest_install\" originurl=\"http://go/foo/"\" tes
tsource=\"dev\" requestid=\"{387E2718-B39C-4458-98CC-24B5293C8383}\" periodoverr
idesec=\"100000\"><os platform=\"win\" version=\"6.0\" sp=\"Service Pack 1\" arc
h=\"x86\"/><app appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\" version=\"\" ne
xtversion=\"\" ap=\"ap_with_update_check\" lang=\"en\" brand=\"\" client=\"\"><u
pdatecheck/><data name=\"install\" index=\"verboselogging\"/><ping active=\"0\"
r=\"5\"/></app><app appid=\"{AD3D0CC0-AD1E-4b1f-B98E-BAA41DCE396C}\" version=\"1
.0\" nextversion=\"2.0\" ap=\"ap_with_no_update_check\" lang=\"en\" brand=\"\" c
lient=\"\" experiments=\"url_exp_2=a|Fri, 14 Aug 2015 16:13:03 GMT\"/></request>
"); // NOLINT | |
| 106 | |
| 107 CString actual_buffer; | |
| 108 EXPECT_HRESULT_SUCCEEDED(XmlParser::SerializeRequest(*update_request, | |
| 109 &actual_buffer)); | |
| 110 EXPECT_STREQ(expected_buffer, actual_buffer); | |
| 111 } | |
| 112 | |
| 113 // Creates a machine update request and serializes it. | |
| 114 TEST_F(XmlParserTest, GenerateRequestWithUserId_MachineUpdateRequest) { | |
| 115 // The origin URL contains an invalid XML character, the double-quote. The | |
| 116 // expectation is that this character should be escaped to """. | |
| 117 scoped_ptr<UpdateRequest> update_request( | |
| 118 UpdateRequest::Create(true, | |
| 119 _T("unittest_session"), | |
| 120 _T("unittest_install"), | |
| 121 _T("http://go/bar/\""))); | |
| 122 | |
| 123 request::Request& xml_request = get_xml_request(update_request.get()); | |
| 124 | |
| 125 xml_request.uid = _T("{c5bcb37e-47eb-4331-a544-2f31101951ab}"); | |
| 126 | |
| 127 xml_request.omaha_version = _T("4.3.2.1"); | |
| 128 xml_request.test_source = _T("dev"); | |
| 129 xml_request.request_id = _T("{387E2718-B39C-4458-98CC-24B5293C8384}"); | |
| 130 xml_request.os.platform = _T("win"); | |
| 131 xml_request.os.version = _T("7.0"); | |
| 132 xml_request.os.service_pack = _T("Service Pack 2"); | |
| 133 xml_request.os.arch = _T("x64"); | |
| 134 xml_request.check_period_sec = 200000; | |
| 135 | |
| 136 request::App app1; | |
| 137 app1.app_id = _T("{8A69D345-D564-463C-AFF1-A69D9E530F97}"); | |
| 138 app1.lang = _T("en"); | |
| 139 app1.iid = GuidToString(GUID_NULL); // Prevents assert. | |
| 140 app1.ap = _T("ap_with_update_check"); | |
| 141 app1.update_check.is_valid = true; | |
| 142 app1.data.install_data_index = _T("verboselogging"); | |
| 143 app1.ping.active = ACTIVE_NOTRUN; | |
| 144 app1.ping.days_since_last_active_ping = -1; | |
| 145 app1.ping.days_since_last_roll_call = 5; | |
| 146 xml_request.apps.push_back(app1); | |
| 147 | |
| 148 request::App app2; | |
| 149 app2.app_id = _T("{AD3D0CC0-AD1E-4b1f-B98E-BAA41DCE396D}"); | |
| 150 app2.lang = _T("en"); | |
| 151 app2.iid = GuidToString(GUID_NULL); // Prevents assert. | |
| 152 app2.version = _T("1.0"); | |
| 153 app2.next_version = _T("2.0"); | |
| 154 app2.ap = _T("ap_with_no_update_check"); | |
| 155 app2.experiments = _T("url_exp_2=a|Fri, 14 Aug 2015 16:13:03 GMT"); | |
| 156 xml_request.apps.push_back(app2); | |
| 157 | |
| 158 CString expected_buffer = _T("<?xml version=\"1.0\" encoding=\"UTF-8\"?><reque
st protocol=\"3.0\" version=\"4.3.2.1\" ismachine=\"1\" sessionid=\"unittest_ses
sion\" userid=\"{c5bcb37e-47eb-4331-a544-2f31101951ab}\" installsource=\"unittes
t_install\" originurl=\"http://go/bar/"\" testsource=\"dev\" requestid=\"{3
87E2718-B39C-4458-98CC-24B5293C8384}\" periodoverridesec=\"200000\"><os platform
=\"win\" version=\"7.0\" sp=\"Service Pack 2\" arch=\"x64\"/><app appid=\"{8A69D
345-D564-463C-AFF1-A69D9E530F97}\" version=\"\" nextversion=\"\" ap=\"ap_with_up
date_check\" lang=\"en\" brand=\"\" client=\"\"><updatecheck/><data name=\"insta
ll\" index=\"verboselogging\"/><ping active=\"0\" r=\"5\"/></app><app appid=\"{A
D3D0CC0-AD1E-4b1f-B98E-BAA41DCE396D}\" version=\"1.0\" nextversion=\"2.0\" ap=\"
ap_with_no_update_check\" lang=\"en\" brand=\"\" client=\"\" experiments=\"url_e
xp_2=a|Fri, 14 Aug 2015 16:13:03 GMT\"/></request>"); // NOLINT | |
| 159 | |
| 160 CString actual_buffer; | |
| 161 EXPECT_HRESULT_SUCCEEDED(XmlParser::SerializeRequest(*update_request, | |
| 162 &actual_buffer)); | |
| 163 EXPECT_STREQ(expected_buffer, actual_buffer); | |
| 164 } | |
| 165 | |
| 166 // TODO(omaha3): Add a UserUpdateRequest test with more values (brand, etc.). | |
| 167 | |
| 168 // Parses a response for one application. | |
| 169 TEST_F(XmlParserTest, Parse) { | |
| 170 // Array of two request strings that are almost same except the second one | |
| 171 // contains some unsupported elements that we expect to be ignored. | |
| 172 CStringA buffer_strings[] = { | |
| 173 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response protocol=\"3.0\
"><daystart elapsed_seconds=\"8400\" /><app appid=\"{8A69D345-D564-463C-AFF1-A69
D9E530F96}\" status=\"ok\" experiments=\"url_exp_2=a|Fri, 14 Aug 2015 16:13:03 G
MT\"><updatecheck status=\"ok\"><urls><url codebase=\"http://cache.pack.google.c
om/edgedl/chrome/install/172.37/\"/></urls><manifest version=\"2.0.172.37\"><pac
kages><package hash=\"NT/6ilbSjWgbVqHZ0rT1vTg1coE=\" name=\"chrome_installer.exe
\" required=\"true\" size=\"9614320\"/></packages><actions><action arguments=\"-
-do-not-launch-chrome\" event=\"install\" needsadmin=\"false\" run=\"chrome_inst
aller.exe\"/><action event=\"postinstall\" onsuccess=\"exitsilentlyonlaunchcmd\"
/></actions></manifest></updatecheck><data index=\"verboselogging\" name=\"insta
ll\" status=\"ok\">{\n \"distribution\": {\n \"verbose_logging\": true\n }\n}\
n</data><ping status=\"ok\"/></app></response>", // NOLINT | |
| 174 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response protocol=\"3.0\
" ExtraUnsupportedAttribute=\"123\"><daystart elapsed_seconds=\"8400\" /><Unsupp
ortedElement1 UnsupportedAttribute1=\"some value\" /><app appid=\"{8A69D345-D564
-463C-AFF1-A69D9E530F96}\" status=\"ok\" experiments=\"url_exp_2=a|Fri, 14 Aug 2
015 16:13:03 GMT\"><updatecheck status=\"ok\"><urls><url codebase=\"http://cache
.pack.google.com/edgedl/chrome/install/172.37/\"/></urls><manifest version=\"2.0
.172.37\"><packages><package hash=\"NT/6ilbSjWgbVqHZ0rT1vTg1coE=\" name=\"chrome
_installer.exe\" required=\"true\" size=\"9614320\"/></packages><actions><action
arguments=\"--do-not-launch-chrome\" event=\"install\" needsadmin=\"false\" run
=\"chrome_installer.exe\"/><action event=\"postinstall\" onsuccess=\"exitsilentl
yonlaunchcmd\"/></actions></manifest></updatecheck><data index=\"verboselogging\
" name=\"install\" status=\"ok\">{\n \"distribution\": {\n \"verbose_logging\"
: true\n }\n}\n</data><ping status=\"ok\"/></app><UnsupportedElement2 Unsupporte
dAttribute2=\"Unsupported value\" >Some strings inside an unsupported element, s
hould be ignored.<ping status=\"ok\"/></UnsupportedElement2></response>", // NO
LINT | |
| 175 }; | |
| 176 | |
| 177 for (int i = 0; i < arraysize(buffer_strings); i++) { | |
| 178 std::vector<uint8> buffer(buffer_strings[i].GetLength()); | |
| 179 memcpy(&buffer.front(), buffer_strings[i], buffer.size()); | |
| 180 | |
| 181 scoped_ptr<UpdateResponse> update_response(UpdateResponse::Create()); | |
| 182 EXPECT_HRESULT_SUCCEEDED(XmlParser::DeserializeResponse( | |
| 183 buffer, | |
| 184 update_response.get())); | |
| 185 | |
| 186 const response::Response& xml_response(update_response->response()); | |
| 187 | |
| 188 EXPECT_STREQ(_T("3.0"), xml_response.protocol); | |
| 189 EXPECT_EQ(1, xml_response.apps.size()); | |
| 190 | |
| 191 const response::App& app(xml_response.apps[0]); | |
| 192 EXPECT_STREQ(_T("{8A69D345-D564-463C-AFF1-A69D9E530F96}"), app.appid); | |
| 193 EXPECT_STREQ(_T("ok"), app.status); | |
| 194 EXPECT_STREQ(_T("url_exp_2=a|Fri, 14 Aug 2015 16:13:03 GMT"), | |
| 195 app.experiments); | |
| 196 | |
| 197 const response::UpdateCheck& update_check(app.update_check); | |
| 198 EXPECT_STREQ(_T("ok"), update_check.status); | |
| 199 EXPECT_EQ(1, update_check.urls.size()); | |
| 200 EXPECT_STREQ( | |
| 201 _T("http://cache.pack.google.com/edgedl/chrome/install/172.37/"), | |
| 202 update_check.urls[0]); | |
| 203 | |
| 204 const InstallManifest& install_manifest(update_check.install_manifest); | |
| 205 EXPECT_STREQ(_T("2.0.172.37"), install_manifest.version); | |
| 206 EXPECT_EQ(1, install_manifest.packages.size()); | |
| 207 | |
| 208 const InstallPackage& install_package(install_manifest.packages[0]); | |
| 209 EXPECT_STREQ(_T("chrome_installer.exe"), install_package.name); | |
| 210 EXPECT_TRUE(install_package.is_required); | |
| 211 EXPECT_EQ(9614320, install_package.size); | |
| 212 EXPECT_STREQ(_T("NT/6ilbSjWgbVqHZ0rT1vTg1coE="), install_package.hash); | |
| 213 | |
| 214 EXPECT_EQ(2, install_manifest.install_actions.size()); | |
| 215 | |
| 216 const InstallAction* install_action(&install_manifest.install_actions[0]); | |
| 217 EXPECT_EQ(InstallAction::kInstall, install_action->install_event); | |
| 218 EXPECT_EQ(NEEDS_ADMIN_NO, install_action->needs_admin); | |
| 219 EXPECT_STREQ(_T("chrome_installer.exe"), install_action->program_to_run); | |
| 220 EXPECT_STREQ(_T("--do-not-launch-chrome"), | |
| 221 install_action->program_arguments); | |
| 222 EXPECT_FALSE(install_action->terminate_all_browsers); | |
| 223 EXPECT_EQ(SUCCESS_ACTION_DEFAULT, install_action->success_action); | |
| 224 | |
| 225 install_action = &install_manifest.install_actions[1]; | |
| 226 EXPECT_EQ(InstallAction::kPostInstall, install_action->install_event); | |
| 227 EXPECT_EQ(NEEDS_ADMIN_NO, install_action->needs_admin); | |
| 228 EXPECT_FALSE(install_action->terminate_all_browsers); | |
| 229 EXPECT_EQ(SUCCESS_ACTION_EXIT_SILENTLY_ON_LAUNCH_CMD, | |
| 230 install_action->success_action); | |
| 231 | |
| 232 EXPECT_EQ(0, app.events.size()); | |
| 233 | |
| 234 CString value; | |
| 235 EXPECT_SUCCEEDED(update_response_utils::GetInstallData(app.data, | |
| 236 _T("verboselogging"), | |
| 237 &value)); | |
| 238 EXPECT_STREQ( | |
| 239 _T("{\n \"distribution\": {\n \"verbose_logging\": true\n }\n}\n"), | |
| 240 value); | |
| 241 } | |
| 242 } | |
| 243 | |
| 244 // Parses a response for one application. | |
| 245 TEST_F(XmlParserTest, Parse_InvalidDataStatusError) { | |
| 246 CStringA buffer_string = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><response
protocol=\"3.0\"><app appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\" status=\"
ok\"><updatecheck status=\"ok\"><urls><url codebase=\"http://cache.pack.google.c
om/edgedl/chrome/install/172.37/\"/></urls><manifest version=\"2.0.172.37\"><pac
kages><package hash=\"NT/6ilbSjWgbVqHZ0rT1vTg1coE=\" name=\"chrome_installer.exe
\" required=\"false\" size=\"9614320\"/></packages><actions><action arguments=\"
--do-not-launch-chrome\" event=\"install\" needsadmin=\"false\" run=\"chrome_ins
taller.exe\"/><action event=\"postinstall\" onsuccess=\"exitsilentlyonlaunchcmd\
"/></actions></manifest></updatecheck><data index=\"verboselog\" name=\"install\
" status=\"error-nodata\"/><ping status=\"ok\"/></app></response>"; // NOLINT | |
| 247 std::vector<uint8> buffer(buffer_string.GetLength()); | |
| 248 memcpy(&buffer.front(), buffer_string, buffer.size()); | |
| 249 | |
| 250 scoped_ptr<UpdateResponse> update_response(UpdateResponse::Create()); | |
| 251 EXPECT_HRESULT_SUCCEEDED(XmlParser::DeserializeResponse( | |
| 252 buffer, | |
| 253 update_response.get())); | |
| 254 const response::Response& xml_response(update_response->response()); | |
| 255 | |
| 256 EXPECT_STREQ(_T("3.0"), xml_response.protocol); | |
| 257 EXPECT_EQ(1, xml_response.apps.size()); | |
| 258 | |
| 259 const response::App& app(xml_response.apps[0]); | |
| 260 EXPECT_STREQ(_T("{8A69D345-D564-463C-AFF1-A69D9E530F96}"), app.appid); | |
| 261 EXPECT_STREQ(_T("ok"), app.status); | |
| 262 | |
| 263 const response::UpdateCheck& update_check(app.update_check); | |
| 264 EXPECT_STREQ(_T("ok"), update_check.status); | |
| 265 EXPECT_EQ(1, update_check.urls.size()); | |
| 266 EXPECT_STREQ(_T("http://cache.pack.google.com/edgedl/chrome/install/172.37/"), | |
| 267 update_check.urls[0]); | |
| 268 | |
| 269 const InstallManifest& install_manifest(update_check.install_manifest); | |
| 270 EXPECT_STREQ(_T("2.0.172.37"), install_manifest.version); | |
| 271 EXPECT_EQ(1, install_manifest.packages.size()); | |
| 272 | |
| 273 const InstallPackage& install_package(install_manifest.packages[0]); | |
| 274 EXPECT_STREQ(_T("chrome_installer.exe"), install_package.name); | |
| 275 EXPECT_FALSE(install_package.is_required); | |
| 276 EXPECT_EQ(9614320, install_package.size); | |
| 277 EXPECT_STREQ(_T("NT/6ilbSjWgbVqHZ0rT1vTg1coE="), install_package.hash); | |
| 278 | |
| 279 EXPECT_EQ(2, install_manifest.install_actions.size()); | |
| 280 | |
| 281 const InstallAction* install_action(&install_manifest.install_actions[0]); | |
| 282 EXPECT_EQ(InstallAction::kInstall, install_action->install_event); | |
| 283 EXPECT_EQ(NEEDS_ADMIN_NO, install_action->needs_admin); | |
| 284 EXPECT_STREQ(_T("chrome_installer.exe"), install_action->program_to_run); | |
| 285 EXPECT_STREQ(_T("--do-not-launch-chrome"), install_action->program_arguments); | |
| 286 EXPECT_FALSE(install_action->terminate_all_browsers); | |
| 287 EXPECT_EQ(SUCCESS_ACTION_DEFAULT, install_action->success_action); | |
| 288 | |
| 289 install_action = &install_manifest.install_actions[1]; | |
| 290 EXPECT_EQ(InstallAction::kPostInstall, install_action->install_event); | |
| 291 EXPECT_EQ(NEEDS_ADMIN_NO, install_action->needs_admin); | |
| 292 EXPECT_FALSE(install_action->terminate_all_browsers); | |
| 293 EXPECT_EQ(SUCCESS_ACTION_EXIT_SILENTLY_ON_LAUNCH_CMD, | |
| 294 install_action->success_action); | |
| 295 | |
| 296 EXPECT_EQ(0, app.events.size()); | |
| 297 | |
| 298 CString value; | |
| 299 EXPECT_EQ(GOOPDATE_E_INVALID_INSTALL_DATA_INDEX, | |
| 300 update_response_utils::GetInstallData(app.data, _T("verboselog"), | |
| 301 &value)); | |
| 302 } | |
| 303 | |
| 304 } // namespace xml | |
| 305 | |
| 306 } // namespace omaha | |
| OLD | NEW |