payload_state_unittest.cc 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658
  1. //
  2. // Copyright (C) 2012 The Android Open Source Project
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. #include "update_engine/payload_state.h"
  17. #include <base/files/file_path.h>
  18. #include <base/files/file_util.h>
  19. #include <base/strings/stringprintf.h>
  20. #include <gmock/gmock.h>
  21. #include <gtest/gtest.h>
  22. #include "update_engine/common/constants.h"
  23. #include "update_engine/common/fake_clock.h"
  24. #include "update_engine/common/fake_hardware.h"
  25. #include "update_engine/common/fake_prefs.h"
  26. #include "update_engine/common/mock_prefs.h"
  27. #include "update_engine/common/prefs.h"
  28. #include "update_engine/common/test_utils.h"
  29. #include "update_engine/common/utils.h"
  30. #include "update_engine/fake_system_state.h"
  31. #include "update_engine/metrics_reporter_interface.h"
  32. #include "update_engine/omaha_request_action.h"
  33. using base::Time;
  34. using base::TimeDelta;
  35. using std::string;
  36. using testing::_;
  37. using testing::AnyNumber;
  38. using testing::AtLeast;
  39. using testing::Mock;
  40. using testing::NiceMock;
  41. using testing::Return;
  42. using testing::SetArgPointee;
  43. namespace chromeos_update_engine {
  44. const char* kCurrentBytesDownloadedFromHttps =
  45. "current-bytes-downloaded-from-HttpsServer";
  46. const char* kTotalBytesDownloadedFromHttps =
  47. "total-bytes-downloaded-from-HttpsServer";
  48. const char* kCurrentBytesDownloadedFromHttp =
  49. "current-bytes-downloaded-from-HttpServer";
  50. const char* kTotalBytesDownloadedFromHttp =
  51. "total-bytes-downloaded-from-HttpServer";
  52. const char* kCurrentBytesDownloadedFromHttpPeer =
  53. "current-bytes-downloaded-from-HttpPeer";
  54. const char* kTotalBytesDownloadedFromHttpPeer =
  55. "total-bytes-downloaded-from-HttpPeer";
  56. static void SetupPayloadStateWith2Urls(string hash,
  57. bool http_enabled,
  58. bool is_delta_payload,
  59. PayloadState* payload_state,
  60. OmahaResponse* response) {
  61. response->packages.clear();
  62. response->packages.push_back({.payload_urls = {"http://test", "https://test"},
  63. .size = 523456789,
  64. .metadata_size = 558123,
  65. .metadata_signature = "metasign",
  66. .hash = hash,
  67. .is_delta = is_delta_payload});
  68. response->max_failure_count_per_url = 3;
  69. payload_state->SetResponse(*response);
  70. string stored_response_sign = payload_state->GetResponseSignature();
  71. string expected_url_https_only =
  72. " NumURLs = 1\n"
  73. " Candidate Url0 = https://test\n";
  74. string expected_urls_both =
  75. " NumURLs = 2\n"
  76. " Candidate Url0 = http://test\n"
  77. " Candidate Url1 = https://test\n";
  78. string expected_response_sign = base::StringPrintf(
  79. "Payload 0:\n"
  80. " Size = 523456789\n"
  81. " Sha256 Hash = %s\n"
  82. " Metadata Size = 558123\n"
  83. " Metadata Signature = metasign\n"
  84. " Is Delta = %d\n"
  85. "%s"
  86. "Max Failure Count Per Url = %d\n"
  87. "Disable Payload Backoff = %d\n",
  88. hash.c_str(),
  89. response->packages[0].is_delta,
  90. (http_enabled ? expected_urls_both : expected_url_https_only).c_str(),
  91. response->max_failure_count_per_url,
  92. response->disable_payload_backoff);
  93. EXPECT_EQ(expected_response_sign, stored_response_sign);
  94. }
  95. class PayloadStateTest : public ::testing::Test {};
  96. TEST(PayloadStateTest, SetResponseWorksWithEmptyResponse) {
  97. OmahaResponse response;
  98. FakeSystemState fake_system_state;
  99. NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
  100. EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
  101. EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
  102. .Times(AtLeast(1));
  103. EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
  104. .Times(AtLeast(1));
  105. EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
  106. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
  107. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
  108. .Times(AtLeast(1));
  109. EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
  110. .Times(AtLeast(1));
  111. EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
  112. .Times(AtLeast(1));
  113. EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
  114. .Times(AtLeast(1));
  115. EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
  116. .Times(AtLeast(1));
  117. EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
  118. .Times(AtLeast(1));
  119. EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
  120. PayloadState payload_state;
  121. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  122. payload_state.SetResponse(response);
  123. string stored_response_sign = payload_state.GetResponseSignature();
  124. string expected_response_sign =
  125. "Max Failure Count Per Url = 0\n"
  126. "Disable Payload Backoff = 0\n";
  127. EXPECT_EQ(expected_response_sign, stored_response_sign);
  128. EXPECT_EQ("", payload_state.GetCurrentUrl());
  129. EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
  130. EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
  131. EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
  132. }
  133. TEST(PayloadStateTest, SetResponseWorksWithSingleUrl) {
  134. OmahaResponse response;
  135. response.packages.push_back({.payload_urls = {"https://single.url.test"},
  136. .size = 123456789,
  137. .metadata_size = 58123,
  138. .metadata_signature = "msign",
  139. .hash = "hash"});
  140. FakeSystemState fake_system_state;
  141. NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
  142. EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
  143. EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
  144. .Times(AtLeast(1));
  145. EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
  146. .Times(AtLeast(1));
  147. EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
  148. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
  149. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
  150. .Times(AtLeast(1));
  151. EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
  152. .Times(AtLeast(1));
  153. EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
  154. .Times(AtLeast(1));
  155. EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
  156. .Times(AtLeast(1));
  157. EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
  158. .Times(AtLeast(1));
  159. EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
  160. .Times(AtLeast(1));
  161. EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
  162. PayloadState payload_state;
  163. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  164. payload_state.SetResponse(response);
  165. string stored_response_sign = payload_state.GetResponseSignature();
  166. string expected_response_sign =
  167. "Payload 0:\n"
  168. " Size = 123456789\n"
  169. " Sha256 Hash = hash\n"
  170. " Metadata Size = 58123\n"
  171. " Metadata Signature = msign\n"
  172. " Is Delta = 0\n"
  173. " NumURLs = 1\n"
  174. " Candidate Url0 = https://single.url.test\n"
  175. "Max Failure Count Per Url = 0\n"
  176. "Disable Payload Backoff = 0\n";
  177. EXPECT_EQ(expected_response_sign, stored_response_sign);
  178. EXPECT_EQ("https://single.url.test", payload_state.GetCurrentUrl());
  179. EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
  180. EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
  181. EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
  182. }
  183. TEST(PayloadStateTest, SetResponseWorksWithMultipleUrls) {
  184. OmahaResponse response;
  185. response.packages.push_back({.payload_urls = {"http://multiple.url.test",
  186. "https://multiple.url.test"},
  187. .size = 523456789,
  188. .metadata_size = 558123,
  189. .metadata_signature = "metasign",
  190. .hash = "rhash"});
  191. FakeSystemState fake_system_state;
  192. NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
  193. EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
  194. EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
  195. .Times(AtLeast(1));
  196. EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
  197. .Times(AtLeast(1));
  198. EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, 0)).Times(AtLeast(1));
  199. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
  200. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
  201. .Times(AtLeast(1));
  202. EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
  203. .Times(AtLeast(1));
  204. EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
  205. .Times(AtLeast(1));
  206. EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
  207. .Times(AtLeast(1));
  208. EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
  209. PayloadState payload_state;
  210. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  211. payload_state.SetResponse(response);
  212. string stored_response_sign = payload_state.GetResponseSignature();
  213. string expected_response_sign =
  214. "Payload 0:\n"
  215. " Size = 523456789\n"
  216. " Sha256 Hash = rhash\n"
  217. " Metadata Size = 558123\n"
  218. " Metadata Signature = metasign\n"
  219. " Is Delta = 0\n"
  220. " NumURLs = 2\n"
  221. " Candidate Url0 = http://multiple.url.test\n"
  222. " Candidate Url1 = https://multiple.url.test\n"
  223. "Max Failure Count Per Url = 0\n"
  224. "Disable Payload Backoff = 0\n";
  225. EXPECT_EQ(expected_response_sign, stored_response_sign);
  226. EXPECT_EQ("http://multiple.url.test", payload_state.GetCurrentUrl());
  227. EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
  228. EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
  229. EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
  230. }
  231. TEST(PayloadStateTest, CanAdvanceUrlIndexCorrectly) {
  232. OmahaResponse response;
  233. FakeSystemState fake_system_state;
  234. NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
  235. PayloadState payload_state;
  236. EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
  237. // Payload attempt should start with 0 and then advance to 1.
  238. EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
  239. .Times(AtLeast(1));
  240. EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
  241. .Times(AtLeast(1));
  242. EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
  243. .Times(AtLeast(1));
  244. EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
  245. .Times(AtLeast(1));
  246. EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2));
  247. // Reboots will be set
  248. EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, _)).Times(AtLeast(1));
  249. // Url index should go from 0 to 1 twice.
  250. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
  251. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(1));
  252. // Failure count should be called each times url index is set, so that's
  253. // 4 times for this test.
  254. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
  255. .Times(AtLeast(4));
  256. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  257. // This does a SetResponse which causes all the states to be set to 0 for
  258. // the first time.
  259. SetupPayloadStateWith2Urls(
  260. "Hash1235", true, false, &payload_state, &response);
  261. EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
  262. // Verify that on the first error, the URL index advances to 1.
  263. ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch;
  264. payload_state.UpdateFailed(error);
  265. EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
  266. // Verify that on the next error, the URL index wraps around to 0.
  267. payload_state.UpdateFailed(error);
  268. EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
  269. // Verify that on the next error, it again advances to 1.
  270. payload_state.UpdateFailed(error);
  271. EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
  272. // Verify that we switched URLs three times
  273. EXPECT_EQ(3U, payload_state.GetUrlSwitchCount());
  274. }
  275. TEST(PayloadStateTest, NewResponseResetsPayloadState) {
  276. OmahaResponse response;
  277. FakeSystemState fake_system_state;
  278. PayloadState payload_state;
  279. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  280. // Set the first response.
  281. SetupPayloadStateWith2Urls(
  282. "Hash5823", true, false, &payload_state, &response);
  283. EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
  284. // Advance the URL index to 1 by faking an error.
  285. ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch;
  286. payload_state.UpdateFailed(error);
  287. EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
  288. EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
  289. // Now, slightly change the response and set it again.
  290. SetupPayloadStateWith2Urls(
  291. "Hash8225", true, false, &payload_state, &response);
  292. EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
  293. // Fake an error again.
  294. payload_state.UpdateFailed(error);
  295. EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
  296. EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
  297. // Return a third different response.
  298. SetupPayloadStateWith2Urls(
  299. "Hash9999", true, false, &payload_state, &response);
  300. EXPECT_EQ(3, payload_state.GetNumResponsesSeen());
  301. // Make sure the url index was reset to 0 because of the new response.
  302. EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
  303. EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
  304. EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
  305. EXPECT_EQ(0U,
  306. payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
  307. EXPECT_EQ(0U,
  308. payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
  309. EXPECT_EQ(
  310. 0U, payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpsServer));
  311. EXPECT_EQ(0U,
  312. payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
  313. }
  314. TEST(PayloadStateTest, AllCountersGetUpdatedProperlyOnErrorCodesAndEvents) {
  315. OmahaResponse response;
  316. PayloadState payload_state;
  317. FakeSystemState fake_system_state;
  318. int progress_bytes = 100;
  319. NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
  320. EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
  321. EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
  322. .Times(AtLeast(2));
  323. EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
  324. .Times(AtLeast(1));
  325. EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 2))
  326. .Times(AtLeast(1));
  327. EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
  328. .Times(AtLeast(2));
  329. EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
  330. .Times(AtLeast(1));
  331. EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 2))
  332. .Times(AtLeast(1));
  333. EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(4));
  334. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(4));
  335. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 1)).Times(AtLeast(2));
  336. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
  337. .Times(AtLeast(7));
  338. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 1))
  339. .Times(AtLeast(2));
  340. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 2))
  341. .Times(AtLeast(1));
  342. EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateTimestampStart, _))
  343. .Times(AtLeast(1));
  344. EXPECT_CALL(*prefs, SetInt64(kPrefsUpdateDurationUptime, _))
  345. .Times(AtLeast(1));
  346. EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttps, 0))
  347. .Times(AtLeast(1));
  348. EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, 0))
  349. .Times(AtLeast(1));
  350. EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttpPeer, 0))
  351. .Times(AtLeast(1));
  352. EXPECT_CALL(*prefs, SetInt64(kCurrentBytesDownloadedFromHttp, progress_bytes))
  353. .Times(AtLeast(1));
  354. EXPECT_CALL(*prefs, SetInt64(kTotalBytesDownloadedFromHttp, progress_bytes))
  355. .Times(AtLeast(1));
  356. EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 0)).Times(AtLeast(1));
  357. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  358. SetupPayloadStateWith2Urls(
  359. "Hash5873", true, false, &payload_state, &response);
  360. EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
  361. // This should advance the URL index.
  362. payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
  363. EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
  364. EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
  365. EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
  366. EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
  367. EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
  368. // This should advance the failure count only.
  369. payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
  370. EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
  371. EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
  372. EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
  373. EXPECT_EQ(1U, payload_state.GetUrlFailureCount());
  374. EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
  375. // This should advance the failure count only.
  376. payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
  377. EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
  378. EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
  379. EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
  380. EXPECT_EQ(2U, payload_state.GetUrlFailureCount());
  381. EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
  382. // This should advance the URL index as we've reached the
  383. // max failure count and reset the failure count for the new URL index.
  384. // This should also wrap around the URL index and thus cause the payload
  385. // attempt number to be incremented.
  386. payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
  387. EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
  388. EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
  389. EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
  390. EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
  391. EXPECT_EQ(2U, payload_state.GetUrlSwitchCount());
  392. EXPECT_TRUE(payload_state.ShouldBackoffDownload());
  393. // This should advance the URL index.
  394. payload_state.UpdateFailed(ErrorCode::kPayloadHashMismatchError);
  395. EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
  396. EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
  397. EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
  398. EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
  399. EXPECT_EQ(3U, payload_state.GetUrlSwitchCount());
  400. EXPECT_TRUE(payload_state.ShouldBackoffDownload());
  401. // This should advance the URL index and payload attempt number due to
  402. // wrap-around of URL index.
  403. payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMissingError);
  404. EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
  405. EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
  406. EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
  407. EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
  408. EXPECT_EQ(4U, payload_state.GetUrlSwitchCount());
  409. EXPECT_TRUE(payload_state.ShouldBackoffDownload());
  410. // This HTTP error code should only increase the failure count.
  411. payload_state.UpdateFailed(static_cast<ErrorCode>(
  412. static_cast<int>(ErrorCode::kOmahaRequestHTTPResponseBase) + 404));
  413. EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
  414. EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
  415. EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
  416. EXPECT_EQ(1U, payload_state.GetUrlFailureCount());
  417. EXPECT_EQ(4U, payload_state.GetUrlSwitchCount());
  418. EXPECT_TRUE(payload_state.ShouldBackoffDownload());
  419. // And that failure count should be reset when we download some bytes
  420. // afterwards.
  421. payload_state.DownloadProgress(progress_bytes);
  422. EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
  423. EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
  424. EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
  425. EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
  426. EXPECT_EQ(4U, payload_state.GetUrlSwitchCount());
  427. EXPECT_TRUE(payload_state.ShouldBackoffDownload());
  428. // Now, slightly change the response and set it again.
  429. SetupPayloadStateWith2Urls(
  430. "Hash8532", true, false, &payload_state, &response);
  431. EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
  432. // Make sure the url index was reset to 0 because of the new response.
  433. EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
  434. EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
  435. EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
  436. EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
  437. EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
  438. EXPECT_FALSE(payload_state.ShouldBackoffDownload());
  439. }
  440. TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulFullDownload) {
  441. OmahaResponse response;
  442. PayloadState payload_state;
  443. FakeSystemState fake_system_state;
  444. NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
  445. EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
  446. EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
  447. .Times(AtLeast(1));
  448. EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
  449. .Times(AtLeast(1));
  450. EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
  451. .Times(AtLeast(1));
  452. EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 1))
  453. .Times(AtLeast(1));
  454. EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(AtLeast(2));
  455. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
  456. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
  457. .Times(AtLeast(1));
  458. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  459. SetupPayloadStateWith2Urls(
  460. "Hash8593", true, false, &payload_state, &response);
  461. // This should just advance the payload attempt number;
  462. EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
  463. EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
  464. payload_state.DownloadComplete();
  465. EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
  466. EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
  467. EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
  468. EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
  469. EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
  470. }
  471. TEST(PayloadStateTest, PayloadAttemptNumberIncreasesOnSuccessfulDeltaDownload) {
  472. OmahaResponse response;
  473. PayloadState payload_state;
  474. FakeSystemState fake_system_state;
  475. NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
  476. EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AnyNumber());
  477. EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 0))
  478. .Times(AtLeast(1));
  479. EXPECT_CALL(*prefs, SetInt64(kPrefsPayloadAttemptNumber, 1))
  480. .Times(AtLeast(1));
  481. // kPrefsFullPayloadAttemptNumber is not incremented for delta payloads.
  482. EXPECT_CALL(*prefs, SetInt64(kPrefsFullPayloadAttemptNumber, 0))
  483. .Times(AtLeast(1));
  484. EXPECT_CALL(*prefs, SetInt64(kPrefsBackoffExpiryTime, _)).Times(1);
  485. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlIndex, 0)).Times(AtLeast(1));
  486. EXPECT_CALL(*prefs, SetInt64(kPrefsCurrentUrlFailureCount, 0))
  487. .Times(AtLeast(1));
  488. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  489. SetupPayloadStateWith2Urls("Hash8593", true, true, &payload_state, &response);
  490. // This should just advance the payload attempt number;
  491. EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
  492. EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
  493. payload_state.DownloadComplete();
  494. EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
  495. EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
  496. EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
  497. EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
  498. EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
  499. }
  500. TEST(PayloadStateTest, SetResponseResetsInvalidUrlIndex) {
  501. OmahaResponse response;
  502. PayloadState payload_state;
  503. FakeSystemState fake_system_state;
  504. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  505. SetupPayloadStateWith2Urls(
  506. "Hash4427", true, false, &payload_state, &response);
  507. // Generate enough events to advance URL index, failure count and
  508. // payload attempt number all to 1.
  509. payload_state.DownloadComplete();
  510. payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
  511. payload_state.UpdateFailed(ErrorCode::kDownloadTransferError);
  512. EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
  513. EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
  514. EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
  515. EXPECT_EQ(1U, payload_state.GetUrlFailureCount());
  516. EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
  517. // Now, simulate a corrupted url index on persisted store which gets
  518. // loaded when update_engine restarts. Using a different prefs object
  519. // so as to not bother accounting for the uninteresting calls above.
  520. FakeSystemState fake_system_state2;
  521. NiceMock<MockPrefs>* prefs2 = fake_system_state2.mock_prefs();
  522. EXPECT_CALL(*prefs2, Exists(_)).WillRepeatedly(Return(true));
  523. EXPECT_CALL(*prefs2, GetInt64(_, _)).Times(AtLeast(1));
  524. EXPECT_CALL(*prefs2, GetInt64(kPrefsPayloadAttemptNumber, _))
  525. .Times(AtLeast(1));
  526. EXPECT_CALL(*prefs2, GetInt64(kPrefsFullPayloadAttemptNumber, _))
  527. .Times(AtLeast(1));
  528. EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlIndex, _))
  529. .WillRepeatedly(DoAll(SetArgPointee<1>(2), Return(true)));
  530. EXPECT_CALL(*prefs2, GetInt64(kPrefsCurrentUrlFailureCount, _))
  531. .Times(AtLeast(1));
  532. EXPECT_CALL(*prefs2, GetInt64(kPrefsUrlSwitchCount, _)).Times(AtLeast(1));
  533. // Note: This will be a different payload object, but the response should
  534. // have the same hash as before so as to not trivially reset because the
  535. // response was different. We want to specifically test that even if the
  536. // response is same, we should reset the state if we find it corrupted.
  537. EXPECT_TRUE(payload_state.Initialize(&fake_system_state2));
  538. SetupPayloadStateWith2Urls(
  539. "Hash4427", true, false, &payload_state, &response);
  540. // Make sure all counters get reset to 0 because of the corrupted URL index
  541. // we supplied above.
  542. EXPECT_EQ(0, payload_state.GetPayloadAttemptNumber());
  543. EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
  544. EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
  545. EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
  546. EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
  547. }
  548. TEST(PayloadStateTest, NoBackoffInteractiveChecks) {
  549. OmahaResponse response;
  550. PayloadState payload_state;
  551. FakeSystemState fake_system_state;
  552. OmahaRequestParams params(&fake_system_state);
  553. params.Init("", "", true); // interactive = True.
  554. fake_system_state.set_request_params(&params);
  555. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  556. SetupPayloadStateWith2Urls(
  557. "Hash6437", true, false, &payload_state, &response);
  558. // Simulate two failures (enough to cause payload backoff) and check
  559. // again that we're ready to re-download without any backoff as this is
  560. // an interactive check.
  561. payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
  562. payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
  563. EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
  564. EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
  565. EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
  566. EXPECT_FALSE(payload_state.ShouldBackoffDownload());
  567. }
  568. TEST(PayloadStateTest, NoBackoffForP2PUpdates) {
  569. OmahaResponse response;
  570. PayloadState payload_state;
  571. FakeSystemState fake_system_state;
  572. OmahaRequestParams params(&fake_system_state);
  573. params.Init("", "", false); // interactive = False.
  574. fake_system_state.set_request_params(&params);
  575. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  576. SetupPayloadStateWith2Urls(
  577. "Hash6437", true, false, &payload_state, &response);
  578. // Simulate two failures (enough to cause payload backoff) and check
  579. // again that we're ready to re-download without any backoff as this is
  580. // an interactive check.
  581. payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
  582. payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
  583. EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
  584. EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
  585. EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
  586. // Set p2p url.
  587. payload_state.SetUsingP2PForDownloading(true);
  588. payload_state.SetP2PUrl("http://mypeer:52909/path/to/file");
  589. // Should not backoff for p2p updates.
  590. EXPECT_FALSE(payload_state.ShouldBackoffDownload());
  591. payload_state.SetP2PUrl("");
  592. // No actual p2p update if no url is provided.
  593. EXPECT_TRUE(payload_state.ShouldBackoffDownload());
  594. }
  595. TEST(PayloadStateTest, NoBackoffForDeltaPayloads) {
  596. OmahaResponse response;
  597. PayloadState payload_state;
  598. FakeSystemState fake_system_state;
  599. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  600. SetupPayloadStateWith2Urls("Hash6437", true, true, &payload_state, &response);
  601. // Simulate a successful download and see that we're ready to download
  602. // again without any backoff as this is a delta payload.
  603. payload_state.DownloadComplete();
  604. EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
  605. EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
  606. EXPECT_FALSE(payload_state.ShouldBackoffDownload());
  607. // Simulate two failures (enough to cause payload backoff) and check
  608. // again that we're ready to re-download without any backoff as this is
  609. // a delta payload.
  610. payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
  611. payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
  612. EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
  613. EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
  614. EXPECT_EQ(0, payload_state.GetFullPayloadAttemptNumber());
  615. EXPECT_FALSE(payload_state.ShouldBackoffDownload());
  616. }
  617. static void CheckPayloadBackoffState(PayloadState* payload_state,
  618. int expected_attempt_number,
  619. TimeDelta expected_days) {
  620. payload_state->DownloadComplete();
  621. EXPECT_EQ(expected_attempt_number,
  622. payload_state->GetFullPayloadAttemptNumber());
  623. EXPECT_TRUE(payload_state->ShouldBackoffDownload());
  624. Time backoff_expiry_time = payload_state->GetBackoffExpiryTime();
  625. // Add 1 hour extra to the 6 hour fuzz check to tolerate edge cases.
  626. TimeDelta max_fuzz_delta = TimeDelta::FromHours(7);
  627. Time expected_min_time = Time::Now() + expected_days - max_fuzz_delta;
  628. Time expected_max_time = Time::Now() + expected_days + max_fuzz_delta;
  629. EXPECT_LT(expected_min_time.ToInternalValue(),
  630. backoff_expiry_time.ToInternalValue());
  631. EXPECT_GT(expected_max_time.ToInternalValue(),
  632. backoff_expiry_time.ToInternalValue());
  633. }
  634. TEST(PayloadStateTest, BackoffPeriodsAreInCorrectRange) {
  635. OmahaResponse response;
  636. PayloadState payload_state;
  637. FakeSystemState fake_system_state;
  638. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  639. SetupPayloadStateWith2Urls(
  640. "Hash8939", true, false, &payload_state, &response);
  641. CheckPayloadBackoffState(&payload_state, 1, TimeDelta::FromDays(1));
  642. CheckPayloadBackoffState(&payload_state, 2, TimeDelta::FromDays(2));
  643. CheckPayloadBackoffState(&payload_state, 3, TimeDelta::FromDays(4));
  644. CheckPayloadBackoffState(&payload_state, 4, TimeDelta::FromDays(8));
  645. CheckPayloadBackoffState(&payload_state, 5, TimeDelta::FromDays(16));
  646. CheckPayloadBackoffState(&payload_state, 6, TimeDelta::FromDays(16));
  647. CheckPayloadBackoffState(&payload_state, 7, TimeDelta::FromDays(16));
  648. CheckPayloadBackoffState(&payload_state, 8, TimeDelta::FromDays(16));
  649. CheckPayloadBackoffState(&payload_state, 9, TimeDelta::FromDays(16));
  650. CheckPayloadBackoffState(&payload_state, 10, TimeDelta::FromDays(16));
  651. }
  652. TEST(PayloadStateTest, BackoffLogicCanBeDisabled) {
  653. OmahaResponse response;
  654. response.disable_payload_backoff = true;
  655. PayloadState payload_state;
  656. FakeSystemState fake_system_state;
  657. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  658. SetupPayloadStateWith2Urls(
  659. "Hash8939", true, false, &payload_state, &response);
  660. // Simulate a successful download and see that we are ready to download
  661. // again without any backoff.
  662. payload_state.DownloadComplete();
  663. EXPECT_EQ(1, payload_state.GetPayloadAttemptNumber());
  664. EXPECT_EQ(1, payload_state.GetFullPayloadAttemptNumber());
  665. EXPECT_FALSE(payload_state.ShouldBackoffDownload());
  666. // Test again, this time by simulating two errors that would cause
  667. // the payload attempt number to increment due to wrap around. And
  668. // check that we are still ready to re-download without any backoff.
  669. payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
  670. payload_state.UpdateFailed(ErrorCode::kDownloadMetadataSignatureMismatch);
  671. EXPECT_EQ(2, payload_state.GetPayloadAttemptNumber());
  672. EXPECT_EQ(2, payload_state.GetFullPayloadAttemptNumber());
  673. EXPECT_FALSE(payload_state.ShouldBackoffDownload());
  674. }
  675. TEST(PayloadStateTest, BytesDownloadedMetricsGetAddedToCorrectSources) {
  676. OmahaResponse response;
  677. response.disable_payload_backoff = true;
  678. PayloadState payload_state;
  679. FakeSystemState fake_system_state;
  680. uint64_t https_total = 0;
  681. uint64_t http_total = 0;
  682. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  683. SetupPayloadStateWith2Urls(
  684. "Hash3286", true, false, &payload_state, &response);
  685. EXPECT_EQ(1, payload_state.GetNumResponsesSeen());
  686. // Simulate a previous attempt with in order to set an initial non-zero value
  687. // for the total bytes downloaded for HTTP.
  688. uint64_t prev_chunk = 323456789;
  689. http_total += prev_chunk;
  690. payload_state.DownloadProgress(prev_chunk);
  691. // Ensure that the initial values for HTTP reflect this attempt.
  692. EXPECT_EQ(prev_chunk,
  693. payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
  694. EXPECT_EQ(http_total,
  695. payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
  696. // Change the response hash so as to simulate a new response which will
  697. // reset the current bytes downloaded, but not the total bytes downloaded.
  698. SetupPayloadStateWith2Urls(
  699. "Hash9904", true, false, &payload_state, &response);
  700. EXPECT_EQ(2, payload_state.GetNumResponsesSeen());
  701. // First, simulate successful download of a few bytes over HTTP.
  702. uint64_t first_chunk = 5000000;
  703. http_total += first_chunk;
  704. payload_state.DownloadProgress(first_chunk);
  705. // Test that first all progress is made on HTTP and none on HTTPS.
  706. EXPECT_EQ(first_chunk,
  707. payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
  708. EXPECT_EQ(http_total,
  709. payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
  710. EXPECT_EQ(
  711. 0U, payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpsServer));
  712. EXPECT_EQ(https_total,
  713. payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
  714. // Simulate an error that'll cause the url index to point to https.
  715. ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch;
  716. payload_state.UpdateFailed(error);
  717. // Test that no new progress is made on HTTP and new progress is on HTTPS.
  718. uint64_t second_chunk = 23456789;
  719. https_total += second_chunk;
  720. payload_state.DownloadProgress(second_chunk);
  721. EXPECT_EQ(first_chunk,
  722. payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
  723. EXPECT_EQ(http_total,
  724. payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
  725. EXPECT_EQ(
  726. second_chunk,
  727. payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpsServer));
  728. EXPECT_EQ(https_total,
  729. payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
  730. // Simulate error to go back to http.
  731. payload_state.UpdateFailed(error);
  732. uint64_t third_chunk = 32345678;
  733. uint64_t http_chunk = first_chunk + third_chunk;
  734. http_total += third_chunk;
  735. payload_state.DownloadProgress(third_chunk);
  736. // Test that third chunk is again back on HTTP. HTTPS remains on second chunk.
  737. EXPECT_EQ(http_chunk,
  738. payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
  739. EXPECT_EQ(http_total,
  740. payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
  741. EXPECT_EQ(
  742. second_chunk,
  743. payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpsServer));
  744. EXPECT_EQ(https_total,
  745. payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
  746. // Simulate error (will cause URL switch), set p2p is to be used and
  747. // then do 42MB worth of progress
  748. payload_state.UpdateFailed(error);
  749. payload_state.SetUsingP2PForDownloading(true);
  750. uint64_t p2p_total = 42 * 1000 * 1000;
  751. payload_state.DownloadProgress(p2p_total);
  752. EXPECT_EQ(p2p_total,
  753. payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpPeer));
  754. EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
  755. ReportSuccessfulUpdateMetrics(
  756. 1, _, kPayloadTypeFull, _, _, 314, _, _, _, 3));
  757. payload_state.UpdateSucceeded();
  758. // Make sure the metrics are reset after a successful update.
  759. EXPECT_EQ(0U,
  760. payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
  761. EXPECT_EQ(0U,
  762. payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
  763. EXPECT_EQ(
  764. 0U, payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpsServer));
  765. EXPECT_EQ(0U,
  766. payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
  767. EXPECT_EQ(0, payload_state.GetNumResponsesSeen());
  768. }
  769. TEST(PayloadStateTest, DownloadSourcesUsedIsCorrect) {
  770. OmahaResponse response;
  771. PayloadState payload_state;
  772. FakeSystemState fake_system_state;
  773. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  774. SetupPayloadStateWith2Urls(
  775. "Hash3286", true, false, &payload_state, &response);
  776. // Simulate progress in order to mark HTTP as one of the sources used.
  777. uint64_t num_bytes = 42 * 1000 * 1000;
  778. payload_state.DownloadProgress(num_bytes);
  779. // Check that this was done via HTTP.
  780. EXPECT_EQ(num_bytes,
  781. payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
  782. EXPECT_EQ(num_bytes,
  783. payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
  784. // Check that only HTTP is reported as a download source.
  785. int64_t total_bytes[kNumDownloadSources] = {};
  786. total_bytes[kDownloadSourceHttpServer] = num_bytes;
  787. EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
  788. ReportSuccessfulUpdateMetrics(
  789. _,
  790. _,
  791. _,
  792. _,
  793. test_utils::DownloadSourceMatcher(total_bytes),
  794. _,
  795. _,
  796. _,
  797. _,
  798. _))
  799. .Times(1);
  800. payload_state.UpdateSucceeded();
  801. }
  802. TEST(PayloadStateTest, RestartingUpdateResetsMetrics) {
  803. OmahaResponse response;
  804. FakeSystemState fake_system_state;
  805. PayloadState payload_state;
  806. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  807. // Set the first response.
  808. SetupPayloadStateWith2Urls(
  809. "Hash5823", true, false, &payload_state, &response);
  810. uint64_t num_bytes = 10000;
  811. payload_state.DownloadProgress(num_bytes);
  812. EXPECT_EQ(num_bytes,
  813. payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
  814. EXPECT_EQ(num_bytes,
  815. payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
  816. EXPECT_EQ(
  817. 0U, payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpsServer));
  818. EXPECT_EQ(0U,
  819. payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpsServer));
  820. payload_state.UpdateRestarted();
  821. // Make sure the current bytes downloaded is reset, but not the total bytes.
  822. EXPECT_EQ(0U,
  823. payload_state.GetCurrentBytesDownloaded(kDownloadSourceHttpServer));
  824. EXPECT_EQ(num_bytes,
  825. payload_state.GetTotalBytesDownloaded(kDownloadSourceHttpServer));
  826. }
  827. TEST(PayloadStateTest, NumRebootsIncrementsCorrectly) {
  828. FakeSystemState fake_system_state;
  829. PayloadState payload_state;
  830. NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
  831. EXPECT_CALL(*prefs, SetInt64(_, _)).Times(AtLeast(0));
  832. EXPECT_CALL(*prefs, SetInt64(kPrefsNumReboots, 1)).Times(AtLeast(1));
  833. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  834. payload_state.UpdateRestarted();
  835. EXPECT_EQ(0U, payload_state.GetNumReboots());
  836. fake_system_state.set_system_rebooted(true);
  837. payload_state.UpdateResumed();
  838. // Num reboots should be incremented because system rebooted detected.
  839. EXPECT_EQ(1U, payload_state.GetNumReboots());
  840. fake_system_state.set_system_rebooted(false);
  841. payload_state.UpdateResumed();
  842. // Num reboots should now be 1 as reboot was not detected.
  843. EXPECT_EQ(1U, payload_state.GetNumReboots());
  844. // Restart the update again to verify we set the num of reboots back to 0.
  845. payload_state.UpdateRestarted();
  846. EXPECT_EQ(0U, payload_state.GetNumReboots());
  847. }
  848. TEST(PayloadStateTest, RollbackHappened) {
  849. FakeSystemState fake_system_state;
  850. PayloadState payload_state;
  851. NiceMock<MockPrefs>* mock_powerwash_safe_prefs =
  852. fake_system_state.mock_powerwash_safe_prefs();
  853. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  854. // Verify pre-conditions are good.
  855. EXPECT_FALSE(payload_state.GetRollbackHappened());
  856. // Set to true.
  857. EXPECT_CALL(*mock_powerwash_safe_prefs,
  858. SetBoolean(kPrefsRollbackHappened, true));
  859. payload_state.SetRollbackHappened(true);
  860. EXPECT_TRUE(payload_state.GetRollbackHappened());
  861. // Set to false.
  862. EXPECT_CALL(*mock_powerwash_safe_prefs, Delete(kPrefsRollbackHappened));
  863. payload_state.SetRollbackHappened(false);
  864. EXPECT_FALSE(payload_state.GetRollbackHappened());
  865. // Let's verify we can reload it correctly.
  866. EXPECT_CALL(*mock_powerwash_safe_prefs, GetBoolean(kPrefsRollbackHappened, _))
  867. .WillOnce(DoAll(SetArgPointee<1>(true), Return(true)));
  868. EXPECT_CALL(*mock_powerwash_safe_prefs,
  869. SetBoolean(kPrefsRollbackHappened, true));
  870. payload_state.LoadRollbackHappened();
  871. EXPECT_TRUE(payload_state.GetRollbackHappened());
  872. }
  873. TEST(PayloadStateTest, RollbackVersion) {
  874. FakeSystemState fake_system_state;
  875. PayloadState payload_state;
  876. NiceMock<MockPrefs>* mock_powerwash_safe_prefs =
  877. fake_system_state.mock_powerwash_safe_prefs();
  878. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  879. // Verify pre-conditions are good.
  880. EXPECT_TRUE(payload_state.GetRollbackVersion().empty());
  881. // Mock out the os version and make sure it's blacklisted correctly.
  882. string rollback_version = "2345.0.0";
  883. OmahaRequestParams params(&fake_system_state);
  884. params.Init(rollback_version, "", false);
  885. fake_system_state.set_request_params(&params);
  886. EXPECT_CALL(*mock_powerwash_safe_prefs,
  887. SetString(kPrefsRollbackVersion, rollback_version));
  888. payload_state.Rollback();
  889. EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion());
  890. // Change it up a little and verify we load it correctly.
  891. rollback_version = "2345.0.1";
  892. // Let's verify we can reload it correctly.
  893. EXPECT_CALL(*mock_powerwash_safe_prefs, GetString(kPrefsRollbackVersion, _))
  894. .WillOnce(DoAll(SetArgPointee<1>(rollback_version), Return(true)));
  895. EXPECT_CALL(*mock_powerwash_safe_prefs,
  896. SetString(kPrefsRollbackVersion, rollback_version));
  897. payload_state.LoadRollbackVersion();
  898. EXPECT_EQ(rollback_version, payload_state.GetRollbackVersion());
  899. // Check that we report only UpdateEngine.Rollback.* metrics in
  900. // UpdateSucceeded().
  901. EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
  902. ReportRollbackMetrics(metrics::RollbackResult::kSuccess))
  903. .Times(1);
  904. payload_state.UpdateSucceeded();
  905. }
  906. TEST(PayloadStateTest, DurationsAreCorrect) {
  907. OmahaResponse response;
  908. response.packages.resize(1);
  909. PayloadState payload_state;
  910. FakeSystemState fake_system_state;
  911. FakeClock fake_clock;
  912. FakePrefs fake_prefs;
  913. // Set the clock to a well-known time - 1 second on the wall-clock
  914. // and 2 seconds on the monotonic clock
  915. fake_clock.SetWallclockTime(Time::FromInternalValue(1000000));
  916. fake_clock.SetMonotonicTime(Time::FromInternalValue(2000000));
  917. fake_system_state.set_clock(&fake_clock);
  918. fake_system_state.set_prefs(&fake_prefs);
  919. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  920. // Check that durations are correct for a successful update where
  921. // time has advanced 7 seconds on the wall clock and 4 seconds on
  922. // the monotonic clock.
  923. SetupPayloadStateWith2Urls(
  924. "Hash8593", true, false, &payload_state, &response);
  925. fake_clock.SetWallclockTime(Time::FromInternalValue(8000000));
  926. fake_clock.SetMonotonicTime(Time::FromInternalValue(6000000));
  927. payload_state.UpdateSucceeded();
  928. EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 7000000);
  929. EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 4000000);
  930. // Check that durations are reset when a new response comes in.
  931. SetupPayloadStateWith2Urls(
  932. "Hash8594", true, false, &payload_state, &response);
  933. EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 0);
  934. EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 0);
  935. // Advance time a bit (10 secs), simulate download progress and
  936. // check that durations are updated.
  937. fake_clock.SetWallclockTime(Time::FromInternalValue(18000000));
  938. fake_clock.SetMonotonicTime(Time::FromInternalValue(16000000));
  939. payload_state.DownloadProgress(10);
  940. EXPECT_EQ(payload_state.GetUpdateDuration().InMicroseconds(), 10000000);
  941. EXPECT_EQ(payload_state.GetUpdateDurationUptime().InMicroseconds(), 10000000);
  942. // Now simulate a reboot by resetting monotonic time (to 5000) and
  943. // creating a new PayloadState object and check that we load the
  944. // durations correctly (e.g. they are the same as before).
  945. fake_clock.SetMonotonicTime(Time::FromInternalValue(5000));
  946. PayloadState payload_state2;
  947. EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
  948. payload_state2.SetResponse(response);
  949. EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 10000000);
  950. EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),
  951. 10000000);
  952. // Advance wall-clock by 7 seconds and monotonic clock by 6 seconds
  953. // and check that the durations are increased accordingly.
  954. fake_clock.SetWallclockTime(Time::FromInternalValue(25000000));
  955. fake_clock.SetMonotonicTime(Time::FromInternalValue(6005000));
  956. payload_state2.UpdateSucceeded();
  957. EXPECT_EQ(payload_state2.GetUpdateDuration().InMicroseconds(), 17000000);
  958. EXPECT_EQ(payload_state2.GetUpdateDurationUptime().InMicroseconds(),
  959. 16000000);
  960. }
  961. TEST(PayloadStateTest, RebootAfterSuccessfulUpdateTest) {
  962. OmahaResponse response;
  963. PayloadState payload_state;
  964. FakeSystemState fake_system_state;
  965. FakeClock fake_clock;
  966. FakePrefs fake_prefs;
  967. // Set the clock to a well-known time (t = 30 seconds).
  968. fake_clock.SetMonotonicTime(
  969. Time::FromInternalValue(30 * Time::kMicrosecondsPerSecond));
  970. fake_system_state.set_clock(&fake_clock);
  971. fake_system_state.set_prefs(&fake_prefs);
  972. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  973. // Make the update succeed.
  974. SetupPayloadStateWith2Urls(
  975. "Hash8593", true, false, &payload_state, &response);
  976. payload_state.UpdateSucceeded();
  977. // Check that the marker was written.
  978. EXPECT_TRUE(fake_prefs.Exists(kPrefsSystemUpdatedMarker));
  979. // Now simulate a reboot and set the wallclock time to a later point
  980. // (t = 500 seconds). We do this by using a new PayloadState object
  981. // and checking that it emits the right UMA metric with the right
  982. // value.
  983. fake_clock.SetMonotonicTime(
  984. Time::FromInternalValue(500 * Time::kMicrosecondsPerSecond));
  985. PayloadState payload_state2;
  986. EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
  987. // Expect 500 - 30 seconds = 470 seconds ~= 7 min 50 sec
  988. EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
  989. ReportTimeToReboot(7));
  990. fake_system_state.set_system_rebooted(true);
  991. payload_state2.UpdateEngineStarted();
  992. // Check that the marker was nuked.
  993. EXPECT_FALSE(fake_prefs.Exists(kPrefsSystemUpdatedMarker));
  994. }
  995. TEST(PayloadStateTest, RestartAfterCrash) {
  996. PayloadState payload_state;
  997. FakeSystemState fake_system_state;
  998. testing::StrictMock<MockMetricsReporter> mock_metrics_reporter;
  999. fake_system_state.set_metrics_reporter(&mock_metrics_reporter);
  1000. NiceMock<MockPrefs>* prefs = fake_system_state.mock_prefs();
  1001. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1002. // Only the |kPrefsAttemptInProgress| state variable should be read.
  1003. EXPECT_CALL(*prefs, Exists(_)).Times(0);
  1004. EXPECT_CALL(*prefs, SetString(_, _)).Times(0);
  1005. EXPECT_CALL(*prefs, SetInt64(_, _)).Times(0);
  1006. EXPECT_CALL(*prefs, SetBoolean(_, _)).Times(0);
  1007. EXPECT_CALL(*prefs, GetString(_, _)).Times(0);
  1008. EXPECT_CALL(*prefs, GetInt64(_, _)).Times(0);
  1009. EXPECT_CALL(*prefs, GetBoolean(_, _)).Times(0);
  1010. EXPECT_CALL(*prefs, GetBoolean(kPrefsAttemptInProgress, _));
  1011. // Simulate an update_engine restart without a reboot.
  1012. fake_system_state.set_system_rebooted(false);
  1013. payload_state.UpdateEngineStarted();
  1014. }
  1015. TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsNoReporting) {
  1016. PayloadState payload_state;
  1017. FakeSystemState fake_system_state;
  1018. // If there's no marker at startup, ensure we don't report a metric.
  1019. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1020. EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
  1021. ReportAbnormallyTerminatedUpdateAttemptMetrics())
  1022. .Times(0);
  1023. payload_state.UpdateEngineStarted();
  1024. }
  1025. TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsReported) {
  1026. PayloadState payload_state;
  1027. FakeSystemState fake_system_state;
  1028. FakePrefs fake_prefs;
  1029. // If we have a marker at startup, ensure it's reported and the
  1030. // marker is then cleared.
  1031. fake_system_state.set_prefs(&fake_prefs);
  1032. fake_prefs.SetBoolean(kPrefsAttemptInProgress, true);
  1033. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1034. EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
  1035. ReportAbnormallyTerminatedUpdateAttemptMetrics())
  1036. .Times(1);
  1037. payload_state.UpdateEngineStarted();
  1038. EXPECT_FALSE(fake_prefs.Exists(kPrefsAttemptInProgress));
  1039. }
  1040. TEST(PayloadStateTest, AbnormalTerminationAttemptMetricsClearedOnSucceess) {
  1041. PayloadState payload_state;
  1042. FakeSystemState fake_system_state;
  1043. FakePrefs fake_prefs;
  1044. // Make sure the marker is written and cleared during an attempt and
  1045. // also that we DO NOT emit the metric (since the attempt didn't end
  1046. // abnormally).
  1047. fake_system_state.set_prefs(&fake_prefs);
  1048. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1049. OmahaResponse response;
  1050. response.packages.resize(1);
  1051. payload_state.SetResponse(response);
  1052. EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
  1053. ReportAbnormallyTerminatedUpdateAttemptMetrics())
  1054. .Times(0);
  1055. // Attempt not in progress, should be clear.
  1056. EXPECT_FALSE(fake_prefs.Exists(kPrefsAttemptInProgress));
  1057. payload_state.UpdateRestarted();
  1058. // Attempt not in progress, should be set.
  1059. EXPECT_TRUE(fake_prefs.Exists(kPrefsAttemptInProgress));
  1060. payload_state.UpdateSucceeded();
  1061. // Attempt not in progress, should be clear.
  1062. EXPECT_FALSE(fake_prefs.Exists(kPrefsAttemptInProgress));
  1063. }
  1064. TEST(PayloadStateTest, CandidateUrlsComputedCorrectly) {
  1065. OmahaResponse response;
  1066. FakeSystemState fake_system_state;
  1067. PayloadState payload_state;
  1068. policy::MockDevicePolicy disable_http_policy;
  1069. fake_system_state.set_device_policy(&disable_http_policy);
  1070. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1071. // Test with no device policy. Should default to allowing http.
  1072. EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
  1073. .WillRepeatedly(Return(false));
  1074. // Set the first response.
  1075. SetupPayloadStateWith2Urls(
  1076. "Hash8433", true, false, &payload_state, &response);
  1077. // Check that we use the HTTP URL since there is no value set for allowing
  1078. // http.
  1079. EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
  1080. // Test with device policy not allowing http updates.
  1081. EXPECT_CALL(disable_http_policy, GetHttpDownloadsEnabled(_))
  1082. .WillRepeatedly(DoAll(SetArgPointee<0>(false), Return(true)));
  1083. // Reset state and set again.
  1084. SetupPayloadStateWith2Urls(
  1085. "Hash8433", false, false, &payload_state, &response);
  1086. // Check that we skip the HTTP URL and use only the HTTPS url.
  1087. EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
  1088. // Advance the URL index to 1 by faking an error.
  1089. ErrorCode error = ErrorCode::kDownloadMetadataSignatureMismatch;
  1090. payload_state.UpdateFailed(error);
  1091. // Check that we still skip the HTTP URL and use only the HTTPS url.
  1092. EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
  1093. EXPECT_EQ(0U, payload_state.GetUrlSwitchCount());
  1094. // Now, slightly change the response and set it again.
  1095. SetupPayloadStateWith2Urls(
  1096. "Hash2399", false, false, &payload_state, &response);
  1097. // Check that we still skip the HTTP URL and use only the HTTPS url.
  1098. EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
  1099. // Now, pretend that the HTTP policy is turned on. We want to make sure
  1100. // the new policy is honored.
  1101. policy::MockDevicePolicy enable_http_policy;
  1102. fake_system_state.set_device_policy(&enable_http_policy);
  1103. EXPECT_CALL(enable_http_policy, GetHttpDownloadsEnabled(_))
  1104. .WillRepeatedly(DoAll(SetArgPointee<0>(true), Return(true)));
  1105. // Now, set the same response using the same hash
  1106. // so that we can test that the state is reset not because of the
  1107. // hash but because of the policy change which results in candidate url
  1108. // list change.
  1109. SetupPayloadStateWith2Urls(
  1110. "Hash2399", true, false, &payload_state, &response);
  1111. // Check that we use the HTTP URL now and the failure count is reset.
  1112. EXPECT_EQ("http://test", payload_state.GetCurrentUrl());
  1113. EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
  1114. // Fake a failure and see if we're moving over to the HTTPS url and update
  1115. // the URL switch count properly.
  1116. payload_state.UpdateFailed(error);
  1117. EXPECT_EQ("https://test", payload_state.GetCurrentUrl());
  1118. EXPECT_EQ(1U, payload_state.GetUrlSwitchCount());
  1119. EXPECT_EQ(0U, payload_state.GetUrlFailureCount());
  1120. }
  1121. TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsDelta) {
  1122. OmahaResponse response;
  1123. PayloadState payload_state;
  1124. FakeSystemState fake_system_state;
  1125. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1126. SetupPayloadStateWith2Urls("Hash6437", true, true, &payload_state, &response);
  1127. // Simulate a successful download and update.
  1128. payload_state.DownloadComplete();
  1129. EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
  1130. ReportSuccessfulUpdateMetrics(
  1131. _, _, kPayloadTypeDelta, _, _, _, _, _, _, _));
  1132. payload_state.UpdateSucceeded();
  1133. // Mock the request to a request where the delta was disabled but Omaha sends
  1134. // a delta anyway and test again.
  1135. OmahaRequestParams params(&fake_system_state);
  1136. params.set_delta_okay(false);
  1137. fake_system_state.set_request_params(&params);
  1138. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1139. SetupPayloadStateWith2Urls("Hash6437", true, true, &payload_state, &response);
  1140. payload_state.DownloadComplete();
  1141. EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
  1142. ReportSuccessfulUpdateMetrics(
  1143. _, _, kPayloadTypeDelta, _, _, _, _, _, _, _));
  1144. payload_state.UpdateSucceeded();
  1145. }
  1146. TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsForcedFull) {
  1147. OmahaResponse response;
  1148. PayloadState payload_state;
  1149. FakeSystemState fake_system_state;
  1150. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1151. SetupPayloadStateWith2Urls(
  1152. "Hash6437", true, false, &payload_state, &response);
  1153. // Mock the request to a request where the delta was disabled.
  1154. OmahaRequestParams params(&fake_system_state);
  1155. params.set_delta_okay(false);
  1156. fake_system_state.set_request_params(&params);
  1157. // Simulate a successful download and update.
  1158. payload_state.DownloadComplete();
  1159. EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
  1160. ReportSuccessfulUpdateMetrics(
  1161. _, _, kPayloadTypeForcedFull, _, _, _, _, _, _, _));
  1162. payload_state.UpdateSucceeded();
  1163. }
  1164. TEST(PayloadStateTest, PayloadTypeMetricWhenTypeIsFull) {
  1165. OmahaResponse response;
  1166. PayloadState payload_state;
  1167. FakeSystemState fake_system_state;
  1168. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1169. SetupPayloadStateWith2Urls(
  1170. "Hash6437", true, false, &payload_state, &response);
  1171. // Mock the request to a request where the delta is enabled, although the
  1172. // result is full.
  1173. OmahaRequestParams params(&fake_system_state);
  1174. params.set_delta_okay(true);
  1175. fake_system_state.set_request_params(&params);
  1176. // Simulate a successful download and update.
  1177. payload_state.DownloadComplete();
  1178. EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
  1179. ReportSuccessfulUpdateMetrics(
  1180. _, _, kPayloadTypeFull, _, _, _, _, _, _, _));
  1181. payload_state.UpdateSucceeded();
  1182. }
  1183. TEST(PayloadStateTest, RebootAfterUpdateFailedMetric) {
  1184. FakeSystemState fake_system_state;
  1185. OmahaResponse response;
  1186. PayloadState payload_state;
  1187. FakePrefs fake_prefs;
  1188. fake_system_state.set_prefs(&fake_prefs);
  1189. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1190. SetupPayloadStateWith2Urls(
  1191. "Hash3141", true, false, &payload_state, &response);
  1192. // Simulate a successful download and update.
  1193. payload_state.DownloadComplete();
  1194. payload_state.UpdateSucceeded();
  1195. payload_state.ExpectRebootInNewVersion("Version:12345678");
  1196. // Reboot into the same environment to get an UMA metric with a value of 1.
  1197. EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
  1198. ReportFailedUpdateCount(1));
  1199. payload_state.ReportFailedBootIfNeeded();
  1200. Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_reporter());
  1201. // Simulate a second update and reboot into the same environment, this should
  1202. // send a value of 2.
  1203. payload_state.ExpectRebootInNewVersion("Version:12345678");
  1204. EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
  1205. ReportFailedUpdateCount(2));
  1206. payload_state.ReportFailedBootIfNeeded();
  1207. Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_reporter());
  1208. // Simulate a third failed reboot to new version, but this time for a
  1209. // different payload. This should send a value of 1 this time.
  1210. payload_state.ExpectRebootInNewVersion("Version:3141592");
  1211. EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
  1212. ReportFailedUpdateCount(1));
  1213. payload_state.ReportFailedBootIfNeeded();
  1214. Mock::VerifyAndClearExpectations(fake_system_state.mock_metrics_reporter());
  1215. }
  1216. TEST(PayloadStateTest, RebootAfterUpdateSucceed) {
  1217. FakeSystemState fake_system_state;
  1218. OmahaResponse response;
  1219. PayloadState payload_state;
  1220. FakePrefs fake_prefs;
  1221. fake_system_state.set_prefs(&fake_prefs);
  1222. FakeBootControl* fake_boot_control = fake_system_state.fake_boot_control();
  1223. fake_boot_control->SetCurrentSlot(0);
  1224. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1225. SetupPayloadStateWith2Urls(
  1226. "Hash3141", true, false, &payload_state, &response);
  1227. // Simulate a successful download and update.
  1228. payload_state.DownloadComplete();
  1229. payload_state.UpdateSucceeded();
  1230. payload_state.ExpectRebootInNewVersion("Version:12345678");
  1231. // Change the BootDevice to a different one, no metric should be sent.
  1232. fake_boot_control->SetCurrentSlot(1);
  1233. EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
  1234. ReportFailedUpdateCount(_))
  1235. .Times(0);
  1236. payload_state.ReportFailedBootIfNeeded();
  1237. // A second reboot in either partition should not send a metric.
  1238. payload_state.ReportFailedBootIfNeeded();
  1239. fake_boot_control->SetCurrentSlot(0);
  1240. payload_state.ReportFailedBootIfNeeded();
  1241. }
  1242. TEST(PayloadStateTest, RebootAfterCanceledUpdate) {
  1243. FakeSystemState fake_system_state;
  1244. OmahaResponse response;
  1245. PayloadState payload_state;
  1246. FakePrefs fake_prefs;
  1247. fake_system_state.set_prefs(&fake_prefs);
  1248. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1249. SetupPayloadStateWith2Urls(
  1250. "Hash3141", true, false, &payload_state, &response);
  1251. // Simulate a successful download and update.
  1252. payload_state.DownloadComplete();
  1253. payload_state.UpdateSucceeded();
  1254. payload_state.ExpectRebootInNewVersion("Version:12345678");
  1255. EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
  1256. ReportFailedUpdateCount(_))
  1257. .Times(0);
  1258. // Cancel the applied update.
  1259. payload_state.ResetUpdateStatus();
  1260. // Simulate a reboot.
  1261. payload_state.ReportFailedBootIfNeeded();
  1262. }
  1263. TEST(PayloadStateTest, UpdateSuccessWithWipedPrefs) {
  1264. FakeSystemState fake_system_state;
  1265. PayloadState payload_state;
  1266. FakePrefs fake_prefs;
  1267. fake_system_state.set_prefs(&fake_prefs);
  1268. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1269. EXPECT_CALL(*fake_system_state.mock_metrics_reporter(),
  1270. ReportFailedUpdateCount(_))
  1271. .Times(0);
  1272. // Simulate a reboot in this environment.
  1273. payload_state.ReportFailedBootIfNeeded();
  1274. }
  1275. TEST(PayloadStateTest, DisallowP2PAfterTooManyAttempts) {
  1276. OmahaResponse response;
  1277. PayloadState payload_state;
  1278. FakeSystemState fake_system_state;
  1279. FakePrefs fake_prefs;
  1280. fake_system_state.set_prefs(&fake_prefs);
  1281. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1282. SetupPayloadStateWith2Urls(
  1283. "Hash8593", true, false, &payload_state, &response);
  1284. // Should allow exactly kMaxP2PAttempts...
  1285. for (int n = 0; n < kMaxP2PAttempts; n++) {
  1286. payload_state.P2PNewAttempt();
  1287. EXPECT_TRUE(payload_state.P2PAttemptAllowed());
  1288. }
  1289. // ... but not more than that.
  1290. payload_state.P2PNewAttempt();
  1291. EXPECT_FALSE(payload_state.P2PAttemptAllowed());
  1292. }
  1293. TEST(PayloadStateTest, DisallowP2PAfterDeadline) {
  1294. OmahaResponse response;
  1295. PayloadState payload_state;
  1296. FakeSystemState fake_system_state;
  1297. FakeClock fake_clock;
  1298. FakePrefs fake_prefs;
  1299. fake_system_state.set_clock(&fake_clock);
  1300. fake_system_state.set_prefs(&fake_prefs);
  1301. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1302. SetupPayloadStateWith2Urls(
  1303. "Hash8593", true, false, &payload_state, &response);
  1304. // Set the clock to 1 second.
  1305. Time epoch = Time::FromInternalValue(1000000);
  1306. fake_clock.SetWallclockTime(epoch);
  1307. // Do an attempt - this will set the timestamp.
  1308. payload_state.P2PNewAttempt();
  1309. // Check that the timestamp equals what we just set.
  1310. EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
  1311. // Time hasn't advanced - this should work.
  1312. EXPECT_TRUE(payload_state.P2PAttemptAllowed());
  1313. // Set clock to half the deadline - this should work.
  1314. fake_clock.SetWallclockTime(
  1315. epoch + TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds) / 2);
  1316. EXPECT_TRUE(payload_state.P2PAttemptAllowed());
  1317. // Check that the first attempt timestamp hasn't changed just
  1318. // because the wall-clock time changed.
  1319. EXPECT_EQ(epoch, payload_state.GetP2PFirstAttemptTimestamp());
  1320. // Set clock to _just_ before the deadline - this should work.
  1321. fake_clock.SetWallclockTime(
  1322. epoch + TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds - 1));
  1323. EXPECT_TRUE(payload_state.P2PAttemptAllowed());
  1324. // Set clock to _just_ after the deadline - this should not work.
  1325. fake_clock.SetWallclockTime(
  1326. epoch + TimeDelta::FromSeconds(kMaxP2PAttemptTimeSeconds + 1));
  1327. EXPECT_FALSE(payload_state.P2PAttemptAllowed());
  1328. }
  1329. TEST(PayloadStateTest, P2PStateVarsInitialValue) {
  1330. OmahaResponse response;
  1331. PayloadState payload_state;
  1332. FakeSystemState fake_system_state;
  1333. FakePrefs fake_prefs;
  1334. fake_system_state.set_prefs(&fake_prefs);
  1335. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1336. SetupPayloadStateWith2Urls(
  1337. "Hash8593", true, false, &payload_state, &response);
  1338. Time null_time = Time();
  1339. EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
  1340. EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
  1341. }
  1342. TEST(PayloadStateTest, P2PStateVarsArePersisted) {
  1343. OmahaResponse response;
  1344. PayloadState payload_state;
  1345. FakeSystemState fake_system_state;
  1346. FakeClock fake_clock;
  1347. FakePrefs fake_prefs;
  1348. fake_system_state.set_clock(&fake_clock);
  1349. fake_system_state.set_prefs(&fake_prefs);
  1350. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1351. SetupPayloadStateWith2Urls(
  1352. "Hash8593", true, false, &payload_state, &response);
  1353. // Set the clock to something known.
  1354. Time time = Time::FromInternalValue(12345);
  1355. fake_clock.SetWallclockTime(time);
  1356. // New p2p attempt - as a side-effect this will update the p2p state vars.
  1357. payload_state.P2PNewAttempt();
  1358. EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
  1359. EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
  1360. // Now create a new PayloadState and check that it loads the state
  1361. // vars correctly.
  1362. PayloadState payload_state2;
  1363. EXPECT_TRUE(payload_state2.Initialize(&fake_system_state));
  1364. EXPECT_EQ(1, payload_state2.GetP2PNumAttempts());
  1365. EXPECT_EQ(time, payload_state2.GetP2PFirstAttemptTimestamp());
  1366. }
  1367. TEST(PayloadStateTest, P2PStateVarsAreClearedOnNewResponse) {
  1368. OmahaResponse response;
  1369. PayloadState payload_state;
  1370. FakeSystemState fake_system_state;
  1371. FakeClock fake_clock;
  1372. FakePrefs fake_prefs;
  1373. fake_system_state.set_clock(&fake_clock);
  1374. fake_system_state.set_prefs(&fake_prefs);
  1375. EXPECT_TRUE(payload_state.Initialize(&fake_system_state));
  1376. SetupPayloadStateWith2Urls(
  1377. "Hash8593", true, false, &payload_state, &response);
  1378. // Set the clock to something known.
  1379. Time time = Time::FromInternalValue(12345);
  1380. fake_clock.SetWallclockTime(time);
  1381. // New p2p attempt - as a side-effect this will update the p2p state vars.
  1382. payload_state.P2PNewAttempt();
  1383. EXPECT_EQ(1, payload_state.GetP2PNumAttempts());
  1384. EXPECT_EQ(time, payload_state.GetP2PFirstAttemptTimestamp());
  1385. // Set a new response...
  1386. SetupPayloadStateWith2Urls(
  1387. "Hash9904", true, false, &payload_state, &response);
  1388. // ... and check that it clears the P2P state vars.
  1389. Time null_time = Time();
  1390. EXPECT_EQ(0, payload_state.GetP2PNumAttempts());
  1391. EXPECT_EQ(null_time, payload_state.GetP2PFirstAttemptTimestamp());
  1392. }
  1393. } // namespace chromeos_update_engine