diff --git a/basePlatformSOMAS_User_Manual.pdf b/Past Manuals/basePlatformSOMASv1.4.pdf similarity index 100% rename from basePlatformSOMAS_User_Manual.pdf rename to Past Manuals/basePlatformSOMASv1.4.pdf diff --git a/README.md b/README.md index 956d6ae..c3a8607 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,155 @@ # basePlatformSOMAS -Base platform for ICL SOMAS course + + + + +[![Contributors][contributors-shield]][contributors-url] +[![Issues][issues-shield]][issues-url] +[![MIT License][license-shield]][license-url] + + +
+ Table of Contents +
    +
  1. + About The Project +
  2. +
  3. + Getting Started + +
  4. +
  5. Usage
  6. +
  7. Contributing
  8. +
  9. License
  10. +
  11. Contact
  12. +
  13. Acknowledgments
  14. +
+
+ + + +## About The Project + +basePlatformSOMAS is a generic 'base platform', in the form of a package, used to simplify the development of a self-organising, multi-agent system (SOMAS). This package provides a set of core 'building block' components: + +- A 'base server' - an extensible server object for managing the environmental gamestate and regulating the internal state of... +- A 'base agent' - an extensible (multi-)agent object that can be injected into the server for simulation, and abstracts the core functions for agent-to-agent interactions through... +- A 'base message' - an extensible messaging component that helps to define a common language for multi-agent communication. + +These building blocks come with 1. an interface definition for defining the core functions required for an operational multi-agent system and 2. the building block object itself, to provide a base implementation of these core functions, and allow extension. + +For example, the `IServer` interface contains a set of functions that all servers in any multi-agent system must perform (the ability to add or remove agents, say), and the `BaseServer` object will give a base implementation of these methods. + +It is then left to the user of this package to define an `ExtendedServer` which adds all of the relevant functionality for their multi-agent scenario, while composing the `BaseServer` to get access to the methods provided by this package. + +

(back to top)

+ + + +## Getting Started + +To begin working with basePlatformSOMAS, follow these simple example steps. + +### Prerequisites + +This package is entirely build in `GoLang (go)`. Your machine therefore needs a golang compiler installed. The relevant download link can be found [here](https://go.dev/doc/install). + +[![Golang][go-shield]][go-url] + +Since we have defined this repository as a package, it must be included in an existing `go` project. As such, you should be initialising a `go` repository in a folder of your choice with: + +```sh +go mod init +``` + +### Installation + +With a working `go` repository, you can now include our package: + +```sh +go get github.com/MattSScott/basePlatformSOMAS/v2 +``` + +and, for peace of mind, tidy the imports: + +```sh +go mod tidy +``` + +

(back to top)

+ + + +## Usage + +You will now have access to the modules provided by this package: + +- The _server_ module can be imported into a file with: `github.com/MattSScott/basePlatformSOMAS/v2/pkg/server` +- The _agent_ module can be imported into a file with: `github.com/MattSScott/basePlatformSOMAS/v2/pkg/agent` +- The _message_ module can be imported into a file with: `github.com/MattSScott/basePlatformSOMAS/v2/pkg/message` + +For more examples, and a **much, much more detailed write-up** of the package, please refer to the [User Manual](https://github.com/MattSScott/basePlatformSOMAS/blob/main/basePlatformSOMASv2.0.pdf) or, if you're using an outdated version of the package, refer to the [Past Manuals](https://github.com/MattSScott/basePlatformSOMAS/tree/main/Past%20Manuals). + +

(back to top)

+ + + +## Contributing + +basePlatformSOMAS is an open source project made for SOMAS programmers, by SOMAS programmers. Any contributions you make are **greatly appreciated**. + +If you have a suggestion that would make this package better, please fork the repo and create a pull request. If you would rather leave the implementation of this suggestion to us, you can also simply open an issue with the tag "enhancement". + +To make a pull request in a helpful way: + +1. Fork the Project +2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) +3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) +4. Push to the Branch (`git push origin feature/AmazingFeature`) +5. Open a Pull Request + +

(back to top)

