/* * RHQ Management Platform * Copyright (C) 2005-2008 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.enterprise.communications.command.client; import java.util.concurrent.TimeUnit; import org.testng.annotations.Test; /** * Tests the command queue and queue throttling. * * @author John Mazzitelli */ @Test public class CommandQueueTest { /** * Tests putting alot of things in the queue and taking them out while not throttled. * * @throws Exception */ public void testBigQueue() throws Exception { CommandQueue q = new CommandQueue(createConfig(10000, false, 0L, 0L)); assert !q.isThrottlingEnabled() : "Queue throttling should have been disabled"; for (int i = 0; i < 10000; i++) { q.put(new QueueItem(i)); assert q.size() == (i + 1); } for (int i = 0; i < 10000; i++) { int num = ((QueueItem) q.take()).asInt(); assert num == i : "The queue did not take the items out in FIFO order"; assert q.size() == (10000 - (i + 1)); } return; } /** * Tests putting alot of things in the queue and taking them out while throttled. * * @throws Exception */ public void testBigQueueThrottled() throws Exception { CommandQueue q = new CommandQueue(createConfig(500, true, 5L, 250L)); assert q.isThrottlingEnabled() : "Queue throttling should have been enabled"; for (int i = 0; i < 500; i++) { q.put(new QueueItem(i)); } for (int i = 0; i < 500; i++) { int num = ((QueueItem) q.take()).asInt(); assert num == i : "The queue did not take the items out in FIFO order"; } return; } /** * Tests queue throttling. * * @throws Exception */ public void testQueueThrottling() throws Exception { long previous_time; CommandQueue q = new CommandQueue(createConfig(5, true, 2L, 1000L)); assert q.isThrottlingEnabled() : "Queue throttling should have been enabled"; q.put(new QueueItem("first")); q.put(new QueueItem("second")); q.put(new QueueItem("third")); q.put(new QueueItem("fourth")); q.put(new QueueItem("fifth")); previous_time = System.currentTimeMillis(); assert q.take().equals(new QueueItem("first")); assert q.take().equals(new QueueItem("second")); assert timeDifference(previous_time) < 1000L : "Should not have taken so long, we took no more than the max"; previous_time = System.currentTimeMillis(); assert q.take().equals(new QueueItem("third")); assert q.take().equals(new QueueItem("fourth")); assert q.take().equals(new QueueItem("fifth")); assert timeDifference(previous_time) >= 1000L : "Should have been throttled, we took more than the max per burst"; q.disableQueueThrottling(); assert !q.isThrottlingEnabled(); q.put(new QueueItem("first")); q.put(new QueueItem("second")); q.put(new QueueItem("third")); q.put(new QueueItem("fourth")); q.put(new QueueItem("fifth")); previous_time = System.currentTimeMillis(); assert q.take().equals(new QueueItem("first")); assert q.take().equals(new QueueItem("second")); assert q.take().equals(new QueueItem("third")); assert q.take().equals(new QueueItem("fourth")); assert q.take().equals(new QueueItem("fifth")); assert timeDifference(previous_time) < 1000L : "Should not have been throttled"; return; } /** * Tests simple queue ops. * * @throws Exception */ public void testQueueing() throws Exception { CommandQueue q = new CommandQueue(createConfig(5, false, 0L, 0L)); assert q.remainingCapacity() == 5; q.put(new QueueItem("first")); q.put(new QueueItem("second")); q.put(new QueueItem("third")); q.put(new QueueItem("fourth")); q.put(new QueueItem("fifth")); assert !q.offer(new QueueItem("NO ROOM"), 500L, TimeUnit.MILLISECONDS) : "The queue should have been full, should not have been able to put this"; assert q.take().equals(new QueueItem("first")); assert q.take().equals(new QueueItem("second")); assert q.take().equals(new QueueItem("third")); assert q.take().equals(new QueueItem("fourth")); assert q.take().equals(new QueueItem("fifth")); assert q.poll(500L, TimeUnit.MILLISECONDS) == null; assert !q.isThrottlingEnabled() : "We never configured queue throttling"; } /** * Creates a config with the given params set. * * @param q_size the size of the queue * @param throttled indicates if the throttling should be enabled * @param burst_max_commands the maximum number of commands that can be taken during burst period * @param burst_period the millisecond time period for the burst * * @return the config */ private ClientCommandSenderConfiguration createConfig(int q_size, boolean throttled, long burst_max_commands, long burst_period) { ClientCommandSenderConfiguration config = new ClientCommandSenderConfiguration(); config.queueSize = q_size; config.enableQueueThrottling = throttled; config.queueThrottleMaxCommands = burst_max_commands; config.queueThrottleBurstPeriodMillis = burst_period; return config; } /** * Returns the number of milliseconds that have elapsed since the given previous time (compared to the current * time). * * @param previous_time * * @return current time minus the previous time */ private long timeDifference(long previous_time) { return System.currentTimeMillis() - previous_time; } private class QueueItem implements Runnable { private String str; public QueueItem(String s) { str = s.toString(); // force NPE - shouldn't happen in our tests } public QueueItem(Integer i) { str = String.valueOf(i.intValue()); // force NPE - shouldn't happen in our tests } public int asInt() { return Integer.parseInt(str); } @Override public String toString() { return str; } @Override public int hashCode() { return str.hashCode(); } @Override public boolean equals(Object obj) { if (obj == null) { return false; } return str.equals(obj.toString()); } public void run() { } } }