//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldCausePanicAfterSomeFailures() throws Throwable
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldCausePanicAfterSomeFailures()
        {
            // GIVEN
            Exception[] failures = new Exception[]
            {
                new Exception("First"),
                new Exception("Second"),
                new Exception("Third")
            };
            when(_checkPointer.checkPointIfNeeded(any(typeof(TriggerInfo)))).thenThrow(failures);
            CheckPointScheduler scheduler = new CheckPointScheduler(_checkPointer, _ioLimiter, _jobScheduler, 1, _health);

            scheduler.Start();

            // WHEN
            for (int i = 0; i < CheckPointScheduler.MaxConsecutiveFailuresTolerance - 1; i++)
            {
                _jobScheduler.runJob();
                verifyZeroInteractions(_health);
            }

            try
            {
                _jobScheduler.runJob();
                fail("Should have failed");
            }
            catch (UnderlyingStorageException e)
            {
                // THEN
                assertEquals(Iterators.asSet(failures), Iterators.asSet(e.Suppressed));
                verify(_health).panic(e);
            }
        }
        // Timeout as fallback safety if test deadlocks
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test(timeout = 60_000) public void shouldWaitOnStopUntilTheRunningCheckpointIsDone() throws Throwable
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldWaitOnStopUntilTheRunningCheckpointIsDone()
        {
            // given
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final java.util.concurrent.atomic.AtomicReference<Throwable> ex = new java.util.concurrent.atomic.AtomicReference<>();
            AtomicReference <Exception> ex = new AtomicReference <Exception>();
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final java.util.concurrent.atomic.AtomicBoolean stoppedCompleted = new java.util.concurrent.atomic.AtomicBoolean();
            AtomicBoolean stoppedCompleted = new AtomicBoolean();
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final org.neo4j.test.DoubleLatch checkPointerLatch = new org.neo4j.test.DoubleLatch(1);
            DoubleLatch checkPointerLatch = new DoubleLatch(1);
            OtherThreadExecutor <Void> otherThreadExecutor = new OtherThreadExecutor <Void>("scheduler stopper", null);
            CheckPointer checkPointer = new CheckPointerAnonymousInnerClass(this, checkPointerLatch);

//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final CheckPointScheduler scheduler = new CheckPointScheduler(checkPointer, ioLimiter, jobScheduler, 20L, health);
            CheckPointScheduler scheduler = new CheckPointScheduler(checkPointer, _ioLimiter, _jobScheduler, 20L, _health);

            // when
            scheduler.Start();

            Thread runCheckPointer = new Thread(_jobScheduler.runJob);

            runCheckPointer.Start();

            checkPointerLatch.WaitForAllToStart();

            otherThreadExecutor.ExecuteDontWait((OtherThreadExecutor.WorkerCommand <Void, Void>)state =>
            {
                try
                {
                    scheduler.Stop();
                    stoppedCompleted.set(true);
                }
                catch (Exception throwable)
                {
                    ex.set(throwable);
                }
                return(null);
            });
            otherThreadExecutor.WaitUntilWaiting(details => details.isAt(typeof(CheckPointScheduler), "waitOngoingCheckpointCompletion"));

            // then
            assertFalse(stoppedCompleted.get());

            checkPointerLatch.Finish();
            runCheckPointer.Join();

            while (!stoppedCompleted.get())
            {
                Thread.Sleep(1);
            }
            otherThreadExecutor.Dispose();

            assertNull(ex.get());
        }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldScheduleTheCheckPointerJobOnStart()
        public virtual void ShouldScheduleTheCheckPointerJobOnStart()
        {
            // given
            CheckPointScheduler scheduler = new CheckPointScheduler(_checkPointer, _ioLimiter, _jobScheduler, 20L, _health);

            assertNull(_jobScheduler.Job);

            // when
            scheduler.Start();

            // then
            assertNotNull(_jobScheduler.Job);
            verify(_jobScheduler, times(1)).schedule(eq(Group.CHECKPOINT), any(typeof(ThreadStart)), eq(20L), eq(TimeUnit.MILLISECONDS));
        }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldNotRescheduleAJobWhenStopped()
        public virtual void ShouldNotRescheduleAJobWhenStopped()
        {
            // given
            CheckPointScheduler scheduler = new CheckPointScheduler(_checkPointer, _ioLimiter, _jobScheduler, 20L, _health);

            assertNull(_jobScheduler.Job);

            scheduler.Start();

            assertNotNull(_jobScheduler.Job);

            // when
            scheduler.Stop();

            // then
            assertNull(_jobScheduler.Job);
        }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void stoppedJobCantBeInvoked() throws Throwable
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void StoppedJobCantBeInvoked()
        {
            CheckPointScheduler scheduler = new CheckPointScheduler(_checkPointer, _ioLimiter, _jobScheduler, 10L, _health);

            scheduler.Start();
            _jobScheduler.runJob();

            // verify checkpoint was triggered
            verify(_checkPointer).checkPointIfNeeded(any(typeof(TriggerInfo)));

            // simulate scheduled run that was triggered just before stop
            scheduler.Stop();
            scheduler.Start();
            _jobScheduler.runJob();

            // checkpointer should not be invoked now because job stopped
            verifyNoMoreInteractions(_checkPointer);
        }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test(timeout = 10_000) public void checkpointOnStopShouldFlushAsFastAsPossible() throws Throwable
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void CheckpointOnStopShouldFlushAsFastAsPossible()
        {
            CheckableIOLimiter ioLimiter = new CheckableIOLimiter();

            System.Threading.CountdownEvent checkPointerLatch = new System.Threading.CountdownEvent(1);
            WaitUnlimitedCheckPointer       checkPointer      = new WaitUnlimitedCheckPointer(ioLimiter, checkPointerLatch);
            CheckPointScheduler             scheduler         = new CheckPointScheduler(checkPointer, ioLimiter, _jobScheduler, 0L, _health);

            scheduler.Start();

//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: java.util.concurrent.Future<?> checkpointerStarter = executor.submit(jobScheduler::runJob);
            Future <object> checkpointerStarter = _executor.submit(_jobScheduler.runJob);

            checkPointerLatch.await();
            scheduler.Stop();
            checkpointerStarter.get();

            assertTrue("Checkpointer should be created.", checkPointer.CheckpointCreated);
            assertTrue("Limiter should be enabled in the end.", ioLimiter.Limited);
        }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldRescheduleTheJobAfterARun() throws Throwable
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
        public virtual void ShouldRescheduleTheJobAfterARun()
        {
            // given
            CheckPointScheduler scheduler = new CheckPointScheduler(_checkPointer, _ioLimiter, _jobScheduler, 20L, _health);

            assertNull(_jobScheduler.Job);

            scheduler.Start();

            ThreadStart scheduledJob = _jobScheduler.Job;

            assertNotNull(scheduledJob);

            // when
            _jobScheduler.runJob();

            // then
            verify(_jobScheduler, times(2)).schedule(eq(Group.CHECKPOINT), any(typeof(ThreadStart)), eq(20L), eq(TimeUnit.MILLISECONDS));
            verify(_checkPointer, times(1)).checkPointIfNeeded(any(typeof(TriggerInfo)));
            assertEquals(scheduledJob, _jobScheduler.Job);
        }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test public void shouldContinueThroughSporadicFailures()
        public virtual void ShouldContinueThroughSporadicFailures()
        {
            // GIVEN
            ControlledCheckPointer checkPointer = new ControlledCheckPointer();
            CheckPointScheduler    scheduler    = new CheckPointScheduler(checkPointer, _ioLimiter, _jobScheduler, 1, _health);

            scheduler.Start();

            // WHEN/THEN
            for (int i = 0; i < CheckPointScheduler.MaxConsecutiveFailuresTolerance * 2; i++)
            {
                // Fail
                checkPointer.Fail = true;
                _jobScheduler.runJob();
                verifyZeroInteractions(_health);

                // Succeed
                checkPointer.Fail = false;
                _jobScheduler.runJob();
                verifyZeroInteractions(_health);
            }
        }