ChatModuleTests.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSimulator Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.Collections.Generic;
  29. using log4net.Config;
  30. using Nini.Config;
  31. using NUnit.Framework;
  32. using OpenMetaverse;
  33. using OpenSim.Framework;
  34. using OpenSim.Framework.Servers;
  35. using OpenSim.Framework.Servers.HttpServer;
  36. using OpenSim.Region.CoreModules.Avatar.Chat;
  37. using OpenSim.Region.CoreModules.Framework;
  38. using OpenSim.Region.CoreModules.Framework.EntityTransfer;
  39. using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
  40. using OpenSim.Region.Framework.Scenes;
  41. using OpenSim.Services.Interfaces;
  42. using OpenSim.Tests.Common;
  43. using System.Threading;
  44. namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests
  45. {
  46. [TestFixture]
  47. public class ChatModuleTests : OpenSimTestCase
  48. {
  49. [TestFixtureSetUp]
  50. public void FixtureInit()
  51. {
  52. // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
  53. // We must do this here so that child agent positions are updated in a predictable manner.
  54. Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
  55. }
  56. [TestFixtureTearDown]
  57. public void TearDown()
  58. {
  59. // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
  60. // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
  61. // tests really shouldn't).
  62. Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
  63. }
  64. private void SetupNeighbourRegions(TestScene sceneA, TestScene sceneB)
  65. {
  66. // XXX: HTTP server is not (and should not be) necessary for this test, though it's absence makes the
  67. // CapabilitiesModule complain when it can't set up HTTP endpoints.
  68. BaseHttpServer httpServer = new BaseHttpServer(99999);
  69. MainServer.AddHttpServer(httpServer);
  70. MainServer.Instance = httpServer;
  71. // We need entity transfer modules so that when sp2 logs into the east region, the region calls
  72. // EntityTransferModuleto set up a child agent on the west region.
  73. // XXX: However, this is not an entity transfer so is misleading.
  74. EntityTransferModule etmA = new EntityTransferModule();
  75. EntityTransferModule etmB = new EntityTransferModule();
  76. LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
  77. IConfigSource config = new IniConfigSource();
  78. config.AddConfig("Chat");
  79. IConfig modulesConfig = config.AddConfig("Modules");
  80. modulesConfig.Set("EntityTransferModule", etmA.Name);
  81. modulesConfig.Set("SimulationServices", lscm.Name);
  82. SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
  83. SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA, new ChatModule());
  84. SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB, new ChatModule());
  85. }
  86. /// <summary>
  87. /// Tests chat between neighbour regions on the east-west axis
  88. /// </summary>
  89. /// <remarks>
  90. /// Really, this is a combination of a child agent position update test and a chat range test. These need
  91. /// to be separated later on.
  92. /// </remarks>
  93. [Test]
  94. public void TestInterRegionChatDistanceEastWest()
  95. {
  96. TestHelpers.InMethod();
  97. // TestHelpers.EnableLogging();
  98. UUID sp1Uuid = TestHelpers.ParseTail(0x11);
  99. UUID sp2Uuid = TestHelpers.ParseTail(0x12);
  100. Vector3 sp1Position = new Vector3(6, 128, 20);
  101. Vector3 sp2Position = new Vector3(250, 128, 20);
  102. SceneHelpers sh = new SceneHelpers();
  103. TestScene sceneWest = sh.SetupScene("sceneWest", TestHelpers.ParseTail(0x1), 1000, 1000);
  104. TestScene sceneEast = sh.SetupScene("sceneEast", TestHelpers.ParseTail(0x2), 1001, 1000);
  105. SetupNeighbourRegions(sceneWest, sceneEast);
  106. ScenePresence sp1 = SceneHelpers.AddScenePresence(sceneEast, sp1Uuid);
  107. TestClient sp1Client = (TestClient)sp1.ControllingClient;
  108. // If we don't set agents to flying, test will go wrong as they instantly fall to z = 0.
  109. // TODO: May need to create special complete no-op test physics module rather than basic physics, since
  110. // physics is irrelevant to this test.
  111. sp1.Flying = true;
  112. // When sp1 logs in to sceneEast, it sets up a child agent in sceneWest and informs the sp2 client to
  113. // make the connection. For this test, will simplify this chain by making the connection directly.
  114. ScenePresence sp1Child = SceneHelpers.AddChildScenePresence(sceneWest, sp1Uuid);
  115. TestClient sp1ChildClient = (TestClient)sp1Child.ControllingClient;
  116. sp1.AbsolutePosition = sp1Position;
  117. ScenePresence sp2 = SceneHelpers.AddScenePresence(sceneWest, sp2Uuid);
  118. TestClient sp2Client = (TestClient)sp2.ControllingClient;
  119. sp2.Flying = true;
  120. ScenePresence sp2Child = SceneHelpers.AddChildScenePresence(sceneEast, sp2Uuid);
  121. TestClient sp2ChildClient = (TestClient)sp2Child.ControllingClient;
  122. sp2.AbsolutePosition = sp2Position;
  123. // We must update the scenes in order to make the root new root agents trigger position updates in their
  124. // children.
  125. for (int i = 0; i < 6; ++i)
  126. {
  127. sceneWest.Update(1);
  128. sceneEast.Update(1);
  129. }
  130. sp1.DrawDistance += 64;
  131. sp2.DrawDistance += 64;
  132. for (int i = 0; i < 6; ++i)
  133. {
  134. sceneWest.Update(1);
  135. sceneEast.Update(1);
  136. }
  137. // Check child positions are correct.
  138. Assert.AreEqual(
  139. new Vector3(sp1Position.X + sceneEast.RegionInfo.RegionSizeX, sp1Position.Y, sp1Position.Z),
  140. sp1ChildClient.SceneAgent.AbsolutePosition);
  141. Assert.AreEqual(
  142. new Vector3(sp2Position.X - sceneWest.RegionInfo.RegionSizeX, sp2Position.Y, sp2Position.Z),
  143. sp2ChildClient.SceneAgent.AbsolutePosition);
  144. string receivedSp1ChatMessage = "";
  145. string receivedSp2ChatMessage = "";
  146. sp1ChildClient.OnReceivedChatMessage
  147. += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp1ChatMessage = message;
  148. sp2ChildClient.OnReceivedChatMessage
  149. += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp2ChatMessage = message;
  150. TestUserInRange(sp1Client, "ello darling", ref receivedSp2ChatMessage);
  151. TestUserInRange(sp2Client, "fantastic cats", ref receivedSp1ChatMessage);
  152. sp1Position = new Vector3(30, 128, 20);
  153. sp1.AbsolutePosition = sp1Position;
  154. for (int i = 0; i < 2; ++i)
  155. {
  156. sceneWest.Update(1);
  157. sceneEast.Update(1);
  158. }
  159. Thread.Sleep(12000); // child updates are now time limited
  160. for (int i = 0; i < 6; ++i)
  161. {
  162. sceneWest.Update(1);
  163. sceneEast.Update(1);
  164. }
  165. // Check child position is correct.
  166. Assert.AreEqual(
  167. new Vector3(sp1Position.X + sceneEast.RegionInfo.RegionSizeX, sp1Position.Y, sp1Position.Z),
  168. sp1ChildClient.SceneAgent.AbsolutePosition);
  169. TestUserOutOfRange(sp1Client, "beef", ref receivedSp2ChatMessage);
  170. TestUserOutOfRange(sp2Client, "lentils", ref receivedSp1ChatMessage);
  171. }
  172. /// <summary>
  173. /// Tests chat between neighbour regions on the north-south axis
  174. /// </summary>
  175. /// <remarks>
  176. /// Really, this is a combination of a child agent position update test and a chat range test. These need
  177. /// to be separated later on.
  178. /// </remarks>
  179. [Test]
  180. public void TestInterRegionChatDistanceNorthSouth()
  181. {
  182. TestHelpers.InMethod();
  183. // TestHelpers.EnableLogging();
  184. UUID sp1Uuid = TestHelpers.ParseTail(0x11);
  185. UUID sp2Uuid = TestHelpers.ParseTail(0x12);
  186. Vector3 sp1Position = new Vector3(128, 250, 20);
  187. Vector3 sp2Position = new Vector3(128, 6, 20);
  188. SceneHelpers sh = new SceneHelpers();
  189. TestScene sceneNorth = sh.SetupScene("sceneNorth", TestHelpers.ParseTail(0x1), 1000, 1000);
  190. TestScene sceneSouth = sh.SetupScene("sceneSouth", TestHelpers.ParseTail(0x2), 1000, 1001);
  191. SetupNeighbourRegions(sceneNorth, sceneSouth);
  192. ScenePresence sp1 = SceneHelpers.AddScenePresence(sceneNorth, sp1Uuid);
  193. TestClient sp1Client = (TestClient)sp1.ControllingClient;
  194. // If we don't set agents to flying, test will go wrong as they instantly fall to z = 0.
  195. // TODO: May need to create special complete no-op test physics module rather than basic physics, since
  196. // physics is irrelevant to this test.
  197. sp1.Flying = true;
  198. // When sp1 logs in to sceneEast, it sets up a child agent in sceneNorth and informs the sp2 client to
  199. // make the connection. For this test, will simplify this chain by making the connection directly.
  200. ScenePresence sp1Child = SceneHelpers.AddChildScenePresence(sceneSouth, sp1Uuid);
  201. TestClient sp1ChildClient = (TestClient)sp1Child.ControllingClient;
  202. sp1.AbsolutePosition = sp1Position;
  203. ScenePresence sp2 = SceneHelpers.AddScenePresence(sceneSouth, sp2Uuid);
  204. TestClient sp2Client = (TestClient)sp2.ControllingClient;
  205. sp2.Flying = true;
  206. ScenePresence sp2Child = SceneHelpers.AddChildScenePresence(sceneNorth, sp2Uuid);
  207. TestClient sp2ChildClient = (TestClient)sp2Child.ControllingClient;
  208. sp2.AbsolutePosition = sp2Position;
  209. // We must update the scenes in order to make the root new root agents trigger position updates in their
  210. // children.
  211. for (int i = 0; i < 6; ++i)
  212. {
  213. sceneNorth.Update(1);
  214. sceneSouth.Update(1);
  215. }
  216. sp1.DrawDistance += 64;
  217. sp2.DrawDistance += 64;
  218. for (int i = 0; i < 6; ++i)
  219. {
  220. sceneNorth.Update(1);
  221. sceneSouth.Update(1);
  222. }
  223. // Check child positions are correct.
  224. Assert.AreEqual(
  225. new Vector3(sp1Position.X, sp1Position.Y - sceneNorth.RegionInfo.RegionSizeY, sp1Position.Z),
  226. sp1ChildClient.SceneAgent.AbsolutePosition);
  227. Assert.AreEqual(
  228. new Vector3(sp2Position.X, sp2Position.Y + sceneSouth.RegionInfo.RegionSizeY, sp2Position.Z),
  229. sp2ChildClient.SceneAgent.AbsolutePosition);
  230. string receivedSp1ChatMessage = "";
  231. string receivedSp2ChatMessage = "";
  232. sp1ChildClient.OnReceivedChatMessage
  233. += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp1ChatMessage = message;
  234. sp2ChildClient.OnReceivedChatMessage
  235. += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp2ChatMessage = message;
  236. TestUserInRange(sp1Client, "ello darling", ref receivedSp2ChatMessage);
  237. TestUserInRange(sp2Client, "fantastic cats", ref receivedSp1ChatMessage);
  238. sp1Position = new Vector3(30, 128, 20);
  239. sp1.AbsolutePosition = sp1Position;
  240. sceneNorth.Update(6);
  241. sceneSouth.Update(6);
  242. Thread.Sleep(12000); // child updates are now time limited
  243. sceneNorth.Update(6);
  244. sceneSouth.Update(6);
  245. // Check child position is correct.
  246. Assert.AreEqual(
  247. new Vector3(sp1Position.X, sp1Position.Y - sceneNorth.RegionInfo.RegionSizeY, sp1Position.Z),
  248. sp1ChildClient.SceneAgent.AbsolutePosition);
  249. TestUserOutOfRange(sp1Client, "beef", ref receivedSp2ChatMessage);
  250. TestUserOutOfRange(sp2Client, "lentils", ref receivedSp1ChatMessage);
  251. }
  252. private void TestUserInRange(TestClient speakClient, string testMessage, ref string receivedMessage)
  253. {
  254. receivedMessage = "";
  255. speakClient.Chat(0, ChatTypeEnum.Say, testMessage);
  256. Assert.AreEqual(testMessage, receivedMessage);
  257. }
  258. private void TestUserOutOfRange(TestClient speakClient, string testMessage, ref string receivedMessage)
  259. {
  260. receivedMessage = "";
  261. speakClient.Chat(0, ChatTypeEnum.Say, testMessage);
  262. Assert.AreNotEqual(testMessage, receivedMessage);
  263. }
  264. }
  265. }