Package net.jodah.lyra.internal

Source Code of net.jodah.lyra.internal.ConsumerRecoveryTest

package net.jodah.lyra.internal;

import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.io.IOException;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import org.testng.annotations.Test;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;

@Test(groups = { "functional", "slow" })
public class ConsumerRecoveryTest extends AbstractFunctionalTest {
  /**
   * Sets up a publisher, consumer, and an acker that acks consumed messages on a delay. Asserts
   * that Lyra drops acks for stale delivery tags after a recovery occurs.
   */
  public void shouldDropAcksForStaleDeliveryTags() throws Throwable {
    mockConnection();
    final MockChannel mockChannel = mockChannel(1);
    doAnswer(failNTimes(1, nonRetryableChannelShutdownSignal(), null, mockChannel.channelHandler)).when(
        mockChannel.delegate)
        .basicCancel("foo-tag");

    final LinkedBlockingQueue<Long> tags = new LinkedBlockingQueue<Long>();
    final Consumer consumer = new DefaultConsumer(mockChannel.proxy) {
      @Override
      public void handleDelivery(String consumerTag, Envelope envelope,
          AMQP.BasicProperties properties, byte[] body) throws IOException {
        try {
          System.out.println("Received " + envelope.getDeliveryTag());
          // Kill channel
          if (envelope.getDeliveryTag() % 25 == 0)
            mockChannel.proxy.basicCancel("foo-tag");

          tags.add(envelope.getDeliveryTag());
          Thread.sleep(5);
        } catch (Exception ignore) {
        }
      }
    };

    // Setup consumer
    when(
        mockChannel.delegate.basicConsume(eq("test-queue"), eq(false), eq("test-tag"),
            argThat(matcherFor(consumer)))).thenReturn("test-tag");
    mockChannel.proxy.basicConsume("test-queue", false, "test-tag", consumer);
    final AtomicInteger deliveryTag = new AtomicInteger(1);

    // Deliver messages
    final AtomicBoolean consume = new AtomicBoolean(true);
    ResourceDeclaration invocation = mockChannel.channelHandler.consumerDeclarations.get("test-tag");
    final ConsumerDelegate consumerDelegate = (ConsumerDelegate) invocation.args[invocation.args.length - 1];
    new Thread() {
      public void run() {
        try {
          for (; deliveryTag.get() <= 100000 && consume.get(); deliveryTag.incrementAndGet()) {
            consumerDelegate.handleDelivery("test-tag", new Envelope(deliveryTag.get(), false, "x",
                "#"), null, ("foo-" + deliveryTag).getBytes());
            Thread.sleep(5);
          }
        } catch (Exception e) {
        }
      }
    }.start();

    // Acker
    Thread.sleep(100);
    long tag = 0;
    while (tag < 100) {
      try {
        tag = tags.take();
        Thread.sleep(10);
        mockChannel.proxy.basicAck(tag, false);
      } catch (Exception e) {
      }
    }

    consume.set(false);
    verify(mockChannel.delegate, never()).basicAck(eq(25L), eq(false));
    verify(mockChannel.delegate).basicAck(eq(26L), eq(false));
  }
}
TOP

Related Classes of net.jodah.lyra.internal.ConsumerRecoveryTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.