From 7a4f11b94da2ba2fbe24393ce2804214e199bce7 Mon Sep 17 00:00:00 2001 From: Sean Dague Date: Fri, 12 Dec 2008 18:33:16 +0000 Subject: * Deleted old EntiyList tests, added new EntityManager tests * Edited EntityManager to treat Exceptions From: Arthur Rodrigo S Valadares --- OpenSim/Region/Environment/Scenes/EntityList.cs | 161 -------------- OpenSim/Region/Environment/Scenes/EntityManager.cs | 108 ++++++++-- .../Environment/Scenes/Tests/EntityListTests.cs | 238 --------------------- .../Environment/Scenes/Tests/EntityManagerTests.cs | 178 +++++++++++++++ 4 files changed, 267 insertions(+), 418 deletions(-) delete mode 100644 OpenSim/Region/Environment/Scenes/EntityList.cs delete mode 100644 OpenSim/Region/Environment/Scenes/Tests/EntityListTests.cs create mode 100644 OpenSim/Region/Environment/Scenes/Tests/EntityManagerTests.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Environment/Scenes/EntityList.cs b/OpenSim/Region/Environment/Scenes/EntityList.cs deleted file mode 100644 index 2488ab3..0000000 --- a/OpenSim/Region/Environment/Scenes/EntityList.cs +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSim Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; -using OpenMetaverse; -using OpenMetaverse.Packets; -using log4net; -using OpenSim.Framework; -using OpenSim.Region.Environment.Types; -using OpenSim.Region.Physics.Manager; - -namespace OpenSim.Region.Environment.Scenes -{ - public class EntityList - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - // we are intentionally using non generics here as testing has - // shown synchronized collections are faster than manually - // locked generics. - - private Hashtable m_obj_by_uuid; - private Hashtable m_obj_by_local; - - private Hashtable m_pres_by_uuid; - - public EntityList() - { - m_obj_by_uuid = Hashtable.Synchronized(new Hashtable()); - m_obj_by_local = Hashtable.Synchronized(new Hashtable()); - m_pres_by_uuid = Hashtable.Synchronized(new Hashtable()); - } - - // Interface definition - // - // Add(SOG) - // Add(SP) - // RemoveObject(SOG) - // RemovePresence(SP) - // List() - // ListObjects() - // ListPresenes() - // RemoveAll() - // FindObject(UUID) - // FindObject(int) - // FindPresence(UUID) - - public void Add(SceneObjectGroup obj) - { - m_obj_by_uuid[obj.UUID] = obj; - m_obj_by_local[obj.LocalId] = obj.UUID; - } - - public void Add(ScenePresence pres) - { - m_pres_by_uuid[pres.UUID] = pres; - } - - public SceneObjectGroup RemoveObject(UUID uuid) - { - SceneObjectGroup sog = null; - try - { - sog = (SceneObjectGroup)m_obj_by_uuid[uuid]; - m_obj_by_uuid.Remove(uuid); - m_obj_by_local.Remove(sog.LocalId); - } - catch (Exception e) - { - m_log.ErrorFormat("RemoveObject failed for {0}", uuid, e); - sog = null; - } - return sog; - } - - public ScenePresence RemovePresence(UUID uuid) - { - ScenePresence sp = null; - try - { - sp = (ScenePresence)m_pres_by_uuid[uuid]; - m_pres_by_uuid.Remove(uuid); - } - catch (Exception e) - { - m_log.ErrorFormat("RemovePresence failed for {0}", uuid, e); - sp = null; - } - return sp; - } - - public SceneObjectGroup FindObject(UUID uuid) - { - try - { - SceneObjectGroup sog = (SceneObjectGroup)m_obj_by_uuid[uuid]; - return sog; - } - catch (Exception e) - { - m_log.ErrorFormat("FindObject failed for {0}", uuid, e); - return null; - } - } - - public SceneObjectGroup FindObject(uint local) - { - try - { - UUID uuid = (UUID)m_obj_by_local[local]; - SceneObjectGroup sog = (SceneObjectGroup)m_obj_by_uuid[uuid]; - return sog; - } - catch (Exception e) - { - m_log.ErrorFormat("FindObject failed for {0}", local, e); - return null; - } - } - - public ScenePresence FindPresense(UUID uuid) - { - try - { - ScenePresence sp = (ScenePresence)m_pres_by_uuid[uuid]; - return sp; - } - catch (Exception) - { - return null; - } - } - } -} diff --git a/OpenSim/Region/Environment/Scenes/EntityManager.cs b/OpenSim/Region/Environment/Scenes/EntityManager.cs index 25f73b4..e7592fe 100644 --- a/OpenSim/Region/Environment/Scenes/EntityManager.cs +++ b/OpenSim/Region/Environment/Scenes/EntityManager.cs @@ -28,14 +28,19 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Reflection; +using log4net; using OpenMetaverse; + namespace OpenSim.Region.Environment.Scenes { public class EntityManager : IEnumerable { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private readonly Dictionary m_eb_uuid = new Dictionary(); private readonly Dictionary m_eb_localID = new Dictionary(); + private readonly Dictionary m_pres_uuid = new Dictionary(); private readonly Object m_lock = new Object(); [Obsolete("Use Add() instead.")] @@ -48,8 +53,15 @@ namespace OpenSim.Region.Environment.Scenes { lock (m_lock) { - m_eb_uuid.Add(entity.UUID, entity); - m_eb_localID.Add(entity.LocalId, entity); + try + { + m_eb_uuid.Add(entity.UUID, entity); + m_eb_localID.Add(entity.LocalId, entity); + } + catch(Exception e) + { + m_log.ErrorFormat("Add Entity failed: ", e); + } } } @@ -57,8 +69,15 @@ namespace OpenSim.Region.Environment.Scenes { lock (m_lock) { - m_eb_uuid[entity.UUID] = entity; - m_eb_localID[entity.LocalId] = entity; + try + { + m_eb_uuid[entity.UUID] = entity; + m_eb_localID[entity.LocalId] = entity; + } + catch(Exception e) + { + m_log.ErrorFormat("Insert or Replace Entity failed: ", e); + } } } @@ -86,7 +105,14 @@ namespace OpenSim.Region.Environment.Scenes { lock (m_lock) { - return m_eb_uuid.ContainsKey(id); + try + { + return m_eb_uuid.ContainsKey(id); + } + catch + { + return false; + } } } @@ -94,7 +120,14 @@ namespace OpenSim.Region.Environment.Scenes { lock (m_lock) { - return m_eb_localID.ContainsKey(localID); + try + { + return m_eb_localID.ContainsKey(localID); + } + catch + { + return false; + } } } @@ -102,10 +135,17 @@ namespace OpenSim.Region.Environment.Scenes { lock (m_lock) { - bool a = m_eb_uuid.Remove(m_eb_localID[localID].UUID); - bool b = m_eb_localID.Remove(localID); - - return a && b; + try + { + bool a = m_eb_uuid.Remove(m_eb_localID[localID].UUID); + bool b = m_eb_localID.Remove(localID); + return a && b; + } + catch (Exception e) + { + m_log.ErrorFormat("Remove Entity failed for {0}", localID, e); + return false; + } } } @@ -113,10 +153,17 @@ namespace OpenSim.Region.Environment.Scenes { lock (m_lock) { - bool a = m_eb_localID.Remove(m_eb_uuid[id].LocalId); - bool b = m_eb_uuid.Remove(id); - - return a && b; + try + { + bool a = m_eb_localID.Remove(m_eb_uuid[id].LocalId); + bool b = m_eb_uuid.Remove(id); + return a && b; + } + catch (Exception e) + { + m_log.ErrorFormat("Remove Entity failed for {0}", id, e); + return false; + } } } @@ -126,13 +173,21 @@ namespace OpenSim.Region.Environment.Scenes lock (m_lock) { - foreach (KeyValuePair pair in m_eb_uuid) + try { - if (pair.Value is T) + foreach (KeyValuePair pair in m_eb_uuid) { - tmp.Add(pair.Value); + if (pair.Value is T) + { + tmp.Add(pair.Value); + } } } + catch (Exception e) + { + m_log.ErrorFormat("GetAllByType failed for {0}", e); + tmp = null; + } } return tmp; @@ -152,7 +207,14 @@ namespace OpenSim.Region.Environment.Scenes { lock (m_lock) { - return m_eb_uuid[id]; + try + { + return m_eb_uuid[id]; + } + catch + { + return null; + } } } set @@ -167,7 +229,14 @@ namespace OpenSim.Region.Environment.Scenes { lock (m_lock) { - return m_eb_localID[localID]; + try + { + return m_eb_localID[localID]; + } + catch + { + return null; + } } } set @@ -205,5 +274,6 @@ namespace OpenSim.Region.Environment.Scenes { return GetEnumerator(); } + } } diff --git a/OpenSim/Region/Environment/Scenes/Tests/EntityListTests.cs b/OpenSim/Region/Environment/Scenes/Tests/EntityListTests.cs deleted file mode 100644 index 405eddd..0000000 --- a/OpenSim/Region/Environment/Scenes/Tests/EntityListTests.cs +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSim Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using NUnit.Framework.SyntaxHelpers; -using System; -using System.Threading; -using System.Text; -using System.Collections.Generic; -using Nini.Config; -using NUnit.Framework; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Region.Environment.Scenes; -using OpenSim.Tests.Common.Mock; - -namespace OpenSim.Region.Environment.Scenes.Tests -{ - /// - /// Scene oriented tests - /// - [TestFixture] - public class EntityListTests - { - static public Random random; - SceneObjectGroup found; - Scene scene = SceneTestUtils.SetupScene(); - - [Test] - public void T010_AddObjects() - { - random = new Random(); - SceneObjectGroup found; - EntityList entlist = new EntityList(); - SceneObjectGroup sog = NewSOG(); - UUID obj1 = sog.UUID; - uint li1 = sog.LocalId; - entlist.Add(sog); - sog = NewSOG(); - UUID obj2 = sog.UUID; - uint li2 = sog.LocalId; - entlist.Add(sog); - - found = entlist.FindObject(obj1); - Assert.That(found.UUID ,Is.EqualTo(obj1) ); - found = entlist.FindObject(li1); - Assert.That(found.UUID ,Is.EqualTo(obj1) ); - found = entlist.FindObject(obj2); - Assert.That(found.UUID ,Is.EqualTo(obj2) ); - found = entlist.FindObject(li2); - Assert.That(found.UUID ,Is.EqualTo(obj2) ); - - entlist.RemoveObject(obj1); - entlist.RemoveObject(obj2); - - found = entlist.FindObject(obj1); - Assert.That(found, Is.Null); - found = entlist.FindObject(obj2); - Assert.That(found, Is.Null); - } - - [Test] - public void T011_ThreadAddRemoveTest() - { - EntityList entlist = new EntityList(); - Dictionary dict = new Dictionary(); - List trdlist = new List(); - for (int i=0; i<80; i++) - { - SceneObjectGroup sog = NewSOG(); - TestThreads test = new TestThreads(entlist,sog); - Thread start = new Thread(new ThreadStart(test.TestAddSceneObject)); - start.Start(); - trdlist.Add(start); - dict.Add(sog.UUID, sog.LocalId); - } - foreach (Thread thread in trdlist) - { - thread.Join(); - } - foreach (KeyValuePair item in dict) - { - found = entlist.FindObject(item.Key); - Assert.That(found.UUID,Is.EqualTo(item.Key)); - found = entlist.FindObject(item.Value); - Assert.That(found.UUID,Is.EqualTo(item.Key)); - - // Start Removing - TestThreads test = new TestThreads(entlist,found); - Thread start = new Thread(new ThreadStart(test.TestRemoveSceneObject)); - start.Start(); - trdlist.Add(start); - } - foreach (Thread thread in trdlist) - { - thread.Join(); - } - foreach (KeyValuePair item in dict) - { - found = entlist.FindObject(item.Key); - Assert.That(found,Is.Null); - found = entlist.FindObject(item.Value); - Assert.That(found,Is.Null); - } - } - - [Test] - public void T012_MultipleUUIDEntry() - { - EntityList entlist = new EntityList(); - UUID id = UUID.Random(); - //int exceptions = 0; - //Dictionary dict = new Dictionary(); - List trdlist = new List(); - SceneObjectGroup sog = NewSOG(id); - uint lid = sog.LocalId; - for (int i=0; i<30; i++) - { - try - { - TestThreads test = new TestThreads(entlist,sog); - Thread start = new Thread(new ThreadStart(test.TestAddSceneObject)); - start.Start(); - trdlist.Add(start); - } - catch - { - } - } - foreach (Thread thread in trdlist) - { - thread.Join(); - } - found = entlist.FindObject(sog.UUID); - Assert.That(found.UUID,Is.EqualTo(sog.UUID)); - found = entlist.FindObject(lid); - Assert.That(found.UUID,Is.EqualTo(sog.UUID)); - - entlist.RemoveObject(id); - found = entlist.FindObject(id); - Assert.That(found,Is.Null); - } - - private SceneObjectGroup NewSOG() - { - SceneObjectGroup sog = new SceneObjectGroup(); - SceneObjectPart sop = new SceneObjectPart(UUID.Random(), PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero); - sop.Name = RandomName(); - sop.Description = sop.Name; - sop.Text = RandomName(); - sop.SitName = RandomName(); - sop.TouchName = RandomName(); - sop.ObjectFlags |= (uint)PrimFlags.Phantom; - - sog.SetRootPart(sop); - - scene.AddNewSceneObject(sog, false); - - return sog; - } - - private SceneObjectGroup NewSOG(UUID id) - { - SceneObjectGroup sog = new SceneObjectGroup(); - SceneObjectPart sop = new SceneObjectPart(UUID.Random(), PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero); - sop.UUID = id; - sop.Name = RandomName(); - sop.Description = sop.Name; - sop.Text = RandomName(); - sop.SitName = RandomName(); - sop.TouchName = RandomName(); - sop.ObjectFlags |= (uint)PrimFlags.Phantom; - - sog.SetRootPart(sop); - - scene.AddNewSceneObject(sog, false); - - return sog; - } - - private static string RandomName() - { - StringBuilder name = new StringBuilder(); - int size = random.Next(40,80); - char ch ; - for (int i=0; i + /// Scene oriented tests + /// + [TestFixture] + public class EntityManagerTests + { + static public Random random; + SceneObjectGroup found; + Scene scene = SceneTestUtils.SetupScene(); + + [Test] + public void T010_AddObjects() + { + random = new Random(); + SceneObjectGroup found; + EntityManager entman = new EntityManager(); + SceneObjectGroup sog = NewSOG(); + UUID obj1 = sog.UUID; + uint li1 = sog.LocalId; + entman.Add(sog); + sog = NewSOG(); + UUID obj2 = sog.UUID; + uint li2 = sog.LocalId; + entman.Add(sog); + + found = (SceneObjectGroup)entman[obj1]; + Assert.That(found.UUID ,Is.EqualTo(obj1) ); + found = (SceneObjectGroup)entman[li1]; + Assert.That(found.UUID ,Is.EqualTo(obj1) ); + found = (SceneObjectGroup)entman[obj2]; + Assert.That(found.UUID ,Is.EqualTo(obj2) ); + found = (SceneObjectGroup)entman[li2]; + Assert.That(found.UUID ,Is.EqualTo(obj2) ); + + entman.Remove(obj1); + entman.Remove(li2); + + Assert.That(entman.ContainsKey(obj1), Is.False); + Assert.That(entman.ContainsKey(li1), Is.False); + Assert.That(entman.ContainsKey(obj2), Is.False); + Assert.That(entman.ContainsKey(li2), Is.False); + } + + [Test] + public void T011_ThreadAddRemoveTest() + { + // This test adds and removes with mutiple threads, attempting to break the + // uuid and localid dictionary coherence. + EntityManager entman = new EntityManager(); + SceneObjectGroup sog = NewSOG(); + for (int j=0; j<20; j++) + { + List trdlist = new List(); + + for (int i=0; i<4; i++) + { + // Adds scene object + NewTestThreads test = new NewTestThreads(entman,sog); + Thread start = new Thread(new ThreadStart(test.TestAddSceneObject)); + start.Start(); + trdlist.Add(start); + + // Removes it + test = new NewTestThreads(entman,sog); + start = new Thread(new ThreadStart(test.TestRemoveSceneObject)); + start.Start(); + trdlist.Add(start); + } + foreach (Thread thread in trdlist) + { + thread.Join(); + } + if (entman.ContainsKey(sog.UUID) || entman.ContainsKey(sog.LocalId)) { + found = (SceneObjectGroup)entman[sog.UUID]; + Assert.That(found.UUID,Is.EqualTo(sog.UUID)); + found = (SceneObjectGroup)entman[sog.LocalId]; + Assert.That(found.UUID,Is.EqualTo(sog.UUID)); + } + } + } + + private SceneObjectGroup NewSOG() + { + SceneObjectGroup sog = new SceneObjectGroup(); + SceneObjectPart sop = new SceneObjectPart(UUID.Random(), PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero); + sop.Name = RandomName(); + sop.Description = sop.Name; + sop.Text = RandomName(); + sop.SitName = RandomName(); + sop.TouchName = RandomName(); + sop.ObjectFlags |= (uint)PrimFlags.Phantom; + + sog.SetRootPart(sop); + + scene.AddNewSceneObject(sog, false); + + return sog; + } + + private static string RandomName() + { + StringBuilder name = new StringBuilder(); + int size = random.Next(40,80); + char ch ; + for (int i=0; i