From c0ab406e2e3ab1e1702285c7cd35e1adc6cc593b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 19 Jul 2012 21:41:13 +0100 Subject: Add basic TestCreateRootScenePresence() regression test --- .../Scenes/Tests/ScenePresenceAgentTests.cs | 279 +++++++++++---------- 1 file changed, 144 insertions(+), 135 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index 02c45ef..44c1396 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs @@ -53,48 +53,60 @@ namespace OpenSim.Region.Framework.Scenes.Tests /// Scene presence tests /// [TestFixture] - public class ScenePresenceAgentTests + public class ScenePresenceAgentTests : OpenSimTestCase { - public Scene scene, scene2, scene3; - public UUID agent1, agent2, agent3; - public static Random random; - public ulong region1,region2,region3; - public AgentCircuitData acd1; - public SceneObjectGroup sog1, sog2, sog3; - public TestClient testclient; - - [TestFixtureSetUp] - public void Init() +// public Scene scene, scene2, scene3; +// public UUID agent1, agent2, agent3; +// public static Random random; +// public ulong region1, region2, region3; +// public AgentCircuitData acd1; +// public TestClient testclient; + +// [TestFixtureSetUp] +// public void Init() +// { +//// TestHelpers.InMethod(); +//// +//// SceneHelpers sh = new SceneHelpers(); +//// +//// scene = sh.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); +//// scene2 = sh.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); +//// scene3 = sh.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000); +//// +//// ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); +//// interregionComms.Initialise(new IniConfigSource()); +//// interregionComms.PostInitialise(); +//// SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms); +//// SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms); +//// SceneHelpers.SetupSceneModules(scene3, new IniConfigSource(), interregionComms); +// +//// agent1 = UUID.Random(); +//// agent2 = UUID.Random(); +//// agent3 = UUID.Random(); +// +//// region1 = scene.RegionInfo.RegionHandle; +//// region2 = scene2.RegionInfo.RegionHandle; +//// region3 = scene3.RegionInfo.RegionHandle; +// } + + [Test] + public void TestCreateRootScenePresence() { TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID spUuid = TestHelpers.ParseTail(0x1); + + TestScene scene = new SceneHelpers().SetupScene(); + SceneHelpers.AddScenePresence(scene, spUuid); + + Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(spUuid), Is.Not.Null); + Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1)); - SceneHelpers sh = new SceneHelpers(); - - scene = sh.SetupScene("Neighbour x", UUID.Random(), 1000, 1000); - scene2 = sh.SetupScene("Neighbour x+1", UUID.Random(), 1001, 1000); - scene3 = sh.SetupScene("Neighbour x-1", UUID.Random(), 999, 1000); - - ISharedRegionModule interregionComms = new LocalSimulationConnectorModule(); - interregionComms.Initialise(new IniConfigSource()); - interregionComms.PostInitialise(); - SceneHelpers.SetupSceneModules(scene, new IniConfigSource(), interregionComms); - SceneHelpers.SetupSceneModules(scene2, new IniConfigSource(), interregionComms); - SceneHelpers.SetupSceneModules(scene3, new IniConfigSource(), interregionComms); - - agent1 = UUID.Random(); - agent2 = UUID.Random(); - agent3 = UUID.Random(); - random = new Random(); - sog1 = SceneHelpers.CreateSceneObject(1, agent1); - scene.AddSceneObject(sog1); - sog2 = SceneHelpers.CreateSceneObject(1, agent1); - scene.AddSceneObject(sog2); - sog3 = SceneHelpers.CreateSceneObject(1, agent1); - scene.AddSceneObject(sog3); - - region1 = scene.RegionInfo.RegionHandle; - region2 = scene2.RegionInfo.RegionHandle; - region3 = scene3.RegionInfo.RegionHandle; + ScenePresence sp = scene.GetScenePresence(spUuid); + Assert.That(sp, Is.Not.Null); + Assert.That(sp.IsChildAgent, Is.False); + Assert.That(sp.UUID, Is.EqualTo(spUuid)); } [Test] @@ -106,9 +118,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestScene scene = new SceneHelpers().SetupScene(); ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); - Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(sp.UUID), Is.Not.Null); - Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1)); - scene.IncomingCloseAgent(sp.UUID); Assert.That(scene.GetScenePresence(sp.UUID), Is.Null); @@ -266,99 +275,99 @@ namespace OpenSim.Region.Framework.Scenes.Tests // but things are synchronous among them. So there should be // 3 threads in here. //[Test] - public void T021_TestCrossToNewRegion() - { - TestHelpers.InMethod(); - - scene.RegisterRegionWithGrid(); - scene2.RegisterRegionWithGrid(); - - // Adding child agent to region 1001 - string reason; - scene2.NewUserConnection(acd1,0, out reason); - scene2.AddNewClient(testclient, PresenceType.User); - - ScenePresence presence = scene.GetScenePresence(agent1); - presence.MakeRootAgent(new Vector3(0,unchecked(Constants.RegionSize-1),0), true); - - ScenePresence presence2 = scene2.GetScenePresence(agent1); - - // Adding neighbour region caps info to presence2 - - string cap = presence.ControllingClient.RequestClientInfo().CapsPath; - presence2.AddNeighbourRegion(region1, cap); - - Assert.That(presence.IsChildAgent, Is.False, "Did not start root in origin region."); - Assert.That(presence2.IsChildAgent, Is.True, "Is not a child on destination region."); - - // Cross to x+1 - presence.AbsolutePosition = new Vector3(Constants.RegionSize+1,3,100); - presence.Update(); - - EventWaitHandle wh = new EventWaitHandle (false, EventResetMode.AutoReset, "Crossing"); - - // Mimicking communication between client and server, by waiting OK from client - // sent by TestClient.CrossRegion call. Originally, this is network comm. - if (!wh.WaitOne(5000,false)) - { - presence.Update(); - if (!wh.WaitOne(8000,false)) - throw new ArgumentException("1 - Timeout waiting for signal/variable."); - } - - // This is a TestClient specific method that fires OnCompleteMovementToRegion event, which - // would normally be fired after receiving the reply packet from comm. done on the last line. - testclient.CompleteMovement(); - - // Crossings are asynchronous - int timer = 10; - - // Make sure cross hasn't already finished - if (!presence.IsInTransit && !presence.IsChildAgent) - { - // If not and not in transit yet, give it some more time - Thread.Sleep(5000); - } - - // Enough time, should at least be in transit by now. - while (presence.IsInTransit && timer > 0) - { - Thread.Sleep(1000); - timer-=1; - } - - Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 2->1."); - Assert.That(presence.IsChildAgent, Is.True, "Did not complete region cross as expected."); - Assert.That(presence2.IsChildAgent, Is.False, "Did not receive root status after receiving agent."); - - // Cross Back - presence2.AbsolutePosition = new Vector3(-10, 3, 100); - presence2.Update(); - - if (!wh.WaitOne(5000,false)) - { - presence2.Update(); - if (!wh.WaitOne(8000,false)) - throw new ArgumentException("2 - Timeout waiting for signal/variable."); - } - testclient.CompleteMovement(); - - if (!presence2.IsInTransit && !presence2.IsChildAgent) - { - // If not and not in transit yet, give it some more time - Thread.Sleep(5000); - } - - // Enough time, should at least be in transit by now. - while (presence2.IsInTransit && timer > 0) - { - Thread.Sleep(1000); - timer-=1; - } - - Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 1->2."); - Assert.That(presence2.IsChildAgent, Is.True, "Did not return from region as expected."); - Assert.That(presence.IsChildAgent, Is.False, "Presence was not made root in old region again."); - } +// public void T021_TestCrossToNewRegion() +// { +// TestHelpers.InMethod(); +// +// scene.RegisterRegionWithGrid(); +// scene2.RegisterRegionWithGrid(); +// +// // Adding child agent to region 1001 +// string reason; +// scene2.NewUserConnection(acd1,0, out reason); +// scene2.AddNewClient(testclient, PresenceType.User); +// +// ScenePresence presence = scene.GetScenePresence(agent1); +// presence.MakeRootAgent(new Vector3(0,unchecked(Constants.RegionSize-1),0), true); +// +// ScenePresence presence2 = scene2.GetScenePresence(agent1); +// +// // Adding neighbour region caps info to presence2 +// +// string cap = presence.ControllingClient.RequestClientInfo().CapsPath; +// presence2.AddNeighbourRegion(region1, cap); +// +// Assert.That(presence.IsChildAgent, Is.False, "Did not start root in origin region."); +// Assert.That(presence2.IsChildAgent, Is.True, "Is not a child on destination region."); +// +// // Cross to x+1 +// presence.AbsolutePosition = new Vector3(Constants.RegionSize+1,3,100); +// presence.Update(); +// +// EventWaitHandle wh = new EventWaitHandle (false, EventResetMode.AutoReset, "Crossing"); +// +// // Mimicking communication between client and server, by waiting OK from client +// // sent by TestClient.CrossRegion call. Originally, this is network comm. +// if (!wh.WaitOne(5000,false)) +// { +// presence.Update(); +// if (!wh.WaitOne(8000,false)) +// throw new ArgumentException("1 - Timeout waiting for signal/variable."); +// } +// +// // This is a TestClient specific method that fires OnCompleteMovementToRegion event, which +// // would normally be fired after receiving the reply packet from comm. done on the last line. +// testclient.CompleteMovement(); +// +// // Crossings are asynchronous +// int timer = 10; +// +// // Make sure cross hasn't already finished +// if (!presence.IsInTransit && !presence.IsChildAgent) +// { +// // If not and not in transit yet, give it some more time +// Thread.Sleep(5000); +// } +// +// // Enough time, should at least be in transit by now. +// while (presence.IsInTransit && timer > 0) +// { +// Thread.Sleep(1000); +// timer-=1; +// } +// +// Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 2->1."); +// Assert.That(presence.IsChildAgent, Is.True, "Did not complete region cross as expected."); +// Assert.That(presence2.IsChildAgent, Is.False, "Did not receive root status after receiving agent."); +// +// // Cross Back +// presence2.AbsolutePosition = new Vector3(-10, 3, 100); +// presence2.Update(); +// +// if (!wh.WaitOne(5000,false)) +// { +// presence2.Update(); +// if (!wh.WaitOne(8000,false)) +// throw new ArgumentException("2 - Timeout waiting for signal/variable."); +// } +// testclient.CompleteMovement(); +// +// if (!presence2.IsInTransit && !presence2.IsChildAgent) +// { +// // If not and not in transit yet, give it some more time +// Thread.Sleep(5000); +// } +// +// // Enough time, should at least be in transit by now. +// while (presence2.IsInTransit && timer > 0) +// { +// Thread.Sleep(1000); +// timer-=1; +// } +// +// Assert.That(timer,Is.GreaterThan(0),"Timed out waiting to cross 1->2."); +// Assert.That(presence2.IsChildAgent, Is.True, "Did not return from region as expected."); +// Assert.That(presence.IsChildAgent, Is.False, "Presence was not made root in old region again."); +// } } } \ No newline at end of file -- cgit v1.1 From e9a121e1b203e8880bcaf85d35612fc6706b281a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 19 Jul 2012 21:54:50 +0100 Subject: Add TestCreateDuplicateRootScenePresence() regression test. --- OpenSim/Region/Framework/Scenes/Scene.cs | 17 ++++++++++++++++ OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- .../Scenes/Tests/ScenePresenceAgentTests.cs | 23 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 6d8ee7b..36452de 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4470,6 +4470,23 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// Gets all the scene presences in this scene. + /// + /// + /// This method will return both root and child scene presences. + /// + /// Consider using ForEachScenePresence() or ForEachRootScenePresence() if possible since these will not + /// involving creating a new List object. + /// + /// + /// A list of the scene presences. Adding or removing from the list will not affect the presences in the scene. + /// + public List GetScenePresences() + { + return new List(m_sceneGraph.GetScenePresences()); + } + + /// /// Performs action on all avatars in the scene (root scene presences) /// Avatars may be an NPC or a 'real' client. /// diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 2be5364..ba68dfa 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -768,7 +768,7 @@ namespace OpenSim.Region.Framework.Scenes /// pass a delegate to ForEachScenePresence. /// /// - private List GetScenePresences() + protected internal List GetScenePresences() { return m_scenePresenceArray; } diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs index 44c1396..5758869 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceAgentTests.cs @@ -107,6 +107,29 @@ namespace OpenSim.Region.Framework.Scenes.Tests Assert.That(sp, Is.Not.Null); Assert.That(sp.IsChildAgent, Is.False); Assert.That(sp.UUID, Is.EqualTo(spUuid)); + + Assert.That(scene.GetScenePresences().Count, Is.EqualTo(1)); + } + + [Test] + public void TestCreateDuplicateRootScenePresence() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID spUuid = TestHelpers.ParseTail(0x1); + + TestScene scene = new SceneHelpers().SetupScene(); + SceneHelpers.AddScenePresence(scene, spUuid); + SceneHelpers.AddScenePresence(scene, spUuid); + + Assert.That(scene.AuthenticateHandler.GetAgentCircuitData(spUuid), Is.Not.Null); + Assert.That(scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(1)); + + ScenePresence sp = scene.GetScenePresence(spUuid); + Assert.That(sp, Is.Not.Null); + Assert.That(sp.IsChildAgent, Is.False); + Assert.That(sp.UUID, Is.EqualTo(spUuid)); } [Test] -- cgit v1.1 From ba80f137b58cfacf46fadb3ec8b63af6896c5b43 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 19 Jul 2012 22:32:27 +0100 Subject: Prevent race conditions between two threads that call LLClientView.Close() simultaneously (e.g. ack timeout and an attempt to reconnect) --- OpenSim/Region/Framework/Scenes/Scene.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 36452de..51a6820 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3517,8 +3517,8 @@ namespace OpenSim.Region.Framework.Scenes // We have a zombie from a crashed session. // Or the same user is trying to be root twice here, won't work. // Kill it. - m_log.DebugFormat( - "[SCENE]: Zombie scene presence detected for {0} {1} in {2}", + m_log.WarnFormat( + "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", sp.Name, sp.UUID, RegionInfo.RegionName); sp.ControllingClient.Close(); @@ -4474,7 +4474,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// This method will return both root and child scene presences. - /// + /// /// Consider using ForEachScenePresence() or ForEachRootScenePresence() if possible since these will not /// involving creating a new List object. /// -- cgit v1.1 From e94831ddab282f2d84d0dad0b28e7cce6ac4c4b0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 19 Jul 2012 22:59:28 +0100 Subject: Stop explicitly closing and nulling out Animator in order to prevent NREs in various places due to race conditions. Even where checks are being made they aren't enough since they all assume that the Animator they just checked is still there in the next line, which is not necessarily the case without locking. The memory used is small and these should be GC'd anyway when the SP is released. If this is not happening then the wider problem of old SPs being retained needs to be resolved. --- .../Scenes/Animation/ScenePresenceAnimator.cs | 8 +------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 22 ++++++---------------- 2 files changed, 7 insertions(+), 23 deletions(-) (limited to 'OpenSim/Region/Framework/Scenes') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index 14ae287..ff53f45 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -535,11 +535,5 @@ namespace OpenSim.Region.Framework.Scenes.Animation SendAnimPack(animIDs, sequenceNums, objectIDs); } - - public void Close() - { - m_animations = null; - m_scenePresence = null; - } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0e7f2e5..548dfd3 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -109,15 +109,10 @@ namespace OpenSim.Region.Framework.Scenes public UUID currentParcelUUID = UUID.Zero; - protected ScenePresenceAnimator m_animator; /// /// The animator for this avatar /// - public ScenePresenceAnimator Animator - { - get { return m_animator; } - private set { m_animator = value; } - } + public ScenePresenceAnimator Animator { get; private set; } /// /// Attachments recorded on this avatar. @@ -2569,8 +2564,7 @@ namespace OpenSim.Region.Framework.Scenes //m_log.DebugFormat("[SCENE PRESENCE] SendAvatarDataToAgent from {0} ({1}) to {2} ({3})", Name, UUID, avatar.Name, avatar.UUID); avatar.ControllingClient.SendAvatarDataImmediate(this); - if (Animator != null) - Animator.SendAnimPackToClient(avatar.ControllingClient); + Animator.SendAnimPackToClient(avatar.ControllingClient); } /// @@ -3239,14 +3233,12 @@ namespace OpenSim.Region.Framework.Scenes //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) // The Physics Scene will send updates every 500 ms grep: PhysicsActor.SubscribeEvents( // as of this comment the interval is set in AddToPhysicalScene - if (Animator != null) - { + // if (m_updateCount > 0) // { - Animator.UpdateMovementAnimations(); + Animator.UpdateMovementAnimations(); // m_updateCount--; // } - } CollisionEventUpdate collisionData = (CollisionEventUpdate)e; Dictionary coldata = collisionData.m_objCollisionList; @@ -3261,7 +3253,7 @@ namespace OpenSim.Region.Framework.Scenes // m_lastColCount = coldata.Count; // } - if (coldata.Count != 0 && Animator != null) + if (coldata.Count != 0) { switch (Animator.CurrentMovementAnimation) { @@ -3371,7 +3363,7 @@ namespace OpenSim.Region.Framework.Scenes ControllingClient.SendHealth(Health); } - public void Close() + protected internal void Close() { // Clear known regions KnownRegions = new Dictionary(); @@ -3387,8 +3379,6 @@ namespace OpenSim.Region.Framework.Scenes // m_reprioritizationTimer.Dispose(); RemoveFromPhysicalScene(); - Animator.Close(); - Animator = null; } public void AddAttachment(SceneObjectGroup gobj) -- cgit v1.1