| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 |
| * |
| * http://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 org.apache.qpid.protonj2.engine.impl; |
| |
| import static org.junit.jupiter.api.Assertions.assertNotNull; |
| import static org.junit.jupiter.api.Assertions.assertNull; |
| import static org.junit.jupiter.api.Assertions.assertSame; |
| import static org.junit.jupiter.api.Assertions.fail; |
| |
| import org.apache.qpid.protonj2.engine.EngineHandler; |
| import org.apache.qpid.protonj2.engine.EngineHandlerContext; |
| import org.apache.qpid.protonj2.engine.HeaderEnvelope; |
| import org.apache.qpid.protonj2.engine.util.FrameReadSinkTransportHandler; |
| import org.apache.qpid.protonj2.engine.util.FrameWriteSinkTransportHandler; |
| import org.junit.jupiter.api.BeforeEach; |
| import org.junit.jupiter.api.Test; |
| import org.mockito.Mockito; |
| |
| public class ProtonEnginePipelineTest { |
| |
| private ProtonEngine engine; |
| |
| @BeforeEach |
| public void initMocks() { |
| engine = Mockito.mock(ProtonEngine.class); |
| } |
| |
| @Test |
| public void testCreatePipeline() { |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| assertSame(pipeline.engine(), engine); |
| assertNull(pipeline.first()); |
| assertNull(pipeline.last()); |
| assertNull(pipeline.firstContext()); |
| assertNull(pipeline.lastContext()); |
| } |
| |
| @Test |
| public void testCreatePipelineRejectsNullParent() { |
| try { |
| new ProtonEnginePipeline(null); |
| fail("Should throw an IllegalArgumentException"); |
| } catch (IllegalArgumentException iae) {} |
| } |
| |
| //----- Tests for addFirst -----------------------------------------------// |
| |
| @Test |
| public void testAddFirstRejectsNullHandler() { |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| try { |
| pipeline.addFirst("one", null); |
| fail("Should throw an IllegalArgumentException"); |
| } catch (IllegalArgumentException iae) {} |
| } |
| |
| @Test |
| public void testAddFirstRejectsNullHandlerName() { |
| EngineHandler handler = Mockito.mock(EngineHandler.class); |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| try { |
| pipeline.addFirst(null, handler); |
| fail("Should throw an IllegalArgumentException"); |
| } catch (IllegalArgumentException iae) {} |
| } |
| |
| @Test |
| public void testAddFirstRejectsEmptyHandlerName() { |
| EngineHandler handler = Mockito.mock(EngineHandler.class); |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| try { |
| pipeline.addFirst("", handler); |
| fail("Should throw an IllegalArgumentException"); |
| } catch (IllegalArgumentException iae) {} |
| } |
| |
| @Test |
| public void testAddFirstWithOneHandler() { |
| EngineHandler handler = Mockito.mock(EngineHandler.class); |
| |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| pipeline.addFirst("one", handler); |
| |
| assertSame(handler, pipeline.first()); |
| assertSame(handler, pipeline.last()); |
| assertNotNull(pipeline.firstContext()); |
| assertSame(handler, pipeline.firstContext().handler()); |
| } |
| |
| @Test |
| public void testAddFirstWithMoreThanOneHandler() { |
| EngineHandler handler1 = Mockito.mock(EngineHandler.class); |
| EngineHandler handler2 = Mockito.mock(EngineHandler.class); |
| EngineHandler handler3 = Mockito.mock(EngineHandler.class); |
| |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| pipeline.addFirst("three", handler3); |
| pipeline.addFirst("two", handler2); |
| pipeline.addFirst("one", handler1); |
| |
| assertSame(handler1, pipeline.first()); |
| assertSame(handler3, pipeline.last()); |
| |
| assertNotNull(pipeline.firstContext()); |
| assertSame(handler1, pipeline.firstContext().handler()); |
| assertNotNull(pipeline.lastContext()); |
| assertSame(handler3, pipeline.lastContext().handler()); |
| } |
| |
| //----- Tests for addLast ------------------------------------------------// |
| |
| @Test |
| public void testAddLastRejectsNullHandler() { |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| try { |
| pipeline.addLast("one", null); |
| fail("Should throw an IllegalArgumentException"); |
| } catch (IllegalArgumentException iae) {} |
| } |
| |
| @Test |
| public void testAddLastRejectsNullHandlerName() { |
| EngineHandler handler = Mockito.mock(EngineHandler.class); |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| try { |
| pipeline.addLast(null, handler); |
| fail("Should throw an IllegalArgumentException"); |
| } catch (IllegalArgumentException iae) {} |
| } |
| |
| @Test |
| public void testAddLastRejectsEmptyHandlerName() { |
| EngineHandler handler = Mockito.mock(EngineHandler.class); |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| try { |
| pipeline.addLast("", handler); |
| fail("Should throw an IllegalArgumentException"); |
| } catch (IllegalArgumentException iae) {} |
| } |
| |
| @Test |
| public void testAddLastWithOneHandler() { |
| EngineHandler handler = Mockito.mock(EngineHandler.class); |
| |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| pipeline.addLast("one", handler); |
| |
| assertSame(handler, pipeline.first()); |
| assertSame(handler, pipeline.last()); |
| |
| assertNotNull(pipeline.firstContext()); |
| assertSame(handler, pipeline.firstContext().handler()); |
| assertNotNull(pipeline.lastContext()); |
| assertSame(handler, pipeline.lastContext().handler()); |
| } |
| |
| @Test |
| public void testAddLastWithMoreThanOneHandler() { |
| EngineHandler handler1 = Mockito.mock(EngineHandler.class); |
| EngineHandler handler2 = Mockito.mock(EngineHandler.class); |
| EngineHandler handler3 = Mockito.mock(EngineHandler.class); |
| |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| pipeline.addLast("one", handler1); |
| pipeline.addLast("two", handler2); |
| pipeline.addLast("three", handler3); |
| |
| assertSame(handler1, pipeline.first()); |
| assertSame(handler3, pipeline.last()); |
| |
| assertNotNull(pipeline.firstContext()); |
| assertSame(handler1, pipeline.firstContext().handler()); |
| assertNotNull(pipeline.lastContext()); |
| assertSame(handler3, pipeline.lastContext().handler()); |
| } |
| |
| //----- Tests for removeFirst --------------------------------------------// |
| |
| @Test |
| public void testRemoveFirstWithOneHandler() { |
| EngineHandler handler = Mockito.mock(EngineHandler.class); |
| |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| pipeline.addFirst("one", handler); |
| |
| assertNotNull(pipeline.first()); |
| assertSame(pipeline, pipeline.removeFirst()); |
| assertNull(pipeline.first()); |
| // calling when empty should not throw. |
| assertSame(pipeline, pipeline.removeFirst()); |
| } |
| |
| @Test |
| public void testRemoveFirstWithMoreThanOneHandler() { |
| EngineHandler handler1 = Mockito.mock(EngineHandler.class); |
| EngineHandler handler2 = Mockito.mock(EngineHandler.class); |
| EngineHandler handler3 = Mockito.mock(EngineHandler.class); |
| |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| pipeline.addFirst("three", handler3); |
| pipeline.addFirst("two", handler2); |
| pipeline.addFirst("one", handler1); |
| |
| assertSame(pipeline, pipeline.removeFirst()); |
| assertSame(handler2, pipeline.first()); |
| assertSame(pipeline, pipeline.removeFirst()); |
| assertSame(handler3, pipeline.first()); |
| assertSame(pipeline, pipeline.removeFirst()); |
| // calling when empty should not throw. |
| assertSame(pipeline, pipeline.removeFirst()); |
| assertNull(pipeline.first()); |
| } |
| |
| //----- Tests for removeLast ---------------------------------------------// |
| |
| @Test |
| public void testRemoveLastWithOneHandler() { |
| EngineHandler handler = Mockito.mock(EngineHandler.class); |
| |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| pipeline.addFirst("one", handler); |
| |
| assertNotNull(pipeline.first()); |
| assertSame(pipeline, pipeline.removeLast()); |
| assertNull(pipeline.first()); |
| // calling when empty should not throw. |
| assertSame(pipeline, pipeline.removeLast()); |
| } |
| |
| @Test |
| public void testRemoveLastWithMoreThanOneHandler() { |
| EngineHandler handler1 = Mockito.mock(EngineHandler.class); |
| EngineHandler handler2 = Mockito.mock(EngineHandler.class); |
| EngineHandler handler3 = Mockito.mock(EngineHandler.class); |
| |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| pipeline.addFirst("three", handler3); |
| pipeline.addFirst("two", handler2); |
| pipeline.addFirst("one", handler1); |
| |
| assertSame(pipeline, pipeline.removeLast()); |
| assertSame(handler2, pipeline.last()); |
| assertSame(pipeline, pipeline.removeLast()); |
| assertSame(handler1, pipeline.last()); |
| assertSame(pipeline, pipeline.removeLast()); |
| // calling when empty should not throw. |
| assertSame(pipeline, pipeline.removeLast()); |
| assertNull(pipeline.last()); |
| } |
| |
| //----- Tests for removeLast ---------------------------------------------// |
| |
| @Test |
| public void testRemoveWhenEmpty() { |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| assertSame(pipeline, pipeline.remove("unknown")); |
| assertSame(pipeline, pipeline.remove("")); |
| assertSame(pipeline, pipeline.remove((String) null)); |
| assertSame(pipeline, pipeline.remove((EngineHandler) null)); |
| } |
| |
| @Test |
| public void testRemoveWithOneHandler() { |
| EngineHandler handler = Mockito.mock(EngineHandler.class); |
| |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| pipeline.addFirst("one", handler); |
| |
| assertSame(handler, pipeline.first()); |
| |
| assertSame(pipeline, pipeline.remove("unknown")); |
| assertSame(pipeline, pipeline.remove("")); |
| assertSame(pipeline, pipeline.remove((String) null)); |
| assertSame(pipeline, pipeline.remove((EngineHandler) null)); |
| |
| assertSame(handler, pipeline.first()); |
| assertSame(pipeline, pipeline.remove("one")); |
| |
| assertNull(pipeline.first()); |
| assertNull(pipeline.last()); |
| |
| pipeline.addFirst("one", handler); |
| |
| assertSame(handler, pipeline.first()); |
| |
| assertSame(pipeline, pipeline.remove(handler)); |
| |
| assertNull(pipeline.first()); |
| assertNull(pipeline.last()); |
| } |
| |
| @Test |
| public void testRemoveWithMoreThanOneHandler() { |
| EngineHandler handler1 = Mockito.mock(EngineHandler.class); |
| EngineHandler handler2 = Mockito.mock(EngineHandler.class); |
| EngineHandler handler3 = Mockito.mock(EngineHandler.class); |
| |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| pipeline.addFirst("three", handler3); |
| pipeline.addFirst("two", handler2); |
| pipeline.addFirst("one", handler1); |
| |
| assertSame(handler1, pipeline.first()); |
| assertSame(pipeline, pipeline.remove("one")); |
| assertSame(handler2, pipeline.first()); |
| assertSame(pipeline, pipeline.remove("two")); |
| assertSame(handler3, pipeline.first()); |
| assertSame(pipeline, pipeline.remove("three")); |
| |
| assertNull(pipeline.first()); |
| assertNull(pipeline.last()); |
| |
| pipeline.addFirst("three", handler3); |
| pipeline.addFirst("two", handler2); |
| pipeline.addFirst("one", handler1); |
| |
| assertSame(handler1, pipeline.first()); |
| assertSame(pipeline, pipeline.remove(handler1)); |
| assertSame(handler2, pipeline.first()); |
| assertSame(pipeline, pipeline.remove(handler2)); |
| assertSame(handler3, pipeline.first()); |
| assertSame(pipeline, pipeline.remove(handler3)); |
| |
| assertNull(pipeline.first()); |
| assertNull(pipeline.last()); |
| } |
| |
| @Test |
| public void testHandlerCanOptIntoAllEvents() { |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| EngineHandler handler = Mockito.mock(EngineHandler.class); |
| Mockito.doAnswer((invocation) -> { |
| ((ProtonEngineHandlerContext) invocation.getArgument(0)).interestMask(ProtonEngineHandlerContext.HANDLER_ALL_EVENTS); |
| return null; |
| }).when(handler).handlerAdded(Mockito.any(EngineHandlerContext.class)); |
| |
| pipeline.addLast("read-sink", new FrameReadSinkTransportHandler()); |
| pipeline.addLast("test", handler); |
| pipeline.addLast("write-sink", new FrameWriteSinkTransportHandler()); |
| |
| pipeline.fireRead(HeaderEnvelope.AMQP_HEADER_ENVELOPE); |
| pipeline.fireWrite(HeaderEnvelope.AMQP_HEADER_ENVELOPE); |
| |
| Mockito.verify(handler).handlerAdded(Mockito.any(EngineHandlerContext.class)); |
| Mockito.verify(handler).handleRead(Mockito.any(EngineHandlerContext.class), Mockito.any(HeaderEnvelope.class)); |
| Mockito.verify(handler).handleWrite(Mockito.any(EngineHandlerContext.class), Mockito.any(HeaderEnvelope.class)); |
| Mockito.verifyNoMoreInteractions(handler); |
| } |
| |
| @Test |
| public void testHandlerCanOptOutOfReadEvents() { |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| EngineHandler handler = Mockito.mock(EngineHandler.class); |
| Mockito.doAnswer((invocation) -> { |
| ((ProtonEngineHandlerContext) invocation.getArgument(0)).interestMask(ProtonEngineHandlerContext.HANDLER_WRITES); |
| return null; |
| }).when(handler).handlerAdded(Mockito.any(EngineHandlerContext.class)); |
| |
| pipeline.addLast("read-sink", new FrameReadSinkTransportHandler()); |
| pipeline.addLast("test", handler); |
| pipeline.addLast("write-sink", new FrameWriteSinkTransportHandler()); |
| |
| pipeline.fireRead(HeaderEnvelope.AMQP_HEADER_ENVELOPE); |
| |
| Mockito.verify(handler).handlerAdded(Mockito.any(EngineHandlerContext.class)); |
| Mockito.verifyNoMoreInteractions(handler); |
| } |
| |
| @Test |
| public void testHandlerCanOptOutOfWriteEvents() { |
| ProtonEnginePipeline pipeline = new ProtonEnginePipeline(engine); |
| |
| EngineHandler handler = Mockito.mock(EngineHandler.class); |
| Mockito.doAnswer((invocation) -> { |
| ((ProtonEngineHandlerContext) invocation.getArgument(0)).interestMask(ProtonEngineHandlerContext.HANDLER_READS); |
| return null; |
| }).when(handler).handlerAdded(Mockito.any(EngineHandlerContext.class)); |
| |
| pipeline.addLast("read-sink", new FrameReadSinkTransportHandler()); |
| pipeline.addLast("test", handler); |
| pipeline.addLast("write-sink", new FrameWriteSinkTransportHandler()); |
| |
| pipeline.fireWrite(HeaderEnvelope.AMQP_HEADER_ENVELOPE); |
| |
| Mockito.verify(handler).handlerAdded(Mockito.any(EngineHandlerContext.class)); |
| Mockito.verifyNoMoreInteractions(handler); |
| } |
| } |