Add regression TestDetachScriptedAttachmentToInventory()

This currently only does a relatively crude check for a ScriptState node in the serialized xml
0.7.3-extended
Justin Clark-Casey (justincc) 2012-07-11 21:43:35 +01:00
parent 0cb1b0bb4a
commit 150860c964
9 changed files with 151 additions and 32 deletions

View File

@ -339,7 +339,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
} }
public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) public SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
{ {
if (!Enabled) if (!Enabled)
return null; return null;
@ -527,6 +527,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
/// </remarks> /// </remarks>
/// <param name="sp"></param> /// <param name="sp"></param>
/// <param name="grp"></param> /// <param name="grp"></param>
/// <param name="saveAllScripted"></param>
private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, bool saveAllScripted) private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp, bool saveAllScripted)
{ {
// Saving attachments for NPCs messes them up for the real owner! // Saving attachments for NPCs messes them up for the real owner!
@ -720,18 +721,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true,
false, false, sp.UUID, true); false, false, sp.UUID, true);
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}",
// objatt.Name, remoteClient.Name, AttachmentPt);
if (objatt != null) if (objatt != null)
{ {
// m_log.DebugFormat(
// "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}",
// objatt.Name, sp.Name, attachmentPt, m_scene.Name);
// HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller.
objatt.HasGroupChanged = false; objatt.HasGroupChanged = false;
bool tainted = false; bool tainted = false;
if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint)
tainted = true; tainted = true;
// FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal
// course of events. If not, then it's probably not worth trying to recover the situation
// since this is more likely to trigger further exceptions and confuse later debugging. If
// exceptions can be thrown in expected error conditions (not NREs) then make this consistent
// since other normal error conditions will simply return false instead.
// This will throw if the attachment fails // This will throw if the attachment fails
try try
{ {

View File

@ -31,6 +31,7 @@ using System.Reflection;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Timers; using System.Timers;
using System.Xml;
using Timer=System.Timers.Timer; using Timer=System.Timers.Timer;
using Nini.Config; using Nini.Config;
using NUnit.Framework; using NUnit.Framework;
@ -41,10 +42,12 @@ using OpenSim.Region.CoreModules.Avatar.Attachments;
using OpenSim.Region.CoreModules.Framework; using OpenSim.Region.CoreModules.Framework;
using OpenSim.Region.CoreModules.Framework.EntityTransfer; using OpenSim.Region.CoreModules.Framework.EntityTransfer;
using OpenSim.Region.CoreModules.Framework.InventoryAccess; using OpenSim.Region.CoreModules.Framework.InventoryAccess;
using OpenSim.Region.CoreModules.World.Serialiser; using OpenSim.Region.CoreModules.Scripting.WorldComm;
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation;
using OpenSim.Region.CoreModules.World.Serialiser;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.ScriptEngine.XEngine;
using OpenSim.Services.Interfaces; using OpenSim.Services.Interfaces;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
using OpenSim.Tests.Common.Mock; using OpenSim.Tests.Common.Mock;
@ -57,6 +60,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
[TestFixture] [TestFixture]
public class AttachmentsModuleTests : OpenSimTestCase public class AttachmentsModuleTests : OpenSimTestCase
{ {
private AutoResetEvent m_chatEvent = new AutoResetEvent(false);
private OSChatMessage m_osChatMessageReceived;
[TestFixtureSetUp] [TestFixtureSetUp]
public void FixtureInit() public void FixtureInit()
{ {
@ -72,16 +78,73 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
} }
private Scene CreateDefaultTestScene() private void OnChatFromWorld(object sender, OSChatMessage oscm)
{
// Console.WriteLine("Got chat [{0}]", oscm.Message);
m_osChatMessageReceived = oscm;
m_chatEvent.Set();
}
private Scene CreateTestScene()
{ {
IConfigSource config = new IniConfigSource(); IConfigSource config = new IniConfigSource();
List<object> modules = new List<object>();
AddCommonConfig(config, modules);
Scene scene
= new SceneHelpers().SetupScene(
"attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config);
SceneHelpers.SetupSceneModules(scene, config, modules.ToArray());
return scene;
}
private Scene CreateScriptingEnabledTestScene()
{
IConfigSource config = new IniConfigSource();
List<object> modules = new List<object>();
AddCommonConfig(config, modules);
AddScriptingConfig(config, modules);
Scene scene
= new SceneHelpers().SetupScene(
"attachments-test-scene", TestHelpers.ParseTail(999), 1000, 1000, config);
SceneHelpers.SetupSceneModules(scene, config, modules.ToArray());
scene.StartScripts();
return scene;
}
private void AddCommonConfig(IConfigSource config, List<object> modules)
{
config.AddConfig("Modules"); config.AddConfig("Modules");
config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule");
Scene scene = new SceneHelpers().SetupScene(); modules.Add(new AttachmentsModule());
SceneHelpers.SetupSceneModules(scene, config, new AttachmentsModule(), new BasicInventoryAccessModule()); modules.Add(new BasicInventoryAccessModule());
}
return scene; private void AddScriptingConfig(IConfigSource config, List<object> modules)
{
IConfig startupConfig = config.AddConfig("Startup");
startupConfig.Set("DefaultScriptEngine", "XEngine");
IConfig xEngineConfig = config.AddConfig("XEngine");
xEngineConfig.Set("Enabled", "true");
// These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call
// to AssemblyResolver.OnAssemblyResolve fails.
xEngineConfig.Set("AppDomainLoading", "false");
modules.Add(new XEngine());
// Necessary to stop serialization complaining
// FIXME: Stop this being necessary if at all possible
// modules.Add(new WorldCommModule());
} }
/// <summary> /// <summary>
@ -116,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
TestHelpers.InMethod(); TestHelpers.InMethod();
// TestHelpers.EnableLogging(); // TestHelpers.EnableLogging();
Scene scene = CreateDefaultTestScene(); Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
@ -163,7 +226,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
TestHelpers.InMethod(); TestHelpers.InMethod();
// TestHelpers.EnableLogging(); // TestHelpers.EnableLogging();
Scene scene = CreateDefaultTestScene(); Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
@ -190,7 +253,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
TestHelpers.InMethod(); TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
Scene scene = CreateDefaultTestScene(); Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
@ -225,7 +288,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
Scene scene = CreateDefaultTestScene(); Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
@ -248,7 +311,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
TestHelpers.InMethod(); TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
Scene scene = CreateDefaultTestScene(); Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
@ -278,9 +341,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
public void TestDetachAttachmentToInventory() public void TestDetachAttachmentToInventory()
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure();
Scene scene = CreateDefaultTestScene(); Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
@ -302,6 +364,45 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(0)); Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(0));
} }
/// <summary>
/// Test specific conditions associated with detaching a scripted attachment from inventory.
/// </summary>
[Test]
public void TestDetachScriptedAttachmentToInventory()
{
TestHelpers.InMethod();
TestHelpers.EnableLogging();
Scene scene = CreateScriptingEnabledTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, sp.UUID, "att-name", 0x10);
TaskInventoryHelpers.AddScript(scene, so.RootPart);
InventoryItemBase userItem = UserInventoryHelpers.AddInventoryItem(scene, so, 0x100, 0x1000);
// FIXME: Right now, we have to do a tricksy chat listen to make sure we know when the script is running.
// In the future, we need to be able to do this programatically more predicably.
scene.EventManager.OnChatFromWorld += OnChatFromWorld;
SceneObjectGroup soRezzed
= scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, userItem.ID, (uint)AttachmentPoint.Chest);
// Wait for chat to signal rezzed script has been started.
m_chatEvent.WaitOne(60000);
scene.AttachmentsModule.DetachSingleAttachmentToInv(sp, soRezzed);
InventoryItemBase userItemUpdated = scene.InventoryService.GetItem(userItem);
AssetBase asset = scene.AssetService.Get(userItemUpdated.AssetID.ToString());
XmlDocument soXml = new XmlDocument();
soXml.LoadXml(Encoding.UTF8.GetString(asset.Data));
XmlNodeList scriptStateNodes = soXml.GetElementsByTagName("ScriptState");
Assert.That(scriptStateNodes.Count, Is.EqualTo(1));
}
/// <summary> /// <summary>
/// Test that attachments don't hang about in the scene when the agent is closed /// Test that attachments don't hang about in the scene when the agent is closed
/// </summary> /// </summary>
@ -311,7 +412,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
TestHelpers.InMethod(); TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
Scene scene = CreateDefaultTestScene(); Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
@ -334,7 +435,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
TestHelpers.InMethod(); TestHelpers.InMethod();
// log4net.Config.XmlConfigurator.Configure(); // log4net.Config.XmlConfigurator.Configure();
Scene scene = CreateDefaultTestScene(); Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);
@ -370,7 +471,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
Scene scene = CreateDefaultTestScene(); Scene scene = CreateTestScene();
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20);

