/*
 * Copyright 2014-2020 Real Logic Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * Copyright 2014-2020 Real Logic Limited.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.aeron;

import io.aeron.driver.MediaDriver;
import io.aeron.logbuffer.FragmentHandler;
import io.aeron.test.*;
import org.agrona.ErrorHandler;
import org.agrona.collections.MutableBoolean;
import org.agrona.concurrent.UnsafeBuffer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.api.extension.RegisterExtension;

import static io.aeron.test.Tests.awaitConnected;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;

public class ClientErrorHandlerTest
{
    private static final int STREAM_ID = 1001;
    private static final String CHANNEL = "aeron:ipc";

    @RegisterExtension
    public final MediaDriverTestWatcher testWatcher = new MediaDriverTestWatcher();

    @Test
    @Timeout(10)
    public void shouldHaveCorrectTermBufferLength()
    {
        final MediaDriver.Context ctx = new MediaDriver.Context()
            .errorHandler(Tests::onError)
            .dirDeleteOnStart(true);

        final ErrorHandler mockErrorHandlerOne = mock(ErrorHandler.class);
        final Aeron.Context clientCtxOne = new Aeron.Context().errorHandler(mockErrorHandlerOne);

        final ErrorHandler mockErrorHandlerTwo = mock(ErrorHandler.class);
        final Aeron.Context clientCtxTwo = new Aeron.Context()
            .errorHandler(mockErrorHandlerTwo)
            .subscriberErrorHandler(RethrowingErrorHandler.INSTANCE);

        try (TestMediaDriver ignore = TestMediaDriver.launch(ctx, testWatcher);
            Aeron aeronOne = Aeron.connect(clientCtxOne);
            Aeron aeronTwo = Aeron.connect(clientCtxTwo);
            Publication publication = aeronOne.addPublication(CHANNEL, STREAM_ID);
            Subscription subscriptionOne = aeronOne.addSubscription(CHANNEL, STREAM_ID);
            Subscription subscriptionTwo = aeronTwo.addSubscription(CHANNEL, STREAM_ID))
        {
            awaitConnected(subscriptionOne);
            awaitConnected(subscriptionTwo);

            assertEquals(clientCtxOne.errorHandler(), clientCtxOne.subscriberErrorHandler());
            assertNotEquals(clientCtxTwo.errorHandler(), clientCtxTwo.subscriberErrorHandler());

            final UnsafeBuffer buffer = new UnsafeBuffer(new byte[100]);
            while (publication.offer(buffer) < 0)
            {
                Tests.yield();
            }

            final MutableBoolean isInvoked = new MutableBoolean();
            final RuntimeException expectedException = new RuntimeException("Expected");
            final FragmentHandler handler =
                (buffer1, offset, length, header) ->
                {
                    isInvoked.set(true);
                    throw expectedException;
                };

            while (true)
            {
                subscriptionOne.poll(handler, 1);
                if (isInvoked.get())
                {
                    break;
                }

                Tests.yield();
            }

            verify(mockErrorHandlerOne).onError(expectedException);

            try
            {
                while (0 == subscriptionTwo.poll(handler, 1))
                {
                    Tests.yield();
                }

                fail("Expected exception");
            }
            catch (final Throwable ex)
            {
                assertEquals(expectedException, ex);
            }

            verify(mockErrorHandlerTwo, never()).onError(any());
        }
        finally
        {
            ctx.deleteDirectory();
        }
    }
}

@@ -1361,54 +1361,8 @@
 er;%0A
-import org.agrona.collections.MutableBoolean;%0A
 impo
@@ -3565,75 +3565,8 @@
  %7D%0A%0A
-            final MutableBoolean isInvoked = new MutableBoolean();%0A
     
@@ -3646,24 +3646,24 @@
 Expected%22);%0A
+
             
@@ -3769,49 +3769,8 @@
   %7B%0A
-                    isInvoked.set(true);%0A
     
@@ -3853,178 +3853,60 @@
 le (
-true)%0A            %7B%0A                subscriptionOne.poll(handler, 1);%0A                if (isInvoked.get())%0A                %7B%0A                    break;%0A                %7D%0A
+0 == subscriptionOne.poll(handler, 1))%0A            %7B
 %0A   

Simplify ClientErrorHandlerTest.