func UpdaterSpec(c gospec.Context) { c.Specify("Basic Updater functionality.", func() { var params core.EngineParams params.Id = 1234 params.Delay = 2 params.Frame_ms = 5 params.Max_frames = 25 var updater core.Updater updater.Params = params local_bundles := make(chan core.FrameBundle) broadcast_bundles := make(chan core.FrameBundle) remote_bundles := make(chan core.FrameBundle) updater.Local_bundles = local_bundles updater.Broadcast_bundles = broadcast_bundles updater.Remote_bundles = remote_bundles data := core.FrameData{ Bundle: nil, Game: &TestGame{}, Info: core.EngineInfo{ Engines: map[core.EngineId]bool{ params.Id: true, params.Id + 1: true, }, }, } var start_frame core.StateFrame = 10 updater.Start(start_frame, data) go func() { for _ = range broadcast_bundles { } }() defer close(broadcast_bundles) cur_frame := start_frame + 1 c.Specify("Local game Events are applied properly.", func() { for cur_frame = start_frame + 1; cur_frame <= start_frame+5; cur_frame++ { local_bundles <- core.FrameBundle{ Frame: cur_frame, Bundle: core.EventBundle{ params.Id: core.AllEvents{ Game: []core.Event{ EventA{2}, EventB{fmt.Sprintf("%d", cur_frame)}, }, }, params.Id + 1: core.AllEvents{ Game: []core.Event{ EventA{1}, EventB{fmt.Sprintf("%d", cur_frame)}, }, }, }, } } state, _ := updater.RequestFinalGameState(cur_frame - 1) c.Expect(state, Not(Equals), nil) tg := state.(*TestGame) c.Expect(tg.Thinks, Equals, 5) c.Expect(tg.A, Equals, 15) c.Expect(tg.B, Equals, fmt.Sprintf("%d", cur_frame-1)) }) // Same test as above, but one of the engine's events come through the // remote_bundles channel. c.Specify("Remote game Events are applied properly.", func() { for cur_frame = start_frame + 1; cur_frame <= start_frame+5; cur_frame++ { local_bundles <- core.FrameBundle{ Frame: cur_frame, Bundle: core.EventBundle{ params.Id: core.AllEvents{ Game: []core.Event{ EventA{2}, EventB{fmt.Sprintf("%d", cur_frame)}, }, }, }, } remote_bundles <- core.FrameBundle{ Frame: cur_frame, Bundle: core.EventBundle{ params.Id + 1: core.AllEvents{ Game: []core.Event{ EventA{1}, EventB{fmt.Sprintf("%d", cur_frame)}, }, }, }, } } state, _ := updater.RequestFinalGameState(cur_frame - 1) c.Expect(state, Not(Equals), nil) tg := state.(*TestGame) c.Expect(tg.Thinks, Equals, 5) c.Expect(tg.A, Equals, 15) c.Expect(tg.B, Equals, fmt.Sprintf("%d", cur_frame-1)) }) // Similar test as above but we drop and rejoin one of the engines. c.Specify("Engine Events are applied properly.", func() { local_bundles <- core.FrameBundle{ Frame: cur_frame, Bundle: core.EventBundle{ params.Id: core.AllEvents{ Engine: []core.EngineEvent{ core.EngineDropped{params.Id + 1}, }, Game: []core.Event{ EventA{1}, }, }, params.Id + 1: core.AllEvents{ Game: []core.Event{ EventA{1}, }, }, }, } local_bundles <- core.FrameBundle{ Frame: cur_frame + 1, Bundle: core.EventBundle{ params.Id: core.AllEvents{ Engine: []core.EngineEvent{ core.EngineJoined{params.Id + 1}, }, Game: []core.Event{ EventA{1}, }, }, params.Id + 1: core.AllEvents{ // These events should not get applied Game: []core.Event{ EventA{1}, }, }, }, } local_bundles <- core.FrameBundle{ Frame: cur_frame + 2, Bundle: core.EventBundle{ params.Id: core.AllEvents{ Game: []core.Event{ EventA{1}, }, }, params.Id + 1: core.AllEvents{ // These events should get applied Game: []core.Event{ EventA{1}, }, }, }, } state, _ := updater.RequestFinalGameState(-1) c.Expect(state, Not(Equals), nil) tg := state.(*TestGame) c.Expect(tg.Thinks, Equals, 3) c.Expect(tg.A, Equals, 5) }) }) }
func BundlerSpec(c gospec.Context) { c.Specify("Basic Bundler functionality.", func() { var params core.EngineParams params.Id = 1234 params.Delay = 2 params.Frame_ms = 5 params.Max_frames = 25 bundles := make(chan core.FrameBundle) local_event := make(chan core.Event) var bundler core.Bundler bundler.Params = params bundler.Local_bundles = bundles bundler.Local_event = local_event bundler.Time_delta = nil ticker := &core.FakeTicker{} bundler.Ticker = ticker bundler.Start() c.Expect(1, Equals, 1) go func() { for i := 0; i < 10; i++ { if i%2 == 0 { local_event <- &EventA{i} local_event <- &EventB{fmt.Sprintf("%d", i)} } else { local_event <- &EventB{fmt.Sprintf("%d", i)} local_event <- &EventA{i} } // Advance two frames, so we will have two events per every other // frame. ticker.Inc(10) } bundler.Shutdown() }() var frame core.StateFrame = 0 for bundle := range bundles { c.Expect(bundle.Frame, Equals, frame) events, ok := bundle.Bundle[params.Id] c.Assume(ok, Equals, true) c.Expect(len(events.Engine), Equals, 0) if ok { if frame%2 == 0 { c.Expect(len(events.Game), Equals, 2) } else { c.Expect(len(events.Game), Equals, 0) } } if frame%2 == 0 { c.Expect(len(bundle.Bundle), Equals, 1) c.Specify("checking bundle values", func() { index_a := 0 if frame%4 != 0 { index_a = 1 } ea, aok := events.Game[index_a].(*EventA) eb, bok := events.Game[(index_a+1)%2].(*EventB) c.Assume(aok, Equals, true) c.Assume(bok, Equals, true) c.Specify("checking event data", func() { c.Expect(ea.Data, Equals, int(frame/2)) c.Expect(eb.Data, Equals, fmt.Sprintf("%d", frame/2)) }) }) } frame++ } }) }