From c307e0e4a7ddf0b07f2b0662fe55adc31b64b393 Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Fri, 30 Jan 2009 20:54:38 +0000 Subject: [PATCH] * Extend archive save test to check for the presence of the file for the object that was in the scene * Can now pass in a wait handle to ArchiveRegion() if you want same thread signalling that the save has completed --- .../Interfaces/IRegionArchiverModule.cs | 10 ++-- .../Archiver/ArchiveWriteRequestExecution.cs | 9 +++- .../ArchiveWriteRequestPreparation.cs | 9 ++-- .../Modules/World/Archiver/ArchiverModule.cs | 5 +- .../World/Archiver/TarArchiveReader.cs | 5 +- .../World/Archiver/TarArchiveWriter.cs | 6 ++- .../World/Archiver/Tests/ArchiverTests.cs | 48 ++++++++++++++++--- 7 files changed, 70 insertions(+), 22 deletions(-) diff --git a/OpenSim/Region/Environment/Interfaces/IRegionArchiverModule.cs b/OpenSim/Region/Environment/Interfaces/IRegionArchiverModule.cs index 7db784eb41..d9f8c086cf 100644 --- a/OpenSim/Region/Environment/Interfaces/IRegionArchiverModule.cs +++ b/OpenSim/Region/Environment/Interfaces/IRegionArchiverModule.cs @@ -26,6 +26,7 @@ */ using System.IO; +using System.Threading; namespace OpenSim.Region.Environment.Interfaces { @@ -44,12 +45,11 @@ namespace OpenSim.Region.Environment.Interfaces /// Archive the region to a stream. /// /// - /// This may be a little problematic to use right now since saves happen asynchronously and there is not yet - /// a mechanism to signal completion to the caller (possibly other than continually checking whether the - /// stream has any data in it). TODO: Address this. - /// /// - void ArchiveRegion(Stream saveStream); + /// + /// Pass in a wait handle if you want to be signalled when the operation completes. + /// + void ArchiveRegion(Stream saveStream, EventWaitHandle waitHandle); /// /// Dearchive the given region archive into the scene diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestExecution.cs b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestExecution.cs index bade121ee9..8eec38dce1 100644 --- a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestExecution.cs +++ b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestExecution.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Reflection; +using System.Threading; using System.Xml; using OpenMetaverse; using log4net; @@ -57,19 +58,22 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver protected List m_sceneObjects; protected RegionInfo m_regionInfo; protected Stream m_saveStream; + protected EventWaitHandle m_signalWhenDoneEvent; public ArchiveWriteRequestExecution( List sceneObjects, ITerrainModule terrainModule, IRegionSerialiserModule serialiser, RegionInfo regionInfo, - Stream saveStream) + Stream saveStream, + EventWaitHandle signalWhenDoneEvent) { m_sceneObjects = sceneObjects; m_terrainModule = terrainModule; m_serialiser = serialiser; m_regionInfo = regionInfo; m_saveStream = saveStream; + m_signalWhenDoneEvent = signalWhenDoneEvent; } protected internal void ReceivedAllAssets(IDictionary assetsFound, ICollection assetsNotFoundUuids) @@ -126,6 +130,9 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver archive.WriteTar(m_saveStream); m_log.InfoFormat("[ARCHIVER]: Wrote out OpenSimulator archive for {0}", m_regionInfo.RegionName); + + if (m_signalWhenDoneEvent != null) + m_signalWhenDoneEvent.Set(); } /// diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs index e9005aea6c..b3c9a91df7 100644 --- a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -53,6 +53,7 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver protected Scene m_scene; protected Stream m_saveStream; + protected EventWaitHandle m_signalWhenDoneEvent; /// /// Used as a temporary store of an asset which represents an object. This can be a null if no appropriate @@ -79,10 +80,11 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver /// /// /// The stream to which to save data. - public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream) + public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream, EventWaitHandle signalWhenDoneEvent) { m_scene = scene; - m_saveStream = saveStream; + m_saveStream = saveStream; + m_signalWhenDoneEvent = signalWhenDoneEvent; } /// @@ -325,7 +327,8 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver m_scene.RequestModuleInterface(), m_scene.RequestModuleInterface(), m_scene.RegionInfo, - m_saveStream); + m_saveStream, + m_signalWhenDoneEvent); new AssetsRequest(assetUuids.Keys, m_scene.AssetCache, awre.ReceivedAllAssets).Execute(); } diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiverModule.cs index f07185c433..e3dfda2241 100644 --- a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiverModule.cs @@ -28,6 +28,7 @@ using System.Collections.Generic; using System.IO; using System.Reflection; +using System.Threading; using OpenMetaverse; using log4net; using Nini.Config; @@ -72,9 +73,9 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver new ArchiveWriteRequestPreparation(m_scene, savePath).ArchiveRegion(); } - public void ArchiveRegion(Stream saveStream) + public void ArchiveRegion(Stream saveStream, EventWaitHandle waitHandle) { - new ArchiveWriteRequestPreparation(m_scene, saveStream).ArchiveRegion(); + new ArchiveWriteRequestPreparation(m_scene, saveStream, waitHandle).ArchiveRegion(); } public void DearchiveRegion(string loadPath) diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/TarArchiveReader.cs b/OpenSim/Region/Environment/Modules/World/Archiver/TarArchiveReader.cs index 642e03c70c..c8ae224890 100644 --- a/OpenSim/Region/Environment/Modules/World/Archiver/TarArchiveReader.cs +++ b/OpenSim/Region/Environment/Modules/World/Archiver/TarArchiveReader.cs @@ -27,9 +27,9 @@ using System; using System.IO; -//using System.Reflection; +using System.Reflection; using System.Text; -//using log4net; +using log4net; namespace OpenSim.Region.Environment.Modules.World.Archiver { @@ -39,6 +39,7 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver public class TarArchiveReader { //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + public enum TarEntryType { TYPE_UNKNOWN = 0, diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/TarArchiveWriter.cs b/OpenSim/Region/Environment/Modules/World/Archiver/TarArchiveWriter.cs index 55edec084a..8fd247c7cb 100644 --- a/OpenSim/Region/Environment/Modules/World/Archiver/TarArchiveWriter.cs +++ b/OpenSim/Region/Environment/Modules/World/Archiver/TarArchiveWriter.cs @@ -29,8 +29,8 @@ using System; using System.Collections.Generic; using System.IO; using System.Text; -//using System.Reflection; -//using log4net; +using System.Reflection; +using log4net; namespace OpenSim.Region.Environment.Modules.World.Archiver { @@ -169,6 +169,8 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver } } + //m_log.Debug("[TAR ARCHIVE WRITER]: Writing final consecutive 0 blocks"); + // Write two consecutive 0 blocks to end the archive byte[] finalZeroPadding = new byte[1024]; bw.Write(finalZeroPadding); diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/Environment/Modules/World/Archiver/Tests/ArchiverTests.cs index 6450238f2a..ccd24116f5 100644 --- a/OpenSim/Region/Environment/Modules/World/Archiver/Tests/ArchiverTests.cs +++ b/OpenSim/Region/Environment/Modules/World/Archiver/Tests/ArchiverTests.cs @@ -25,11 +25,16 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using System.IO; +using System.Threading; using NUnit.Framework; using NUnit.Framework.SyntaxHelpers; +using OpenMetaverse; +using OpenSim.Framework; using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Modules.World.Archiver; +using OpenSim.Region.Environment.Modules.World.Serialiser; using OpenSim.Region.Environment.Modules.World.Terrain; using OpenSim.Region.Environment.Scenes; using OpenSim.Tests.Common.Setup; @@ -48,21 +53,41 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver.Tests //log4net.Config.XmlConfigurator.Configure(); ArchiverModule archiverModule = new ArchiverModule(); + SerialiserModule serialiserModule = new SerialiserModule(); TerrainModule terrainModule = new TerrainModule(); Scene scene = SceneSetupHelpers.SetupScene(); - SceneSetupHelpers.SetupSceneModules(scene, archiverModule, terrainModule); + SceneSetupHelpers.SetupSceneModules(scene, archiverModule, serialiserModule, terrainModule); - + string partName = "My Little Pony"; + UUID ownerId = UUID.Parse("00000000-0000-0000-0000-000000000015"); + PrimitiveBaseShape shape = PrimitiveBaseShape.CreateSphere(); + Vector3 groupPosition = new Vector3(10, 20, 30); + Quaternion rotationOffset = new Quaternion(20, 30, 40, 50); + Vector3 offsetPosition = new Vector3(5, 10, 15); + + SceneObjectPart part + = new SceneObjectPart( + ownerId, shape, groupPosition, rotationOffset, offsetPosition); + part.Name = partName; + + scene.AddNewSceneObject(new SceneObjectGroup(part), false); + EventWaitHandle waitHandle = new ManualResetEvent(false); MemoryStream archiveWriteStream = new MemoryStream(); - archiverModule.ArchiveRegion(archiveWriteStream); + archiverModule.ArchiveRegion(archiveWriteStream, waitHandle); + waitHandle.WaitOne(); - // If there are no assets to fetch, then the entire archive region code path will execute in this thread, - // so no need to worry about signalling. - MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray()); + byte[] archive = archiveWriteStream.ToArray(); + MemoryStream archiveReadStream = new MemoryStream(archive); TarArchiveReader tar = new TarArchiveReader(archiveReadStream); - bool gotControlFile = false; + bool gotControlFile = false; + bool gotObjectFile = false; + string expectedObjectFileName = string.Format( + "{0}_{1:000}-{2:000}-{3:000}__{4}.xml", + partName, + Math.Round(groupPosition.X), Math.Round(groupPosition.Y), Math.Round(groupPosition.Z), + part.UUID); string filePath; TarArchiveReader.TarEntryType tarEntryType; @@ -70,10 +95,19 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver.Tests while (tar.ReadEntry(out filePath, out tarEntryType) != null) { if (ArchiveConstants.CONTROL_FILE_PATH == filePath) + { gotControlFile = true; + } + else if (filePath.StartsWith(ArchiveConstants.OBJECTS_PATH)) + { + string fileName = filePath.Remove(0, ArchiveConstants.OBJECTS_PATH.Length); + Assert.That(fileName, Is.EqualTo(expectedObjectFileName)); + gotObjectFile = true; + } } Assert.That(gotControlFile, Is.True, "No control file in archive"); + Assert.That(gotObjectFile, Is.True, "No object file in archive"); // TODO: Test presence of more files and contents of files. }