diff --git a/XenAdminTests/UnitTests/ExceptionSerializationTest.cs b/XenAdminTests/UnitTests/ExceptionSerializationTest.cs new file mode 100644 index 000000000..a20f412e7 --- /dev/null +++ b/XenAdminTests/UnitTests/ExceptionSerializationTest.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.Serialization.Formatters.Binary; +using System.Text; +using NUnit.Framework; +using XenAPI; + +namespace XenAdminTests.UnitTests +{ + [TestFixture, Category(TestCategories.Unit)] + class ExceptionSerializationTest + { + private List errorDescriptions = new List { "AN_ERROR_CODEE", "Error description", "Some text"}; + private List friendlyErrorDescriptions = new List { "CANNOT_ADD_VLAN_TO_BOND_SLAVE", "Cannot add..."}; + private string errorText = "An Error has occured"; + + [Test] + public void TestEmptyFailure() + { + var failure = new Failure(); + TestFailureSeralization(failure); + } + + [Test] + public void TestInnerExceptionFailure() + { + var failure = new Failure(errorText, new Exception(errorText)); + TestFailureSeralization(failure); + } + + [Test] + public void TestSimpleFailure() + { + var failure = new Failure(errorText); + TestFailureSeralization(failure); + } + + [Test] + public void TestFailureWithErrorDescriptions() + { + var failure = new Failure(errorDescriptions); + TestFailureSeralization(failure); + } + + [Test] + public void TestFailureWithFriendlyErrorNames() + { + var failure = new Failure(friendlyErrorDescriptions); + TestFailureSeralization(failure); + } + + private static void TestFailureSeralization(Failure failure) + { + Failure deserializedFailure; + + // Serialize and de-serialize with a BinaryFormatter + BinaryFormatter bf = new BinaryFormatter(); + using (MemoryStream ms = new MemoryStream()) + { + bf.Serialize(ms, failure); + ms.Seek(0, 0); + deserializedFailure = (Failure)(bf.Deserialize(ms)); + } + + // Check that properties are preserved + Assert.AreEqual(failure.Message, deserializedFailure.Message, "Message is different"); + Assert.AreEqual(failure.ShortMessage, deserializedFailure.ShortMessage, "ShortMessage is different"); + if (failure.ErrorDescription != null) + { + Assert.IsNotNull(deserializedFailure.ErrorDescription); + Assert.AreEqual(failure.ErrorDescription.Count, deserializedFailure.ErrorDescription.Count, + "ErrorDescription count is different"); + for (int i = 0; i < failure.ErrorDescription.Count; i++) + { + Assert.AreEqual(failure.ErrorDescription[i], deserializedFailure.ErrorDescription[i], + string.Format("ErrorDescription[{0}] count is different", i)); + } + } + else + { + Assert.IsNull(deserializedFailure.ErrorDescription); + } + + if (failure.InnerException != null) + { + Assert.IsNotNull(deserializedFailure.InnerException); + Assert.AreEqual(failure.InnerException.Message, deserializedFailure.InnerException.Message, "Message is different"); + } + else + { + Assert.IsNull(deserializedFailure.InnerException); + } + + } + + [Test] + public void TestTooManyRedirectsException() + { + var exception = new HTTP.TooManyRedirectsException(2, new Uri("http://www.someurl.com")); + HTTP.TooManyRedirectsException deserializedException; + + // Serialize and de-serialize with a BinaryFormatter + BinaryFormatter bf = new BinaryFormatter(); + using (MemoryStream ms = new MemoryStream()) + { + bf.Serialize(ms, exception); + ms.Seek(0, 0); + deserializedException = (HTTP.TooManyRedirectsException)(bf.Deserialize(ms)); + } + + // Check that properties are preserved + Assert.AreEqual(exception.Message, deserializedException.Message, "Message is different"); + } + + [Test] + public void TestBadServerResponseException() + { + var exception = new HTTP.BadServerResponseException(); + HTTP.BadServerResponseException deserializedException; + + // Serialize and de-serialize with a BinaryFormatter + BinaryFormatter bf = new BinaryFormatter(); + using (MemoryStream ms = new MemoryStream()) + { + bf.Serialize(ms, exception); + ms.Seek(0, 0); + deserializedException = (HTTP.BadServerResponseException)(bf.Deserialize(ms)); + } + + // Check that properties are preserved + Assert.AreEqual(exception.Message, deserializedException.Message, "Message is different"); + } + + [Test] + public void TestCancelledException() + { + var exception = new HTTP.CancelledException(); + HTTP.CancelledException deserializedException; + + // Serialize and de-serialize with a BinaryFormatter + BinaryFormatter bf = new BinaryFormatter(); + using (MemoryStream ms = new MemoryStream()) + { + bf.Serialize(ms, exception); + ms.Seek(0, 0); + deserializedException = (HTTP.CancelledException)(bf.Deserialize(ms)); + } + + // Check that properties are preserved + Assert.AreEqual(exception.Message, deserializedException.Message, "Message is different"); + } + + [Test] + public void TestEventNextBlockedException() + { + var exception = new EventNextBlockedException(); + EventNextBlockedException deserializedException; + + // Serialize and de-serialize with a BinaryFormatter + BinaryFormatter bf = new BinaryFormatter(); + using (MemoryStream ms = new MemoryStream()) + { + bf.Serialize(ms, exception); + ms.Seek(0, 0); + deserializedException = (EventNextBlockedException)(bf.Deserialize(ms)); + } + + // Check that properties are preserved + Assert.AreEqual(exception.Message, deserializedException.Message, "Message is different"); + } + } +} diff --git a/XenAdminTests/XenAdminTests.csproj b/XenAdminTests/XenAdminTests.csproj index 11e2820a9..e55bf927a 100644 --- a/XenAdminTests/XenAdminTests.csproj +++ b/XenAdminTests/XenAdminTests.csproj @@ -64,6 +64,7 @@ + diff --git a/XenModel/XenAPI/Failure.cs b/XenModel/XenAPI/Failure.cs index f704a86cd..c5e3a283d 100644 --- a/XenModel/XenAPI/Failure.cs +++ b/XenModel/XenAPI/Failure.cs @@ -35,9 +35,11 @@ using System.Resources; using System.Collections; using System.Text.RegularExpressions; using System.Xml; +using System.Runtime.Serialization; namespace XenAPI { + [Serializable] public partial class Failure : Exception { public const string INTERNAL_ERROR = "INTERNAL_ERROR"; @@ -73,10 +75,27 @@ namespace XenAPI } } + public Failure() : base() { } + public Failure(params string[] err) : this(new List(err)) {} + public Failure(string message, Exception exception) + : base(message, exception) + { + errorDescription = new List() { message }; + Setup(); + } + + protected Failure(SerializationInfo info, StreamingContext context) + : base(info, context) + { + errorDescription = (List)info.GetValue("errorDescription", typeof(List)); + errorText = info.GetString("errorText"); + shortError = info.GetString("shortError"); + } + public Failure(List errDescription) { errorDescription = errDescription; @@ -207,5 +226,19 @@ namespace XenAPI { return Message; } + + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + { + throw new ArgumentNullException("info"); + } + + info.AddValue("errorDescription", errorDescription, typeof(List)); + info.AddValue("errorText", errorText); + info.AddValue("shortError", shortError); + + base.GetObjectData(info, context); + } } } diff --git a/XenModel/XenAPI/HTTP.cs b/XenModel/XenAPI/HTTP.cs index 5cf89f8bf..0de4e62b3 100644 --- a/XenModel/XenAPI/HTTP.cs +++ b/XenModel/XenAPI/HTTP.cs @@ -36,11 +36,13 @@ using System.Net.Sockets; using System.Text; using System.Net.Security; using System.Security.Cryptography.X509Certificates; +using System.Runtime.Serialization; namespace XenAPI { public partial class HTTP { + [Serializable] public class TooManyRedirectsException : Exception { private readonly int redirect; @@ -51,17 +53,56 @@ namespace XenAPI this.redirect = redirect; this.uri = uri; } + + public TooManyRedirectsException() : base() { } + + public TooManyRedirectsException(string message) : base(message) { } + + public TooManyRedirectsException(string message, Exception exception) : base(message, exception) { } + + protected TooManyRedirectsException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + redirect = info.GetInt32("redirect"); + uri = (Uri)info.GetValue("uri", typeof(Uri)); + } + + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + { + throw new ArgumentNullException("info"); + } + + info.AddValue("redirect", redirect); + info.AddValue("uri", uri, typeof(Uri)); + + base.GetObjectData(info, context); + } } + [Serializable] public class BadServerResponseException : Exception { - public BadServerResponseException(string msg) - : base(msg) - { } + public BadServerResponseException() : base() { } + + public BadServerResponseException(string message) : base(message) { } + + public BadServerResponseException(string message, Exception exception) : base(message, exception) { } + + protected BadServerResponseException(SerializationInfo info, StreamingContext context) : base(info, context) { } } + [Serializable] public class CancelledException : Exception { + public CancelledException() : base() { } + + public CancelledException(string message) : base(message) { } + + public CancelledException(string message, Exception exception) : base(message, exception) { } + + protected CancelledException(SerializationInfo info, StreamingContext context) : base(info, context) { } } public delegate bool FuncBool(); diff --git a/XenModel/XenAPI/XenObjectDownloader.cs b/XenModel/XenAPI/XenObjectDownloader.cs index 1b4604321..be94369c1 100644 --- a/XenModel/XenAPI/XenObjectDownloader.cs +++ b/XenModel/XenAPI/XenObjectDownloader.cs @@ -34,11 +34,22 @@ using System.Collections; using System.Collections.Generic; using System.IO; using System.Net; +using System.Runtime.Serialization; using XenAdmin.Core; namespace XenAPI { - public class EventNextBlockedException : Exception { } + [Serializable] + public class EventNextBlockedException : Exception + { + public EventNextBlockedException() : base() { } + + public EventNextBlockedException(string message) : base(message) { } + + public EventNextBlockedException(string message, Exception exception) : base(message, exception) { } + + protected EventNextBlockedException(SerializationInfo info, StreamingContext context) : base(info, context) { } + } public static class XenObjectDownloader {