diff --git a/oslo_messaging/tests/functional/test_functional.py b/oslo_messaging/tests/functional/test_functional.py
index 39422f578..e1e90205d 100644
--- a/oslo_messaging/tests/functional/test_functional.py
+++ b/oslo_messaging/tests/functional/test_functional.py
@@ -11,6 +11,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import os
 import time
 import uuid
 
@@ -331,6 +332,13 @@ class NotifyTestCase(utils.SkipIfNoTransportURL):
             self.assertEqual(expected[3], actual[2])
 
     def test_simple_batch(self):
+        if self.url.startswith("amqp:"):
+            backend = os.environ.get("AMQP1_BACKEND")
+            if backend == "qdrouterd":
+                # end-to-end acknowledgement with router intermediary
+                # sender pends until batch_size or timeout reached
+                self.skipTest("qdrouterd backend")
+
         listener = self.useFixture(
             utils.BatchNotificationFixture(self.conf, self.url,
                                            ['test_simple_batch'],
diff --git a/setup-test-env-amqp1.sh b/setup-test-env-amqp1.sh
new file mode 100755
index 000000000..0ecfd0dd7
--- /dev/null
+++ b/setup-test-env-amqp1.sh
@@ -0,0 +1,191 @@
+#!/bin/bash
+#
+# Usage: setup-test-env-amqp.sh <command to run>
+# where AMQP1_BACKEND is the AMQP 1.0 intermediary to use. Valid
+# values are "qdrouterd" for router and "qpidd" for broker.
+set -e
+
+# router requires qdrouterd, sasl2-bin/cyrus-sasl-plain+cyrus-sasl-lib
+# broker requires qpidd, qpid-tools sasl2-bin/cyrus-sasl-plain+cyrus-sasl-lib
+
+. tools/functions.sh
+
+DATADIR=$(mktemp -d /tmp/OSLOMSG-${AMQP1_BACKEND}.XXXXX)
+trap "clean_exit $DATADIR" EXIT
+
+function _setup_qdrouterd_user {
+    echo secretqpid | saslpasswd2 -c -p -f ${DATADIR}/qdrouterd.sasldb stackqpid
+}
+
+function _setup_qpidd_user {
+    echo secretqpid | saslpasswd2 -c -p -f ${DATADIR}/qpidd.sasldb -u QPID stackqpid
+}
+
+function _configure_qdrouterd {
+    # create a stand alone router
+    cat > ${DATADIR}/qdrouterd.conf <<EOF
+router {
+    mode: standalone
+    id: Router.A
+    workerThreads: 4
+    saslConfigPath: ${DATADIR}/sasl2
+    saslConfigName: qdrouterd
+}
+
+EOF
+
+    # create a listener for incoming connect to the router
+    cat >> ${DATADIR}/qdrouterd.conf <<EOF
+listener {
+    addr: 0.0.0.0
+    port: 65123
+    role: normal
+    authenticatePeer: yes
+}
+
+EOF
+    # create fixed address prefixes
+    cat >> ${DATADIR}/qdrouterd.conf <<EOF
+address {
+    prefix: unicast
+    distribution: closest
+}
+
+address {
+    prefix: exclusive
+    distribution: closest
+}
+
+address {
+    prefix: broadcast
+    distribution: multicast
+}
+
+address {
+    prefix: openstack.org/om/rpc/multicast
+    distribution: multicast
+}
+
+address {
+    prefix: openstack.org/om/rpc/unicast
+    distribution: closest
+}
+
+address {
+    prefix: openstack.org/om/rpc/anycast
+    distribution: balanced
+}
+
+address {
+    prefix: openstack.org/om/notify/multicast
+    distribution: multicast
+}
+
+address {
+    prefix: openstack.org/om/notify/unicast
+    distribution: closest
+}
+
+address {
+    prefix: openstack.org/om/notify/anycast
+    distribution: balanced
+}
+
+EOF
+
+    # create log file configuration
+    cat >> ${DATADIR}/qdrouterd.conf <<EOF
+log {
+    module: DEFAULT
+    enable: trace+
+    output: ${DATADIR}/out
+}
+
+EOF
+    # sasl2 config
+    mkdir -p ${DATADIR}/sasl2
+    cat > ${DATADIR}/sasl2/qdrouterd.conf <<EOF
+pwcheck_method: auxprop
+auxprop_plugin: sasldb
+sasldb_path: ${DATADIR}/qdrouterd.sasldb
+mech_list: PLAIN ANONYMOUS
+EOF
+
+}
+
+function _configure_qpidd {
+
+    [ -f "/usr/lib/qpid/daemon/acl.so" ] && LIBACL="load-module=/usr/lib/qpid/daemon/acl.so"
+
+    cat > ${DATADIR}/qpidd.conf <<EOF
+port=65123
+sasl-config=${DATADIR}/sasl2
+${LIBACL}
+mgmt-enable=yes
+log-to-stderr=no
+EOF
+
+if ! `$(which qpidd 2>/dev/null) --help | grep -q "sasl-service-name"`; then
+    echo "This version of $QPIDD does not support SASL authentication with AMQP 1.0"
+    cat >> ${DATADIR}/qpidd.conf <<EOF
+auth=no
+EOF
+else
+    cat >> ${DATADIR}/qpidd.conf <<EOF
+auth=yes
+acl-file=${DATADIR}/qpidd.acl
+sasl-service-name=amqp
+EOF
+fi
+
+    cat >> ${DATADIR}/qpidd.conf <<EOF
+queue-patterns=exclusive
+queue-patterns=unicast
+topic-patterns=broadcast
+EOF
+
+    cat > ${DATADIR}/qpidd.acl <<EOF
+group admin stackqpid@QPID
+acl allow admin all
+acl deny all all
+EOF
+
+    mkdir -p ${DATADIR}/sasl2
+    cat > ${DATADIR}/sasl2/qpidd.conf <<EOF
+pwcheck_method: auxprop
+auxprop_plugin: sasldb
+sasldb_path: ${DATADIR}/qpidd.sasldb
+mech_list: PLAIN ANONYMOUS
+EOF
+
+}
+
+function _start_qdrouterd {
+    MAJOR=$(python -c 'import sys; print sys.version_info.major')
+    MINOR=$(python -c 'import sys; print sys.version_info.minor')
+    # qdrouterd needs access to global site packages
+    # create path file and place in virtual env working directory
+    SITEDIR=${WORKDIR}/${ENVNAME}/lib/python${MAJOR}.${MINOR}/site-packages
+    cat > ${SITEDIR}/dispatch.pth <<EOF
+/usr/lib/python${MAJOR}.${MINOR}/site-packages
+EOF
+
+    QDR=$(which qdrouterd 2>/dev/null)
+    mkfifo ${DATADIR}/out
+    $QDR --config ${DATADIR}/qdrouterd.conf &
+    wait_for_line "Router .*started" "error" ${DATADIR}/out
+    rm ${SITEDIR}/dispatch.pth
+}
+
+function _start_qpidd {
+    QPIDD=$(which qpidd 2>/dev/null)
+    mkfifo ${DATADIR}/out
+    $QPIDD --log-enable trace+ --log-to-file ${DATADIR}/out --config ${DATADIR}/qpidd.conf &
+    wait_for_line "Broker .*running" "error" ${DATADIR}/out
+}
+
+_configure_${AMQP1_BACKEND}
+_setup_${AMQP1_BACKEND}_user
+_start_${AMQP1_BACKEND}
+
+$*
diff --git a/setup-test-env-qpid.sh b/setup-test-env-qpid.sh
deleted file mode 100755
index c66d85cd5..000000000
--- a/setup-test-env-qpid.sh
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/bin/bash
-#
-# Usage: setup-test-env-qpid.sh PROTOCOL <command to run>
-# where PROTOCOL is the version of the AMQP protocol to use with
-# qpidd.  Valid values for PROTOCOL are "1", "1.0", "0-10", "0.10"
-set -e
-
-# require qpidd, qpid-tools sasl2-bin/cyrus-sasl-plain+cyrus-sasl-lib
-
-. tools/functions.sh
-
-DATADIR=$(mktemp -d /tmp/OSLOMSG-QPID.XXXXX)
-trap "clean_exit $DATADIR" EXIT
-
-QPIDD=$(which qpidd 2>/dev/null)
-
-# which protocol should be used with qpidd?
-# 1 for AMQP 1.0, 0.10 for AMQP 0.10
-#
-PROTOCOL=$1
-case $PROTOCOL in
-    "1" | "1.0")
-        PROTOCOL="1"
-        shift
-        ;;
-    "0.10" | "0-10")
-        PROTOCOL="0-10"
-        shift
-        ;;
-    *)
-        # assume the old protocol
-        echo "No protocol specified, assuming 0.10"
-        PROTOCOL="0-10"
-        ;;
-esac
-
-# ensure that the version of qpidd does support AMQP 1.0
-if [ $PROTOCOL == "1" ] && ! `$QPIDD --help | grep -q "queue-patterns"`; then
-    echo "This version of $QPIDD does not support AMQP 1.0"
-    exit 1
-fi
-
-[ -f "/usr/lib/qpid/daemon/acl.so" ] && LIBACL="load-module=/usr/lib/qpid/daemon/acl.so"
-
-cat > ${DATADIR}/qpidd.conf <<EOF
-port=65123
-sasl-config=${DATADIR}/sasl2
-${LIBACL}
-mgmt-enable=yes
-log-to-stderr=no
-EOF
-
-# sadly, older versions of qpidd (<=0.32) cannot authenticate against
-# newer versions of proton (>=0.10).  If this version of qpidd does
-# not support the fix, then do not require authentication
-
-if [ $PROTOCOL == "1" ] && ! `$QPIDD --help | grep -q "sasl-service-name"`; then
-    echo "This version of $QPIDD does not support SASL authentication with AMQP 1.0"
-    cat >> ${DATADIR}/qpidd.conf <<EOF
-auth=no
-EOF
-else
-    cat >> ${DATADIR}/qpidd.conf <<EOF
-auth=yes
-acl-file=${DATADIR}/qpidd.acl
-EOF
-fi
-
-if [ $PROTOCOL == "1" ]; then
-    cat >> ${DATADIR}/qpidd.conf <<EOF
-# Used by AMQP1.0 only
-queue-patterns=exclusive
-queue-patterns=unicast
-topic-patterns=broadcast
-EOF
-    # versions of qpidd >0.32 require this for AMQP 1 and SASL:
-    if `$QPIDD --help | grep -q "sasl-service-name"`; then
-        cat >> ${DATADIR}/qpidd.conf <<EOF
-sasl-service-name=amqp
-EOF
-    fi
-fi
-
-cat > ${DATADIR}/qpidd.acl <<EOF
-group admin stackqpid@QPID
-acl allow admin all
-acl deny all all
-EOF
-
-mkdir -p ${DATADIR}/sasl2
-cat > ${DATADIR}/sasl2/qpidd.conf <<EOF
-pwcheck_method: auxprop
-auxprop_plugin: sasldb
-sasldb_path: ${DATADIR}/qpidd.sasldb
-EOF
-
-# TODO(kgiusti): we can remove "ANONYMOUS" once proton 0.10.1+ is released:
-# https://issues.apache.org/jira/browse/PROTON-974
-if [ $PROTOCOL == "1" ]; then
-    cat >> ${DATADIR}/sasl2/qpidd.conf <<EOF
-mech_list: PLAIN ANONYMOUS
-EOF
-else
-    cat >> ${DATADIR}/sasl2/qpidd.conf <<EOF
-mech_list: PLAIN
-EOF
-fi
-
-echo secretqpid | saslpasswd2 -c -p -f ${DATADIR}/qpidd.sasldb -u QPID stackqpid
-
-mkfifo ${DATADIR}/out
-$QPIDD --log-enable info+ --log-to-file ${DATADIR}/out --config ${DATADIR}/qpidd.conf &
-wait_for_line "Broker .*running" "error" ${DATADIR}/out
-
-$*
diff --git a/tox.ini b/tox.ini
index c02313014..7039a25cd 100644
--- a/tox.ini
+++ b/tox.ini
@@ -43,21 +43,33 @@ setenv = TRANSPORT_DRIVER=pika
 commands = pifpaf run rabbitmq --  python setup.py testr --slowest --testr-args='{posargs:oslo_messaging.tests.functional}'
 
 [testenv:py27-func-amqp1]
