From cc8289ddd2584bc9d32b3e2deefead55a38caff2 Mon Sep 17 00:00:00 2001 From: Jim Radford Date: Thu, 31 Jul 2008 03:55:49 +0000 Subject: [PATCH] LIBOMV-337 Adds Unit tests for InventoryManager from Chris Omega git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@2041 52acb1d6-8a22-11de-b505-999d5b087335 --- OpenMetaverse.Tests/MockNetworkManager.cs | 103 +++++ OpenMetaverse.Tests/OfflineInventoryTests.cs | 383 +++++++++++++++++++ OpenMetaverse.Tests/OnlineInventoryTests.cs | 107 ++++++ 3 files changed, 593 insertions(+) create mode 100644 OpenMetaverse.Tests/MockNetworkManager.cs create mode 100644 OpenMetaverse.Tests/OfflineInventoryTests.cs create mode 100644 OpenMetaverse.Tests/OnlineInventoryTests.cs diff --git a/OpenMetaverse.Tests/MockNetworkManager.cs b/OpenMetaverse.Tests/MockNetworkManager.cs new file mode 100644 index 00000000..39a33f5b --- /dev/null +++ b/OpenMetaverse.Tests/MockNetworkManager.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Collections; +using System.Net; +using OpenMetaverse; +using OpenMetaverse.Packets; +using NUnit.Framework; + +namespace OpenMetaverse.Tests +{ + public class MockNetworkManager : INetworkManager + { + public delegate void PacketSent(Packet packet, Simulator sim); + public event PacketSent OnPacketSent; + + #region INetworkManager Members + + public event NetworkManager.LoginCallback OnLogin; + + public event NetworkManager.ConnectedCallback OnConnected; + + public event NetworkManager.DisconnectedCallback OnDisconnected; + + + public Simulator CurrentSim + { + get { return null; } + } + + public uint CircuitCode + { + get { return 0; } + } + + private bool _Connected; + public bool Connected + { + get { return _Connected; } + } + + public UUID SessionID + { + get { return UUID.Zero; } + } + + public UUID SecureSessionID + { + get { return UUID.Zero; } + } + + public UUID AgentID + { + get { return UUID.Zero; } + } + + + public void RegisterCallback(PacketType type, NetworkManager.PacketCallback callback) + { + return; + } + + public void RegisterEventCallback(string capsEvent, Caps.EventQueueCallback callback) + { + return; + } + + public void RegisterLoginResponseCallback(NetworkManager.LoginResponseCallback callback, string[] options) + { + return; + } + + public void SendPacket(Packet packet, Simulator sim) + { + if (OnPacketSent != null) + { + OnPacketSent(packet, sim); + } + } + + public void SendPacket(Packet packet) + { + if (OnPacketSent != null) + { + OnPacketSent(packet, CurrentSim); + } + } + + public bool Login(LoginParams loginParams) + { + _Connected = true; + OnLogin(LoginStatus.Success, "Testing"); + OnConnected(null); + return true; + } + + public void Logout() + { + return; + } + + #endregion + } +} diff --git a/OpenMetaverse.Tests/OfflineInventoryTests.cs b/OpenMetaverse.Tests/OfflineInventoryTests.cs new file mode 100644 index 00000000..22aedca3 --- /dev/null +++ b/OpenMetaverse.Tests/OfflineInventoryTests.cs @@ -0,0 +1,383 @@ +using System; +using System.Collections.Generic; +using System.Collections; +using System.Net; +using OpenMetaverse; +using OpenMetaverse.Packets; +using NUnit.Framework; + +namespace OpenMetaverse.Tests +{ + public class ExposedInventory : Inventory + { + public Dictionary GetItems() + { + return Items; + } + + public void InjectUpdate(ItemData data) + { + base.manager_OnItemUpdate(data); + } + + public void InjectUpdate(FolderData data) + { + base.manager_OnFolderUpdate(data); + } + + public ExposedInventory(InventoryManager manager, InventorySkeleton skeleton) + : base(manager, skeleton) { } + } + + [TestFixture] + public class OfflineInventoryTests + { + public MockNetworkManager Network; + public InventorySkeleton Skeleton; + public InventoryManager Manager; + public ExposedInventory Inventory; + + public UUID RootUUID = UUID.Random(); + public UUID OwnerUUID = UUID.Random(); + + [SetUp] + public void Init() + { + Skeleton = new InventorySkeleton(RootUUID, OwnerUUID); + FolderData[] folders = new FolderData[5]; + folders[0] = new FolderData(RootUUID); + folders[0].OwnerID = OwnerUUID; + for (int i = 1; i < folders.Length; ++i) + { + folders[i] = new FolderData(UUID.Random()); + folders[i].ParentUUID = RootUUID; + folders[i].OwnerID = OwnerUUID; + } + Skeleton.Folders = folders; + + Network = new MockNetworkManager(); + Network.OnPacketSent += delegate(Packet packet, Simulator sim) + { + // Print out all the packets that are sent. + Console.WriteLine(packet.ToString()); + }; + //Manager = new InventoryManager(Network); + Inventory = new ExposedInventory(Manager, Skeleton); + + Assert.IsNotNull(Inventory.RootFolder, "Root folder is not managed."); + Assert.AreEqual(Skeleton.Folders.Length, Inventory.GetItems().Count, "Inventory skeleton partially managed."); + Assert.AreEqual(Skeleton.RootUUID, Inventory.RootFolder.UUID, "Skeleton root does not match inventory root."); + } + + [Test] + public void StructAbstractions() + { + FolderData newFolder = ValidFolder(RootUUID); + ItemData newItem = ValidItem(RootUUID); + + InventoryBase item = Inventory.Manage(newItem); + InventoryBase folder = Inventory.Manage(newFolder); + + // ItemData abstractions: + Assert.AreEqual(item.UUID, (item as InventoryItem).Data.UUID, "ItemData UUID abstraction failed."); + Assert.AreEqual(item.ParentUUID, (item as InventoryItem).Data.ParentUUID, "ItemData ParentUUID abstraction failed."); + Assert.AreEqual(item.Name, (item as InventoryItem).Data.Name, "ItemData Name abstraction failed."); + Assert.AreEqual(item.OwnerUUID, (item as InventoryItem).Data.OwnerID, "ItemData OwnerID abstraction failed."); + + // FolderData abstractions: + Assert.AreEqual(folder.UUID, (folder as InventoryFolder).Data.UUID, "FolderData UUID abstraction failed."); + Assert.AreEqual(folder.ParentUUID, (folder as InventoryFolder).Data.ParentUUID, "FolderData ParentUUID abstraction failed."); + Assert.AreEqual(folder.Name, (folder as InventoryFolder).Data.Name, "FolderData Name abstraction failed."); + Assert.AreEqual(folder.OwnerUUID, (folder as InventoryFolder).Data.OwnerID, "FolderData OwnerID abstraction failed."); + } + + [Test] + public void RejectUnowned() + { + FolderData badFolder = ValidFolder(RootUUID); + badFolder.OwnerID = UUID.Random(); + + ItemData badItem = ValidItem(RootUUID); + badItem.OwnerID = UUID.Random(); + + // Test folder: + Assert.IsNull(Inventory.Manage(badFolder), "Inventory managed folder it doesn't own."); + Assert.IsNull(Inventory[badFolder.UUID], "Inventory stored folder it doesn't own."); + + Inventory.InjectUpdate(badFolder); + Assert.IsNull(Inventory[badFolder.UUID], "Inventory stored and managed folder it doesn't own from update."); + + // Test item: + Assert.IsNull(Inventory.Manage(badItem), "Inventory managed item it doesn't own."); + Assert.IsNull(Inventory[badItem.UUID], "Inventory stored item it doesn't own."); + + Inventory.InjectUpdate(badItem); + Assert.IsNull(Inventory[badFolder.UUID], "Inventory stored and managed item it doesn't own from update."); + } + + [Test] + public void ExplicitManagment() + { + // Parent arrives before item. + { + FolderData newFolder = ValidFolder(RootUUID); + + ItemData newItem = ValidItem(newFolder.UUID); + + // Test folder, explicit manage: + + InventoryBase folder = Inventory.Manage(newFolder); + Assert.IsNotNull(folder, "Folder is not managed."); + Assert.IsInstanceOfType(typeof(InventoryFolder), folder, "Managed FolderData did not result in InventoryFolder wrapper."); + Assert.IsNotNull(Inventory[newFolder.UUID], "Folder not stored."); + Assert.IsEmpty((ICollection)((folder as InventoryFolder).Contents), "Folder not empty."); + Assert.AreSame(Inventory.RootFolder, folder.Parent, "Folder parent is not the root folder."); + + // Test item, explicit manage: + + InventoryBase item = Inventory.Manage(newItem); + Assert.IsNotNull(item, "Item is not managed."); + Assert.IsInstanceOfType(typeof(InventoryItem), item, "Managed ItemData did not result in InventoryItem wrapper."); + Assert.IsNotNull(Inventory[newItem.UUID], "Item not stored."); + Assert.IsNotNull(item.Parent, "Item's parent reference not updated."); + CollectionAssert.Contains(folder as InventoryFolder, item, "Folder not updated with managed item."); + Assert.AreEqual(1, (folder as InventoryFolder).Contents.Count, "Folder contains more then 1 item."); + } + + // Opposite scenerio, item arrives before parent. + { + FolderData newFolder = ValidFolder(RootUUID); + + ItemData newItem = ValidItem(newFolder.UUID); + + InventoryItem item = Inventory.Manage(newItem) as InventoryItem; + Assert.IsNotNull(item, "Parentless item not managed."); + Assert.IsNotNull(Inventory[newItem.UUID], "Parentless item not stored."); + Assert.IsNull(Inventory[newFolder.UUID], "Parent stored before FolderData for it obtained."); + Assert.IsNull(item.Parent, "Parent referenced before FolderData for it obtained."); + + InventoryFolder folder = Inventory.Manage(newFolder) as InventoryFolder; + CollectionAssert.Contains(folder, item, "Early item not added to late parent folder."); + } + } + + [Test] + public void UpdateManagment() + { + FolderData newFolder = ValidFolder(RootUUID); + + ItemData newItem = ValidItem(newFolder.UUID); + newItem.Name = "Foo"; + + // Reject updates from unmanaged items: + Inventory.InjectUpdate(newItem); + Assert.IsNull(Inventory[newItem.UUID], "Update for unmanaged item stored."); + + // Test new folder from update, child of managed folder: + Inventory.InjectUpdate(newFolder); + InventoryFolder folder = Inventory[newFolder.UUID] as InventoryFolder; + Assert.IsNotNull(folder, "New child of managed folder not stored."); + CollectionAssert.Contains(Inventory.RootFolder, folder, "Managed folder does not contain new child folder."); + + // Test new item from update: + Inventory.InjectUpdate(newItem); + InventoryItem item = Inventory[newItem.UUID] as InventoryItem; + Assert.IsNotNull(item, "New child of new folder not stored."); + CollectionAssert.Contains(folder, item, "New folder does not have reference to new item."); + + // Test wrapper data struct update: + Assert.AreEqual(item.Name, "Foo", "New folder ItemData wrap failue."); + newItem.Name = "Bar"; + Inventory.InjectUpdate(newItem); + Assert.AreEqual(item.Name, "Bar", "Item wrapper update failure."); + + Assert.AreEqual(0, folder.Data.DescendentCount, "New folder DescendentCount set from non-update."); + newFolder.DescendentCount = 1; + Inventory.InjectUpdate(newFolder); + Assert.AreEqual(1, folder.Data.DescendentCount, "Folder wrapper update failure."); + + // Test parent change update: + newItem.ParentUUID = RootUUID; + Inventory.InjectUpdate(newItem); + Assert.AreSame(item.Parent, Inventory.RootFolder, "New parent reference not set."); + CollectionAssert.DoesNotContain(folder, item, "Removal from old parent failed."); + CollectionAssert.Contains(Inventory.RootFolder, item, "Add to new parent failed."); + + } + + [Test] + public void Removal() + { + FolderData newFolder = ValidFolder(RootUUID); + ItemData newItem = ValidItem(newFolder.UUID); + + InventoryFolder folder = Inventory.Manage(newFolder); + InventoryItem item = Inventory.Manage(newItem); + + folder.Remove(); + CollectionAssert.DoesNotContain(Inventory, folder, "Delete failed to unmanage item."); + CollectionAssert.DoesNotContain(Inventory, item, "Delete failed to recurse."); + } + + [Test] + public void InventoryFromPath() + { + // Null path: + CollectionAssert.Contains(Inventory.InventoryFromPath(null), Inventory.RootFolder, "Null path does not return root"); + CollectionAssert.Contains(Inventory.InventoryFromPath(new string[0]), Inventory.RootFolder, "Empty path does not return root."); + + FolderData folder1 = ValidFolder(RootUUID); + folder1.Name = "Objects"; + FolderData folder1_1 = ValidFolder(folder1.UUID); + folder1_1.Name = "Trees"; + FolderData folder1_2 = ValidFolder(folder1.UUID); + folder1_2.Name = "Gizmos"; + FolderData folder1_3 = ValidFolder(folder1.UUID); + folder1_3.Name = "Purchases"; + + ItemData item1_1 = ValidItem(folder1.UUID); + item1_1.Name = "Object"; + ItemData item1_2 = ValidItem(folder1.UUID); + item1_2.Name = "Object"; + ItemData item1_3 = ValidItem(folder1.UUID); + item1_3.Name = "Tilly"; + ItemData item1_1_1 = ValidItem(folder1_1.UUID); + item1_1_1.Name = "Pine"; + ItemData item1_1_2 = ValidItem(folder1_1.UUID); + item1_1_2.Name = "Maple"; + ItemData item1_1_3 = ValidItem(folder1_1.UUID); + item1_1_3.Name = "Maple"; + ItemData item1_3_1 = ValidItem(folder1_3.UUID); + item1_3_1.Name = "Death Ray"; + ItemData item1_3_2 = ValidItem(folder1_3.UUID); + item1_3_2.Name = "Maple"; + + // Add all of these to the inventory: + FolderData[] folders = new FolderData[] { folder1, folder1_1, folder1_2, folder1_3 }; + ItemData[] items = new ItemData[] { item1_1, item1_1_1, item1_1_2, item1_1_3, item1_2, item1_3, item1_3_1, item1_3_2 }; + + foreach (FolderData folder in folders) + Inventory.Manage(folder); + foreach (ItemData item in items) + Inventory.Manage(item); + + /* Inventory looks like: + * Root + * folder1 + * item1_1 + * item1_2 + * item1_3 + * folder1_1 + * item1_1_1 + * item1_1_2 + * item1_1_3 + * folder1_2 + * folder1_3 + * item1_3_1 + * item1_3_2 + */ + List results = null; + // Test one item path. + results = Inventory.InventoryFromPath(new string[] { "Objects", "Tilly" }); + CollectionAssert.Contains(results, Inventory[item1_3.UUID], "Path search did not find item at path to it."); + Assert.AreEqual(results.Count, 1, "Unexpected results returned for single item path search."); + + // Test multiple items in same folder, with same path. + results = Inventory.InventoryFromPath(new string[] { "Objects", "Object" }); + CollectionAssert.AreEquivalent(results, new InventoryBase[] { Inventory[item1_2.UUID], Inventory[item1_1.UUID] }, "Multiple result, same folders path failed."); + + folder1_1.Name = "Purchases"; // Rename folder1_1 from "Trees" to "Purchases" + Inventory.InjectUpdate(folder1_1); + // folder1_1 and folder1_3 now have the same name. + + // Test items from different folders with the same path. + results = Inventory.InventoryFromPath(new string[] { "Objects", "Purchases", "Maple" }); + // This should return item1_3_2 "Maple" in folder1_3 and item 1_1_2 "Maple" and item1_1_3 "Maple" in folder1_1. + CollectionAssert.AreEquivalent(results, + new InventoryBase[] { Inventory[item1_3_2.UUID], Inventory[item1_1_2.UUID], Inventory[item1_1_3.UUID] }, + "Multiple result, different folders path failed."); + } + + [Test] + public void Move() + { + FolderData newFolder1 = ValidFolder(RootUUID); + ItemData newItem = ValidItem(newFolder1.UUID); + FolderData newFolder2 = ValidFolder(RootUUID); + + + InventoryFolder folder1 = Inventory.Manage(newFolder1); + InventoryFolder folder2 = Inventory.Manage(newFolder2); + InventoryItem item = Inventory.Manage(newItem); + + CollectionAssert.Contains(folder1, item); + + // Move item into folder2. + item.Move(folder2); + CollectionAssert.Contains(folder2, item, "Item not added to new parent's contents."); + Assert.AreSame(item.Parent, folder2, "Item parent reference not updated."); + Assert.AreEqual(item.ParentUUID, folder2.UUID, "Reference to parent's UUID not updated."); + + // Move folder2 into folder1 + folder2.Move(folder1); + CollectionAssert.Contains(folder1, folder2, "Folder2 not added to new parent's contents."); + Assert.AreSame(folder2.Parent, folder1, "Folder parent reference not updated."); + Assert.AreEqual(folder2.ParentUUID, folder1.UUID, "Reference to parent's UUID not updated"); + } + + [Test] + public void DataStructParsing() + { + ItemData item = new ItemData(); + item.AssetType = AssetType.Object; + item.AssetUUID = UUID.Random(); + item.CreationDate = DateTime.Today; + item.CreatorID = UUID.Random(); + item.Description = "Madonna"; + item.Flags = 0xF00; + item.GroupID = UUID.Random(); + item.InventoryType = InventoryType.Object; + item.Name = "Jimmy Jimmy"; + item.OwnerID = UUID.Random(); + item.ParentUUID = UUID.Random(); + item.Permissions = new Permissions(0xF00, 0xBA0, 0xCAF, 0xEBA, 0xBE); + item.SalePrice = 402; + item.SaleType = SaleType.Copy; + item.UUID = UUID.Random(); + + ItemData reconstituted; + Assert.IsTrue(ItemData.TryParse(item.ToString(), out reconstituted), "ItemData.ToString output parsing failed."); + Assert.IsTrue(item == reconstituted, "Reconstituted item is not identical to original."); + + FolderData folder = new FolderData(); + folder.Name = "What?"; + folder.OwnerID = UUID.Random(); + folder.ParentUUID = UUID.Random(); + folder.PreferredType = AssetType.LSLText; + folder.UUID = UUID.Random(); + folder.Version = 24; + // folder.DescendentCount = 2; // Not recorded in string form. + + FolderData reconFolder; + Assert.IsTrue(FolderData.TryParse(folder.ToString(), out reconFolder), "FolderData.ToString output parsing failed."); + Assert.IsTrue(folder == reconFolder, "Reconstituted folder is not identical to original."); + } + + private ItemData ValidItem(UUID parent) + { + ItemData item = new ItemData(UUID.Random()); + item.ParentUUID = parent; + item.OwnerID = OwnerUUID; + return item; + } + + private FolderData ValidFolder(UUID parent) + { + FolderData folder = new FolderData(UUID.Random()); + folder.ParentUUID = parent; + folder.OwnerID = OwnerUUID; + return folder; + } + + } +} diff --git a/OpenMetaverse.Tests/OnlineInventoryTests.cs b/OpenMetaverse.Tests/OnlineInventoryTests.cs new file mode 100644 index 00000000..7af2f83a --- /dev/null +++ b/OpenMetaverse.Tests/OnlineInventoryTests.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.Net; +using OpenMetaverse; +using OpenMetaverse.Packets; +using System.Threading; +using NUnit.Framework; + + + +namespace OpenMetaverse.Tests +{ + [TestFixture] + public class OnlineInventoryTests + { + public GridClient Client; + public Inventory Inventory; + public OnlineInventoryTests() + { + Client = new GridClient(); + Console.WriteLine("Logging in..."); + //string startLoc = NetworkManager.StartLocation("Hooper", 179, 18, 32); + Client.Network.Login("Testing", "Anvil", "testinganvil", "Unit Test Framework", "last", + "contact@libsecondlife.org"); + } + + [SetUp] + public void Init() + { + Assert.IsTrue(Client.Network.Connected, "Client is not connected to the grid"); + + Inventory = new Inventory(Client.Inventory, Client.Inventory.InventorySkeleton); + Assert.IsNotNull(Inventory.RootFolder, "Root folder is null."); + Assert.AreNotEqual(UUID.Zero, Inventory.RootUUID, "Root UUID is zero."); + } + + ~OnlineInventoryTests() + { + if (Client.Network.Connected) + Client.Network.Logout(); + } + + [Test] + public void Rename() + { + InventoryFolder objects = Inventory[Client.Inventory.FindFolderForType(AssetType.Object)] as InventoryFolder; + Assert.IsTrue(objects.DownloadContents(TimeSpan.FromSeconds(30)), "Initial contents request failure."); + List contents = objects.Contents; + CollectionAssert.IsNotEmpty(contents, "Objects folder does not contain any items"); + + InventoryBase randomthing = contents[0]; + UUID uuid = randomthing.UUID; + string oldName = randomthing.Name; + Random rand = new Random(); + string newName = rand.Next().ToString(); + Console.WriteLine("Renaming {0} to {1}", oldName, newName); + randomthing.Rename(newName); + + Assert.AreEqual(randomthing.Name, newName, "Local name update failed."); + + // Redownload the contents: + Assert.IsTrue(objects.DownloadContents(TimeSpan.FromSeconds(30)), "Post-update contents request failure."); + Assert.AreEqual(newName, Inventory[uuid].Name, "Remote update failed."); + } + + [Test] + public void Copy() + { + InventoryFolder notecards = Inventory[Client.Inventory.FindFolderForType(AssetType.Notecard)] as InventoryFolder; + Assert.IsTrue(notecards.DownloadContents(TimeSpan.FromSeconds(30)), "Initial contents request failure"); + List contents = notecards.Contents; + + Console.WriteLine("Notecards folder contents:"); + InventoryItem note = null; + foreach (InventoryBase ib in notecards) + { + if (ib is InventoryItem) + { + if (note == null || note.Data.InventoryType != InventoryType.Notecard) + { + note = ib as InventoryItem; + } + } + Console.WriteLine(ib.Name); + } + Console.WriteLine("Chosen note: {0}", note.Name); + + InventoryItem copy = note.Copy(Inventory.RootFolder, TimeSpan.FromSeconds(30)); + Assert.IsNotNull(copy, "Copied ItemData not wrapped."); + + Console.WriteLine("Copied item:"); + Console.WriteLine(copy.Data.ToString()); + + Console.WriteLine("Original item:"); + Console.WriteLine(note.Data.ToString()); + + ItemData theoretical = note.Data; + // All other properties should be identical. + theoretical.ParentUUID = Inventory.RootUUID; + theoretical.CreationDate = copy.Data.CreationDate; + theoretical.UUID = copy.UUID; + + Assert.IsNotNull(Inventory[copy.UUID], "Copy not managed."); + Assert.IsTrue(copy.Data == theoretical, "Copied item is not identical to original."); + } + } +}