+ + + +## License + +Distributed under the MIT License. See `LICENSE.txt` for more information. + +

(back to top)

+ + + +## Contact + +[Matthew Scott](https://profiles.imperial.ac.uk/matthew.scott18) - matthew.scott18@imperial.ac.uk + +

(back to top)

+ + + +## Acknowledgments + +This work was produced by the following developers: + +- [Matthew Scott](https://github.com/MattSScott) +- [Ana Dimoska](https://github.com/ADimoska) +- [Mikayel Suvaryan](https://github.com/mika111) + +

(back to top)

+ + + + +[contributors-shield]: https://img.shields.io/github/contributors/MattSScott/basePlatformSOMAS.svg +[contributors-url]: https://github.com/MattSScott/basePlatformSOMAS/graphs/contributors +[issues-shield]: https://img.shields.io/github/issues/MattSScott/basePlatformSOMAS.svg?color=orange +[issues-url]: https://github.com/MattSScott/basePlatformSOMAS/graphs/issues +[license-shield]: https://img.shields.io/github/license/MattSScott/basePlatformSOMAS.svg +[license-url]: https://github.com/MattSScott/basePlatformSOMAS/blob/main/LICENSE.txt +[go-shield]: https://img.shields.io/badge/GoLang-blue?logo=go +[go-url]: https://go.dev diff --git a/basePlatformSOMASv2.0.pdf b/basePlatformSOMASv2.0.pdf new file mode 100644 index 0000000..769fb5f Binary files /dev/null and b/basePlatformSOMASv2.0.pdf differ diff --git a/internal/diagnosticsEngine/diagnosticsEngine.go b/internal/diagnosticsEngine/diagnosticsEngine.go index 636c807..1b75667 100644 --- a/internal/diagnosticsEngine/diagnosticsEngine.go +++ b/internal/diagnosticsEngine/diagnosticsEngine.go @@ -13,7 +13,7 @@ type IDiagnosticsEngine interface { // allow agents to report status of sent message ReportSendMessageStatus(bool) // allow server to report number of end message closures - ReportEndMessagingStatus() + ReportEndMessagingStatus(int) // allow for resetting of diagnostics for round-to-round data ResetRoundDiagnostics() // compile results for end of round messaging status @@ -33,8 +33,8 @@ func (de *DiagnosticsEngine) ReportSendMessageStatus(status bool) { } } -func (de *DiagnosticsEngine) ReportEndMessagingStatus() { - de.numEndMessagings++ +func (de *DiagnosticsEngine) ReportEndMessagingStatus(n int) { + de.numEndMessagings = n } func (de *DiagnosticsEngine) ResetRoundDiagnostics() { @@ -68,9 +68,15 @@ func (de *DiagnosticsEngine) GetNumberMessageDrops() int { } func (de *DiagnosticsEngine) GetMessagingSuccessRate() float32 { + if de.numMessages == 0 { + return 100 + } return 100 * float32(de.numMessageSuccesses) / float32(de.numMessages) } func (de *DiagnosticsEngine) GetEndMessagingSuccessRate(numAgents int) float32 { + if numAgents == 0 { + return 100 + } return 100 * float32(de.numEndMessagings) / float32(numAgents) } diff --git a/internal/diagnosticsEngine/diagnosticsEngine_test.go b/internal/diagnosticsEngine/diagnosticsEngine_test.go index fe45ef7..a0d5c37 100644 --- a/internal/diagnosticsEngine/diagnosticsEngine_test.go +++ b/internal/diagnosticsEngine/diagnosticsEngine_test.go @@ -48,7 +48,7 @@ func TestGetNumberEndMessagings(t *testing.T) { if initEnds != 0 { t.Error("Diagnostics engine intialised with non-zero number") } - engine.ReportEndMessagingStatus() + engine.ReportEndMessagingStatus(1) newEnds := engine.GetNumberEndMessagings() if newEnds != initEnds+1 { t.Error("Diagnostics engine successes not correctly incremented") @@ -94,11 +94,8 @@ func TestEndMessagingSuccessRate(t *testing.T) { engine := diagnosticsEngine.CreateDiagnosticsEngine() numAgents := 100 numReports := 20 - for i := 0; i < numAgents; i++ { - if i < numReports { - engine.ReportEndMessagingStatus() - } - } + + engine.ReportEndMessagingStatus(numReports) trueSuccessRate := engine.GetEndMessagingSuccessRate(numAgents) expectedSuccessRate := float32(numReports) / float32(numAgents) * 100 if trueSuccessRate != expectedSuccessRate { @@ -109,11 +106,12 @@ func TestEndMessagingSuccessRate(t *testing.T) { func TestResetDiagnostics(t *testing.T) { engine := diagnosticsEngine.CreateDiagnosticsEngine() rounds := 3 + nMessages := 10 for r := 0; r < rounds; r++ { - for delta := 0; delta < 10; delta++ { - engine.ReportEndMessagingStatus() + for delta := 0; delta < nMessages; delta++ { engine.ReportSendMessageStatus(true) } + engine.ReportEndMessagingStatus(nMessages) engine.ResetRoundDiagnostics() nSent := engine.GetNumberSentMessages() nSucc := engine.GetNumberMessageSuccesses() @@ -123,3 +121,15 @@ func TestResetDiagnostics(t *testing.T) { } } } + +func TestDivideByZeroProtection(t *testing.T) { + engine := diagnosticsEngine.CreateDiagnosticsEngine() + msgSuccessRate := engine.GetMessagingSuccessRate() + endMsgingSuccessRate := engine.GetEndMessagingSuccessRate(0) + if msgSuccessRate != 100.0 { + t.Errorf("Diagnostic Engine incorrectly reported Message Success rate when 0 messages sent. Expected 100%%, got %v%%", msgSuccessRate) + } + if endMsgingSuccessRate != 100.0 { + t.Errorf("Diagnostic Engine incorrectly reported Finished Messaging Success rate when 0 agents are present. Expected 100%%, got %v%%", endMsgingSuccessRate) + } +} diff --git a/internal/testUtils/testUtilsAgent.go b/internal/testUtils/testUtilsAgent.go index 29a0909..df0fd9e 100644 --- a/internal/testUtils/testUtilsAgent.go +++ b/internal/testUtils/testUtilsAgent.go @@ -19,7 +19,7 @@ type ITestBaseAgent interface { GetGoal() int32 SetGoal(int32) FinishedMessaging() - NotifyAgentFinishedMessagingUnthreaded(*sync.WaitGroup, *uint32) + SignalMessagingCompleteUnthreaded(*sync.WaitGroup, *uint32) GetAgentStoppedTalking() int HandleTimeoutTestMessage(msg TestTimeoutMessage) HandleInfiniteLoopMessage(msg TestMessagingBandwidthLimiter) @@ -32,13 +32,9 @@ type TestServerFunctionsAgent struct { *agent.BaseAgent[ITestBaseAgent] } -func (ta *TestServerFunctionsAgent) UpdateAgentInternalState() { - ta.Counter += 1 -} - func (ta *TestServerFunctionsAgent) FinishedMessaging() { ta.StoppedTalking++ - ta.NotifyAgentFinishedMessaging() + ta.SignalMessagingComplete() } func (ta *TestServerFunctionsAgent) CreateTestMessage() *TestMessage { @@ -48,7 +44,7 @@ func (ta *TestServerFunctionsAgent) CreateTestMessage() *TestMessage { } } -func (ta *TestServerFunctionsAgent) NotifyAgentFinishedMessagingUnthreaded(wg *sync.WaitGroup, counter *uint32) { +func (ta *TestServerFunctionsAgent) SignalMessagingCompleteUnthreaded(wg *sync.WaitGroup, counter *uint32) { defer wg.Done() ta.AgentStoppedTalking(ta.GetID()) atomic.AddUint32(counter, 1) @@ -61,7 +57,7 @@ func (ta TestServerFunctionsAgent) GetAgentStoppedTalking() int { func (ta *TestServerFunctionsAgent) HandleTestMessage() { newCounterValue := atomic.AddInt32(&ta.Counter, 1) if newCounterValue == atomic.LoadInt32(&ta.Goal) { - ta.NotifyAgentFinishedMessaging() + ta.SignalMessagingComplete() } } @@ -104,7 +100,7 @@ func (ta *TestServerFunctionsAgent) HandleTimeoutTestMessage(msg TestTimeoutMess start := time.Now() time.Sleep(msg.Workload) // simulate long work fmt.Println("work has been completed, took ", time.Since(start), "notifying finished messaging") - ta.NotifyAgentFinishedMessaging() + ta.SignalMessagingComplete() } func (ta *TestServerFunctionsAgent) HandleInfiniteLoopMessage(msg TestMessagingBandwidthLimiter) { diff --git a/internal/testUtils/testUtilsServer.go b/internal/testUtils/testUtilsServer.go index 7dfb529..a72d2c2 100644 --- a/internal/testUtils/testUtilsServer.go +++ b/internal/testUtils/testUtilsServer.go @@ -26,7 +26,7 @@ type TestServer struct { func GenerateTestServer(numAgents, iterations, turns int, maxDuration time.Duration, maxThreads int) *TestServer { serv := &TestServer{ - BaseServer: server.CreateServer[ITestBaseAgent](iterations, turns, maxDuration, maxThreads), + BaseServer: server.CreateBaseServer[ITestBaseAgent](iterations, turns, maxDuration, maxThreads), TurnCounter: 0, IterationStartCounter: 0, IterationEndCounter: 0, @@ -58,17 +58,14 @@ func NewTestMessage() *TestMessage { } func (ts *TestServer) RunTurn(turn, iteration int) { - for _,ag:= range ts.GetAgentMap() { + for _, ag := range ts.GetAgentMap() { newMsg := ag.CreateTestMessage() ag.BroadcastMessage(newMsg) } - + ts.TurnCounter += 1 } - - - func (ts *TestServer) RunStartOfIteration(iteration int) { ts.IterationStartCounter += 1 } @@ -80,6 +77,6 @@ func (ts *TestServer) RunEndOfIteration(iteration int) { func SendNotifyMessages(agMap map[uuid.UUID]ITestBaseAgent, count *uint32, wg *sync.WaitGroup) { for _, ag := range agMap { wg.Add(1) - go ag.NotifyAgentFinishedMessagingUnthreaded(wg, count) + go ag.SignalMessagingCompleteUnthreaded(wg, count) } } diff --git a/pkg/agent/agentInterface.go b/pkg/agent/agentInterface.go index 1db688e..1554394 100644 --- a/pkg/agent/agentInterface.go +++ b/pkg/agent/agentInterface.go @@ -22,16 +22,18 @@ type IExposedServerFunctions[T any] interface { } type IMessagingFunctions[T any] interface { - // signals end of agent's listening session - NotifyAgentFinishedMessaging() // allows for creation of a base message CreateBaseMessage() message.BaseMessage - // allows for sending a message across the entire system - BroadcastMessage(message.IMessage[T]) // allows for sending a message to a single recipient SendMessage(message.IMessage[T], uuid.UUID) // allows for sending a message to a single recipient synchronously SendSynchronousMessage(message.IMessage[T], uuid.UUID) + // allows for sending an async message across the entire system + BroadcastMessage(message.IMessage[T]) + // allows for sending a sync message across the entire system + BroadcastSynchronousMessage(message.IMessage[T]) + // signals end of agent's listening session + SignalMessagingComplete() } type IAgent[T any] interface { @@ -41,6 +43,4 @@ type IAgent[T any] interface { IMessagingFunctions[T] // returns the unique ID of an agent GetID() uuid.UUID - // allows agent to update their internal state - UpdateAgentInternalState() } diff --git a/pkg/agent/agent_test.go b/pkg/agent/agent_test.go index 8265a02..e1838ca 100644 --- a/pkg/agent/agent_test.go +++ b/pkg/agent/agent_test.go @@ -12,7 +12,7 @@ import ( func TestAgentIdOperations(t *testing.T) { var testServ agent.IExposedServerFunctions[testUtils.ITestBaseAgent] = &testUtils.TestServer{ - BaseServer: server.CreateServer[testUtils.ITestBaseAgent](1, 1, time.Second, 100), + BaseServer: server.CreateBaseServer[testUtils.ITestBaseAgent](1, 1, time.Second, 100), TurnCounter: 0, IterationStartCounter: 0, IterationEndCounter: 0, @@ -33,26 +33,6 @@ func TestNilInterfaceInjection(t *testing.T) { ag.GetID() } -func TestUpdateAgentInternalState(t *testing.T) { - var testServ agent.IExposedServerFunctions[testUtils.ITestBaseAgent] = &testUtils.TestServer{ - BaseServer: server.CreateServer[testUtils.ITestBaseAgent](1, 1, time.Second, 100), - TurnCounter: 0, - IterationStartCounter: 0, - IterationEndCounter: 0, - } - ag := testUtils.TestServerFunctionsAgent{ - BaseAgent: agent.CreateBaseAgent(testServ), - Counter: 0, - } - if ag.Counter != 0 { - t.Error("Additional agent field not correctly instantiated") - } - ag.UpdateAgentInternalState() - if ag.Counter != 1 { - t.Error("Agent state not correctly updated") - } -} - func TestCreateBaseMessage(t *testing.T) { testServ := testUtils.GenerateTestServer(1, 1, 1, time.Second, 100000) ag := testUtils.NewTestAgent(testServ) @@ -146,7 +126,7 @@ func TestRecursiveInvokeMessageHandlerCalls(t *testing.T) { msg := testUtils.CreateInfLoopMessage(ag.GetID()) ag.BroadcastMessage(msg) } - time.Sleep(10 * time.Millisecond) + time.Sleep(1 * time.Second) } func TestSendMessage(t *testing.T) { @@ -159,7 +139,7 @@ func TestSendMessage(t *testing.T) { ag.SetGoal(1) agent1.SendMessage(testMessage, id) } - time.Sleep(10 * time.Millisecond) + time.Sleep(1 * time.Second) for _, ag := range server.GetAgentMap() { if !ag.ReceivedMessage() { t.Error(ag, "Didn't Receive Message") @@ -178,7 +158,45 @@ func TestBroadcastMessage(t *testing.T) { } agent1.BroadcastMessage(testMessage) senderID := agent1.GetID() - time.Sleep(10 * time.Millisecond) + time.Sleep(1 * time.Second) + for _, ag := range server.GetAgentMap() { + if !ag.ReceivedMessage() && ag.GetID() != senderID { + t.Error(ag, "Didn't Receive Message") + } else if ag.ReceivedMessage() && ag.GetID() == senderID { + t.Error(ag, "is sender and received its own message") + } + } +} + +func TestBroadcastMessageDoesPanic(t *testing.T) { + defer func() { + if r := recover(); r == nil { + t.Errorf("BroadcastMessage did not panic as expected") + } + }() + numAgents := 3 + server := testUtils.GenerateTestServer(numAgents, 1, 1, 10*time.Millisecond, 100) + agent1 := testUtils.NewTestAgent(server) + testMessage := &testUtils.TestMessage{} + server.AddAgent(agent1) + for _, ag := range server.GetAgentMap() { + ag.SetGoal(1) + } + agent1.BroadcastMessage(testMessage) + time.Sleep(1 * time.Second) +} + +func TestBroadcastSynchronousMessage(t *testing.T) { + numAgents := 3 + server := testUtils.GenerateTestServer(numAgents, 1, 1, 10*time.Millisecond, 100) + agent1 := testUtils.NewTestAgent(server) + testMessage := agent1.CreateTestMessage() + server.AddAgent(agent1) + for _, ag := range server.GetAgentMap() { + ag.SetGoal(1) + } + agent1.BroadcastSynchronousMessage(testMessage) + senderID := agent1.GetID() for _, ag := range server.GetAgentMap() { if !ag.ReceivedMessage() && ag.GetID() != senderID { t.Error(ag, "Didn't Receive Message") @@ -187,3 +205,20 @@ func TestBroadcastMessage(t *testing.T) { } } } + +func TestBroadcastSynchronousMessageDoesPanic(t *testing.T) { + defer func() { + if r := recover(); r == nil { + t.Errorf("BroadcastSynchronousMessage did not panic as expected") + } + }() + numAgents := 3 + server := testUtils.GenerateTestServer(numAgents, 1, 1, 10*time.Millisecond, 100) + agent1 := testUtils.NewTestAgent(server) + testMessage := &testUtils.TestMessage{} + server.AddAgent(agent1) + for _, ag := range server.GetAgentMap() { + ag.SetGoal(1) + } + agent1.BroadcastSynchronousMessage(testMessage) +} diff --git a/pkg/agent/baseAgent.go b/pkg/agent/baseAgent.go index efe5250..7d9ebc0 100644 --- a/pkg/agent/baseAgent.go +++ b/pkg/agent/baseAgent.go @@ -33,9 +33,7 @@ func (a *BaseAgent[T]) CreateBaseMessage() message.BaseMessage { return message.BaseMessage{Sender: a.GetID()} } -func (a *BaseAgent[T]) UpdateAgentInternalState() {} - -func (a *BaseAgent[T]) NotifyAgentFinishedMessaging() { +func (a *BaseAgent[T]) SignalMessagingComplete() { go a.AgentStoppedTalking(a.id) } @@ -74,3 +72,15 @@ func (agent *BaseAgent[T]) BroadcastMessage(msg message.IMessage[T]) { agent.SendMessage(msg, id) } } + +func (agent *BaseAgent[T]) BroadcastSynchronousMessage(msg message.IMessage[T]) { + if msg.GetSender() == uuid.Nil { + panic("No sender found - did you compose the BaseMessage?") + } + for id := range agent.ViewAgentIdSet() { + if id == msg.GetSender() { + continue + } + agent.SendSynchronousMessage(msg, id) + } +} diff --git a/pkg/message/message_test.go b/pkg/message/message_test.go index ab26ca5..00bea3f 100644 --- a/pkg/message/message_test.go +++ b/pkg/message/message_test.go @@ -10,7 +10,7 @@ import ( ) func TestMessageCanBeExtended(t *testing.T) { - server := server.CreateServer[testUtils.IExtendedAgent](1, 1, time.Second, 100000) + server := server.CreateBaseServer[testUtils.IExtendedAgent](1, 1, time.Second, 100000) agent1 := testUtils.NewExtendedAgent(server) agent2 := testUtils.NewExtendedAgent(server) msgFromA1 := agent1.GetMessage1() @@ -26,7 +26,7 @@ func TestMessageCanBeExtended(t *testing.T) { } func TestSingleMessageGetsHandled(t *testing.T) { - server := server.CreateServer[testUtils.IExtendedAgent](1, 1, time.Second, 100000) + server := server.CreateBaseServer[testUtils.IExtendedAgent](1, 1, time.Second, 100000) a1 := testUtils.NewExtendedAgent(server) a2 := testUtils.NewExtendedAgent(server) a3 := testUtils.NewExtendedAgent(server) @@ -40,7 +40,7 @@ func TestSingleMessageGetsHandled(t *testing.T) { } func TestMultipleMessagesGetHandled(t *testing.T) { - server := server.CreateServer[testUtils.IExtendedAgent](1, 1, time.Second, 100000) + server := server.CreateBaseServer[testUtils.IExtendedAgent](1, 1, time.Second, 100000) a1 := testUtils.NewExtendedAgent(server) a2 := testUtils.NewExtendedAgent(server) allMessages := []message.IMessage[testUtils.IExtendedAgent]{a1.GetMessage1(), a1.GetMessage1(), a1.GetMessage2()} @@ -53,7 +53,7 @@ func TestMultipleMessagesGetHandled(t *testing.T) { } func TestGetSender(t *testing.T) { - server := server.CreateServer[testUtils.IExtendedAgent](1, 1, time.Second, 100000) + server := server.CreateBaseServer[testUtils.IExtendedAgent](1, 1, time.Second, 100000) a1 := testUtils.NewExtendedAgent(server) msg := a1.GetMessage1() agID := a1.GetID() diff --git a/pkg/server/baseServer.go b/pkg/server/baseServer.go index 35d23fd..8851c17 100644 --- a/pkg/server/baseServer.go +++ b/pkg/server/baseServer.go @@ -55,12 +55,12 @@ awaitSessionEnd: select { case id := <-serv.agentFinishedMessaging: agentStoppedTalkingMap[id] = struct{}{} - serv.diagnosticsEngine.ReportEndMessagingStatus() case <-ctx.Done(): status = false break awaitSessionEnd } } + serv.diagnosticsEngine.ReportEndMessagingStatus(len(agentStoppedTalkingMap)) close(serv.endNotifyAgentDone) return status } @@ -103,7 +103,7 @@ func (serv *BaseServer[T]) AccessAgentByID(id uuid.UUID) T { } func (serv *BaseServer[T]) Start() { - serv.checkHandler() + serv.checkGameRunner() for i := 0; i < serv.iterations; i++ { serv.gameRunner.RunStartOfIteration(i) for j := 0; j < serv.turns; j++ { @@ -132,7 +132,7 @@ func (serv *BaseServer[T]) SetGameRunner(handler GameRunner) { serv.gameRunner = handler } -func (serv *BaseServer[T]) checkHandler() { +func (serv *BaseServer[T]) checkGameRunner() { if serv.gameRunner == nil { panic("Handler for running turn has not been set. Have you called SetGameRunner?") } @@ -172,7 +172,7 @@ func (serv *BaseServer[T]) GetDiagnosticEngine() diagnosticsEngine.IDiagnosticsE } // generate a server instance based on a mapping function and number of iterations -func CreateServer[T agent.IAgent[T]](iterations, turns int, turnMaxDuration time.Duration, messageBandwidth int) *BaseServer[T] { +func CreateBaseServer[T agent.IAgent[T]](iterations, turns int, turnMaxDuration time.Duration, messageBandwidth int) *BaseServer[T] { return &BaseServer[T]{ agentMap: make(map[uuid.UUID]T), agentIdSet: make(map[uuid.UUID]struct{}), diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index e17b8d8..5532198 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -300,7 +300,7 @@ func TestRunTurnNotSetPanic(t *testing.T) { } }() server := &testUtils.TestTurnMethodPanics{ - BaseServer: server.CreateServer[testUtils.ITestBaseAgent](1, 1, time.Millisecond, 100), + BaseServer: server.CreateBaseServer[testUtils.ITestBaseAgent](1, 1, time.Millisecond, 100), } server.RunTurn(0, 0) } @@ -312,7 +312,7 @@ func TestRunStartOfIterationNotSetPanic(t *testing.T) { } }() server := &testUtils.TestTurnMethodPanics{ - BaseServer: server.CreateServer[testUtils.ITestBaseAgent](1, 1, time.Millisecond, 100), + BaseServer: server.CreateBaseServer[testUtils.ITestBaseAgent](1, 1, time.Millisecond, 100), } server.RunStartOfIteration(0) } @@ -324,7 +324,7 @@ func TestRunEndOfIterationNotSetPanic(t *testing.T) { } }() server := &testUtils.TestTurnMethodPanics{ - BaseServer: server.CreateServer[testUtils.ITestBaseAgent](1, 1, time.Millisecond, 100), + BaseServer: server.CreateBaseServer[testUtils.ITestBaseAgent](1, 1, time.Millisecond, 100), } server.RunEndOfIteration(0) } @@ -363,7 +363,7 @@ func TestMessagesSendInSaturatedServer(t *testing.T) { infLoopMessage := testUtils.CreateInfLoopMessage(evilAgent1.GetID()) evilAgent1.SendMessage(infLoopMessage, evilAgent2.GetID()) - time.Sleep(10 * time.Millisecond) + time.Sleep(1 * time.Second) //if message bandwidth is faulty this will fill it with messages from the two agents testMsg := testAgent1.CreateTestMessage() testAgent1.SendMessage(testMsg, testAgent2.GetID())