001: package org.drools.reteoo;
002:
003: /*
004: * Copyright 2005 JBoss Inc
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * 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: */
018:
019: import org.drools.DroolsTestCase;
020: import org.drools.FactException;
021: import org.drools.RuleBaseFactory;
022: import org.drools.common.DefaultFactHandle;
023: import org.drools.common.PropagationContextImpl;
024: import org.drools.spi.PropagationContext;
025: import org.drools.util.TupleHashTable;
026:
027: public class EvalConditionNodeTest extends DroolsTestCase {
028: private PropagationContext context;
029: private ReteooWorkingMemory workingMemory;
030:
031: public EvalConditionNodeTest(final String name) {
032: super (name);
033: }
034:
035: public void setUp() {
036: this .context = new PropagationContextImpl(0,
037: PropagationContext.ASSERTION, null, null);
038:
039: this .workingMemory = new ReteooWorkingMemory(1,
040: (ReteooRuleBase) RuleBaseFactory.newRuleBase());
041: }
042:
043: public void testAttach() throws Exception {
044: final MockTupleSource source = new MockTupleSource(12);
045:
046: final EvalConditionNode node = new EvalConditionNode(18,
047: source, new MockEvalCondition(true));
048:
049: assertEquals(18, node.getId());
050:
051: assertEquals(0, source.getAttached());
052:
053: node.attach();
054:
055: assertEquals(1, source.getAttached());
056:
057: }
058:
059: public void testMemory() {
060: final ReteooWorkingMemory workingMemory = new ReteooWorkingMemory(
061: 1, (ReteooRuleBase) RuleBaseFactory.newRuleBase());
062:
063: final MockTupleSource source = new MockTupleSource(12);
064:
065: final EvalConditionNode node = new EvalConditionNode(18,
066: source, new MockEvalCondition(true));
067:
068: final TupleHashTable memory = (TupleHashTable) workingMemory
069: .getNodeMemory(node);
070:
071: assertNotNull(memory);
072: }
073:
074: /**
075: * If a eval allows an incoming Object, then the Object MUST be
076: * propagated. This tests that the memory is updated
077: *
078: * @throws FactException
079: */
080: public void testAssertedAllowed() throws FactException {
081: final MockEvalCondition eval = new MockEvalCondition(true);
082:
083: // Create a test node that always returns false
084: final EvalConditionNode node = new EvalConditionNode(1,
085: new MockTupleSource(15), eval);
086:
087: final MockTupleSink sink = new MockTupleSink();
088: node.addTupleSink(sink);
089:
090: // Create the Tuple
091: final DefaultFactHandle f0 = new DefaultFactHandle(0, "stilton");
092: final ReteTuple tuple0 = new ReteTuple(f0);
093:
094: // Tuple should pass and propagate
095: node.assertTuple(tuple0, this .context, this .workingMemory);
096:
097: // Create the Tuple
098: final DefaultFactHandle f1 = new DefaultFactHandle(1, "cheddar");
099: final ReteTuple tuple1 = new ReteTuple(f1);
100:
101: // Tuple should pass and propagate
102: node.assertTuple(tuple1, this .context, this .workingMemory);
103:
104: // Check memory was populated
105: final TupleHashTable memory = (TupleHashTable) this .workingMemory
106: .getNodeMemory(node);
107:
108: assertEquals(2, memory.size());
109:
110: assertTrue(memory.contains(tuple0));
111: assertTrue(memory.contains(tuple1));
112:
113: // make sure assertions were propagated
114: assertEquals(2, sink.getAsserted().size());
115: }
116:
117: public void testAssertedAllowedThenRetract() throws FactException {
118: final MockEvalCondition eval = new MockEvalCondition(true);
119:
120: // Create a test node that always returns false
121: final EvalConditionNode node = new EvalConditionNode(1,
122: new MockTupleSource(15), eval);
123:
124: final MockTupleSink sink = new MockTupleSink();
125: node.addTupleSink(sink);
126:
127: // Create the Tuple
128: final DefaultFactHandle f0 = new DefaultFactHandle(0, "stilton");
129: final ReteTuple tuple0 = new ReteTuple(f0);
130:
131: // Tuple should pass and propagate
132: node.assertTuple(tuple0, this .context, this .workingMemory);
133:
134: // we create and retract two tuples, checking the linkedtuples is null for JBRULES-246 "NPE on retract()"
135: // Create the Tuple
136: final DefaultFactHandle f1 = new DefaultFactHandle(1, "cheddar");
137: final ReteTuple tuple1 = new ReteTuple(f1);
138:
139: // Tuple should pass and propagate
140: node.assertTuple(tuple1, this .context, this .workingMemory);
141:
142: // Check memory was populated
143: final TupleHashTable memory = (TupleHashTable) this .workingMemory
144: .getNodeMemory(node);
145:
146: assertEquals(2, memory.size());
147: assertTrue(memory.contains(tuple0));
148: assertTrue(memory.contains(tuple1));
149:
150: // make sure assertions were propagated
151: assertEquals(2, sink.getAsserted().size());
152:
153: // Now test that the fact is retracted correctly
154: node.retractTuple(tuple0, this .context, this .workingMemory);
155:
156: // Now test that the fact is retracted correctly
157: assertEquals(1, memory.size());
158:
159: assertTrue(memory.contains(tuple1));
160:
161: // make sure retractions were propagated
162: assertEquals(1, sink.getRetracted().size());
163:
164: // Now test that the fact is retracted correctly
165: node.retractTuple(tuple1, this .context, this .workingMemory);
166:
167: // Now test that the fact is retracted correctly
168: assertEquals(0, memory.size());
169:
170: // make sure retractions were propagated
171: assertEquals(2, sink.getRetracted().size());
172: }
173:
174: public void testAssertedNotAllowed() throws FactException {
175: final MockEvalCondition eval = new MockEvalCondition(false);
176:
177: // Create a test node that always returns false
178: final EvalConditionNode node = new EvalConditionNode(1,
179: new MockTupleSource(15), eval);
180:
181: final MockTupleSink sink = new MockTupleSink();
182: node.addTupleSink(sink);
183:
184: // Create the Tuple
185: final DefaultFactHandle f0 = new DefaultFactHandle(0, "stilton");
186: final ReteTuple tuple0 = new ReteTuple(f0);
187:
188: // Tuple should fail and not propagate
189: node.assertTuple(tuple0, this .context, this .workingMemory);
190:
191: // Create the Tuple
192: final DefaultFactHandle f1 = new DefaultFactHandle(1, "cheddar");
193: final ReteTuple tuple1 = new ReteTuple(f1);
194:
195: // Tuple should fail and not propagate
196: node.assertTuple(tuple1, this .context, this .workingMemory);
197:
198: // Check memory was not populated
199: final TupleHashTable memory = (TupleHashTable) this .workingMemory
200: .getNodeMemory(node);
201:
202: assertEquals(0, memory.size());
203:
204: // test no propagations
205: assertEquals(0, sink.getAsserted().size());
206: assertEquals(0, sink.getRetracted().size());
207: }
208:
209: public void testUpdateWithMemory() throws FactException {
210: // If no child nodes have children then we need to re-process the left
211: // and right memories
212: // as a joinnode does not store the resulting tuples
213: final ReteooWorkingMemory workingMemory = new ReteooWorkingMemory(
214: 1, (ReteooRuleBase) RuleBaseFactory.newRuleBase());
215:
216: // Creat the object source so we can detect the alphaNode telling it to
217: // propate its contents
218: //final MockTupleSource source = new MockTupleSource( 1 );
219:
220: /* Create a test node that always returns true */
221: final EvalConditionNode node = new EvalConditionNode(1,
222: new MockTupleSource(15), new MockEvalCondition(true));
223:
224: // Add the first tuple sink and assert a tuple and object
225: // The sink has no memory
226: final MockTupleSink sink1 = new MockTupleSink(2);
227: node.addTupleSink(sink1);
228:
229: final DefaultFactHandle f0 = new DefaultFactHandle(0, "string0");
230:
231: final ReteTuple tuple1 = new ReteTuple(f0);
232:
233: node.assertTuple(tuple1, this .context, workingMemory);
234:
235: assertLength(1, sink1.getAsserted());
236:
237: // Add the new sink, this should be updated from the re-processed
238: // joinnode memory
239: final MockTupleSink sink2 = new MockTupleSink(3);
240: node.addTupleSink(sink2);
241: assertLength(0, sink2.getAsserted());
242:
243: node.updateSink(sink2, this .context, workingMemory);
244:
245: assertLength(1, sink2.getAsserted());
246: }
247: }
|