From 43d4d72e64b688ae2747d8b6b88bdf1bd1c36332 Mon Sep 17 00:00:00 2001 From: "balamg@yahoo.com" Date: Tue, 30 Apr 2019 12:32:41 +0530 Subject: [PATCH] Fix for #47 : A tuple remains in the rule session's network after retract is invoked --- rete/network.go | 1 + ruleapi/tests/retract_1_test.go | 109 ++++++++++++++++++++++++++++++++ ruleapi/tests/tests.json | 23 ++++++- 3 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 ruleapi/tests/retract_1_test.go diff --git a/rete/network.go b/rete/network.go index 94fa2c9..4d300e9 100644 --- a/rete/network.go +++ b/rete/network.go @@ -601,6 +601,7 @@ func (nw *reteNetworkImpl) retractInternal(ctx context.Context, tuple model.Tupl if mode == DELETE { rCtx.addToRtcDeleted(tuple) } + delete (nw.allHandles, tuple.GetKey().String()) } } diff --git a/ruleapi/tests/retract_1_test.go b/ruleapi/tests/retract_1_test.go new file mode 100644 index 0000000..29b8b52 --- /dev/null +++ b/ruleapi/tests/retract_1_test.go @@ -0,0 +1,109 @@ +package tests + +import ( + "context" + "github.com/project-flogo/rules/common/model" + "github.com/project-flogo/rules/ruleapi" + "testing" +) + +//Retract +func Test_Retract_1(t *testing.T) { + + rs, _ := createRuleSession() + + //create a rule joining t1 and t3 + rule := ruleapi.NewRule("Retract_Test") + err := rule.AddCondition("R7_c1", []string{"t1.none", "t3.none"}, trueCondition, nil) + if err != nil { + t.Logf("%s", err) + t.FailNow() + } + rule.SetAction(assert_action) + rule.SetPriority(1) + err = rs.AddRule(rule) + if err != nil { + t.Logf("%s", err) + t.FailNow() + } + t.Logf("Rule added: [%s]\n", rule.GetName()) + + err = rs.Start(nil) + if err != nil { + t.Logf("%s", err) + t.FailNow() + } + + //assert a t1 + { + ctx := context.WithValue(context.TODO(), "key", t) + tuple, _ := model.NewTupleWithKeyValues("t1", "t1") + err := rs.Assert(ctx, tuple) + if err != nil { + t.Logf("%s", err) + t.FailNow() + } + } + //assert a t3 so that the rule fires for keys t1 and t3 + { + ctx := context.WithValue(context.TODO(), "key", t) + tuple, _ := model.NewTupleWithKeyValues("t3", "t3") + err := rs.Assert(ctx, tuple) + if err != nil { + t.Logf("%s", err) + t.FailNow() + } + } + //now retract t3 + { + ctx := context.WithValue(context.TODO(), "key", t) + tuple, _ := model.NewTupleWithKeyValues("t3", "t3") + rs.Retract(ctx, tuple) + } + /** + now assert with same key again, see that the test does not fail, and rule fires + for keys t1 and t3 + */ + + { + ctx := context.WithValue(context.TODO(), "key", t) + tuple, _ := model.NewTupleWithKeyValues("t3", "t3") + err := rs.Assert(ctx, tuple) + if err != nil { + t.Logf("%s", err) + t.FailNow() + } + } + /** + now retract t3 again, just to check if a subsequent t1 does not fire the rule + there by proving that t3 has been retracted + */ + { + ctx := context.WithValue(context.TODO(), "key", t) + tuple, _ := model.NewTupleWithKeyValues("t3", "t3") + rs.Retract(ctx, tuple) + } + + /** + now assert another t1 with a different key and observe that rule does not fire + for keys t3 and t11 (since t3 has been retracted) + */ + { + ctx := context.WithValue(context.TODO(), "key", t) + tuple, _ := model.NewTupleWithKeyValues("t1", "t11") + err := rs.Assert(ctx, tuple) + if err != nil { + t.Logf("%s", err) + t.FailNow() + } + } + rs.Unregister() + +} + +func assert_action(ctx context.Context, rs model.RuleSession, ruleName string, tuples map[model.TupleType]model.Tuple, ruleCtx model.RuleContext) { + t := ctx.Value("key").(*testing.T) + t1 := tuples["t1"] + t3 := tuples["t3"] + t.Logf("Rule fired.. [%s], [%s]\n", t1.GetKey().String(), t3.GetKey().String()) +} \ No newline at end of file diff --git a/ruleapi/tests/tests.json b/ruleapi/tests/tests.json index 8fc81e5..40a4d82 100644 --- a/ruleapi/tests/tests.json +++ b/ruleapi/tests/tests.json @@ -43,6 +43,27 @@ "type":"string" } ] + }, + { + "name":"t3", + "properties":[ + { + "name":"id", + "type":"string", + "pk-index":0 + }, + { + "name":"p1", + "type":"int" + }, + { + "name":"p2", + "type":"double" + }, + { + "name":"p3", + "type":"string" + } + ] } - ] \ No newline at end of file