1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tradefed.config; 18 19 import com.android.tradefed.command.CommandScheduler; 20 import com.android.tradefed.config.Option.Importance; 21 import com.android.tradefed.util.ArrayUtil; 22 import com.android.tradefed.util.FileUtil; 23 import com.android.tradefed.util.keystore.StubKeyStoreFactory; 24 25 import junit.framework.TestCase; 26 27 import java.io.ByteArrayOutputStream; 28 import java.io.File; 29 import java.io.InputStream; 30 import java.io.PrintStream; 31 import java.util.ArrayList; 32 import java.util.List; 33 34 /** 35 * Unit Tests for {@link GlobalConfiguration} 36 * It is difficult to test since GlobalConfiguration is a singleton and we cannot use reflection to 37 * unset the instance since it might be in use in the currently running Trade Federation instance. 38 */ 39 public class GlobalConfigurationTest extends TestCase { 40 41 GlobalConfiguration mGlobalConfig; 42 private final static String OPTION_DESCRIPTION = "mandatory option should be set"; 43 private final static String OPTION_NAME = "manda"; 44 private final static String ALIAS_NAME = "aliasssss"; 45 private final static String EMPTY_CONFIG = "empty"; 46 private static final String GLOBAL_TEST_CONFIG = "global-config"; 47 private static final String GLOBAL_CONFIG_SERVER_TEST_CONFIG = "global-config-server-config"; 48 49 @Override 50 protected void setUp() throws Exception { 51 super.setUp(); 52 mGlobalConfig = new GlobalConfiguration(EMPTY_CONFIG, "description"); 53 assertNotNull(mGlobalConfig); 54 } 55 56 @OptionClass(alias = ALIAS_NAME) 57 private class FakeCommandScheduler extends CommandScheduler { 58 @Option(name = OPTION_NAME, description = OPTION_DESCRIPTION, mandatory = true, 59 importance = Importance.IF_UNSET) 60 private String mandatoryTest = null; 61 } 62 63 /** 64 * Test for {@link GlobalConfiguration#validateOptions()} 65 */ 66 public void testValidateOptions() throws Exception { 67 mGlobalConfig.validateOptions(); 68 mGlobalConfig.setCommandScheduler(new FakeCommandScheduler()); 69 try { 70 mGlobalConfig.validateOptions(); 71 fail("Should have thrown a configuration exception"); 72 } catch (ConfigurationException ce) { 73 // expected 74 } 75 } 76 77 /** 78 * Test that the creation of Global configuration with basic default parameter is working 79 */ 80 public void testCreateGlobalConfiguration_empty() throws Exception { 81 String[] args = {}; 82 List<String> nonGlobalArgs = new ArrayList<String>(args.length); 83 IConfigurationFactory configFactory = ConfigurationFactory.getInstance(); 84 // use the known "empty" config as a global config to avoid issues. 85 String globalConfigPath = EMPTY_CONFIG; 86 IGlobalConfiguration mGlobalConfig = configFactory.createGlobalConfigurationFromArgs( 87 ArrayUtil.buildArray(new String[] {globalConfigPath}, args), nonGlobalArgs); 88 assertTrue(nonGlobalArgs.size() == 0); 89 assertNotNull(mGlobalConfig); 90 mGlobalConfig.validateOptions(); 91 } 92 93 /** 94 * Printing is properly reading the properties 95 */ 96 public void testPrintCommandUsage() throws Exception { 97 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 98 PrintStream ps = new PrintStream(baos, true); 99 mGlobalConfig.printCommandUsage(true, ps); 100 String expected = "'empty' configuration: description\n\n" + 101 "Printing help for only the important options. " + 102 "To see help for all options, use the --help-all flag\n\n"; 103 assertEquals(expected, baos.toString()); 104 105 mGlobalConfig.setCommandScheduler(new FakeCommandScheduler()); 106 baos = new ByteArrayOutputStream(); 107 ps = new PrintStream(baos, true); 108 mGlobalConfig.printCommandUsage(true, ps); 109 expected = String.format("'%s' command_scheduler options:\n" + 110 " --%s %s", ALIAS_NAME, OPTION_NAME, OPTION_DESCRIPTION); 111 assertTrue(baos.toString().contains(expected)); 112 } 113 114 /** 115 * Test that the creation of Global configuration with basic global configuration that is not 116 * empty. 117 */ 118 public void testCreateGlobalConfiguration_nonEmpty() throws Exception { 119 // one global arg, one non-global arg 120 String[] args = {"test-tag", "test"}; 121 List<String> nonGlobalArgs = new ArrayList<String>(args.length); 122 // In order to find our test config, we provide our testconfigs/ folder. Otherwise only 123 // the config/ folder is searched for configuration by default. 124 IConfigurationFactory configFactory = 125 new ConfigurationFactory() { 126 @Override 127 protected String getConfigPrefix() { 128 return "testconfigs/"; 129 } 130 }; 131 String globalConfigPath = GLOBAL_TEST_CONFIG; 132 IGlobalConfiguration mGlobalConfig = configFactory.createGlobalConfigurationFromArgs( 133 ArrayUtil.buildArray(new String[] {globalConfigPath}, args), nonGlobalArgs); 134 assertNotNull(mGlobalConfig); 135 assertNotNull(mGlobalConfig.getDeviceMonitors()); 136 assertNotNull(mGlobalConfig.getWtfHandler()); 137 assertNotNull(mGlobalConfig.getKeyStoreFactory()); 138 mGlobalConfig.validateOptions(); 139 // Only --test-tag test remains, the global config name has been removed. 140 assertTrue(nonGlobalArgs.size() == 2); 141 } 142 143 /** 144 * Test that a subset of Global configuration can be created based on the default white list 145 * filtering defined in GlobalConfiguration. 146 */ 147 public void testCreateGlobalConfiguration_cloneConfigWithFilterByDefault() throws Exception { 148 String[] args = {}; 149 List<String> nonGlobalArgs = new ArrayList<String>(); 150 // In order to find our test config, we provide our testconfigs/ folder. Otherwise only 151 // the config/ folder is searched for configuration by default. 152 IConfigurationFactory configFactory = 153 new ConfigurationFactory() { 154 @Override 155 protected String getConfigPrefix() { 156 return "testconfigs/"; 157 } 158 }; 159 String globalConfigPath = GLOBAL_TEST_CONFIG; 160 IGlobalConfiguration globalConfig = 161 configFactory.createGlobalConfigurationFromArgs( 162 ArrayUtil.buildArray(new String[] {globalConfigPath}, args), nonGlobalArgs); 163 164 File tmpXml = FileUtil.createTempFile("filtered_global_config", ".xml"); 165 try { 166 globalConfig.cloneConfigWithFilter(tmpXml, null); 167 168 // Load the filtered XML and confirm it has desired content. 169 IGlobalConfiguration filteredGlobalConfig = 170 configFactory.createGlobalConfigurationFromArgs( 171 ArrayUtil.buildArray(new String[] {tmpXml.toString()}, args), 172 nonGlobalArgs); 173 assertNotNull(filteredGlobalConfig); 174 assertNotNull(filteredGlobalConfig.getKeyStoreFactory()); 175 filteredGlobalConfig.validateOptions(); 176 // Fail if any configuration not in the white list presents. 177 assertNull(filteredGlobalConfig.getDeviceMonitors()); 178 assertNull(filteredGlobalConfig.getWtfHandler()); 179 } finally { 180 FileUtil.deleteFile(tmpXml); 181 } 182 } 183 184 /** Test that a subset of Global configuration can be created based on a given white list. */ 185 public void testCreateGlobalConfiguration_cloneConfigWithFilter() throws Exception { 186 String[] args = {}; 187 List<String> nonGlobalArgs = new ArrayList<String>(); 188 // In order to find our test config, we provide our testconfigs/ folder. Otherwise only 189 // the config/ folder is searched for configuration by default. 190 IConfigurationFactory configFactory = 191 new ConfigurationFactory() { 192 @Override 193 protected String getConfigPrefix() { 194 return "testconfigs/"; 195 } 196 }; 197 String globalConfigPath = GLOBAL_TEST_CONFIG; 198 IGlobalConfiguration globalConfig = 199 configFactory.createGlobalConfigurationFromArgs( 200 ArrayUtil.buildArray(new String[] {globalConfigPath}, args), nonGlobalArgs); 201 202 File tmpXml = FileUtil.createTempFile("filtered_global_config", ".xml"); 203 try { 204 globalConfig.cloneConfigWithFilter(tmpXml, new String[] {"wtf_handler"}); 205 206 // Load the filtered XML and confirm it has desired content. 207 IGlobalConfiguration filteredGlobalConfig = 208 configFactory.createGlobalConfigurationFromArgs( 209 ArrayUtil.buildArray(new String[] {tmpXml.toString()}, args), 210 nonGlobalArgs); 211 assertNotNull(filteredGlobalConfig); 212 assertNotNull(filteredGlobalConfig.getWtfHandler()); 213 filteredGlobalConfig.validateOptions(); 214 // Fail if any configuration not in the white list presents. 215 assertNull(filteredGlobalConfig.getDeviceMonitors()); 216 assertTrue(filteredGlobalConfig.getKeyStoreFactory() instanceof StubKeyStoreFactory); 217 } finally { 218 FileUtil.deleteFile(tmpXml); 219 } 220 } 221 222 public static class StubConfigServer implements IConfigurationServer { 223 224 @Option(name = "server-name", description = "Config server's name.") 225 private String mServerName; 226 227 @Override 228 public InputStream getConfig(String name) throws ConfigurationException { 229 return null; 230 } 231 232 @Override 233 public String getCurrentHostConfig() throws ConfigurationException { 234 return "current-host-config.xml"; 235 } 236 237 public String getServerName() { 238 return mServerName; 239 } 240 } 241 242 /** Test global configuration load from config server. */ 243 public void testCreateGlobalConfiguration_configServer() throws Exception { 244 IConfigurationFactory configFactory = 245 new ConfigurationFactory() { 246 @Override 247 protected String getConfigPrefix() { 248 return "testconfigs/"; 249 } 250 }; 251 String[] args = {"--server-name", "stub", "test-tag", "test"}; 252 String globalConfigServerConfigPath = GLOBAL_CONFIG_SERVER_TEST_CONFIG; 253 List<String> nonConfigServerArgs = new ArrayList<String>(args.length); 254 IGlobalConfiguration configServerConfig = 255 configFactory.createGlobalConfigurationFromArgs( 256 ArrayUtil.buildArray(new String[] {globalConfigServerConfigPath}, args), 257 nonConfigServerArgs); 258 StubConfigServer globalConfigServer = 259 (StubConfigServer) configServerConfig.getGlobalConfigServer(); 260 assertNotNull(globalConfigServer); 261 assertEquals("stub", globalConfigServer.getServerName()); 262 assertEquals("current-host-config.xml", globalConfigServer.getCurrentHostConfig()); 263 assertTrue(nonConfigServerArgs.size() == 2); 264 } 265 } 266