1 // 2 // Copyright (C) 2014 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 17 #include "update_engine/update_manager/boxed_value.h" 18 19 #include <gtest/gtest.h> 20 #include <list> 21 #include <map> 22 #include <set> 23 #include <string> 24 #include <utility> 25 26 #include <base/strings/stringprintf.h> 27 #include <base/time/time.h> 28 29 #include "update_engine/update_manager/rollback_prefs.h" 30 #include "update_engine/update_manager/shill_provider.h" 31 #include "update_engine/update_manager/umtest_utils.h" 32 #include "update_engine/update_manager/updater_provider.h" 33 #include "update_engine/update_manager/weekly_time.h" 34 35 using base::Time; 36 using base::TimeDelta; 37 using chromeos_update_engine::ConnectionTethering; 38 using chromeos_update_engine::ConnectionType; 39 using std::list; 40 using std::map; 41 using std::set; 42 using std::string; 43 44 namespace chromeos_update_manager { 45 46 // The DeleterMarker flags a bool variable when the class is destroyed. 47 class DeleterMarker { 48 public: 49 explicit DeleterMarker(bool* marker) : marker_(marker) { *marker_ = false; } 50 51 ~DeleterMarker() { *marker_ = true; } 52 53 private: 54 friend string BoxedValue::ValuePrinter<DeleterMarker>(const void*); 55 56 // Pointer to the bool marker. 57 bool* marker_; 58 }; 59 60 template <> 61 string BoxedValue::ValuePrinter<DeleterMarker>(const void* value) { 62 const DeleterMarker* val = reinterpret_cast<const DeleterMarker*>(value); 63 return base::StringPrintf("DeleterMarker:%s", 64 *val->marker_ ? "true" : "false"); 65 } 66 67 TEST(UmBoxedValueTest, Deleted) { 68 bool marker = true; 69 const DeleterMarker* deleter_marker = new DeleterMarker(&marker); 70 71 EXPECT_FALSE(marker); 72 BoxedValue* box = new BoxedValue(deleter_marker); 73 EXPECT_FALSE(marker); 74 delete box; 75 EXPECT_TRUE(marker); 76 } 77 78 TEST(UmBoxedValueTest, MoveConstructor) { 79 bool marker = true; 80 const DeleterMarker* deleter_marker = new DeleterMarker(&marker); 81 82 BoxedValue* box = new BoxedValue(deleter_marker); 83 BoxedValue* new_box = new BoxedValue(std::move(*box)); 84 // box is now undefined but valid. 85 delete box; 86 EXPECT_FALSE(marker); 87 // The deleter_marker gets deleted at this point. 88 delete new_box; 89 EXPECT_TRUE(marker); 90 } 91 92 TEST(UmBoxedValueTest, MixedList) { 93 list<BoxedValue> lst; 94 // This is mostly a compile test. 95 lst.emplace_back(new const int{42}); 96 lst.emplace_back(new const string("Hello world!")); 97 bool marker; 98 lst.emplace_back(new const DeleterMarker(&marker)); 99 EXPECT_FALSE(marker); 100 lst.clear(); 101 EXPECT_TRUE(marker); 102 } 103 104 TEST(UmBoxedValueTest, MixedMap) { 105 map<int, BoxedValue> m; 106 m.emplace(42, BoxedValue(new const string("Hola mundo!"))); 107 108 auto it = m.find(42); 109 ASSERT_NE(it, m.end()); 110 EXPECT_NE(nullptr, it->second.value()); 111 EXPECT_EQ(nullptr, m[33].value()); 112 } 113 114 TEST(UmBoxedValueTest, StringToString) { 115 EXPECT_EQ("Hej Verden!", BoxedValue(new string("Hej Verden!")).ToString()); 116 } 117 118 TEST(UmBoxedValueTest, IntToString) { 119 EXPECT_EQ("42", BoxedValue(new int(42)).ToString()); 120 } 121 122 TEST(UmBoxedValueTest, Int64ToString) { 123 // -123456789012345 doesn't fit in 32-bit integers. 124 EXPECT_EQ("-123456789012345", 125 BoxedValue(new int64_t(-123456789012345LL)).ToString()); 126 } 127 128 TEST(UmBoxedValueTest, UnsignedIntToString) { 129 // 4294967295 is the biggest possible 32-bit unsigned integer. 130 EXPECT_EQ("4294967295", 131 BoxedValue(new unsigned int(4294967295U)).ToString()); // NOLINT 132 } 133 134 TEST(UmBoxedValueTest, UnsignedInt64ToString) { 135 // 18446744073709551615 is the biggest possible 64-bit unsigned integer. 136 EXPECT_EQ("18446744073709551615", 137 BoxedValue(new uint64_t(18446744073709551615ULL)).ToString()); 138 } 139 140 TEST(UmBoxedValueTest, BoolToString) { 141 EXPECT_EQ("false", BoxedValue(new bool(false)).ToString()); 142 EXPECT_EQ("true", BoxedValue(new bool(true)).ToString()); 143 } 144 145 TEST(UmBoxedValueTest, DoubleToString) { 146 EXPECT_EQ("1.501", BoxedValue(new double(1.501)).ToString()); 147 } 148 149 TEST(UmBoxedValueTest, TimeToString) { 150 // Tue Apr 29 22:30:55 UTC 2014 is 1398810655 seconds since the Unix Epoch. 151 EXPECT_EQ("4/29/2014 22:30:55 GMT", 152 BoxedValue(new Time(Time::FromTimeT(1398810655))).ToString()); 153 } 154 155 TEST(UmBoxedValueTest, TimeDeltaToString) { 156 // 12345 seconds is 3 hours, 25 minutes and 45 seconds. 157 EXPECT_EQ( 158 "3h25m45s", 159 BoxedValue(new TimeDelta(TimeDelta::FromSeconds(12345))).ToString()); 160 } 161 162 TEST(UmBoxedValueTest, ConnectionTypeToString) { 163 EXPECT_EQ( 164 "Disconnected", 165 BoxedValue(new ConnectionType(ConnectionType::kDisconnected)).ToString()); 166 EXPECT_EQ( 167 "ethernet", 168 BoxedValue(new ConnectionType(ConnectionType::kEthernet)).ToString()); 169 EXPECT_EQ("wifi", 170 BoxedValue(new ConnectionType(ConnectionType::kWifi)).ToString()); 171 EXPECT_EQ("wimax", 172 BoxedValue(new ConnectionType(ConnectionType::kWimax)).ToString()); 173 EXPECT_EQ( 174 "bluetooth", 175 BoxedValue(new ConnectionType(ConnectionType::kBluetooth)).ToString()); 176 EXPECT_EQ( 177 "cellular", 178 BoxedValue(new ConnectionType(ConnectionType::kCellular)).ToString()); 179 EXPECT_EQ( 180 "Unknown", 181 BoxedValue(new ConnectionType(ConnectionType::kUnknown)).ToString()); 182 } 183 184 TEST(UmBoxedValueTest, ConnectionTetheringToString) { 185 EXPECT_EQ( 186 "Not Detected", 187 BoxedValue(new ConnectionTethering(ConnectionTethering::kNotDetected)) 188 .ToString()); 189 EXPECT_EQ("Suspected", 190 BoxedValue(new ConnectionTethering(ConnectionTethering::kSuspected)) 191 .ToString()); 192 EXPECT_EQ("Confirmed", 193 BoxedValue(new ConnectionTethering(ConnectionTethering::kConfirmed)) 194 .ToString()); 195 EXPECT_EQ("Unknown", 196 BoxedValue(new ConnectionTethering(ConnectionTethering::kUnknown)) 197 .ToString()); 198 } 199 200 TEST(UmBoxedValueTest, RollbackToTargetVersionToString) { 201 EXPECT_EQ("Unspecified", 202 BoxedValue(new RollbackToTargetVersion( 203 RollbackToTargetVersion::kUnspecified)) 204 .ToString()); 205 EXPECT_EQ("Disabled", 206 BoxedValue( 207 new RollbackToTargetVersion(RollbackToTargetVersion::kDisabled)) 208 .ToString()); 209 EXPECT_EQ("Rollback and powerwash", 210 BoxedValue(new RollbackToTargetVersion( 211 RollbackToTargetVersion::kRollbackAndPowerwash)) 212 .ToString()); 213 EXPECT_EQ( 214 "Rollback and restore if possible", 215 BoxedValue(new RollbackToTargetVersion( 216 RollbackToTargetVersion::kRollbackAndRestoreIfPossible)) 217 .ToString()); 218 EXPECT_EQ( 219 "Rollback only if restore is possible", 220 BoxedValue(new RollbackToTargetVersion( 221 RollbackToTargetVersion::kRollbackOnlyIfRestorePossible)) 222 .ToString()); 223 } 224 225 TEST(UmBoxedValueTest, SetConnectionTypeToString) { 226 set<ConnectionType>* set1 = new set<ConnectionType>; 227 set1->insert(ConnectionType::kWimax); 228 set1->insert(ConnectionType::kEthernet); 229 EXPECT_EQ("ethernet,wimax", BoxedValue(set1).ToString()); 230 231 set<ConnectionType>* set2 = new set<ConnectionType>; 232 set2->insert(ConnectionType::kWifi); 233 EXPECT_EQ("wifi", BoxedValue(set2).ToString()); 234 } 235 236 TEST(UmBoxedValueTest, StageToString) { 237 EXPECT_EQ("Idle", BoxedValue(new Stage(Stage::kIdle)).ToString()); 238 EXPECT_EQ("Checking For Update", 239 BoxedValue(new Stage(Stage::kCheckingForUpdate)).ToString()); 240 EXPECT_EQ("Update Available", 241 BoxedValue(new Stage(Stage::kUpdateAvailable)).ToString()); 242 EXPECT_EQ("Downloading", 243 BoxedValue(new Stage(Stage::kDownloading)).ToString()); 244 EXPECT_EQ("Verifying", BoxedValue(new Stage(Stage::kVerifying)).ToString()); 245 EXPECT_EQ("Finalizing", BoxedValue(new Stage(Stage::kFinalizing)).ToString()); 246 EXPECT_EQ("Updated, Need Reboot", 247 BoxedValue(new Stage(Stage::kUpdatedNeedReboot)).ToString()); 248 EXPECT_EQ("Reporting Error Event", 249 BoxedValue(new Stage(Stage::kReportingErrorEvent)).ToString()); 250 EXPECT_EQ("Attempting Rollback", 251 BoxedValue(new Stage(Stage::kAttemptingRollback)).ToString()); 252 } 253 254 TEST(UmBoxedValueTest, DeleterMarkerToString) { 255 bool marker = false; 256 BoxedValue value = BoxedValue(new DeleterMarker(&marker)); 257 EXPECT_EQ("DeleterMarker:false", value.ToString()); 258 marker = true; 259 EXPECT_EQ("DeleterMarker:true", value.ToString()); 260 } 261 262 TEST(UmBoxedValueTest, UpdateRestrictionsToString) { 263 EXPECT_EQ( 264 "None", 265 BoxedValue(new UpdateRestrictions(UpdateRestrictions::kNone)).ToString()); 266 EXPECT_EQ("Flags: RestrictDownloading", 267 BoxedValue(new UpdateRestrictions( 268 UpdateRestrictions::kRestrictDownloading)) 269 .ToString()); 270 } 271 272 TEST(UmBoxedValueTest, WeeklyTimeIntervalToString) { 273 EXPECT_EQ("Start: day_of_week=2 time=100\nEnd: day_of_week=4 time=200", 274 BoxedValue(new WeeklyTimeInterval( 275 WeeklyTime(2, TimeDelta::FromMinutes(100)), 276 WeeklyTime(4, TimeDelta::FromMinutes(200)))) 277 .ToString()); 278 EXPECT_EQ("Start: day_of_week=1 time=10\nEnd: day_of_week=1 time=20", 279 BoxedValue(new WeeklyTimeInterval( 280 WeeklyTime(1, TimeDelta::FromMinutes(10)), 281 WeeklyTime(1, TimeDelta::FromMinutes(20)))) 282 .ToString()); 283 } 284 285 TEST(UmBoxedValueTest, WeeklyTimeIntervalVectorToString) { 286 WeeklyTimeIntervalVector intervals; 287 intervals.emplace_back(WeeklyTime(5, TimeDelta::FromMinutes(10)), 288 WeeklyTime(1, TimeDelta::FromMinutes(30))); 289 EXPECT_EQ( 290 "Disallowed intervals:\nStart: day_of_week=5 time=10\nEnd: " 291 "day_of_week=1 time=30\n", 292 BoxedValue(new WeeklyTimeIntervalVector(intervals)).ToString()); 293 intervals.emplace_back(WeeklyTime(1, TimeDelta::FromMinutes(5)), 294 WeeklyTime(6, TimeDelta::FromMinutes(1000))); 295 EXPECT_EQ( 296 "Disallowed intervals:\nStart: day_of_week=5 time=10\nEnd: " 297 "day_of_week=1 time=30\nStart: day_of_week=1 time=5\nEnd: day_of_week=6 " 298 "time=1000\n", 299 BoxedValue(new WeeklyTimeIntervalVector(intervals)).ToString()); 300 } 301 302 } // namespace chromeos_update_manager 303