View File

@ -92,7 +92,7 @@ namespace OpenSim.Region.Framework.Interfaces
/// <param name="itemID"></param> /// <param name="itemID"></param>
/// <param name="AttachmentPt"></param> /// <param name="AttachmentPt"></param>
/// <returns>The scene object that was attached. Null if the scene object could not be found</returns> /// <returns>The scene object that was attached. Null if the scene object could not be found</returns>
ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt); SceneObjectGroup RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt);
/// <summary> /// <summary>
/// Rez multiple attachments from a user's inventory /// Rez multiple attachments from a user's inventory

View File

@ -1213,6 +1213,10 @@ namespace OpenSim.Region.Framework.Scenes
{ {
if (e != null) if (e != null)
{ {
// m_log.DebugFormat(
// "[PRIM INVENTORY]: Getting script state from engine {0} for {1} in part {2} in group {3} in {4}",
// e.Name, item.Name, m_part.Name, m_part.ParentGroup.Name, m_part.ParentGroup.Scene.Name);
string n = e.GetXMLState(item.ItemID); string n = e.GetXMLState(item.ItemID);
if (n != String.Empty) if (n != String.Empty)
{ {

View File

@ -233,8 +233,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_Timer[engine].UnSetTimerEvents(localID, itemID); m_Timer[engine].UnSetTimerEvents(localID, itemID);
// Remove from: HttpRequest // Remove from: HttpRequest
IHttpRequestModule iHttpReq = IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface<IHttpRequestModule>();
engine.World.RequestModuleInterface<IHttpRequestModule>(); if (iHttpReq != null)
iHttpReq.StopHttpRequest(localID, itemID); iHttpReq.StopHttpRequest(localID, itemID);
IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>(); IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
@ -242,8 +242,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
comms.DeleteListener(itemID); comms.DeleteListener(itemID);
IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>(); IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
if (xmlrpc != null)
{
xmlrpc.DeleteChannels(itemID); xmlrpc.DeleteChannels(itemID);
xmlrpc.CancelSRDRequests(itemID); xmlrpc.CancelSRDRequests(itemID);
}
// Remove Sensors // Remove Sensors
m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID); m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
@ -305,7 +308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{ {
List<Object> data = new List<Object>(); List<Object> data = new List<Object>();
Object[] listeners=m_Listener[engine].GetSerializationData(itemID); Object[] listeners = m_Listener[engine].GetSerializationData(itemID);
if (listeners.Length > 0) if (listeners.Length > 0)
{ {
data.Add("listener"); data.Add("listener");

View File

@ -88,12 +88,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
public Object[] GetSerializationData(UUID itemID) public Object[] GetSerializationData(UUID itemID)
{ {
if (m_commsPlugin != null)
return m_commsPlugin.GetSerializationData(itemID); return m_commsPlugin.GetSerializationData(itemID);
else
return new Object[]{};
} }
public void CreateFromData(uint localID, UUID itemID, UUID hostID, public void CreateFromData(uint localID, UUID itemID, UUID hostID,
Object[] data) Object[] data)
{ {
if (m_commsPlugin != null)
m_commsPlugin.CreateFromData(localID, itemID, hostID, data); m_commsPlugin.CreateFromData(localID, itemID, hostID, data);
} }
} }

View File

@ -1669,12 +1669,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
public string GetXMLState(UUID itemID) public string GetXMLState(UUID itemID)
{ {
// m_log.DebugFormat("[XEngine]: Getting XML state for {0}", itemID); // m_log.DebugFormat("[XEngine]: Getting XML state for script instance {0}", itemID);
IScriptInstance instance = GetInstance(itemID); IScriptInstance instance = GetInstance(itemID);
if (instance == null) if (instance == null)
{ {
// m_log.DebugFormat("[XEngine]: Found no script for {0}, returning empty string", itemID); // m_log.DebugFormat("[XEngine]: Found no script instance for {0}, returning empty string", itemID);
return ""; return "";
} }

View File

@ -81,7 +81,7 @@ namespace OpenSim.Tests.Common
public static TaskInventoryItem AddScript(Scene scene, SceneObjectPart part) public static TaskInventoryItem AddScript(Scene scene, SceneObjectPart part)
{ {
AssetScriptText ast = new AssetScriptText(); AssetScriptText ast = new AssetScriptText();
ast.Source = "default { state_entry() {} }"; ast.Source = "default { state_entry() { llSay(0, \"Hello World\"); } }";
ast.Encode(); ast.Encode();
UUID assetUuid = new UUID("00000000-0000-0000-1000-000000000000"); UUID assetUuid = new UUID("00000000-0000-0000-1000-000000000000");

View File

@ -2925,6 +2925,7 @@
<Reference name="OpenSim.Region.Framework"/> <Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenSim.Region.CoreModules"/> <Reference name="OpenSim.Region.CoreModules"/>
<Reference name="OpenSim.Region.Physics.Manager"/> <Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="OpenSim.Region.ScriptEngine.XEngine"/>
<Reference name="OpenSim.Services.Interfaces"/> <Reference name="OpenSim.Services.Interfaces"/>
<!-- Unit tests --> <!-- Unit tests -->