Переглянути джерело

Added tests and some slashdocs for ForwardedPortStatus.

drieseng 9 роки тому
батько
коміт
59923ceca0

+ 13 - 1
src/Renci.SshNet.Tests.NET35/Renci.SshNet.Tests.NET35.csproj

@@ -65,6 +65,18 @@
     <Compile Include="..\..\test\Renci.SshNet.Shared.Tests\Abstractions\ThreadAbstraction_ExecuteThread.cs">
       <Link>Classes\Abstraction\ThreadAbstraction_ExecuteThread.cs</Link>
     </Compile>
+    <Compile Include="..\..\test\Renci.SshNet.Shared.Tests\ForwardedPortStatusTest_Started.cs">
+      <Link>Classes\ForwardedPortStatusTest_Started.cs</Link>
+    </Compile>
+    <Compile Include="..\..\test\Renci.SshNet.Shared.Tests\ForwardedPortStatusTest_Starting.cs">
+      <Link>Classes\ForwardedPortStatusTest_Starting.cs</Link>
+    </Compile>
+    <Compile Include="..\..\test\Renci.SshNet.Shared.Tests\ForwardedPortStatusTest_Stopped.cs">
+      <Link>Classes\ForwardedPortStatusTest_Stopped.cs</Link>
+    </Compile>
+    <Compile Include="..\..\test\Renci.SshNet.Shared.Tests\ForwardedPortStatusTest_Stopping.cs">
+      <Link>Classes\ForwardedPortStatusTest_Stopping.cs</Link>
+    </Compile>
     <Compile Include="..\Renci.SshNet.Tests\Classes\Channels\ChannelDirectTcpipTest.cs">
       <Link>Classes\Channels\ChannelDirectTcpipTest.cs</Link>
     </Compile>
@@ -1286,7 +1298,7 @@
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ProjectExtensions>
     <VisualStudio>
-      <UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="c45379b9-17b1-4e89-bc2e-6d41726413e8" />
+      <UserProperties ProjectLinkReference="c45379b9-17b1-4e89-bc2e-6d41726413e8" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
     </VisualStudio>
   </ProjectExtensions>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 

+ 12 - 0
src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj

@@ -73,6 +73,18 @@
     <Compile Include="..\..\test\Renci.SshNet.Shared.Tests\Abstractions\ThreadAbstraction_ExecuteThread.cs">
       <Link>Classes\Abstractions\ThreadAbstraction_ExecuteThread.cs</Link>
     </Compile>
+    <Compile Include="..\..\test\Renci.SshNet.Shared.Tests\ForwardedPortStatusTest_Started.cs">
+      <Link>Classes\ForwardedPortStatusTest_Started.cs</Link>
+    </Compile>
+    <Compile Include="..\..\test\Renci.SshNet.Shared.Tests\ForwardedPortStatusTest_Starting.cs">
+      <Link>Classes\ForwardedPortStatusTest_Starting.cs</Link>
+    </Compile>
+    <Compile Include="..\..\test\Renci.SshNet.Shared.Tests\ForwardedPortStatusTest_Stopped.cs">
+      <Link>Classes\ForwardedPortStatusTest_Stopped.cs</Link>
+    </Compile>
+    <Compile Include="..\..\test\Renci.SshNet.Shared.Tests\ForwardedPortStatusTest_Stopping.cs">
+      <Link>Classes\ForwardedPortStatusTest_Stopping.cs</Link>
+    </Compile>
     <Compile Include="..\..\test\Renci.SshNet.Shared.Tests\SshMessageFactoryTest.cs">
       <Link>Classes\SshMessageFactoryTest.cs</Link>
     </Compile>

+ 48 - 15
src/Renci.SshNet/ForwardedPortStatus.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Globalization;
 using System.Threading;
 
 namespace Renci.SshNet
