diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 5a7c379f0f..ed92b2d2f4 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -58,10 +58,12 @@ namespace OpenSim.Framework /// /// None is used to execute the method in the same thread that made the call. It should only be used by regression /// test code that relies on predictable event ordering. + /// RegressionTest is used by regression tests. It fires the call synchronously and does not catch any exceptions. /// public enum FireAndForgetMethod { None, + RegressionTest, UnsafeQueueUserWorkItem, QueueUserWorkItem, BeginInvoke, @@ -1544,27 +1546,38 @@ namespace OpenSim.Framework public static void FireAndForget(System.Threading.WaitCallback callback, object obj) { - // When OpenSim interacts with a database or sends data over the wire, it must send this in en_US culture - // so that we don't encounter problems where, for instance, data is saved with a culture that uses commas - // for decimals places but is read by a culture that treats commas as number seperators. - WaitCallback realCallback = delegate(object o) - { - Culture.SetCurrentCulture(); + WaitCallback realCallback; - try + if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest) + { + // If we're running regression tests, then we want any exceptions to rise up to the test code. + realCallback = o => { Culture.SetCurrentCulture(); callback(o); }; + } + else + { + // When OpenSim interacts with a database or sends data over the wire, it must send this in en_US culture + // so that we don't encounter problems where, for instance, data is saved with a culture that uses commas + // for decimals places but is read by a culture that treats commas as number seperators. + realCallback = o => { - callback(o); - } - catch (Exception e) - { -// m_log.ErrorFormat( -// "[UTIL]: Continuing after async_call_method thread terminated with exception {0}{1}", -// e.Message, e.StackTrace); - } - }; + Culture.SetCurrentCulture(); + + try + { + callback(o); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[UTIL]: Continuing after async_call_method thread terminated with exception {0}{1}", + e.Message, e.StackTrace); + } + }; + } switch (FireAndForgetMethod) { + case FireAndForgetMethod.RegressionTest: case FireAndForgetMethod.None: realCallback.Invoke(obj); break; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 4ab8fd02fd..ac21805c54 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -611,11 +611,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; } - protected override void PacketReceived(UDPPacketBuffer buffer) + public override void PacketReceived(UDPPacketBuffer buffer) { // Debugging/Profiling //try { Thread.CurrentThread.Name = "PacketReceived (" + m_scene.RegionInfo.RegionName + ")"; } //catch (Exception) { } +// m_log.DebugFormat( +// "[LLUDPSERVER]: Packet received from {0} in {1}", buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); LLUDPClient udpClient = null; Packet packet = null; @@ -625,7 +627,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Decoding if (buffer.DataLength < 7) + { +// m_log.WarnFormat( +// "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}", +// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); + return; // Drop undersizd packet + } int headerLen = 7; if (buffer.Data[6] == 0xFF) @@ -637,7 +645,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP } if (buffer.DataLength < headerLen) + { +// m_log.WarnFormat( +// "[LLUDPSERVER]: Dropping packet with malformed header received from {0} in {1}", +// buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); + return; // Malformed header + } try { @@ -650,6 +664,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP } catch (IndexOutOfRangeException) { +// m_log.WarnFormat( +// "[LLUDPSERVER]: Dropping short packet received from {0} in {1}", +// buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); + return; // Drop short packet } catch(Exception e) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 6eebd9df3a..039379d4ee 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs @@ -44,7 +44,7 @@ namespace OpenMetaverse /// This method is called when an incoming packet is received /// /// Incoming packet buffer - protected abstract void PacketReceived(UDPPacketBuffer buffer); + public abstract void PacketReceived(UDPPacketBuffer buffer); /// UDP port to bind to in server mode protected int m_udpPort; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs index 9d37cdfc3a..e3b0eab121 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System; using System.Net; using log4net.Config; using Nini.Config; @@ -32,10 +33,11 @@ using NUnit.Framework; using OpenMetaverse; using OpenMetaverse.Packets; using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; -namespace OpenSim.Region.ClientStack.LindenUDP.Tests +namespace OpenSim.Region.ClientStack.LindenUDP { /// /// This will contain basic tests for the LindenUDP client stack @@ -43,19 +45,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests [TestFixture] public class BasicCircuitTests { - [SetUp] - public void Init() + [TestFixtureSetUp] + public void FixtureInit() { - try - { - XmlConfigurator.Configure(); - } - catch - { - // I don't care, just leave log4net off - } + // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. + Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest; } - + + [TestFixtureTearDown] + public void TearDown() + { + // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple + // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression + // tests really shouldn't). + Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; + } + // /// // /// Add a client for testing // /// @@ -78,54 +83,54 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests // testLLUDPServer.LocalScene = scene; // } - /// - /// Set up a client for tests which aren't concerned with this process itself and where only one client is being - /// tested - /// - /// - /// - /// - /// - protected void AddClient( - uint circuitCode, EndPoint epSender, TestLLUDPServer testLLUDPServer, AgentCircuitManager acm) - { - UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001"); - UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002"); - - AddClient(circuitCode, epSender, myAgentUuid, mySessionUuid, testLLUDPServer, acm); - } +// /// +// /// Set up a client for tests which aren't concerned with this process itself and where only one client is being +// /// tested +// /// +// /// +// /// +// /// +// /// +// protected void AddClient( +// uint circuitCode, EndPoint epSender, TestLLUDPServer testLLUDPServer, AgentCircuitManager acm) +// { +// UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001"); +// UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002"); +// +// AddClient(circuitCode, epSender, myAgentUuid, mySessionUuid, testLLUDPServer, acm); +// } - /// - /// Set up a client for tests which aren't concerned with this process itself - /// - /// - /// - /// - /// - /// - /// - protected void AddClient( - uint circuitCode, EndPoint epSender, UUID agentId, UUID sessionId, - TestLLUDPServer testLLUDPServer, AgentCircuitManager acm) - { - AgentCircuitData acd = new AgentCircuitData(); - acd.AgentID = agentId; - acd.SessionID = sessionId; - - UseCircuitCodePacket uccp = new UseCircuitCodePacket(); - - UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock - = new UseCircuitCodePacket.CircuitCodeBlock(); - uccpCcBlock.Code = circuitCode; - uccpCcBlock.ID = agentId; - uccpCcBlock.SessionID = sessionId; - uccp.CircuitCode = uccpCcBlock; - - acm.AddNewCircuit(circuitCode, acd); - - testLLUDPServer.LoadReceive(uccp, epSender); - testLLUDPServer.ReceiveData(null); - } +// /// +// /// Set up a client for tests which aren't concerned with this process itself +// /// +// /// +// /// +// /// +// /// +// /// +// /// +// protected void AddClient( +// uint circuitCode, EndPoint epSender, UUID agentId, UUID sessionId, +// TestLLUDPServer testLLUDPServer, AgentCircuitManager acm) +// { +// AgentCircuitData acd = new AgentCircuitData(); +// acd.AgentID = agentId; +// acd.SessionID = sessionId; +// +// UseCircuitCodePacket uccp = new UseCircuitCodePacket(); +// +// UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock +// = new UseCircuitCodePacket.CircuitCodeBlock(); +// uccpCcBlock.Code = circuitCode; +// uccpCcBlock.ID = agentId; +// uccpCcBlock.SessionID = sessionId; +// uccp.CircuitCode = uccpCcBlock; +// +// acm.AddNewCircuit(circuitCode, acd); +// +// testLLUDPServer.LoadReceive(uccp, epSender); +// testLLUDPServer.ReceiveData(null); +// } /// /// Build an object name packet for test purposes @@ -144,54 +149,60 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests return onp; } -// /// -// /// Test adding a client to the stack -// /// -// [Test] -// public void TestAddClient() -// { -// TestHelper.InMethod(); -// -// uint myCircuitCode = 123456; -// UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001"); -// UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002"); -// -// TestLLUDPServer testLLUDPServer; -// TestLLPacketServer testLLPacketServer; -// AgentCircuitManager acm; -// SetupStack(new MockScene(), out testLLUDPServer, out testLLPacketServer, out acm); -// -// AgentCircuitData acd = new AgentCircuitData(); -// acd.AgentID = myAgentUuid; -// acd.SessionID = mySessionUuid; -// -// UseCircuitCodePacket uccp = new UseCircuitCodePacket(); -// -// UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock -// = new UseCircuitCodePacket.CircuitCodeBlock(); -// uccpCcBlock.Code = myCircuitCode; -// uccpCcBlock.ID = myAgentUuid; -// uccpCcBlock.SessionID = mySessionUuid; -// uccp.CircuitCode = uccpCcBlock; -// -// EndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999); -// -// testLLUDPServer.LoadReceive(uccp, testEp); -// testLLUDPServer.ReceiveData(null); -// -// // Circuit shouildn't exist since the circuit manager doesn't know about this circuit for authentication yet -// Assert.IsFalse(testLLUDPServer.HasCircuit(myCircuitCode)); -// -// acm.AddNewCircuit(myCircuitCode, acd); -// -// testLLUDPServer.LoadReceive(uccp, testEp); -// testLLUDPServer.ReceiveData(null); -// -// // Should succeed now -// Assert.IsTrue(testLLUDPServer.HasCircuit(myCircuitCode)); -// Assert.IsFalse(testLLUDPServer.HasCircuit(101)); -// } -// + /// + /// Test adding a client to the stack + /// + [Test] + public void TestAddClient() + { + TestHelpers.InMethod(); + XmlConfigurator.Configure(); + + TestScene scene = SceneHelpers.SetupScene(); + uint myCircuitCode = 123456; + UUID myAgentUuid = TestHelpers.ParseTail(0x1); + UUID mySessionUuid = TestHelpers.ParseTail(0x2); + IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999); + + uint port = 0; + AgentCircuitManager acm = scene.AuthenticateHandler; + + LLUDPServer llUdpServer + = new LLUDPServer(IPAddress.Any, ref port, 0, false, new IniConfigSource(), acm); + llUdpServer.AddScene(scene); + + UseCircuitCodePacket uccp = new UseCircuitCodePacket(); + + UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock + = new UseCircuitCodePacket.CircuitCodeBlock(); + uccpCcBlock.Code = myCircuitCode; + uccpCcBlock.ID = myAgentUuid; + uccpCcBlock.SessionID = mySessionUuid; + uccp.CircuitCode = uccpCcBlock; + + byte[] uccpBytes = uccp.ToBytes(); + UDPPacketBuffer upb = new UDPPacketBuffer(testEp, uccpBytes.Length); + upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor. + Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length); + + llUdpServer.PacketReceived(upb); + + // Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet + Assert.That(scene.GetScenePresence(myAgentUuid), Is.Null); + + AgentCircuitData acd = new AgentCircuitData(); + acd.AgentID = myAgentUuid; + acd.SessionID = mySessionUuid; + + acm.AddNewCircuit(myCircuitCode, acd); + + llUdpServer.PacketReceived(upb); + + // Should succeed now + ScenePresence sp = scene.GetScenePresence(myAgentUuid); + Assert.That(sp.UUID, Is.EqualTo(myAgentUuid)); + } + // /// // /// Test removing a client from the stack // /// diff --git a/bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll.config b/bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll.config new file mode 100644 index 0000000000..a3f681d89e --- /dev/null +++ b/bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll.config @@ -0,0 +1,33 @@ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +