001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.security.visibility;
019
020import static org.junit.Assert.assertEquals;
021import static org.junit.Assert.assertTrue;
022
023import org.apache.hadoop.hbase.HBaseClassTestRule;
024import org.apache.hadoop.hbase.security.visibility.expression.ExpressionNode;
025import org.apache.hadoop.hbase.security.visibility.expression.LeafExpressionNode;
026import org.apache.hadoop.hbase.security.visibility.expression.NonLeafExpressionNode;
027import org.apache.hadoop.hbase.security.visibility.expression.Operator;
028import org.apache.hadoop.hbase.testclassification.SecurityTests;
029import org.apache.hadoop.hbase.testclassification.SmallTests;
030import org.junit.ClassRule;
031import org.junit.Test;
032import org.junit.experimental.categories.Category;
033
034@Category({SecurityTests.class, SmallTests.class})
035public class TestExpressionExpander {
036
037  @ClassRule
038  public static final HBaseClassTestRule CLASS_RULE =
039      HBaseClassTestRule.forClass(TestExpressionExpander.class);
040
041  @Test
042  public void testPositiveCases() throws Exception {
043    ExpressionExpander expander = new ExpressionExpander();
044
045    // (!a) -> (!a)
046    NonLeafExpressionNode exp1 = new NonLeafExpressionNode(Operator.NOT,
047        new LeafExpressionNode("a"));
048    ExpressionNode result = expander.expand(exp1);
049    assertTrue(result instanceof NonLeafExpressionNode);
050    NonLeafExpressionNode nlResult = (NonLeafExpressionNode) result;
051    assertEquals(Operator.NOT, nlResult.getOperator());
052    assertEquals("a", ((LeafExpressionNode) nlResult.getChildExps().get(0)).getIdentifier());
053
054    // (a | b) -> (a | b)
055    NonLeafExpressionNode exp2 = new NonLeafExpressionNode(Operator.OR,
056        new LeafExpressionNode("a"), new LeafExpressionNode("b"));
057    result = expander.expand(exp2);
058    assertTrue(result instanceof NonLeafExpressionNode);
059    nlResult = (NonLeafExpressionNode) result;
060    assertEquals(Operator.OR, nlResult.getOperator());
061    assertEquals(2, nlResult.getChildExps().size());
062    assertEquals("a", ((LeafExpressionNode) nlResult.getChildExps().get(0)).getIdentifier());
063    assertEquals("b", ((LeafExpressionNode) nlResult.getChildExps().get(1)).getIdentifier());
064
065    // (a & b) -> (a & b)
066    NonLeafExpressionNode exp3 = new NonLeafExpressionNode(Operator.AND,
067        new LeafExpressionNode("a"), new LeafExpressionNode("b"));
068    result = expander.expand(exp3);
069    assertTrue(result instanceof NonLeafExpressionNode);
070    nlResult = (NonLeafExpressionNode) result;
071    assertEquals(Operator.AND, nlResult.getOperator());
072    assertEquals(2, nlResult.getChildExps().size());
073    assertEquals("a", ((LeafExpressionNode) nlResult.getChildExps().get(0)).getIdentifier());
074    assertEquals("b", ((LeafExpressionNode) nlResult.getChildExps().get(1)).getIdentifier());
075
076    // ((a | b) | c) -> (a | b | c)
077    NonLeafExpressionNode exp4 = new NonLeafExpressionNode(Operator.OR, new NonLeafExpressionNode(
078        Operator.OR, new LeafExpressionNode("a"), new LeafExpressionNode("b")),
079        new LeafExpressionNode("c"));
080    result = expander.expand(exp4);
081    assertTrue(result instanceof NonLeafExpressionNode);
082    nlResult = (NonLeafExpressionNode) result;
083    assertEquals(Operator.OR, nlResult.getOperator());
084    assertEquals(3, nlResult.getChildExps().size());
085    assertEquals("a", ((LeafExpressionNode) nlResult.getChildExps().get(0)).getIdentifier());
086    assertEquals("b", ((LeafExpressionNode) nlResult.getChildExps().get(1)).getIdentifier());
087    assertEquals("c", ((LeafExpressionNode) nlResult.getChildExps().get(2)).getIdentifier());
088
089    // ((a & b) & c) -> (a & b & c)
090    NonLeafExpressionNode exp5 = new NonLeafExpressionNode(Operator.AND, new NonLeafExpressionNode(
091        Operator.AND, new LeafExpressionNode("a"), new LeafExpressionNode("b")),
092        new LeafExpressionNode("c"));
093    result = expander.expand(exp5);
094    assertTrue(result instanceof NonLeafExpressionNode);
095    nlResult = (NonLeafExpressionNode) result;
096    assertEquals(Operator.AND, nlResult.getOperator());
097    assertEquals(3, nlResult.getChildExps().size());
098    assertEquals("a", ((LeafExpressionNode) nlResult.getChildExps().get(0)).getIdentifier());
099    assertEquals("b", ((LeafExpressionNode) nlResult.getChildExps().get(1)).getIdentifier());
100    assertEquals("c", ((LeafExpressionNode) nlResult.getChildExps().get(2)).getIdentifier());
101
102    // (a | b) & c -> ((a & c) | (b & c))
103    NonLeafExpressionNode exp6 = new NonLeafExpressionNode(Operator.AND, new NonLeafExpressionNode(
104        Operator.OR, new LeafExpressionNode("a"), new LeafExpressionNode("b")),
105        new LeafExpressionNode("c"));
106    result = expander.expand(exp6);
107    assertTrue(result instanceof NonLeafExpressionNode);
108    nlResult = (NonLeafExpressionNode) result;
109    assertEquals(Operator.OR, nlResult.getOperator());
110    assertEquals(2, nlResult.getChildExps().size());
111    NonLeafExpressionNode temp = (NonLeafExpressionNode) nlResult.getChildExps().get(0);
112    assertEquals(Operator.AND, temp.getOperator());
113    assertEquals(2, temp.getChildExps().size());
114    assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
115    assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
116    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(1);
117    assertEquals(Operator.AND, temp.getOperator());
118    assertEquals(2, temp.getChildExps().size());
119    assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
120    assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
121
122    // (a & b) | c -> ((a & b) | c)
123    NonLeafExpressionNode exp7 = new NonLeafExpressionNode(Operator.OR, new NonLeafExpressionNode(
124        Operator.AND, new LeafExpressionNode("a"), new LeafExpressionNode("b")),
125        new LeafExpressionNode("c"));
126    result = expander.expand(exp7);
127    assertTrue(result instanceof NonLeafExpressionNode);
128    nlResult = (NonLeafExpressionNode) result;
129    assertEquals(Operator.OR, nlResult.getOperator());
130    assertEquals(2, nlResult.getChildExps().size());
131    assertEquals("c", ((LeafExpressionNode) nlResult.getChildExps().get(1)).getIdentifier());
132    nlResult = (NonLeafExpressionNode) nlResult.getChildExps().get(0);
133    assertEquals(Operator.AND, nlResult.getOperator());
134    assertEquals(2, nlResult.getChildExps().size());
135    assertEquals("a", ((LeafExpressionNode) nlResult.getChildExps().get(0)).getIdentifier());
136    assertEquals("b", ((LeafExpressionNode) nlResult.getChildExps().get(1)).getIdentifier());
137
138    // ((a & b) | c) & d -> (((a & b) & d) | (c & d))
139    NonLeafExpressionNode exp8 = new NonLeafExpressionNode(Operator.AND);
140    exp8.addChildExp(new NonLeafExpressionNode(Operator.OR, new NonLeafExpressionNode(Operator.AND,
141        new LeafExpressionNode("a"), new LeafExpressionNode("b")), new LeafExpressionNode("c")));
142    exp8.addChildExp(new LeafExpressionNode("d"));
143    result = expander.expand(exp8);
144    assertTrue(result instanceof NonLeafExpressionNode);
145    nlResult = (NonLeafExpressionNode) result;
146    assertEquals(Operator.OR, nlResult.getOperator());
147    assertEquals(2, nlResult.getChildExps().size());
148    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(1);
149    assertEquals(Operator.AND, temp.getOperator());
150    assertEquals(2, temp.getChildExps().size());
151    assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
152    assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
153    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(0);
154    assertEquals(Operator.AND, temp.getOperator());
155    assertEquals(2, temp.getChildExps().size());
156    assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
157    temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
158    assertEquals(Operator.AND, temp.getOperator());
159    assertEquals(2, temp.getChildExps().size());
160    assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
161    assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
162
163    // (a | b) | (c | d) -> (a | b | c | d)
164    NonLeafExpressionNode exp9 = new NonLeafExpressionNode(Operator.OR);
165    exp9.addChildExp(new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("a"),
166        new LeafExpressionNode("b")));
167    exp9.addChildExp(new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("c"),
168        new LeafExpressionNode("d")));
169    result = expander.expand(exp9);
170    assertTrue(result instanceof NonLeafExpressionNode);
171    nlResult = (NonLeafExpressionNode) result;
172    assertEquals(Operator.OR, nlResult.getOperator());
173    assertEquals(4, nlResult.getChildExps().size());
174    assertEquals("a", ((LeafExpressionNode) nlResult.getChildExps().get(0)).getIdentifier());
175    assertEquals("b", ((LeafExpressionNode) nlResult.getChildExps().get(1)).getIdentifier());
176    assertEquals("c", ((LeafExpressionNode) nlResult.getChildExps().get(2)).getIdentifier());
177    assertEquals("d", ((LeafExpressionNode) nlResult.getChildExps().get(3)).getIdentifier());
178
179    // (a & b) & (c & d) -> (a & b & c & d)
180    NonLeafExpressionNode exp10 = new NonLeafExpressionNode(Operator.AND);
181    exp10.addChildExp(new NonLeafExpressionNode(Operator.AND, new LeafExpressionNode("a"),
182        new LeafExpressionNode("b")));
183    exp10.addChildExp(new NonLeafExpressionNode(Operator.AND, new LeafExpressionNode("c"),
184        new LeafExpressionNode("d")));
185    result = expander.expand(exp10);
186    assertTrue(result instanceof NonLeafExpressionNode);
187    nlResult = (NonLeafExpressionNode) result;
188    assertEquals(Operator.AND, nlResult.getOperator());
189    assertEquals(4, nlResult.getChildExps().size());
190    assertEquals("a", ((LeafExpressionNode) nlResult.getChildExps().get(0)).getIdentifier());
191    assertEquals("b", ((LeafExpressionNode) nlResult.getChildExps().get(1)).getIdentifier());
192    assertEquals("c", ((LeafExpressionNode) nlResult.getChildExps().get(2)).getIdentifier());
193    assertEquals("d", ((LeafExpressionNode) nlResult.getChildExps().get(3)).getIdentifier());
194
195    // (a | b) & (c | d) -> ((a & c) | (a & d) | (b & c) | (b & d))
196    NonLeafExpressionNode exp11 = new NonLeafExpressionNode(Operator.AND);
197    exp11.addChildExp(new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("a"),
198        new LeafExpressionNode("b")));
199    exp11.addChildExp(new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("c"),
200        new LeafExpressionNode("d")));
201    result = expander.expand(exp11);
202    assertTrue(result instanceof NonLeafExpressionNode);
203    nlResult = (NonLeafExpressionNode) result;
204    assertEquals(Operator.OR, nlResult.getOperator());
205    assertEquals(4, nlResult.getChildExps().size());
206    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(0);
207    assertEquals(Operator.AND, temp.getOperator());
208    assertEquals(2, temp.getChildExps().size());
209    assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
210    assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
211    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(1);
212    assertEquals(Operator.AND, temp.getOperator());
213    assertEquals(2, temp.getChildExps().size());
214    assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
215    assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
216    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(2);
217    assertEquals(Operator.AND, temp.getOperator());
218    assertEquals(2, temp.getChildExps().size());
219    assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
220    assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
221    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(3);
222    assertEquals(Operator.AND, temp.getOperator());
223    assertEquals(2, temp.getChildExps().size());
224    assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
225    assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
226
227    // (((a | b) | c) | d) & e -> ((a & e) | (b & e) | (c & e) | (d & e))
228    NonLeafExpressionNode exp12 = new NonLeafExpressionNode(Operator.AND);
229    NonLeafExpressionNode tempExp1 = new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode(
230        "a"), new LeafExpressionNode("b"));
231    NonLeafExpressionNode tempExp2 = new NonLeafExpressionNode(Operator.OR, tempExp1,
232        new LeafExpressionNode("c"));
233    NonLeafExpressionNode tempExp3 = new NonLeafExpressionNode(Operator.OR, tempExp2,
234        new LeafExpressionNode("d"));
235    exp12.addChildExp(tempExp3);
236    exp12.addChildExp(new LeafExpressionNode("e"));
237    result = expander.expand(exp12);
238    assertTrue(result instanceof NonLeafExpressionNode);
239    nlResult = (NonLeafExpressionNode) result;
240    assertEquals(Operator.OR, nlResult.getOperator());
241    assertEquals(4, nlResult.getChildExps().size());
242    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(0);
243    assertEquals(Operator.AND, temp.getOperator());
244    assertEquals(2, temp.getChildExps().size());
245    assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
246    assertEquals("e", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
247    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(1);
248    assertEquals(Operator.AND, temp.getOperator());
249    assertEquals(2, temp.getChildExps().size());
250    assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
251    assertEquals("e", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
252    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(2);
253    assertEquals(Operator.AND, temp.getOperator());
254    assertEquals(2, temp.getChildExps().size());
255    assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
256    assertEquals("e", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
257    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(3);
258    assertEquals(Operator.AND, temp.getOperator());
259    assertEquals(2, temp.getChildExps().size());
260    assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
261    assertEquals("e", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
262
263    // (a | b | c) & d -> ((a & d) | (b & d) | (c & d))
264    NonLeafExpressionNode exp13 = new NonLeafExpressionNode(Operator.AND,
265        new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("a"), new LeafExpressionNode(
266            "b"), new LeafExpressionNode("c")), new LeafExpressionNode("d"));
267    result = expander.expand(exp13);
268    assertTrue(result instanceof NonLeafExpressionNode);
269    nlResult = (NonLeafExpressionNode) result;
270    assertEquals(Operator.OR, nlResult.getOperator());
271    assertEquals(3, nlResult.getChildExps().size());
272    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(0);
273    assertEquals(Operator.AND, temp.getOperator());
274    assertEquals(2, temp.getChildExps().size());
275    assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
276    assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
277    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(1);
278    assertEquals(Operator.AND, temp.getOperator());
279    assertEquals(2, temp.getChildExps().size());
280    assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
281    assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
282    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(2);
283    assertEquals(Operator.AND, temp.getOperator());
284    assertEquals(2, temp.getChildExps().size());
285    assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
286    assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
287
288    // ((a | b) & (c | d)) & (e | f) -> (((a & c) & e) | ((a & c) & f) | ((a & d) & e) | ((a & d) &
289    // f) | ((b & c) & e) | ((b & c) & f) | ((b & d) & e) | ((b & d) & f))
290    NonLeafExpressionNode exp15 = new NonLeafExpressionNode(Operator.AND);
291    NonLeafExpressionNode temp1 = new NonLeafExpressionNode(Operator.AND);
292    temp1.addChildExp(new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("a"),
293        new LeafExpressionNode("b")));
294    temp1.addChildExp(new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("c"),
295        new LeafExpressionNode("d")));
296    exp15.addChildExp(temp1);
297    exp15.addChildExp(new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("e"),
298        new LeafExpressionNode("f")));
299    result = expander.expand(exp15);
300    assertTrue(result instanceof NonLeafExpressionNode);
301    nlResult = (NonLeafExpressionNode) result;
302    assertEquals(Operator.OR, nlResult.getOperator());
303    assertEquals(8, nlResult.getChildExps().size());
304    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(0);
305    assertEquals(Operator.AND, temp.getOperator());
306    assertEquals(2, temp.getChildExps().size());
307    assertEquals("e", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
308    temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
309    assertEquals(Operator.AND, temp.getOperator());
310    assertEquals(2, temp.getChildExps().size());
311    assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
312    assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
313
314    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(1);
315    assertEquals(Operator.AND, temp.getOperator());
316    assertEquals(2, temp.getChildExps().size());
317    assertEquals("f", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
318    temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
319    assertEquals(Operator.AND, temp.getOperator());
320    assertEquals(2, temp.getChildExps().size());
321    assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
322    assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
323
324    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(2);
325    assertEquals(Operator.AND, temp.getOperator());
326    assertEquals(2, temp.getChildExps().size());
327    assertEquals("e", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
328    temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
329    assertEquals(Operator.AND, temp.getOperator());
330    assertEquals(2, temp.getChildExps().size());
331    assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
332    assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
333
334    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(3);
335    assertEquals(Operator.AND, temp.getOperator());
336    assertEquals(2, temp.getChildExps().size());
337    assertEquals("f", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
338    temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
339    assertEquals(Operator.AND, temp.getOperator());
340    assertEquals(2, temp.getChildExps().size());
341    assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
342    assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
343
344    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(4);
345    assertEquals(Operator.AND, temp.getOperator());
346    assertEquals(2, temp.getChildExps().size());
347    assertEquals("e", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
348    temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
349    assertEquals(Operator.AND, temp.getOperator());
350    assertEquals(2, temp.getChildExps().size());
351    assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
352    assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
353
354    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(5);
355    assertEquals(Operator.AND, temp.getOperator());
356    assertEquals(2, temp.getChildExps().size());
357    assertEquals("f", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
358    temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
359    assertEquals(Operator.AND, temp.getOperator());
360    assertEquals(2, temp.getChildExps().size());
361    assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
362    assertEquals("c", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
363
364    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(6);
365    assertEquals(Operator.AND, temp.getOperator());
366    assertEquals(2, temp.getChildExps().size());
367    assertEquals("e", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
368    temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
369    assertEquals(Operator.AND, temp.getOperator());
370    assertEquals(2, temp.getChildExps().size());
371    assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
372    assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
373
374    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(7);
375    assertEquals(Operator.AND, temp.getOperator());
376    assertEquals(2, temp.getChildExps().size());
377    assertEquals("f", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
378    temp = (NonLeafExpressionNode) temp.getChildExps().get(0);
379    assertEquals(Operator.AND, temp.getOperator());
380    assertEquals(2, temp.getChildExps().size());
381    assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
382    assertEquals("d", ((LeafExpressionNode) temp.getChildExps().get(1)).getIdentifier());
383
384    // !(a | b) -> ((!a) & (!b))
385    NonLeafExpressionNode exp16 = new NonLeafExpressionNode(Operator.NOT,
386        new NonLeafExpressionNode(Operator.OR, new LeafExpressionNode("a"), new LeafExpressionNode(
387            "b")));
388    result = expander.expand(exp16);
389    assertTrue(result instanceof NonLeafExpressionNode);
390    nlResult = (NonLeafExpressionNode) result;
391    assertEquals(Operator.AND, nlResult.getOperator());
392    assertEquals(2, nlResult.getChildExps().size());
393    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(0);
394    assertEquals(Operator.NOT, temp.getOperator());
395    assertEquals("a", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
396    temp = (NonLeafExpressionNode) nlResult.getChildExps().get(1);
397    assertEquals(Operator.NOT, temp.getOperator());
398    assertEquals("b", ((LeafExpressionNode) temp.getChildExps().get(0)).getIdentifier());
399  }
400}