@@ -19,36 +20,36 @@ namespace Renci.SshNet
             _name = name;
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object other)
         {
-            if (ReferenceEquals(obj, null))
+            if (ReferenceEquals(other, null))
                 return false;
 
-            if (ReferenceEquals(this, obj))
+            if (ReferenceEquals(this, other))
                 return true;
 
-            var forwardedPortStatus = obj as ForwardedPortStatus;
+            var forwardedPortStatus = other as ForwardedPortStatus;
             if (forwardedPortStatus == null)
                 return false;
 
             return forwardedPortStatus._value == _value;
         }
 
-        public static bool operator ==(ForwardedPortStatus c1, ForwardedPortStatus c2)
+        public static bool operator ==(ForwardedPortStatus left, ForwardedPortStatus right)
         {
             // check if lhs is null
-            if (ReferenceEquals(c1, null))
+            if (ReferenceEquals(left, null))
             {
                 // check if both lhs and rhs are null
-                return (ReferenceEquals(c2, null));
+                return (ReferenceEquals(right, null));
             }
 
-            return c1.Equals(c2);
+            return left.Equals(right);
         }
 
-        public static bool operator !=(ForwardedPortStatus c1, ForwardedPortStatus c2)
+        public static bool operator !=(ForwardedPortStatus left, ForwardedPortStatus right)
         {
-            return !(c1==c2);
+            return !(left==right);
         }
 
         public override int GetHashCode()
@@ -61,13 +62,25 @@ namespace Renci.SshNet
             return _name;
         }
 
+        /// <summary>
+        /// Returns a value indicating whether <paramref name="status"/> has been changed to <see cref="Stopping"/>.
+        /// </summary>
+        /// <param name="status">The status to transition from.</param>
+        /// <returns>
+        /// <c>true</c> if <paramref name="status"/> has been changed to <see cref="Stopping"/>; otherwise, <c>false</c>.
+        /// </returns>
+        /// <exception cref="InvalidOperationException">Cannot transition <paramref name="status"/> to <see cref="Stopping"/>.</exception>
+        /// <remarks>
+        /// While a transition from <see cref="Stopped"/> to <see cref="Stopping"/> is not possible, this method will
+        /// return <c>false</c> for any such attempts.  This is related to concurrency.
+        /// </remarks>
         public static bool ToStopping(ref ForwardedPortStatus status)
         {
             // attempt to transition from Started to Stopping
             var previousStatus = Interlocked.CompareExchange(ref status, Stopping, Started);
             if (previousStatus == Stopping || previousStatus == Stopped)
             {
-                // status is already Stopping or Stopped, so no transition to Stopped is necessary
+                // status is already Stopping or Stopped, so no transition to Stopping is necessary
                 return false;
             }
 
@@ -79,14 +92,32 @@ namespace Renci.SshNet
             previousStatus = Interlocked.CompareExchange(ref status, Stopping, Starting);
             if (previousStatus == Stopping || previousStatus == Stopped)
             {
-                // status is already Stopping or Stopped, so no transition to Stopped is necessary
+                // status is already Stopping or Stopped, so no transition to Stopping is necessary
                 return false;
             }
 
             // we've successfully transitioned from Starting to Stopping
-            return status == Stopping;
+            if (status == Stopping)
+                return true;
+
+            // there's no valid transition from status to Stopping
+            throw new InvalidOperationException(string.Format("Forwarded port cannot transition from '{0}' to '{1}'.",
+                                                              previousStatus,
+                                                              Stopping));
         }
 
+        /// <summary>
+        /// Returns a value indicating whether <paramref name="status"/> has been changed to <see cref="Starting"/>.
+        /// </summary>
+        /// <param name="status">The status to transition from.</param>
+        /// <returns>
+        /// <c>true</c> if <paramref name="status"/> has been changed to <see cref="Starting"/>; otherwise, <c>false</c>.
+        /// </returns>
+        /// <exception cref="InvalidOperationException">Cannot transition <paramref name="status"/> to <see cref="Starting"/>.</exception>
+        /// <remarks>
+        /// While a transition from <see cref="Started"/> to <see cref="Starting"/> is not possible, this method will
+        /// return <c>false</c> for any such attempts.  This is related to concurrency.
+        /// </remarks>
         public static bool ToStarting(ref ForwardedPortStatus status)
         {
             // attemp to transition from Stopped to Starting
@@ -101,8 +132,10 @@ namespace Renci.SshNet
             if (status == Starting)
                 return true;
 
-            // there's no valid transition from Stopping to Starting
-            throw new InvalidOperationException("Forwarded port is stopping.");
+            // there's no valid transition from status to Starting
+            throw new InvalidOperationException(string.Format("Forwarded port cannot transition from '{0}' to '{1}'.",
+                                                              previousStatus,
+                                                              Starting));
         }
     }
 }

+ 243 - 0
test/Renci.SshNet.Shared.Tests/ForwardedPortStatusTest_Started.cs

