* 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
0.6.3-post-fixes
Justin Clarke Casey 2009-01-30 20:54:38 +00:00
parent f351ab62ec
commit c307e0e4a7
7 changed files with 70 additions and 22 deletions

View File

@ -26,6 +26,7 @@
*/ */
using System.IO; using System.IO;
using System.Threading;
namespace OpenSim.Region.Environment.Interfaces namespace OpenSim.Region.Environment.Interfaces
{ {
@ -44,12 +45,11 @@ namespace OpenSim.Region.Environment.Interfaces
/// Archive the region to a stream. /// Archive the region to a stream.
/// </summary> /// </summary>
/// ///
/// 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.
///
/// <param name="saveStream"></param> /// <param name="saveStream"></param>
void ArchiveRegion(Stream saveStream); /// <param name="waitHandle">
/// Pass in a wait handle if you want to be signalled when the operation completes.
/// </param>
void ArchiveRegion(Stream saveStream, EventWaitHandle waitHandle);
/// <summary> /// <summary>
/// Dearchive the given region archive into the scene /// Dearchive the given region archive into the scene

View File

@ -29,6 +29,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Threading;
using System.Xml; using System.Xml;
using OpenMetaverse; using OpenMetaverse;
using log4net; using log4net;
@ -57,19 +58,22 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
protected List<SceneObjectGroup> m_sceneObjects; protected List<SceneObjectGroup> m_sceneObjects;
protected RegionInfo m_regionInfo; protected RegionInfo m_regionInfo;
protected Stream m_saveStream; protected Stream m_saveStream;
protected EventWaitHandle m_signalWhenDoneEvent;
public ArchiveWriteRequestExecution( public ArchiveWriteRequestExecution(
List<SceneObjectGroup> sceneObjects, List<SceneObjectGroup> sceneObjects,
ITerrainModule terrainModule, ITerrainModule terrainModule,
IRegionSerialiserModule serialiser, IRegionSerialiserModule serialiser,
RegionInfo regionInfo, RegionInfo regionInfo,
Stream saveStream) Stream saveStream,
EventWaitHandle signalWhenDoneEvent)
{ {
m_sceneObjects = sceneObjects; m_sceneObjects = sceneObjects;
m_terrainModule = terrainModule; m_terrainModule = terrainModule;
m_serialiser = serialiser; m_serialiser = serialiser;
m_regionInfo = regionInfo; m_regionInfo = regionInfo;
m_saveStream = saveStream; m_saveStream = saveStream;
m_signalWhenDoneEvent = signalWhenDoneEvent;
} }
protected internal void ReceivedAllAssets(IDictionary<UUID, AssetBase> assetsFound, ICollection<UUID> assetsNotFoundUuids) protected internal void ReceivedAllAssets(IDictionary<UUID, AssetBase> assetsFound, ICollection<UUID> assetsNotFoundUuids)
@ -126,6 +130,9 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
archive.WriteTar(m_saveStream); archive.WriteTar(m_saveStream);
m_log.InfoFormat("[ARCHIVER]: Wrote out OpenSimulator archive for {0}", m_regionInfo.RegionName); m_log.InfoFormat("[ARCHIVER]: Wrote out OpenSimulator archive for {0}", m_regionInfo.RegionName);
if (m_signalWhenDoneEvent != null)
m_signalWhenDoneEvent.Set();
} }
/// <summary> /// <summary>

View File

