diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 7bcc4dbf44..c434e4fa1e 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -684,7 +684,7 @@ namespace OpenSim.Region.Framework.Scenes
}
}
- public void TriggerOnBackup(IRegionDataStore dstore)
+ public void TriggerOnBackup(IRegionDataStore dstore, bool forced)
{
OnBackupDelegate handlerOnAttach = OnBackup;
if (handlerOnAttach != null)
@@ -693,7 +693,7 @@ namespace OpenSim.Region.Framework.Scenes
{
try
{
- d(dstore, false);
+ d(dstore, forced);
}
catch (Exception e)
{
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 49f29ad26b..93882bad98 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1531,15 +1531,24 @@ namespace OpenSim.Region.Framework.Scenes
Backup();
}
+ public void Backup()
+ {
+ Backup(false);
+ }
+
///
/// Backup the scene. This acts as the main method of the backup thread.
///
+ ///
+ /// If true, then any changes that have not yet been persisted are persisted. If false,
+ /// then the persistence decision is left to the backup code (in some situations, such as object persistence,
+ /// it's much more efficient to backup multiple changes at once rather than every single one).
///
- public void Backup()
+ public void Backup(bool forced)
{
lock (m_returns)
{
- EventManager.TriggerOnBackup(m_storageManager.DataStore);
+ EventManager.TriggerOnBackup(m_storageManager.DataStore, forced);
m_backingup = false;
foreach (KeyValuePair ret in m_returns)
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 64a6dd57fe..b8b3db5486 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1383,12 +1383,11 @@ namespace OpenSim.Region.Framework.Scenes
if (!m_isBackedUp)
return;
- // Since this is the top of the section of call stack for backing up a particular scene object, don't let
- // any exception propogate upwards.
-
if (IsDeleted || UUID == UUID.Zero)
return;
+ // Since this is the top of the section of call stack for backing up a particular scene object, don't let
+ // any exception propogate upwards.
try
{
if (!m_scene.ShuttingDown) // if shutting down then there will be nothing to handle the return so leave till next restart
diff --git a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
index e140cd5785..3a0dd00ad5 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/BorderTests.cs
@@ -28,20 +28,21 @@
using System;
using System.Collections.Generic;
using System.Text;
+using NUnit.Framework;
using OpenMetaverse;
using OpenSim.Region.Framework.Scenes;
-
-using NUnit.Framework;
+using OpenSim.Tests.Common;
namespace OpenSim.Region.Framework.Scenes.Tests
{
[TestFixture]
public class BorderTests
{
-
[Test]
public void TestCross()
{
+ TestHelper.InMethod();
+
List testborders = new List();
Border NorthBorder = new Border();
@@ -75,8 +76,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests
position = new Vector3(200,280,21);
Assert.That(NorthBorder.TestCross(position));
-
-
// Test automatic border crossing
// by setting the border crossing aabb to be the whole region
position = new Vector3(25,25,21); // safely within one 256m region
@@ -95,12 +94,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests
WestBorder.BorderLine = new Vector3(0, 256, 255); // automatic border cross in the region
Assert.That(WestBorder.TestCross(position));
-
}
[Test]
public void TestCrossSquare512()
{
+ TestHelper.InMethod();
+
List testborders = new List();
Border NorthBorder = new Border();
@@ -174,12 +174,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Assert.That(!b.TestCross(position));
}
-
}
[Test]
public void TestCrossRectangle512x256()
{
+ TestHelper.InMethod();
+
List testborders = new List();
Border NorthBorder = new Border();
@@ -258,6 +259,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
[Test]
public void TestCrossOdd512x512w256hole()
{
+ TestHelper.InMethod();
+
List testborders = new List();
// 512____
// | |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
index 3e2a2af94b..b3c3e22af6 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/EntityManagerTests.cs
@@ -53,7 +53,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests
public void T010_AddObjects()
{
TestHelper.InMethod();
- // Console.WriteLine("Beginning test {0}", MethodBase.GetCurrentMethod());
random = new Random();
SceneObjectGroup found;
@@ -89,7 +88,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests
public void T011_ThreadAddRemoveTest()
{
TestHelper.InMethod();
- // Console.WriteLine("Beginning test {0}", MethodBase.GetCurrentMethod());
// This test adds and removes with mutiple threads, attempting to break the
// uuid and localid dictionary coherence.
diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
index 0b7608d0b8..bfed2047bf 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectLinkingTests.cs
@@ -26,13 +26,13 @@
*/
using System;
+using System.Collections.Generic;
using System.Reflection;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Framework.Communications;
-
using OpenSim.Region.Framework.Scenes;
using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock;
@@ -260,5 +260,54 @@ namespace OpenSim.Region.Framework.Scenes.Tests
&& (part4.RotationOffset.W - compareQuaternion.W < 0.00003),
"Badness 3");
}
+
+ ///
+ /// Test that a new scene object which is already linked is correctly persisted to the persistence layer.
+ ///
+ [Test]
+ public void TestNewSceneObjectLinkPersistence()
+ {
+ TestHelper.InMethod();
+ log4net.Config.XmlConfigurator.Configure();
+
+ TestScene scene = SceneSetupHelpers.SetupScene();
+
+ string rootPartName = "rootpart";
+ UUID rootPartUuid = new UUID("00000000-0000-0000-0000-000000000001");
+ string linkPartName = "linkpart";
+ UUID linkPartUuid = new UUID("00000000-0000-0000-0001-000000000000");
+
+ SceneObjectPart rootPart
+ = new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero)
+ { Name = rootPartName, UUID = rootPartUuid };
+ SceneObjectPart linkPart
+ = new SceneObjectPart(UUID.Zero, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero)
+ { Name = linkPartName, UUID = linkPartUuid };
+
+ SceneObjectGroup sog = new SceneObjectGroup(rootPart);
+ sog.AddPart(linkPart);
+ scene.AddNewSceneObject(sog, true);
+
+ // In a test, we have to crank the backup handle manually. Normally this would be done by the timer invoked
+ // scene backup thread.
+ scene.Backup(true);
+
+ List storedObjects = scene.StorageManager.DataStore.LoadObjects(scene.RegionInfo.RegionID);
+ Assert.That(storedObjects.Count, Is.EqualTo(1));
+ Assert.That(storedObjects[0].Children.Count, Is.EqualTo(2));
+ Assert.That(storedObjects[0].RootPart.UUID, Is.EqualTo(rootPartUuid));
+ // TODO: assertion for child prim
+ }
+
+ ///
+ /// Test that a delink is correctly persisted to the database
+ ///
+// [Test]
+// public void TestDelinkPersistence()
+// {
+// TestHelper.InMethod();
+//
+// Scene scene = SceneSetupHelpers.SetupScene();
+// }
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs
index e39a362883..ab5968c37c 100644
--- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs
+++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTests.cs
@@ -173,6 +173,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests
Assert.That(neighbours.Count, Is.EqualTo(2));
}
+
public void fixNullPresence()
{
string firstName = "testfirstname";
@@ -389,8 +390,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests
public static string GetRandomCapsObjectPath()
{
- TestHelper.InMethod();
-
UUID caps = UUID.Random();
string capsPath = caps.ToString();
capsPath = capsPath.Remove(capsPath.Length - 4, 4);
@@ -429,4 +428,4 @@ namespace OpenSim.Region.Framework.Scenes.Tests
return name.ToString();
}
}
-}
+}
\ No newline at end of file
diff --git a/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs
new file mode 100644
index 0000000000..1c139c5250
--- /dev/null
+++ b/OpenSim/Tests/Common/Mock/MockRegionDataPlugin.cs
@@ -0,0 +1,149 @@
+/*
+ * 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 OpenSimulator 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.Reflection;
+using System.Collections.Generic;
+using log4net;
+using OpenMetaverse;
+using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
+using OpenSim.Region.Framework.Scenes;
+
+namespace OpenSim.Data.Null
+{
+ ///
+ /// Mock region data plugin. This obeys the api contract for persistence but stores everything in memory, so that
+ /// tests can check correct persistence.
+ ///
+ public class NullDataStore : IRegionDataStore
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ protected Dictionary m_regionSettings = new Dictionary();
+ protected Dictionary m_sceneObjects = new Dictionary();
+ protected Dictionary> m_primItems
+ = new Dictionary>();
+ protected Dictionary m_terrains = new Dictionary();
+ protected Dictionary m_landData = new Dictionary();
+
+ public void Initialise(string dbfile)
+ {
+ return;
+ }
+
+ public void Dispose()
+ {
+ }
+
+ public void StoreRegionSettings(RegionSettings rs)
+ {
+ m_regionSettings[rs.RegionUUID] = rs;
+ }
+
+ public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID)
+ {
+ //This connector doesn't support the windlight module yet
+ //Return default LL windlight settings
+ return new RegionLightShareData();
+ }
+
+ public void StoreRegionWindlightSettings(RegionLightShareData wl)
+ {
+ //This connector doesn't support the windlight module yet
+ }
+
+ public RegionSettings LoadRegionSettings(UUID regionUUID)
+ {
+ RegionSettings rs = null;
+ m_regionSettings.TryGetValue(regionUUID, out rs);
+ return rs;
+ }
+
+ public void StoreObject(SceneObjectGroup obj, UUID regionUUID)
+ {
+ m_log.DebugFormat(
+ "[MOCK REGION DATA PLUGIN]: Storing object {0} {1} in {2}", obj.Name, obj.UUID, regionUUID);
+ m_sceneObjects[obj.UUID] = obj;
+ }
+
+ public void RemoveObject(UUID obj, UUID regionUUID)
+ {
+ m_log.DebugFormat(
+ "[MOCK REGION DATA PLUGIN]: Removing object {0} from {1}", obj, regionUUID);
+
+ if (m_sceneObjects.ContainsKey(obj))
+ m_sceneObjects.Remove(obj);
+ }
+
+ // see IRegionDatastore
+ public void StorePrimInventory(UUID primID, ICollection items)
+ {
+ m_primItems[primID] = items;
+ }
+
+ public List LoadObjects(UUID regionUUID)
+ {
+ m_log.DebugFormat(
+ "[MOCK REGION DATA PLUGIN]: Loading objects from {0}", regionUUID);
+
+ return new List(m_sceneObjects.Values);
+ }
+
+ public void StoreTerrain(double[,] ter, UUID regionID)
+ {
+ m_terrains[regionID] = ter;
+ }
+
+ public double[,] LoadTerrain(UUID regionID)
+ {
+ if (m_terrains.ContainsKey(regionID))
+ return m_terrains[regionID];
+ else
+ return null;
+ }
+
+ public void RemoveLandObject(UUID globalID)
+ {
+ if (m_landData.ContainsKey(globalID))
+ m_landData.Remove(globalID);
+ }
+
+ public void StoreLandObject(ILandObject land)
+ {
+ m_landData[land.LandData.GlobalID] = land.LandData;
+ }
+
+ public List LoadLandObjects(UUID regionUUID)
+ {
+ return new List(m_landData.Values);
+ }
+
+ public void Shutdown()
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/OpenSim/Tests/Common/Mock/TestScene.cs b/OpenSim/Tests/Common/Mock/TestScene.cs
index 01f2c146e8..615e519b2d 100644
--- a/OpenSim/Tests/Common/Mock/TestScene.cs
+++ b/OpenSim/Tests/Common/Mock/TestScene.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
@@ -29,7 +29,6 @@ using System;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.Communications;
-
using OpenSim.Framework.Servers;
using OpenSim.Region.Framework;
using OpenSim.Region.Framework.Scenes;
@@ -48,6 +47,11 @@ namespace OpenSim.Tests.Common.Mock
{
}
+ ///
+ /// Allow retrieval for test check purposes
+ ///
+ public StorageManager StorageManager { get { return m_storageManager; } }
+
///
/// Temporarily override session authentication for tests (namely teleport).
///
diff --git a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs
index d9ded2d0c4..9318a27d05 100644
--- a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs
+++ b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs
@@ -157,7 +157,7 @@ namespace OpenSim.Tests.Common.Setup
AgentCircuitManager acm = new AgentCircuitManager();
SceneCommunicationService scs = new SceneCommunicationService();
- StorageManager sm = new StorageManager("OpenSim.Data.Null.dll", "", "");
+ StorageManager sm = new StorageManager("OpenSim.Tests.Common.dll", "", "");
IConfigSource configSource = new IniConfigSource();
TestScene testScene = new TestScene(