diff options
author | Gordon Sim <gsim@apache.org> | 2009-06-29 13:24:23 +0000 |
---|---|---|
committer | Gordon Sim <gsim@apache.org> | 2009-06-29 13:24:23 +0000 |
commit | 22b88667e064da2322feb32f1bdb446de517f6db (patch) | |
tree | 6aefe492858dde82cb74565ea8c8ce7ca011b79a | |
parent | a9139896be73e0356ff0160009a6a9aac2db63f7 (diff) | |
download | qpid-python-22b88667e064da2322feb32f1bdb446de517f6db.tar.gz |
Added extra test script for testing ring queues plus a random data generation utility.
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@789317 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | cpp/src/tests/Makefile.am | 4 | ||||
-rw-r--r-- | cpp/src/tests/datagen.cpp | 96 | ||||
-rwxr-xr-x | cpp/src/tests/ring_queue_test | 174 |
3 files changed, 274 insertions, 0 deletions
diff --git a/cpp/src/tests/Makefile.am b/cpp/src/tests/Makefile.am index b20e8da96b..d922268ab4 100644 --- a/cpp/src/tests/Makefile.am +++ b/cpp/src/tests/Makefile.am @@ -234,6 +234,10 @@ check_PROGRAMS+=qpid_ping qpid_ping_SOURCES=qpid_ping.cpp test_tools.h TestOptions.h ConnectionOptions.h qpid_ping_LDADD=$(lib_client) +check_PROGRAMS+=datagen +datagen_SOURCES=datagen.cpp +datagen_LDADD=$(lib_common) + TESTS_ENVIRONMENT = \ VALGRIND=$(VALGRIND) \ diff --git a/cpp/src/tests/datagen.cpp b/cpp/src/tests/datagen.cpp new file mode 100644 index 0000000000..175f14cc57 --- /dev/null +++ b/cpp/src/tests/datagen.cpp @@ -0,0 +1,96 @@ +/* + * + * 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. + * + */ + +#include <exception> +#include <iostream> +#include <stdlib.h> +#include <time.h> +#include "qpid/Options.h" + +struct Args : public qpid::Options +{ + uint count; + uint minSize; + uint maxSize; + uint minChar; + uint maxChar; + bool help; + + Args() : qpid::Options("Random data generator"), + count(1), minSize(8), maxSize(4096), + minChar(32), maxChar(126),//safely printable ascii chars + help(false) + { + addOptions() + ("count", qpid::optValue(count, "N"), "number of data strings to generate") + ("min-size", qpid::optValue(minSize, "N"), "minimum size of data string") + ("max-size", qpid::optValue(maxSize, "N"), "maximum size of data string") + ("min-char", qpid::optValue(minChar, "N"), "minimum char value used in data string") + ("max-char", qpid::optValue(maxChar, "N"), "maximum char value used in data string") + ("help", qpid::optValue(help), "print this usage statement"); + } + + bool parse(int argc, char** argv) { + try { + qpid::Options::parse(argc, argv); + if (maxSize < minSize) throw qpid::Options::Exception("max-size must be greater than min-size"); + if (maxChar < minChar) throw qpid::Options::Exception("max-char must be greater than min-char"); + + if (help) { + std::cerr << *this << std::endl << std::endl; + } else { + return true; + } + } catch (const std::exception& e) { + std::cerr << *this << std::endl << std::endl << e.what() << std::endl; + } + return false; + } + +}; + +uint random(uint min, uint max) +{ + return (rand() % (max-min+1)) + min; +} + +std::string generateData(uint size, uint min, uint max) +{ + std::string data; + for (uint i = 0; i < size; i++) { + data += (char) random(min, max); + } + return data; +} + +int main(int argc, char** argv) +{ + Args opts; + if (opts.parse(argc, argv)) { + srand(time(0)); + for (uint i = 0; i < opts.count; i++) { + std::cout << generateData(random(opts.minSize, opts.maxSize), opts.minChar, opts.maxChar) << std::endl; + } + return 0; + } else { + return 1; + } +} diff --git a/cpp/src/tests/ring_queue_test b/cpp/src/tests/ring_queue_test new file mode 100755 index 0000000000..b6479cf16d --- /dev/null +++ b/cpp/src/tests/ring_queue_test @@ -0,0 +1,174 @@ +#!/bin/bash + +# +# 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. +# + +# Test script for validating the behaviour of a ring queue + +QUEUE_NAME=ring-queue +LIMIT=100 +DURABLE=0 +MESSAGES=10000 +SENDERS=1 +RECEIVERS=1 +CONCURRENT=0 + +setup() { + if [[ $DURABLE -gt 0 ]]; then + EXTRA_ARGS=" --durable" + fi + qpid-config add queue $QUEUE_NAME --max-queue-count $LIMIT --limit-policy ring $EXTRA_ARGS +} + +send() { + datagen --count $MESSAGES | tee sender_${QUEUE_NAME}_${1} | sender --durable $DURABLE --routing-key $QUEUE_NAME +} + +receive() { + #TODO: allow a variety of receiver options to be passed in (ack-frequency, credit-window etc) + receiver --queue $QUEUE_NAME > receiver_${QUEUE_NAME}_${1} +} + +cleanup() { + rm -f sender_${QUEUE_NAME}_* receiver_${QUEUE_NAME}_* + qpid-config add queue $QUEUE_NAME +} + +log() { + echo $1 +} + +fail() { + echo $1 + FAILED=1 +} + +validate() { + if [[ $RECEIVERS -eq 0 ]]; then + #queue should have $LIMIT messages on it, but need to send an eos also + sender --routing-key $QUEUE_NAME --send-eos 1 < /dev/null + if [[ $(receiver --queue $QUEUE_NAME --browse | wc -l) -eq $(( $LIMIT - 1)) ]]; then + log "queue contains $LIMIT messages as expected" + else + fail "queue does not contain the expected $LIMIT messages" + fi + elif [[ $CONCURRENT -eq 0 ]]; then + #sum of length of all output files should be equal to $LIMIT - $RECEIVERS (1 eos message each) + received=$(cat receiver_${QUEUE_NAME}_* | wc -l) + expected=$(( $LIMIT - $RECEIVERS )) + if [[ $received -eq $expected ]]; then + log "received $LIMIT messages as expected" + else + fail "received $received messages, expected $expected" + fi + #if there were only a single sender and receiver (executed serially) we can check the + #actual received contents + if [[ $RECEIVERS -eq 1 ]] && [[ $SENDERS -eq 1 ]]; then + tail -n $(($LIMIT - 1)) sender_${QUEUE_NAME}_1 | diff - receiver_${QUEUE_NAME}_1 || FAILED=1 + if [[ $FAILED -eq 1 ]]; then + fail "did not receive expected messages" + else + log "received messages matched expectations" + fi + fi + else + #multiple receivers, concurrent with senders; ring queue functionality cannot be validated in this case + if [[ $(cat receiver_${QUEUE_NAME}_* | wc -l) -le $(cat sender_${QUEUE_NAME}_* | wc -l) ]]; then + log "sent at least as many messages as were received" + else + #Note: if any receiver was browsing, this would be valid (would need to add 'sort | uniq') + # to pipeline above + fail "received more messages than were sent" + fi + fi + + if [[ $FAILED ]]; then + echo $(basename $0): FAILED + exit 1 + else + cleanup + fi +} + +run_test() { + if [[ $CONCURRENT -eq 0 ]]; then + echo "Starting $SENDERS senders followed by $RECEIVERS receivers " + else + echo "Starting $SENDERS senders concurrently with $RECEIVERS receivers" + fi + for ((i=1; i <= $SENDERS; i++)); do + send $i & + sender_pids[$i]=$! + done + if [[ $CONCURRENT -eq 0 ]] && [[ $RECEIVERS -gt 0 ]]; then + wait + sender --routing-key $QUEUE_NAME --send-eos $RECEIVERS < /dev/null + fi + for ((i=1; i <= $RECEIVERS; i++)); do + receive $i & + done + if [[ $CONCURRENT -gt 0 ]]; then + for ((i=1; i <= $SENDERS; i++)); do + wait ${sender_pids[$i]} + done + sender --routing-key $QUEUE_NAME --send-eos $RECEIVERS < /dev/null + fi + wait +} + +usage() { + cat <<EOF +$(basename $0): Test script for validating the behaviour of a ring queue + +Options: + -q <queue> the name of the queue to use + -s <senders> the number of senders to start + -r <receivers> the number of receivers to start + -u <url> + -l <limit> the limit for the ring queue + -m <messages> the number of messages to send + -c if specified, receivers will run concurrently with senders + -d if specified the queue and messages will be durable +EOF + exit 1 +} + +while getopts "s:r:m:u:dch" opt ; do + case $opt in + q) QUEUE_NAME=$OPTARG ;; + l) LIMIT=$OPTARG ;; + s) SENDERS=$OPTARG ;; + r) RECEIVERS=$OPTARG ;; + m) MESSAGES=$OPTARG ;; + u) URL=$OPTARG ;; + d) DURABLE=1 ;; + c) CONCURRENT=1 ;; + h) usage;; + ?) usage;; + esac +done + +if [[ $SENDERS -gt 0 ]]; then + setup + run_test + validate +else + echo "Nothing can be done if there are no senders" +fi + |