-setenv = TRANSPORT_URL=amqp://stackqpid:secretqpid@127.0.0.1:65123//
+setenv =
+    TRANSPORT_URL=amqp://stackqpid:secretqpid@127.0.0.1:65123//
+    AMQP1_BACKEND=qpidd
+    ENVNAME={envname}
+    WORKDIR={toxworkdir}
 # NOTE(kgiusti): This gate job runs on Centos 7 for now.
-commands = {toxinidir}/setup-test-env-qpid.sh 1.0 python setup.py testr --slowest --testr-args='{posargs:oslo_messaging.tests.functional}'
+commands = {toxinidir}/setup-test-env-amqp1.sh python setup.py testr --slowest --testr-args='oslo_messaging.tests.functional'
 
 [testenv:py34-func-amqp1]
 basepython = python3.4
-setenv = TRANSPORT_URL=amqp://stackqpid:secretqpid@127.0.0.1:65123//
+setenv =
+    TRANSPORT_URL=amqp://stackqpid:secretqpid@127.0.0.1:65123//
+    AMQP1_BACKEND=qpidd
+    ENVNAME={envname}
+    WORKDIR={toxworkdir}
 # NOTE(kgiusti): This gate job runs on Centos 7 for now.
-commands = {toxinidir}/setup-test-env-qpid.sh 1.0 python setup.py testr --slowest --testr-args='{posargs:oslo_messaging.tests.functional}'
+commands = {toxinidir}/setup-test-env-amqp1.sh python setup.py testr --slowest --testr-args='oslo_messaging.tests.functional'
 
 [testenv:py35-func-amqp1]
 basepython = python3.5
-setenv = TRANSPORT_URL=amqp://stackqpid:secretqpid@127.0.0.1:65123//
+setenv =
+    TRANSPORT_URL=amqp://stackqpid:secretqpid@127.0.0.1:65123//
+    AMQP1_BACKEND=qpidd
+    ENVNAME={envname}
+    WORKDIR={toxworkdir}
 # NOTE(kgiusti): This gate job runs on Centos 7 for now.
-commands = {toxinidir}/setup-test-env-qpid.sh 1.0 python setup.py testr --slowest --testr-args='{posargs:oslo_messaging.tests.functional}'
+commands = {toxinidir}/setup-test-env-amqp1.sh python setup.py testr --slowest --testr-args='oslo_messaging.tests.functional'
 
 [testenv:py27-func-zeromq]
 commands = {toxinidir}/setup-test-env-zmq.sh python setup.py testr --slowest --testr-args='{posargs:oslo_messaging.tests.functional}'