// TestEnvironment tests general environment methods. func TestEnvironment(t *testing.T) { assert := audit.NewTestingAssertion(t, true) envOne := cells.NewEnvironment("part", 1, "of", "env", "ONE") defer envOne.Stop() id := envOne.ID() assert.Equal(id, "part:1:of:env:one") envTwo := cells.NewEnvironment("environment TWO") defer envTwo.Stop() id = envTwo.ID() assert.Equal(id, "environment-two") }
// TestFilterBehavior tests the filter behavior. func TestFilterBehavior(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("filter-behavior") defer env.Stop() ff := func(id string, event cells.Event) bool { dp, ok := event.Payload().Get(cells.DefaultPayload) if !ok { return false } payload := dp.(string) return event.Topic() == payload } env.StartCell("filter", behaviors.NewFilterBehavior(ff)) env.StartCell("collector", behaviors.NewCollectorBehavior(10)) env.Subscribe("filter", "collector") env.EmitNew("filter", "a", "a", nil) env.EmitNew("filter", "a", "b", nil) env.EmitNew("filter", "b", "b", nil) time.Sleep(100 * time.Millisecond) collected, err := env.Request("collector", cells.CollectedTopic, nil, nil, cells.DefaultTimeout) assert.Nil(err) assert.Length(collected, 2, "two collected events") }
// TestCallbackBehavior tests the callback behavior. func TestCallbackBehavior(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("callback-behavior") defer env.Stop() cbdA := []string{} cbfA := func(topic string, payload cells.Payload) error { cbdA = append(cbdA, topic) return nil } cbdB := 0 cbfB := func(topic string, payload cells.Payload) error { cbdB++ return nil } sigc := audit.MakeSigChan() cbfC := func(topic string, payload cells.Payload) error { if topic == "baz" { sigc <- true } return nil } env.StartCell("callback", behaviors.NewCallbackBehavior(cbfA, cbfB, cbfC)) env.EmitNew("callback", "foo", nil, nil) env.EmitNew("callback", "bar", nil, nil) env.EmitNew("callback", "baz", nil, nil) assert.Wait(sigc, true, time.Second) assert.Equal(cbdA, []string{"foo", "bar", "baz"}) assert.Equal(cbdB, 3) }
// TestRouterBehavior tests the router behavior. func TestRouterBehavior(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("router-behavior") defer env.Stop() rf := func(emitterID, subscriberID string, event cells.Event) (bool, error) { ok := strings.Contains(event.Topic(), subscriberID) return ok, nil } env.StartCell("router", behaviors.NewRouterBehavior(rf)) env.StartCell("test-1", behaviors.NewCollectorBehavior(10)) env.StartCell("test-2", behaviors.NewCollectorBehavior(10)) env.StartCell("test-3", behaviors.NewCollectorBehavior(10)) env.StartCell("test-4", behaviors.NewCollectorBehavior(10)) env.StartCell("test-5", behaviors.NewCollectorBehavior(10)) env.Subscribe("router", "test-1", "test-2", "test-3", "test-4", "test-5") env.EmitNew("router", "test-1:test-2", "a", nil) env.EmitNew("router", "test-1:test-2:test-3", "b", nil) env.EmitNew("router", "test-3:test-4:test-5", "c", nil) time.Sleep(100 * time.Millisecond) test := func(id string, length int) { collected, err := env.Request(id, cells.CollectedTopic, nil, nil, cells.DefaultTimeout) assert.Nil(err) assert.Length(collected, length) } test("test-1", 2) test("test-2", 2) test("test-3", 2) test("test-4", 1) test("test-5", 1) }
// TestEnvironmentScenario tests creating and using the // environment in a simple way. func TestEnvironmentScenario(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("scenario") defer env.Stop() err := env.StartCell("foo", newCollectBehavior()) assert.Nil(err) err = env.StartCell("bar", newCollectBehavior()) assert.Nil(err) err = env.StartCell("collector", newCollectBehavior()) assert.Nil(err) err = env.Subscribe("foo", "bar") assert.Nil(err) err = env.Subscribe("bar", "collector") assert.Nil(err) err = env.EmitNew("foo", "lorem", 4711, nil) assert.Nil(err) err = env.EmitNew("foo", "ipsum", 1234, nil) assert.Nil(err) response, err := env.Request("foo", cells.PingTopic, nil, nil, cells.DefaultTimeout) assert.Nil(err) assert.Equal(response, cells.PongResponse) time.Sleep(200 * time.Millisecond) collected, err := env.Request("collector", cells.ProcessedTopic, nil, nil, cells.DefaultTimeout) assert.Nil(err) assert.Length(collected, 2, "two collected events") assert.Contents(`<topic: "lorem" / payload: <"default": 4711>>`, collected) assert.Contents(`<topic: "ipsum" / payload: <"default": 1234>>`, collected) }
// TestConfigurationRead tests the successful reading of a configuration. func TestConfigurationRead(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("configuration-read") defer env.Stop() tempDir, filename := createConfigurationFile(assert, "{config {foo 42}}") defer tempDir.Restore() sigc := audit.MakeSigChan() spf := func(ctx cells.Context, event cells.Event) error { if event.Topic() == behaviors.ConfigurationTopic { config := behaviors.Configuration(event) v, err := config.At("foo").Value() assert.Nil(err) assert.Equal(v, "42") sigc <- true } return nil } env.StartCell("configurator", behaviors.NewConfiguratorBehavior(nil)) env.StartCell("simple", behaviors.NewSimpleProcessorBehavior(spf)) env.Subscribe("configurator", "simple") pvs := cells.PayloadValues{ behaviors.ConfigurationFilenamePayload: filename, } env.EmitNew("configurator", behaviors.ReadConfigurationTopic, pvs, nil) assert.Wait(sigc, true, 100*time.Millisecond) }
// TestEnvironmentSubscribersDo tests the iteration over // the subscribers. func TestEnvironmentSubscribersDo(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("subscribers-do") defer env.Stop() err := env.StartCell("foo", newCollectBehavior()) assert.Nil(err) err = env.StartCell("bar", newCollectBehavior()) assert.Nil(err) err = env.StartCell("baz", newCollectBehavior()) assert.Nil(err) err = env.Subscribe("foo", "bar", "baz") assert.Nil(err) err = env.EmitNew("foo", iterateTopic, nil, nil) assert.Nil(err) time.Sleep(200 * time.Millisecond) collected, err := env.Request("bar", cells.ProcessedTopic, nil, nil, cells.DefaultTimeout) assert.Nil(err) assert.Length(collected, 1) assert.Contents(`<topic: "love" / payload: <"default": foo loves bar>>`, collected) collected, err = env.Request("baz", cells.ProcessedTopic, nil, nil, cells.DefaultTimeout) assert.Nil(err) assert.Length(collected, 1) assert.Contents(`<topic: "love" / payload: <"default": foo loves baz>>`, collected) }
// BenchmarkSmpleEmitNullMonitoring is a simple emitting to one cell // with the null monitor. func BenchmarkSmpleEmitNullMonitoring(b *testing.B) { env := cells.NewEnvironment("simple-emit") defer env.Stop() env.StartCell("collector", newCollectBehavior()) event, _ := cells.NewEvent("foo", "bar", nil) for i := 0; i < b.N; i++ { env.Emit("collector", event) } }
// BenchmarkSmpleEmitStandardMonitoring is a simple emitting to one cell // with the standard monitor. func BenchmarkSmpleEmitStandardMonitoring(b *testing.B) { monitoring.SetBackend(monitoring.NewStandardBackend()) env := cells.NewEnvironment("simple-emit-standard") defer env.Stop() env.StartCell("null", &nullBehavior{}) event, _ := cells.NewEvent("foo", "bar", nil) for i := 0; i < b.N; i++ { env.Emit("null", event) } }
// TestTickerBehavior tests the ticker behavior. func TestTickerBehavior(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("ticker-behavior") defer env.Stop() env.StartCell("ticker", behaviors.NewTickerBehavior(50*time.Millisecond)) env.StartCell("test", behaviors.NewCollectorBehavior(10)) env.Subscribe("ticker", "test") time.Sleep(125 * time.Millisecond) collected, err := env.Request("test", cells.CollectedTopic, nil, nil, cells.DefaultTimeout) assert.Nil(err) assert.Length(collected, 2) }
func main() { golib_logger.SetLevel(golib_logger.LevelInfo) log.Print("start") rootEnvironment = cells.NewEnvironment() defer rootEnvironment.Stop() addBuilding(rootEnvironment, "school") addRoom(rootEnvironment, "school", "cafeteria") startServer(rootEnvironment) /* addRoom(rootEnvironment, "school", "playground") time.Sleep(time.Millisecond * 100) addLogUser(rootEnvironment, "school", "cafeteria") addUser(rootEnvironment, "school", "cafeteria", "willy") addUser(rootEnvironment, "school", "cafeteria", "bart") addUser(rootEnvironment, "school", "cafeteria", "lisa") time.Sleep(time.Millisecond * 100) bart := makeUserID("bart") rootEnvironment.EmitNew(bart, SAY, cells.PayloadValues{ "room": makeRoomID("cafeteria", "school"), "message": "Don't have a cow, Man!", }, nil) time.Sleep(time.Millisecond * 100) rootEnvironment.EmitNew(bart, SAY, cells.PayloadValues{ "room": makeRoomID("cafeteria", "school"), "message": "I'm Bart Simpson, who the hell are you?", }, nil) time.Sleep(time.Millisecond * 100) rootEnvironment.EmitNew(bart, SAY, cells.PayloadValues{ "room": makeRoomID("cafeteria", "school"), "message": "what teh hell ?", }, nil) time.Sleep(time.Second * 5) */ }
// TestEnvironmentSubscribeStop subscribing and stopping func TestEnvironmentSubscribeStop(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("subscribe-unsubscribe-stop") defer env.Stop() assert.Nil(env.StartCell("foo", newCollectBehavior())) assert.Nil(env.StartCell("bar", newCollectBehavior())) assert.Nil(env.StartCell("baz", newCollectBehavior())) assert.Nil(env.Subscribe("foo", "bar", "baz")) assert.Nil(env.Subscribe("bar", "foo", "baz")) assert.Nil(env.StopCell("bar")) assert.Nil(env.StopCell("foo")) assert.Nil(env.StopCell("baz")) }
// TestMapperBehavior tests the mapping of events. func TestMapperBehavior(t *testing.T) { assert := audit.NewTestingAssertion(t, true) assertPayload := func(collected interface{}, index int, value string) { eventData, ok := collected.([]behaviors.EventData) assert.True(ok) payload, ok := eventData[index].Payload.(cells.Payload) assert.True(ok) upperText, ok := payload.Get("upper-text") assert.True(ok) assert.Equal(upperText, value) } env := cells.NewEnvironment("mapper-behavior") defer env.Stop() mf := func(id string, event cells.Event) (cells.Event, error) { text, ok := event.Payload().Get(cells.DefaultPayload) if !ok { return event, nil } pv := cells.PayloadValues{ "upper-text": strings.ToUpper(text.(string)), } payload := event.Payload().Apply(pv) return cells.NewEvent(event.Topic(), payload, event.Scene()) } env.StartCell("mapper", behaviors.NewMapperBehavior(mf)) env.StartCell("collector", behaviors.NewCollectorBehavior(10)) env.Subscribe("mapper", "collector") env.EmitNew("mapper", "a", "abc", nil) env.EmitNew("mapper", "b", "def", nil) env.EmitNew("mapper", "c", "ghi", nil) time.Sleep(100 * time.Millisecond) collected, err := env.Request("collector", cells.CollectedTopic, nil, nil, cells.DefaultTimeout) assert.Nil(err) assert.Length(collected, 3, "three mapped events") assertPayload(collected, 0, "ABC") assertPayload(collected, 1, "DEF") assertPayload(collected, 2, "GHI") }
// TestBehaviorEmitTimeoutError tests the timeout error handling // when one or more emit need too much time. func TestBehaviorEmitTimeoutError(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("emit-timeout-error") defer env.Stop() err := env.StartCell("emitter", newEmitBehavior()) assert.Nil(err) err = env.StartCell("sleeper", newSleepBehavior()) assert.Nil(err) err = env.Subscribe("emitter", "sleeper") assert.Nil(err) // Emit more events than queue can take while the subscriber works. for i := 0; i < 25; i++ { env.EmitNew("emitter", emitTopic, i, nil) } time.Sleep(2 * time.Second) }
// TestBehaviorEventBufferSize tests the setting of // the event buffer size. func TestBehaviorEventBufferSize(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("event-buffer") defer env.Stop() err := env.StartCell("negative", newEventBufferBehavior(-8)) assert.Nil(err) ci := cells.InspectCell(env, "negative") assert.Equal(ci.EventBufferSize(), cells.MinEventBufferSize) err = env.StartCell("low", newEventBufferBehavior(1)) assert.Nil(err) ci = cells.InspectCell(env, "low") assert.Equal(ci.EventBufferSize(), cells.MinEventBufferSize) err = env.StartCell("high", newEventBufferBehavior(2*cells.MinEventBufferSize)) assert.Nil(err) ci = cells.InspectCell(env, "high") assert.Equal(ci.EventBufferSize(), 2*cells.MinEventBufferSize) }
// TestBehaviorEmitTimeout tests the setting of // the emit timeout. func TestBehaviorEmitTimeout(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("emit-timeout") defer env.Stop() err := env.StartCell("low", newTestEmitTimeoutBehavior(time.Millisecond)) assert.Nil(err) ci := cells.InspectCell(env, "low") assert.Equal(ci.EmitTimeout(), cells.MinEmitTimeout) err = env.StartCell("correct", newTestEmitTimeoutBehavior(10*time.Second)) assert.Nil(err) ci = cells.InspectCell(env, "correct") assert.Equal(ci.EmitTimeout(), 10*time.Second) err = env.StartCell("high", newTestEmitTimeoutBehavior(2*cells.MaxEmitTimeout)) assert.Nil(err) ci = cells.InspectCell(env, "high") assert.Equal(ci.EmitTimeout(), cells.MaxEmitTimeout) }
// TestConfigurationValidation tests the validation of a configuration. func TestConfigurationValidation(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("configuration-validation") defer env.Stop() tempDir, filename := createConfigurationFile(assert, "{config {foo 42}}") defer tempDir.Restore() sigc := audit.MakeSigChan() spf := func(ctx cells.Context, event cells.Event) error { sigc <- true return nil } var key string cv := func(config configuration.Configuration) error { _, err := config.At(key).Value() if err != nil { sigc <- false } return err } env.StartCell("configurator", behaviors.NewConfiguratorBehavior(cv)) env.StartCell("simple", behaviors.NewSimpleProcessorBehavior(spf)) env.Subscribe("configurator", "simple") // First run with success as key has the valid value "foo" pvs := cells.PayloadValues{ behaviors.ConfigurationFilenamePayload: filename, } key = "foo" env.EmitNew("configurator", behaviors.ReadConfigurationTopic, pvs, nil) assert.Wait(sigc, true, 100*time.Millisecond) // Second run also will succeed, even with "bar" as invalid value. // See definition of validator cv above. But validationError is not // nil. key = "bar" env.EmitNew("configurator", behaviors.ReadConfigurationTopic, pvs, nil) assert.Wait(sigc, false, 100*time.Millisecond) }
// TestSceneBehavior tests the scene behavior. func TestSceneBehavior(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("scene-behavior") defer env.Stop() env.StartCell("broadcast", behaviors.NewBroadcasterBehavior()) env.StartCell("scene", behaviors.NewSceneBehavior()) env.Subscribe("broadcast", "scene") scn := scene.Start() defer scn.Stop() env.EmitNew("broadcast", "foo", "bar", scn) value, err := scn.WaitFlagLimitedAndFetch("foo", 5*time.Second) assert.Nil(err) assert.Equal(value, cells.NewPayload("bar")) env.EmitNew("broadcast", "yadda", 42, nil) value, err = scn.WaitFlagLimitedAndFetch("yadda", 1*time.Second) assert.Nil(value) assert.ErrorMatch(err, `.* waiting for signal "yadda" timed out`) }
// TestEnvironmentSubscribeUnsubscribe tests subscribing, // checking and unsubscribing of cells. func TestEnvironmentSubscribeUnsubscribe(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("subscribe-unsubscribe") defer env.Stop() err := env.StartCell("foo", newCollectBehavior()) assert.Nil(err) err = env.StartCell("bar", newCollectBehavior()) assert.Nil(err) err = env.StartCell("baz", newCollectBehavior()) assert.Nil(err) err = env.StartCell("yadda", newCollectBehavior()) assert.Nil(err) err = env.Subscribe("humpf", "foo") assert.True(errors.IsError(err, cells.ErrInvalidID)) err = env.Subscribe("foo", "humpf") assert.True(errors.IsError(err, cells.ErrInvalidID)) err = env.Subscribe("foo", "bar", "baz") assert.Nil(err) subs, err := env.Subscribers("foo") assert.Nil(err) assert.Contents("bar", subs) assert.Contents("baz", subs) err = env.Unsubscribe("foo", "bar") assert.Nil(err) subs, err = env.Subscribers("foo") assert.Nil(err) assert.Contents("baz", subs) err = env.Unsubscribe("foo", "baz") assert.Nil(err) subs, err = env.Subscribers("foo") assert.Nil(err) assert.Empty(subs) }
// TestSimpleBehavior tests the simple processor behavior. func TestSimpleBehavior(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("simple-procesor-behavior") defer env.Stop() topics := []string{} var wg sync.WaitGroup spf := func(ctx cells.Context, event cells.Event) error { topics = append(topics, event.Topic()) wg.Done() return nil } env.StartCell("simple", behaviors.NewSimpleProcessorBehavior(spf)) wg.Add(3) env.EmitNew("simple", "foo", "", nil) env.EmitNew("simple", "bar", "", nil) env.EmitNew("simple", "baz", "", nil) wg.Wait() assert.Length(topics, 3) }
// TestCounterBehavior tests the counting of events. func TestCounterBehavior(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("counter-behavior") defer env.Stop() cf := func(id string, event cells.Event) []string { payload, ok := event.Payload().Get(cells.DefaultPayload) if !ok { return []string{} } return payload.([]string) } env.StartCell("counter", behaviors.NewCounterBehavior(cf)) env.EmitNew("counter", "count", []string{"a", "b"}, nil) env.EmitNew("counter", "count", []string{"a", "c", "d"}, nil) env.EmitNew("counter", "count", []string{"a", "d"}, nil) time.Sleep(100 * time.Millisecond) counters, err := env.Request("counter", cells.CountersTopic, nil, nil, cells.DefaultTimeout) assert.Nil(err) assert.Length(counters, 4, "four counted events") c := counters.(behaviors.Counters) assert.Equal(c["a"], int64(3)) assert.Equal(c["b"], int64(1)) assert.Equal(c["c"], int64(1)) assert.Equal(c["d"], int64(2)) err = env.EmitNew("counter", cells.ResetTopic, nil, nil) assert.Nil(err) counters, err = env.Request("counter", cells.CountersTopic, nil, nil, cells.DefaultTimeout) assert.Nil(err) assert.Empty(counters, "zero counted events") }
// TestBehaviorEmitTimeoutSetting tests the setting of // the emit timeout. func TestBehaviorEmitTimeoutSetting(t *testing.T) { assert := audit.NewTestingAssertion(t, true) minSeconds := int(cells.MinEmitTimeout.Seconds() / 5) maxSeconds := int(cells.MaxEmitTimeout.Seconds() / 5) env := cells.NewEnvironment("emit-timeout-setting") defer env.Stop() err := env.StartCell("low", newEmitTimeoutBehavior(time.Millisecond)) assert.Nil(err) ci := cells.InspectCell(env, "low") assert.Equal(ci.EmitTimeout(), minSeconds) err = env.StartCell("correct", newEmitTimeoutBehavior(10*time.Second)) assert.Nil(err) ci = cells.InspectCell(env, "correct") assert.Equal(ci.EmitTimeout(), 2) err = env.StartCell("high", newEmitTimeoutBehavior(2*cells.MaxEmitTimeout)) assert.Nil(err) ci = cells.InspectCell(env, "high") assert.Equal(ci.EmitTimeout(), maxSeconds) }
// TestEnvironmentStopUnsubscribe tests the unsubscribe of a cell when // it is stopped. func TestEnvironmentStopUnsubscribe(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("stop-unsubscribe") defer env.Stop() err := env.StartCell("foo", newCollectBehavior()) assert.Nil(err) err = env.StartCell("bar", newCollectBehavior()) assert.Nil(err) err = env.StartCell("baz", newCollectBehavior()) assert.Nil(err) err = env.Subscribe("foo", "bar", "baz") assert.Nil(err) err = env.StopCell("bar") assert.Nil(err) // Expect only baz because bar is stopped. response, err := env.Request("foo", subscribersTopic, nil, nil, cells.DefaultTimeout) assert.Nil(err) assert.Equal(response, []string{"baz"}) }
// TestBehaviorRecoveringFrequency tests the setting of // the recovering frequency. func TestBehaviorRecoveringFrequency(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("recovering-frequency") defer env.Stop() err := env.StartCell("negative", newRecoveringFrequencyBehavior(-1, time.Second)) assert.Nil(err) ci := cells.InspectCell(env, "negative") assert.Equal(ci.RecoveringNumber(), cells.MinRecoveringNumber) assert.Equal(ci.RecoveringDuration(), cells.MinRecoveringDuration) err = env.StartCell("low", newRecoveringFrequencyBehavior(10, time.Millisecond)) assert.Nil(err) ci = cells.InspectCell(env, "low") assert.Equal(ci.RecoveringNumber(), cells.MinRecoveringNumber) assert.Equal(ci.RecoveringDuration(), cells.MinRecoveringDuration) err = env.StartCell("high", newRecoveringFrequencyBehavior(12, time.Minute)) assert.Nil(err) ci = cells.InspectCell(env, "high") assert.Equal(ci.RecoveringNumber(), 12) assert.Equal(ci.RecoveringDuration(), time.Minute) }
// TestCollectorBehavior tests the collector behavior. func TestCollectorBehavior(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("collector-behavior") defer env.Stop() env.StartCell("collector", behaviors.NewCollectorBehavior(10)) for i := 0; i < 25; i++ { env.EmitNew("collector", "collect", i, nil) } time.Sleep(100 * time.Millisecond) collected, err := env.Request("collector", cells.CollectedTopic, nil, nil, cells.DefaultTimeout) assert.Nil(err) assert.Length(collected, 10) err = env.EmitNew("collector", cells.ResetTopic, nil, nil) assert.Nil(err) collected, err = env.Request("collector", cells.CollectedTopic, nil, nil, cells.DefaultTimeout) assert.Nil(err) assert.Length(collected, 0) }
// TestEnvironmentStartStopCell tests starting, checking and // stopping of cells. func TestEnvironmentStartStopCell(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("start-stop") defer env.Stop() err := env.StartCell("foo", newCollectBehavior()) assert.Nil(err) hasFoo := env.HasCell("foo") assert.True(hasFoo) err = env.StopCell("foo") assert.Nil(err) hasFoo = env.HasCell("foo") assert.False(hasFoo) hasBar := env.HasCell("bar") assert.False(hasBar) err = env.StopCell("bar") assert.True(errors.IsError(err, cells.ErrInvalidID)) hasBar = env.HasCell("bar") assert.False(hasBar) }
// TestBroadcasterBehavior tests the broadcast behavior. func TestBroadcasterBehavior(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("broadcast-behavior") defer env.Stop() env.StartCell("broadcast", behaviors.NewBroadcasterBehavior()) env.StartCell("test-1", behaviors.NewCollectorBehavior(10)) env.StartCell("test-2", behaviors.NewCollectorBehavior(10)) env.Subscribe("broadcast", "test-1", "test-2") env.EmitNew("broadcast", "test", "a", nil) env.EmitNew("broadcast", "test", "b", nil) env.EmitNew("broadcast", "test", "c", nil) time.Sleep(100 * time.Millisecond) collected, err := env.Request("test-1", cells.CollectedTopic, nil, nil, cells.DefaultTimeout) assert.Nil(err) assert.Length(collected, 3) collected, err = env.Request("test-2", cells.CollectedTopic, nil, nil, cells.DefaultTimeout) assert.Nil(err) assert.Length(collected, 3) }
// TestFSMBehavior tests the finite state machine behavior. func TestFSMBehavior(t *testing.T) { assert := audit.NewTestingAssertion(t, true) env := cells.NewEnvironment("fsm-behavior") defer env.Stop() checkCents := func(id string) int { cents, err := env.Request(id, "cents?", nil, nil, cells.DefaultTimeout) assert.Nil(err) return cents.(int) } info := func(id string) string { info, err := env.Request(id, "info?", nil, nil, cells.DefaultTimeout) assert.Nil(err) return info.(string) } grabCents := func() int { cents, err := env.Request("restorer", "grab!", nil, nil, cells.DefaultTimeout) assert.Nil(err) return cents.(int) } lockA := lockMachine{} lockB := lockMachine{} env.StartCell("lock-a", behaviors.NewFSMBehavior(lockA.Locked)) env.StartCell("lock-b", behaviors.NewFSMBehavior(lockB.Locked)) env.StartCell("restorer", newRestorerBehavior()) env.Subscribe("lock-a", "restorer") env.Subscribe("lock-b", "restorer") // 1st run: emit not enough and press button. env.EmitNew("lock-a", "coin!", 20, nil) env.EmitNew("lock-a", "coin!", 20, nil) env.EmitNew("lock-a", "coin!", 20, nil) env.EmitNew("lock-a", "button-press!", nil, nil) time.Sleep(100 * time.Millisecond) assert.Equal(checkCents("lock-a"), 0) assert.Equal(grabCents(), 60) // 2nd run: unlock the lock and lock it again. env.EmitNew("lock-a", "coin!", 50, nil) env.EmitNew("lock-a", "coin!", 20, nil) env.EmitNew("lock-a", "coin!", 50, nil) time.Sleep(100 * time.Millisecond) assert.Equal(info("lock-a"), "state 'unlocked' with 20 cents") env.EmitNew("lock-a", "button-press!", nil, nil) time.Sleep(100 * time.Millisecond) assert.Equal(checkCents("lock-a"), 00) assert.Equal(info("lock-a"), "state 'locked' with 0 cents") assert.Equal(grabCents(), 20) // 3rd run: put a screwdriwer in the lock. env.EmitNew("lock-a", "screwdriver!", nil, nil) time.Sleep(100 * time.Millisecond) status := behaviors.RequestFSMStatus(env, "lock-a") assert.Equal(status.Done, true) assert.Nil(status.Error) // 4th run: try an illegal action. env.EmitNew("lock-b", "chewing-gum", nil, nil) time.Sleep(100 * time.Millisecond) status = behaviors.RequestFSMStatus(env, "lock-b") assert.Equal(status.Done, true) assert.ErrorMatch(status.Error, "illegal topic in state 'locked': chewing-gum") }