1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core.blackbox.joran.conditional;
15
16 import ch.qos.logback.core.Context;
17 import ch.qos.logback.core.ContextBase;
18 import ch.qos.logback.core.blackbox.BlackboxCoreTestConstants;
19 import ch.qos.logback.core.blackbox.joran.BlackboxSimpleConfigurator;
20 import ch.qos.logback.core.blackbox.joran.action.BlackboxTopElementAction;
21 import ch.qos.logback.core.blackbox.joran.action.ext.BlackboxStackAction;
22 import ch.qos.logback.core.blackbox.model.BlackboxStackModel;
23 import ch.qos.logback.core.blackbox.model.BlackboxTopModel;
24 import ch.qos.logback.core.blackbox.model.processor.BlackboxStackModelHandler;
25 import ch.qos.logback.core.joran.action.Action;
26 import ch.qos.logback.core.joran.action.PropertyAction;
27 import ch.qos.logback.core.joran.conditional.ElseAction;
28 import ch.qos.logback.core.joran.conditional.IfAction;
29 import ch.qos.logback.core.joran.conditional.ThenAction;
30 import ch.qos.logback.core.joran.spi.ElementSelector;
31 import ch.qos.logback.core.joran.spi.JoranException;
32 import ch.qos.logback.core.joran.spi.RuleStore;
33 import ch.qos.logback.core.model.ImplicitModel;
34 import ch.qos.logback.core.model.PropertyModel;
35 import ch.qos.logback.core.model.conditional.ElseModel;
36 import ch.qos.logback.core.model.conditional.IfModel;
37 import ch.qos.logback.core.model.conditional.ThenModel;
38 import ch.qos.logback.core.model.processor.DefaultProcessor;
39 import ch.qos.logback.core.model.processor.ImplicitModelHandler;
40 import ch.qos.logback.core.model.processor.NOPModelHandler;
41 import ch.qos.logback.core.model.processor.PropertyModelHandler;
42 import ch.qos.logback.core.model.processor.conditional.ElseModelHandler;
43 import ch.qos.logback.core.model.processor.conditional.IfModelHandler;
44 import ch.qos.logback.core.model.processor.conditional.ThenModelHandler;
45 import ch.qos.logback.core.status.Status;
46 import ch.qos.logback.core.status.StatusUtil;
47 import ch.qos.logback.core.testUtil.RandomUtil;
48 import ch.qos.logback.core.util.StatusPrinter;
49 import org.junit.jupiter.api.AfterEach;
50 import org.junit.jupiter.api.Assertions;
51 import org.junit.jupiter.api.BeforeEach;
52 import org.junit.jupiter.api.Test;
53
54 import java.io.IOException;
55 import java.util.Arrays;
56 import java.util.HashMap;
57 import java.util.Stack;
58 import java.util.function.Supplier;
59
60 public class IfThenElseTest {
61
62 Context context = new ContextBase();
63 StatusUtil checker = new StatusUtil(context);
64 BlackboxSimpleConfigurator simpleConfigurator;
65 int diff = RandomUtil.getPositiveInt();
66 static final String CONDITIONAL_DIR_PREFIX = BlackboxCoreTestConstants.JORAN_INPUT_PREFIX + "conditional/";
67
68 String ki1 = "ki1";
69 String val1 = "val1";
70 String sysKey = "sysKey";
71 String dynaKey = "dynaKey";
72
73 @BeforeEach
74 public void setUp() throws Exception {
75 HashMap<ElementSelector, Supplier<Action>> rulesMap = new HashMap<>();
76 rulesMap.put(new ElementSelector("x"), BlackboxTopElementAction::new);
77 rulesMap.put(new ElementSelector("x/stack"), BlackboxStackAction::new);
78 rulesMap.put(new ElementSelector("x/property"), PropertyAction::new);
79 rulesMap.put(new ElementSelector("*/if"), IfAction::new);
80 rulesMap.put(new ElementSelector("*/if/then"), ThenAction::new);
81 rulesMap.put(new ElementSelector("*/if/else"), ElseAction::new);
82
83 simpleConfigurator = new BlackboxSimpleConfigurator(rulesMap) {
84
85 @Override
86 protected void addElementSelectorAndActionAssociations(RuleStore rs) {
87 super.addElementSelectorAndActionAssociations(rs);
88
89 rs.addTransparentPathPart("if");
90 rs.addTransparentPathPart("then");
91 rs.addTransparentPathPart("else");
92
93 }
94
95 @Override
96 protected void addModelHandlerAssociations(DefaultProcessor defaultProcessor) {
97 defaultProcessor.addHandler(BlackboxTopModel.class, NOPModelHandler::makeInstance);
98
99 defaultProcessor.addHandler(BlackboxStackModel.class, BlackboxStackModelHandler::makeInstance);
100 defaultProcessor.addHandler(PropertyModel.class, PropertyModelHandler::makeInstance);
101 defaultProcessor.addHandler(ImplicitModel.class, ImplicitModelHandler::makeInstance);
102 defaultProcessor.addHandler(IfModel.class, IfModelHandler::makeInstance);
103 defaultProcessor.addHandler(ThenModel.class, ThenModelHandler::makeInstance);
104 defaultProcessor.addHandler(ElseModel.class, ElseModelHandler::makeInstance);
105 }
106 };
107
108 simpleConfigurator.setContext(context);
109 }
110
111 @AfterEach
112 public void tearDown() throws Exception {
113 StatusPrinter.printIfErrorsOccured(context);
114 System.clearProperty(sysKey);
115 }
116
117 @Test
118 public void ifWithExec() throws JoranException {
119 context.putProperty(ki1, val1);
120 simpleConfigurator.doConfigure(CONDITIONAL_DIR_PREFIX + "ifWithExec.xml");
121 checker.containsException(org.codehaus.commons.compiler.CompileException.class);
122 checker.containsMatch(Status.ERROR, "Failed to parse condition");
123 }
124
125 @Test
126 public void whenContextPropertyIsSet_IfThenBranchIsEvaluated() throws JoranException {
127 context.putProperty(ki1, val1);
128 simpleConfigurator.doConfigure(CONDITIONAL_DIR_PREFIX + "if0.xml");
129 verifyConfig(new String[] { "BEGIN", "a", "END" });
130 }
131
132 @Test
133 public void whenLocalPropertyIsSet_IfThenBranchIsEvaluated() throws JoranException {
134 simpleConfigurator.doConfigure(CONDITIONAL_DIR_PREFIX + "if_localProperty.xml");
135 verifyConfig(new String[] { "BEGIN", "a", "END" });
136 }
137
138 @Test
139 public void whenNoPropertyIsDefined_ElseBranchIsEvaluated() throws JoranException {
140 simpleConfigurator.doConfigure(CONDITIONAL_DIR_PREFIX + "if0.xml");
141 verifyConfig(new String[] { "BEGIN", "b", "END" });
142 }
143
144 @Test
145 public void whenContextPropertyIsSet_IfThenBranchIsEvaluated_NO_ELSE_DEFINED() throws JoranException {
146 context.putProperty(ki1, val1);
147 simpleConfigurator.doConfigure(CONDITIONAL_DIR_PREFIX + "ifWithoutElse.xml");
148 verifyConfig(new String[] { "BEGIN", "a", "END" });
149 }
150
151 @Test
152 public void whenNoPropertyIsDefined_IfThenBranchIsNotEvaluated_NO_ELSE_DEFINED() throws JoranException {
153 simpleConfigurator.doConfigure(CONDITIONAL_DIR_PREFIX + "ifWithoutElse.xml");
154 verifyConfig(new String[] { "BEGIN", "END" });
155 Assertions.assertTrue(checker.isErrorFree(0));
156 }
157
158 @Test
159 public void nestedIf() throws JoranException {
160 simpleConfigurator.doConfigure(CONDITIONAL_DIR_PREFIX + "nestedIf.xml");
161
162 verifyConfig(new String[] { "BEGIN", "a", "c", "END" });
163 Assertions.assertTrue(checker.isErrorFree(0));
164 }
165
166 @Test
167 public void useNonExistenceOfSystemPropertyToDefineAContextProperty() throws JoranException {
168 Assertions.assertNull(System.getProperty(sysKey));
169 Assertions.assertNull(context.getProperty(dynaKey));
170 simpleConfigurator.doConfigure(CONDITIONAL_DIR_PREFIX + "ifSystem.xml");
171 System.out.println(dynaKey + "=" + context.getProperty(dynaKey));
172 Assertions.assertNotNull(context.getProperty(dynaKey));
173 }
174
175 @Test
176 public void noContextPropertyShouldBeDefinedIfSystemPropertyExists() throws JoranException {
177 System.setProperty(sysKey, "a");
178 Assertions.assertNull(context.getProperty(dynaKey));
179 System.out.println("before " + dynaKey + "=" + context.getProperty(dynaKey));
180 simpleConfigurator.doConfigure(CONDITIONAL_DIR_PREFIX + "ifSystem.xml");
181 System.out.println(dynaKey + "=" + context.getProperty(dynaKey));
182 Assertions.assertNull(context.getProperty(dynaKey));
183 }
184
185 private void verifyConfig(String[] expected) {
186 Stack<String> witness = new Stack<>();
187 witness.addAll(Arrays.asList(expected));
188
189 @SuppressWarnings({ "unchecked", "rawtypes" })
190 Stack<String> aStack = (Stack) context.getObject(BlackboxStackModelHandler.STACK_TEST);
191 Assertions.assertEquals(witness, aStack);
192 }
193
194 }