001: /*
002: * Copyright 2005 JBoss Inc
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.drools.reteoo;
017:
018: import junit.framework.Assert;
019:
020: import org.drools.DroolsTestCase;
021: import org.drools.RuleBaseConfiguration;
022: import org.drools.RuleBaseFactory;
023: import org.drools.base.ClassObjectType;
024: import org.drools.common.DefaultFactHandle;
025: import org.drools.common.InternalFactHandle;
026: import org.drools.common.InternalWorkingMemory;
027: import org.drools.common.PropagationContextImpl;
028: import org.drools.reteoo.AccumulateNode.AccumulateMemory;
029: import org.drools.rule.Accumulate;
030: import org.drools.rule.Declaration;
031: import org.drools.rule.Pattern;
032: import org.drools.rule.Rule;
033: import org.drools.spi.MockConstraint;
034: import org.drools.spi.ObjectType;
035: import org.drools.spi.PropagationContext;
036:
037: /**
038: * A test case for AccumulateNode
039: *
040: * @author etirelli
041: */
042: public class AccumulateNodeTest extends DroolsTestCase {
043:
044: Rule rule;
045: PropagationContext context;
046: ReteooWorkingMemory workingMemory;
047: MockObjectSource objectSource;
048: MockTupleSource tupleSource;
049: MockTupleSink sink;
050: BetaNode node;
051: BetaMemory memory;
052: MockConstraint constraint = new MockConstraint();
053: MockAccumulator accumulator;
054: Accumulate accumulate;
055:
056: /* (non-Javadoc)
057: * @see junit.framework.TestCase#setUp()
058: */
059: protected void setUp() throws Exception {
060: super .setUp();
061: this .rule = new Rule("test-rule");
062: this .context = new PropagationContextImpl(0,
063: PropagationContext.ASSERTION, null, null);
064: this .workingMemory = new ReteooWorkingMemory(1,
065: (ReteooRuleBase) RuleBaseFactory.newRuleBase());
066:
067: this .tupleSource = new MockTupleSource(4);
068: this .objectSource = new MockObjectSource(4);
069: this .sink = new MockTupleSink();
070:
071: this .accumulator = new MockAccumulator();
072:
073: final ObjectType srcObjType = new ClassObjectType(String.class);
074: final Pattern sourcePattern = new Pattern(0, srcObjType);
075: this .accumulate = new Accumulate(sourcePattern,
076: new Declaration[0], new Declaration[0],
077: this .accumulator);
078:
079: this .node = new AccumulateNode(15, this .tupleSource,
080: this .objectSource, this .accumulate);
081:
082: this .node.addTupleSink(this .sink);
083:
084: this .memory = ((AccumulateMemory) this .workingMemory
085: .getNodeMemory(this .node)).betaMemory;
086:
087: // check memories are empty
088: assertEquals(0, this .memory.getTupleMemory().size());
089: assertEquals(0, this .memory.getFactHandleMemory().size());
090: }
091:
092: /* (non-Javadoc)
093: * @see junit.framework.TestCase#tearDown()
094: */
095: protected void tearDown() throws Exception {
096: super .tearDown();
097: }
098:
099: /**
100: * Test method for {@link org.drools.reteoo.AccumulateNode#updateNewNode(InternalWorkingMemory, org.drools.spi.PropagationContext)}.
101: */
102: public void testUpdateSink() {
103: this .node.updateSink(this .sink, this .context,
104: this .workingMemory);
105: Assert.assertEquals("No tuple should be propagated", 0,
106: this .sink.getAsserted().size());
107:
108: this .node.assertTuple(new ReteTuple(this .workingMemory
109: .getFactHandleFactory().newFactHandle("cheese")),
110: this .context, this .workingMemory);
111: this .node.assertTuple(new ReteTuple(this .workingMemory
112: .getFactHandleFactory().newFactHandle("other cheese")),
113: this .context, this .workingMemory);
114:
115: Assert.assertEquals("Two tuples should have been propagated",
116: 2, this .sink.getAsserted().size());
117:
118: final MockTupleSink otherSink = new MockTupleSink();
119:
120: this .node.addTupleSink(otherSink);
121: this .node.updateSink(otherSink, this .context,
122: this .workingMemory);
123:
124: Assert.assertEquals("Two tuples should have been propagated",
125: 2, otherSink.getAsserted().size());
126: }
127:
128: /**
129: * Test method for {@link org.drools.reteoo.AccumulateNode#assertTuple(org.drools.reteoo.ReteTuple, org.drools.spi.PropagationContext, org.drools.reteoo.ReteooWorkingMemory)}.
130: */
131: public void testAssertTuple() {
132: final DefaultFactHandle f0 = (DefaultFactHandle) this .workingMemory
133: .getFactHandleFactory().newFactHandle("cheese");
134: final ReteTuple tuple0 = new ReteTuple(f0);
135:
136: // assert tuple, should add one to left memory
137: this .node.assertTuple(tuple0, this .context, this .workingMemory);
138: // check memories
139: assertEquals(1, this .memory.getTupleMemory().size());
140: assertEquals(0, this .memory.getFactHandleMemory().size());
141: Assert.assertTrue(
142: "An empty matching objects list should be propagated",
143: this .accumulator.getMatchingObjects().isEmpty());
144:
145: // assert tuple, should add left memory
146: final DefaultFactHandle f1 = (DefaultFactHandle) this .workingMemory
147: .getFactHandleFactory().newFactHandle("other cheese");
148:
149: final ReteTuple tuple1 = new ReteTuple(f1);
150: this .node.assertTuple(tuple1, this .context, this .workingMemory);
151: assertEquals(2, this .memory.getTupleMemory().size());
152: Assert.assertTrue(
153: "An empty matching objects list should be propagated",
154: this .accumulator.getMatchingObjects().isEmpty());
155:
156: final TupleMemory memory = this .memory.getTupleMemory();
157: assertTrue(memory.contains(tuple0));
158: assertTrue(memory.contains(tuple1));
159:
160: Assert.assertEquals("Two tuples should have been propagated",
161: 2, this .sink.getAsserted().size());
162: }
163:
164: /**
165: * Test method for {@link org.drools.reteoo.AccumulateNode#assertTuple(org.drools.reteoo.ReteTuple, org.drools.spi.PropagationContext, org.drools.reteoo.ReteooWorkingMemory)}.
166: */
167: public void testAssertTupleWithObjects() {
168: final DefaultFactHandle f0 = (DefaultFactHandle) this .workingMemory
169: .getFactHandleFactory().newFactHandle("cheese");
170: final DefaultFactHandle f1 = (DefaultFactHandle) this .workingMemory
171: .getFactHandleFactory().newFactHandle("other cheese");
172:
173: final ReteTuple tuple0 = new ReteTuple(f0);
174:
175: this .node.assertObject(f0, this .context, this .workingMemory);
176: this .node.assertObject(f1, this .context, this .workingMemory);
177:
178: // assert tuple, should add one to left memory
179: this .node.assertTuple(tuple0, this .context, this .workingMemory);
180: // check memories
181: assertEquals(1, this .memory.getTupleMemory().size());
182: assertEquals(2, this .memory.getFactHandleMemory().size());
183: Assert.assertEquals(
184: "Wrong number of elements in matching objects list ",
185: 2, this .accumulator.getMatchingObjects().size());
186:
187: // assert tuple, should add left memory
188: final ReteTuple tuple1 = new ReteTuple(f1);
189: this .node.assertTuple(tuple1, this .context, this .workingMemory);
190: assertEquals(2, this .memory.getTupleMemory().size());
191: Assert.assertEquals(
192: "Wrong number of elements in matching objects list ",
193: 2, this .accumulator.getMatchingObjects().size());
194:
195: final TupleMemory memory = this .memory.getTupleMemory();
196: assertTrue(memory.contains(tuple0));
197: assertTrue(memory.contains(tuple1));
198:
199: Assert.assertEquals("Two tuples should have been propagated",
200: 2, this .sink.getAsserted().size());
201: }
202:
203: /**
204: * Test method for {@link org.drools.reteoo.AccumulateNode#retractTuple(org.drools.reteoo.ReteTuple, org.drools.spi.PropagationContext, org.drools.reteoo.ReteooWorkingMemory)}.
205: */
206: public void testRetractTuple() {
207: final DefaultFactHandle f0 = (DefaultFactHandle) this .workingMemory
208: .getFactHandleFactory().newFactHandle("cheese");
209:
210: final ReteTuple tuple0 = new ReteTuple(f0);
211:
212: // assert tuple, should add one to left memory
213: this .node.assertTuple(tuple0, this .context, this .workingMemory);
214: // check memories
215: assertEquals(1, this .memory.getTupleMemory().size());
216: assertEquals(0, this .memory.getFactHandleMemory().size());
217: Assert.assertTrue(
218: "An empty matching objects list should be propagated",
219: this .accumulator.getMatchingObjects().isEmpty());
220:
221: this .node
222: .retractTuple(tuple0, this .context, this .workingMemory);
223: assertEquals(0, this .memory.getTupleMemory().size());
224: assertEquals(1, this .sink.getRetracted().size());
225: assertEquals(1, this .sink.getAsserted().size());
226: }
227:
228: /**
229: * Test method for {@link org.drools.reteoo.AccumulateNode#assertObject(InternalFactHandle, org.drools.spi.PropagationContext, InternalWorkingMemory)}.
230: */
231: public void testAssertObject() {
232: final DefaultFactHandle f0 = (DefaultFactHandle) this .workingMemory
233: .getFactHandleFactory().newFactHandle("cheese");
234: final DefaultFactHandle f1 = (DefaultFactHandle) this .workingMemory
235: .getFactHandleFactory().newFactHandle("other cheese");
236:
237: final ReteTuple tuple0 = new ReteTuple(f0);
238:
239: // assert tuple, should add one to left memory
240: this .node.assertTuple(tuple0, this .context, this .workingMemory);
241:
242: // check memory
243: assertEquals(1, this .memory.getTupleMemory().size());
244: assertEquals(1, this .sink.getAsserted().size());
245: assertEquals(0, this .accumulator.getMatchingObjects().size());
246:
247: this .node.assertObject(f0, this .context, this .workingMemory);
248: assertEquals(1, this .memory.getFactHandleMemory().size());
249: assertEquals(2, this .sink.getAsserted().size());
250: assertEquals(1, this .accumulator.getMatchingObjects().size());
251:
252: this .node.assertObject(f1, this .context, this .workingMemory);
253:
254: assertEquals(2, this .memory.getFactHandleMemory().size());
255: assertEquals(3, this .sink.getAsserted().size());
256: assertEquals(2, this .accumulator.getMatchingObjects().size());
257:
258: }
259:
260: /**
261: * Test method for {@link org.drools.reteoo.AccumulateNode#retractObject(InternalFactHandle, org.drools.spi.PropagationContext, InternalWorkingMemory)}.
262: */
263: public void testRetractObject() {
264: final DefaultFactHandle f0 = (DefaultFactHandle) this .workingMemory
265: .getFactHandleFactory().newFactHandle("cheese");
266: final DefaultFactHandle f1 = (DefaultFactHandle) this .workingMemory
267: .getFactHandleFactory().newFactHandle("other cheese");
268:
269: final ReteTuple tuple0 = new ReteTuple(f0);
270:
271: this .node.assertObject(f0, this .context, this .workingMemory);
272: this .node.assertObject(f1, this .context, this .workingMemory);
273: assertEquals(2, this .memory.getFactHandleMemory().size());
274:
275: // assert tuple, should add one to left memory
276: this .node.assertTuple(tuple0, this .context, this .workingMemory);
277:
278: // check memory
279: assertEquals(1, this .memory.getTupleMemory().size());
280: assertEquals(0, this .sink.getRetracted().size());
281: assertEquals(1, this .sink.getAsserted().size());
282: assertEquals(2, this .accumulator.getMatchingObjects().size());
283:
284: this .node.retractObject(f1, this .context, this .workingMemory);
285: assertEquals(1, this .memory.getFactHandleMemory().size());
286: assertEquals(1, this .sink.getRetracted().size());
287: assertEquals(2, this .sink.getAsserted().size());
288: assertEquals(1, this .accumulator.getMatchingObjects().size());
289:
290: this .node.retractObject(f0, this .context, this .workingMemory);
291: assertEquals(0, this .memory.getFactHandleMemory().size());
292: assertEquals(2, this .sink.getRetracted().size());
293: assertEquals(3, this .sink.getAsserted().size());
294: assertEquals(0, this .accumulator.getMatchingObjects().size());
295:
296: }
297:
298: public void testMemory() {
299: final ReteooWorkingMemory workingMemory = new ReteooWorkingMemory(
300: 1, (ReteooRuleBase) RuleBaseFactory.newRuleBase());
301:
302: final MockObjectSource objectSource = new MockObjectSource(1);
303: final MockTupleSource tupleSource = new MockTupleSource(1);
304:
305: final AccumulateNode accumulateNode = new AccumulateNode(2,
306: tupleSource, objectSource, this .accumulate);
307:
308: final BetaMemory memory = ((AccumulateMemory) this .workingMemory
309: .getNodeMemory(this .node)).betaMemory;
310:
311: assertNotNull(memory);
312: }
313:
314: /**
315: * Test just tuple assertions
316: *
317: * @throws AssertionException
318: */
319: public void testAssertTupleSequentialMode() throws Exception {
320: RuleBaseConfiguration conf = new RuleBaseConfiguration();
321: conf.setSequential(true);
322:
323: this .workingMemory = new ReteooWorkingMemory(1,
324: (ReteooRuleBase) RuleBaseFactory.newRuleBase(conf));
325:
326: this .memory = ((AccumulateMemory) this .workingMemory
327: .getNodeMemory(this .node)).betaMemory;
328:
329: final DefaultFactHandle f0 = (DefaultFactHandle) this .workingMemory
330: .getFactHandleFactory().newFactHandle("cheese");
331: final DefaultFactHandle f1 = (DefaultFactHandle) this .workingMemory
332: .getFactHandleFactory().newFactHandle("other cheese");
333:
334: final ReteTuple tuple0 = new ReteTuple(f0);
335:
336: this .node.assertObject(f0, this .context, this .workingMemory);
337: this .node.assertObject(f1, this .context, this .workingMemory);
338:
339: // assert tuple, should not add to left memory, since we are in sequential mode
340: this .node.assertTuple(tuple0, this .context, this .workingMemory);
341: // check memories
342: assertNull(this .memory.getTupleMemory());
343: assertEquals(2, this .memory.getFactHandleMemory().size());
344: Assert.assertEquals(
345: "Wrong number of elements in matching objects list ",
346: 2, this .accumulator.getMatchingObjects().size());
347:
348: // assert tuple, should not add left memory
349: final ReteTuple tuple1 = new ReteTuple(f1);
350: this .node.assertTuple(tuple1, this .context, this .workingMemory);
351: assertNull(this .memory.getTupleMemory());
352: Assert.assertEquals(
353: "Wrong number of elements in matching objects list ",
354: 2, this .accumulator.getMatchingObjects().size());
355:
356: Assert.assertEquals("Two tuples should have been propagated",
357: 2, this.sink.getAsserted().size());
358: }
359:
360: }
|