001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.chain.config; 018 019import static org.junit.jupiter.api.Assertions.assertEquals; 020import static org.junit.jupiter.api.Assertions.assertFalse; 021import static org.junit.jupiter.api.Assertions.assertInstanceOf; 022import static org.junit.jupiter.api.Assertions.assertNotNull; 023import static org.junit.jupiter.api.Assertions.assertNull; 024import static org.junit.jupiter.api.Assertions.assertTrue; 025 026import java.util.Iterator; 027 028import org.apache.commons.chain.Catalog; 029import org.apache.commons.chain.CatalogFactory; 030import org.apache.commons.chain.Command; 031import org.apache.commons.chain.Context; 032import org.apache.commons.chain.impl.AddingCommand; 033import org.apache.commons.chain.impl.CatalogBase; 034import org.apache.commons.chain.impl.ChainBase; 035import org.apache.commons.chain.impl.ContextBase; 036import org.apache.commons.chain.impl.DelegatingCommand; 037import org.apache.commons.chain.impl.DelegatingFilter; 038import org.apache.commons.chain.impl.ExceptionCommand; 039import org.apache.commons.chain.impl.ExceptionFilter; 040import org.apache.commons.chain.impl.NonDelegatingCommand; 041import org.apache.commons.chain.impl.NonDelegatingFilter; 042import org.apache.commons.digester.Digester; 043import org.junit.jupiter.api.AfterEach; 044import org.junit.jupiter.api.BeforeEach; 045import org.junit.jupiter.api.Test; 046 047/** 048 * Test Case for {@code org.apache.commons.chain.config.ConfigParser}. 049 */ 050public class ConfigParserTestCase { 051 private static final String DEFAULT_XML = 052 "/org/apache/commons/chain/config/test-config.xml"; 053 054 // ------------------------------------------------------ Instance Variables 055 056 /** 057 * The {@code Catalog} to contain our configured commands. 058 */ 059 protected Catalog<Context> catalog = null; 060 061 /** 062 * The {@code Context} to use for execution tests. 063 */ 064 protected Context context = null; 065 066 /** 067 * The {@code ConfigParser} instance under test. 068 */ 069 protected ConfigParser parser = null; 070 071 // ------------------------------------------------------------ Constructors 072 073 /** 074 * The Default-Constructor for this class. 075 */ 076 public ConfigParserTestCase() { 077 } 078 079 // ---------------------------------------------------- Overall Test Methods 080 081 /** 082 * Set up instance variables required by this test case. 083 */ 084 @BeforeEach 085 public void init() { 086 catalog = new CatalogBase<>(); 087 context = new ContextBase(); 088 parser = new ConfigParser(); 089 } 090 091 /** 092 * Tear down instance variables required by this test case. 093 */ 094 @AfterEach 095 public void tearDown() { 096 parser = null; 097 context = null; 098 catalog = null; 099 } 100 101 // ------------------------------------------------ Individual Test Methods 102 103 /** 104 * Load the default test-config.xml file and examine the results 105 * 106 * @throws Exception any error 107 */ 108 @Test 109 public void testDefaut() throws Exception { 110 // Check overall command count 111 load(DEFAULT_XML); 112 checkCommandCount(17); 113 114 // Check individual single command instances 115 Command<Context> command = null; 116 117 command = catalog.getCommand("AddingCommand"); 118 assertNotNull(command); 119 assertInstanceOf(AddingCommand.class, command); 120 121 command = catalog.getCommand("DelegatingCommand"); 122 assertNotNull(command); 123 assertInstanceOf(DelegatingCommand.class, command); 124 125 command = catalog.getCommand("DelegatingFilter"); 126 assertNotNull(command); 127 assertInstanceOf(DelegatingFilter.class, command); 128 129 command = catalog.getCommand("ExceptionCommand"); 130 assertNotNull(command); 131 assertInstanceOf(ExceptionCommand.class, command); 132 133 command = catalog.getCommand("ExceptionFilter"); 134 assertNotNull(command); 135 assertInstanceOf(ExceptionFilter.class, command); 136 137 command = catalog.getCommand("NonDelegatingCommand"); 138 assertNotNull(command); 139 assertInstanceOf(NonDelegatingCommand.class, command); 140 141 command = catalog.getCommand("NonDelegatingFilter"); 142 assertNotNull(command); 143 assertInstanceOf(NonDelegatingFilter.class, command); 144 145 command = catalog.getCommand("ChainBase"); 146 assertNotNull(command); 147 assertInstanceOf(ChainBase.class, command); 148 assertInstanceOf(TestChain.class, command); 149 150 // Check configurable properties instance 151 TestCommand tcommand = (TestCommand) catalog.getCommand("Configurable"); 152 assertNotNull(tcommand); 153 assertEquals(tcommand.getFoo(), "Foo Value"); 154 assertEquals(tcommand.getBar(), "Bar Value"); 155 } 156 157 /** 158 * Test execution of chain "Execute2a" 159 * 160 * @throws Exception any error 161 */ 162 @Test 163 public void testExecute2a() throws Exception { 164 load(DEFAULT_XML); 165 assertTrue(catalog.getCommand("Execute2a").execute(context), 166 "Chain returned true"); 167 checkExecuteLog("1/2/3"); 168 } 169 170 /** 171 * Test execution of chain "Execute2b" 172 * 173 * @throws Exception any error 174 */ 175 @Test 176 public void testExecute2b() throws Exception { 177 load(DEFAULT_XML); 178 assertFalse(catalog.getCommand("Execute2b").execute(context), 179 "Chain returned false"); 180 checkExecuteLog("1/2/3"); 181 } 182 183 /** 184 * Test execution of chain "Execute2c" 185 * 186 * @throws Exception any error 187 */ 188 @Test 189 public void testExecute2c() throws Exception { 190 load(DEFAULT_XML); 191 try { 192 catalog.getCommand("Execute2c").execute(context); 193 } catch (ArithmeticException e) { 194 assertEquals("3", e.getMessage(), 195 "Correct exception id"); 196 } 197 checkExecuteLog("1/2/3"); 198 } 199 200 /** 201 * Test execution of chain "Execute2d" 202 * 203 * @throws Exception any error 204 */ 205 @Test 206 public void testExecute2d() throws Exception { 207 load(DEFAULT_XML); 208 try { 209 catalog.getCommand("Execute2d").execute(context); 210 } catch (ArithmeticException e) { 211 assertEquals("2", e.getMessage(), 212 "Correct exception id"); 213 } 214 checkExecuteLog("1/2"); 215 } 216 217 /** 218 * Test execution of chain "Execute4a" 219 * 220 * @throws Exception any error 221 */ 222 @Test 223 public void testExecute4a() throws Exception { 224 load(DEFAULT_XML); 225 assertTrue(catalog.getCommand("Execute4a").execute(context), 226 "Chain returned true"); 227 checkExecuteLog("1/2/3/c/a"); 228 } 229 230 /** 231 * Test execution of chain "Execute2b" 232 * 233 * @throws Exception any error 234 */ 235 @Test 236 public void testExecute4b() throws Exception { 237 load(DEFAULT_XML); 238 assertFalse(catalog.getCommand("Execute4b").execute(context), 239 "Chain returned false"); 240 checkExecuteLog("1/2/3/b"); 241 } 242 243 /** 244 * Test execution of chain "Execute4c" 245 * 246 * @throws Exception any error 247 */ 248 @Test 249 public void testExecute4c() throws Exception { 250 load(DEFAULT_XML); 251 try { 252 catalog.getCommand("Execute4c").execute(context); 253 } catch (ArithmeticException e) { 254 assertEquals("3", e.getMessage(), 255 "Correct exception id"); 256 } 257 checkExecuteLog("1/2/3/c/b/a"); 258 } 259 260 /** 261 * Test execution of chain "Execute4d" 262 * 263 * @throws Exception any error 264 */ 265 @Test 266 public void testExecute4d() throws Exception { 267 load(DEFAULT_XML); 268 try { 269 catalog.getCommand("Execute4d").execute(context); 270 } catch (ArithmeticException e) { 271 assertEquals("2", e.getMessage(), 272 "Correct exception id"); 273 } 274 checkExecuteLog("1/2/b/a"); 275 } 276 277 /** 278 * Test a pristine ConfigParser instance 279 */ 280 @Test 281 public void testPristine() { 282 // Validate the "digester" property 283 Digester digester = parser.getDigester(); 284 assertNotNull(digester, "Returned a Digester instance"); 285 assertFalse(digester.getNamespaceAware(), 286 "Default namespaceAware"); 287 assertTrue(digester.getUseContextClassLoader(), 288 "Default useContextClassLoader"); 289 assertFalse(digester.getValidating(), 290 "Default validating"); 291 292 // Validate the "ruleSet" property 293 ConfigRuleSet ruleSet = (ConfigRuleSet) parser.getRuleSet(); 294 assertNotNull(ruleSet, "Returned a RuleSet instance"); 295 assertEquals("chain", ruleSet.getChainElement(), 296 "Default chainElement"); 297 assertEquals("className", ruleSet.getClassAttribute(), 298 "Default classAttribute"); 299 assertEquals("command", ruleSet.getCommandElement(), 300 "Default commandElement"); 301 assertEquals("name", ruleSet.getNameAttribute(), 302 "Default nameAttribute"); 303 assertNull(ruleSet.getNamespaceURI(), 304 "Default namespaceURI"); 305 306 // Validate the "useContextClassLoader" property 307 assertTrue(parser.getUseContextClassLoader(), 308 "Defaults to use context class loader"); 309 310 // Ensure that there are no preconfigured commands in the catalog 311 checkCommandCount(0); 312 } 313 314 // --------------------------------------------------------- Private Methods 315 316 /** 317 * Verify the number of configured commands 318 * 319 * @param expected the expected value 320 */ 321 protected void checkCommandCount(int expected) { 322 int n = 0; 323 Iterator<String> names = catalog.getNames(); 324 while (names.hasNext()) { 325 String name = names.next(); 326 n++; 327 assertNotNull(catalog.getCommand(name), name + " exists"); 328 } 329 assertEquals(expected, n, "Correct command count"); 330 } 331 332 /** 333 * Verify the contents of the execution log 334 * 335 * @param expected the expected value 336 */ 337 protected void checkExecuteLog(String expected) { 338 StringBuffer log = (StringBuffer) context.get("log"); 339 assertNotNull(log, "Context returned log"); 340 assertEquals(expected, log.toString(), 341 "Context returned correct log"); 342 } 343 344 /** 345 * Load the specified catalog from the specified resource path 346 * 347 * @param path resource path to load specified catalog 348 * 349 * @throws Exception any error 350 */ 351 protected void load(String path) throws Exception { 352 CatalogFactory.clear(); 353 parser.parse(this.getClass().getResource(path)); 354 catalog = CatalogFactory.getInstance().getCatalog(); 355 } 356}