Loading core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.java +30 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"); } } core/java/android/app/timezonedetector/TelephonyTimeZoneSuggestion.java +95 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"); } } core/tests/coretests/src/android/app/timezonedetector/ManualTimeZoneSuggestionTest.java +39 −0 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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); } } core/tests/coretests/src/android/app/timezonedetector/ShellCommandTestSupport.java 0 → 100644 +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; } } core/tests/coretests/src/android/app/timezonedetector/TelephonyTimeZoneSuggestionTest.java +59 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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
core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.java +30 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"); } }
core/java/android/app/timezonedetector/TelephonyTimeZoneSuggestion.java +95 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"); } }
core/tests/coretests/src/android/app/timezonedetector/ManualTimeZoneSuggestionTest.java +39 −0 Original line number Diff line number Diff line Loading @@ -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"; Loading Loading @@ -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); } }
core/tests/coretests/src/android/app/timezonedetector/ShellCommandTestSupport.java 0 → 100644 +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; } }
core/tests/coretests/src/android/app/timezonedetector/TelephonyTimeZoneSuggestionTest.java +59 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } }