Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b9f46d32 authored by Neil Fuller's avatar Neil Fuller Committed by Automerger Merge Worker
Browse files

Merge "Add command line support for testing tz detection" into rvc-dev am:...

Merge "Add command line support for testing tz detection" into rvc-dev am: 278c7083 am: 0b210196

Change-Id: Ieeef7f8a93ab6855321b4448cde02c3385afeece
parents 2fe503f8 0b210196
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -20,7 +20,9 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.ShellCommand;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -127,4 +129,32 @@ public final class ManualTimeZoneSuggestion implements Parcelable {
                + ", mDebugInfo=" + mDebugInfo
                + '}';
    }

    /** @hide */
    public static ManualTimeZoneSuggestion parseCommandLineArg(@NonNull ShellCommand cmd) {
        String zoneId = null;
        String opt;
        while ((opt = cmd.getNextArg()) != null) {
            switch (opt) {
                case "--zone_id": {
                    zoneId = cmd.getNextArgRequired();
                    break;
                }
                default: {
                    throw new IllegalArgumentException("Unknown option: " + opt);
                }
            }
        }
        ManualTimeZoneSuggestion suggestion = new ManualTimeZoneSuggestion(zoneId);
        suggestion.addDebugInfo("Command line injection");
        return suggestion;
    }

    /** @hide */
    public static void printCommandLineOpts(@NonNull PrintWriter pw) {
        pw.println("Manual suggestion options:");
        pw.println("  --zone_id <Olson ID>");
        pw.println();
        pw.println("See " + ManualTimeZoneSuggestion.class.getName() + " for more information");
    }
}
+95 −0
Original line number Diff line number Diff line
@@ -21,7 +21,10 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.ShellCommand;
import android.text.TextUtils;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -392,4 +395,96 @@ public final class TelephonyTimeZoneSuggestion implements Parcelable {
            return new TelephonyTimeZoneSuggestion(this);
        }
    }

    /** @hide */
    public static TelephonyTimeZoneSuggestion parseCommandLineArg(@NonNull ShellCommand cmd)
            throws IllegalArgumentException {
        Integer slotIndex = null;
        String zoneId = null;
        Integer quality = null;
        Integer matchType = null;
        String opt;
        while ((opt = cmd.getNextArg()) != null) {
            switch (opt) {
                case "--slot_index": {
                    slotIndex = Integer.parseInt(cmd.getNextArgRequired());
                    break;
                }
                case "--zone_id": {
                    zoneId = cmd.getNextArgRequired();
                    break;
                }
                case "--quality": {
                    quality = parseQualityCommandLineArg(cmd.getNextArgRequired());
                    break;
                }
                case "--match_type": {
                    matchType = parseMatchTypeCommandLineArg(cmd.getNextArgRequired());
                    break;
                }
                default: {
                    throw new IllegalArgumentException("Unknown option: " + opt);
                }
            }
        }

        if (slotIndex == null) {
            throw new IllegalArgumentException("No slotIndex specified.");
        }

        Builder builder = new Builder(slotIndex);
        if (!(TextUtils.isEmpty(zoneId) || "_".equals(zoneId))) {
            builder.setZoneId(zoneId);
        }
        if (quality != null) {
            builder.setQuality(quality);
        }
        if (matchType != null) {
            builder.setMatchType(matchType);
        }
        builder.addDebugInfo("Command line injection");
        return builder.build();
    }

    private static int parseQualityCommandLineArg(@NonNull String arg) {
        switch (arg) {
            case "single":
                return QUALITY_SINGLE_ZONE;
            case "multiple_same":
                return QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET;
            case "multiple_different":
                return QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS;
            default:
                throw new IllegalArgumentException("Unrecognized quality: " + arg);
        }
    }

    private static int parseMatchTypeCommandLineArg(@NonNull String arg) {
        switch (arg) {
            case "emulator":
                return MATCH_TYPE_EMULATOR_ZONE_ID;
            case "country_with_offset":
                return MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET;
            case "country":
                return MATCH_TYPE_NETWORK_COUNTRY_ONLY;
            case "test_network":
                return MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY;
            default:
                throw new IllegalArgumentException("Unrecognized match_type: " + arg);
        }
    }

    /** @hide */
    public static void printCommandLineOpts(@NonNull PrintWriter pw) {
        pw.println("Telephony suggestion options:");
        pw.println("  --slot_index <number>");
        pw.println("  To withdraw a previous suggestion:");
        pw.println("    [--zone_id \"_\"]");
        pw.println("  To make a new suggestion:");
        pw.println("    --zone_id <Olson ID>");
        pw.println("    --quality <single|multiple_same|multiple_different>");
        pw.println("    --match_type <emulator|country_with_offset|country|test_network>");
        pw.println();
        pw.println("See " + TelephonyTimeZoneSuggestion.class.getName() + " for more information");
    }
}
+39 −0
Original line number Diff line number Diff line
@@ -18,12 +18,19 @@ package android.app.timezonedetector;

import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
import static android.app.timezonedetector.ShellCommandTestSupport.createShellCommandWithArgsAndOptions;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;

import android.os.ShellCommand;

import org.junit.Test;

import java.io.PrintWriter;
import java.io.StringWriter;

public class ManualTimeZoneSuggestionTest {

    private static final String ARBITRARY_ZONE_ID1 = "Europe/London";
@@ -58,4 +65,36 @@ public class ManualTimeZoneSuggestionTest {
        ManualTimeZoneSuggestion rtSuggestion = roundTripParcelable(suggestion);
        assertEquals(suggestion.getDebugInfo(), rtSuggestion.getDebugInfo());
    }