@ -53,6 +53,7 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
protected Scene m_scene; protected Scene m_scene;
protected Stream m_saveStream; protected Stream m_saveStream;
protected EventWaitHandle m_signalWhenDoneEvent;
/// <summary> /// <summary>
/// Used as a temporary store of an asset which represents an object. This can be a null if no appropriate /// 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
/// </summary> /// </summary>
/// <param name="scene"></param> /// <param name="scene"></param>
/// <param name="saveStream">The stream to which to save data.</param> /// <param name="saveStream">The stream to which to save data.</param>
public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream) public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream, EventWaitHandle signalWhenDoneEvent)
{ {
m_scene = scene; m_scene = scene;
m_saveStream = saveStream; m_saveStream = saveStream;
m_signalWhenDoneEvent = signalWhenDoneEvent;
} }
/// <summary> /// <summary>
@ -325,7 +327,8 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
m_scene.RequestModuleInterface<ITerrainModule>(), m_scene.RequestModuleInterface<ITerrainModule>(),
m_scene.RequestModuleInterface<IRegionSerialiserModule>(), m_scene.RequestModuleInterface<IRegionSerialiserModule>(),
m_scene.RegionInfo, m_scene.RegionInfo,
m_saveStream); m_saveStream,
m_signalWhenDoneEvent);
new AssetsRequest(assetUuids.Keys, m_scene.AssetCache, awre.ReceivedAllAssets).Execute(); new AssetsRequest(assetUuids.Keys, m_scene.AssetCache, awre.ReceivedAllAssets).Execute();
} }

View File

@ -28,6 +28,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Threading;
using OpenMetaverse; using OpenMetaverse;
using log4net; using log4net;
using Nini.Config; using Nini.Config;
@ -72,9 +73,9 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
new ArchiveWriteRequestPreparation(m_scene, savePath).ArchiveRegion(); 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) public void DearchiveRegion(string loadPath)

View File

@ -27,9 +27,9 @@
using System; using System;
using System.IO; using System.IO;
//using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
//using log4net; using log4net;
namespace OpenSim.Region.Environment.Modules.World.Archiver namespace OpenSim.Region.Environment.Modules.World.Archiver
{ {
@ -39,6 +39,7 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
public class TarArchiveReader public class TarArchiveReader
{ {
//private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public enum TarEntryType public enum TarEntryType
{ {
TYPE_UNKNOWN = 0, TYPE_UNKNOWN = 0,

View File

@ -29,8 +29,8 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
//using System.Reflection; using System.Reflection;
//using log4net; using log4net;
namespace OpenSim.Region.Environment.Modules.World.Archiver 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 // Write two consecutive 0 blocks to end the archive
byte[] finalZeroPadding = new byte[1024]; byte[] finalZeroPadding = new byte[1024];
bw.Write(finalZeroPadding); bw.Write(finalZeroPadding);

View File

@ -25,11 +25,16 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
using System;
using System.IO; using System.IO;
using System.Threading;
using NUnit.Framework; using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers; using NUnit.Framework.SyntaxHelpers;
using OpenMetaverse;
using OpenSim.Framework;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Modules.World.Archiver; 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.Modules.World.Terrain;
using OpenSim.Region.Environment.Scenes; using OpenSim.Region.Environment.Scenes;
using OpenSim.Tests.Common.Setup; using OpenSim.Tests.Common.Setup;
@ -48,21 +53,41 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver.Tests
//log4net.Config.XmlConfigurator.Configure(); //log4net.Config.XmlConfigurator.Configure();
ArchiverModule archiverModule = new ArchiverModule(); ArchiverModule archiverModule = new ArchiverModule();
SerialiserModule serialiserModule = new SerialiserModule();
TerrainModule terrainModule = new TerrainModule(); TerrainModule terrainModule = new TerrainModule();
Scene scene = SceneSetupHelpers.SetupScene(); 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(); 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, byte[] archive = archiveWriteStream.ToArray();
// so no need to worry about signalling. MemoryStream archiveReadStream = new MemoryStream(archive);
MemoryStream archiveReadStream = new MemoryStream(archiveWriteStream.ToArray());
TarArchiveReader tar = new TarArchiveReader(archiveReadStream); 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; string filePath;
TarArchiveReader.TarEntryType tarEntryType; TarArchiveReader.TarEntryType tarEntryType;
@ -70,10 +95,19 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver.Tests
while (tar.ReadEntry(out filePath, out tarEntryType) != null) while (tar.ReadEntry(out filePath, out tarEntryType) != null)
{ {
if (ArchiveConstants.CONTROL_FILE_PATH == filePath) if (ArchiveConstants.CONTROL_FILE_PATH == filePath)
{
gotControlFile = true; 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(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. // TODO: Test presence of more files and contents of files.
} }