update_engine: Add Update Time Restrictions
Implementation for the update time restrictions policy where the admin
is allowed to choose time interval in which updates will not be checked.
- Adds WeeklyTime and WeeklyTimeInterval classes to update_engine to be
able to easily do interval range checking and time operations easily in
the policy. Added the wiring so the classes can be used as Values and
BoxedValues.
- Adds disallowed_intervals member to device_policy_provider, since this
contains the policy dictated disallowed intervals. The intervals are
obtained from libpolicy, a function was added to convert them to the
new WeeklyTime classes. Added the corresponding changes to the device
policy provider header and interface.
- Added the policy to chromeos_policy.cc so that it's taken into account
in UpdateCheckAllowed.
BUG=chromium:852860
TEST=cros_workon_make update_engine --test
Change-Id: If62a2b3650adf149ba87790345e1eb62f0e1bb1f
Reviewed-on: https://chromium-review.googlesource.com/1119397
Commit-Ready: Adolfo Higueros <adokar@google.com>
Tested-by: Adolfo Higueros <adokar@google.com>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
diff --git a/update_manager/weekly_time_unittest.cc b/update_manager/weekly_time_unittest.cc
new file mode 100644
index 0000000..52c5425
--- /dev/null
+++ b/update_manager/weekly_time_unittest.cc
@@ -0,0 +1,212 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#include "update_engine/update_manager/weekly_time.h"
+
+#include <tuple>
+
+#include <base/time/time.h>
+#include <gtest/gtest.h>
+
+using base::TimeDelta;
+using std::tuple;
+
+namespace chromeos_update_manager {
+
+namespace {
+
+enum {
+ kSunday = 0,
+ kMonday,
+ kTuesday,
+ kWednesday,
+ kThursday,
+ kFriday,
+ kSaturday
+};
+
+} // namespace
+
+class WeeklyTimeDurationTest
+ : public testing::TestWithParam<tuple<int /* start_day_of_week */,
+ TimeDelta /* start_time */,
+ int /* end_day_of_week */,
+ TimeDelta /* end_time */,
+ TimeDelta /* expected result */>> {
+ protected:
+ int start_day_of_week() { return std::get<0>(GetParam()); }
+ TimeDelta start_time() { return std::get<1>(GetParam()); }
+ int end_day_of_week() { return std::get<2>(GetParam()); }
+ TimeDelta end_time() { return std::get<3>(GetParam()); }
+ TimeDelta result() { return std::get<4>(GetParam()); }
+};
+
+TEST_P(WeeklyTimeDurationTest, GetDurationTo) {
+ WeeklyTime start = WeeklyTime(start_day_of_week(), start_time());
+ WeeklyTime end = WeeklyTime(end_day_of_week(), end_time());
+
+ EXPECT_EQ(result(), start.GetDurationTo(end));
+}
+
+INSTANTIATE_TEST_CASE_P(
+ SameMinutes,
+ WeeklyTimeDurationTest,
+ testing::Values(std::make_tuple(kThursday,
+ TimeDelta::FromMinutes(30),
+ kSaturday,
+ TimeDelta::FromMinutes(30),
+ TimeDelta::FromDays(2))));
+
+INSTANTIATE_TEST_CASE_P(
+ DifferentMinutes,
+ WeeklyTimeDurationTest,
+ testing::Values(std::make_tuple(kMonday,
+ TimeDelta::FromMinutes(10),
+ kWednesday,
+ TimeDelta::FromMinutes(30),
+ TimeDelta::FromDays(2) +
+ TimeDelta::FromMinutes(20))));
+
+INSTANTIATE_TEST_CASE_P(
+ EndLessThanStartSameMinutes,
+ WeeklyTimeDurationTest,
+ testing::Values(std::make_tuple(kSaturday,
+ TimeDelta::FromMinutes(100),
+ kTuesday,
+ TimeDelta::FromMinutes(100),
+ TimeDelta::FromDays(3))));
+
+INSTANTIATE_TEST_CASE_P(
+ EndLessThanStartDifferentMinutes,
+ WeeklyTimeDurationTest,
+ testing::Values(std::make_tuple(kSaturday,
+ TimeDelta::FromMinutes(150),
+ kMonday,
+ TimeDelta::FromMinutes(10),
+ TimeDelta::FromDays(2) -
+ TimeDelta::FromMinutes(140))));
+
+class WeeklyTimeOffsetTest
+ : public testing::TestWithParam<tuple<int /* day_of_week */,
+ TimeDelta /* time */,
+ TimeDelta /* offset */,
+ WeeklyTime /* expected result */>> {
+ protected:
+ int day_of_week() { return std::get<0>(GetParam()); }
+ TimeDelta time() { return std::get<1>(GetParam()); }
+ TimeDelta offset() { return std::get<2>(GetParam()); }
+ WeeklyTime result() { return std::get<3>(GetParam()); }
+};
+
+TEST_P(WeeklyTimeOffsetTest, WeekTimeAddTime) {
+ WeeklyTime test_time = WeeklyTime(day_of_week(), time());
+ test_time.AddTime(offset());
+
+ EXPECT_EQ(result(), test_time);
+}
+
+INSTANTIATE_TEST_CASE_P(
+ SameDayTest,
+ WeeklyTimeOffsetTest,
+ testing::Values(std::make_tuple(kTuesday,
+ TimeDelta::FromMinutes(200),
+ TimeDelta::FromMinutes(400),
+ WeeklyTime(kTuesday,
+ TimeDelta::FromMinutes(600)))));
+
+INSTANTIATE_TEST_CASE_P(DayChangeTest,
+ WeeklyTimeOffsetTest,
+ testing::Values(std::make_tuple(
+ kThursday,
+ TimeDelta::FromHours(23),
+ TimeDelta::FromHours(2),
+ WeeklyTime(kFriday, TimeDelta::FromHours(1)))));
+
+INSTANTIATE_TEST_CASE_P(DayChangeTestOver7,
+ WeeklyTimeOffsetTest,
+ testing::Values(std::make_tuple(
+ kSunday,
+ TimeDelta::FromHours(20),
+ TimeDelta::FromDays(3),
+ WeeklyTime(kWednesday, TimeDelta::FromHours(20)))));
+
+class WeeklyTimeIntervalRangeTest
+ : public testing::TestWithParam<tuple<int /* test_day_of_week */,
+ int /* test_time */,
+ bool /* in regular interval */,
+ bool /* in short interval */,
+ bool /* |start| < | */>> {
+ protected:
+ int day_of_week() { return std::get<0>(GetParam()); }
+ int minutes() { return std::get<1>(GetParam()); }
+ bool regular_result() { return std::get<2>(GetParam()); }
+ bool short_result() { return std::get<3>(GetParam()); }
+ bool wraparound_result() { return std::get<4>(GetParam()); }
+};
+
+TEST_P(WeeklyTimeIntervalRangeTest, InRange) {
+ WeeklyTime test =
+ WeeklyTime(day_of_week(), TimeDelta::FromMinutes(minutes()));
+ WeeklyTimeInterval interval_regular =
+ WeeklyTimeInterval(WeeklyTime(kMonday, TimeDelta::FromMinutes(10)),
+ WeeklyTime(kWednesday, TimeDelta::FromMinutes(30)));
+ WeeklyTimeInterval interval_short =
+ WeeklyTimeInterval(WeeklyTime(kThursday, TimeDelta::FromMinutes(10)),
+ WeeklyTime(kThursday, TimeDelta::FromMinutes(11)));
+
+ WeeklyTimeInterval interval_wraparound =
+ WeeklyTimeInterval(WeeklyTime(kFriday, TimeDelta::FromMinutes(10)),
+ WeeklyTime(kTuesday, TimeDelta::FromMinutes(30)));
+
+ EXPECT_EQ(regular_result(), interval_regular.InRange(test));
+ EXPECT_EQ(short_result(), interval_short.InRange(test));
+ EXPECT_EQ(wraparound_result(), interval_wraparound.InRange(test));
+}
+
+// Test the left side of the range being inclusive.
+INSTANTIATE_TEST_CASE_P(
+ InclusiveSuccessLeft,
+ WeeklyTimeIntervalRangeTest,
+ testing::Values(std::make_tuple(kThursday, 10, false, true, false)));
+
+// Test the right side of the range being exclusive.
+INSTANTIATE_TEST_CASE_P(
+ ExclusiveSuccessRight,
+ WeeklyTimeIntervalRangeTest,
+ testing::Values(std::make_tuple(kThursday, 11, false, false, false)));
+
+// Test falling out of the interval by a small amount.
+INSTANTIATE_TEST_CASE_P(
+ FailOutsideRangeSmall,
+ WeeklyTimeIntervalRangeTest,
+ testing::Values(std::make_tuple(kThursday, 12, false, false, false)));
+
+// These test cases check that intervals wrap around properly.
+INSTANTIATE_TEST_CASE_P(
+ WraparoundOutside,
+ WeeklyTimeIntervalRangeTest,
+ testing::Values(std::make_tuple(kWednesday, 10, true, false, false)));
+
+INSTANTIATE_TEST_CASE_P(
+ WraparoundInsideRight,
+ WeeklyTimeIntervalRangeTest,
+ testing::Values(std::make_tuple(kSaturday, 10, false, false, true)));
+
+INSTANTIATE_TEST_CASE_P(
+ WraparoundInsideLeft,
+ WeeklyTimeIntervalRangeTest,
+ testing::Values(std::make_tuple(kMonday, 0, false, false, true)));
+
+} // namespace chromeos_update_manager