1 // Copyright 2020 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.base; 6 7 import androidx.test.filters.SmallTest; 8 9 import org.junit.Assert; 10 import org.junit.Before; 11 import org.junit.Rule; 12 import org.junit.Test; 13 import org.junit.rules.TestRule; 14 import org.junit.runner.Description; 15 import org.junit.runner.RunWith; 16 import org.junit.runners.model.InitializationError; 17 import org.junit.runners.model.Statement; 18 19 import org.chromium.base.library_loader.LibraryLoader; 20 import org.chromium.base.test.BaseJUnit4ClassRunner; 21 import org.chromium.base.test.util.Batch; 22 import org.chromium.base.test.util.CommandLineFlags; 23 import org.chromium.base.test.util.Feature; 24 25 import java.util.List; 26 27 /** Test class for {@link CommandLineFlags}. */ 28 @RunWith(CommandLineFlagsTest.ClassRunner.class) 29 @Batch(Batch.UNIT_TESTS) 30 @CommandLineFlags.Add({ 31 CommandLineFlagsTest.FLAG_1, 32 "flagwithvalue=foo", 33 "enable-features=feature1,feature2" 34 }) 35 public class CommandLineFlagsTest { 36 public static class ClassRunner extends BaseJUnit4ClassRunner { ClassRunner(final Class<?> klass)37 public ClassRunner(final Class<?> klass) throws InitializationError { 38 super(klass); 39 } 40 41 // Verify class-level modifications are reset after class finishes. 42 @Override getPostClassHooks()43 protected List<ClassHook> getPostClassHooks() { 44 return addToList( 45 ClassRunner.super.getPostClassHooks(), 46 (targetContext, testClass) -> { 47 verifyCommandLine(false, false, false, false, false, false, false); 48 Assert.assertFalse(CommandLine.getInstance().hasSwitch("flagwithvalue")); 49 String enabledFeatures = 50 CommandLine.getInstance().getSwitchValue("enable-features"); 51 if (enabledFeatures != null) { 52 Assert.assertFalse(enabledFeatures.contains("feature1")); 53 Assert.assertFalse(enabledFeatures.contains("feature2")); 54 } 55 }); 56 } 57 58 // Verify that after each test, flags are reset to class-level state. 59 @Override getPostTestHooks()60 protected List<TestHook> getPostTestHooks() { 61 return addToList( 62 ClassRunner.super.getPostTestHooks(), 63 (targetContext, testMethod) -> { 64 verifyClassLevelStateOnly(); 65 }); 66 } 67 } 68 69 static final String FLAG_1 = "flag1"; 70 private static final String FLAG_2 = "flag2"; 71 private static final String FLAG_3 = "flag3"; 72 private static final String FLAG_4 = "flag4"; 73 private static final String FLAG_5 = "flag5"; 74 private static final String FLAG_6 = "flag6"; 75 private static final String FLAG_7 = "flag7"; 76 77 @CommandLineFlags.Add(FLAG_2) 78 private static class EmptyRule implements TestRule { 79 @Override 80 public Statement apply(Statement base, Description description) { 81 return base; 82 } 83 } 84 85 @CommandLineFlags.Add(FLAG_3) 86 private static class MyRule extends EmptyRule { 87 @CommandLineFlags.Add(FLAG_4) 88 private static class InnerRule extends EmptyRule {} 89 90 @SuppressWarnings("UnusedNestedClass") 91 @CommandLineFlags.Add(FLAG_5) 92 private static class UnusedRule extends EmptyRule {} 93 94 @Rule public InnerRule mInnerRule = new InnerRule(); 95 } 96 97 @Rule public MyRule mRule = new MyRule(); 98 99 @Before 100 public void setUp() { 101 LibraryLoader.getInstance().ensureInitialized(); 102 } 103 104 private static void verifyCommandLine( 105 boolean flag1, 106 boolean flag2, 107 boolean flag3, 108 boolean flag4, 109 boolean flag5, 110 boolean flag6, 111 boolean flag7) { 112 CommandLine cmdLine = CommandLine.getInstance(); 113 Assert.assertEquals(flag1, cmdLine.hasSwitch(FLAG_1)); 114 Assert.assertEquals(flag2, cmdLine.hasSwitch(FLAG_2)); 115 Assert.assertEquals(flag3, cmdLine.hasSwitch(FLAG_3)); 116 Assert.assertEquals(flag4, cmdLine.hasSwitch(FLAG_4)); 117 Assert.assertEquals(flag5, cmdLine.hasSwitch(FLAG_5)); 118 Assert.assertEquals(flag6, cmdLine.hasSwitch(FLAG_6)); 119 Assert.assertEquals(flag7, cmdLine.hasSwitch(FLAG_7)); 120 } 121 122 private static void verifyClassLevelStateOnly() { 123 verifyCommandLine(true, true, true, true, false, false, false); 124 Assert.assertEquals("foo", CommandLine.getInstance().getSwitchValue("flagwithvalue")); 125 String enabledFeatures = CommandLine.getInstance().getSwitchValue("enable-features"); 126 Assert.assertTrue(enabledFeatures.contains("feature1")); 127 Assert.assertTrue(enabledFeatures.contains("feature2")); 128 Assert.assertFalse( 129 CommandLine.getInstance().getSwitchValue("enable-features").contains("feature3")); 130 String disabledFeatures = CommandLine.getInstance().getSwitchValue("disable-features"); 131 if (disabledFeatures != null) Assert.assertFalse(disabledFeatures.contains("feature2")); 132 } 133 134 @Test 135 @SmallTest 136 @Feature({"CommandLine"}) 137 public void testNoMethodModifications() { 138 verifyClassLevelStateOnly(); 139 } 140 141 @Test 142 @SmallTest 143 @Feature({"CommandLine"}) 144 @CommandLineFlags.Add({FLAG_1, FLAG_6}) 145 public void testMethodAdd() { 146 verifyCommandLine(true, true, true, true, false, true, false); 147 } 148 149 @Test 150 @SmallTest 151 @Feature({"CommandLine"}) 152 @CommandLineFlags.Remove({FLAG_4, FLAG_7}) 153 public void testMethodRemove() { 154 verifyCommandLine(true, true, true, false, false, false, false); 155 } 156 157 @Test 158 @SmallTest 159 @Feature({"CommandLine"}) 160 @CommandLineFlags.Add({"flagwithvalue=bar"}) 161 public void testOverrideFlagValue() { 162 Assert.assertEquals("bar", CommandLine.getInstance().getSwitchValue("flagwithvalue")); 163 } 164 165 @Test 166 @SmallTest 167 @Feature({"CommandLine"}) 168 @CommandLineFlags.Add({"enable-features=feature3", "disable-features=feature2"}) 169 public void testFeatures() { 170 String enabledFeatures = CommandLine.getInstance().getSwitchValue("enable-features"); 171 Assert.assertTrue(enabledFeatures.contains("feature1")); 172 Assert.assertTrue(enabledFeatures.contains("feature2")); 173 Assert.assertTrue(enabledFeatures.contains("feature3")); 174 Assert.assertTrue( 175 CommandLine.getInstance().getSwitchValue("disable-features").contains("feature2")); 176 } 177 } 178