//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldResumeWhenWritabilityChanged() throws Exception
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldResumeWhenWritabilityChanged()
        {
            TestThrottleLock lockOverride = new TestThrottleLock();

            // given
            TransportThrottle throttle = NewThrottleAndInstall(_channel, lockOverride);

            when(_channel.Writable).thenReturn(false);

            Future <Void> completionFuture = OtherThread.execute(state =>
            {
                throttle.Acquire(_channel);
                return(null);
            });

            OtherThread.get().waitUntilWaiting();

            // when
            when(_channel.Writable).thenReturn(true);
            ArgumentCaptor <ChannelInboundHandler> captor = ArgumentCaptor.forClass(typeof(ChannelInboundHandler));

            verify(_channel.pipeline()).addLast(captor.capture());
            captor.Value.channelWritabilityChanged(_context);

            OtherThread.get().awaitFuture(completionFuture);

            assertThat(lockOverride.LockCallCount(), greaterThan(0));
            assertThat(lockOverride.UnlockCallCount(), @is(1));
        }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldNotLockWhenWritable() throws Exception
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldNotLockWhenWritable()
        {
            // given
            TestThrottleLock  lockOverride = new TestThrottleLock();
            TransportThrottle throttle     = NewThrottleAndInstall(_channel, lockOverride);

            when(_channel.Writable).thenReturn(true);

            // when
            Future future = OtherThread.execute(state =>
            {
                throttle.Acquire(_channel);
                return(null);
            });

            // expect
            try
            {
                future.get(2000, TimeUnit.MILLISECONDS);
            }
            catch (Exception)
            {
                fail("should not throw");
            }

            assertTrue(future.Done);
            assertThat(lockOverride.LockCallCount(), @is(0));
            assertThat(lockOverride.UnlockCallCount(), @is(0));
        }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldLockWhenNotWritable() throws Exception
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldLockWhenNotWritable()
        {
            // given
            TestThrottleLock  lockOverride = new TestThrottleLock();
            TransportThrottle throttle     = NewThrottleAndInstall(_channel, lockOverride);

            when(_channel.Writable).thenReturn(false);

            // when
            Future <Void> future = OtherThread.execute(state =>
            {
                throttle.Acquire(_channel);
                return(null);
            });

            // expect
            try
            {
                future.get(2000, TimeUnit.MILLISECONDS);

                fail("should timeout");
            }
            catch (TimeoutException)
            {
                // expected
            }

            assertFalse(future.Done);
            assertThat(lockOverride.LockCallCount(), greaterThan(0));
            assertThat(lockOverride.UnlockCallCount(), @is(0));

            // stop the thread that is trying to acquire the lock
            // otherwise it remains actively spinning even after the test
            future.cancel(true);
            try
            {
                OtherThread.get().awaitFuture(future);
                fail("Exception expected");
            }
            catch (CancellationException)
            {
            }
        }