diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs index 7849d88320..9b98de3b67 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiveReadRequest.cs @@ -41,6 +41,7 @@ using OpenSim.Framework.Serialization; using OpenSim.Framework.Serialization.External; using OpenSim.Region.CoreModules.World.Archiver; using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Serialization; using OpenSim.Region.Framework.Interfaces; using OpenSim.Services.Interfaces; @@ -75,6 +76,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// The stream from which the inventory archive will be loaded. /// private Stream m_loadStream; + + protected bool m_controlFileLoaded; + protected bool m_assetsLoaded; + protected bool m_inventoryNodesLoaded; + + protected int m_successfulAssetRestores; + protected int m_failedAssetRestores; + protected int m_successfulItemRestores; + + /// + /// Root destination folder for the IAR load. + /// + protected InventoryFolderBase m_rootDestinationFolder; + + /// + /// Inventory nodes loaded from the iar. + /// + protected HashSet m_loadedNodes = new HashSet(); + + /// + /// In order to load identically named folders, we need to keep track of the folders that we have already + /// resolved. + /// + Dictionary m_resolvedFolders = new Dictionary(); + + /// + /// Record the creator id that should be associated with an asset. This is used to adjust asset creator ids + /// after OSP resolution (since OSP creators are only stored in the item + /// + protected Dictionary m_creatorIdForAssetId = new Dictionary(); public InventoryArchiveReadRequest( Scene scene, UserAccount userInfo, string invPath, string loadPath, bool merge) @@ -100,20 +131,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver /// /// Execute the request /// + /// + /// Only call this once. To load another IAR, construct another request object. + /// /// /// A list of the inventory nodes loaded. If folders were loaded then only the root folders are /// returned /// + /// Thrown if load fails. public HashSet Execute() { try { string filePath = "ERROR"; - int successfulAssetRestores = 0; - int failedAssetRestores = 0; - int successfulItemRestores = 0; - - HashSet loadedNodes = new HashSet(); List folderCandidates = InventoryArchiveUtils.FindFolderByPath( @@ -124,16 +154,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // Possibly provide an option later on to automatically create this folder if it does not exist m_log.ErrorFormat("[INVENTORY ARCHIVER]: Inventory path {0} does not exist", m_invPath); - return loadedNodes; + return m_loadedNodes; } - InventoryFolderBase rootDestinationFolder = folderCandidates[0]; + m_rootDestinationFolder = folderCandidates[0]; archive = new TarArchiveReader(m_loadStream); - - // In order to load identically named folders, we need to keep track of the folders that we have already - // resolved - Dictionary resolvedFolders = new Dictionary(); - byte[] data; TarArchiveReader.TarEntryType entryType; @@ -142,45 +167,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver if (filePath == ArchiveConstants.CONTROL_FILE_PATH) { LoadControlFile(filePath, data); - } + } else if (filePath.StartsWith(ArchiveConstants.ASSETS_PATH)) { - if (LoadAsset(filePath, data)) - successfulAssetRestores++; - else - failedAssetRestores++; - - if ((successfulAssetRestores) % 50 == 0) - m_log.DebugFormat( - "[INVENTORY ARCHIVER]: Loaded {0} assets...", - successfulAssetRestores); + LoadAssetFile(filePath, data); } else if (filePath.StartsWith(ArchiveConstants.INVENTORY_PATH)) { - filePath = filePath.Substring(ArchiveConstants.INVENTORY_PATH.Length); - - // Trim off the file portion if we aren't already dealing with a directory path - if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType) - filePath = filePath.Remove(filePath.LastIndexOf("/") + 1); - - InventoryFolderBase foundFolder - = ReplicateArchivePathToUserInventory( - filePath, rootDestinationFolder, resolvedFolders, loadedNodes); - - if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType) - { - InventoryItemBase item = LoadItem(data, foundFolder); - - if (item != null) - { - successfulItemRestores++; - - // If we aren't loading the folder containing the item then well need to update the - // viewer separately for that item. - if (!loadedNodes.Contains(foundFolder)) - loadedNodes.Add(item); - } - } + LoadInventoryFile(filePath, entryType, data); } } @@ -188,10 +182,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver m_log.DebugFormat( "[INVENTORY ARCHIVER]: Successfully loaded {0} assets with {1} failures", - successfulAssetRestores, failedAssetRestores); - m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", successfulItemRestores); + m_successfulAssetRestores, m_failedAssetRestores); + m_log.InfoFormat("[INVENTORY ARCHIVER]: Successfully loaded {0} items", m_successfulItemRestores); - return loadedNodes; + return m_loadedNodes; } finally { @@ -404,7 +398,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver item.CreatorIdAsUuid = ospResolvedId; - // XXX: For now, don't preserve the OSPA in the creator id (which actually gets persisted to the + // Don't preserve the OSPA in the creator id (which actually gets persisted to the // database). Instead, replace with the UUID that we found. item.CreatorId = ospResolvedId.ToString(); @@ -412,7 +406,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver } else if (item.CreatorData == null || item.CreatorData == String.Empty) { - item.CreatorIdAsUuid = m_userInfo.PrincipalID; + item.CreatorId = m_userInfo.PrincipalID.ToString(); + item.CreatorIdAsUuid = new UUID(item.CreatorId); } item.Owner = m_userInfo.PrincipalID; @@ -420,6 +415,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver // Reset folder ID to the one in which we want to load it item.Folder = loadFolder.ID; + // Record the creator id for the item's asset so that we can use it later, if necessary, when the asset + // is loaded. + // FIXME: This relies on the items coming before the assets in the TAR file. Need to create stronger + // checks for this, and maybe even an external tool for creating OARs which enforces this, rather than + // relying on native tar tools. + m_creatorIdForAssetId[item.AssetID] = item.CreatorIdAsUuid; + m_scene.AddInventoryItem(item); return item; @@ -448,18 +450,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver } string extension = filename.Substring(i); - string uuid = filename.Remove(filename.Length - extension.Length); + string rawUuid = filename.Remove(filename.Length - extension.Length); + UUID assetId = new UUID(rawUuid); if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) { sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; if (assetType == (sbyte)AssetType.Unknown) - m_log.WarnFormat("[INVENTORY ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, uuid); + { + m_log.WarnFormat("[INVENTORY ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, assetId); + } + else if (assetType == (sbyte)AssetType.Object) + { + if (m_creatorIdForAssetId.ContainsKey(assetId)) + { + string xmlData = Utils.BytesToString(data); + SceneObjectGroup sog = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); + foreach (SceneObjectPart sop in sog.Parts) + { + if (sop.CreatorData == null || sop.CreatorData == "") + { + sop.CreatorID = m_creatorIdForAssetId[assetId]; + } + } + + data = Utils.StringToBytes(SceneObjectSerializer.ToOriginalXmlFormat(sog)); + } + } //m_log.DebugFormat("[INVENTORY ARCHIVER]: Importing asset {0}, type {1}", uuid, assetType); - AssetBase asset = new AssetBase(new UUID(uuid), "RandomName", assetType, UUID.Zero.ToString()); + AssetBase asset = new AssetBase(assetId, "From IAR", assetType, UUID.Zero.ToString()); asset.Data = data; m_scene.AssetService.Store(asset); @@ -497,7 +519,88 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver majorVersion, MAX_MAJOR_VERSION)); } - m_log.InfoFormat("[INVENTORY ARCHIVER]: Loading IAR with version {0}", version); + m_controlFileLoaded = true; + m_log.InfoFormat("[INVENTORY ARCHIVER]: Loading IAR with version {0}", version); } + + /// + /// Load inventory file + /// + /// + /// + /// + protected void LoadInventoryFile(string path, TarArchiveReader.TarEntryType entryType, byte[] data) + { + if (!m_controlFileLoaded) + throw new Exception( + string.Format( + "The IAR you are trying to load does not list {0} before {1}. Aborting load", + ArchiveConstants.CONTROL_FILE_PATH, ArchiveConstants.INVENTORY_PATH)); + + if (m_assetsLoaded) + throw new Exception( + string.Format( + "The IAR you are trying to load does not list all {0} before {1}. Aborting load", + ArchiveConstants.INVENTORY_PATH, ArchiveConstants.ASSETS_PATH)); + + path = path.Substring(ArchiveConstants.INVENTORY_PATH.Length); + + // Trim off the file portion if we aren't already dealing with a directory path + if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType) + path = path.Remove(path.LastIndexOf("/") + 1); + + InventoryFolderBase foundFolder + = ReplicateArchivePathToUserInventory( + path, m_rootDestinationFolder, m_resolvedFolders, m_loadedNodes); + + if (TarArchiveReader.TarEntryType.TYPE_DIRECTORY != entryType) + { + InventoryItemBase item = LoadItem(data, foundFolder); + + if (item != null) + { + m_successfulItemRestores++; + + // If we aren't loading the folder containing the item then well need to update the + // viewer separately for that item. + if (!m_loadedNodes.Contains(foundFolder)) + m_loadedNodes.Add(item); + } + } + + m_inventoryNodesLoaded = true; + } + + /// + /// Load asset file + /// + /// + /// + protected void LoadAssetFile(string path, byte[] data) + { + if (!m_controlFileLoaded) + throw new Exception( + string.Format( + "The IAR you are trying to load does not list {0} before {1}. Aborting load", + ArchiveConstants.CONTROL_FILE_PATH, ArchiveConstants.ASSETS_PATH)); + + if (!m_inventoryNodesLoaded) + throw new Exception( + string.Format( + "The IAR you are trying to load does not list all {0} before {1}. Aborting load", + ArchiveConstants.INVENTORY_PATH, ArchiveConstants.ASSETS_PATH)); + + if (LoadAsset(path, data)) + m_successfulAssetRestores++; + else + m_failedAssetRestores++; + + if ((m_successfulAssetRestores) % 50 == 0) + m_log.DebugFormat( + "[INVENTORY ARCHIVER]: Loaded {0} assets...", + m_successfulAssetRestores); + + m_assetsLoaded = true; + } } } \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs index dcafc49ee4..e5127a0118 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiveTestCase.cs @@ -63,17 +63,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests /// protected MemoryStream m_iarStream; - protected UserAccount m_ua1 + protected UserAccount m_uaMT = new UserAccount { PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000555"), FirstName = "Mr", LastName = "Tiddles" }; - protected UserAccount m_ua2 + protected UserAccount m_uaLL1 = new UserAccount { PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000666"), FirstName = "Lord", LastName = "Lucan" }; - protected UserAccount m_ua3 + protected UserAccount m_uaLL2 = new UserAccount { PrincipalID = UUID.Parse("00000000-0000-0000-0000-000000000777"), FirstName = "Lord", @@ -81,7 +81,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests protected string m_item1Name = "Ray Gun Item"; [SetUp] - public void SetUp() + public virtual void SetUp() { m_iarStream = new MemoryStream(m_iarStreamBytes); } @@ -96,11 +96,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests { // log4net.Config.XmlConfigurator.Configure(); + InventoryArchiverModule archiverModule = new InventoryArchiverModule(); Scene scene = SceneSetupHelpers.SetupScene("Inventory"); - UserProfileTestUtils.CreateUserWithInventory(scene, m_ua2, "hampshire"); + SceneSetupHelpers.SetupSceneModules(scene, archiverModule); + + UserProfileTestUtils.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); MemoryStream archiveWriteStream = new MemoryStream(); - TarArchiveWriter tar = new TarArchiveWriter(archiveWriteStream); // Create asset SceneObjectGroup object1; @@ -129,18 +131,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests // Create item InventoryItemBase item1 = new InventoryItemBase(); item1.Name = m_item1Name; + item1.ID = UUID.Parse("00000000-0000-0000-0000-000000000020"); item1.AssetID = asset1.FullID; item1.GroupID = UUID.Random(); - item1.CreatorIdAsUuid = m_ua2.PrincipalID; - item1.Owner = UUID.Zero; - - string archiveItem1Name = InventoryArchiveWriteRequest.CreateArchiveItemName(m_item1Name, UUID.Random()); - string archiveItem1Path = string.Format("{0}{1}", ArchiveConstants.INVENTORY_PATH, archiveItem1Name); - tar.WriteFile( - archiveItem1Path, - UserInventoryItemSerializer.Serialize( - item1, new Dictionary(), scene.UserAccountService)); - tar.Close(); + item1.CreatorIdAsUuid = m_uaLL1.PrincipalID; + item1.Owner = m_uaLL1.PrincipalID; + item1.Folder = scene.InventoryService.GetRootFolder(m_uaLL1.PrincipalID).ID; + scene.AddInventoryItem(item1); + + archiverModule.ArchiveInventory( + Guid.NewGuid(), m_uaLL1.FirstName, m_uaLL1.LastName, m_item1Name, "hampshire", archiveWriteStream); m_iarStreamBytes = archiveWriteStream.ToArray(); } diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index b52014b12a..7f156f8904 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs @@ -50,7 +50,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests { [TestFixture] public class InventoryArchiverTests : InventoryArchiveTestCase - { + { + protected TestScene m_scene; + protected InventoryArchiverModule m_archiverModule; + + [SetUp] + public override void SetUp() + { + base.SetUp(); + + SerialiserModule serialiserModule = new SerialiserModule(); + m_archiverModule = new InventoryArchiverModule(); + + m_scene = SceneSetupHelpers.SetupScene("Inventory"); + SceneSetupHelpers.SetupSceneModules(m_scene, serialiserModule, m_archiverModule); + } + /// /// Test saving a single inventory item to a V0.1 OpenSim Inventory Archive /// (subject to change since there is no fixed format yet). @@ -61,17 +76,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests TestHelper.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - InventoryArchiverModule archiverModule = new InventoryArchiverModule(); - - Scene scene = SceneSetupHelpers.SetupScene("Inventory"); - SceneSetupHelpers.SetupSceneModules(scene, archiverModule); - // Create user string userFirstName = "Jock"; string userLastName = "Stirrup"; string userPassword = "troll"; UUID userId = UUID.Parse("00000000-0000-0000-0000-000000000020"); - UserProfileTestUtils.CreateUserWithInventory(scene, userFirstName, userLastName, userId, userPassword); + UserProfileTestUtils.CreateUserWithInventory(m_scene, userFirstName, userLastName, userId, userPassword); // Create asset SceneObjectGroup object1; @@ -90,12 +100,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests part1.Name = partName; object1 = new SceneObjectGroup(part1); - scene.AddNewSceneObject(object1, false); + m_scene.AddNewSceneObject(object1, false); } UUID asset1Id = UUID.Parse("00000000-0000-0000-0000-000000000060"); AssetBase asset1 = AssetHelpers.CreateAsset(asset1Id, object1); - scene.AssetService.Store(asset1); + m_scene.AssetService.Store(asset1); // Create item UUID item1Id = UUID.Parse("00000000-0000-0000-0000-000000000080"); @@ -105,15 +115,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests item1.AssetID = asset1.FullID; item1.ID = item1Id; InventoryFolderBase objsFolder - = InventoryArchiveUtils.FindFolderByPath(scene.InventoryService, userId, "Objects")[0]; + = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, userId, "Objects")[0]; item1.Folder = objsFolder.ID; - scene.AddInventoryItem(item1); + m_scene.AddInventoryItem(item1); MemoryStream archiveWriteStream = new MemoryStream(); - archiverModule.OnInventoryArchiveSaved += SaveCompleted; + m_archiverModule.OnInventoryArchiveSaved += SaveCompleted; mre.Reset(); - archiverModule.ArchiveInventory( + m_archiverModule.ArchiveInventory( Guid.NewGuid(), userFirstName, userLastName, "Objects/" + item1Name, userPassword, archiveWriteStream); mre.WaitOne(60000, false); @@ -168,6 +178,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests // TODO: Test presence of more files and contents of files. } + /// + /// Test case where a creator account exists for the creator UUID embedded in item metadata and serialized + /// objects. + /// + [Test] + public void TestLoadIarCreatorAccountPresent() + { + TestHelper.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + UserProfileTestUtils.CreateUserWithInventory(m_scene, m_uaLL1, "meowfood"); + + m_archiverModule.DearchiveInventory(m_uaLL1.FirstName, m_uaLL1.LastName, "/", "meowfood", m_iarStream); + InventoryItemBase foundItem1 + = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaLL1.PrincipalID, m_item1Name); + + Assert.That( + foundItem1.CreatorId, Is.EqualTo(m_uaLL1.PrincipalID.ToString()), + "Loaded item non-uuid creator doesn't match original"); + Assert.That( + foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL1.PrincipalID), + "Loaded item uuid creator doesn't match original"); + Assert.That(foundItem1.Owner, Is.EqualTo(m_uaLL1.PrincipalID), + "Loaded item owner doesn't match inventory reciever"); + + AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); + string xmlData = Utils.BytesToString(asset1.Data); + SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); + + Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID)); + } + /// /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where /// an account exists with the same name as the creator, though not the same id. @@ -177,35 +219,28 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests { TestHelper.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - - SerialiserModule serialiserModule = new SerialiserModule(); - InventoryArchiverModule archiverModule = new InventoryArchiverModule(); - - // Annoyingly, we have to set up a scene even though inventory loading has nothing to do with a scene - Scene scene = SceneSetupHelpers.SetupScene("inventory"); - - SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); - UserProfileTestUtils.CreateUserWithInventory(scene, m_ua1, "meowfood"); - UserProfileTestUtils.CreateUserWithInventory(scene, m_ua3, "hampshire"); + UserProfileTestUtils.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); + UserProfileTestUtils.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire"); - archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "/", "meowfood", m_iarStream); + m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); InventoryItemBase foundItem1 - = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_ua1.PrincipalID, m_item1Name); + = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); -// We have to disable this check since loaded items that did find users via OSPA resolution are now only storing the -// UUID, not the OSPA itself. -// Assert.That( -// foundItem1.CreatorId, Is.EqualTo(item1.CreatorId), -// "Loaded item non-uuid creator doesn't match original"); Assert.That( - foundItem1.CreatorId, Is.EqualTo(m_ua3.PrincipalID.ToString()), + foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()), "Loaded item non-uuid creator doesn't match original"); Assert.That( - foundItem1.CreatorIdAsUuid, Is.EqualTo(m_ua3.PrincipalID), + foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID), "Loaded item uuid creator doesn't match original"); - Assert.That(foundItem1.Owner, Is.EqualTo(m_ua1.PrincipalID), + Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID), "Loaded item owner doesn't match inventory reciever"); + + AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); + string xmlData = Utils.BytesToString(asset1.Data); + SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); + + Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID)); } /// @@ -218,24 +253,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests TestHelper.InMethod(); // log4net.Config.XmlConfigurator.Configure(); - SerialiserModule serialiserModule = new SerialiserModule(); - InventoryArchiverModule archiverModule = new InventoryArchiverModule(); - Scene scene = SceneSetupHelpers.SetupScene("inventory"); - SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); - - UserProfileTestUtils.CreateUserWithInventory(scene, m_ua1, "password"); - archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "/", "password", m_iarStream); + UserProfileTestUtils.CreateUserWithInventory(m_scene, m_uaMT, "password"); + m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "password", m_iarStream); InventoryItemBase foundItem1 - = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_ua1.PrincipalID, m_item1Name); + = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); -// Assert.That( -// foundItem1.CreatorId, Is.EqualTo(userUuid), -// "Loaded item non-uuid creator doesn't match that of the loading user"); Assert.That( - foundItem1.CreatorIdAsUuid, Is.EqualTo(m_ua1.PrincipalID), + foundItem1.CreatorId, Is.EqualTo(m_uaMT.PrincipalID.ToString()), + "Loaded item non-uuid creator doesn't match that of the loading user"); + Assert.That( + foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaMT.PrincipalID), "Loaded item uuid creator doesn't match that of the loading user"); + + AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); + string xmlData = Utils.BytesToString(asset1.Data); + SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); + + Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaMT.PrincipalID)); } } } \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs index 1220a7090a..0e8f647dbc 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/PathTests.cs @@ -84,9 +84,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests Quaternion rotationOffset = new Quaternion(20, 30, 40, 50); Vector3 offsetPosition = new Vector3(5, 10, 15); - part1 - = new SceneObjectPart( - ownerId, shape, groupPosition, rotationOffset, offsetPosition); + part1 = new SceneObjectPart(ownerId, shape, groupPosition, rotationOffset, offsetPosition); part1.Name = partName; object1 = new SceneObjectGroup(part1); @@ -186,31 +184,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); - UserProfileTestUtils.CreateUserWithInventory(scene, m_ua1, "meowfood"); - UserProfileTestUtils.CreateUserWithInventory(scene, m_ua2, "hampshire"); + UserProfileTestUtils.CreateUserWithInventory(scene, m_uaMT, "meowfood"); + UserProfileTestUtils.CreateUserWithInventory(scene, m_uaLL1, "hampshire"); - archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "/", "meowfood", m_iarStream); + archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); InventoryItemBase foundItem1 - = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_ua1.PrincipalID, m_item1Name); + = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1"); // Now try loading to a root child folder - UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, m_ua1.PrincipalID, "xA"); + UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xA"); MemoryStream archiveReadStream = new MemoryStream(m_iarStream.ToArray()); - archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "xA", "meowfood", archiveReadStream); + archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xA", "meowfood", archiveReadStream); InventoryItemBase foundItem2 - = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_ua1.PrincipalID, "xA/" + m_item1Name); + = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xA/" + m_item1Name); Assert.That(foundItem2, Is.Not.Null, "Didn't find loaded item 2"); // Now try loading to a more deeply nested folder - UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, m_ua1.PrincipalID, "xB/xC"); + UserInventoryTestUtils.CreateInventoryFolder(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC"); archiveReadStream = new MemoryStream(archiveReadStream.ToArray()); - archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "xB/xC", "meowfood", archiveReadStream); + archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "xB/xC", "meowfood", archiveReadStream); InventoryItemBase foundItem3 - = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_ua1.PrincipalID, "xB/xC/" + m_item1Name); + = InventoryArchiveUtils.FindItemByPath(scene.InventoryService, m_uaMT.PrincipalID, "xB/xC/" + m_item1Name); Assert.That(foundItem3, Is.Not.Null, "Didn't find loaded item 3"); } @@ -228,12 +226,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests Scene scene = SceneSetupHelpers.SetupScene("inventory"); SceneSetupHelpers.SetupSceneModules(scene, serialiserModule, archiverModule); - UserProfileTestUtils.CreateUserWithInventory(scene, m_ua1, "password"); - archiverModule.DearchiveInventory(m_ua1.FirstName, m_ua1.LastName, "/Objects", "password", m_iarStream); + UserProfileTestUtils.CreateUserWithInventory(scene, m_uaMT, "password"); + archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/Objects", "password", m_iarStream); InventoryItemBase foundItem1 = InventoryArchiveUtils.FindItemByPath( - scene.InventoryService, m_ua1.PrincipalID, "/Objects/" + m_item1Name); + scene.InventoryService, m_uaMT.PrincipalID, "/Objects/" + m_item1Name); Assert.That(foundItem1, Is.Not.Null, "Didn't find loaded item 1 in TestLoadIarFolderStartsWithSlash()"); } diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index 334dcb0f47..282e4f18fa 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -113,7 +113,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap data = new MapBlockData(); data.Agents = 0; data.Access = info.Access; - data.MapImageId = info.TerrainImage; + data.MapImageId = UUID.Zero; // could use info.TerrainImage but it seems to break viewer2 data.Name = info.RegionName; data.RegionFlags = 0; // TODO not used? data.WaterHeight = 0; // not used diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 7e59b10037..854f1dc996 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -1287,9 +1287,13 @@ namespace OpenSim.Region.Framework.Scenes public Dictionary GetScriptStates(bool oldIDs) { + Dictionary ret = new Dictionary(); + + if (m_part.ParentGroup.Scene == null) // Group not in a scene + return ret; + IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces(); - - Dictionary ret = new Dictionary(); + if (engines == null) // No engine at all return ret; diff --git a/OpenSim/Tests/Common/Setup/AssetHelpers.cs b/OpenSim/Tests/Common/Setup/AssetHelpers.cs index 8647cfed51..ff4423f7ab 100644 --- a/OpenSim/Tests/Common/Setup/AssetHelpers.cs +++ b/OpenSim/Tests/Common/Setup/AssetHelpers.cs @@ -68,7 +68,7 @@ namespace OpenSim.Tests.Common return CreateAsset( assetUuid, AssetType.Object, - Encoding.ASCII.GetBytes(SceneObjectSerializer.ToXml2Format(sog)), + Encoding.ASCII.GetBytes(SceneObjectSerializer.ToOriginalXmlFormat(sog)), sog.OwnerID); } diff --git a/TESTING.txt b/TESTING.txt index e0a7748e6f..54fc976e95 100644 --- a/TESTING.txt +++ b/TESTING.txt @@ -2,23 +2,14 @@ == Running Tests == -On Linux: +On Linux you will need to have NUnit installed (http://www.nunit.org). +This is commonly available in distribution package repositories. + +When this is installed, run the command > nant test -This will print out to the console the test state. - -On Windows: Please see the TESTING ON WINDOWS section below. - - -Also, every checkin will run tests that are kicked off by bamboo. -Results are posted here: http://www.opensimulator.org:8085/ as well as -to #opensim-dev IRC channel. - -== Writing Tests == - -Tests are written to run under NUnit. For more information on NUnit -please see: http://www.nunit.org/index.php +Please see the TESTING ON WINDOWS section below for Windows instructions. == Adding Tests == @@ -32,70 +23,15 @@ that if you are writing tests they end up in a "Tests" sub-directory of the directory where the code you are testing resides. If you have added a new test assembly that hasn't existed before you -must list it in both ".nant/local.include" and ".nant/bamboo.build" +must list it in both ".nant/local.include" for it to be accessible to Linux users and to the continuous integration system. - -=== The Gory Details === -The following is the original document which started off this -document. It should probably be better integrated with the new info. - -==UPDATE== - -The text immediately following is an update to the testing documentation. The -update is written on 2008.08.30 and is copied from an email to the opensim-dev -mailing list[1]. The information below the update, beginning with the section -titled TESTING, is still relevant, so please read this document in its -entirety. - -Mike Mazur - -[1] https://lists.berlios.de/pipermail/opensim-dev/2008-August/002695.html - -""" -The tests are contained in certain DLLs. At the time of writing, these DLLs -have tests in them: - -OpenSim.Region.ScriptEngine.Common.Tests.dll -OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests.dll -OpenSim.Region.ScriptEngine.Shared.Tests.dll -OpenSim.Framework.Tests.dll OpenSim.Region.CoreModules.dll -OpenSim.Region.Physics.OdePlugin.dll[2] - -The console command used to run the tests is `nunit-console` (or -`nunit-console2` on some systems). This command takes a listing of DLLs to -inspect for tests. - -Currently Bamboo's[3] build file (.nant/bamboo.build) lists only those DLLs -for nunit-console to use. However it would be equally correct to simply pass -in all DLLs in bin/; those without tests are just skipped. - -The nunit-console command generates a file TestResults.txt by default. This is -an XML file containing a listing of all DLLs inspected, tests executed, -successes, failures, etc. If nunit-console is passed in all DLLs in bin/, this -file bloats with lots of entries like this: - - - - - - - - -Therefore it makes more sense to me to specify the DLLs when running -nunit-console. - -[2] Note that OpenSim.Region.Physics.OdePlugin.dll is in bin/Physics/ and -needs to be first copied to bin/ before nunit-console is executed. -[3] http://opensimulator.org:8085/ -""" - ==TESTING ON WINDOWS== To use nunit testing on opensim code, you have a variety of methods. The easiast methods involve using IDE capabilities to test code. Using -VS2005/2008 I recommend using the testing capabilities of Resarper(commercial) +VS2005/2008 I recommend using the testing capabilities of Resharper(commercial) or TestDriven.Net(free). Both will recognize nunit tests within your application and allow you to test them individually, or all at once, etc. You will also be able to step into debug mode into a test through these add-ins @@ -133,6 +69,3 @@ Example nunit-console2 OpenSim.Framework.Tests.dll (on linux) nunit-console OpenSim.Framework.Tests.dll (on windows) - -For more information on testing contact the autor of this testing readme: Daedius Moskvitch ( daedius @@@@ daedius com) -