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

Commit 215eafab authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Merge "Add command line support for testing tz detection" am: 86fd801b

Change-Id: Ia1060d6120c3572dc74a47256e1a1735aef08dbd
parents f83325ec 86fd801b
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