Package com.comcast.cqs.test.unit

Source Code of com.comcast.cqs.test.unit.CQSLongPollTest$MessageSender

/**
* Copyright 2012 Comcast Corporation
*
* 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
*
*   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 com.comcast.cqs.test.unit;

import static org.junit.Assert.*;

import java.util.HashMap;
import java.util.Map;
import org.junit.Test;

import com.amazonaws.AmazonServiceException;
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.model.DeleteMessageRequest;
import com.amazonaws.services.sqs.model.ReceiveMessageRequest;
import com.amazonaws.services.sqs.model.ReceiveMessageResult;
import com.amazonaws.services.sqs.model.SendMessageRequest;
import com.amazonaws.services.sqs.model.SetQueueAttributesRequest;
import com.comcast.cmb.test.tools.CMBAWSBaseTest;

public class CQSLongPollTest extends CMBAWSBaseTest {
 
    private static HashMap<String, String> attributeParams = new HashMap<String, String>();
    private static Map<String, String> messageMap;
    private static String queueUrl;
   
    static {
        attributeParams.put("MessageRetentionPeriod", "600");
        attributeParams.put("VisibilityTimeout", "30");
    }
   
    private class MessageSender extends Thread {
      public void run() {
        try {
        logger.info("sender sleeping for 5 sec");
          sleep(5000);
              cqs1.sendMessage(new SendMessageRequest(queueUrl, "test message"));
              logger.info("test message sent");
      } catch (Exception ex) {
        ex.printStackTrace();
      }
      }
    }
   
    /**
     * Simple functional test: Call receive() with 20 sec TO, then 5 sec later call send()
     * and check if message is received exactly once after around 5 sec.
     */
    private void testLongPoll(AmazonSQS receiverSqs) {
     
      messageMap = new HashMap<String, String>();

      try {
       
        queueUrl = getQueueUrl(1, USR.USER1);
        cqs1.setQueueAttributes(new SetQueueAttributesRequest(queueUrl, attributeParams));

        Thread.sleep(1000);

      ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest();
      receiveMessageRequest.setQueueUrl(queueUrl);
      receiveMessageRequest.setMaxNumberOfMessages(1);
      receiveMessageRequest.setWaitTimeSeconds(20);
     
      long start = System.currentTimeMillis();
     
      (new MessageSender()).start();
     
      logger.info("calling receive message");
     
      ReceiveMessageResult receiveMessageResult = receiverSqs.receiveMessage(receiveMessageRequest);
     
      logger.info("receive message returns");
     
      long end = System.currentTimeMillis();
     
      assertTrue("No message received", receiveMessageResult.getMessages().size() == 1);
     
      assertTrue("Wrong message content", receiveMessageResult.getMessages().get(0).getBody().equals("test message"));
     
      assertTrue("Message came back too fast: " + (end-start) + " ms", end-start >= 4750);
     
      assertTrue("Message came back too slow: " + (end-start) + " ms", end-start <= 5250);
         
    } catch (Exception ex) {
      ex.printStackTrace();
      fail("failed long poll test: " + ex.getMessage());
    }
    }

    /**
     * Simple functional test: Call receive() on a queue with a default 15 sec wait time, then 5 sec later call
     * send() and check if message is received exactly once after around 5 sec.
     */
    @Test
    public void testLongPollQueue() {
     
      messageMap = new HashMap<String, String>();

      try {
           
        queueUrl = getQueueUrl(1, USR.USER1);
        cqs1.setQueueAttributes(new SetQueueAttributesRequest(queueUrl, attributeParams));

        Thread.sleep(1000);
       
        SetQueueAttributesRequest setQueueAttributesRequest = new SetQueueAttributesRequest();
        setQueueAttributesRequest.setQueueUrl(queueUrl);
            attributeParams.put("ReceiveMessageWaitTimeSeconds", "15");
        setQueueAttributesRequest.setAttributes(attributeParams);

        cqs1.setQueueAttributes(setQueueAttributesRequest);

      ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest();
      receiveMessageRequest.setQueueUrl(queueUrl);
      receiveMessageRequest.setMaxNumberOfMessages(1);
     
      long start = System.currentTimeMillis();
     
      (new MessageSender()).start();
     
      logger.info("calling receive message");
     
      // note: we are calling receivemessage without waittime set and yet we should see long poll
      // behavior because the queue has a default wait time set
     
      ReceiveMessageResult receiveMessageResult = cqs1.receiveMessage(receiveMessageRequest);
     
      logger.info("receive message returns");
     
      long end = System.currentTimeMillis();
     
      assertTrue("No message received", receiveMessageResult.getMessages().size() == 1);
     
      assertTrue("Wrong message content", receiveMessageResult.getMessages().get(0).getBody().equals("test message"));
     
      assertTrue("Message came back too fast: " + (end-start) + " ms", end-start >= 4750);
     
      assertTrue("Message came back too slow: " + (end-start) + " ms", end-start <= 5250);
         
    } catch (Exception ex) {
      logger.error("test failed", ex);
      fail(ex.getMessage());
    }
    }

    @Test
    public void testLongPoll() {
      testLongPoll(cqs1);
    }
   
    @Test
    public void testLongPollWithLoadBalancer() {
     
      if (this.cqsAlt == null) {
        logger.info("skipping load balanced long poll test due to missing alternate sqs service url");
        return;
      }
     
      testLongPoll(cqsAlt);
    }
   
    /**
     * Simple functional test: Like testLongPoll above but in this test send() happens before
     * receive(). Here we ensure that the message is received immediately despite a long poll
     * timeout of 20 sec.
     */
    @Test
    public void testLongPollNoDelay() {

      messageMap = new HashMap<String, String>();

      try {
       
        queueUrl = getQueueUrl(1, USR.USER1);
        cqs1.setQueueAttributes(new SetQueueAttributesRequest(queueUrl, attributeParams));

        Thread.sleep(1000);

      ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest();
      receiveMessageRequest.setQueueUrl(queueUrl);
      receiveMessageRequest.setMaxNumberOfMessages(1);
      receiveMessageRequest.setWaitTimeSeconds(20);
     
      long start = System.currentTimeMillis();
     
            cqs1.sendMessage(new SendMessageRequest(queueUrl, "test message"));
     
      logger.info("calling receive message");
     
      ReceiveMessageResult receiveMessageResult = cqs1.receiveMessage(receiveMessageRequest);
     
      logger.info("receive message returns");
     
      long end = System.currentTimeMillis();
     
      assertTrue("No message received", receiveMessageResult.getMessages().size() == 1);
     
      assertTrue("Wrong message content", receiveMessageResult.getMessages().get(0).getBody().equals("test message"));
     
      assertTrue("Message came back too slow: " + (end-start) + " ms", end-start <= 250);
         
    } catch (Exception ex) {
      logger.error("test failed", ex);
      fail(ex.getMessage());
    }
    }

    /**
     * Test if long poll calls timeout after desired periods of wait time (e.g. after 1, 5, 20 sec) and if
     * the normal empty response comes back indicating no messages available.
     */
    private void testLongPollTimeout(int timeoutSecs) {
     
      messageMap = new HashMap<String, String>();

      try {
       
        queueUrl = getQueueUrl(1, USR.USER1);
        cqs1.setQueueAttributes(new SetQueueAttributesRequest(queueUrl, attributeParams));

        Thread.sleep(1000);

      ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest();
      receiveMessageRequest.setQueueUrl(queueUrl);
      receiveMessageRequest.setMaxNumberOfMessages(1);
      receiveMessageRequest.setWaitTimeSeconds(timeoutSecs);
     
      long start = System.currentTimeMillis();
     
      logger.info("calling receive message");
     
      ReceiveMessageResult receiveMessageResult = cqs1.receiveMessage(receiveMessageRequest);
     
      logger.info("receive message returns");
     
      long end = System.currentTimeMillis();
     
      assertTrue("Unexpected message received", receiveMessageResult.getMessages().size() == 0);
     
      assertTrue("Receive came back too fast: " + (end-start) + " ms", end-start >= timeoutSecs*1000-100);
     
      assertTrue("Receive came back too slow: " + (end-start) + " ms", end-start <= timeoutSecs*1000+100);
         
    } catch (Exception ex) {
      logger.error("test failed", ex);
      fail(ex.getMessage());
    }
    }
   
    @Test
    public void testLongPollTimeout20() {
      testLongPollTimeout(20);
    }
   
    @Test
    public void testLongPollTimeout5() {
      testLongPollTimeout(5);
    }

    @Test
    public void testLongPollTimeout1() {
      testLongPollTimeout(1);
    }

    private class MultiMessageSender extends Thread {

      int count;
      int delay;
     
      public MultiMessageSender(int count, int delay) {
        this.count = count;
        this.delay = delay;
      }
     
      public void run() {
        try {
          Thread.sleep(delay);
          for (int i=0; i<count; i++) {
            cqs1.sendMessage(new SendMessageRequest(queueUrl, "test message " + i));
          }
      } catch (Exception ex) {
        logger.error("error", ex);
      }
      }
    }
   
    /**
     * Single-threaded load test, with one thread sending 5000 messages and another thread receiving
     * messages. Test verifies that 5000 unique messages are received with no duplicates (all 5000
     * messages have different content to spot duplicates). Test can be benchmarked against sending
     * and receiving 5000 messages without using the long poll feature (WaitTime parameter not set).
     */
   
    private void testLongPollLoad(int timeoutSecs) {
     
      messageMap = new HashMap<String, String>();
     
      // set timeoutSecs to 0 to test traditional polling receives (mainly for benchmarking)
     
      try {

        queueUrl = getQueueUrl(1, USR.USER1);
        cqs1.setQueueAttributes(new SetQueueAttributesRequest(queueUrl, attributeParams));

        (new MultiMessageSender(5000,0)).start();

          int messageCounter = 0;
         
          long begin = System.currentTimeMillis();
         
          while (messageCounter < 5000) {
           
            ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest();
        receiveMessageRequest.setQueueUrl(queueUrl);
        receiveMessageRequest.setMaxNumberOfMessages(1);
       
        if (timeoutSecs > 0) {
          receiveMessageRequest.setWaitTimeSeconds(timeoutSecs);
        }
       
        ReceiveMessageResult receiveMessageResult = cqs1.receiveMessage(receiveMessageRequest);
        messageCounter += receiveMessageResult.getMessages().size();
       
        if (receiveMessageResult.getMessages().size() == 1) {
          messageMap.put(receiveMessageResult.getMessages().get(0).getBody(), "");
         
          DeleteMessageRequest deleteMessageRequest = new DeleteMessageRequest();
          deleteMessageRequest.setQueueUrl(queueUrl);
          deleteMessageRequest.setReceiptHandle(receiveMessageResult.getMessages().get(0).getReceiptHandle());
          cqs1.deleteMessage(deleteMessageRequest);
        }
          }
         
          long end = System.currentTimeMillis();
         
          logger.info("duration=" + (end-begin));
         
          assertTrue("wrong number of messages: " + messageMap.size(), messageMap.size() == 5000);
         
    } catch (Exception ex) {
      logger.error("test failed", ex);
      fail(ex.getMessage());
    }
    }

    @Test
    public void testLongPollLoadTO20() {
      testLongPollLoad(20);
    }   
   
    @Test
    public void testLongPollLoadTO0() {
      testLongPollLoad(0);
    }  
   
    /**
     * Functional test to check if correct errors are produced for invalid parameters. So far we only
     * test WaitSeconds > 20. Other tests could include WaitSeconds < 1 or WaitSeconds not an integer.
     */
    @Test
    public void testInvalidParameters() {
     
      messageMap = new HashMap<String, String>();

      try {
       
        queueUrl = getQueueUrl(1, USR.USER1);
        cqs1.setQueueAttributes(new SetQueueAttributesRequest(queueUrl, attributeParams));

        Thread.sleep(1000);

      ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest();
      receiveMessageRequest.setQueueUrl(queueUrl);
      receiveMessageRequest.setMaxNumberOfMessages(1);
     
      // timeout > 20 sec, should fail
     
      receiveMessageRequest.setWaitTimeSeconds(21);
     
      boolean failed = false;
     
      try {
        cqs1.receiveMessage(receiveMessageRequest);
      } catch (AmazonServiceException ex) {
        assertTrue("Wrong error message: " + ex.getErrorCode(), ex.getErrorCode().equals("InvalidParameterValue"));
        failed = true;
      }
     
      assertTrue("Didn't fail", failed);
     
      receiveMessageRequest.setWaitTimeSeconds(-1);
     
      failed = false;
     
      try {
        cqs1.receiveMessage(receiveMessageRequest);
      } catch (AmazonServiceException ex) {
        assertTrue("Wrong error message: " + ex.getErrorCode(), ex.getErrorCode().equals("InvalidParameterValue"));
        failed = true;
      }
     
      assertTrue("Didn't fail", failed);
         
    } catch (Exception ex) {
      logger.error("test failed", ex);
      fail(ex.getMessage());
    }
    }
   
    private class MessageReceiver extends Thread {
     
      public void run() {
       
        try {
         
          ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest();
          receiveMessageRequest.setQueueUrl(queueUrl);
          receiveMessageRequest.setMaxNumberOfMessages(1);
          receiveMessageRequest.setWaitTimeSeconds(20);
         
          ReceiveMessageResult receiveMessageResult = cqs1.receiveMessage(receiveMessageRequest);
         
          if (receiveMessageResult.getMessages().size() == 1) {
           
            messageMap.put(receiveMessageResult.getMessages().get(0).getBody(), "");
         
            DeleteMessageRequest deleteMessageRequest = new DeleteMessageRequest();
            deleteMessageRequest.setQueueUrl(queueUrl);
            deleteMessageRequest.setReceiptHandle(receiveMessageResult.getMessages().get(0).getReceiptHandle());
            cqs1.deleteMessage(deleteMessageRequest);
          }
         
      } catch (Exception ex) {
        logger.error("test failed", ex);
        fail(ex.getMessage());
      }
      }
    }
   
    /**
     * Multi-threaded load test. This test launches 25 concurrent message receivers each of them consecutively
     * calling receive() with a TO of 20 sec. After a dealy of 2 sec a single threaded messages sender starts
     * sending 25 seconds. Test verifies that 25 unique messages are received.
     */
    private void testConcurrentLPRequests(AmazonSQS senderSqs) {
     
      messageMap = new HashMap<String, String>();

      try {
       
        queueUrl = getQueueUrl(1, USR.USER1);

          // apparently there is a limit of 50 concurrent operations in aws sdk
         
          int numMessages = 25;
         
          for (int i=0; i<numMessages; i++) {
            new MessageReceiver().start();
          }
         
          Thread.sleep(2000);
         
        for (int i=0; i<numMessages; i++) {
          senderSqs.sendMessage(new SendMessageRequest(queueUrl, "test message " + i));
      }
       
        Thread.sleep(1000);
       
        assertTrue("Wrong number of messages: " + messageMap.size(), messageMap.size() == numMessages);
     
      } catch (Exception ex) {
      logger.error("test failed", ex);
      fail(ex.getMessage());
    }
    }
   
    @Test
    public void testConcurrentLPRequests() {
      testConcurrentLPRequests(cqs1);
    }

    @Test
    public void testConcurrentLPRequestsLoadBalancer() {

      if (cqsAlt == null) {
        logger.info("skipping concurrent load balanced long poll test due to missing alternate sqs service url");
        return;
      }
     
      testConcurrentLPRequests(cqsAlt);
    }
}
TOP

Related Classes of com.comcast.cqs.test.unit.CQSLongPollTest$MessageSender

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.