aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--.nant/local.include4
-rw-r--r--OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs14
-rw-r--r--OpenSim/Framework/IScene.cs4
-rw-r--r--OpenSim/Framework/Util.cs45
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs107
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs232
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs177
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs15
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs4
-rw-r--r--bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll.config33
12 files changed, 357 insertions, 282 deletions
diff --git a/.nant/local.include b/.nant/local.include
index 94f510f..a9ba17d 100644
--- a/.nant/local.include
+++ b/.nant/local.include
@@ -117,12 +117,10 @@
117 </exec> 117 </exec>
118 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindencaps.tests)==0}" /> 118 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindencaps.tests)==0}" />
119 119
120<!--
121 <exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.clientstack.lindenudp.tests"> 120 <exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.clientstack.lindenudp.tests">
122 <arg value="./bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll" /> 121 <arg value="./bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll" />
123 </exec> 122 </exec>
124 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" /> 123 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" />
125-->
126 124
127 <exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.scriptengine.tests"> 125 <exec program="${nunitcmd}" failonerror="true" resultproperty="testresult.opensim.region.scriptengine.tests">
128 <arg value="./bin/OpenSim.Region.ScriptEngine.Tests.dll" /> 126 <arg value="./bin/OpenSim.Region.ScriptEngine.Tests.dll" />
@@ -351,7 +349,7 @@
351 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests)==0}" /> 349 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.tests)==0}" />
352 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.tests)==0}" /> 350 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.tests)==0}" />
353 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.servers.tests)==0}" /> 351 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.framework.servers.tests)==0}" />
354<!-- <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" /> --> 352 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.clientstack.lindenudp.tests)==0}" />
355 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.scriptengine.tests)==0}" /> 353 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.scriptengine.tests)==0}" />
356 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.coremodules.tests)==0}" /> 354 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.coremodules.tests)==0}" />
357 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.optionalmodules.tests)==0}" /> 355 <fail message="Failures reported in unit tests." unless="${int::parse(testresult.opensim.region.optionalmodules.tests)==0}" />
diff --git a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs
index b7ca703..c637ccf 100644
--- a/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs
+++ b/OpenSim/Capabilities/Handlers/UploadBakedTexture/UploadBakedTextureHandler.cs
@@ -104,7 +104,7 @@ namespace OpenSim.Capabilities.Handlers
104 } 104 }
105 catch (Exception e) 105 catch (Exception e)
106 { 106 {
107 m_log.Error("[CAPS]: " + e.ToString()); 107 m_log.Error("[UPLOAD BAKED TEXTURE HANDLER]: " + e.ToString());
108 } 108 }
109 109
110 return null; 110 return null;
@@ -130,6 +130,8 @@ namespace OpenSim.Capabilities.Handlers
130 130
131 class BakedTextureUploader 131 class BakedTextureUploader
132 { 132 {
133// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
134
133 public event Action<UUID, byte[]> OnUpLoad; 135 public event Action<UUID, byte[]> OnUpLoad;
134 136
135 private string uploaderPath = String.Empty; 137 private string uploaderPath = String.Empty;
@@ -154,10 +156,12 @@ namespace OpenSim.Capabilities.Handlers
154 public string uploaderCaps(byte[] data, string path, string param) 156 public string uploaderCaps(byte[] data, string path, string param)
155 { 157 {
156 Action<UUID, byte[]> handlerUpLoad = OnUpLoad; 158 Action<UUID, byte[]> handlerUpLoad = OnUpLoad;
159
160 // Don't do this asynchronously, otherwise it's possible for the client to send set appearance information
161 // on another thread which might send out avatar updates before the asset has been put into the asset
162 // service.
157 if (handlerUpLoad != null) 163 if (handlerUpLoad != null)
158 { 164 handlerUpLoad(newAssetID, data);
159 Util.FireAndForget(delegate(object o) { handlerUpLoad(newAssetID, data); });
160 }
161 165
162 string res = String.Empty; 166 string res = String.Empty;
163 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); 167 LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete();
@@ -169,7 +173,7 @@ namespace OpenSim.Capabilities.Handlers
169 173
170 httpListener.RemoveStreamHandler("POST", uploaderPath); 174 httpListener.RemoveStreamHandler("POST", uploaderPath);
171 175
172 // m_log.InfoFormat("[CAPS] baked texture upload completed for {0}",newAssetID); 176// m_log.DebugFormat("[BAKED TEXTURE UPLOADER]: baked texture upload completed for {0}", newAssetID);
173 177
174 return res; 178 return res;
175 } 179 }
diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs
index 6919c48..e0e023d 100644
--- a/OpenSim/Framework/IScene.cs
+++ b/OpenSim/Framework/IScene.cs
@@ -74,9 +74,7 @@ namespace OpenSim.Framework
74 /// <param name="client"></param> 74 /// <param name="client"></param>
75 /// <param name="type">The type of agent to add.</param> 75 /// <param name="type">The type of agent to add.</param>
76 /// <returns> 76 /// <returns>
77 /// The scene agent if the new client was added. 77 /// The scene agent if the new client was added or if an agent that already existed.</returns>
78 /// Null if the required scene agent already existed or no scene agent was added because the required client circuit doesn't exist.
79 /// </returns>
80 ISceneAgent AddNewClient(IClientAPI client, PresenceType type); 78 ISceneAgent AddNewClient(IClientAPI client, PresenceType type);
81 79
82 /// <summary> 80 /// <summary>
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 0b2fbb9..fae6802 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -58,10 +58,12 @@ namespace OpenSim.Framework
58 /// <remarks> 58 /// <remarks>
59 /// None is used to execute the method in the same thread that made the call. It should only be used by regression 59 /// None is used to execute the method in the same thread that made the call. It should only be used by regression
60 /// test code that relies on predictable event ordering. 60 /// test code that relies on predictable event ordering.
61 /// RegressionTest is used by regression tests. It fires the call synchronously and does not catch any exceptions.
61 /// </remarks> 62 /// </remarks>
62 public enum FireAndForgetMethod 63 public enum FireAndForgetMethod
63 { 64 {
64 None, 65 None,
66 RegressionTest,
65 UnsafeQueueUserWorkItem, 67 UnsafeQueueUserWorkItem,
66 QueueUserWorkItem, 68 QueueUserWorkItem,
67 BeginInvoke, 69 BeginInvoke,
@@ -1556,27 +1558,38 @@ namespace OpenSim.Framework
1556 1558
1557 public static void FireAndForget(System.Threading.WaitCallback callback, object obj) 1559 public static void FireAndForget(System.Threading.WaitCallback callback, object obj)
1558 { 1560 {
1559 // When OpenSim interacts with a database or sends data over the wire, it must send this in en_US culture 1561 WaitCallback realCallback;
1560 // so that we don't encounter problems where, for instance, data is saved with a culture that uses commas
1561 // for decimals places but is read by a culture that treats commas as number seperators.
1562 WaitCallback realCallback = delegate(object o)
1563 {
1564 Culture.SetCurrentCulture();
1565 1562
1566 try 1563 if (FireAndForgetMethod == FireAndForgetMethod.RegressionTest)
1567 { 1564 {
1568 callback(o); 1565 // If we're running regression tests, then we want any exceptions to rise up to the test code.
1569 } 1566 realCallback = o => { Culture.SetCurrentCulture(); callback(o); };
1570 catch (Exception e) 1567 }
1568 else
1569 {
1570 // When OpenSim interacts with a database or sends data over the wire, it must send this in en_US culture
1571 // so that we don't encounter problems where, for instance, data is saved with a culture that uses commas
1572 // for decimals places but is read by a culture that treats commas as number seperators.
1573 realCallback = o =>
1571 { 1574 {
1572 m_log.ErrorFormat( 1575 Culture.SetCurrentCulture();
1573 "[UTIL]: Continuing after async_call_method thread terminated with exception {0}{1}", 1576
1574 e.Message, e.StackTrace); 1577 try
1575 } 1578 {
1576 }; 1579 callback(o);
1580 }
1581 catch (Exception e)
1582 {
1583 m_log.ErrorFormat(
1584 "[UTIL]: Continuing after async_call_method thread terminated with exception {0}{1}",
1585 e.Message, e.StackTrace);
1586 }
1587 };
1588 }
1577 1589
1578 switch (FireAndForgetMethod) 1590 switch (FireAndForgetMethod)
1579 { 1591 {
1592 case FireAndForgetMethod.RegressionTest:
1580 case FireAndForgetMethod.None: 1593 case FireAndForgetMethod.None:
1581 realCallback.Invoke(obj); 1594 realCallback.Invoke(obj);
1582 break; 1595 break;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index b04fe9f..bf5b85a 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -328,7 +328,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
328 /// The method to call if the packet is not acked by the client. If null, then a standard 328 /// The method to call if the packet is not acked by the client. If null, then a standard
329 /// resend of the packet is done. 329 /// resend of the packet is done.
330 /// </param> 330 /// </param>
331 public void SendPacket( 331 public virtual void SendPacket(
332 LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting, UnackedPacketMethod method) 332 LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting, UnackedPacketMethod method)
333 { 333 {
334 // CoarseLocationUpdate packets cannot be split in an automated way 334 // CoarseLocationUpdate packets cannot be split in an automated way
@@ -611,11 +611,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
611 outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; 611 outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue;
612 } 612 }
613 613
614 protected override void PacketReceived(UDPPacketBuffer buffer) 614 public override void PacketReceived(UDPPacketBuffer buffer)
615 { 615 {
616 // Debugging/Profiling 616 // Debugging/Profiling
617 //try { Thread.CurrentThread.Name = "PacketReceived (" + m_scene.RegionInfo.RegionName + ")"; } 617 //try { Thread.CurrentThread.Name = "PacketReceived (" + m_scene.RegionInfo.RegionName + ")"; }
618 //catch (Exception) { } 618 //catch (Exception) { }
619// m_log.DebugFormat(
620// "[LLUDPSERVER]: Packet received from {0} in {1}", buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
619 621
620 LLUDPClient udpClient = null; 622 LLUDPClient udpClient = null;
621 Packet packet = null; 623 Packet packet = null;
@@ -625,7 +627,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
625 #region Decoding 627 #region Decoding
626 628
627 if (buffer.DataLength < 7) 629 if (buffer.DataLength < 7)
630 {
631// m_log.WarnFormat(
632// "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}",
633// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
634
628 return; // Drop undersizd packet 635 return; // Drop undersizd packet
636 }
629 637
630 int headerLen = 7; 638 int headerLen = 7;
631 if (buffer.Data[6] == 0xFF) 639 if (buffer.Data[6] == 0xFF)
@@ -637,7 +645,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
637 } 645 }
638 646
639 if (buffer.DataLength < headerLen) 647 if (buffer.DataLength < headerLen)
648 {
649// m_log.WarnFormat(
650// "[LLUDPSERVER]: Dropping packet with malformed header received from {0} in {1}",
651// buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
652
640 return; // Malformed header 653 return; // Malformed header
654 }
641 655
642 try 656 try
643 { 657 {
@@ -650,6 +664,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
650 } 664 }
651 catch (IndexOutOfRangeException) 665 catch (IndexOutOfRangeException)
652 { 666 {
667// m_log.WarnFormat(
668// "[LLUDPSERVER]: Dropping short packet received from {0} in {1}",
669// buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
670
653 return; // Drop short packet 671 return; // Drop short packet
654 } 672 }
655 catch(Exception e) 673 catch(Exception e)
@@ -887,29 +905,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
887// DateTime startTime = DateTime.Now; 905// DateTime startTime = DateTime.Now;
888 object[] array = (object[])o; 906 object[] array = (object[])o;
889 UDPPacketBuffer buffer = (UDPPacketBuffer)array[0]; 907 UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
890 UseCircuitCodePacket packet = (UseCircuitCodePacket)array[1]; 908 UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
891 909
892 m_log.DebugFormat("[LLUDPSERVER]: Handling UseCircuitCode request from {0}", buffer.RemoteEndPoint); 910 m_log.DebugFormat("[LLUDPSERVER]: Handling UseCircuitCode request from {0}", buffer.RemoteEndPoint);
893 911
894 IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint; 912 IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
895 913
896 // Begin the process of adding the client to the simulator 914 AuthenticateResponse sessionInfo;
897 IClientAPI client = AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint); 915 if (IsClientAuthorized(uccp, out sessionInfo))
898 916 {
899 // Send ack straight away to let the viewer know that the connection is active. 917 // Begin the process of adding the client to the simulator
900 SendAckImmediate(remoteEndPoint, packet.Header.Sequence); 918 IClientAPI client
901 919 = AddClient(
902 // FIXME: Nasty - this is the only way we currently know if Scene.AddNewClient() failed to find a 920 uccp.CircuitCode.Code,
903 // circuit and bombed out early. That check might be pointless since authorization is established 921 uccp.CircuitCode.ID,
904 // up here. 922 uccp.CircuitCode.SessionID,
905 if (client != null && client.SceneAgent != null) 923 remoteEndPoint,
906 client.SceneAgent.SendInitialDataToMe(); 924 sessionInfo);
925
926 // Send ack straight away to let the viewer know that the connection is active.
927 // The client will be null if it already exists (e.g. if on a region crossing the client sends a use
928 // circuit code to the existing child agent. This is not particularly obvious.
929 SendAckImmediate(remoteEndPoint, uccp.Header.Sequence);
930
931 // We only want to send initial data to new clients, not ones which are being converted from child to root.
932 if (client != null)
933 client.SceneAgent.SendInitialDataToMe();
934 }
935 else
936 {
937 // Don't create clients for unauthorized requesters.
938 m_log.WarnFormat(
939 "[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
940 uccp.CircuitCode.ID, uccp.CircuitCode.Code, remoteEndPoint);
941 }
907 942
908 // m_log.DebugFormat( 943 // m_log.DebugFormat(
909// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms", 944// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
910// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds); 945// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
911 } 946 }
912 947
948 /// <summary>
949 /// Send an ack immediately to the given endpoint.
950 /// </summary>
951 /// <remarks>
952 /// FIXME: Might be possible to use SendPacketData() like everything else, but this will require refactoring so
953 /// that we can obtain the UDPClient easily at this point.
954 /// </remarks>
955 /// <param name="remoteEndpoint"></param>
956 /// <param name="sequenceNumber"></param>
913 private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber) 957 private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber)
914 { 958 {
915 PacketAckPacket ack = new PacketAckPacket(); 959 PacketAckPacket ack = new PacketAckPacket();
@@ -918,6 +962,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
918 ack.Packets[0] = new PacketAckPacket.PacketsBlock(); 962 ack.Packets[0] = new PacketAckPacket.PacketsBlock();
919 ack.Packets[0].ID = sequenceNumber; 963 ack.Packets[0].ID = sequenceNumber;
920 964
965 SendAckImmediate(remoteEndpoint, ack);
966 }
967
968 public virtual void SendAckImmediate(IPEndPoint remoteEndpoint, PacketAckPacket ack)
969 {
921 byte[] packetData = ack.ToBytes(); 970 byte[] packetData = ack.ToBytes();
922 int length = packetData.Length; 971 int length = packetData.Length;
923 972
@@ -940,36 +989,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
940 } 989 }
941 990
942 /// <summary> 991 /// <summary>
943 /// Add a new client.
944 /// </summary>
945 /// <param name="useCircuitCode"></param>
946 /// <param name="remoteEndPoint"></param>
947 /// <returns>
948 /// The client that was added or null if the client failed authorization or already existed.
949 /// </returns>
950 private IClientAPI AddNewClient(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint)
951 {
952 UUID agentID = useCircuitCode.CircuitCode.ID;
953 UUID sessionID = useCircuitCode.CircuitCode.SessionID;
954 uint circuitCode = useCircuitCode.CircuitCode.Code;
955
956 AuthenticateResponse sessionInfo;
957 if (IsClientAuthorized(useCircuitCode, out sessionInfo))
958 {
959 return AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo);
960 }
961 else
962 {
963 // Don't create circuits for unauthorized clients
964 m_log.WarnFormat(
965 "[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
966 useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint);
967
968 return null;
969 }
970 }
971
972 /// <summary>
973 /// Add a client. 992 /// Add a client.
974 /// </summary> 993 /// </summary>
975 /// <param name="circuitCode"></param> 994 /// <param name="circuitCode"></param>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index d2779ba..cfe7c9d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -44,7 +44,7 @@ namespace OpenMetaverse
44 /// This method is called when an incoming packet is received 44 /// This method is called when an incoming packet is received
45 /// </summary> 45 /// </summary>
46 /// <param name="buffer">Incoming packet buffer</param> 46 /// <param name="buffer">Incoming packet buffer</param>
47 protected abstract void PacketReceived(UDPPacketBuffer buffer); 47 public abstract void PacketReceived(UDPPacketBuffer buffer);
48 48
49 /// <summary>UDP port to bind to in server mode</summary> 49 /// <summary>UDP port to bind to in server mode</summary>
50 protected int m_udpPort; 50 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 9d37cdf..a575e36 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
@@ -25,6 +25,7 @@
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System;
28using System.Net; 29using System.Net;
29using log4net.Config; 30using log4net.Config;
30using Nini.Config; 31using Nini.Config;
@@ -32,6 +33,7 @@ using NUnit.Framework;
32using OpenMetaverse; 33using OpenMetaverse;
33using OpenMetaverse.Packets; 34using OpenMetaverse.Packets;
34using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.Framework.Scenes;
35using OpenSim.Tests.Common; 37using OpenSim.Tests.Common;
36using OpenSim.Tests.Common.Mock; 38using OpenSim.Tests.Common.Mock;
37 39
@@ -43,19 +45,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
43 [TestFixture] 45 [TestFixture]
44 public class BasicCircuitTests 46 public class BasicCircuitTests
45 { 47 {
46 [SetUp] 48 [TestFixtureSetUp]
47 public void Init() 49 public void FixtureInit()
48 { 50 {
49 try 51 // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread.
50 { 52 Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest;
51 XmlConfigurator.Configure();
52 }
53 catch
54 {
55 // I don't care, just leave log4net off
56 }
57 } 53 }
58 54
55 [TestFixtureTearDown]
56 public void TearDown()
57 {
58 // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple
59 // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression
60 // tests really shouldn't).
61 Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod;
62 }
63
59// /// <summary> 64// /// <summary>
60// /// Add a client for testing 65// /// Add a client for testing
61// /// </summary> 66// /// </summary>
@@ -78,54 +83,54 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
78// testLLUDPServer.LocalScene = scene; 83// testLLUDPServer.LocalScene = scene;
79// } 84// }
80 85
81 /// <summary> 86// /// <summary>
82 /// Set up a client for tests which aren't concerned with this process itself and where only one client is being 87// /// Set up a client for tests which aren't concerned with this process itself and where only one client is being
83 /// tested 88// /// tested
84 /// </summary> 89// /// </summary>
85 /// <param name="circuitCode"></param> 90// /// <param name="circuitCode"></param>
86 /// <param name="epSender"></param> 91// /// <param name="epSender"></param>
87 /// <param name="testLLUDPServer"></param> 92// /// <param name="testLLUDPServer"></param>
88 /// <param name="acm"></param> 93// /// <param name="acm"></param>
89 protected void AddClient( 94// protected void AddClient(
90 uint circuitCode, EndPoint epSender, TestLLUDPServer testLLUDPServer, AgentCircuitManager acm) 95// uint circuitCode, EndPoint epSender, TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
91 { 96// {
92 UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001"); 97// UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001");
93 UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002"); 98// UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002");
94 99//
95 AddClient(circuitCode, epSender, myAgentUuid, mySessionUuid, testLLUDPServer, acm); 100// AddClient(circuitCode, epSender, myAgentUuid, mySessionUuid, testLLUDPServer, acm);
96 } 101// }
97 102
98 /// <summary> 103// /// <summary>
99 /// Set up a client for tests which aren't concerned with this process itself 104// /// Set up a client for tests which aren't concerned with this process itself
100 /// </summary> 105// /// </summary>
101 /// <param name="circuitCode"></param> 106// /// <param name="circuitCode"></param>
102 /// <param name="epSender"></param> 107// /// <param name="epSender"></param>
103 /// <param name="agentId"></param> 108// /// <param name="agentId"></param>
104 /// <param name="sessionId"></param> 109// /// <param name="sessionId"></param>
105 /// <param name="testLLUDPServer"></param> 110// /// <param name="testLLUDPServer"></param>
106 /// <param name="acm"></param> 111// /// <param name="acm"></param>
107 protected void AddClient( 112// protected void AddClient(
108 uint circuitCode, EndPoint epSender, UUID agentId, UUID sessionId, 113// uint circuitCode, EndPoint epSender, UUID agentId, UUID sessionId,
109 TestLLUDPServer testLLUDPServer, AgentCircuitManager acm) 114// TestLLUDPServer testLLUDPServer, AgentCircuitManager acm)
110 { 115// {
111 AgentCircuitData acd = new AgentCircuitData(); 116// AgentCircuitData acd = new AgentCircuitData();
112 acd.AgentID = agentId; 117// acd.AgentID = agentId;
113 acd.SessionID = sessionId; 118// acd.SessionID = sessionId;
114 119//
115 UseCircuitCodePacket uccp = new UseCircuitCodePacket(); 120// UseCircuitCodePacket uccp = new UseCircuitCodePacket();
116 121//
117 UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock 122// UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
118 = new UseCircuitCodePacket.CircuitCodeBlock(); 123// = new UseCircuitCodePacket.CircuitCodeBlock();
119 uccpCcBlock.Code = circuitCode; 124// uccpCcBlock.Code = circuitCode;
120 uccpCcBlock.ID = agentId; 125// uccpCcBlock.ID = agentId;
121 uccpCcBlock.SessionID = sessionId; 126// uccpCcBlock.SessionID = sessionId;
122 uccp.CircuitCode = uccpCcBlock; 127// uccp.CircuitCode = uccpCcBlock;
123 128//
124 acm.AddNewCircuit(circuitCode, acd); 129// acm.AddNewCircuit(circuitCode, acd);
125 130//
126 testLLUDPServer.LoadReceive(uccp, epSender); 131// testLLUDPServer.LoadReceive(uccp, epSender);
127 testLLUDPServer.ReceiveData(null); 132// testLLUDPServer.ReceiveData(null);
128 } 133// }
129 134
130 /// <summary> 135 /// <summary>
131 /// Build an object name packet for test purposes 136 /// Build an object name packet for test purposes
@@ -144,54 +149,69 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
144 return onp; 149 return onp;
145 } 150 }
146 151
147// /// <summary> 152 /// <summary>
148// /// Test adding a client to the stack 153 /// Test adding a client to the stack
149// /// </summary> 154 /// </summary>
150// [Test] 155 [Test]
151// public void TestAddClient() 156 public void TestAddClient()
152// { 157 {
153// TestHelper.InMethod(); 158 TestHelpers.InMethod();
154// 159// XmlConfigurator.Configure();
155// uint myCircuitCode = 123456; 160
156// UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001"); 161 TestScene scene = SceneHelpers.SetupScene();
157// UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002"); 162 uint myCircuitCode = 123456;
158// 163 UUID myAgentUuid = TestHelpers.ParseTail(0x1);
159// TestLLUDPServer testLLUDPServer; 164 UUID mySessionUuid = TestHelpers.ParseTail(0x2);
160// TestLLPacketServer testLLPacketServer; 165 IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999);
161// AgentCircuitManager acm; 166
162// SetupStack(new MockScene(), out testLLUDPServer, out testLLPacketServer, out acm); 167 uint port = 0;
163// 168 AgentCircuitManager acm = scene.AuthenticateHandler;
164// AgentCircuitData acd = new AgentCircuitData(); 169
165// acd.AgentID = myAgentUuid; 170 TestLLUDPServer llUdpServer
166// acd.SessionID = mySessionUuid; 171 = new TestLLUDPServer(IPAddress.Any, ref port, 0, false, new IniConfigSource(), acm);
167// 172 llUdpServer.AddScene(scene);
168// UseCircuitCodePacket uccp = new UseCircuitCodePacket(); 173
169// 174 UseCircuitCodePacket uccp = new UseCircuitCodePacket();
170// UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock 175
171// = new UseCircuitCodePacket.CircuitCodeBlock(); 176 UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
172// uccpCcBlock.Code = myCircuitCode; 177 = new UseCircuitCodePacket.CircuitCodeBlock();
173// uccpCcBlock.ID = myAgentUuid; 178 uccpCcBlock.Code = myCircuitCode;
174// uccpCcBlock.SessionID = mySessionUuid; 179 uccpCcBlock.ID = myAgentUuid;
175// uccp.CircuitCode = uccpCcBlock; 180 uccpCcBlock.SessionID = mySessionUuid;
176// 181 uccp.CircuitCode = uccpCcBlock;
177// EndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999); 182
178// 183 byte[] uccpBytes = uccp.ToBytes();
179// testLLUDPServer.LoadReceive(uccp, testEp); 184 UDPPacketBuffer upb = new UDPPacketBuffer(testEp, uccpBytes.Length);
180// testLLUDPServer.ReceiveData(null); 185 upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor.
181// 186 Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);
182// // Circuit shouildn't exist since the circuit manager doesn't know about this circuit for authentication yet 187
183// Assert.IsFalse(testLLUDPServer.HasCircuit(myCircuitCode)); 188 llUdpServer.PacketReceived(upb);
184// 189
185// acm.AddNewCircuit(myCircuitCode, acd); 190 // Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet
186// 191 Assert.That(scene.GetScenePresence(myAgentUuid), Is.Null);
187// testLLUDPServer.LoadReceive(uccp, testEp); 192
188// testLLUDPServer.ReceiveData(null); 193 AgentCircuitData acd = new AgentCircuitData();
189// 194 acd.AgentID = myAgentUuid;
190// // Should succeed now 195 acd.SessionID = mySessionUuid;
191// Assert.IsTrue(testLLUDPServer.HasCircuit(myCircuitCode)); 196
192// Assert.IsFalse(testLLUDPServer.HasCircuit(101)); 197 acm.AddNewCircuit(myCircuitCode, acd);
193// } 198
194// 199 llUdpServer.PacketReceived(upb);
200
201 // Should succeed now
202 ScenePresence sp = scene.GetScenePresence(myAgentUuid);
203 Assert.That(sp.UUID, Is.EqualTo(myAgentUuid));
204
205 Assert.That(llUdpServer.PacketsSent.Count, Is.EqualTo(1));
206
207 Packet packet = llUdpServer.PacketsSent[0];
208 Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket)));
209
210 PacketAckPacket ackPacket = packet as PacketAckPacket;
211 Assert.That(ackPacket.Packets.Length, Is.EqualTo(1));
212 Assert.That(ackPacket.Packets[0].ID, Is.EqualTo(0));
213 }
214
195// /// <summary> 215// /// <summary>
196// /// Test removing a client from the stack 216// /// Test removing a client from the stack
197// /// </summary> 217// /// </summary>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs
index dd7999a..0302385 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs
@@ -36,107 +36,106 @@ using OpenSim.Framework;
36namespace OpenSim.Region.ClientStack.LindenUDP.Tests 36namespace OpenSim.Region.ClientStack.LindenUDP.Tests
37{ 37{
38 /// <summary> 38 /// <summary>
39 /// This class enables synchronous testing of the LLUDPServer by allowing us to load our own data into the end 39 /// This class enables regression testing of the LLUDPServer by allowing us to intercept outgoing data.
40 /// receive event
41 /// </summary> 40 /// </summary>
42 public class TestLLUDPServer : LLUDPServer 41 public class TestLLUDPServer : LLUDPServer
43 { 42 {
43 public List<Packet> PacketsSent { get; private set; }
44
44 public TestLLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) 45 public TestLLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
45 : base(listenIP, ref port, proxyPortOffsetParm, allow_alternate_port, configSource, circuitManager) 46 : base(listenIP, ref port, proxyPortOffsetParm, allow_alternate_port, configSource, circuitManager)
46 {}
47
48 /// <summary>
49 /// The chunks of data to pass to the LLUDPServer when it calls EndReceive
50 /// </summary>
51 protected Queue<ChunkSenderTuple> m_chunksToLoad = new Queue<ChunkSenderTuple>();
52
53// protected override void BeginReceive()
54// {
55// if (m_chunksToLoad.Count > 0 && m_chunksToLoad.Peek().BeginReceiveException)
56// {
57// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue();
58// reusedEpSender = tuple.Sender;
59// throw new SocketException();
60// }
61// }
62
63// protected override bool EndReceive(out int numBytes, IAsyncResult result, ref EndPoint epSender)
64// {
65// numBytes = 0;
66//
67// //m_log.Debug("Queue size " + m_chunksToLoad.Count);
68//
69// if (m_chunksToLoad.Count <= 0)
70// return false;
71//
72// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue();
73// RecvBuffer = tuple.Data;
74// numBytes = tuple.Data.Length;
75// epSender = tuple.Sender;
76//
77// return true;
78// }
79
80// public override void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode)
81// {
82// // Don't do anything just yet
83// }
84
85 /// <summary>
86 /// Signal that this chunk should throw an exception on Socket.BeginReceive()
87 /// </summary>
88 /// <param name="epSender"></param>
89 public void LoadReceiveWithBeginException(EndPoint epSender)
90 {
91 ChunkSenderTuple tuple = new ChunkSenderTuple(epSender);
92 tuple.BeginReceiveException = true;
93 m_chunksToLoad.Enqueue(tuple);
94 }
95
96 /// <summary>
97 /// Load some data to be received by the LLUDPServer on the next receive call
98 /// </summary>
99 /// <param name="data"></param>
100 /// <param name="epSender"></param>
101 public void LoadReceive(byte[] data, EndPoint epSender)
102 { 47 {
103 m_chunksToLoad.Enqueue(new ChunkSenderTuple(data, epSender)); 48 PacketsSent = new List<Packet>();
104 } 49 }
105 50
106 /// <summary> 51 public override void SendAckImmediate(IPEndPoint remoteEndpoint, PacketAckPacket ack)
107 /// Load a packet to be received by the LLUDPServer on the next receive call
108 /// </summary>
109 /// <param name="packet"></param>
110 public void LoadReceive(Packet packet, EndPoint epSender)
111 { 52 {
112 LoadReceive(packet.ToBytes(), epSender); 53 PacketsSent.Add(ack);
113 } 54 }
114 55
115 /// <summary> 56 public override void SendPacket(
116 /// Calls the protected asynchronous result method. This fires out all data chunks currently queued for send 57 LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting, UnackedPacketMethod method)
117 /// </summary>
118 /// <param name="result"></param>
119 public void ReceiveData(IAsyncResult result)
120 { 58 {
121 // Doesn't work the same way anymore 59 PacketsSent.Add(packet);
122// while (m_chunksToLoad.Count > 0)
123// OnReceivedData(result);
124 } 60 }
125
126 /// <summary>
127 /// Has a circuit with the given code been established?
128 /// </summary>
129 /// <param name="circuitCode"></param>
130 /// <returns></returns>
131 public bool HasCircuit(uint circuitCode)
132 {
133// lock (clientCircuits_reverse)
134// {
135// return clientCircuits_reverse.ContainsKey(circuitCode);
136// }
137 61
138 return true; 62//// /// <summary>
139 } 63//// /// The chunks of data to pass to the LLUDPServer when it calls EndReceive
64//// /// </summary>
65//// protected Queue<ChunkSenderTuple> m_chunksToLoad = new Queue<ChunkSenderTuple>();
66//
67//// protected override void BeginReceive()
68//// {
69//// if (m_chunksToLoad.Count > 0 && m_chunksToLoad.Peek().BeginReceiveException)
70//// {
71//// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue();
72//// reusedEpSender = tuple.Sender;
73//// throw new SocketException();
74//// }
75//// }
76//
77//// protected override bool EndReceive(out int numBytes, IAsyncResult result, ref EndPoint epSender)
78//// {
79//// numBytes = 0;
80////
81//// //m_log.Debug("Queue size " + m_chunksToLoad.Count);
82////
83//// if (m_chunksToLoad.Count <= 0)
84//// return false;
85////
86//// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue();
87//// RecvBuffer = tuple.Data;
88//// numBytes = tuple.Data.Length;
89//// epSender = tuple.Sender;
90////
91//// return true;
92//// }
93//
94//// public override void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode)
95//// {
96//// // Don't do anything just yet
97//// }
98//
99// /// <summary>
100// /// Signal that this chunk should throw an exception on Socket.BeginReceive()
101// /// </summary>
102// /// <param name="epSender"></param>
103// public void LoadReceiveWithBeginException(EndPoint epSender)
104// {
105// ChunkSenderTuple tuple = new ChunkSenderTuple(epSender);
106// tuple.BeginReceiveException = true;
107// m_chunksToLoad.Enqueue(tuple);
108// }
109//
110// /// <summary>
111// /// Load some data to be received by the LLUDPServer on the next receive call
112// /// </summary>
113// /// <param name="data"></param>
114// /// <param name="epSender"></param>
115// public void LoadReceive(byte[] data, EndPoint epSender)
116// {
117// m_chunksToLoad.Enqueue(new ChunkSenderTuple(data, epSender));
118// }
119//
120// /// <summary>
121// /// Load a packet to be received by the LLUDPServer on the next receive call
122// /// </summary>
123// /// <param name="packet"></param>
124// public void LoadReceive(Packet packet, EndPoint epSender)
125// {
126// LoadReceive(packet.ToBytes(), epSender);
127// }
128//
129// /// <summary>
130// /// Calls the protected asynchronous result method. This fires out all data chunks currently queued for send
131// /// </summary>
132// /// <param name="result"></param>
133// public void ReceiveData(IAsyncResult result)
134// {
135// // Doesn't work the same way anymore
136//// while (m_chunksToLoad.Count > 0)
137//// OnReceivedData(result);
138// }
140 } 139 }
141 140
142 /// <summary> 141 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
index 43cfd80..eda085f 100644
--- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -60,7 +60,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation
60 public int m_animTickJump; // ScenePresence has to see this to control +Z force 60 public int m_animTickJump; // ScenePresence has to see this to control +Z force
61 public bool m_jumping = false; 61 public bool m_jumping = false;
62 public float m_jumpVelocity = 0f; 62 public float m_jumpVelocity = 0f;
63 private int m_landing = 0; 63// private int m_landing = 0;
64 public bool Falling 64 public bool Falling
65 { 65 {
66 get { return m_falling; } 66 get { return m_falling; }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index a51fca2..684745f 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2609,21 +2609,14 @@ namespace OpenSim.Region.Framework.Scenes
2609 2609
2610 #region Add/Remove Avatar Methods 2610 #region Add/Remove Avatar Methods
2611 2611
2612 /// <summary>
2613 /// Add a new client and create a child scene presence for it.
2614 /// </summary>
2615 /// <param name="client"></param>
2616 /// <param name="type">The type of agent to add.</param>
2617 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) 2612 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type)
2618 { 2613 {
2614 // Validation occurs in LLUDPServer
2619 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); 2615 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
2620 bool vialogin = false;
2621
2622 if (aCircuit == null) // no good, didn't pass NewUserConnection successfully
2623 return null;
2624 2616
2625 vialogin = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0 || 2617 bool vialogin
2626 (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0; 2618 = (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0
2619 || (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaLogin) != 0;
2627 2620
2628 CheckHeartbeat(); 2621 CheckHeartbeat();
2629 ScenePresence presence; 2622 ScenePresence presence;
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 2748a75..21e3d3f 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -2397,8 +2397,6 @@ namespace OpenSim.Region.Framework.Scenes
2397 2397
2398 #region Overridden Methods 2398 #region Overridden Methods
2399 2399
2400 private bool sendingPrims = false;
2401
2402 public override void Update() 2400 public override void Update()
2403 { 2401 {
2404 const float ROTATION_TOLERANCE = 0.01f; 2402 const float ROTATION_TOLERANCE = 0.01f;
@@ -2569,7 +2567,7 @@ namespace OpenSim.Region.Framework.Scenes
2569 } 2567 }
2570 2568
2571 // This agent just became root. We are going to tell everyone about it. The process of 2569 // This agent just became root. We are going to tell everyone about it. The process of
2572 // getting other avatars information was initiated in the constructor... don't do it 2570 // getting other avatars information was initiated elsewhere immediately after the child circuit connected... don't do it
2573 // again here... this comes after the cached appearance check because the avatars 2571 // again here... this comes after the cached appearance check because the avatars
2574 // appearance goes into the avatar update packet 2572 // appearance goes into the avatar update packet
2575 SendAvatarDataToAllAgents(); 2573 SendAvatarDataToAllAgents();
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 0000000..a3f681d
--- /dev/null
+++ b/bin/OpenSim.Region.ClientStack.LindenUDP.Tests.dll.config
@@ -0,0 +1,33 @@
1<?xml version="1.0" encoding="utf-8" ?>
2<configuration>
3 <configSections>
4 <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
5 </configSections>
6 <runtime>
7 <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
8 <dependentAssembly>
9 <assemblyIdentity name="nunit.framework" publicKeyToken="96d09a1eb7f44a77" culture="Neutral" />
10 <bindingRedirect oldVersion="2.0.6.0" newVersion="2.4.6.0" />
11 <bindingRedirect oldVersion="2.1.4.0" newVersion="2.4.6.0" />
12 <bindingRedirect oldVersion="2.2.8.0" newVersion="2.4.6.0" />
13 </dependentAssembly>
14 </assemblyBinding>
15 </runtime>
16 <log4net>
17 <!-- A1 is set to be a ConsoleAppender -->
18 <appender name="A1" type="log4net.Appender.ConsoleAppender">
19
20 <!-- A1 uses PatternLayout -->
21 <layout type="log4net.Layout.PatternLayout">
22 <!-- Print the date in ISO 8601 format -->
23 <conversionPattern value="%date [%thread] %-5level %logger %ndc - %message%newline" />
24 </layout>
25 </appender>
26
27 <!-- Set root logger level to DEBUG and its only appender to A1 -->
28 <root>
29 <level value="DEBUG" />
30 <appender-ref ref="A1" />
31 </root>
32 </log4net>
33</configuration>