@@ -0,0 +1,243 @@
+using System;
+#if SILVERLIGHT
+using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
+#else
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+#endif
+
+namespace Renci.SshNet.Tests
+{
+    [TestClass]
+    public class ForwardedPortStatusTest_Started
+    {
+        [TestMethod]
+        public void ToStopping_ShouldReturnTrueAndChangeStatusToStopping()
+        {
+            var status = ForwardedPortStatus.Started;
+
+            var actual = ForwardedPortStatus.ToStopping(ref status);
+
+            Assert.IsTrue(actual);
+            Assert.AreEqual(ForwardedPortStatus.Stopping, status);
+        }
+
+        [TestMethod]
+        public void ToStarting_ShouldReturnFalseAndNotChangeStatus()
+        {
+            var status = ForwardedPortStatus.Started;
+
+            var actual = ForwardedPortStatus.ToStarting(ref status);
+
+            Assert.IsFalse(actual);
+            Assert.AreEqual(ForwardedPortStatus.Started, status);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsNull()
+        {
+            const ForwardedPortStatus other = null;
+
+            var actual = ForwardedPortStatus.Started.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsNotInstanceOfForwardedPortStatus()
+        {
+            var other = new object();
+
+            var actual = ForwardedPortStatus.Started.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsStopped()
+        {
+            var other = ForwardedPortStatus.Stopped;
+
+            var actual = ForwardedPortStatus.Started.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsStopping()
+        {
+            var other = ForwardedPortStatus.Stopping;
+
+            var actual = ForwardedPortStatus.Started.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnTrueWhenOtherIsStarted()
+        {
+            var other = ForwardedPortStatus.Started;
+
+            var actual = ForwardedPortStatus.Started.Equals(other);
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsStarting()
+        {
+            var other = ForwardedPortStatus.Starting;
+
+            var actual = ForwardedPortStatus.Started.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenRightIsNull()
+        {
+            var left = ForwardedPortStatus.Started;
+            const ForwardedPortStatus right = null;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenLeftIsNull()
+        {
+            const ForwardedPortStatus left = null;
+            var right = ForwardedPortStatus.Started;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenLeftIsStartedAndRightIsStopped()
+        {
+            var left = ForwardedPortStatus.Started;
+            var right = ForwardedPortStatus.Stopped;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenLeftIsStartedAndRightIsStopping()
+        {
+            var left = ForwardedPortStatus.Started;
+            var right = ForwardedPortStatus.Stopping;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenLeftIsStartedAndRightIsStarted()
+        {
+            var left = ForwardedPortStatus.Started;
+            var right = ForwardedPortStatus.Started;
+
+            var actual = left == right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenLeftIsStartedAndRightIsStarting()
+        {
+            var left = ForwardedPortStatus.Started;
+            var right = ForwardedPortStatus.Starting;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenRightIsNull()
+        {
+            var left = ForwardedPortStatus.Started;
+            const ForwardedPortStatus right = null;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenLeftIsNull()
+        {
+            const ForwardedPortStatus left = null;
+            var right = ForwardedPortStatus.Started;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenLeftIsStartedAndRightIsStopped()
+        {
+            var left = ForwardedPortStatus.Started;
+            var right = ForwardedPortStatus.Stopped;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenLeftIsStartedAndRightIsStopping()
+        {
+            var left = ForwardedPortStatus.Started;
+            var right = ForwardedPortStatus.Stopping;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenLeftIsStartedAndRightIsStarted()
+        {
+            var left = ForwardedPortStatus.Started;
+            var right = ForwardedPortStatus.Started;
+
+            var actual = left != right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenLeftIsStartedAndRightIsStarting()
+        {
+            var left = ForwardedPortStatus.Started;
+            var right = ForwardedPortStatus.Starting;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void GetHashCodeShouldReturnThree()
+        {
+            var actual = ForwardedPortStatus.Started.GetHashCode();
+
+            Assert.AreEqual(3, actual);
+        }
+
+        [TestMethod]
+        public void ToStringShouldReturnStarted()
+        {
+            var actual = ForwardedPortStatus.Started.ToString();
+
+            Assert.AreEqual("Started", actual);
+        }
+    }
+}

+ 243 - 0
test/Renci.SshNet.Shared.Tests/ForwardedPortStatusTest_Starting.cs

@@ -0,0 +1,243 @@
+using System;
+#if SILVERLIGHT
+using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
+#else
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+#endif
+
+namespace Renci.SshNet.Tests
+{
+    [TestClass]
+    public class ForwardedPortStatusTest_Starting
+    {
+        [TestMethod]
+        public void ToStopping_ShouldReturnTrueAndChangeStatusToStopping()
+        {
+            var status = ForwardedPortStatus.Starting;
+
+            var actual = ForwardedPortStatus.ToStopping(ref status);
+
+            Assert.IsTrue(actual);
+            Assert.AreEqual(ForwardedPortStatus.Stopping, status);
+        }
+
+        [TestMethod]
+        public void ToStarting_ShouldReturnFalseAndNotChangeStatus()
+        {
+            var status = ForwardedPortStatus.Starting;
+
+            var actual = ForwardedPortStatus.ToStarting(ref status);
+
+            Assert.IsFalse(actual);
+            Assert.AreEqual(ForwardedPortStatus.Starting, status);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsNull()
+        {
+            const ForwardedPortStatus other = null;
+
+            var actual = ForwardedPortStatus.Starting.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsNotInstanceOfForwardedPortStatus()
+        {
+            var other = new object();
+
+            var actual = ForwardedPortStatus.Starting.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsStopped()
+        {
+            var other = ForwardedPortStatus.Stopped;
+
+            var actual = ForwardedPortStatus.Starting.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsStopping()
+        {
+            var other = ForwardedPortStatus.Stopping;
+
+            var actual = ForwardedPortStatus.Starting.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsStarted()
+        {
+            var other = ForwardedPortStatus.Started;
+
+            var actual = ForwardedPortStatus.Starting.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnTrueWhenOtherIsStarting()
+        {
+            var other = ForwardedPortStatus.Starting;
+
+            var actual = ForwardedPortStatus.Starting.Equals(other);
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenRightIsNull()
+        {
+            var left = ForwardedPortStatus.Starting;
+            const ForwardedPortStatus right = null;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenLeftIsNull()
+        {
+            const ForwardedPortStatus left = null;
+            var right = ForwardedPortStatus.Starting;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenLeftIsStartingAndRightIsStopped()
+        {
+            var left = ForwardedPortStatus.Starting;
+            var right = ForwardedPortStatus.Stopped;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenLeftIsStartingAndRightIsStopping()
+        {
+            var left = ForwardedPortStatus.Starting;
+            var right = ForwardedPortStatus.Stopping;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenLeftIsStartingAndRightIsStarted()
+        {
+            var left = ForwardedPortStatus.Starting;
+            var right = ForwardedPortStatus.Started;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnTrueWhenLeftIsStartingAndRightIsStarting()
+        {
+            var left = ForwardedPortStatus.Starting;
+            var right = ForwardedPortStatus.Starting;
+
+            var actual = left == right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenRightIsNull()
+        {
+            var left = ForwardedPortStatus.Starting;
+            const ForwardedPortStatus right = null;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenLeftIsNull()
+        {
+            const ForwardedPortStatus left = null;
+            var right = ForwardedPortStatus.Starting;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenLeftIsStartingAndRightIsStopped()
+        {
+            var left = ForwardedPortStatus.Starting;
+            var right = ForwardedPortStatus.Stopped;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenLeftIsStartingAndRightIsStopping()
+        {
+            var left = ForwardedPortStatus.Starting;
+            var right = ForwardedPortStatus.Stopping;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenLeftIsStartingAndRightIsStarted()
+        {
+            var left = ForwardedPortStatus.Starting;
+            var right = ForwardedPortStatus.Started;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnFalseWhenLeftIsStartingAndRightIsStarting()
+        {
+            var left = ForwardedPortStatus.Starting;
+            var right = ForwardedPortStatus.Starting;
+
+            var actual = left != right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void GetHashCodeShouldReturnFour()
+        {
+            var actual = ForwardedPortStatus.Starting.GetHashCode();
+
+            Assert.AreEqual(4, actual);
+        }
+
+        [TestMethod]
+        public void ToStringShouldReturnStarting()
+        {
+            var actual = ForwardedPortStatus.Starting.ToString();
+
+            Assert.AreEqual("Starting", actual);
+        }
+    }
+}

+ 243 - 0
test/Renci.SshNet.Shared.Tests/ForwardedPortStatusTest_Stopped.cs

@@ -0,0 +1,243 @@
+using System;
+#if SILVERLIGHT
+using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
+#else
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+#endif
+
+namespace Renci.SshNet.Tests
+{
+    [TestClass]
+    public class ForwardedPortStatusTest_Stopped
+    {
+        [TestMethod]
+        public void ToStopping_ShouldReturnFalseAndNotChangeStatus()
+        {
+            var status = ForwardedPortStatus.Stopped;
+
+            var actual = ForwardedPortStatus.ToStopping(ref status);
+
+            Assert.IsFalse(actual);
+            Assert.AreEqual(ForwardedPortStatus.Stopped, status);
+        }
+
+        [TestMethod]
+        public void ToStarting_ShouldReturnTrueAndChangeStatusToStarting()
+        {
+            var status = ForwardedPortStatus.Stopped;
+
+            var actual = ForwardedPortStatus.ToStarting(ref status);
+
+            Assert.IsTrue(actual);
+            Assert.AreEqual(ForwardedPortStatus.Starting, status);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsNull()
+        {
+            const ForwardedPortStatus other = null;
+
+            var actual = ForwardedPortStatus.Stopped.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsNotInstanceOfForwardedPortStatus()
+        {
+            var other = new object();
+
+            var actual = ForwardedPortStatus.Stopped.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturTrueWhenOtherIsStopped()
+        {
+            var other = ForwardedPortStatus.Stopped;
+
+            var actual = ForwardedPortStatus.Stopped.Equals(other);
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsStopping()
+        {
+            var other = ForwardedPortStatus.Stopping;
+
+            var actual = ForwardedPortStatus.Stopped.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsStarted()
+        {
+            var other = ForwardedPortStatus.Started;
+
+            var actual = ForwardedPortStatus.Stopped.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsStarting()
+        {
+            var other = ForwardedPortStatus.Starting;
+
+            var actual = ForwardedPortStatus.Stopped.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenRightIsNull()
+        {
+            var left = ForwardedPortStatus.Stopped;
+            const ForwardedPortStatus right = null;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenLeftIsNull()
+        {
+            const ForwardedPortStatus left = null;
+            var right = ForwardedPortStatus.Stopped;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnTrueWhenLeftIsStoppedAndRightIsStopped()
+        {
+            var left = ForwardedPortStatus.Stopped;
+            var right = ForwardedPortStatus.Stopped;
+
+            var actual = left == right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenLeftIsStoppedAndRightIsStopping()
+        {
+            var left = ForwardedPortStatus.Stopped;
+            var right = ForwardedPortStatus.Stopping;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenLeftIsStoppedAndRightIsStarted()
+        {
+            var left = ForwardedPortStatus.Stopped;
+            var right = ForwardedPortStatus.Started;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenLeftIsStoppedAndRightIsStarting()
+        {
+            var left = ForwardedPortStatus.Stopped;
+            var right = ForwardedPortStatus.Starting;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenRightIsNull()
+        {
+            var left = ForwardedPortStatus.Stopped;
+            const ForwardedPortStatus right = null;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenLeftIsNull()
+        {
+            const ForwardedPortStatus left = null;
+            var right = ForwardedPortStatus.Stopped;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnFalseWhenLeftIsStoppedAndRightIsStopped()
+        {
+            var left = ForwardedPortStatus.Stopped;
+            var right = ForwardedPortStatus.Stopped;
+
+            var actual = left != right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenLeftIsStoppedAndRightIsStopping()
+        {
+            var left = ForwardedPortStatus.Stopped;
+            var right = ForwardedPortStatus.Stopping;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenLeftIsStoppedAndRightIsStarted()
+        {
+            var left = ForwardedPortStatus.Stopped;
+            var right = ForwardedPortStatus.Started;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenLeftIsStoppedAndRightIsStarting()
+        {
+            var left = ForwardedPortStatus.Stopped;
+            var right = ForwardedPortStatus.Starting;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void GetHashCodeShouldReturnOne()
+        {
+            var actual = ForwardedPortStatus.Stopped.GetHashCode();
+
+            Assert.AreEqual(1, actual);
+        }
+
+        [TestMethod]
+        public void ToStringShouldReturnStopping()
+        {
+            var actual = ForwardedPortStatus.Stopped.ToString();
+
+            Assert.AreEqual("Stopped", actual);
+        }
+    }
+}

+ 255 - 0
test/Renci.SshNet.Shared.Tests/ForwardedPortStatusTest_Stopping.cs

@@ -0,0 +1,255 @@
+using System;
+#if SILVERLIGHT
+using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
+#else
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+#endif
+
+namespace Renci.SshNet.Tests
+{
+    [TestClass]
+    public class ForwardedPortStatusTest_Stopping
+    {
+        [TestMethod]
+        public void ToStopping_ShouldReturnFalseAndNotChangeStatus()
+        {
+            var status = ForwardedPortStatus.Stopping;
+
+            var actual = ForwardedPortStatus.ToStopping(ref status);
+
+            Assert.IsFalse(actual);
+            Assert.AreEqual(ForwardedPortStatus.Stopping, status);
+        }
+
+        [TestMethod]
+        public void ToStarting_ShouldThrowInvalidOperationExceptionAndNotChangeStatus()
+        {
+            var status = ForwardedPortStatus.Stopping;
+
+            try
+            {
+                ForwardedPortStatus.ToStarting(ref status);
+                Assert.Fail();
+            }
+            catch (InvalidOperationException ex)
+            {
+                Assert.IsNull(ex.InnerException);
+                Assert.AreEqual(
+                    string.Format("Forwarded port cannot transition from '{0}' to '{1}'.",
+                                  ForwardedPortStatus.Stopping,
+                                  ForwardedPortStatus.Starting),
+                    ex.Message);
+            }
+
+            Assert.AreEqual(ForwardedPortStatus.Stopping, status);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsNull()
+        {
+            const ForwardedPortStatus other = null;
+
+            var actual = ForwardedPortStatus.Stopping.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsNotInstanceOfForwardedPortStatus()
+        {
+            var other = new object();
+
+            var actual = ForwardedPortStatus.Stopping.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsStopped()
+        {
+            var other = ForwardedPortStatus.Stopped;
+
+            var actual = ForwardedPortStatus.Stopping.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnTrueWhenOtherIsStopping()
+        {
+            var other = ForwardedPortStatus.Stopping;
+
+            var actual = ForwardedPortStatus.Stopping.Equals(other);
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsStarted()
+        {
+            var other = ForwardedPortStatus.Started;
+
+            var actual = ForwardedPortStatus.Stopping.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void Equals_ShouldReturnFalseWhenOtherIsStarting()
+        {
+            var other = ForwardedPortStatus.Starting;
+
+            var actual = ForwardedPortStatus.Stopping.Equals(other);
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenRightIsNull()
+        {
+            var left = ForwardedPortStatus.Stopping;
+            const ForwardedPortStatus right = null;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenLeftIsNull()
+        {
+            const ForwardedPortStatus left = null;
+            var right = ForwardedPortStatus.Stopping;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenLeftIsStoppingAndRightIsStopped()
+        {
+            var left = ForwardedPortStatus.Stopping;
+            var right = ForwardedPortStatus.Stopped;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnTrueWhenLeftIsStoppingAndRightIsStopping()
+        {
+            var left = ForwardedPortStatus.Stopping;
+            var right = ForwardedPortStatus.Stopping;
+
+            var actual = left == right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenLeftIsStoppingAndRightIsStarted()
+        {
+            var left = ForwardedPortStatus.Stopping;
+            var right = ForwardedPortStatus.Started;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void EqualityOperator_ShouldReturnFalseWhenLeftIsStoppingAndRightIsStarting()
+        {
+            var left = ForwardedPortStatus.Stopping;
+            var right = ForwardedPortStatus.Starting;
+
+            var actual = left == right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenRightIsNull()
+        {
+            var left = ForwardedPortStatus.Stopping;
+            const ForwardedPortStatus right = null;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenLeftIsNull()
+        {
+            const ForwardedPortStatus left = null;
+            var right = ForwardedPortStatus.Stopping;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenLeftIsStoppingAndRightIsStopped()
+        {
+            var left = ForwardedPortStatus.Stopping;
+            var right = ForwardedPortStatus.Stopped;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnFalseWhenLeftIsStoppingAndRightIsStopping()
+        {
+            var left = ForwardedPortStatus.Stopping;
+            var right = ForwardedPortStatus.Stopping;
+
+            var actual = left != right;
+
+            Assert.IsFalse(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenLeftIsStoppingAndRightIsStarted()
+        {
+            var left = ForwardedPortStatus.Stopping;
+            var right = ForwardedPortStatus.Started;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void InEqualityOperator_ShouldReturnTrueWhenLeftIsStoppingAndRightIsStarting()
+        {
+            var left = ForwardedPortStatus.Stopping;
+            var right = ForwardedPortStatus.Starting;
+
+            var actual = left != right;
+
+            Assert.IsTrue(actual);
+        }
+
+        [TestMethod]
+        public void GetHashCodeShouldReturnTwo()
+        {
+            var actual = ForwardedPortStatus.Stopping.GetHashCode();
+
+            Assert.AreEqual(2, actual);
+        }
+
+        [TestMethod]
+        public void ToStringShouldReturnStopping()
+        {
+            var actual = ForwardedPortStatus.Stopping.ToString();
+
+            Assert.AreEqual("Stopping", actual);
+        }
+    }
+}

+ 4 - 0
test/Renci.SshNet.Shared.Tests/Renci.SshNet.Shared.Tests.projitems

@@ -13,6 +13,10 @@
     <Compile Include="$(MSBuildThisFileDirectory)Abstractions\DnsAbstraction_GetHostAddresses.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Abstractions\FileSystemAbstraction_EnumerateFiles.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)Abstractions\ThreadAbstraction_ExecuteThread.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)ForwardedPortStatusTest_Started.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)ForwardedPortStatusTest_Starting.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)ForwardedPortStatusTest_Stopped.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)ForwardedPortStatusTest_Stopping.cs" />
     <Compile Include="$(MSBuildThisFileDirectory)SshMessageFactoryTest.cs" />
   </ItemGroup>
 </Project>