func TestRulesetParallelGuarding(t *testing.T) { rules := fsm.Ruleset{} rules.AddTransition(fsm.T{"pending", "started"}) rules.AddTransition(fsm.T{"started", "finished"}) // Add two failing rules, the slow should be caught first rules.AddRule(fsm.T{"started", "finished"}, func(subject fsm.Stater, goal fsm.State) error { time.Sleep(1 * time.Second) t.Error("Slow rule should have been short-circuited") return errors.New("Slow guard") }) rules.AddRule(fsm.T{"started", "finished"}, func(subject fsm.Stater, goal fsm.State) error { return errors.New("Always reject guard") }) st.Expect(t, rules.Permitted(&Thing{State: "started"}, "finished"), errors.New("Always reject guard")) }
func BenchmarkRulesetParallelGuarding(b *testing.B) { rules := fsm.Ruleset{} rules.AddTransition(fsm.T{"pending", "started"}) rules.AddTransition(fsm.T{"started", "finished"}) // Add two failing rules, one very slow and the other terribly fast rules.AddRule(fsm.T{"started", "finished"}, func(subject fsm.Stater, goal fsm.State) error { time.Sleep(1 * time.Second) return errors.New("Slow guard") }) rules.AddRule(fsm.T{"started", "finished"}, func(subject fsm.Stater, goal fsm.State) error { return errors.New("Failing guard") }) b.ResetTimer() for i := 0; i < b.N; i++ { rules.Permitted(&Thing{State: "started"}, "finished") } }
func BenchmarkRulesetRuleForbids(b *testing.B) { // Here, we explicity create a transition that is forbidden. This simulates an // otherwise valid transition that would be denied based on a user role or the like. // It should be slower than a standard invalid transition, since we have to // actually execute a function to perform the check. The first guard to // fail (returning false) will short circuit the execution, getting some some speed. rules := fsm.Ruleset{} rules.AddTransition(fsm.T{"pending", "started"}) rules.AddRule(fsm.T{"started", "finished"}, func(subject fsm.Stater, goal fsm.State) error { return errors.New("Failing guard") }) some_thing := &Thing{State: "started"} b.ResetTimer() for i := 0; i < b.N; i++ { rules.Permitted(some_thing, "finished") } }