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( 172 "cellular", 173 BoxedValue(new ConnectionType(ConnectionType::kCellular)).ToString()); 174 EXPECT_EQ( 175 "Unknown", 176 BoxedValue(new ConnectionType(ConnectionType::kUnknown)).ToString()); 177 } 178 179 TEST(UmBoxedValueTest, ConnectionTetheringToString) { 180 EXPECT_EQ( 181 "Not Detected", 182 BoxedValue(new ConnectionTethering(ConnectionTethering::kNotDetected)) 183 .ToString()); 184 EXPECT_EQ("Suspected", 185 BoxedValue(new ConnectionTethering(ConnectionTethering::kSuspected)) 186 .ToString()); 187 EXPECT_EQ("Confirmed", 188 BoxedValue(new ConnectionTethering(ConnectionTethering::kConfirmed)) 189 .ToString()); 190 EXPECT_EQ("Unknown", 191 BoxedValue(new ConnectionTethering(ConnectionTethering::kUnknown)) 192 .ToString()); 193 } 194 195 TEST(UmBoxedValueTest, RollbackToTargetVersionToString) { 196 EXPECT_EQ("Unspecified", 197 BoxedValue(new RollbackToTargetVersion( 198 RollbackToTargetVersion::kUnspecified)) 199 .ToString()); 200 EXPECT_EQ("Disabled", 201 BoxedValue( 202 new RollbackToTargetVersion(RollbackToTargetVersion::kDisabled)) 203 .ToString()); 204 EXPECT_EQ("Rollback and powerwash", 205 BoxedValue(new RollbackToTargetVersion( 206 RollbackToTargetVersion::kRollbackAndPowerwash)) 207 .ToString()); 208 EXPECT_EQ( 209 "Rollback and restore if possible", 210 BoxedValue(new RollbackToTargetVersion( 211 RollbackToTargetVersion::kRollbackAndRestoreIfPossible)) 212 .ToString()); 213 } 214 215 TEST(UmBoxedValueTest, SetConnectionTypeToString) { 216 set<ConnectionType>* set1 = new set<ConnectionType>; 217 set1->insert(ConnectionType::kCellular); 218 set1->insert(ConnectionType::kEthernet); 219 EXPECT_EQ("ethernet,cellular", BoxedValue(set1).ToString()); 220 221 set<ConnectionType>* set2 = new set<ConnectionType>; 222 set2->insert(ConnectionType::kWifi); 223 EXPECT_EQ("wifi", BoxedValue(set2).ToString()); 224 } 225 226 TEST(UmBoxedValueTest, StageToString) { 227 EXPECT_EQ("Idle", BoxedValue(new Stage(Stage::kIdle)).ToString()); 228 EXPECT_EQ("Checking For Update", 229 BoxedValue(new Stage(Stage::kCheckingForUpdate)).ToString()); 230 EXPECT_EQ("Update Available", 231 BoxedValue(new Stage(Stage::kUpdateAvailable)).ToString()); 232 EXPECT_EQ("Downloading", 233 BoxedValue(new Stage(Stage::kDownloading)).ToString()); 234 EXPECT_EQ("Verifying", BoxedValue(new Stage(Stage::kVerifying)).ToString()); 235 EXPECT_EQ("Finalizing", BoxedValue(new Stage(Stage::kFinalizing)).ToString()); 236 EXPECT_EQ("Updated, Need Reboot", 237 BoxedValue(new Stage(Stage::kUpdatedNeedReboot)).ToString()); 238 EXPECT_EQ("Reporting Error Event", 239 BoxedValue(new Stage(Stage::kReportingErrorEvent)).ToString()); 240 EXPECT_EQ("Attempting Rollback", 241 BoxedValue(new Stage(Stage::kAttemptingRollback)).ToString()); 242 } 243 244 TEST(UmBoxedValueTest, DeleterMarkerToString) { 245 bool marker = false; 246 BoxedValue value = BoxedValue(new DeleterMarker(&marker)); 247 EXPECT_EQ("DeleterMarker:false", value.ToString()); 248 marker = true; 249 EXPECT_EQ("DeleterMarker:true", value.ToString()); 250 } 251 252 TEST(UmBoxedValueTest, UpdateRestrictionsToString) { 253 EXPECT_EQ( 254 "None", 255 BoxedValue(new UpdateRestrictions(UpdateRestrictions::kNone)).ToString()); 256 EXPECT_EQ("Flags: RestrictDownloading", 257 BoxedValue(new UpdateRestrictions( 258 UpdateRestrictions::kRestrictDownloading)) 259 .ToString()); 260 } 261 262 TEST(UmBoxedValueTest, WeeklyTimeIntervalToString) { 263 EXPECT_EQ("Start: day_of_week=2 time=100\nEnd: day_of_week=4 time=200", 264 BoxedValue(new WeeklyTimeInterval( 265 WeeklyTime(2, TimeDelta::FromMinutes(100)), 266 WeeklyTime(4, TimeDelta::FromMinutes(200)))) 267 .ToString()); 268 EXPECT_EQ("Start: day_of_week=1 time=10\nEnd: day_of_week=1 time=20", 269 BoxedValue(new WeeklyTimeInterval( 270 WeeklyTime(1, TimeDelta::FromMinutes(10)), 271 WeeklyTime(1, TimeDelta::FromMinutes(20)))) 272 .ToString()); 273 } 274 275 TEST(UmBoxedValueTest, WeeklyTimeIntervalVectorToString) { 276 WeeklyTimeIntervalVector intervals; 277 intervals.emplace_back(WeeklyTime(5, TimeDelta::FromMinutes(10)), 278 WeeklyTime(1, TimeDelta::FromMinutes(30))); 279 EXPECT_EQ( 280 "Disallowed intervals:\nStart: day_of_week=5 time=10\nEnd: " 281 "day_of_week=1 time=30\n", 282 BoxedValue(new WeeklyTimeIntervalVector(intervals)).ToString()); 283 intervals.emplace_back(WeeklyTime(1, TimeDelta::FromMinutes(5)), 284 WeeklyTime(6, TimeDelta::FromMinutes(1000))); 285 EXPECT_EQ( 286 "Disallowed intervals:\nStart: day_of_week=5 time=10\nEnd: " 287 "day_of_week=1 time=30\nStart: day_of_week=1 time=5\nEnd: day_of_week=6 " 288 "time=1000\n", 289 BoxedValue(new WeeklyTimeIntervalVector(intervals)).ToString()); 290 } 291 292 } // namespace chromeos_update_manager 293