1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 package org.apache.hadoop.hbase.security.visibility;
19 
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertTrue;
22 
23 import org.apache.hadoop.hbase.testclassification.SmallTests;
24 import org.apache.hadoop.hbase.security.visibility.expression.ExpressionNode;
25 import org.apache.hadoop.hbase.security.visibility.expression.LeafExpressionNode;
26 import org.apache.hadoop.hbase.security.visibility.expression.NonLeafExpressionNode;
27 import org.apache.hadoop.hbase.security.visibility.expression.Operator;
28 import org.junit.Test;
29 import org.junit.experimental.categories.Category;
30 
31 @Category(SmallTests.class)
32 public class TestExpressionExpander {
33 
34   @Test
testPositiveCases()35   public void testPositiveCases() throws Exception {
36     ExpressionExpander expander = new ExpressionExpander();
37 
38     // (!a) -> (!a)
39     NonLeafExpressionNode exp1 = new NonLeafExpressionNode(Operator.NOT,
40         new LeafExpressionNode("a"));
41     ExpressionNode result = expander.expand(exp1);
42     assertTrue(result instanceof NonLeafExpressionNode);
43     NonLeafExpressionNode nlResult = (NonLeafExpressionNode) result;
44     assertEquals(Operator.NOT, nlResult.getOperator());
45     assertEquals("a", ((LeafExpressionNode) nlResult.getChildExps().get(0)).getIdentifier());
46 
47     // (a | b) -> (a | b)
48     NonLeafExpressionNode exp2 = new NonLeafExpressionNode(Operator.OR,
49         new LeafExpressionNode("a"), new LeafExpressionNode("b"));
50     result = expander.expand(exp2);
51     assertTrue(result instanceof NonLeafExpressionNode);
52     nlResult = (NonLeafExpressionNode) result;
53     assertEquals(Operator.OR, nlResult.getOperator());
54     assertEquals(2, nlResult.getChildExps().size());
55     assertEquals("a", ((LeafExpressionNode) nlResult.getChildExps().get(0)).getIdentifier());
56     assertEquals("b", ((LeafExpressionNode) nlResult.getChildExps().get(1)).getIdentifier());
57 
58     // (a & b) -> (a & b)
59     NonLeafExpressionNode exp3 = new NonLeafExpressionNode(Operator.AND,
60         new LeafExpressionNode("a"), new LeafExpressionNode("b"));
61     result = expander.expand(exp3);
62     assertTrue(result instanceof NonLeafExpressionNode);
63     nlResult = (NonLeafExpressionNode) result;
64     assertEquals(Operator.AND, nlResult.getOperator());
65     assertEquals(2, nlResult.getChildExps().size());
66     assertEquals("a", ((LeafExpressionNode) nlResult.getChildExps().get(0)).getIdentifier());
67     assertEquals("b", ((LeafExpressionNode) nlResult.getChildExps().get(1)).getIdentifier());
68 
69     // ((a | b) | c) -> (a | b | c)
70     NonLeafExpressionNode exp4 = new NonLeafExpressionNode(Operator.OR, new NonLeafExpressionNode(
71         Operator.OR, new LeafExpressionNode("a"), new LeafExpressionNode("b")),
72         new LeafExpressionNode("c"));
73     result = expander.expand(exp4);
74     assertTrue(result instanceof NonLeafExpressionNode);
75     nlResult = (NonLeafExpressionNode) result;
76     assertEquals(Operator.OR, nlResult.getOperator());
77     assertEquals(3, nlResult.getChildExps().size());
78     assertEquals("a", ((LeafExpressionNode) nlResult.getChildExps().get(0)).getIdentifier());
79     assertEquals("b", ((LeafExpressionNode) nlResult.getChildExps().get(1)).getIdentifier());
80     assertEquals("c", ((LeafExpressionNode) nlResult.getChildExps().get(2)).getIdentifier());
81 
82     // ((a & b) & c) -> (a & b & c)
83     NonLeafExpressionNode exp5 = new NonLeafExpressionNode(Operator.AND, new NonLeafExpressionNode(
84         Operator.AND, new LeafExpressionNode("a"), new LeafExpressionNode("b")),
85         new LeafExpressionNode("c"));
86     result = expander.expand(exp5);
87     assertTrue(result instanceof NonLeafExpressionNode);
88     nlResult = (NonLeafExpressionNode) result;
89     assertEquals(Operator.AND, nlResult.getOperator());
90     assertEquals(3, nlResult.getChildExps().size());
91     assertEquals("a", ((LeafExpressionNode) nlResult.getChildExps().get(0)).getIdentifier());
92     assertEquals("b", ((LeafExpressionNode) nlResult.getChildExps().get(1)).getIdentifier());
93     assertEquals("c", ((LeafExpressionNode) nlResult.getChildExps().get(2)).getIdentifier());
94 
95     // (a | b) & c -> ((a & c) | (b & c))
96     NonLeafExpressionNode exp6 = new NonLeafExpressionNode(Operator.AND, new NonLeafExpressionNode(
97         Operator.OR, new LeafExpressionNode("a"), new LeafExpressionNode("b")),
98         new LeafExpressionNode("c"));
99     result = expander.expand(exp6);
100     assertTrue(result instanceof NonLeafExpressionNode);
101     nlResult = (NonLeafExpressionNode) result;
102     assertEquals(Operator.OR, nlResult.getOperator());
103     assertEquals(2, nlResult.getChildExps().size());
104     NonLeafExpressionNode temp = (NonLeafExpressionNode) nlResult.getChildExps().get(0);
105     assertEquals(Operator.AND, temp.getOperator());
106     assertEquals(2, temp.getChildExps().size());
107     assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
108     assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
109     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(1);
110     assertEquals(Operator.AND, temp.getOperator());
111     assertEquals(2, temp.getChildExps().size());
112     assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
113     assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
114 
115     // (a & b) | c -> ((a & b) | c)
116     NonLeafExpressionNode exp7 = new NonLeafExpressionNode(Operator.OR, new NonLeafExpressionNode(
117         Operator.AND, new LeafExpressionNode("a"), new LeafExpressionNode("b")),
118         new LeafExpressionNode("c"));
119     result = expander.expand(exp7);
120     assertTrue(result instanceof NonLeafExpressionNode);
121     nlResult = (NonLeafExpressionNode) result;
122     assertEquals(Operator.OR, nlResult.getOperator());
123     assertEquals(2, nlResult.getChildExps().size());
124     assertEquals("c", ((LeafExpressionNode) nlResult.getChildExps().get(1)).getIdentifier());
125     nlResult = (NonLeafExpressionNode) nlResult.getChildExps().get(0);
126     assertEquals(Operator.AND, nlResult.getOperator());
127     assertEquals(2, nlResult.getChildExps().size());
128     assertEquals("a", ((LeafExpressionNode) nlResult.getChildExps().get(0)).getIdentifier());
129     assertEquals("b", ((LeafExpressionNode) nlResult.getChildExps().get(1)).getIdentifier());
130 
131     // ((a & b) | c) & d -> (((a & b) & d) | (c & d))
132     NonLeafExpressionNode exp8 = new NonLeafExpressionNode(Operator.AND);
133     exp8.addChildExp(new NonLeafExpressionNode(Operator.OR, new NonLeafExpressionNode(Operator.AND,
134         new LeafExpressionNode("a"), new LeafExpressionNode("b")), new LeafExpressionNode("c")));
135     exp8.addChildExp(new LeafExpressionNode("d"));
136     result = expander.expand(exp8);
137     assertTrue(result instanceof NonLeafExpressionNode);
138     nlResult = (NonLeafExpressionNode) result;
139     assertEquals(Operator.OR, nlResult.getOperator());
140     assertEquals(2, nlResult.getChildExps().size());
141     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(1);
142     assertEquals(Operator.AND, temp.getOperator());
143     assertEquals(2, temp.getChildExps().size());
144     assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
145     assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
146     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(0);
147     assertEquals(Operator.AND, temp.getOperator());
148     assertEquals(2, temp.getChildExps().size());
149     assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
150     temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
151     assertEquals(Operator.AND, temp.getOperator());
152     assertEquals(2, temp.getChildExps().size());
153     assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
154     assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
155 
156     // (a | b) | (c | d) -> (a | b | c | d)
157     NonLeafExpressionNode exp9 = new NonLeafExpressionNode(Operator.OR);
158     exp9.addChildExp(new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("a"),
159         new LeafExpressionNode("b")));
160     exp9.addChildExp(new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("c"),
161         new LeafExpressionNode("d")));
162     result = expander.expand(exp9);
163     assertTrue(result instanceof NonLeafExpressionNode);
164     nlResult = (NonLeafExpressionNode) result;
165     assertEquals(Operator.OR, nlResult.getOperator());
166     assertEquals(4, nlResult.getChildExps().size());
167     assertEquals("a", ((LeafExpressionNode) nlResult.getChildExps().get(0)).getIdentifier());
168     assertEquals("b", ((LeafExpressionNode) nlResult.getChildExps().get(1)).getIdentifier());
169     assertEquals("c", ((LeafExpressionNode) nlResult.getChildExps().get(2)).getIdentifier());
170     assertEquals("d", ((LeafExpressionNode) nlResult.getChildExps().get(3)).getIdentifier());
171 
172     // (a & b) & (c & d) -> (a & b & c & d)
173     NonLeafExpressionNode exp10 = new NonLeafExpressionNode(Operator.AND);
174     exp10.addChildExp(new NonLeafExpressionNode(Operator.AND, new LeafExpressionNode("a"),
175         new LeafExpressionNode("b")));
176     exp10.addChildExp(new NonLeafExpressionNode(Operator.AND, new LeafExpressionNode("c"),
177         new LeafExpressionNode("d")));
178     result = expander.expand(exp10);
179     assertTrue(result instanceof NonLeafExpressionNode);
180     nlResult = (NonLeafExpressionNode) result;
181     assertEquals(Operator.AND, nlResult.getOperator());
182     assertEquals(4, nlResult.getChildExps().size());
183     assertEquals("a", ((LeafExpressionNode) nlResult.getChildExps().get(0)).getIdentifier());
184     assertEquals("b", ((LeafExpressionNode) nlResult.getChildExps().get(1)).getIdentifier());
185     assertEquals("c", ((LeafExpressionNode) nlResult.getChildExps().get(2)).getIdentifier());
186     assertEquals("d", ((LeafExpressionNode) nlResult.getChildExps().get(3)).getIdentifier());
187 
188     // (a | b) & (c | d) -> ((a & c) | (a & d) | (b & c) | (b & d))
189     NonLeafExpressionNode exp11 = new NonLeafExpressionNode(Operator.AND);
190     exp11.addChildExp(new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("a"),
191         new LeafExpressionNode("b")));
192     exp11.addChildExp(new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("c"),
193         new LeafExpressionNode("d")));
194     result = expander.expand(exp11);
195     assertTrue(result instanceof NonLeafExpressionNode);
196     nlResult = (NonLeafExpressionNode) result;
197     assertEquals(Operator.OR, nlResult.getOperator());
198     assertEquals(4, nlResult.getChildExps().size());
199     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(0);
200     assertEquals(Operator.AND, temp.getOperator());
201     assertEquals(2, temp.getChildExps().size());
202     assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
203     assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
204     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(1);
205     assertEquals(Operator.AND, temp.getOperator());
206     assertEquals(2, temp.getChildExps().size());
207     assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
208     assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
209     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(2);
210     assertEquals(Operator.AND, temp.getOperator());
211     assertEquals(2, temp.getChildExps().size());
212     assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
213     assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
214     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(3);
215     assertEquals(Operator.AND, temp.getOperator());
216     assertEquals(2, temp.getChildExps().size());
217     assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
218     assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
219 
220     // (((a | b) | c) | d) & e -> ((a & e) | (b & e) | (c & e) | (d & e))
221     NonLeafExpressionNode exp12 = new NonLeafExpressionNode(Operator.AND);
222     NonLeafExpressionNode tempExp1 = new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode(
223         "a"), new LeafExpressionNode("b"));
224     NonLeafExpressionNode tempExp2 = new NonLeafExpressionNode(Operator.OR, tempExp1,
225         new LeafExpressionNode("c"));
226     NonLeafExpressionNode tempExp3 = new NonLeafExpressionNode(Operator.OR, tempExp2,
227         new LeafExpressionNode("d"));
228     exp12.addChildExp(tempExp3);
229     exp12.addChildExp(new LeafExpressionNode("e"));
230     result = expander.expand(exp12);
231     assertTrue(result instanceof NonLeafExpressionNode);
232     nlResult = (NonLeafExpressionNode) result;
233     assertEquals(Operator.OR, nlResult.getOperator());
234     assertEquals(4, nlResult.getChildExps().size());
235     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(0);
236     assertEquals(Operator.AND, temp.getOperator());
237     assertEquals(2, temp.getChildExps().size());
238     assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
239     assertEquals("e", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
240     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(1);
241     assertEquals(Operator.AND, temp.getOperator());
242     assertEquals(2, temp.getChildExps().size());
243     assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
244     assertEquals("e", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
245     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(2);
246     assertEquals(Operator.AND, temp.getOperator());
247     assertEquals(2, temp.getChildExps().size());
248     assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
249     assertEquals("e", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
250     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(3);
251     assertEquals(Operator.AND, temp.getOperator());
252     assertEquals(2, temp.getChildExps().size());
253     assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
254     assertEquals("e", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
255 
256     // (a | b | c) & d -> ((a & d) | (b & d) | (c & d))
257     NonLeafExpressionNode exp13 = new NonLeafExpressionNode(Operator.AND,
258         new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("a"), new LeafExpressionNode(
259             "b"), new LeafExpressionNode("c")), new LeafExpressionNode("d"));
260     result = expander.expand(exp13);
261     assertTrue(result instanceof NonLeafExpressionNode);
262     nlResult = (NonLeafExpressionNode) result;
263     assertEquals(Operator.OR, nlResult.getOperator());
264     assertEquals(3, nlResult.getChildExps().size());
265     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(0);
266     assertEquals(Operator.AND, temp.getOperator());
267     assertEquals(2, temp.getChildExps().size());
268     assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
269     assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
270     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(1);
271     assertEquals(Operator.AND, temp.getOperator());
272     assertEquals(2, temp.getChildExps().size());
273     assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
274     assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
275     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(2);
276     assertEquals(Operator.AND, temp.getOperator());
277     assertEquals(2, temp.getChildExps().size());
278     assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
279     assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
280 
281     // ((a | b) & (c | d)) & (e | f) -> (((a & c) & e) | ((a & c) & f) | ((a & d) & e) | ((a & d) &
282     // f) | ((b & c) & e) | ((b & c) & f) | ((b & d) & e) | ((b & d) & f))
283     NonLeafExpressionNode exp15 = new NonLeafExpressionNode(Operator.AND);
284     NonLeafExpressionNode temp1 = new NonLeafExpressionNode(Operator.AND);
285     temp1.addChildExp(new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("a"),
286         new LeafExpressionNode("b")));
287     temp1.addChildExp(new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("c"),
288         new LeafExpressionNode("d")));
289     exp15.addChildExp(temp1);
290     exp15.addChildExp(new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("e"),
291         new LeafExpressionNode("f")));
292     result = expander.expand(exp15);
293     assertTrue(result instanceof NonLeafExpressionNode);
294     nlResult = (NonLeafExpressionNode) result;
295     assertEquals(Operator.OR, nlResult.getOperator());
296     assertEquals(8, nlResult.getChildExps().size());
297     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(0);
298     assertEquals(Operator.AND, temp.getOperator());
299     assertEquals(2, temp.getChildExps().size());
300     assertEquals("e", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
301     temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
302     assertEquals(Operator.AND, temp.getOperator());
303     assertEquals(2, temp.getChildExps().size());
304     assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
305     assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
306 
307     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(1);
308     assertEquals(Operator.AND, temp.getOperator());
309     assertEquals(2, temp.getChildExps().size());
310     assertEquals("f", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
311     temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
312     assertEquals(Operator.AND, temp.getOperator());
313     assertEquals(2, temp.getChildExps().size());
314     assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
315     assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
316 
317     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(2);
318     assertEquals(Operator.AND, temp.getOperator());
319     assertEquals(2, temp.getChildExps().size());
320     assertEquals("e", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
321     temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
322     assertEquals(Operator.AND, temp.getOperator());
323     assertEquals(2, temp.getChildExps().size());
324     assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
325     assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
326 
327     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(3);
328     assertEquals(Operator.AND, temp.getOperator());
329     assertEquals(2, temp.getChildExps().size());
330     assertEquals("f", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
331     temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
332     assertEquals(Operator.AND, temp.getOperator());
333     assertEquals(2, temp.getChildExps().size());
334     assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
335     assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
336 
337     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(4);
338     assertEquals(Operator.AND, temp.getOperator());
339     assertEquals(2, temp.getChildExps().size());
340     assertEquals("e", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
341     temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
342     assertEquals(Operator.AND, temp.getOperator());
343     assertEquals(2, temp.getChildExps().size());
344     assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
345     assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
346 
347     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(5);
348     assertEquals(Operator.AND, temp.getOperator());
349     assertEquals(2, temp.getChildExps().size());
350     assertEquals("f", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
351     temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
352     assertEquals(Operator.AND, temp.getOperator());
353     assertEquals(2, temp.getChildExps().size());
354     assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
355     assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
356 
357     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(6);
358     assertEquals(Operator.AND, temp.getOperator());
359     assertEquals(2, temp.getChildExps().size());
360     assertEquals("e", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
361     temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
362     assertEquals(Operator.AND, temp.getOperator());
363     assertEquals(2, temp.getChildExps().size());
364     assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
365     assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
366 
367     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(7);
368     assertEquals(Operator.AND, temp.getOperator());
369     assertEquals(2, temp.getChildExps().size());
370     assertEquals("f", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
371     temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
372     assertEquals(Operator.AND, temp.getOperator());
373     assertEquals(2, temp.getChildExps().size());
374     assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
375     assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
376 
377     // !(a | b) -> ((!a) & (!b))
378     NonLeafExpressionNode exp16 = new NonLeafExpressionNode(Operator.NOT,
379         new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("a"), new LeafExpressionNode(
380             "b")));
381     result = expander.expand(exp16);
382     assertTrue(result instanceof NonLeafExpressionNode);
383     nlResult = (NonLeafExpressionNode) result;
384     assertEquals(Operator.AND, nlResult.getOperator());
385     assertEquals(2, nlResult.getChildExps().size());
386     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(0);
387     assertEquals(Operator.NOT, temp.getOperator());
388     assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
389     temp = (NonLeafExpressionNode) nlResult.getChildExps().get(1);
390     assertEquals(Operator.NOT, temp.getOperator());
391     assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
392   }
393 }
394