This is an automated email from the ASF dual-hosted git repository.

xyz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pulsar-client-python.git


The following commit(s) were added to refs/heads/main by this push:
     new d14aada  Add CI job to build and run Python tests (#9)
d14aada is described below

commit d14aada9fc418c99f4be58f58289d1b884bcabdc
Author: Matteo Merli <[email protected]>
AuthorDate: Fri Oct 7 20:36:16 2022 -0700

    Add CI job to build and run Python tests (#9)
    
    Fixed build and added Github actions to validate PR with unit tests
---
 .github/workflows/ci-pr-validation.yaml            |  66 +++++
 .gitignore                                         |   3 +
 CMakeLists.txt                                     |  62 ++---
 .../install-cpp-client.sh                          |  26 +-
 .../pulsar-test-service-start.sh                   |  28 +-
 .../pulsar-test-service-stop.sh                    |  24 +-
 .../start-test-service-inside-container.sh         | 101 +++++++
 test_consumer.py => examples/consumer.py           |   0
 test_producer.py => examples/producer.py           |   0
 pulsar-client-cpp-version.txt                      |   1 +
 setup.py                                           |   5 +-
 tests/.gitignore                                   |   1 +
 .../custom_logger_test.py                          |   0
 pulsar_test.py => tests/pulsar_test.py             |  31 +--
 test_consumer.py => tests/run-unit-tests.sh        |  21 +-
 schema_test.py => tests/schema_test.py             |   0
 tests/test-conf/.htpasswd                          |   1 +
 tests/test-conf/broker-cert.pem                    | 117 ++++++++
 tests/test-conf/broker-key.pem                     |  27 ++
 tests/test-conf/cacert.pem                         | 127 +++++++++
 tests/test-conf/client-cert.pem                    |  90 ++++++
 tests/test-conf/client-key.pem                     |  27 ++
 .../test-conf/client-ssl.conf                      |  24 +-
 test_consumer.py => tests/test-conf/client.conf    |  25 +-
 tests/test-conf/cpp_credentials_file.json          |   4 +
 tests/test-conf/private-key.client-ecdsa.pem       |  13 +
 .../test-conf/private-key.client-mismatch-rsa.pem  |  29 ++
 tests/test-conf/private-key.client-rsa.pem         |  27 ++
 tests/test-conf/public-key.client-ecdsa.pem        |   7 +
 tests/test-conf/public-key.client-mismatch-rsa.pem |   9 +
 tests/test-conf/public-key.client-rsa.pem          |   9 +
 tests/test-conf/standalone-ssl.conf                | 309 +++++++++++++++++++++
 tests/test-conf/standalone.conf                    | 291 +++++++++++++++++++
 version.txt                                        |   6 +-
 34 files changed, 1350 insertions(+), 161 deletions(-)

diff --git a/.github/workflows/ci-pr-validation.yaml 
b/.github/workflows/ci-pr-validation.yaml
new file mode 100644
index 0000000..fb2a888
--- /dev/null
+++ b/.github/workflows/ci-pr-validation.yaml
@@ -0,0 +1,66 @@
+#
+# 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.
+#
+
+name: PR validation
+on:
+  pull_request:
+    branches: ['main']
+
+concurrency:
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+
+  unit-tests:
+    name: Run unit tests
+    runs-on: ubuntu-latest
+    timeout-minutes: 120
+
+    steps:
+      - name: checkout
+        uses: actions/checkout@v3
+
+      - name: Install deps
+        run: sudo apt-get install -y libboost-python-dev
+
+      - name: Install Pulsar C++ client
+        run: build-support/install-cpp-client.sh
+
+      - name: CMake
+        run: cmake .
+
+      - name: Build
+        run: make -j8
+
+      - name: Python install
+        run: |
+            ./setup.py bdist_wheel
+            WHEEL=$(find dist -name '*.whl')
+            pip3 install ${WHEEL}[avro]
+
+      - name: Start Pulsar service
+        run: ./build-support/pulsar-test-service-start.sh
+
+      - name: Run unit tests
+        run: ./tests/run-unit-tests.sh
+
+      - name: Stop Pulsar service
+        run: ./build-support/pulsar-test-service-stop.sh
+
diff --git a/.gitignore b/.gitignore
index 1a4bc13..fdff2ec 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,6 @@ Makefile
 _pulsar.so
 cmake_install.cmake
 __pycache__
+.build
+.pulsar-mac-wheels-cache
+.DS_Store
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6c994b2..087678c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,20 +21,26 @@ project (pulsar-client-python)
 cmake_minimum_required(VERSION 3.12)
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake_modules")
 
+option(LINK_STATIC "Link against static libraries" OFF)
+MESSAGE(STATUS "LINK_STATIC:  " ${LINK_STATIC})
+
 MESSAGE(STATUS "CMAKE_BUILD_TYPE:  " ${CMAKE_BUILD_TYPE})
 set(THREADS_PREFER_PTHREAD_FLAG TRUE)
 find_package(Threads REQUIRED)
 MESSAGE(STATUS "Threads library: " ${CMAKE_THREAD_LIBS_INIT})
 
-
-find_library(PULSAR_LIBRARY NAMES libpulsar.a)
+if (LINK_STATIC)
+    find_library(PULSAR_LIBRARY NAMES libpulsar.a)
+else()
+    find_library(PULSAR_LIBRARY NAMES libpulsar.so)
+endif()
 message(STATUS "PULSAR_LIBRARY: ${PULSAR_LIBRARY}")
 
 find_path(PULSAR_INCLUDE pulsar/Client.h)
 message(STATUS "PULSAR_INCLUDE: ${PULSAR_INCLUDE}")
 
 SET(Boost_NO_BOOST_CMAKE ON)
-SET(Boost_USE_STATIC_LIBS   ON)
+SET(Boost_USE_STATIC_LIBS   ${LINK_STATIC})
 
 SET(CMAKE_CXX_STANDARD 11)
 
@@ -63,32 +69,6 @@ endif ()
 
 MESSAGE(STATUS "BOOST_PYTHON_NAME_FOUND: " ${BOOST_PYTHON_NAME_FOUND})
 
-set(OPENSSL_ROOT_DIR ${OPENSSL_ROOT_DIR} /usr/lib64/)
-
-### This part is to find and keep SSL dynamic libs in 
RECORD_OPENSSL_SSL_LIBRARY and RECORD_OPENSSL_CRYPTO_LIBRARY
-### After find the libs, will unset related cache, and will not affect another 
same call to find_package.
-if (APPLE)
-    set(OPENSSL_INCLUDE_DIR /usr/local/opt/openssl/include/ 
/opt/homebrew/opt/openssl/include)
-    set(OPENSSL_ROOT_DIR ${OPENSSL_ROOT_DIR} /usr/local/opt/openssl/ 
/opt/homebrew/opt/openssl)
-endif ()
-
-set(OPENSSL_USE_STATIC_LIBS TRUE)
-find_package(OpenSSL REQUIRED)
-
-find_library(ZLIB_LIBRARIES REQUIRED NAMES libz.a z zlib)
-message(STATUS "ZLIB_LIBRARIES: ${ZLIB_LIBRARIES}")
-
-find_library(CURL_LIBRARIES NAMES libcurl.a curl curl_a libcurl_a)
-message(STATUS "CURL_LIBRARIES: ${CURL_LIBRARIES}")
-find_library(Protobuf_LIBRARIES NAMES libprotobuf.a libprotobuf)
-message(STATUS "Protobuf: ${Protobuf_LIBRARIES}")
-find_library(CURL_LIBRARIES NAMES libcurl.a curl curl_a libcurl_a)
-message(STATUS "CURL_LIBRARIES: ${CURL_LIBRARIES}")
-find_library(LIB_ZSTD NAMES libzstd.a)
-message(STATUS "ZStd: ${LIB_ZSTD}")
-find_library(LIB_SNAPPY NAMES libsnappy.a)
-message(STATUS "LIB_SNAPPY: ${LIB_SNAPPY}")
-
 
########################################################################################################################
 
 INCLUDE_DIRECTORIES(${PULSAR_INCLUDE} "${Boost_INCLUDE_DIRS}" 
"${Python3_INCLUDE_DIRS}")
@@ -138,12 +118,6 @@ endif()
 
 # Try all possible boost-python variable namings
 set(PYTHON_WRAPPER_LIBS ${PULSAR_LIBRARY}
-                        ${OPENSSL_LIBRARIES}
-                        ${ZLIB_LIBRARIES}
-                        ${CURL_LIBRARIES}
-                        ${Protobuf_LIBRARIES}
-                        ${LIB_ZSTD}
-                        ${LIB_SNAPPY}
                         ${Boost_PYTHON_LIBRARY}
                         ${Boost_PYTHON3_LIBRARY}
                         ${Boost_PYTHON37-MT_LIBRARY}
@@ -173,13 +147,17 @@ endif ()
 
 message(STATUS "All libraries: ${PYTHON_WRAPPER_LIBS}")
 
-if (APPLE)
-    set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS 
"${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS} -undefined dynamic_lookup")
-    target_link_libraries(_pulsar -Wl,-all_load ${PYTHON_WRAPPER_LIBS})
-else ()
-    if (NOT MSVC)
-      set (CMAKE_SHARED_LINKER_FLAGS " -static-libgcc  -static-libstdc++")
-    endif()
+if (LINK_STATIC)
+    if (APPLE)
+        set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS 
"${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS} -undefined dynamic_lookup")
+        target_link_libraries(_pulsar -Wl,-all_load ${PYTHON_WRAPPER_LIBS})
+    else ()
+        if (NOT MSVC)
+          set (CMAKE_SHARED_LINKER_FLAGS " -static-libgcc  -static-libstdc++")
+        endif()
+        target_link_libraries(_pulsar ${PYTHON_WRAPPER_LIBS})
+    endif ()
+else()
     target_link_libraries(_pulsar ${PYTHON_WRAPPER_LIBS})
 endif ()
 
diff --git a/test_consumer.py b/build-support/install-cpp-client.sh
similarity index 57%
copy from test_consumer.py
copy to build-support/install-cpp-client.sh
index 8c2985e..2efe8f2 100755
--- a/test_consumer.py
+++ b/build-support/install-cpp-client.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env bash
 #
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
@@ -18,19 +18,19 @@
 # under the License.
 #
 
+set -e -x
 
-import pulsar
+ROOT_DIR=$(git rev-parse --show-toplevel)
 
-client = pulsar.Client('pulsar://localhost:6650')
-consumer = client.subscribe('my-topic', "my-subscription",
-                            properties={
-                                "consumer-name": "test-consumer-name",
-                                "consumer-id": "test-consumer-id"
-                            })
+cd $ROOT_DIR
 
-while True:
-    msg = consumer.receive()
-    print("Received message '{0}' id='{1}'".format(msg.data().decode('utf-8'), 
msg.message_id()))
-    consumer.acknowledge(msg)
+CPP_CLIENT_VERSION=$(cat pulsar-client-cpp-version.txt | xargs)
 
-client.close()
+# Fetch the client binaries
+## TODO: Fetch from official release once it's available
+pushd /tmp
+  curl -L -O 
https://github.com/merlimat/pulsar-client-cpp/releases/download/${CPP_CLIENT_VERSION}/apache-pulsar-client.deb
+  curl -L -O 
https://github.com/merlimat/pulsar-client-cpp/releases/download/${CPP_CLIENT_VERSION}/apache-pulsar-client-dev.deb
+popd
+
+sudo apt install /tmp/apache-pulsar-client.deb 
/tmp/apache-pulsar-client-dev.deb
diff --git a/test_consumer.py b/build-support/pulsar-test-service-start.sh
similarity index 54%
copy from test_consumer.py
copy to build-support/pulsar-test-service-start.sh
index 8c2985e..a44fafe 100755
--- a/test_consumer.py
+++ b/build-support/pulsar-test-service-start.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env bash
 #
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
@@ -18,19 +18,21 @@
 # under the License.
 #
 
+set -e
 
-import pulsar
+SRC_DIR=$(git rev-parse --show-toplevel)
+cd $SRC_DIR
 
-client = pulsar.Client('pulsar://localhost:6650')
-consumer = client.subscribe('my-topic', "my-subscription",
-                            properties={
-                                "consumer-name": "test-consumer-name",
-                                "consumer-id": "test-consumer-id"
-                            })
+./build-support/pulsar-test-service-stop.sh
 
-while True:
-    msg = consumer.receive()
-    print("Received message '{0}' id='{1}'".format(msg.data().decode('utf-8'), 
msg.message_id()))
-    consumer.acknowledge(msg)
+CONTAINER_ID=$(docker run -i -p 8080:8080 -p 6650:6650 -p 8443:8443 -p 
6651:6651 --rm --detach apachepulsar/pulsar:latest sleep 3600)
+echo $CONTAINER_ID > .tests-container-id.txt
 
-client.close()
+docker cp tests/test-conf $CONTAINER_ID:/pulsar/test-conf
+docker cp build-support/start-test-service-inside-container.sh 
$CONTAINER_ID:start-test-service-inside-container.sh
+
+docker exec -i $CONTAINER_ID /start-test-service-inside-container.sh
+
+docker cp $CONTAINER_ID:/pulsar/data/tokens/token.txt tests/.test-token.txt
+
+echo "-- Ready to start tests"
diff --git a/test_consumer.py b/build-support/pulsar-test-service-stop.sh
similarity index 59%
copy from test_consumer.py
copy to build-support/pulsar-test-service-stop.sh
index 8c2985e..9d3bf4e 100755
--- a/test_consumer.py
+++ b/build-support/pulsar-test-service-stop.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env bash
 #
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
@@ -18,19 +18,15 @@
 # under the License.
 #
 
+set -e
 
-import pulsar
+SRC_DIR=$(git rev-parse --show-toplevel)
+cd $SRC_DIR
 
-client = pulsar.Client('pulsar://localhost:6650')
-consumer = client.subscribe('my-topic', "my-subscription",
-                            properties={
-                                "consumer-name": "test-consumer-name",
-                                "consumer-id": "test-consumer-id"
-                            })
+CONTAINER_ID_PATH=".tests-container-id.txt"
 
-while True:
-    msg = consumer.receive()
-    print("Received message '{0}' id='{1}'".format(msg.data().decode('utf-8'), 
msg.message_id()))
-    consumer.acknowledge(msg)
-
-client.close()
+if [ -f ${CONTAINER_ID_PATH} ]; then
+  CONTAINER_ID=$(cat $CONTAINER_ID_PATH)
+  docker kill $CONTAINER_ID || true
+  rm .tests-container-id.txt
+fi
diff --git a/build-support/start-test-service-inside-container.sh 
b/build-support/start-test-service-inside-container.sh
new file mode 100755
index 0000000..0517f77
--- /dev/null
+++ b/build-support/start-test-service-inside-container.sh
@@ -0,0 +1,101 @@
+#!/usr/bin/env 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.
+#
+
+set -e -x
+
+export PULSAR_EXTRA_OPTS=-Dpulsar.auth.basic.conf=test-conf/.htpasswd
+
+# Generate secret key and token
+mkdir -p data/tokens
+bin/pulsar tokens create-secret-key --output data/tokens/secret.key
+
+bin/pulsar tokens create \
+            --subject token-principal \
+            --secret-key file:///pulsar/data/tokens/secret.key \
+            > /pulsar/data/tokens/token.txt
+
+export PULSAR_STANDALONE_CONF=test-conf/standalone-ssl.conf
+export PULSAR_PID_DIR=/tmp
+bin/pulsar-daemon start standalone \
+        --no-functions-worker --no-stream-storage \
+        --bookkeeper-dir data/bookkeeper
+
+echo "-- Wait for Pulsar service to be ready"
+until curl http://localhost:8080/metrics > /dev/null 2>&1 ; do sleep 1; done
+
+echo "-- Pulsar service is ready -- Configure permissions"
+
+export PULSAR_CLIENT_CONF=test-conf/client-ssl.conf
+
+# Create "standalone" cluster if it does not exist
+bin/pulsar-admin clusters list | grep -q '^standalone$' ||
+        bin/pulsar-admin clusters create \
+                standalone \
+                --url http://localhost:8080/ \
+                --url-secure https://localhost:8443/ \
+                --broker-url pulsar://localhost:6650/ \
+                --broker-url-secure pulsar+ssl://localhost:6651/
+
+# Update "public" tenant
+bin/pulsar-admin tenants create public -r "anonymous" -c "standalone"
+
+# Update "public/default" with no auth required
+bin/pulsar-admin namespaces create public/default -c standalone
+bin/pulsar-admin namespaces grant-permission public/default \
+                        --actions produce,consume \
+                        --role "anonymous"
+
+# Create "public/default-2" with no auth required
+bin/pulsar-admin namespaces create public/default-2 \
+                        --clusters standalone
+bin/pulsar-admin namespaces grant-permission public/default-2 \
+                        --actions produce,consume \
+                        --role "anonymous"
+
+# Create "public/default-3" with no auth required
+bin/pulsar-admin namespaces create public/default-3 \
+                        --clusters standalone
+bin/pulsar-admin namespaces grant-permission public/default-3 \
+                        --actions produce,consume \
+                        --role "anonymous"
+
+# Create "public/default-4" with encryption required
+bin/pulsar-admin namespaces create public/default-4 \
+                        --clusters standalone
+bin/pulsar-admin namespaces grant-permission public/default-4 \
+                        --actions produce,consume \
+                        --role "anonymous"
+bin/pulsar-admin namespaces set-encryption-required public/default-4 -e
+
+# Create "public/test-backlog-quotas" to test backlog quotas policy
+bin/pulsar-admin namespaces create public/test-backlog-quotas \
+                        --clusters standalone
+
+# Create "private" tenant
+bin/pulsar-admin tenants create private -r "" -c "standalone"
+
+# Create "private/auth" with required authentication
+bin/pulsar-admin namespaces create private/auth --clusters standalone
+
+bin/pulsar-admin namespaces grant-permission private/auth \
+                        --actions produce,consume \
+                        --role "token-principal"
+
+echo "-- Ready to start tests"
diff --git a/test_consumer.py b/examples/consumer.py
similarity index 100%
copy from test_consumer.py
copy to examples/consumer.py
diff --git a/test_producer.py b/examples/producer.py
similarity index 100%
rename from test_producer.py
rename to examples/producer.py
diff --git a/pulsar-client-cpp-version.txt b/pulsar-client-cpp-version.txt
new file mode 100644
index 0000000..6390d75
--- /dev/null
+++ b/pulsar-client-cpp-version.txt
@@ -0,0 +1 @@
+3.0.0-pre-1
diff --git a/setup.py b/setup.py
old mode 100644
new mode 100755
index 1263df4..f20446f
--- a/setup.py
+++ b/setup.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python3
 #
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
@@ -29,9 +30,7 @@ def get_version():
     root = path.dirname(path.realpath(__file__))
     version_file = path.join(root, 'version.txt')
     with open(version_file) as f:
-        for line in f.readlines():
-            if 'pulsar-client-python: ' in line:
-                return line.split()[-1].strip()
+        return f.read().strip()
 
 
 def get_name():
diff --git a/tests/.gitignore b/tests/.gitignore
new file mode 100644
index 0000000..dcf8e28
--- /dev/null
+++ b/tests/.gitignore
@@ -0,0 +1 @@
+.test-token.txt
\ No newline at end of file
diff --git a/custom_logger_test.py b/tests/custom_logger_test.py
similarity index 100%
rename from custom_logger_test.py
rename to tests/custom_logger_test.py
diff --git a/pulsar_test.py b/tests/pulsar_test.py
similarity index 97%
rename from pulsar_test.py
rename to tests/pulsar_test.py
index 375afe4..86abbfe 100755
--- a/pulsar_test.py
+++ b/tests/pulsar_test.py
@@ -46,12 +46,7 @@ from _pulsar import ProducerConfiguration, 
ConsumerConfiguration
 
 from schema_test import *
 
-try:
-    # For Python 3.0 and later
-    from urllib.request import urlopen, Request
-except ImportError:
-    # Fall back to Python 2's urllib2
-    from urllib2 import urlopen, Request
+from urllib.request import urlopen, Request
 
 TM = 10000  # Do not wait forever in tests
 
@@ -324,9 +319,7 @@ class PulsarTest(TestCase):
         client.close()
 
     def test_tls_auth(self):
-        certs_dir = 
"/pulsar/pulsar-broker/src/test/resources/authentication/tls/"
-        if not os.path.exists(certs_dir):
-            certs_dir = 
"../../pulsar-broker/src/test/resources/authentication/tls/"
+        certs_dir = "test-conf/"
         client = Client(
             self.serviceUrlTls,
             tls_trust_certs_file_path=certs_dir + "cacert.pem",
@@ -349,9 +342,7 @@ class PulsarTest(TestCase):
         client.close()
 
     def test_tls_auth2(self):
-        certs_dir = 
"/pulsar/pulsar-broker/src/test/resources/authentication/tls/"
-        if not os.path.exists(certs_dir):
-            certs_dir = 
"../../pulsar-broker/src/test/resources/authentication/tls/"
+        certs_dir = "test-conf/"
         authPlugin = "org.apache.pulsar.client.impl.auth.AuthenticationTls"
         authParams = 
"tlsCertFile:%s/client-cert.pem,tlsKeyFile:%s/client-key.pem" % (certs_dir, 
certs_dir)
 
@@ -377,8 +368,8 @@ class PulsarTest(TestCase):
         client.close()
 
     def test_encryption(self):
-        publicKeyPath = 
"/pulsar//pulsar-broker/src/test/resources/certificate/public-key.client-rsa.pem"
-        privateKeyPath = 
"/pulsar/pulsar-broker/src/test/resources/certificate/private-key.client-rsa.pem"
+        publicKeyPath = "test-conf/public-key.client-rsa.pem"
+        privateKeyPath = "test-conf/private-key.client-rsa.pem"
         crypto_key_reader = CryptoKeyReader(publicKeyPath, privateKeyPath)
         client = Client(self.serviceUrl)
         topic = "my-python-test-end-to-end-encryption"
@@ -409,9 +400,7 @@ class PulsarTest(TestCase):
         client.close()
 
     def test_tls_auth3(self):
-        certs_dir = 
"/pulsar/pulsar-broker/src/test/resources/authentication/tls/"
-        if not os.path.exists(certs_dir):
-            certs_dir = 
"../../pulsar-broker/src/test/resources/authentication/tls/"
+        certs_dir = "test-conf/"
         authPlugin = "tls"
         authParams = 
"tlsCertFile:%s/client-cert.pem,tlsKeyFile:%s/client-key.pem" % (certs_dir, 
certs_dir)
 
@@ -437,9 +426,7 @@ class PulsarTest(TestCase):
         client.close()
 
     def test_auth_junk_params(self):
-        certs_dir = 
"/pulsar/pulsar-broker/src/test/resources/authentication/tls/"
-        if not os.path.exists(certs_dir):
-            certs_dir = 
"../../pulsar-broker/src/test/resources/authentication/tls/"
+        certs_dir = "test-conf/"
         authPlugin = "someoldjunk.so"
         authParams = "blah"
         client = Client(
@@ -1077,7 +1064,7 @@ class PulsarTest(TestCase):
         client.close()
 
     def test_token_auth(self):
-        with open("/tmp/pulsar-test-data/tokens/token.txt") as tf:
+        with open(".test-token.txt") as tf:
             token = tf.read().strip()
 
         # Use adminUrl to test both HTTP request and binary protocol
@@ -1096,7 +1083,7 @@ class PulsarTest(TestCase):
 
     def test_token_auth_supplier(self):
         def read_token():
-            with open("/tmp/pulsar-test-data/tokens/token.txt") as tf:
+            with open(".test-token.txt") as tf:
                 return tf.read().strip()
 
         client = Client(self.serviceUrl, 
authentication=AuthenticationToken(read_token))
diff --git a/test_consumer.py b/tests/run-unit-tests.sh
similarity index 59%
copy from test_consumer.py
copy to tests/run-unit-tests.sh
index 8c2985e..13349f9 100755
--- a/test_consumer.py
+++ b/tests/run-unit-tests.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+#!/usr/bin/env bash
 #
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
@@ -18,19 +18,10 @@
 # under the License.
 #
 
+set -e -x
 
-import pulsar
+ROOT_DIR=$(git rev-parse --show-toplevel)
+cd $ROOT_DIR/tests
 
-client = pulsar.Client('pulsar://localhost:6650')
-consumer = client.subscribe('my-topic', "my-subscription",
-                            properties={
-                                "consumer-name": "test-consumer-name",
-                                "consumer-id": "test-consumer-id"
-                            })
-
-while True:
-    msg = consumer.receive()
-    print("Received message '{0}' id='{1}'".format(msg.data().decode('utf-8'), 
msg.message_id()))
-    consumer.acknowledge(msg)
-
-client.close()
+python3 custom_logger_test.py
+python3 pulsar_test.py
diff --git a/schema_test.py b/tests/schema_test.py
similarity index 100%
rename from schema_test.py
rename to tests/schema_test.py
diff --git a/tests/test-conf/.htpasswd b/tests/test-conf/.htpasswd
new file mode 100644
index 0000000..2aa3a47
--- /dev/null
+++ b/tests/test-conf/.htpasswd
@@ -0,0 +1 @@
+admin:$apr1$FG4AO6aX$KGYPuMoLUou3i6vUkPUUf.
diff --git a/tests/test-conf/broker-cert.pem b/tests/test-conf/broker-cert.pem
new file mode 100644
index 0000000..8d0a02f
--- /dev/null
+++ b/tests/test-conf/broker-cert.pem
@@ -0,0 +1,117 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 4098 (0x1002)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=US, ST=California, L=Palo Alto, O=Apache Software 
Foundation, OU=Pulsar, CN=Pulsar CA/[email protected]
+        Validity
+            Not Before: Feb 17 17:00:44 2021 GMT
+            Not After : Feb 12 17:00:44 2041 GMT
+        Subject: C=US, ST=California, O=Apache Software Foundation, OU=Pulsar, 
CN=localhost/[email protected]
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:9b:2a:6f:24:02:23:f7:ff:e6:75:61:ca:07:a8:
+                    c0:ab:e9:8d:eb:51:2e:64:f7:9e:9b:d4:b4:be:3a:
+                    fa:f4:6e:c6:92:8f:38:4d:08:cd:89:15:3e:2c:c4:
+                    99:6d:cb:58:80:fc:e0:4d:d6:7d:f6:82:ab:0d:94:
+                    f2:e2:45:c9:d3:15:95:57:0a:6c:86:dc:78:64:3b:
+                    34:4b:01:7c:5d:de:4f:d4:21:1a:5d:27:a0:a5:70:
+                    7a:2e:02:50:e1:19:b4:b9:05:df:99:0d:8b:cc:62:
+                    dc:10:73:fa:72:8b:38:7f:d3:56:54:61:50:bb:92:
+                    ff:09:71:09:c7:bd:04:43:3c:8c:9c:8b:32:d1:05:
+                    04:8a:c6:89:d8:78:56:4d:da:2f:f4:ec:34:37:26:
+                    b5:87:e4:3f:26:c9:41:60:ba:31:10:19:be:f8:0c:
+                    a4:0a:85:19:59:e2:00:5d:b7:c0:bd:d1:2e:fc:a6:
+                    34:8b:85:2a:cc:05:f6:fb:e4:00:e6:74:95:ff:02:
+                    6f:43:7f:39:a7:c2:83:8e:5b:38:40:c9:42:c8:bc:
+                    26:72:36:35:64:c2:54:22:11:87:e8:65:8f:3d:e9:
+                    41:a7:6d:19:88:9a:20:9b:9a:52:e7:d2:cb:b3:e0:
+                    2e:8f:c1:56:54:bc:6d:14:30:73:c5:d7:8e:d0:5a:
+                    5e:cd
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints:
+                CA:FALSE
+            Netscape Cert Type:
+                SSL Server
+            Netscape Comment:
+                OpenSSL Generated Server Certificate
+            X509v3 Subject Key Identifier:
+                49:3C:B2:98:30:CE:7F:79:7A:C6:8B:57:CA:24:9F:12:82:1E:5D:EF
+            X509v3 Authority Key Identifier:
+                
keyid:D2:B2:3D:B1:A4:7C:48:4B:36:E1:A7:DE:D8:FC:BA:92:BA:A7:C4:71
+                DirName:/C=US/ST=California/L=Palo Alto/O=Apache Software 
Foundation/OU=Pulsar/CN=Pulsar CA/[email protected]
+                
serial:52:7B:B4:00:96:60:B4:26:85:BE:01:82:B8:B8:E2:8C:72:EF:5B:90
+
+            X509v3 Key Usage: critical
+                Digital Signature, Key Encipherment
+            X509v3 Extended Key Usage:
+                TLS Web Server Authentication
+    Signature Algorithm: sha256WithRSAEncryption
+         0f:bd:af:39:0c:2c:dc:8f:7e:06:0d:27:df:35:c7:8d:5a:03:
+         68:97:f6:dc:d6:d3:39:0e:b4:76:48:7d:e1:1c:a9:4b:83:fa:
+         52:00:ab:28:93:2d:06:76:0c:14:35:3c:f1:8e:3b:af:c8:d0:
+         27:1f:58:d4:71:22:5f:05:a6:9e:73:c6:a5:5e:2a:e6:fb:eb:
+         fc:73:52:87:ca:8a:2a:f9:1e:5f:e2:b9:bd:01:27:9f:7c:61:
+         a6:97:ad:a0:ab:4e:fb:cc:fa:c8:77:6a:65:1b:ae:60:5e:fb:
+         97:14:8c:40:d7:96:c6:2c:64:59:c0:52:52:7c:2d:98:4b:f4:
+         72:da:83:f7:c6:4f:32:42:ce:df:02:dd:5f:eb:58:42:f9:62:
+         a1:9a:05:ef:13:48:27:af:a3:7f:23:eb:e0:dc:1d:8f:96:2a:
+         88:47:f7:e4:75:6f:a9:15:f6:44:f1:6d:39:3a:2c:df:a7:82:
+         cc:7e:aa:9c:1c:c0:a7:7d:68:31:4a:4e:21:b8:9f:17:90:4b:
+         f1:68:23:ef:a7:53:fc:a9:a8:35:6b:8f:4c:5e:d4:ea:b0:8a:
+         27:9a:86:89:ce:f2:5d:03:35:80:fc:45:e8:87:66:0f:32:b5:
+         2a:f5:1b:79:0e:09:8b:90:40:20:fb:e3:27:8a:c9:92:c1:53:
+         97:10:5a:8c:50:ef:02:46:7e:ec:68:c8:1e:26:66:0e:1d:d6:
+         6c:82:e7:38:14:e8:cb:45:77:29:5f:2c:1a:9d:d7:54:21:8a:
+         cf:0f:b7:0c:ae:fe:d6:fb:fb:c3:07:3e:33:df:59:25:1c:73:
+         d4:87:73:14:b4:76:16:8a:3f:82:05:7b:42:0a:55:0c:79:24:
+         3c:58:31:3f:e0:3e:9f:4e:d0:0e:fd:77:b7:13:2c:d3:d0:46:
+         cc:80:09:0f:50:56:8b:6e:6e:91:b2:5b:c8:2f:4d:86:dc:72:
+         00:de:08:0d:5e:3e:96:1f:12:7d:3b:0d:4d:71:d5:c8:a8:06:
+         ba:00:23:ec:10:4c:a4:c3:6f:bc:f0:d7:b1:cf:57:3f:3b:79:
+         db:80:87:35:c7:4e:7f:bb:38:30:0a:9f:fe:5a:86:f5:97:ce:
+         24:38:79:fd:a0:dc:0b:82:11:a1:ea:0c:e9:16:65:e0:c0:54:
+         80:ad:6e:55:18:ac:27:35:3a:b0:20:70:62:8e:5d:a2:33:53:
+         8c:ce:f9:ee:a1:27:cb:db:e5:9a:5e:e6:f7:80:93:84:63:04:
+         26:58:ab:23:bb:94:80:d0:a0:55:a2:8a:ed:bc:0f:c3:41:d2:
+         26:a5:b9:8d:8a:45:e8:a1:fc:e8:ee:7a:64:93:ed:d6:ef:a2:
+         51:d7:c9:0a:31:39:35:4a
+-----BEGIN CERTIFICATE-----
+MIIGPDCCBCSgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwgaYxCzAJBgNVBAYTAlVT
+MRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlQYWxvIEFsdG8xIzAhBgNV
+BAoMGkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uMQ8wDQYDVQQLDAZQdWxzYXIx
+EjAQBgNVBAMMCVB1bHNhciBDQTEkMCIGCSqGSIb3DQEJARYVZGV2QHB1bHNhci5h
+cGFjaGUub3JnMB4XDTIxMDIxNzE3MDA0NFoXDTQxMDIxMjE3MDA0NFowgZIxCzAJ
+BgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMSMwIQYDVQQKDBpBcGFjaGUg
+U29mdHdhcmUgRm91bmRhdGlvbjEPMA0GA1UECwwGUHVsc2FyMRIwEAYDVQQDDAls
+b2NhbGhvc3QxJDAiBgkqhkiG9w0BCQEWFWRldkBwdWxzYXIuYXBhY2hlLm9yZzCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJsqbyQCI/f/5nVhygeowKvp
+jetRLmT3npvUtL46+vRuxpKPOE0IzYkVPizEmW3LWID84E3WffaCqw2U8uJFydMV
+lVcKbIbceGQ7NEsBfF3eT9QhGl0noKVwei4CUOEZtLkF35kNi8xi3BBz+nKLOH/T
+VlRhULuS/wlxCce9BEM8jJyLMtEFBIrGidh4Vk3aL/TsNDcmtYfkPybJQWC6MRAZ
+vvgMpAqFGVniAF23wL3RLvymNIuFKswF9vvkAOZ0lf8Cb0N/OafCg45bOEDJQsi8
+JnI2NWTCVCIRh+hljz3pQadtGYiaIJuaUufSy7PgLo/BVlS8bRQwc8XXjtBaXs0C
+AwEAAaOCAYQwggGAMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQDAgZAMDMGCWCG
+SAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRlZCBTZXJ2ZXIgQ2VydGlmaWNhdGUw
+HQYDVR0OBBYEFEk8spgwzn95esaLV8oknxKCHl3vMIHmBgNVHSMEgd4wgduAFNKy
+PbGkfEhLNuGn3tj8upK6p8RxoYGspIGpMIGmMQswCQYDVQQGEwJVUzETMBEGA1UE
+CAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJUGFsbyBBbHRvMSMwIQYDVQQKDBpBcGFj
+aGUgU29mdHdhcmUgRm91bmRhdGlvbjEPMA0GA1UECwwGUHVsc2FyMRIwEAYDVQQD
+DAlQdWxzYXIgQ0ExJDAiBgkqhkiG9w0BCQEWFWRldkBwdWxzYXIuYXBhY2hlLm9y
+Z4IUUnu0AJZgtCaFvgGCuLjijHLvW5AwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQM
+MAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4ICAQAPva85DCzcj34GDSffNceN
+WgNol/bc1tM5DrR2SH3hHKlLg/pSAKsoky0GdgwUNTzxjjuvyNAnH1jUcSJfBaae
+c8alXirm++v8c1KHyooq+R5f4rm9ASeffGGml62gq077zPrId2plG65gXvuXFIxA
+15bGLGRZwFJSfC2YS/Ry2oP3xk8yQs7fAt1f61hC+WKhmgXvE0gnr6N/I+vg3B2P
+liqIR/fkdW+pFfZE8W05Oizfp4LMfqqcHMCnfWgxSk4huJ8XkEvxaCPvp1P8qag1
+a49MXtTqsIonmoaJzvJdAzWA/EXoh2YPMrUq9Rt5DgmLkEAg++MnismSwVOXEFqM
+UO8CRn7saMgeJmYOHdZsguc4FOjLRXcpXywanddUIYrPD7cMrv7W+/vDBz4z31kl
+HHPUh3MUtHYWij+CBXtCClUMeSQ8WDE/4D6fTtAO/Xe3EyzT0EbMgAkPUFaLbm6R
+slvIL02G3HIA3ggNXj6WHxJ9Ow1NcdXIqAa6ACPsEEykw2+88Nexz1c/O3nbgIc1
+x05/uzgwCp/+Wob1l84kOHn9oNwLghGh6gzpFmXgwFSArW5VGKwnNTqwIHBijl2i
+M1OMzvnuoSfL2+WaXub3gJOEYwQmWKsju5SA0KBVoortvA/DQdImpbmNikXoofzo
+7npkk+3W76JR18kKMTk1Sg==
+-----END CERTIFICATE-----
diff --git a/tests/test-conf/broker-key.pem b/tests/test-conf/broker-key.pem
new file mode 100644
index 0000000..ee03e75
--- /dev/null
+++ b/tests/test-conf/broker-key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAmypvJAIj9//mdWHKB6jAq+mN61EuZPeem9S0vjr69G7Gko84
+TQjNiRU+LMSZbctYgPzgTdZ99oKrDZTy4kXJ0xWVVwpshtx4ZDs0SwF8Xd5P1CEa
+XSegpXB6LgJQ4Rm0uQXfmQ2LzGLcEHP6cos4f9NWVGFQu5L/CXEJx70EQzyMnIsy
+0QUEisaJ2HhWTdov9Ow0Nya1h+Q/JslBYLoxEBm++AykCoUZWeIAXbfAvdEu/KY0
+i4UqzAX2++QA5nSV/wJvQ385p8KDjls4QMlCyLwmcjY1ZMJUIhGH6GWPPelBp20Z
+iJogm5pS59LLs+Auj8FWVLxtFDBzxdeO0FpezQIDAQABAoIBAG9pk63mP49l1kM4
+eQjw2Y9WvslVXBuxVNiNbU4eKW1zUO+RGJrvlC027JLWg1g7pwvPBvu85GspPcsd
+xRxFgfonyDhcSrq2+Vb2z8B/i54W73jgX/69YnMIBSKeFRbcD1C+7+MEv/l8jojd
+zdmLL4FQ7O7fhUl57dgIqz4Y8UOYyyBsPpz3pzJLFEb5rE/ajqmFzyl+dO+8140B
+niQ0+7+tAK0njX8OC0WN844GkO24WPCfWhUFrYGkfLq498eRUCWM2YP2tAJ+Uxnh
+v3K9icDwOX6PJXYlbvNEUCE+t60NoDYHcMpfzUdFEhBYpKadfKE/RFFcu0vAZ+aR
+y24oAuECgYEAyPLYXWIs88pPHQhSf2DAMRref5eeV+XA6Dy/P+z8z0bA7I6X9dl6
+AK6rRKGJl9HI7c/Gky6P10fymopYopNkClXm7SBTLKx0vfjil0U6Mx5ZsfDspE3q
+0o9MJKVgobCxVZlLErU55XzktKwjlv2UvDX7VuxRndqN9qdf+YSMb9kCgYEAxayx
+sOrJcPZVfy3Ohy5CeStF+E2dtfcKB7M7xZxZqykVy+6J1XjXHmp1L7Wpi0ju57Hi
+l2ZqKasHDwtlLOnfSTbvC47hsa1ydnoFTjJBObR1wS43oVkyV0AHid4w81ddOWPC
+H0ZmhvNe7pUxm5crpxsY6hAAraJ4Hej23MOxghUCgYEAip26UvCeQa2U1VogTm3X
+Jgh641kbiVabs5fz9Yzs966+9m+Gs7jJSB81Vap415mHGUTyniTIZKDk4WX9rmgt
+4lNPcNOTjIWKImHFLMQ8WXbeOLkRBGYbThQ7WiwadG8GZR3Rg54vyfZVbawxAL78
+ErjKIDP0OQfCVhsvQVgF6EECgYEAlQ2P+xA/Dv+gHkLjDUmTdBxuKToVZqU9merL
+cklfz9EuD1Tx99ajltq9PFll25IGGw0mB/WAraS5sN1tz/0VkfZrL7LwefKIcc+2
+em0og6OQezcnWXGRpPqx9IJnNMY2lFSlhsGmA7I1bf9vpZvKnbmwAqZIbKUqn5sP
+sg2ZprUCgYEApAVD+9wXfZE/YDHVZX1k6p38ORqjq/04AJkL/LmUW5DL5to1+1KQ
+Q438HzMtYIq7aZyzWmlF6DmyN5mxKKK3yY79p0rvdV74AoT+ucDzM3ge0Md7liCs
+0GwNnDSiPzdau738UoIKc1VbF7dMDL3LzqnfrBUCr7nXRbR3BHHuqws=
+-----END RSA PRIVATE KEY-----
diff --git a/tests/test-conf/cacert.pem b/tests/test-conf/cacert.pem
new file mode 100644
index 0000000..6abfc2d
--- /dev/null
+++ b/tests/test-conf/cacert.pem
@@ -0,0 +1,127 @@
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number:
+            52:7b:b4:00:96:60:b4:26:85:be:01:82:b8:b8:e2:8c:72:ef:5b:90
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=US, ST=California, L=Palo Alto, O=Apache Software 
Foundation, OU=Pulsar, CN=Pulsar CA/[email protected]
+        Validity
+            Not Before: Feb 17 16:43:44 2021 GMT
+            Not After : Feb 12 16:43:44 2041 GMT
+        Subject: C=US, ST=California, L=Palo Alto, O=Apache Software 
Foundation, OU=Pulsar, CN=Pulsar CA/[email protected]
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (4096 bit)
+                Modulus:
+                    00:b1:3c:7d:ab:4a:54:72:37:2a:92:94:0a:66:46:
+                    af:8c:ed:f4:2e:f3:87:1a:d0:c7:9d:23:35:1b:61:
+                    74:69:ca:f7:f5:3e:95:9c:86:f2:21:34:f8:0b:ed:
+                    45:76:22:ec:75:52:c0:67:db:2f:ba:da:25:3f:e1:
+                    5b:ac:da:15:dd:a5:75:24:b2:12:f0:b0:ce:fd:ab:
+                    44:06:a9:09:f6:b0:8e:8f:83:53:16:69:fa:9c:cc:
+                    00:fa:dd:13:f3:da:fd:f2:bf:88:8e:c4:f8:1a:6f:
+                    ab:4d:f8:32:81:80:7e:51:7a:99:2d:94:cd:f3:5d:
+                    1c:58:b2:44:f1:96:12:46:56:bd:60:8f:65:32:b7:
+                    d4:4b:7b:f3:23:88:2d:9b:a4:c4:c9:52:ea:9f:66:
+                    c1:74:be:4b:91:c6:b9:57:ec:c1:cc:81:bb:03:d5:
+                    fa:a0:46:4f:9a:a7:3e:3c:27:26:2b:97:eb:69:53:
+                    04:75:50:97:d6:0d:90:b1:37:9f:64:df:70:4d:d9:
+                    b3:e3:b7:cc:76:50:d9:3c:9b:4c:ac:e9:26:2e:cf:
+                    ac:47:42:14:b7:60:00:0a:de:42:47:66:0c:c7:7a:
+                    b9:4d:f4:fb:c2:6a:45:78:ec:b0:b4:ce:b3:1f:50:
+                    25:96:13:0c:55:0a:e0:d6:76:f7:1f:e1:16:e6:41:
+                    d6:72:6a:49:17:12:d9:05:8f:dc:56:b6:31:b3:b7:
+                    9c:e3:d8:a9:99:8a:1d:3b:9d:d9:59:44:ee:46:88:
+                    11:5f:ab:fa:38:a9:8b:d2:23:15:8b:af:1a:de:66:
+                    ba:7d:51:95:37:94:91:aa:01:01:d7:83:19:4b:5d:
+                    8d:f4:18:39:ef:e3:32:d0:62:c8:12:50:4e:91:c2:
+                    ac:58:73:68:bb:92:20:fc:14:e5:1a:86:bd:40:4c:
+                    94:e0:7d:0d:9c:08:57:ae:00:44:38:94:a3:3d:64:
+                    99:43:f8:e3:12:90:14:0f:5d:63:e2:c6:07:ea:d0:
+                    4c:8e:cf:e0:ae:34:be:86:4f:fc:58:e2:ea:f5:23:
+                    82:37:96:02:57:1b:b4:29:ca:fd:68:a0:48:79:e8:
+                    31:97:9a:5a:0e:2b:b4:b0:84:bb:57:4e:5f:4f:a7:
+                    43:45:97:d7:de:05:fc:2f:6c:3e:f5:53:26:56:a3:
+                    a5:da:52:69:57:8e:a0:4b:27:50:f9:ad:6e:76:a6:
+                    29:cc:06:94:dd:d0:ac:c6:18:22:a0:e2:bb:ed:d5:
+                    e4:97:f7:ac:23:df:75:30:41:97:07:3f:d3:12:8e:
+                    c5:a4:ef:ce:40:e8:3b:57:24:19:33:1b:ee:8a:0e:
+                    dd:0c:70:f2:1a:87:35:d9:71:d8:18:a7:9c:47:db:
+                    93:51:c3
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Subject Key Identifier:
+                D2:B2:3D:B1:A4:7C:48:4B:36:E1:A7:DE:D8:FC:BA:92:BA:A7:C4:71
+            X509v3 Authority Key Identifier:
+                
keyid:D2:B2:3D:B1:A4:7C:48:4B:36:E1:A7:DE:D8:FC:BA:92:BA:A7:C4:71
+
+            X509v3 Basic Constraints: critical
+                CA:TRUE
+            X509v3 Key Usage: critical
+                Digital Signature, Certificate Sign, CRL Sign
+    Signature Algorithm: sha256WithRSAEncryption
+         14:3d:7c:15:86:de:aa:5a:30:5d:d4:f2:bc:5f:10:d2:af:fe:
+         91:d7:ee:f3:b8:5f:ce:e4:c9:b2:01:c3:16:da:66:8e:7e:b1:
+         c1:e3:30:ff:1d:73:d0:9c:20:3d:54:32:57:ae:07:80:4a:24:
+         6e:7e:32:a3:e7:23:4d:5c:31:54:8b:c1:1b:c5:bc:20:5d:43:
+         62:93:e0:2e:a7:01:77:39:cf:fd:ec:4c:57:09:4f:2b:ad:ac:
+         b6:c0:be:5a:a3:ea:12:ac:5a:7f:60:23:81:bb:9a:fa:5f:7a:
+         67:a9:31:c3:34:af:db:ff:32:22:83:40:c2:7d:2f:39:5e:8a:
+         29:44:73:5f:6e:b4:f4:a2:ae:60:1f:8e:ef:91:9a:49:bb:a6:
+         90:2b:e0:44:95:24:8b:37:90:18:2d:41:32:8a:8e:07:8d:ea:
+         75:62:b8:9c:ec:73:6f:12:54:23:6d:40:00:74:c7:d3:fb:b7:
+         95:06:7d:cc:6d:8e:2c:d0:8b:11:06:8a:b7:43:1a:d7:e9:98:
+         f4:c6:ef:ad:2a:75:08:fb:07:8f:20:36:7a:86:1a:cf:f7:d6:
+         96:ad:ed:71:59:d1:81:56:18:8d:98:c2:c0:44:e5:29:7a:7c:
+         c0:e3:d7:fb:b8:f5:b2:50:53:8a:cf:38:ff:99:aa:bb:28:51:
+         60:e8:05:91:e1:ee:86:90:90:9b:87:60:63:38:cf:54:a5:82:
+         74:0f:40:b5:d2:6a:c5:a9:98:22:59:4e:fb:a5:81:e2:7b:0e:
+         3f:71:f3:24:17:1e:c5:89:fc:ae:ed:f3:69:65:02:b8:1e:98:
+         bc:37:c6:25:36:f8:ca:99:60:8e:13:3b:33:ec:91:b3:eb:04:
+         6d:41:97:3e:35:c0:97:ed:66:12:25:44:23:f3:2e:fa:9c:2e:
+         c2:ba:dd:f3:63:d7:5b:b2:72:03:4d:3b:fb:5e:29:d6:5c:02:
+         32:93:47:d1:4c:77:4a:58:c5:aa:81:ab:67:84:80:81:14:28:
+         e1:db:11:16:6d:31:50:7a:47:b2:a8:2d:15:a1:c4:63:1b:ce:
+         d5:e1:d7:57:dc:1a:71:e0:55:9f:6d:fb:be:e6:99:e8:89:be:
+         2c:e0:19:5e:cd:02:79:52:ee:93:56:9f:dc:d7:de:31:9b:2a:
+         c8:91:48:a0:c7:44:7d:72:32:27:c3:2b:d8:e8:6b:94:67:b5:
+         1d:9d:99:25:23:d9:24:b5:ed:4b:f2:18:2d:88:f5:d4:36:bb:
+         53:8c:a8:b1:7f:05:13:d7:8d:89:9d:55:33:90:bc:60:99:cf:
+         05:ba:bd:cb:c5:61:f9:c5:1a:f7:46:9c:40:90:dd:83:aa:7a:
+         1f:ab:5c:10:8d:26:27:1e
+-----BEGIN CERTIFICATE-----
+MIIGPzCCBCegAwIBAgIUUnu0AJZgtCaFvgGCuLjijHLvW5AwDQYJKoZIhvcNAQEL
+BQAwgaYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQH
+DAlQYWxvIEFsdG8xIzAhBgNVBAoMGkFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9u
+MQ8wDQYDVQQLDAZQdWxzYXIxEjAQBgNVBAMMCVB1bHNhciBDQTEkMCIGCSqGSIb3
+DQEJARYVZGV2QHB1bHNhci5hcGFjaGUub3JnMB4XDTIxMDIxNzE2NDM0NFoXDTQx
+MDIxMjE2NDM0NFowgaYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
+MRIwEAYDVQQHDAlQYWxvIEFsdG8xIzAhBgNVBAoMGkFwYWNoZSBTb2Z0d2FyZSBG
+b3VuZGF0aW9uMQ8wDQYDVQQLDAZQdWxzYXIxEjAQBgNVBAMMCVB1bHNhciBDQTEk
+MCIGCSqGSIb3DQEJARYVZGV2QHB1bHNhci5hcGFjaGUub3JnMIICIjANBgkqhkiG
+9w0BAQEFAAOCAg8AMIICCgKCAgEAsTx9q0pUcjcqkpQKZkavjO30LvOHGtDHnSM1
+G2F0acr39T6VnIbyITT4C+1FdiLsdVLAZ9svutolP+FbrNoV3aV1JLIS8LDO/atE
+BqkJ9rCOj4NTFmn6nMwA+t0T89r98r+IjsT4Gm+rTfgygYB+UXqZLZTN810cWLJE
+8ZYSRla9YI9lMrfUS3vzI4gtm6TEyVLqn2bBdL5Lkca5V+zBzIG7A9X6oEZPmqc+
+PCcmK5fraVMEdVCX1g2QsTefZN9wTdmz47fMdlDZPJtMrOkmLs+sR0IUt2AACt5C
+R2YMx3q5TfT7wmpFeOywtM6zH1AllhMMVQrg1nb3H+EW5kHWcmpJFxLZBY/cVrYx
+s7ec49ipmYodO53ZWUTuRogRX6v6OKmL0iMVi68a3ma6fVGVN5SRqgEB14MZS12N
+9Bg57+My0GLIElBOkcKsWHNou5Ig/BTlGoa9QEyU4H0NnAhXrgBEOJSjPWSZQ/jj
+EpAUD11j4sYH6tBMjs/grjS+hk/8WOLq9SOCN5YCVxu0Kcr9aKBIeegxl5paDiu0
+sIS7V05fT6dDRZfX3gX8L2w+9VMmVqOl2lJpV46gSydQ+a1udqYpzAaU3dCsxhgi
+oOK77dXkl/esI991MEGXBz/TEo7FpO/OQOg7VyQZMxvuig7dDHDyGoc12XHYGKec
+R9uTUcMCAwEAAaNjMGEwHQYDVR0OBBYEFNKyPbGkfEhLNuGn3tj8upK6p8RxMB8G
+A1UdIwQYMBaAFNKyPbGkfEhLNuGn3tj8upK6p8RxMA8GA1UdEwEB/wQFMAMBAf8w
+DgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQAUPXwVht6qWjBd1PK8
+XxDSr/6R1+7zuF/O5MmyAcMW2maOfrHB4zD/HXPQnCA9VDJXrgeASiRufjKj5yNN
+XDFUi8EbxbwgXUNik+AupwF3Oc/97ExXCU8rray2wL5ao+oSrFp/YCOBu5r6X3pn
+qTHDNK/b/zIig0DCfS85XoopRHNfbrT0oq5gH47vkZpJu6aQK+BElSSLN5AYLUEy
+io4Hjep1Yric7HNvElQjbUAAdMfT+7eVBn3MbY4s0IsRBoq3QxrX6Zj0xu+tKnUI
++wePIDZ6hhrP99aWre1xWdGBVhiNmMLAROUpenzA49f7uPWyUFOKzzj/maq7KFFg
+6AWR4e6GkJCbh2BjOM9UpYJ0D0C10mrFqZgiWU77pYHiew4/cfMkFx7Fifyu7fNp
+ZQK4Hpi8N8YlNvjKmWCOEzsz7JGz6wRtQZc+NcCX7WYSJUQj8y76nC7Cut3zY9db
+snIDTTv7XinWXAIyk0fRTHdKWMWqgatnhICBFCjh2xEWbTFQekeyqC0VocRjG87V
+4ddX3Bpx4FWfbfu+5pnoib4s4BlezQJ5Uu6TVp/c194xmyrIkUigx0R9cjInwyvY
+6GuUZ7UdnZklI9kkte1L8hgtiPXUNrtTjKixfwUT142JnVUzkLxgmc8Fur3LxWH5
+xRr3RpxAkN2Dqnofq1wQjSYnHg==
+-----END CERTIFICATE-----
diff --git a/tests/test-conf/client-cert.pem b/tests/test-conf/client-cert.pem
new file mode 100644
index 0000000..45f3cde
--- /dev/null
+++ b/tests/test-conf/client-cert.pem
@@ -0,0 +1,90 @@
+Certificate:
+    Data:
+        Version: 1 (0x0)
+        Serial Number: 4097 (0x1001)
+    Signature Algorithm: sha256WithRSAEncryption
+        Issuer: C=US, ST=California, L=Palo Alto, O=Apache Software 
Foundation, OU=Pulsar, CN=Pulsar CA/[email protected]
+        Validity
+            Not Before: Feb 17 16:56:55 2021 GMT
+            Not After : Feb 12 16:56:55 2041 GMT
+        Subject: C=US, ST=California, O=Apache Software Foundation, OU=Pulsar, 
CN=admin/[email protected]
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+                Public-Key: (2048 bit)
+                Modulus:
+                    00:ab:61:f5:12:b1:e1:ae:19:01:3e:59:4a:c6:ca:
+                    00:0c:96:e8:76:3a:83:20:d9:af:3a:e1:11:20:12:
+                    e0:e4:d0:70:8f:4b:7b:af:e1:89:ef:9b:c5:a9:c2:
+                    ed:ae:24:8d:bb:42:6e:ec:59:11:3f:f5:63:59:61:
+                    18:9f:70:b6:76:88:e2:ca:79:15:cc:fb:9c:5e:5c:
+                    bb:a1:d7:f0:d8:11:d4:17:34:1e:81:7e:0b:0e:05:
+                    be:5d:fa:d6:46:af:e1:95:d8:a0:5d:c5:2f:d9:a9:
+                    8f:69:64:49:95:f7:42:16:6a:84:2b:2e:af:91:73:
+                    3d:b6:d4:44:56:9a:61:43:49:15:22:ae:90:5d:04:
+                    29:90:4e:b2:41:34:73:3e:a2:48:05:1c:bc:8e:1b:
+                    0b:c1:d5:df:56:32:40:e9:91:a2:7b:de:31:2b:67:
+                    f1:8e:d6:c5:c0:87:57:70:29:f9:af:db:57:a0:2e:
+                    8c:30:0a:a7:47:39:33:4c:d7:2d:32:aa:48:29:bd:
+                    c4:48:c5:58:52:07:c4:99:b1:cc:66:da:ac:28:4d:
+                    c1:bc:1f:44:3f:a3:63:61:bd:ff:48:61:76:04:b2:
+                    7d:1c:6e:9c:ee:82:bb:f7:60:1c:7a:a0:98:be:2d:
+                    70:43:2f:64:bf:d2:0f:20:25:f7:c7:7d:70:05:b8:
+                    2e:bf
+                Exponent: 65537 (0x10001)
+    Signature Algorithm: sha256WithRSAEncryption
+         1c:31:b8:0f:a1:03:28:a0:da:31:ec:34:ce:e0:fd:01:99:9d:
+         9b:ad:f8:03:5d:20:85:18:de:ca:b5:ea:61:c9:3b:65:42:9c:
+         e5:21:73:d2:06:41:4b:a9:3a:fb:7f:ff:45:f3:5a:4a:ab:5a:
+         86:cd:57:6a:5f:13:c0:ae:7e:ad:5c:6e:c3:c4:e7:b7:d3:14:
+         bf:86:fe:f2:d1:70:0e:fc:98:50:a7:fe:53:62:5a:2d:f5:63:
+         2c:ee:4a:7c:dd:32:3e:d1:52:3a:1f:15:38:4b:2a:4a:ee:27:
+         a9:d8:92:a8:33:92:83:c9:3a:09:5a:01:66:0e:68:da:8f:82:
+         c0:18:cc:78:ea:c5:db:09:7c:2f:61:c3:51:f8:58:7a:27:d7:
+         92:c0:ff:f8:29:d7:a0:e9:54:17:8d:48:a8:ff:5e:92:ee:81:
+         6c:37:90:1c:93:28:8c:d2:f5:b1:20:96:d3:1d:0f:c0:7f:db:
+         0c:6d:65:7f:3a:55:e5:c9:9a:ad:09:91:a5:57:cb:fc:bf:df:
+         69:bd:6b:87:94:5b:d0:cf:3b:8b:48:41:3d:56:b6:1d:3f:e7:
+         f6:b6:58:f7:54:2a:dd:da:60:68:db:9b:70:04:8b:19:c3:44:
+         bf:1d:b4:28:b9:f8:ea:ad:d3:1a:6e:64:72:b1:61:6a:f3:e1:
+         d4:68:56:7b:0e:ad:4c:53:1e:d2:2e:1c:bc:b7:82:59:af:65:
+         d2:fd:ef:89:7c:34:8f:51:a1:4e:9d:7e:dc:c7:97:68:ea:aa:
+         e5:67:ed:be:dc:38:74:0e:c3:6f:fd:08:62:54:d8:1f:15:d1:
+         25:fc:21:f6:8c:f9:2f:65:5e:07:b9:e9:56:ba:48:14:5c:0d:
+         18:ba:f8:83:54:5b:b6:27:0c:36:2c:20:29:9c:c2:68:c5:3a:
+         0f:a5:d6:5f:7c:aa:f9:a6:2a:2b:69:c5:b1:39:e7:1c:02:31:
+         5b:f5:82:de:c9:4e:8d:33:dc:94:02:44:0a:44:95:75:7b:a1:
+         e7:ee:92:fc:35:93:73:8c:22:c1:32:ea:39:17:ca:d0:87:fc:
+         4d:8e:04:f8:59:66:d3:14:3f:59:ad:76:14:20:16:7b:77:4f:
+         94:58:f8:85:5c:ba:b3:69:ed:7f:75:54:9a:1a:88:21:5d:04:
+         57:87:85:e2:d4:0e:1b:61:7f:5d:36:dc:72:a1:9d:0b:c8:ce:
+         19:69:49:fa:1b:bb:3f:3d:1b:4d:81:42:95:4e:d8:0b:04:d1:
+         08:6d:15:b3:ae:52:41:12:ff:e1:90:c4:7d:52:88:55:8b:87:
+         83:06:48:8b:fc:3a:a7:47:0e:6c:a8:4c:9e:b0:aa:da:50:f5:
+         97:97:98:3e:9d:18:ef:43
+-----BEGIN CERTIFICATE-----
+MIIEqzCCApMCAhABMA0GCSqGSIb3DQEBCwUAMIGmMQswCQYDVQQGEwJVUzETMBEG
+A1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJUGFsbyBBbHRvMSMwIQYDVQQKDBpB
+cGFjaGUgU29mdHdhcmUgRm91bmRhdGlvbjEPMA0GA1UECwwGUHVsc2FyMRIwEAYD
+VQQDDAlQdWxzYXIgQ0ExJDAiBgkqhkiG9w0BCQEWFWRldkBwdWxzYXIuYXBhY2hl
+Lm9yZzAeFw0yMTAyMTcxNjU2NTVaFw00MTAyMTIxNjU2NTVaMIGOMQswCQYDVQQG
+EwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEjMCEGA1UECgwaQXBhY2hlIFNvZnR3
+YXJlIEZvdW5kYXRpb24xDzANBgNVBAsMBlB1bHNhcjEOMAwGA1UEAwwFYWRtaW4x
+JDAiBgkqhkiG9w0BCQEWFWRldkBwdWxzYXIuYXBhY2hlLm9yZzCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAKth9RKx4a4ZAT5ZSsbKAAyW6HY6gyDZrzrh
+ESAS4OTQcI9Le6/hie+bxanC7a4kjbtCbuxZET/1Y1lhGJ9wtnaI4sp5Fcz7nF5c
+u6HX8NgR1Bc0HoF+Cw4Fvl361kav4ZXYoF3FL9mpj2lkSZX3QhZqhCsur5FzPbbU
+RFaaYUNJFSKukF0EKZBOskE0cz6iSAUcvI4bC8HV31YyQOmRonveMStn8Y7WxcCH
+V3Ap+a/bV6AujDAKp0c5M0zXLTKqSCm9xEjFWFIHxJmxzGbarChNwbwfRD+jY2G9
+/0hhdgSyfRxunO6Cu/dgHHqgmL4tcEMvZL/SDyAl98d9cAW4Lr8CAwEAATANBgkq
+hkiG9w0BAQsFAAOCAgEAHDG4D6EDKKDaMew0zuD9AZmdm634A10ghRjeyrXqYck7
+ZUKc5SFz0gZBS6k6+3//RfNaSqtahs1Xal8TwK5+rVxuw8Tnt9MUv4b+8tFwDvyY
+UKf+U2JaLfVjLO5KfN0yPtFSOh8VOEsqSu4nqdiSqDOSg8k6CVoBZg5o2o+CwBjM
+eOrF2wl8L2HDUfhYeifXksD/+CnXoOlUF41IqP9eku6BbDeQHJMojNL1sSCW0x0P
+wH/bDG1lfzpV5cmarQmRpVfL/L/fab1rh5Rb0M87i0hBPVa2HT/n9rZY91Qq3dpg
+aNubcASLGcNEvx20KLn46q3TGm5kcrFhavPh1GhWew6tTFMe0i4cvLeCWa9l0v3v
+iXw0j1GhTp1+3MeXaOqq5Wftvtw4dA7Db/0IYlTYHxXRJfwh9oz5L2VeB7npVrpI
+FFwNGLr4g1RbticMNiwgKZzCaMU6D6XWX3yq+aYqK2nFsTnnHAIxW/WC3slOjTPc
+lAJECkSVdXuh5+6S/DWTc4wiwTLqORfK0If8TY4E+Flm0xQ/Wa12FCAWe3dPlFj4
+hVy6s2ntf3VUmhqIIV0EV4eF4tQOG2F/XTbccqGdC8jOGWlJ+hu7Pz0bTYFClU7Y
+CwTRCG0Vs65SQRL/4ZDEfVKIVYuHgwZIi/w6p0cObKhMnrCq2lD1l5eYPp0Y70M=
+-----END CERTIFICATE-----
diff --git a/tests/test-conf/client-key.pem b/tests/test-conf/client-key.pem
new file mode 100644
index 0000000..e12697c
--- /dev/null
+++ b/tests/test-conf/client-key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEoQIBAAKCAQEAq2H1ErHhrhkBPllKxsoADJbodjqDINmvOuERIBLg5NBwj0t7
+r+GJ75vFqcLtriSNu0Ju7FkRP/VjWWEYn3C2dojiynkVzPucXly7odfw2BHUFzQe
+gX4LDgW+XfrWRq/hldigXcUv2amPaWRJlfdCFmqEKy6vkXM9ttREVpphQ0kVIq6Q
+XQQpkE6yQTRzPqJIBRy8jhsLwdXfVjJA6ZGie94xK2fxjtbFwIdXcCn5r9tXoC6M
+MAqnRzkzTNctMqpIKb3ESMVYUgfEmbHMZtqsKE3BvB9EP6NjYb3/SGF2BLJ9HG6c
+7oK792AceqCYvi1wQy9kv9IPICX3x31wBbguvwIDAQABAoIBAQCcwbSPrPRncaeZ
+h8LFoO36le16dnqKCZIloMcxNxNNNvo9lyVC8mBgMXLSm+Eab4TTyyf6Nl14ytJc
+ZltHOqkqMnp+B9LQ8zNLfDaDCijY+TWtI5bjio5B/S7qdwyXCzii/slv+3SQ+m6a
+T4ifCtH//t11QfaEa4v/NphrPjnIeAgB681bk8nKdRop84ar+51lgbHoAza+wv+8
+e+aK3Od8r4yD19ZoPiMg0o4t2cEi8kupVgjsuZVtcvF9Q6QLYV17BFYEHqYjcr18
+N1EJ96f2FLO6cwEM+cG4n8gHjfDGRcDlhT9Cum1kDpg4J88auVUXnrDyi5Dcv1Pz
+6EC+ZmXBAoGBAOHUSUDMkbEePKDaM3Z+4jLqZWc3UZhxQLnqg5l7phdQ6iSogQX9
+1LpZCJ+lOMTHBCnaTCoQpuSHgYgraVkD4KG6nzC423oDesd/xNvlfW3TRsmwZWbL
+khdcdBSoVy3Kbv1v8kxw0NlcR68qo1XYfmFCAITcFHdxDz/jGStydlR9AoGBAMJH
+gyPenL595X8t47R93rkGOIx5cVf5YrDIZCByp4K44Tf9OqZHbky7jSPSSbur10mI
+pypRq5EcZ/cudU4w4gGaMauczt5Dgvlqd3T+GTZY3jO8bxi66gvzYTbigAxaJWcY
+Uafiv5W9ldRKsY3pyCL8ubg38Ed2cSaS2wGd/SDrAn8NO2MPaO0gc6UZx688QjL+
+yL0oTxV42Snxusv7MkOJGjSd8UGeGEFeqdjXgdbRsNeNnDzaOh+NRGNSlziU/qUq
+1MR/FlXF0G5hQhtGxyuSQ87iAnPukf79X21tyG9TP4lBUE3iLLoQAlgw606muQiu
+qi9dmYeZeAZst+HBqfNFAoGADg6qmH/VC5uEbY1eeoLZCL5AfTmUT+9FitEVHZvu
+LvE9qpVyFvH4Mykm7z6aAzBN5Y4zukYqiddqVmJQLpYu5DrJ+UbhWQe9hFqFxjtU
+i7Amc8vgpgNwR+kWUahV547mQe1qiyFHB4iuPKwi6MfPqWhr775sbl9NlKLvodBS
+rn0CgYBDrLH6ehNV/RnJIVZYQD6YcocYdYFy4u76mCYKmEP57XmstZHZXQgiRwbK
+Oy2Yg/qieKtSMjstgHFK6ZNYIR37l9J9Lh9aeal61+wW2dsGEy29Rhg01FpvKReq
+wCHz3tneUyaOhq9m0gKMOpWYcO+FBX1/2K5Gwj8FgEpu9r2b3w==
+-----END RSA PRIVATE KEY-----
diff --git a/test_consumer.py b/tests/test-conf/client-ssl.conf
old mode 100755
new mode 100644
similarity index 59%
copy from test_consumer.py
copy to tests/test-conf/client-ssl.conf
index 8c2985e..a04ff0b
--- a/test_consumer.py
+++ b/tests/test-conf/client-ssl.conf
@@ -1,4 +1,3 @@
-#!/usr/bin/env python3
 #
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
@@ -18,19 +17,10 @@
 # under the License.
 #
 
-
-import pulsar
-
-client = pulsar.Client('pulsar://localhost:6650')
-consumer = client.subscribe('my-topic', "my-subscription",
-                            properties={
-                                "consumer-name": "test-consumer-name",
-                                "consumer-id": "test-consumer-id"
-                            })
-
-while True:
-    msg = consumer.receive()
-    print("Received message '{0}' id='{1}'".format(msg.data().decode('utf-8'), 
msg.message_id()))
-    consumer.acknowledge(msg)
-
-client.close()
+# Pulsar Client configuration
+webServiceUrl=https://localhost:8443/
+brokerServiceUrl=pulsar+ssl://localhost:6651/
+tlsAllowInsecureConnection=false
+tlsTrustCertsFilePath=test-conf/cacert.pem
+authPlugin=org.apache.pulsar.client.impl.auth.AuthenticationTls
+authParams=tlsCertFile:test-conf/client-cert.pem,tlsKeyFile:test-conf/client-key.pem
diff --git a/test_consumer.py b/tests/test-conf/client.conf
old mode 100755
new mode 100644
similarity index 59%
rename from test_consumer.py
rename to tests/test-conf/client.conf
index 8c2985e..978fc21
--- a/test_consumer.py
+++ b/tests/test-conf/client.conf
@@ -1,4 +1,3 @@
-#!/usr/bin/env python3
 #
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
@@ -18,19 +17,11 @@
 # under the License.
 #
 
-
-import pulsar
-
-client = pulsar.Client('pulsar://localhost:6650')
-consumer = client.subscribe('my-topic', "my-subscription",
-                            properties={
-                                "consumer-name": "test-consumer-name",
-                                "consumer-id": "test-consumer-id"
-                            })
-
-while True:
-    msg = consumer.receive()
-    print("Received message '{0}' id='{1}'".format(msg.data().decode('utf-8'), 
msg.message_id()))
-    consumer.acknowledge(msg)
-
-client.close()
+# Pulsar Client configuration
+webServiceUrl=http://localhost:8765/
+brokerServiceUrl=pulsar://localhost:8885/
+#authPlugin=
+#authParams=
+#useTls=
+#tlsAllowInsecureConnection
+#tlsTrustCertsFilePath
diff --git a/tests/test-conf/cpp_credentials_file.json 
b/tests/test-conf/cpp_credentials_file.json
new file mode 100644
index 0000000..db1eccd
--- /dev/null
+++ b/tests/test-conf/cpp_credentials_file.json
@@ -0,0 +1,4 @@
+{
+  "client_id":"Xd23RHsUnvUlP7wchjNYOaIfazgeHd9x",
+  
"client_secret":"rT7ps7WY8uhdVuBTKWZkttwLdQotmdEliaM5rLfmgNibvqziZ-g07ZH52N_poGAb"
+}
diff --git a/tests/test-conf/private-key.client-ecdsa.pem 
b/tests/test-conf/private-key.client-ecdsa.pem
new file mode 100644
index 0000000..58ab3d4
--- /dev/null
+++ b/tests/test-conf/private-key.client-ecdsa.pem
@@ -0,0 +1,13 @@
+-----BEGIN EC PARAMETERS-----
+MIGXAgEBMBwGByqGSM49AQECEQD////9////////////////MDsEEP////3/////
+//////////wEEOh1ecEQefQ92CSZPCzuXtMDFQAADg1NaW5naHVhUXUMwDpEc9A2
+eQQhBBYf91KLiZstDChgfKUsW4bPWsg5W6/rE8AtopLd7XqDAhEA/////gAAAAB1
+ow0bkDihFQIBAQ==
+-----END EC PARAMETERS-----
+-----BEGIN EC PRIVATE KEY-----
+MIHYAgEBBBDeu9hc8kOvL3pl+LYSjLq9oIGaMIGXAgEBMBwGByqGSM49AQECEQD/
+///9////////////////MDsEEP////3///////////////wEEOh1ecEQefQ92CSZ
+PCzuXtMDFQAADg1NaW5naHVhUXUMwDpEc9A2eQQhBBYf91KLiZstDChgfKUsW4bP
+Wsg5W6/rE8AtopLd7XqDAhEA/////gAAAAB1ow0bkDihFQIBAaEkAyIABOsqPpE8
+cY80pxkog5xw3i2AQ0yfV3MqMusxlOQnigBp
+-----END EC PRIVATE KEY-----
diff --git a/tests/test-conf/private-key.client-mismatch-rsa.pem 
b/tests/test-conf/private-key.client-mismatch-rsa.pem
new file mode 100644
index 0000000..3e2831a
--- /dev/null
+++ b/tests/test-conf/private-key.client-mismatch-rsa.pem
@@ -0,0 +1,29 @@
+-----BEGIN EC PARAMETERS-----
+MIIBwgIBATBNBgcqhkjOPQEBAkIB////////////////////////////////////
+//////////////////////////////////////////////////8wgZ4EQgH/////
+////////////////////////////////////////////////////////////////
+/////////////////ARBUZU+uWGOHJofkpohoLaFQO6i2nJbmbMV87i0iZGO8Qnh
+Vhk5Uex+k3sWUsC9O7G/BzVz34g9LDTx70Uf1GtQPwADFQDQnogAKRy4U5bMZxc5
+MoSqoNpkugSBhQQAxoWOBrcEBOnNnj7LZiOVtEKcZIE5BT+1Ifgor2BrTT26oUte
+d+/nWSj+HcEnov+o3jNIs8GFakKb+X5+McLlvWYBGDkpaniaO8AEXIpftCx9G9mY
+9URJV5tEaBevvRcnPmYsl+5ymV70JkDFULkBP60HYTU8cIaicsJAiL6Udp/RZlAC
+QgH///////////////////////////////////////////pRhoeDvy+Wa3/MAUj3
+CaXQO7XJuImcR667b7cekThkCQIBAQ==
+-----END EC PARAMETERS-----
+-----BEGIN EC PRIVATE KEY-----
+MIICnQIBAQRCAeNLEp1HefZ1nMl5vvgFMsJCd5ieCWqPT7TXbQkn27A8WkyAGTYC
+GtolyPokOgSjbJh+ofBt/MgvE/nMrqzmkZVtoIIBxjCCAcICAQEwTQYHKoZIzj0B
+AQJCAf//////////////////////////////////////////////////////////
+////////////////////////////MIGeBEIB////////////////////////////
+//////////////////////////////////////////////////////////wEQVGV
+PrlhjhyaH5KaIaC2hUDuotpyW5mzFfO4tImRjvEJ4VYZOVHsfpN7FlLAvTuxvwc1
+c9+IPSw08e9FH9RrUD8AAxUA0J6IACkcuFOWzGcXOTKEqqDaZLoEgYUEAMaFjga3
+BATpzZ4+y2YjlbRCnGSBOQU/tSH4KK9ga009uqFLXnfv51ko/h3BJ6L/qN4zSLPB
+hWpCm/l+fjHC5b1mARg5KWp4mjvABFyKX7QsfRvZmPVESVebRGgXr70XJz5mLJfu
+cple9CZAxVC5AT+tB2E1PHCGonLCQIi+lHaf0WZQAkIB////////////////////
+///////////////////////6UYaHg78vlmt/zAFI9wml0Du1ybiJnEeuu2+3HpE4
+ZAkCAQGhgYkDgYYABAFhUHeaHfIWre/pPmv2a2l891co79dFpg6ixPRg+Y5qe0C7
+src//LT/ZR5rgj8ne+YcaIlwyQRl5OYEd25n799IcgHIBTGyaLB6Td5mW/oWT/Fz
+soufOnUJ7O/kDHjIQ15sczk3rDhe8/mB9zPjKlKTuAl5jBEt6E3yiB44Dtng02xD
+uQ==
+-----END EC PRIVATE KEY-----
diff --git a/tests/test-conf/private-key.client-rsa.pem 
b/tests/test-conf/private-key.client-rsa.pem
new file mode 100644
index 0000000..a0d589e
--- /dev/null
+++ b/tests/test-conf/private-key.client-rsa.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAtKWwgqdnTYrOCv+j1MkTWfSH0wCsHZZca9wAW3qP4uuhlBvn
+b10JcFf5ZjzP9BSXK+tHmI8uoN368vEv6yhURHM4yuXqzCxzuAwkQSo39rzX8PGC
+7qdjCN7LDJ3MnqiBIrUsSaEP1wrNsB1kI+o9ER1e5O/uEPAotP933hHQ0J2hMEek
+HqL7sBlJ98h6NmsicEaUkardk0TOXrlkjC+cMd8ZbGScPqI9M38bmn3OLxFTn1vt
+hpvnXLvCmG4M+6xtYtD+npcVPZw1i1R90fMs7ppZnRbv8Hc/DFdOKVQIgam6CDdn
+NKgW7c7IBMrP0AEm37HTu0LSOjP2OHXlvvlQGQIDAQABAoIBAAaJFAi2C7u3cNrf
+AstY9vVDLoLIvHFZlkBktjKZDYmVIsRb+hSCViwVUrWLL67R6+Iv4eg4DeTOAx00
+8pncXKgZTw2wIb1/QjR/Y/RjlaC8lkdmRWli7udMQCZVsyhuSjW6Pj7vr8YE4woj
+FhNijxEGcf9wWrmMJrzdnTWQiXByo+eTvUQ9BPgPGrRjsMZmTkLyAVJff2DfxO5b
+IWFDYDJcyYAMCIMQu7vys/I50ou6ilb1CO6QM6Z7KpPeOoVFPwtzbh8cf9xM8UNS
+j6J/JmdWhgI34GS3NA68xTQ6PV7zjnhCc+iccm3JKyzGXwaApAZ+Eoce/9j4WKmu
+5B4ziR0CgYEA3l/9OHbl1zmyV+rRxWOIj/i2rTvHzwBnbnPJyuemL5VMFdpGodQ3
+vwHvyQmcECRVRxmXojQ4QuPPHs3qp6wEEFPCWxChLSTxlUc85SOFHWU2O99jV7zI
+7+JOpDK/Mstsx9nHgXduJF+glTFtA3LH8Oqylzu2aFPsprwKuZf94Q8CgYEAz/Zx
+akEG+PEMtP5YS28cX5XfjsIX/V26Fs6/sH16QjUIEddE5T4fCuokxCjSiwUcWhml
+pHEJ5S5xp3VYRfISW3jRW3qstIH1tpZipB6+S0zTuJmLJbA3IiWEg2rtMt7X1uJv
+A/bYOqe0hOPTuXuZdtVZ0nMTKk7GG8O6VkBI7FcCgYEAkDfCmscJgs7JahlBWHmX
+zH9pwem+SPKjIc/4NB6N+dgikx2Pp05hpP/VihUwYIufvs/LNogVYNQrtHepUnrN
+2+TmbHbZgNSv1Ldxt82UfB7y0FutKu6lhmXHyNecho3Fi8sih0V0aiSWmYuHfrAH
+GaiskEZKo1iiZvQXJIx9O2MCgYATBf0r9hTYMtyxtc6H3/sdd01C9thQ8gDy0yjP
+0Tqc0dMSJroDqmIWkoKYew9/bhFA4LW5TCnWkCAPbHmNtG4fdfbYwmkH/hdnA2y0
+jKdlpfp8GXeUFAGHGx17FA3sqFvgKUh0eWEgRHUL7vdQMVFBgJS93o7zQM94fLgP
+6cOB8wKBgFcGV4GjI2Ww9cillaC554MvoSjf8B/+04kXzDOh8iYIIzO9EUil1jjK
+Jvxp4hnLzTKWbux3MEWqurLkYas6GpKBjw+iNOCar6YdqWGVqM3RUx7PTUaZwkKx
+UdP63IfY7iZCIT/QbyHQvIUe2MaiVnH+ulxdkK6Y5e7gxcbckIH4
+-----END RSA PRIVATE KEY-----
diff --git a/tests/test-conf/public-key.client-ecdsa.pem 
b/tests/test-conf/public-key.client-ecdsa.pem
new file mode 100644
index 0000000..5aeb429
--- /dev/null
+++ b/tests/test-conf/public-key.client-ecdsa.pem
@@ -0,0 +1,7 @@
+-----BEGIN PUBLIC KEY-----
+MIHKMIGjBgcqhkjOPQIBMIGXAgEBMBwGByqGSM49AQECEQD////9////////////
+////MDsEEP////3///////////////wEEOh1ecEQefQ92CSZPCzuXtMDFQAADg1N
+aW5naHVhUXUMwDpEc9A2eQQhBBYf91KLiZstDChgfKUsW4bPWsg5W6/rE8AtopLd
+7XqDAhEA/////gAAAAB1ow0bkDihFQIBAQMiAATrKj6RPHGPNKcZKIOccN4tgENM
+n1dzKjLrMZTkJ4oAaQ==
+-----END PUBLIC KEY-----
diff --git a/tests/test-conf/public-key.client-mismatch-rsa.pem 
b/tests/test-conf/public-key.client-mismatch-rsa.pem
new file mode 100644
index 0000000..6fc427b
--- /dev/null
+++ b/tests/test-conf/public-key.client-mismatch-rsa.pem
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtKWwgqdnTYrOCv+j1MkT
+WfSH0wCsHZZca9wAW3qP4uuhlBvnb10JcFf5ZjzP9BSXK+tHmI8uoN368vEv6yhU
+RHM4yuXqzCxzuAwkQSo39rzX8PGC7qdjCN7LDJ3MnqiBIrUsSaEP1wrNsB1kI+o9
+ER1e5O/uEPAotP933hHQ0J2hMEekHqL7sBlJ98h6NmsicEaUkardk0TOXrlkjC+c
+Md8ZbGScPqI9M38bmn3OLxFTn1vthpvnXLvCmG4M+6xtYtD+npcVPZw1i1R90fMs
+7ppZnRbv8Hc/DFdOKVQIgam6CDdnNKgW7c7IBMrP0AEm37HTu0LSOjP2OHXlvvlQ
+GQIDAQAB
+-----END PUBLIC KEY-----
diff --git a/tests/test-conf/public-key.client-rsa.pem 
b/tests/test-conf/public-key.client-rsa.pem
new file mode 100644
index 0000000..6fc427b
--- /dev/null
+++ b/tests/test-conf/public-key.client-rsa.pem
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtKWwgqdnTYrOCv+j1MkT
+WfSH0wCsHZZca9wAW3qP4uuhlBvnb10JcFf5ZjzP9BSXK+tHmI8uoN368vEv6yhU
+RHM4yuXqzCxzuAwkQSo39rzX8PGC7qdjCN7LDJ3MnqiBIrUsSaEP1wrNsB1kI+o9
+ER1e5O/uEPAotP933hHQ0J2hMEekHqL7sBlJ98h6NmsicEaUkardk0TOXrlkjC+c
+Md8ZbGScPqI9M38bmn3OLxFTn1vthpvnXLvCmG4M+6xtYtD+npcVPZw1i1R90fMs
+7ppZnRbv8Hc/DFdOKVQIgam6CDdnNKgW7c7IBMrP0AEm37HTu0LSOjP2OHXlvvlQ
+GQIDAQAB
+-----END PUBLIC KEY-----
diff --git a/tests/test-conf/standalone-ssl.conf 
b/tests/test-conf/standalone-ssl.conf
new file mode 100644
index 0000000..2ee4432
--- /dev/null
+++ b/tests/test-conf/standalone-ssl.conf
@@ -0,0 +1,309 @@
+#
+# 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.
+#
+
+### --- General broker settings --- ###
+
+# Zookeeper quorum connection string
+zookeeperServers=
+
+# Configuration Store connection string
+configurationStoreServers=
+
+brokerServicePort=6650
+brokerServicePortTls=6651
+
+# Port to use to server HTTP request
+webServicePort=8080
+webServicePortTls=8443
+
+# Hostname or IP address the service binds on, default is 0.0.0.0.
+bindAddress=0.0.0.0
+
+# Hostname or IP address the service advertises to the outside world. If not 
set, the value of InetAddress.getLocalHost().getCanonicalHostName() is used.
+advertisedAddress=localhost
+
+# Name of the cluster to which this broker belongs to
+clusterName=standalone
+
+# Zookeeper session timeout in milliseconds
+zooKeeperSessionTimeoutMillis=30000
+
+# Time to wait for broker graceful shutdown. After this time elapses, the 
process will be killed
+brokerShutdownTimeoutMs=3000
+
+# Enable backlog quota check. Enforces action on topic when the quota is 
reached
+backlogQuotaCheckEnabled=true
+
+# How often to check for topics that have reached the quota
+backlogQuotaCheckIntervalInSeconds=60
+
+# Default per-topic backlog quota limit
+backlogQuotaDefaultLimitGB=10
+
+# Enable the deletion of inactive topics
+brokerDeleteInactiveTopicsEnabled=true
+
+# How often to check for inactive topics
+brokerDeleteInactiveTopicsFrequencySeconds=60
+
+# How frequently to proactively check and purge expired messages
+messageExpiryCheckIntervalInMinutes=5
+
+# Enable check for minimum allowed client library version
+clientLibraryVersionCheckEnabled=false
+
+# Allow client libraries with no version information
+clientLibraryVersionCheckAllowUnversioned=true
+
+# Path for the file used to determine the rotation status for the broker when 
responding
+# to service discovery health checks
+statusFilePath=/usr/local/apache/htdocs
+
+# Max number of unacknowledged messages allowed to receive messages by a 
consumer on a shared subscription. Broker will stop sending
+# messages to consumer once, this limit reaches until consumer starts 
acknowledging messages back
+# Using a value of 0, is disabling unackeMessage limit check and consumer can 
receive messages without any restriction
+maxUnackedMessagesPerConsumer=50000
+
+subscriptionRedeliveryTrackerEnabled=true
+
+### --- Authentication --- ###
+
+# Enable TLS
+tlsEnabled=true
+tlsCertificateFilePath=test-conf/broker-cert.pem
+tlsKeyFilePath=test-conf/broker-key.pem
+tlsTrustCertsFilePath=test-conf/cacert.pem
+tlsAllowInsecureConnection=false
+
+anonymousUserRole=anonymous
+
+# Enable authentication
+authenticationEnabled=true
+
+# Authentication provider name list, which is comma separated list of class 
names
+authenticationProviders=org.apache.pulsar.broker.authentication.AuthenticationProviderTls,org.apache.pulsar.broker.authentication.AuthenticationProviderToken,org.apache.pulsar.broker.authentication.AuthenticationProviderBasic
+
+# Enforce authorization
+authorizationEnabled=true
+
+tokenSecretKey=file:///pulsar/data/tokens/secret.key
+
+# Role names that are treated as "super-user", meaning they will be able to do 
all admin
+# operations and publish/consume from all topics
+superUserRoles=localhost,superUser,admin
+
+# Authentication settings of the broker itself. Used when the broker connects 
to other brokers,
+# either in same or other clusters
+brokerClientAuthenticationPlugin=
+brokerClientAuthenticationParameters=
+
+### --- BookKeeper Client --- ###
+
+# Authentication plugin to use when connecting to bookies
+bookkeeperClientAuthenticationPlugin=
+
+# BookKeeper auth plugin implementatation specifics parameters name and values
+bookkeeperClientAuthenticationParametersName=
+bookkeeperClientAuthenticationParameters=
+
+# Timeout for BK add / read operations
+bookkeeperClientTimeoutInSeconds=30
+
+# Speculative reads are initiated if a read request doesn't complete within a 
certain time
+# Using a value of 0, is disabling the speculative reads
+bookkeeperClientSpeculativeReadTimeoutInMillis=0
+
+# Enable bookies health check. Bookies that have more than the configured 
number of failure within
+# the interval will be quarantined for some time. During this period, new 
ledgers won't be created
+# on these bookies
+bookkeeperClientHealthCheckEnabled=true
+bookkeeperClientHealthCheckIntervalSeconds=60
+bookkeeperClientHealthCheckErrorThresholdPerInterval=5
+bookkeeperClientHealthCheckQuarantineTimeInSeconds=1800
+
+# Enable rack-aware bookie selection policy. BK will chose bookies from 
different racks when
+# forming a new bookie ensemble
+bookkeeperClientRackawarePolicyEnabled=true
+
+# Enable region-aware bookie selection policy. BK will chose bookies from
+# different regions and racks when forming a new bookie ensemble
+# If enabled, the value of bookkeeperClientRackawarePolicyEnabled is ignored
+bookkeeperClientRegionawarePolicyEnabled=false
+
+# Minimum number of racks per write quorum. BK rack-aware bookie selection 
policy will try to
+# get bookies from at least 'bookkeeperClientMinNumRacksPerWriteQuorum' racks 
for a write quorum.
+bookkeeperClientMinNumRacksPerWriteQuorum=1
+
+# Enforces rack-aware bookie selection policy to pick bookies from 
'bookkeeperClientMinNumRacksPerWriteQuorum'
+# racks for a writeQuorum.
+# If BK can't find bookie then it would throw BKNotEnoughBookiesException 
instead of picking random one.
+bookkeeperClientEnforceMinNumRacksPerWriteQuorum=false
+
+# Enable/disable reordering read sequence on reading entries.
+bookkeeperClientReorderReadSequenceEnabled=false
+
+# Enable bookie isolation by specifying a list of bookie groups to choose 
from. Any bookie
+# outside the specified groups will not be used by the broker
+bookkeeperClientIsolationGroups=
+
+### --- Managed Ledger --- ###
+
+# Number of bookies to use when creating a ledger
+managedLedgerDefaultEnsembleSize=1
+
+# Number of copies to store for each message
+managedLedgerDefaultWriteQuorum=1
+
+# Number of guaranteed copies (acks to wait before write is complete)
+managedLedgerDefaultAckQuorum=1
+
+# Amount of memory to use for caching data payload in managed ledger. This 
memory
+# is allocated from JVM direct memory and it's shared across all the topics
+# running  in the same broker
+managedLedgerCacheSizeMB=1024
+
+# Threshold to which bring down the cache level when eviction is triggered
+managedLedgerCacheEvictionWatermark=0.9
+
+# Rate limit the amount of writes generated by consumer acking the messages
+managedLedgerDefaultMarkDeleteRateLimit=0.1
+
+# Max number of entries to append to a ledger before triggering a rollover
+# A ledger rollover is triggered after the min rollover time has passed
+# and one of the following conditions is true:
+#  * The max rollover time has been reached
+#  * The max entries have been written to the ledger
+#  * The max ledger size has been written to the ledger
+managedLedgerMaxEntriesPerLedger=50000
+
+# Minimum time between ledger rollover for a topic
+managedLedgerMinLedgerRolloverTimeMinutes=10
+
+# Maximum time before forcing a ledger rollover for a topic
+managedLedgerMaxLedgerRolloverTimeMinutes=240
+
+# Max number of entries to append to a cursor ledger
+managedLedgerCursorMaxEntriesPerLedger=50000
+
+# Max time before triggering a rollover on a cursor ledger
+managedLedgerCursorRolloverTimeInSeconds=14400
+
+
+
+### --- Load balancer --- ###
+
+# Enable load balancer
+loadBalancerEnabled=false
+
+# Strategy to assign a new bundle
+loadBalancerPlacementStrategy=weightedRandomSelection
+
+# Percentage of change to trigger load report update
+loadBalancerReportUpdateThresholdPercentage=10
+
+# maximum interval to update load report
+loadBalancerReportUpdateMaxIntervalMinutes=15
+
+# Frequency of report to collect
+loadBalancerHostUsageCheckIntervalMinutes=1
+
+# Load shedding interval. Broker periodically checks whether some traffic 
should be offload from
+# some over-loaded broker to other under-loaded brokers
+loadBalancerSheddingIntervalMinutes=30
+
+# Prevent the same topics to be shed and moved to other broker more than once 
within this timeframe
+loadBalancerSheddingGracePeriodMinutes=30
+
+# Usage threshold to determine a broker as under-loaded
+loadBalancerBrokerUnderloadedThresholdPercentage=1
+
+# Usage threshold to determine a broker as over-loaded
+loadBalancerBrokerOverloadedThresholdPercentage=85
+
+# Interval to update namespace bundle resource quota
+loadBalancerResourceQuotaUpdateIntervalMinutes=15
+
+# Usage threshold to determine a broker is having just right level of load
+loadBalancerBrokerComfortLoadLevelPercentage=65
+
+# enable/disable namespace bundle auto split
+loadBalancerAutoBundleSplitEnabled=false
+
+# interval to detect & split hot namespace bundle
+loadBalancerNamespaceBundleSplitIntervalMinutes=15
+
+# maximum topics in a bundle, otherwise bundle split will be triggered
+loadBalancerNamespaceBundleMaxTopics=1000
+
+# maximum sessions (producers + consumers) in a bundle, otherwise bundle split 
will be triggered
+loadBalancerNamespaceBundleMaxSessions=1000
+
+# maximum msgRate (in + out) in a bundle, otherwise bundle split will be 
triggered
+loadBalancerNamespaceBundleMaxMsgRate=1000
+
+# maximum bandwidth (in + out) in a bundle, otherwise bundle split will be 
triggered
+loadBalancerNamespaceBundleMaxBandwidthMbytes=100
+
+# maximum number of bundles in a namespace
+loadBalancerNamespaceMaximumBundles=128
+
+### --- Replication --- ###
+
+# Enable replication metrics
+replicationMetricsEnabled=true
+
+# Max number of connections to open for each broker in a remote cluster
+# More connections host-to-host lead to better throughput over high-latency
+# links.
+replicationConnectionsPerBroker=16
+
+# Replicator producer queue size
+replicationProducerQueueSize=1000
+
+# Default message retention time. 0 means retention is disabled. -1 means data 
is not removed by time quota
+defaultRetentionTimeInMinutes=0
+
+# Default retention size. 0 means retention is disabled. -1 means data is not 
removed by size quota
+defaultRetentionSizeInMB=0
+
+# How often to check whether the connections are still alive
+keepAliveIntervalSeconds=30
+
+# Enable topic auto creation if new producer or consumer connected (disable 
auto creation with value false)
+allowAutoTopicCreation=true
+
+# The type of topic that is allowed to be automatically 
created.(partitioned/non-partitioned)
+allowAutoTopicCreationType=non-partitioned
+
+# The number of partitioned topics that is allowed to be automatically created 
if allowAutoTopicCreationType is partitioned.
+defaultNumPartitions=1
+
+### --- Deprecated config variables --- ###
+
+# Deprecated. Use configurationStoreServers
+globalZookeeperServers=
+
+# Deprecated. Use brokerDeleteInactiveTopicsFrequencySeconds
+brokerServicePurgeInactiveFrequencyInSeconds=60
+
+# Given a specific limit of the max message size
+maxMessageSize=1024000
+
+# Disable consistent hashing to fix flaky 
`KeySharedConsumerTest#testMultiTopics`.
+subscriptionKeySharedUseConsistentHashing=false
diff --git a/tests/test-conf/standalone.conf b/tests/test-conf/standalone.conf
new file mode 100644
index 0000000..faa1277
--- /dev/null
+++ b/tests/test-conf/standalone.conf
@@ -0,0 +1,291 @@
+#
+# 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.
+#
+
+### --- General broker settings --- ###
+
+# Zookeeper quorum connection string
+zookeeperServers=
+
+# Configuration Store connection string
+configurationStoreServers=
+
+brokerServicePort=8885
+
+# Port to use to server HTTP request
+webServicePort=8765
+
+# Hostname or IP address the service binds on, default is 0.0.0.0.
+bindAddress=0.0.0.0
+
+# Hostname or IP address the service advertises to the outside world. If not 
set, the value of InetAddress.getLocalHost().getCanonicalHostName() is used.
+advertisedAddress=localhost
+
+# Name of the cluster to which this broker belongs to
+clusterName=standalone
+
+# Zookeeper session timeout in milliseconds
+zooKeeperSessionTimeoutMillis=30000
+
+# Time to wait for broker graceful shutdown. After this time elapses, the 
process will be killed
+brokerShutdownTimeoutMs=3000
+
+# Enable backlog quota check. Enforces action on topic when the quota is 
reached
+backlogQuotaCheckEnabled=true
+
+# How often to check for topics that have reached the quota
+backlogQuotaCheckIntervalInSeconds=60
+
+# Default per-topic backlog quota limit
+backlogQuotaDefaultLimitGB=10
+
+# Enable the deletion of inactive topics
+brokerDeleteInactiveTopicsEnabled=true
+
+# How often to check for inactive topics
+brokerDeleteInactiveTopicsFrequencySeconds=60
+
+# How frequently to proactively check and purge expired messages
+messageExpiryCheckIntervalInMinutes=5
+
+# Enable check for minimum allowed client library version
+clientLibraryVersionCheckEnabled=false
+
+# Allow client libraries with no version information
+clientLibraryVersionCheckAllowUnversioned=true
+
+# Path for the file used to determine the rotation status for the broker when 
responding
+# to service discovery health checks
+statusFilePath=/usr/local/apache/htdocs
+
+# Max number of unacknowledged messages allowed to receive messages by a 
consumer on a shared subscription. Broker will stop sending
+# messages to consumer once, this limit reaches until consumer starts 
acknowledging messages back
+# Using a value of 0, is disabling unackeMessage limit check and consumer can 
receive messages without any restriction
+maxUnackedMessagesPerConsumer=50000
+
+subscriptionRedeliveryTrackerEnabled=true
+
+### --- Authentication --- ###
+
+# Enable authentication
+authenticationEnabled=false
+
+# Authentication provider name list, which is comma separated list of class 
names
+authenticationProviders=false
+
+# Enforce authorization
+authorizationEnabled=false
+
+# Role names that are treated as "super-user", meaning they will be able to do 
all admin
+# operations and publish/consume from all topics
+superUserRoles=
+
+# Authentication settings of the broker itself. Used when the broker connects 
to other brokers,
+# either in same or other clusters
+brokerClientAuthenticationPlugin=
+brokerClientAuthenticationParameters=
+
+
+### --- BookKeeper Client --- ###
+
+# Authentication plugin to use when connecting to bookies
+bookkeeperClientAuthenticationPlugin=
+
+# BookKeeper auth plugin implementatation specifics parameters name and values
+bookkeeperClientAuthenticationParametersName=
+bookkeeperClientAuthenticationParameters=
+
+# Timeout for BK add / read operations
+bookkeeperClientTimeoutInSeconds=30
+
+# Speculative reads are initiated if a read request doesn't complete within a 
certain time
+# Using a value of 0, is disabling the speculative reads
+bookkeeperClientSpeculativeReadTimeoutInMillis=0
+
+# Enable bookies health check. Bookies that have more than the configured 
number of failure within
+# the interval will be quarantined for some time. During this period, new 
ledgers won't be created
+# on these bookies
+bookkeeperClientHealthCheckEnabled=true
+bookkeeperClientHealthCheckIntervalSeconds=60
+bookkeeperClientHealthCheckErrorThresholdPerInterval=5
+bookkeeperClientHealthCheckQuarantineTimeInSeconds=1800
+
+# Enable rack-aware bookie selection policy. BK will chose bookies from 
different racks when
+# forming a new bookie ensemble
+bookkeeperClientRackawarePolicyEnabled=true
+
+# Enable region-aware bookie selection policy. BK will chose bookies from
+# different regions and racks when forming a new bookie ensemble
+# If enabled, the value of bookkeeperClientRackawarePolicyEnabled is ignored
+bookkeeperClientRegionawarePolicyEnabled=false
+
+# Minimum number of racks per write quorum. BK rack-aware bookie selection 
policy will try to
+# get bookies from at least 'bookkeeperClientMinNumRacksPerWriteQuorum' racks 
for a write quorum.
+bookkeeperClientMinNumRacksPerWriteQuorum=1
+
+# Enforces rack-aware bookie selection policy to pick bookies from 
'bookkeeperClientMinNumRacksPerWriteQuorum'
+# racks for a writeQuorum.
+# If BK can't find bookie then it would throw BKNotEnoughBookiesException 
instead of picking random one.
+bookkeeperClientEnforceMinNumRacksPerWriteQuorum=false
+
+# Enable/disable reordering read sequence on reading entries.
+bookkeeperClientReorderReadSequenceEnabled=false
+
+# Enable bookie isolation by specifying a list of bookie groups to choose 
from. Any bookie
+# outside the specified groups will not be used by the broker
+bookkeeperClientIsolationGroups=
+
+### --- Managed Ledger --- ###
+
+# Number of bookies to use when creating a ledger
+managedLedgerDefaultEnsembleSize=1
+
+# Number of copies to store for each message
+managedLedgerDefaultWriteQuorum=1
+
+# Number of guaranteed copies (acks to wait before write is complete)
+managedLedgerDefaultAckQuorum=1
+
+# Amount of memory to use for caching data payload in managed ledger. This 
memory
+# is allocated from JVM direct memory and it's shared across all the topics
+# running  in the same broker
+managedLedgerCacheSizeMB=1024
+
+# Threshold to which bring down the cache level when eviction is triggered
+managedLedgerCacheEvictionWatermark=0.9
+
+# Rate limit the amount of writes generated by consumer acking the messages
+managedLedgerDefaultMarkDeleteRateLimit=0.1
+
+# Max number of entries to append to a ledger before triggering a rollover
+# A ledger rollover is triggered after the min rollover time has passed
+# and one of the following conditions is true:
+#  * The max rollover time has been reached
+#  * The max entries have been written to the ledger
+#  * The max ledger size has been written to the ledger
+managedLedgerMaxEntriesPerLedger=50000
+
+# Minimum time between ledger rollover for a topic
+managedLedgerMinLedgerRolloverTimeMinutes=10
+
+# Maximum time before forcing a ledger rollover for a topic
+managedLedgerMaxLedgerRolloverTimeMinutes=240
+
+# Max number of entries to append to a cursor ledger
+managedLedgerCursorMaxEntriesPerLedger=50000
+
+# Max time before triggering a rollover on a cursor ledger
+managedLedgerCursorRolloverTimeInSeconds=14400
+
+
+
+### --- Load balancer --- ###
+
+# Enable load balancer
+loadBalancerEnabled=false
+
+# Strategy to assign a new bundle
+loadBalancerPlacementStrategy=weightedRandomSelection
+
+# Percentage of change to trigger load report update
+loadBalancerReportUpdateThresholdPercentage=10
+
+# maximum interval to update load report
+loadBalancerReportUpdateMaxIntervalMinutes=15
+
+# Frequency of report to collect
+loadBalancerHostUsageCheckIntervalMinutes=1
+
+# Load shedding interval. Broker periodically checks whether some traffic 
should be offload from
+# some over-loaded broker to other under-loaded brokers
+loadBalancerSheddingIntervalMinutes=30
+
+# Prevent the same topics to be shed and moved to other broker more than once 
within this timeframe
+loadBalancerSheddingGracePeriodMinutes=30
+
+# Usage threshold to determine a broker as under-loaded
+loadBalancerBrokerUnderloadedThresholdPercentage=1
+
+# Usage threshold to determine a broker as over-loaded
+loadBalancerBrokerOverloadedThresholdPercentage=85
+
+# Interval to update namespace bundle resource quota
+loadBalancerResourceQuotaUpdateIntervalMinutes=15
+
+# Usage threshold to determine a broker is having just right level of load
+loadBalancerBrokerComfortLoadLevelPercentage=65
+
+# enable/disable namespace bundle auto split
+loadBalancerAutoBundleSplitEnabled=false
+
+# interval to detect & split hot namespace bundle
+loadBalancerNamespaceBundleSplitIntervalMinutes=15
+
+# maximum topics in a bundle, otherwise bundle split will be triggered
+loadBalancerNamespaceBundleMaxTopics=1000
+
+# maximum sessions (producers + consumers) in a bundle, otherwise bundle split 
will be triggered
+loadBalancerNamespaceBundleMaxSessions=1000
+
+# maximum msgRate (in + out) in a bundle, otherwise bundle split will be 
triggered
+loadBalancerNamespaceBundleMaxMsgRate=1000
+
+# maximum bandwidth (in + out) in a bundle, otherwise bundle split will be 
triggered
+loadBalancerNamespaceBundleMaxBandwidthMbytes=100
+
+# maximum number of bundles in a namespace
+loadBalancerNamespaceMaximumBundles=128
+
+### --- Replication --- ###
+
+# Enable replication metrics
+replicationMetricsEnabled=true
+
+# Max number of connections to open for each broker in a remote cluster
+# More connections host-to-host lead to better throughput over high-latency
+# links.
+replicationConnectionsPerBroker=16
+
+# Replicator producer queue size
+replicationProducerQueueSize=1000
+
+# Default message retention time. 0 means retention is disabled. -1 means data 
is not removed by time quota
+defaultRetentionTimeInMinutes=0
+
+# Default retention size. 0 means retention is disabled. -1 means data is not 
removed by size quota
+defaultRetentionSizeInMB=0
+
+# How often to check whether the connections are still alive
+keepAliveIntervalSeconds=30
+
+# Enable topic auto creation if new producer or consumer connected (disable 
auto creation with value false)
+allowAutoTopicCreation=true
+
+# The type of topic that is allowed to be automatically 
created.(partitioned/non-partitioned)
+allowAutoTopicCreationType=non-partitioned
+
+# The number of partitioned topics that is allowed to be automatically created 
if allowAutoTopicCreationType is partitioned.
+defaultNumPartitions=1
+
+### --- Deprecated config variables --- ###
+
+# Deprecated. Use configurationStoreServers
+globalZookeeperServers=
+
+# Deprecated. Use brokerDeleteInactiveTopicsFrequencySeconds
+brokerServicePurgeInactiveFrequencyInSeconds=60
diff --git a/version.txt b/version.txt
index 05f2b11..a6f4248 100644
--- a/version.txt
+++ b/version.txt
@@ -1,5 +1 @@
-
-pulsar-client-python: 3.0.0a1
-
-# Dependency
-pulsar-client-cpp: 2.10.1
+3.0.0a1

Reply via email to