From 9d2e1c67a8969e4769006c7347505b58a7827b3f Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 1 May 2012 23:14:12 +0100 Subject: [PATCH 1/3] Add regression test for teleporting between neighbouring regions on the same simulator This adds a non-advertised wait_for_callback option in [EntityTransfer]. Default is always true. Teleport tests disable the wait for callback from the destination region in order to run within a single thread. --- .../Linden/UDP/Tests/LLImageManagerTests.cs | 3 +- .../ClientStack/RegionApplicationBase.cs | 2 +- .../EntityTransfer/EntityTransferModule.cs | 30 ++++- .../Tests/InventoryAccessModuleTests.cs | 7 +- .../Region/Framework/Scenes/ScenePresence.cs | 4 +- .../Scenes/Tests/ScenePresenceAgentTests.cs | 3 +- .../Tests/ScenePresenceTeleportTests.cs | 112 ++++++++++++++++-- OpenSim/Tests/Common/Helpers/SceneHelpers.cs | 72 ++++++++++- OpenSim/Tests/Common/Mock/TestClient.cs | 39 +++++- OpenSim/Tests/Common/TestHelpers.cs | 9 +- 10 files changed, 248 insertions(+), 33 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs index 221f02bda9..5fcf376b84 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/LLImageManagerTests.cs @@ -79,7 +79,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests J2KDecoderModule j2kdm = new J2KDecoderModule(); - scene = new SceneHelpers().SetupScene(); + SceneHelpers sceneHelpers = new SceneHelpers(); + scene = sceneHelpers.SetupScene(); SceneHelpers.SetupSceneModules(scene, j2kdm); tc = new TestClient(SceneHelpers.GenerateAgentData(userId), scene); diff --git a/OpenSim/Region/ClientStack/RegionApplicationBase.cs b/OpenSim/Region/ClientStack/RegionApplicationBase.cs index 6e3a58e63a..6e78d6d774 100644 --- a/OpenSim/Region/ClientStack/RegionApplicationBase.cs +++ b/OpenSim/Region/ClientStack/RegionApplicationBase.cs @@ -111,7 +111,7 @@ namespace OpenSim.Region.ClientStack server.Start(); } } - + base.StartupSpecific(); } diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 230706e042..35486bb5c1 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -52,12 +52,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public const int DefaultMaxTransferDistance = 4095; + public const bool EnableWaitForCallbackFromTeleportDestDefault = true; + /// /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer. /// public int MaxTransferDistance { get; set; } + /// + /// If true then on a teleport, the source region waits for a callback from the destination region. If + /// a callback fails to arrive within a set time then the user is pulled back into the source region. + /// + public bool EnableWaitForCallbackFromTeleportDest { get; set; } + protected bool m_Enabled = false; protected Scene m_aScene; protected List m_Scenes = new List(); @@ -99,9 +107,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { IConfig transferConfig = source.Configs["EntityTransfer"]; if (transferConfig != null) + { + EnableWaitForCallbackFromTeleportDest + = transferConfig.GetBoolean("wait_for_callback", EnableWaitForCallbackFromTeleportDestDefault); + MaxTransferDistance = transferConfig.GetInt("max_distance", DefaultMaxTransferDistance); + } else + { MaxTransferDistance = DefaultMaxTransferDistance; + } m_agentsInTransit = new List(); m_Enabled = true; @@ -499,6 +514,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } else { + ICapabilitiesModule capModule = sp.Scene.CapsModule; + ulong regionHandle = reg.RegionHandle; + capModule.GetChildSeed(UUID.Zero, regionHandle); agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); } @@ -527,7 +545,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID); + "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", + capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); if (eq != null) { @@ -546,7 +565,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation // that the client contacted the destination before we close things here. - if (!WaitForCallback(sp.UUID)) + if (EnableWaitForCallbackFromTeleportDest && !WaitForCallback(sp.UUID)) { m_log.WarnFormat( "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} failed due to no callback from destination region. Returning avatar to source region.", @@ -1286,7 +1305,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) { - AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); agent.BaseFolder = UUID.Zero; @@ -1311,7 +1329,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer seeds.Add(neighbour.RegionHandle, agent.CapsPath); } else + { agent.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, neighbour.RegionHandle); + } cagents.Add(agent); } @@ -1926,7 +1946,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer int count = 200; while (m_agentsInTransit.Contains(id) && count-- > 0) { - //m_log.Debug(" >>> Waiting... " + count); +// m_log.Debug(" >>> Waiting... " + count); Thread.Sleep(100); } @@ -1934,6 +1954,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return true; else return false; + + return true; } protected void SetInTransit(UUID id) diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs index d6afaa9e75..21d8bd77a9 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs @@ -64,8 +64,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); - - m_scene = new SceneHelpers().SetupScene(); + + SceneHelpers sceneHelpers = new SceneHelpers(); + m_scene = sceneHelpers.SetupScene(); SceneHelpers.SetupSceneModules(m_scene, config, m_iam); // Create user @@ -76,7 +77,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests AgentCircuitData acd = new AgentCircuitData(); acd.AgentID = m_userId; - m_tc = new TestClient(acd, m_scene); + m_tc = new TestClient(acd, m_scene); } [Test] diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f1d092616c..e5a9a996ba 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2895,8 +2895,8 @@ namespace OpenSim.Region.Framework.Scenes x = x / Constants.RegionSize; y = y / Constants.RegionSize; - //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); - //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); +// m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); +// m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY)) { byebyeRegions.Add(handle); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index 2e46377901..1aa48d7520 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs @@ -128,7 +128,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests IConfig config = configSource.AddConfig("Modules"); config.Set("SimulationServices", "LocalSimulationConnectorModule"); - TestScene scene = new SceneHelpers().SetupScene(); + SceneHelpers sceneHelpers = new SceneHelpers(); + TestScene scene = sceneHelpers.SetupScene(); SceneHelpers.SetupSceneModules(scene, configSource, lsc); UUID agentId = TestHelpers.ParseTail(0x01); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index c750cc5d10..ea4fb66b4e 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -33,8 +33,9 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Communications; using OpenSim.Framework.Servers; -using OpenSim.Region.CoreModules.Framework.EntityTransfer; using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.CoreModules.Framework; +using OpenSim.Region.CoreModules.Framework.EntityTransfer; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; @@ -49,6 +50,22 @@ namespace OpenSim.Region.Framework.Scenes.Tests [TestFixture] public class ScenePresenceTeleportTests { + [TestFixtureSetUp] + public void FixtureInit() + { + // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. + Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest; + } + + [TestFixtureTearDown] + public void TearDown() + { + // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple + // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression + // tests really shouldn't). + Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; + } + [Test] public void TestSameRegionTeleport() { @@ -96,10 +113,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); - config.AddConfig("Modules"); - // Not strictly necessary since FriendsModule assumes it is the default (!) - config.Configs["Modules"].Set("EntityTransferModule", etm.Name); - config.Configs["Modules"].Set("SimulationServices", lscm.Name); + IConfig modulesConfig = config.AddConfig("Modules"); + modulesConfig.Set("EntityTransferModule", etm.Name); + modulesConfig.Set("SimulationServices", lscm.Name); + IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); + + // In order to run a single threaded regression test we do not want the entity transfer module waiting + // for a callback from the destination scene before removing its avatar data. + entityTransferConfig.Set("wait_for_callback", false); SceneHelpers sh = new SceneHelpers(); TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); @@ -110,12 +131,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportLookAt = new Vector3(20, 21, 22); - ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId); + ScenePresence sp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager); sp.AbsolutePosition = new Vector3(30, 31, 32); // XXX: A very nasty hack to tell the client about the destination scene without having to crank the whole // UDP stack (?) - ((TestClient)sp.ControllingClient).TeleportTargetScene = sceneB; +// ((TestClient)sp.ControllingClient).TeleportTargetScene = sceneB; sceneA.RequestTeleportLocation( sp.ControllingClient, @@ -124,6 +145,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests teleportLookAt, (uint)TeleportFlags.ViaLocation); + ((TestClient)sp.ControllingClient).CompleteTeleportClientSide(); + Assert.That(sceneA.GetScenePresence(userId), Is.Null); ScenePresence sceneBSp = sceneB.GetScenePresence(userId); @@ -137,5 +160,80 @@ namespace OpenSim.Region.Framework.Scenes.Tests // position instead). // Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); } + + [Test] + public void TestSameSimulatorNeighbouringRegionsTeleport() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID userId = TestHelpers.ParseTail(0x1); + + EntityTransferModule etm = new EntityTransferModule(); + LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); + + IConfigSource config = new IniConfigSource(); + IConfig modulesConfig = config.AddConfig("Modules"); + modulesConfig.Set("EntityTransferModule", etm.Name); + modulesConfig.Set("SimulationServices", lscm.Name); + IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); + + // In order to run a single threaded regression test we do not want the entity transfer module waiting + // for a callback from the destination scene before removing its avatar data. + entityTransferConfig.Set("wait_for_callback", false); + + SceneHelpers sh = new SceneHelpers(); + TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); + TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000); + + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, etm, lscm); + SceneHelpers.SetupSceneModules(sceneA, new CapabilitiesModule()); + SceneHelpers.SetupSceneModules(sceneB, new CapabilitiesModule()); + + Vector3 teleportPosition = new Vector3(10, 11, 12); + Vector3 teleportLookAt = new Vector3(20, 21, 22); + + ScenePresence originalSp = SceneHelpers.AddScenePresence(sceneA, userId, sh.SceneManager); + originalSp.AbsolutePosition = new Vector3(30, 31, 32); + + ScenePresence beforeSceneASp = sceneA.GetScenePresence(userId); + Assert.That(beforeSceneASp, Is.Not.Null); + Assert.That(beforeSceneASp.IsChildAgent, Is.False); + + ScenePresence beforeSceneBSp = sceneB.GetScenePresence(userId); + Assert.That(beforeSceneBSp, Is.Not.Null); + Assert.That(beforeSceneBSp.IsChildAgent, Is.True); + + // XXX: A very nasty hack to tell the client about the destination scene without having to crank the whole + // UDP stack (?) +// ((TestClient)beforeSceneASp.ControllingClient).TeleportTargetScene = sceneB; + + sceneA.RequestTeleportLocation( + beforeSceneASp.ControllingClient, + sceneB.RegionInfo.RegionHandle, + teleportPosition, + teleportLookAt, + (uint)TeleportFlags.ViaLocation); + + ((TestClient)beforeSceneASp.ControllingClient).CompleteTeleportClientSide(); + + ScenePresence afterSceneASp = sceneA.GetScenePresence(userId); + Assert.That(afterSceneASp, Is.Not.Null); + Assert.That(afterSceneASp.IsChildAgent, Is.True); + + ScenePresence afterSceneBSp = sceneB.GetScenePresence(userId); + Assert.That(afterSceneBSp, Is.Not.Null); + Assert.That(afterSceneBSp.IsChildAgent, Is.False); + Assert.That(afterSceneBSp.Scene.RegionInfo.RegionName, Is.EqualTo(sceneB.RegionInfo.RegionName)); + Assert.That(afterSceneBSp.AbsolutePosition, Is.EqualTo(teleportPosition)); + + // TODO: Add assertions to check correct circuit details in both scenes. + + // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera + // position instead). +// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); + +// TestHelpers.DisableLogging(); + } } } \ No newline at end of file diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs index 8e547077fc..dc24418145 100644 --- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs @@ -58,6 +58,11 @@ namespace OpenSim.Tests.Common /// public class SceneHelpers { + /// + /// We need a scene manager so that test clients can retrieve a scene when performing teleport tests. + /// + public SceneManager SceneManager { get; private set; } + private AgentCircuitManager m_acm = new AgentCircuitManager(); private ISimulationDataService m_simDataService = OpenSim.Server.Base.ServerUtils.LoadPlugin("OpenSim.Tests.Common.dll", null); @@ -76,6 +81,8 @@ namespace OpenSim.Tests.Common public SceneHelpers(CoreAssetCache cache) { + SceneManager = new SceneManager(); + m_assetService = StartAssetService(cache); m_authenticationService = StartAuthenticationService(); m_inventoryService = StartInventoryService(); @@ -186,6 +193,8 @@ namespace OpenSim.Tests.Common testScene.LoginsDisabled = false; testScene.RegisterRegionWithGrid(); + SceneManager.Add(testScene); + return testScene; } @@ -350,6 +359,7 @@ namespace OpenSim.Tests.Common List newModules = new List(); foreach (object module in modules) { +// Console.WriteLine("MODULE RAW {0}", module); if (module is IRegionModule) { IRegionModule m = (IRegionModule)module; @@ -367,6 +377,7 @@ namespace OpenSim.Tests.Common // for the new system, everything has to be initialised first, // shared modules have to be post-initialised, then all get an AddRegion with the scene IRegionModuleBase m = (IRegionModuleBase)module; +// Console.WriteLine("MODULE {0}", m.Name); m.Initialise(config); newModules.Add(m); } @@ -426,6 +437,10 @@ namespace OpenSim.Tests.Common /// /// Add a root agent where the details of the agent connection (apart from the id) are unimportant for the test /// + /// + /// This can be used for tests where there is only one region or where there are multiple non-neighbour regions + /// and teleport doesn't take place. + /// /// /// /// @@ -434,6 +449,18 @@ namespace OpenSim.Tests.Common return AddScenePresence(scene, GenerateAgentData(agentId)); } + /// + /// Add a root agent where the details of the agent connection (apart from the id) are unimportant for the test + /// + /// + /// + /// + /// + public static ScenePresence AddScenePresence(Scene scene, UUID agentId, SceneManager sceneManager) + { + return AddScenePresence(scene, GenerateAgentData(agentId), sceneManager); + } + /// /// Add a root agent. /// @@ -453,6 +480,30 @@ namespace OpenSim.Tests.Common /// /// public static ScenePresence AddScenePresence(Scene scene, AgentCircuitData agentData) + { + return AddScenePresence(scene, agentData, null); + } + + /// + /// Add a root agent. + /// + /// + /// This function + /// + /// 1) Tells the scene that an agent is coming. Normally, the login service (local if standalone, from the + /// userserver if grid) would give initial login data back to the client and separately tell the scene that the + /// agent was coming. + /// + /// 2) Connects the agent with the scene + /// + /// This function performs actions equivalent with notifying the scene that an agent is + /// coming and then actually connecting the agent to the scene. The one step missed out is the very first + /// + /// + /// + /// + /// + public static ScenePresence AddScenePresence(Scene scene, AgentCircuitData agentData, SceneManager sceneManager) { // We emulate the proper login sequence here by doing things in four stages @@ -463,7 +514,7 @@ namespace OpenSim.Tests.Common lpsc.m_PresenceService.LoginAgent(agentData.AgentID.ToString(), agentData.SessionID, agentData.SecureSessionID); // Stages 1 & 2 - ScenePresence sp = IntroduceClientToScene(scene, agentData, TeleportFlags.ViaLogin); + ScenePresence sp = IntroduceClientToScene(scene, sceneManager, agentData, TeleportFlags.ViaLogin); // Stage 3: Complete the entrance into the region. This converts the child agent into a root agent. sp.CompleteMovement(sp.ControllingClient, true); @@ -471,7 +522,20 @@ namespace OpenSim.Tests.Common return sp; } - private static ScenePresence IntroduceClientToScene(Scene scene, AgentCircuitData agentData, TeleportFlags tf) + /// + /// Introduce an agent into the scene by adding a new client. + /// + /// The scene presence added + /// + /// Scene manager. Can be null if there is only one region in the test or multiple regions that are not + /// neighbours and where no teleporting takes place. + /// + /// + /// + /// + private static ScenePresence IntroduceClientToScene( + Scene scene, SceneManager sceneManager, AgentCircuitData agentData, TeleportFlags tf) { string reason; @@ -480,7 +544,7 @@ namespace OpenSim.Tests.Common Console.WriteLine("NewUserConnection failed: " + reason); // Stage 2: add the new client as a child agent to the scene - TestClient client = new TestClient(agentData, scene); + TestClient client = new TestClient(agentData, scene, sceneManager); scene.AddNewClient(client, PresenceType.User); return scene.GetScenePresence(agentData.AgentID); @@ -492,7 +556,7 @@ namespace OpenSim.Tests.Common acd.child = true; // XXX: ViaLogin may not be correct for child agents - return IntroduceClientToScene(scene, acd, TeleportFlags.ViaLogin); + return IntroduceClientToScene(scene, null, acd, TeleportFlags.ViaLogin); } /// diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index cb9840e4f7..36049a1386 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -46,12 +46,10 @@ namespace OpenSim.Tests.Common.Mock EventWaitHandle wh = new EventWaitHandle (false, EventResetMode.AutoReset, "Crossing"); - // TODO: This is a really nasty (and temporary) means of telling the test client which scene to invoke setup - // methods on when a teleport is requested - public Scene TeleportTargetScene; private TestClient TeleportSceneClient; private Scene m_scene; + private SceneManager m_sceneManager; // Properties so that we can get at received data for test purposes public List ReceivedOfflineNotifications { get; private set; } @@ -432,15 +430,29 @@ namespace OpenSim.Tests.Common.Mock /// /// Constructor /// + /// + /// Can be used for a test where there is only one region or where there are multiple regions that are not + /// neighbours and where no teleporting takes place. In other situations, the constructor that takes in a + /// scene manager should be used. + /// /// /// - public TestClient(AgentCircuitData agentData, Scene scene) + public TestClient(AgentCircuitData agentData, Scene scene) : this(agentData, scene, null) {} + + /// + /// Constructor + /// + /// + /// + /// + public TestClient(AgentCircuitData agentData, Scene scene, SceneManager sceneManager) { m_agentId = agentData.AgentID; m_firstName = agentData.firstname; m_lastName = agentData.lastname; m_circuitCode = agentData.circuitcode; m_scene = scene; + m_sceneManager = sceneManager; SessionId = agentData.SessionID; SecureSessionId = agentData.SecureSessionID; CapsSeedUrl = agentData.CapsPath; @@ -590,8 +602,16 @@ namespace OpenSim.Tests.Common.Mock AgentCircuitData newAgent = RequestClientInfo(); // Stage 2: add the new client as a child agent to the scene - TeleportSceneClient = new TestClient(newAgent, TeleportTargetScene); - TeleportTargetScene.AddNewClient(TeleportSceneClient, PresenceType.User); + uint x, y; + Utils.LongToUInts(neighbourHandle, out x, out y); + x /= Constants.RegionSize; + y /= Constants.RegionSize; + + Scene neighbourScene; + m_sceneManager.TryGetScene(x, y, out neighbourScene); + + TeleportSceneClient = new TestClient(newAgent, neighbourScene, m_sceneManager); + neighbourScene.AddNewClient(TeleportSceneClient, PresenceType.User); } public virtual void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint, @@ -601,6 +621,13 @@ namespace OpenSim.Tests.Common.Mock CapsSeedUrl = capsURL; + // We don't do this here so that the source region can complete processing first in a single-threaded + // regression test scenario. The test itself will have to call CompleteTeleportClientSide() after a teleport + // CompleteTeleportClientSide(); + } + + public void CompleteTeleportClientSide() + { TeleportSceneClient.CompleteMovement(); //TeleportTargetScene.AgentCrossing(newAgent.AgentID, new Vector3(90, 90, 90), false); } diff --git a/OpenSim/Tests/Common/TestHelpers.cs b/OpenSim/Tests/Common/TestHelpers.cs index 5030d4bf7f..6744fcac97 100644 --- a/OpenSim/Tests/Common/TestHelpers.cs +++ b/OpenSim/Tests/Common/TestHelpers.cs @@ -46,7 +46,8 @@ namespace OpenSim.Tests.Common - + + @@ -62,9 +63,9 @@ namespace OpenSim.Tests.Common Encoding.UTF8.GetBytes( // ""))); //""))); - //""))); - //""))); - //""))); +// "")); +// ""))); +// "")); "")); public static bool AssertThisDelegateCausesArgumentException(TestDelegate d) From a29f7f7551c0b6d783d9c6df9f6a6487901dfd82 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 1 May 2012 23:25:30 +0100 Subject: [PATCH 2/3] Remove some test code that accidentally crept in with 9d2e1c67 --- .../Framework/EntityTransfer/EntityTransferModule.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 35486bb5c1..75d1586565 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -514,9 +514,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } else { - ICapabilitiesModule capModule = sp.Scene.CapsModule; - ulong regionHandle = reg.RegionHandle; - capModule.GetChildSeed(UUID.Zero, regionHandle); agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); } From 40f3c24562e620e8f09b3569c0b643eb5eae013f Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 1 May 2012 23:49:02 +0100 Subject: [PATCH 3/3] Comment out the five second sleep in etm.DoTeleport() if the old agent needs to be closed because it is no longer in the child's view distance. This sleep appears unnecessary since a sleep has already occurred in WaitForCallback() whilst waiting for the destination region to notify of teleport success. There are no async operations between this sleep and the WaitForCallback() If this sleep is present, then teleporting back to the source region within 5 seconds results in a disconnection. If this sleep is commented out then teleporting quickly back and forth between two simulators appears to work without issue. Tested on standalone, local grid and distributed grid. Please revert if there's something that I've missed. --- .../Framework/EntityTransfer/EntityTransferModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 75d1586565..8d5e0a5890 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -595,7 +595,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) { - Thread.Sleep(5000); +// Thread.Sleep(5000); sp.Close(); sp.Scene.IncomingCloseAgent(sp.UUID); }