| /* |
| * 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. |
| */ |
| package com.android.server.devicepolicy; |
| |
| import static android.app.admin.SystemUpdatePolicy.ValidationFailedException.ERROR_COMBINED_FREEZE_PERIOD_TOO_CLOSE; |
| import static android.app.admin.SystemUpdatePolicy.ValidationFailedException.ERROR_COMBINED_FREEZE_PERIOD_TOO_LONG; |
| import static android.app.admin.SystemUpdatePolicy.ValidationFailedException.ERROR_DUPLICATE_OR_OVERLAP; |
| import static android.app.admin.SystemUpdatePolicy.ValidationFailedException.ERROR_NEW_FREEZE_PERIOD_TOO_CLOSE; |
| import static android.app.admin.SystemUpdatePolicy.ValidationFailedException.ERROR_NEW_FREEZE_PERIOD_TOO_LONG; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| |
| import android.app.admin.FreezeInterval; |
| import android.app.admin.SystemUpdatePolicy; |
| import android.os.Parcel; |
| import android.support.test.runner.AndroidJUnit4; |
| import android.util.Pair; |
| import android.util.Xml; |
| |
| import com.android.internal.util.FastXmlSerializer; |
| |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.xmlpull.v1.XmlPullParser; |
| import org.xmlpull.v1.XmlSerializer; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.InputStreamReader; |
| import java.nio.charset.StandardCharsets; |
| import java.time.LocalDate; |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.concurrent.TimeUnit; |
| |
| /** |
| * Unit tests for {@link android.app.admin.SystemUpdatePolicy}. |
| * Throughout this test, we use "MM-DD" format to denote dates without year. |
| * |
| * atest com.android.server.devicepolicy.SystemUpdatePolicyTest |
| * runtest -c com.android.server.devicepolicy.SystemUpdatePolicyTest frameworks-services |
| */ |
| @RunWith(AndroidJUnit4.class) |
| public final class SystemUpdatePolicyTest { |
| |
| private static final int DUPLICATE_OR_OVERLAP = ERROR_DUPLICATE_OR_OVERLAP; |
| private static final int TOO_LONG = ERROR_NEW_FREEZE_PERIOD_TOO_LONG; |
| private static final int TOO_CLOSE = ERROR_NEW_FREEZE_PERIOD_TOO_CLOSE; |
| private static final int COMBINED_TOO_LONG = ERROR_COMBINED_FREEZE_PERIOD_TOO_LONG; |
| private static final int COMBINED_TOO_CLOSE = ERROR_COMBINED_FREEZE_PERIOD_TOO_CLOSE; |
| |
| @Test |
| public void testSimplePeriod() throws Exception { |
| testFreezePeriodsSucceeds("01-01", "01-02"); |
| testFreezePeriodsSucceeds("01-31", "01-31"); |
| testFreezePeriodsSucceeds("11-01", "01-15"); |
| testFreezePeriodsSucceeds("02-01", "02-29"); // Leap year |
| testFreezePeriodsSucceeds("02-01", "03-01"); |
| testFreezePeriodsSucceeds("12-01", "01-30"); // Wrapped Period |
| testFreezePeriodsSucceeds("11-02", "01-30", "04-01", "04-30"); // Wrapped Period |
| } |
| |
| @Test |
| public void testCanonicalizationValidation() throws Exception { |
| testFreezePeriodsSucceeds("03-01", "03-31", "09-01", "09-30"); |
| testFreezePeriodsSucceeds("06-01", "07-01", "09-01", "09-30"); |
| testFreezePeriodsSucceeds("10-01", "10-31", "12-31", "01-31"); |
| testFreezePeriodsSucceeds("01-01", "01-30", "04-01", "04-30"); |
| testFreezePeriodsSucceeds("01-01", "02-28", "05-01", "06-30", "09-01", "10-31"); |
| |
| // One interval fully covers the other |
| testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "03-01", "03-31", "03-15", "03-31"); |
| testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "03-01", "03-31", "03-15", "03-16"); |
| testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "11-15", "01-31", "12-01", "12-31"); |
| testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "12-01", "01-31", "01-01", "01-15"); |
| |
| // Partial overlap |
| testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "03-01", "03-31", "03-15", "01-01"); |
| testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "11-15", "01-31", "12-01", "02-28"); |
| |
| // No gap between two intervals |
| testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "01-31", "01-31", "02-01", "02-01"); |
| testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "12-01", "12-15", "12-15", "02-01"); |
| testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "12-01", "12-15", "12-16", "02-01"); |
| testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "12-01", "01-15", "01-15", "02-01"); |
| testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "12-01", "01-15", "01-16", "02-01"); |
| testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "01-01", "01-30", "12-01", "12-31"); |
| testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "12-01", "12-31", "04-01", "04-01", |
| "01-01", "01-30"); |
| } |
| |
| @Test |
| public void testLengthValidation() throws Exception { |
| testFreezePeriodsSucceeds("03-01", "03-31"); |
| testFreezePeriodsSucceeds("03-03", "03-03", "12-31", "01-01"); |
| testFreezePeriodsSucceeds("01-01", "03-31", "06-01", "08-29"); |
| // entire year |
| testFreezePeriodsFails(TOO_LONG, "01-01", "12-31"); |
| // long period spanning across year end |
| testFreezePeriodsSucceeds("11-01", "01-29"); |
| testFreezePeriodsFails(TOO_LONG, "11-01", "01-30"); |
| // Leap year handling |
| testFreezePeriodsSucceeds("12-01", "02-28"); |
| testFreezePeriodsSucceeds("12-01", "02-29"); |
| testFreezePeriodsFails(TOO_LONG, "12-01", "03-01"); |
| // Regular long period |
| testFreezePeriodsSucceeds("01-01", "03-31", "06-01", "08-29"); |
| testFreezePeriodsFails(TOO_LONG, "01-01", "03-31", "06-01", "08-30"); |
| } |
| |
| @Test |
| public void testSeparationValidation() throws Exception { |
| testFreezePeriodsSucceeds("01-01", "03-31", "06-01", "08-29"); |
| testFreezePeriodsFails(TOO_CLOSE, "01-01", "01-01", "01-03", "01-03"); |
| testFreezePeriodsFails(TOO_CLOSE, "03-01", "03-31", "05-01", "05-31"); |
| // Short interval spans across end of year |
| testFreezePeriodsSucceeds("01-31", "03-01", "11-01", "12-01"); |
| testFreezePeriodsFails(TOO_CLOSE, "01-30", "03-01", "11-01", "12-01"); |
| // Short separation is after wrapped period |
| testFreezePeriodsSucceeds("03-03", "03-31", "12-31", "01-01"); |
| testFreezePeriodsFails(TOO_CLOSE, "03-02", "03-31", "12-31", "01-01"); |
| // Short separation including Feb 29 |
| testFreezePeriodsSucceeds("12-01", "01-15", "03-17", "04-01"); |
| testFreezePeriodsFails(TOO_CLOSE, "12-01", "01-15", "03-16", "04-01"); |
| // Short separation including Feb 29 |
| testFreezePeriodsSucceeds("01-01", "02-28", "04-30", "06-01"); |
| testFreezePeriodsSucceeds("01-01", "02-29", "04-30", "06-01"); |
| testFreezePeriodsFails(TOO_CLOSE, "01-01", "03-01", "04-30", "06-01"); |
| } |
| |
| @Test |
| public void testValidateTotalLengthWithPreviousPeriods() throws Exception { |
| testPrevFreezePeriodSucceeds("2018-01-19", "2018-01-19", /* now */"2018-01-19", |
| "07-01", "07-31", "10-01", "11-30"); |
| testPrevFreezePeriodSucceeds("2018-01-01", "2018-01-19", /* now */"2018-01-19", |
| "01-01", "03-30"); |
| testPrevFreezePeriodSucceeds("2018-01-01", "2018-02-01", /* now */"2018-02-01", |
| "11-01", "12-31"); |
| |
| testPrevFreezePeriodSucceeds("2017-11-01", "2018-01-02", /* now */"2018-01-02", |
| "01-01", "01-29"); |
| testPrevFreezePeriodFails(COMBINED_TOO_LONG, "2017-11-01", "2018-01-02", "2018-01-02", |
| "01-01", "01-30"); |
| testPrevFreezePeriodSucceeds("2017-11-01", "2018-01-02", /* now */"2018-01-01", |
| "01-02", "01-29"); |
| testPrevFreezePeriodFails(COMBINED_TOO_LONG, "2017-11-01", "2018-01-02", "2018-01-01", |
| "01-02", "01-30"); |
| |
| testPrevFreezePeriodSucceeds("2017-11-01", "2017-12-01", /* now */"2017-12-01", |
| "11-15", "01-29"); |
| testPrevFreezePeriodFails(COMBINED_TOO_LONG, "2017-11-01", "2017-12-01", "2017-12-01", |
| "11-15", "01-30"); |
| |
| testPrevFreezePeriodSucceeds("2017-11-01", "2018-01-01", /* now */"2018-01-01", |
| "11-15", "01-29"); |
| testPrevFreezePeriodFails(COMBINED_TOO_LONG, "2017-11-01", "2018-01-01", "2018-01-01", |
| "11-15", "01-30"); |
| |
| testPrevFreezePeriodSucceeds("2018-03-01", "2018-03-31", /* now */"2018-03-31", |
| "04-01", "05-29"); |
| testPrevFreezePeriodFails(COMBINED_TOO_LONG, "2018-03-01", "2018-03-31", "2018-03-31", |
| "04-01", "05-30"); |
| |
| // Leap year handing |
| testPrevFreezePeriodSucceeds("2017-12-01", "2018-01-02", /* now */"2018-01-02", |
| "01-01", "02-28"); |
| testPrevFreezePeriodSucceeds("2017-12-01", "2018-01-02", /* now */"2018-01-02", |
| "01-01", "02-29"); |
| testPrevFreezePeriodFails(COMBINED_TOO_LONG, "2017-12-01", "2018-01-02", "2018-01-02", |
| "01-01", "03-01"); |
| |
| testPrevFreezePeriodSucceeds("2016-01-01", "2016-02-28", /* now */"2016-02-28", |
| "02-01", "03-31"); |
| testPrevFreezePeriodSucceeds("2016-01-01", "2016-02-28", /* now */"2016-02-29", |
| "02-01", "03-31"); |
| testPrevFreezePeriodFails(COMBINED_TOO_LONG, "2016-01-01", "2016-02-28", "2016-02-29", |
| "02-01", "04-01"); |
| |
| } |
| |
| @Test |
| public void testValidateSeparationWithPreviousPeriods() throws Exception { |
| testPrevFreezePeriodSucceeds("2018-01-01", "2018-01-02", /* now */"2018-03-04", |
| "01-01", "03-30"); |
| testPrevFreezePeriodSucceeds("2018-01-01", "2018-01-02", /* now */"2018-01-19", |
| "04-01", "06-29"); |
| testPrevFreezePeriodSucceeds("2017-01-01", "2017-03-30", /* now */"2018-12-01", |
| "01-01", "03-30"); |
| |
| testPrevFreezePeriodSucceeds("2018-01-01", "2018-02-01", "2018-02-01", |
| "04-03", "06-01"); |
| testPrevFreezePeriodFails(COMBINED_TOO_CLOSE, "2018-01-01", "2018-02-01", "2018-02-01", |
| "04-02", "06-01"); |
| |
| testPrevFreezePeriodSucceeds("2018-04-01", "2018-06-01", "2018-08-01", |
| "07-01", "08-30"); |
| testPrevFreezePeriodFails(COMBINED_TOO_CLOSE, "2018-04-01", "2018-06-01", "2018-07-30", |
| "07-01", "08-30"); |
| |
| |
| testPrevFreezePeriodSucceeds("2018-03-01", "2018-04-01", "2018-06-01", |
| "05-01", "07-01"); |
| testPrevFreezePeriodFails(COMBINED_TOO_CLOSE, "2018-03-01", "2018-04-01", "2018-05-31", |
| "05-01", "07-01"); |
| } |
| |
| @Test |
| public void testDistanceWithoutLeapYear() { |
| assertEquals(364, FreezeInterval.distanceWithoutLeapYear( |
| LocalDate.of(2016, 12, 31), LocalDate.of(2016, 1, 1))); |
| assertEquals(365, FreezeInterval.distanceWithoutLeapYear( |
| LocalDate.of(2017, 1, 1), LocalDate.of(2016, 1, 1))); |
| assertEquals(365, FreezeInterval.distanceWithoutLeapYear( |
| LocalDate.of(2017, 2, 28), LocalDate.of(2016, 2, 29))); |
| assertEquals(-365, FreezeInterval.distanceWithoutLeapYear( |
| LocalDate.of(2016, 1, 1), LocalDate.of(2017, 1, 1))); |
| assertEquals(1, FreezeInterval.distanceWithoutLeapYear( |
| LocalDate.of(2016, 3, 1), LocalDate.of(2016, 2, 29))); |
| assertEquals(1, FreezeInterval.distanceWithoutLeapYear( |
| LocalDate.of(2016, 3, 1), LocalDate.of(2016, 2, 28))); |
| assertEquals(0, FreezeInterval.distanceWithoutLeapYear( |
| LocalDate.of(2016, 2, 29), LocalDate.of(2016, 2, 28))); |
| assertEquals(0, FreezeInterval.distanceWithoutLeapYear( |
| LocalDate.of(2016, 2, 28), LocalDate.of(2016, 2, 28))); |
| |
| assertEquals(59, FreezeInterval.distanceWithoutLeapYear( |
| LocalDate.of(2016, 3, 1), LocalDate.of(2016, 1, 1))); |
| assertEquals(59, FreezeInterval.distanceWithoutLeapYear( |
| LocalDate.of(2017, 3, 1), LocalDate.of(2017, 1, 1))); |
| |
| assertEquals(365 * 40, FreezeInterval.distanceWithoutLeapYear( |
| LocalDate.of(2040, 1, 1), LocalDate.of(2000, 1, 1))); |
| |
| assertEquals(365 * 2, FreezeInterval.distanceWithoutLeapYear( |
| LocalDate.of(2019, 3, 1), LocalDate.of(2017, 3, 1))); |
| assertEquals(365 * 2, FreezeInterval.distanceWithoutLeapYear( |
| LocalDate.of(2018, 3, 1), LocalDate.of(2016, 3, 1))); |
| assertEquals(365 * 2, FreezeInterval.distanceWithoutLeapYear( |
| LocalDate.of(2017, 3, 1), LocalDate.of(2015, 3, 1))); |
| |
| } |
| |
| @Test |
| public void testInstallationOptionWithoutFreeze() { |
| // Also duplicated at com.google.android.gts.deviceowner.SystemUpdatePolicyTest |
| final long millis_2018_01_01 = TimeUnit.SECONDS.toMillis(1514764800); |
| |
| SystemUpdatePolicy p = SystemUpdatePolicy.createAutomaticInstallPolicy(); |
| assertInstallationOption(SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, Long.MAX_VALUE, |
| millis_2018_01_01, p); |
| |
| p = SystemUpdatePolicy.createPostponeInstallPolicy(); |
| assertInstallationOption(SystemUpdatePolicy.TYPE_POSTPONE, Long.MAX_VALUE, |
| millis_2018_01_01, p); |
| |
| p = SystemUpdatePolicy.createWindowedInstallPolicy(120, 180); // 2:00 - 3:00 |
| // 00:00 is two hours before the next window |
| assertInstallationOption(SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.HOURS.toMillis(2), |
| millis_2018_01_01, p); |
| // 02:00 is within the current maintenance window, and one hour until the window ends |
| assertInstallationOption( |
| SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.HOURS.toMillis(1), |
| millis_2018_01_01 + TimeUnit.HOURS.toMillis(2), p); |
| // 04:00 is 22 hours from the window next day |
| assertInstallationOption(SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.HOURS.toMillis(22), |
| millis_2018_01_01 + TimeUnit.HOURS.toMillis(4), p); |
| |
| p = SystemUpdatePolicy.createWindowedInstallPolicy(22 * 60, 2 * 60); // 22:00 - 2:00 |
| // 21:00 is one hour from the next window |
| assertInstallationOption(SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.HOURS.toMillis(1), |
| millis_2018_01_01 + TimeUnit.HOURS.toMillis(21), p); |
| // 00:00 is two hours from the end of current window |
| assertInstallationOption( |
| SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.HOURS.toMillis(2), |
| millis_2018_01_01, p); |
| // 03:00 is 22 hours from the window today |
| assertInstallationOption(SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.HOURS.toMillis(19), |
| millis_2018_01_01 + TimeUnit.HOURS.toMillis(3), p); |
| } |
| |
| @Test |
| public void testInstallationOptionWithFreeze() throws Exception { |
| final long millis_2016_02_29 = TimeUnit.SECONDS.toMillis(1456704000); |
| final long millis_2017_01_31 = TimeUnit.SECONDS.toMillis(1485820800); |
| final long millis_2017_02_28 = TimeUnit.SECONDS.toMillis(1488240000); |
| final long millis_2018_01_01 = TimeUnit.SECONDS.toMillis(1514764800); |
| final long millis_2018_08_01 = TimeUnit.SECONDS.toMillis(1533081600); |
| |
| SystemUpdatePolicy p = SystemUpdatePolicy.createAutomaticInstallPolicy(); |
| setFreezePeriods(p, "01-01", "01-31"); |
| // Inside a freeze period |
| assertInstallationOption( |
| SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(31), |
| millis_2018_01_01, p); |
| // Device is outside freeze between 2/28 to 12/31 inclusive |
| assertInstallationOption( |
| SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.DAYS.toMillis(307), |
| millis_2017_02_28, p); |
| |
| // Freeze period contains leap day Feb 29 |
| p = SystemUpdatePolicy.createPostponeInstallPolicy(); |
| setFreezePeriods(p, "02-01", "03-15"); |
| // Freezed until 3/31, note 2016 is a leap year |
| assertInstallationOption(SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(16), |
| millis_2016_02_29, p); |
| // Freezed until 3/31, note 2017 is not a leap year |
| assertInstallationOption(SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(16), |
| millis_2017_02_28, p); |
| // Next freeze is 2018/2/1 |
| assertInstallationOption(SystemUpdatePolicy.TYPE_POSTPONE, TimeUnit.DAYS.toMillis(31), |
| millis_2018_01_01, p); |
| |
| // Freeze period start on or right after leap day |
| p = SystemUpdatePolicy.createAutomaticInstallPolicy(); |
| setFreezePeriods(p, "03-01", "03-31"); |
| assertInstallationOption( |
| SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.DAYS.toMillis(1), |
| millis_2016_02_29, p); |
| assertInstallationOption( |
| SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.DAYS.toMillis(1), |
| millis_2017_02_28, p); |
| setFreezePeriods(p, "02-28", "03-15"); |
| assertInstallationOption( |
| SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(16), |
| millis_2016_02_29, p); |
| assertInstallationOption( |
| SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(16), |
| millis_2017_02_28, p); |
| |
| // Freeze period end on or right after leap day |
| p = SystemUpdatePolicy.createAutomaticInstallPolicy(); |
| setFreezePeriods(p, "02-01", "02-28"); |
| assertInstallationOption( |
| SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(1), |
| millis_2016_02_29, p); |
| assertInstallationOption( |
| SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(1), |
| millis_2017_02_28, p); |
| p = SystemUpdatePolicy.createAutomaticInstallPolicy(); |
| setFreezePeriods(p, "02-01", "03-01"); |
| assertInstallationOption( |
| SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(2), |
| millis_2016_02_29, p); |
| assertInstallationOption( |
| SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(2), |
| millis_2017_02_28, p); |
| |
| // Freeze period with maintenance window |
| p = SystemUpdatePolicy.createWindowedInstallPolicy(23 * 60, 1 * 60); // 23:00 - 1:00 |
| setFreezePeriods(p, "02-01", "02-28"); |
| // 00:00 is within the current window, outside freeze period |
| assertInstallationOption( |
| SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.HOURS.toMillis(1), |
| millis_2018_01_01, p); |
| // Last day of feeze period, which ends in 22 hours |
| assertInstallationOption( |
| SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.HOURS.toMillis(22), |
| millis_2017_02_28 + TimeUnit.HOURS.toMillis(2), p); |
| // Last day before the next freeze, and within window |
| assertInstallationOption( |
| SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.HOURS.toMillis(1), |
| millis_2017_01_31, p); |
| // Last day before the next freeze, and there is still a partial maintenance window before |
| // the freeze. |
| assertInstallationOption( |
| SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.HOURS.toMillis(19), |
| millis_2017_01_31 + TimeUnit.HOURS.toMillis(4), p); |
| |
| // Two freeze periods |
| p = SystemUpdatePolicy.createAutomaticInstallPolicy(); |
| setFreezePeriods(p, "05-01", "06-01", "12-01", "01-31"); |
| // automatic policy for August, September, November and December |
| assertInstallationOption( |
| SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.DAYS.toMillis(122), |
| millis_2018_08_01, p); |
| } |
| |
| private void assertInstallationOption(int expectedType, long expectedTime, long now, |
| SystemUpdatePolicy p) { |
| assertEquals(expectedType, p.getInstallationOptionAt(now).getType()); |
| assertEquals(expectedTime, p.getInstallationOptionAt(now).getEffectiveTime()); |
| } |
| |
| private void testFreezePeriodsSucceeds(String...dates) throws Exception { |
| SystemUpdatePolicy p = SystemUpdatePolicy.createPostponeInstallPolicy(); |
| setFreezePeriods(p, dates); |
| } |
| |
| private void testFreezePeriodsFails(int expectedError, String... dates) throws Exception { |
| SystemUpdatePolicy p = SystemUpdatePolicy.createPostponeInstallPolicy(); |
| try { |
| setFreezePeriods(p, dates); |
| fail("Invalid periods (" + expectedError + ") not flagged: " + String.join(" ", dates)); |
| } catch (SystemUpdatePolicy.ValidationFailedException e) { |
| assertTrue("Exception not expected: " + e.getMessage(), |
| e.getErrorCode() == expectedError); |
| } |
| } |
| |
| private void testPrevFreezePeriodSucceeds(String prevStart, String prevEnd, String now, |
| String... dates) throws Exception { |
| createPrevFreezePeriod(prevStart, prevEnd, now, dates); |
| } |
| |
| private void testPrevFreezePeriodFails(int expectedError, String prevStart, String prevEnd, |
| String now, String... dates) throws Exception { |
| try { |
| createPrevFreezePeriod(prevStart, prevEnd, now, dates); |
| fail("Invalid period (" + expectedError + ") not flagged: " + String.join(" ", dates)); |
| } catch (SystemUpdatePolicy.ValidationFailedException e) { |
| assertTrue("Exception not expected: " + e.getMessage(), |
| e.getErrorCode() == expectedError); |
| } |
| } |
| |
| private void createPrevFreezePeriod(String prevStart, String prevEnd, String now, |
| String... dates) throws Exception { |
| SystemUpdatePolicy p = SystemUpdatePolicy.createPostponeInstallPolicy(); |
| setFreezePeriods(p, dates); |
| p.validateAgainstPreviousFreezePeriod(parseDate(prevStart), parseDate(prevEnd), |
| parseDate(now)); |
| } |
| |
| // "MM-DD" format for date |
| private void setFreezePeriods(SystemUpdatePolicy policy, String... dates) throws Exception { |
| List<Pair<Integer, Integer>> periods = new ArrayList<>(); |
| LocalDate lastDate = null; |
| for (String date : dates) { |
| LocalDate currentDate = parseDate(date); |
| if (lastDate != null) { |
| periods.add(new Pair<>(lastDate.getDayOfYear(), currentDate.getDayOfYear())); |
| lastDate = null; |
| } else { |
| lastDate = currentDate; |
| } |
| } |
| policy.setFreezePeriods(periods); |
| testSerialization(policy, periods); |
| } |
| |
| private void testSerialization(SystemUpdatePolicy policy, |
| List<Pair<Integer, Integer>> expectedPeriods) throws Exception { |
| // Test parcel / unparcel |
| Parcel parcel = Parcel.obtain(); |
| policy.writeToParcel(parcel, 0); |
| parcel.setDataPosition(0); |
| SystemUpdatePolicy q = SystemUpdatePolicy.CREATOR.createFromParcel(parcel); |
| checkFreezePeriods(q, expectedPeriods); |
| parcel.recycle(); |
| |
| // Test XML serialization |
| ByteArrayOutputStream outStream = new ByteArrayOutputStream(); |
| final XmlSerializer outXml = new FastXmlSerializer(); |
| outXml.setOutput(outStream, StandardCharsets.UTF_8.name()); |
| outXml.startDocument(null, true); |
| outXml.startTag(null, "ota"); |
| policy.saveToXml(outXml); |
| outXml.endTag(null, "ota"); |
| outXml.endDocument(); |
| outXml.flush(); |
| |
| ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray()); |
| XmlPullParser parser = Xml.newPullParser(); |
| parser.setInput(new InputStreamReader(inStream)); |
| assertEquals(XmlPullParser.START_TAG, parser.next()); |
| checkFreezePeriods(SystemUpdatePolicy.restoreFromXml(parser), expectedPeriods); |
| } |
| |
| private void checkFreezePeriods(SystemUpdatePolicy policy, |
| List<Pair<Integer, Integer>> expectedPeriods) { |
| int i = 0; |
| for (Pair<Integer, Integer> period : policy.getFreezePeriods()) { |
| assertEquals(expectedPeriods.get(i).first, period.first); |
| assertEquals(expectedPeriods.get(i).second, period.second); |
| i++; |
| } |
| } |
| |
| private LocalDate parseDate(String date) { |
| // Use leap year when parsing date string to handle "02-29", but force round down |
| // to Feb 28th by overriding the year to non-leap year. |
| final int year; |
| boolean monthDateOnly = false; |
| if (date.length() == 5) { |
| year = 2000; |
| monthDateOnly = true; |
| } else { |
| year = Integer.parseInt(date.substring(0, 4)); |
| date = date.substring(5); |
| } |
| LocalDate result = LocalDate.of(year, Integer.parseInt(date.substring(0, 2)), |
| Integer.parseInt(date.substring(3, 5))); |
| if (monthDateOnly) { |
| return result.withYear(2001); |
| } else { |
| return result; |
| } |
| } |
| } |