    @Test
    public void testPrintCommandLineOpts() throws Exception {
        try (StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw)) {
            ManualTimeZoneSuggestion.printCommandLineOpts(pw);
            assertTrue(sw.getBuffer().length() > 0);
        }
    }

    @Test(expected = IllegalArgumentException.class)
    public void testParseCommandLineArg_noArgs() {
        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions("");
        ManualTimeZoneSuggestion.parseCommandLineArg(testShellCommand);
    }

    @Test
    public void testParseCommandLineArg_validSuggestion() {
        ShellCommand testShellCommand =
                createShellCommandWithArgsAndOptions("--zone_id Europe/London");
        ManualTimeZoneSuggestion expectedSuggestion =
                new ManualTimeZoneSuggestion("Europe/London");
        ManualTimeZoneSuggestion actualSuggestion =
                ManualTimeZoneSuggestion.parseCommandLineArg(testShellCommand);
        assertEquals(expectedSuggestion, actualSuggestion);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testParseCommandLineArg_unknownArgument() {
        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
                "--zone_id Europe/London --bad_arg 0");
        ManualTimeZoneSuggestion.parseCommandLineArg(testShellCommand);
    }
}
+65 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 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 android.app.timezonedetector;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import android.os.ShellCommand;

import org.mockito.stubbing.Answer;

import java.util.Arrays;
import java.util.List;

/** Utility methods related to {@link ShellCommand} objects used in several tests. */
final class ShellCommandTestSupport {
    private ShellCommandTestSupport() {}

    static ShellCommand createShellCommandWithArgsAndOptions(String argsWithSpaces) {
        return createShellCommandWithArgsAndOptions(Arrays.asList(argsWithSpaces.split(" ")));
    }

    static ShellCommand createShellCommandWithArgsAndOptions(List<String> args) {
        ShellCommand command = mock(ShellCommand.class);
        class ArgProvider {
            private int mCount;

            String getNext() {
                if (mCount >= args.size()) {
                    return null;
                }
                return args.get(mCount++);
            }

            String getNextRequired() {
                String next = getNext();
                if (next == null) {
                    throw new IllegalArgumentException("No next");
                }
                return next;
            }
        }
        ArgProvider argProvider = new ArgProvider();
        when(command.getNextArg()).thenAnswer(
                (Answer<String>) invocation -> argProvider.getNext());
        when(command.getNextOption()).thenAnswer(
                (Answer<String>) invocation -> argProvider.getNext());
        when(command.getNextArgRequired()).thenAnswer(
                (Answer<String>) invocation -> argProvider.getNextRequired());
        return command;
    }
}
+59 −0
Original line number Diff line number Diff line
@@ -18,13 +18,19 @@ package android.app.timezonedetector;

import static android.app.timezonedetector.ParcelableTestSupport.assertRoundTripParcelable;
import static android.app.timezonedetector.ParcelableTestSupport.roundTripParcelable;
import static android.app.timezonedetector.ShellCommandTestSupport.createShellCommandWithArgsAndOptions;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;

import android.os.ShellCommand;

import org.junit.Test;

import java.io.PrintWriter;
import java.io.StringWriter;

public class TelephonyTimeZoneSuggestionTest {
    private static final int SLOT_INDEX = 99999;

@@ -159,4 +165,57 @@ public class TelephonyTimeZoneSuggestionTest {
        assertEquals(suggestion1, suggestion1_2);
        assertTrue(suggestion1_2.getDebugInfo().contains(debugString));
    }

    @Test
    public void testPrintCommandLineOpts() throws Exception {
        try (StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw)) {
            TelephonyTimeZoneSuggestion.printCommandLineOpts(pw);
            assertTrue(sw.getBuffer().length() > 0);
        }
    }

    @Test(expected = IllegalArgumentException.class)
    public void testParseCommandLineArg_noArgs() {
        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions("");
        TelephonyTimeZoneSuggestion.parseCommandLineArg(testShellCommand);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testParseCommandLineArg_noSlotIndex() {
        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions("--zone_id _");
        TelephonyTimeZoneSuggestion.parseCommandLineArg(testShellCommand);
    }

    @Test
    public void testParseCommandLineArg_validEmptyZoneIdSuggestion() {
        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
                "--slot_index 0 --zone_id _");
        TelephonyTimeZoneSuggestion expectedSuggestion =
                new TelephonyTimeZoneSuggestion.Builder(0).build();
        TelephonyTimeZoneSuggestion actualSuggestion =
                TelephonyTimeZoneSuggestion.parseCommandLineArg(testShellCommand);
        assertEquals(expectedSuggestion, actualSuggestion);
    }

    @Test
    public void testParseCommandLineArg_validNonEmptySuggestion() {
        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
                "--slot_index 0 --zone_id Europe/London --quality single --match_type country");
        TelephonyTimeZoneSuggestion expectedSuggestion =
                new TelephonyTimeZoneSuggestion.Builder(0)
                        .setZoneId("Europe/London")
                        .setQuality(TelephonyTimeZoneSuggestion.QUALITY_SINGLE_ZONE)
                        .setMatchType(TelephonyTimeZoneSuggestion.MATCH_TYPE_NETWORK_COUNTRY_ONLY)
                        .build();
        TelephonyTimeZoneSuggestion actualSuggestion =
                TelephonyTimeZoneSuggestion.parseCommandLineArg(testShellCommand);
        assertEquals(expectedSuggestion, actualSuggestion);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testParseCommandLineArg_unknownArgument() {
        ShellCommand testShellCommand = createShellCommandWithArgsAndOptions(
                "--slot_index 0 --zone_id _ --bad_arg 0");
        TelephonyTimeZoneSuggestion.parseCommandLineArg(testShellCommand);
    }
}
Loading