PROTON-1798: [c, cpp, ruby] Installable tests for proton Tests can be executed from install for c, cpp, ruby. See tests/share/examples-README.md
RUNTIME_CHECK=memcheck, helgrind are supported for normal builds. asan, tsan require a special library build so less likely to be useful for install tests. TODO: - python, go examples - non-example tests installed under share/pronton-VERSION/tests/<language> Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/393f8a67 Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/393f8a67 Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/393f8a67 Branch: refs/heads/go1 Commit: 393f8a67712d126f98b3a87e83fdafab57011239 Parents: 6c765bc Author: Alan Conway <acon...@redhat.com> Authored: Mon Sep 10 17:13:09 2018 -0400 Committer: Alan Conway <acon...@redhat.com> Committed: Tue Sep 11 12:07:56 2018 -0400 ---------------------------------------------------------------------- CMakeLists.txt | 7 +- c/CMakeLists.txt | 1 + c/examples/CMakeLists.txt | 33 +++--- c/examples/example_test.py | 115 ------------------- c/examples/testme | 111 ++++++++++++++++++ cpp/CMakeLists.txt | 1 + cpp/examples/CMakeLists.txt | 40 ++++--- cpp/examples/example_test.py | 216 ------------------------------------ cpp/examples/testme | 213 +++++++++++++++++++++++++++++++++++ go/CMakeLists.txt | 5 +- python/CMakeLists.txt | 5 +- ruby/CMakeLists.txt | 20 ++-- ruby/examples/example_test.rb | 110 ------------------ ruby/examples/testme | 110 ++++++++++++++++++ runtime_check.cmake | 123 -------------------- tests/py/test_subprocess.py | 10 +- tests/runtime_check.cmake | 123 ++++++++++++++++++++ tests/share/CMakeLists.txt | 42 +++++++ tests/share/README.txt | 3 + tests/share/examples-README.md | 20 ++++ 20 files changed, 692 insertions(+), 616 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/CMakeLists.txt b/CMakeLists.txt index 105f22e..b9e1656 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,7 +39,7 @@ find_package (CyrusSASL) enable_testing () # Set up runtime checks (valgrind, sanitizers etc.) -include(runtime_check.cmake) +include(tests/runtime_check.cmake) ## Variables used across components @@ -394,8 +394,9 @@ endforeach(BINDING) unset(BUILD_BINDINGS CACHE) # Remove from cache, only relevant when creating the initial cache. -install (FILES LICENSE.txt README.md - DESTINATION ${PROTON_SHARE}) +install (FILES LICENSE.txt README.md tests/share/CMakeLists.txt DESTINATION ${PROTON_SHARE}) +install (FILES tests/share/examples-README.md RENAME README.md DESTINATION ${PROTON_SHARE}/examples) +install (DIRECTORY tests DESTINATION ${PROTON_SHARE} PATTERN share EXCLUDE) # Generate test environment settings configure_file(${CMAKE_SOURCE_DIR}/misc/config.sh.in http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/c/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/c/CMakeLists.txt b/c/CMakeLists.txt index a16f46b..effb96b 100644 --- a/c/CMakeLists.txt +++ b/c/CMakeLists.txt @@ -601,4 +601,5 @@ add_subdirectory(tools) install (DIRECTORY examples/ DESTINATION "${PROTON_SHARE}/examples/c" + USE_SOURCE_PERMISSIONS PATTERN ProtonConfig.cmake EXCLUDE) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/c/examples/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/c/examples/CMakeLists.txt b/c/examples/CMakeLists.txt index b04e444..8526ffe 100644 --- a/c/examples/CMakeLists.txt +++ b/c/examples/CMakeLists.txt @@ -34,20 +34,23 @@ foreach (name broker send receive direct send-abort send-ssl) endforeach() -# Add a test to run all examples +find_package (PythonInterp) # For test-driver script +if (PYTHON_EXECUTABLE) + if(WIN32) + # NOTE: need to escape semicolons as cmake uses them as list separators. + set(test_path "$<TARGET_FILE_DIR:c-broker>\;$<TARGET_FILE_DIR:qpid-proton-core>\;$<TARGET_FILE_DIR:qpid-proton-proactor>") + else() + set(test_path "$<TARGET_FILE_DIR:c-broker>:$ENV{PATH}") + endif() -# Make correct environment to find test executables and valgrind. -if(WIN32) - set(test_path "$<TARGET_FILE_DIR:c-broker>;$<TARGET_FILE_DIR:qpid-proton-core>;$<TARGET_FILE_DIR:qpid-proton-proactor>") -else() - set(test_path "$<TARGET_FILE_DIR:c-broker>:$ENV{PATH}") -endif() + set(test_env + "PATH=${test_path}" + "PYTHONPATH=../../tests/py" + ${TEST_ENV}) -add_test( - NAME c-example-tests - COMMAND ${PN_ENV_SCRIPT} - "PATH=${test_path}" - "PYTHONPATH=${CMAKE_SOURCE_DIR}/tests/py" - ${TEST_ENV} -- - ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example_test.py -v - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + add_test( + NAME c-example-tests + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND ${PYTHON_EXECUTABLE} testme -v) + set_tests_properties(c-example-tests PROPERTIES ENVIRONMENT "${test_env}") +endif() http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/c/examples/example_test.py ---------------------------------------------------------------------- diff --git a/c/examples/example_test.py b/c/examples/example_test.py deleted file mode 100644 index 35a8993..0000000 --- a/c/examples/example_test.py +++ /dev/null @@ -1,115 +0,0 @@ -# -# 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 -# - -# Run the C examples and verify that they behave as expected. -# Example executables must be in PATH - -import unittest - -from test_subprocess import Popen, TestProcessError, check_output - -class Server(Popen): - def __init__(self, *args, **kwargs): - super(Server, self).__init__(*args, **kwargs) - self.port = self.expect("listening on ([0-9]+)$").group(1) - -MESSAGES=10 - -def receive_expect_messages(n=MESSAGES): return ''.join(['{"sequence"=%s}\n'%i for i in range(1, n+1)]) -def receive_expect_total(n=MESSAGES): return "%s messages received\n"%n -def receive_expect(n=MESSAGES): return receive_expect_messages(n)+receive_expect_total(n) -def send_expect(n=MESSAGES): return "%s messages sent and acknowledged\n" % n -def send_abort_expect(n=MESSAGES): return "%s messages started and aborted\n" % n - -class Broker(Server): - def __init__(self): - super(Broker, self).__init__(["broker", "", "0"], kill_me=True) - -class ExampleTest(unittest.TestCase): - - def runex(self, name, port, messages=MESSAGES): - """Run an example with standard arguments, return output""" - return check_output([name, "", port, "xtest", str(messages)]) - - def startex(self, name, port, messages=MESSAGES): - """Start an example sub-process with standard arguments""" - return Popen([name, "", port, "xtest", str(messages)]) - - def test_send_receive(self): - """Send first then receive""" - with Broker() as b: - self.assertEqual(send_expect(), self.runex("send", b.port)) - self.assertMultiLineEqual(receive_expect(), self.runex("receive", b.port)) - - def test_receive_send(self): - """Start receiving first, then send.""" - with Broker() as b: - r = self.startex("receive", b.port) - self.assertEqual(send_expect(), self.runex("send", b.port)) - self.assertMultiLineEqual(receive_expect(), r.communicate()[0]) - - def test_send_direct(self): - """Send to direct server""" - d = Server(["direct", "", "0"]) - self.assertEqual(send_expect(), self.runex("send", d.port)) - self.assertMultiLineEqual(receive_expect(), d.communicate()[0]) - - def test_receive_direct(self): - """Receive from direct server""" - d = Server(["direct", "", "0"]) - self.assertMultiLineEqual(receive_expect(), self.runex("receive", d.port)) - self.assertEqual("10 messages sent and acknowledged\n", d.communicate()[0]) - - def test_send_abort_broker(self): - """Sending aborted messages to a broker""" - with Broker() as b: - self.assertEqual(send_expect(), self.runex("send", b.port)) - self.assertEqual(send_abort_expect(), self.runex("send-abort", b.port)) - for i in range(MESSAGES): - self.assertEqual("Message aborted\n", b.stdout.readline()) - self.assertEqual(send_expect(), self.runex("send", b.port)) - expect = receive_expect_messages(MESSAGES)+receive_expect_messages(MESSAGES)+receive_expect_total(20) - self.assertMultiLineEqual(expect, self.runex("receive", b.port, "20")) - - def test_send_abort_direct(self): - """Send aborted messages to the direct server""" - d = Server(["direct", "", "0", "examples", "20"]) - self.assertEqual(send_expect(), self.runex("send", d.port)) - self.assertEqual(send_abort_expect(), self.runex("send-abort", d.port)) - self.assertEqual(send_expect(), self.runex("send", d.port)) - expect = receive_expect_messages() + "Message aborted\n"*MESSAGES + receive_expect_messages()+receive_expect_total(20) - self.maxDiff = None - self.assertMultiLineEqual(expect, d.communicate()[0]) - - def test_send_ssl_receive(self): - """Send with SSL, then receive""" - try: - with Broker() as b: - got = self.runex("send-ssl", b.port) - self.assertIn("secure connection:", got) - self.assertIn(send_expect(), got) - self.assertMultiLineEqual(receive_expect(), self.runex("receive", b.port)) - except TestProcessError as e: - if e.output and e.output.startswith(b"error initializing SSL"): - print("Skipping %s: SSL not available" % self.id()) - else: - raise - -if __name__ == "__main__": - unittest.main() http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/c/examples/testme ---------------------------------------------------------------------- diff --git a/c/examples/testme b/c/examples/testme new file mode 100755 index 0000000..c498293 --- /dev/null +++ b/c/examples/testme @@ -0,0 +1,111 @@ +#!/usr/bin/python +# +# 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 +# + +# Run the C examples and verify that they behave as expected. +# Example executables must be in PATH + +import unittest + +from test_subprocess import Popen, Server, TestProcessError, check_output + +MESSAGES=10 + +def receive_expect_messages(n=MESSAGES): return ''.join(['{"sequence"=%s}\n'%i for i in range(1, n+1)]) +def receive_expect_total(n=MESSAGES): return "%s messages received\n"%n +def receive_expect(n=MESSAGES): return receive_expect_messages(n)+receive_expect_total(n) +def send_expect(n=MESSAGES): return "%s messages sent and acknowledged\n" % n +def send_abort_expect(n=MESSAGES): return "%s messages started and aborted\n" % n + +class Broker(Server): + def __init__(self): + super(Broker, self).__init__(["broker", "", "0"], kill_me=True) + +class ExampleTest(unittest.TestCase): + + def runex(self, name, port, messages=MESSAGES): + """Run an example with standard arguments, return output""" + return check_output([name, "", port, "xtest", str(messages)]) + + def startex(self, name, port, messages=MESSAGES): + """Start an example sub-process with standard arguments""" + return Popen([name, "", port, "xtest", str(messages)]) + + def test_send_receive(self): + """Send first then receive""" + with Broker() as b: + self.assertEqual(send_expect(), self.runex("send", b.port)) + self.assertMultiLineEqual(receive_expect(), self.runex("receive", b.port)) + + def test_receive_send(self): + """Start receiving first, then send.""" + with Broker() as b: + r = self.startex("receive", b.port) + self.assertEqual(send_expect(), self.runex("send", b.port)) + self.assertMultiLineEqual(receive_expect(), r.communicate()[0]) + + def test_send_direct(self): + """Send to direct server""" + d = Server(["direct", "", "0"]) + self.assertEqual(send_expect(), self.runex("send", d.port)) + self.assertMultiLineEqual(receive_expect(), d.communicate()[0]) + + def test_receive_direct(self): + """Receive from direct server""" + d = Server(["direct", "", "0"]) + self.assertMultiLineEqual(receive_expect(), self.runex("receive", d.port)) + self.assertEqual("10 messages sent and acknowledged\n", d.communicate()[0]) + + def test_send_abort_broker(self): + """Sending aborted messages to a broker""" + with Broker() as b: + self.assertEqual(send_expect(), self.runex("send", b.port)) + self.assertEqual(send_abort_expect(), self.runex("send-abort", b.port)) + for i in range(MESSAGES): + self.assertEqual("Message aborted\n", b.stdout.readline()) + self.assertEqual(send_expect(), self.runex("send", b.port)) + expect = receive_expect_messages(MESSAGES)+receive_expect_messages(MESSAGES)+receive_expect_total(20) + self.assertMultiLineEqual(expect, self.runex("receive", b.port, "20")) + + def test_send_abort_direct(self): + """Send aborted messages to the direct server""" + d = Server(["direct", "", "0", "examples", "20"]) + self.assertEqual(send_expect(), self.runex("send", d.port)) + self.assertEqual(send_abort_expect(), self.runex("send-abort", d.port)) + self.assertEqual(send_expect(), self.runex("send", d.port)) + expect = receive_expect_messages() + "Message aborted\n"*MESSAGES + receive_expect_messages()+receive_expect_total(20) + self.maxDiff = None + self.assertMultiLineEqual(expect, d.communicate()[0]) + + def test_send_ssl_receive(self): + """Send with SSL, then receive""" + try: + with Broker() as b: + got = self.runex("send-ssl", b.port) + self.assertIn("secure connection:", got) + self.assertIn(send_expect(), got) + self.assertMultiLineEqual(receive_expect(), self.runex("receive", b.port)) + except TestProcessError as e: + if e.output and e.output.startswith(b"error initializing SSL"): + print("Skipping %s: SSL not available" % self.id()) + else: + raise + +if __name__ == "__main__": + unittest.main() http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/cpp/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index a06e67d..d0b3cfb 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -198,6 +198,7 @@ install (DIRECTORY "include/proton" DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MAT install (FILES "${CMAKE_CURRENT_BINARY_DIR}/config_presets.hpp" DESTINATION "${INCLUDE_INSTALL_DIR}/proton/internal") install (DIRECTORY "examples/" DESTINATION "${PROTON_SHARE}/examples/cpp" + USE_SOURCE_PERMISSIONS PATTERN "ProtonCppConfig.cmake" EXCLUDE) add_subdirectory(examples) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/cpp/examples/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/cpp/examples/CMakeLists.txt b/cpp/examples/CMakeLists.txt index ba18d83..35ad01c 100644 --- a/cpp/examples/CMakeLists.txt +++ b/cpp/examples/CMakeLists.txt @@ -23,7 +23,7 @@ enable_language(CXX) set (ProtonCpp_DIR ${CMAKE_CURRENT_SOURCE_DIR}) find_package(ProtonCpp REQUIRED) set(CMAKE_THREAD_PREFER_PTHREAD TRUE) -find_package(Threads) +find_package(Threads REQUIRED) include_directories(${ProtonCpp_INCLUDE_DIRS}) link_libraries(${ProtonCpp_LIBRARIES}) @@ -103,26 +103,32 @@ if(HAS_ENOUGH_CPP11) endif() endif() -# Add a test with the correct environment to find test executables and valgrind. -macro(add_cpp_example_test name) +find_package (PythonInterp) # For test-driver script +if (PYTHON_EXECUTABLE) if(WIN32) - set(test_path "$<TARGET_FILE_DIR:broker>;$<TARGET_FILE_DIR:qpid-proton>;$<TARGET_FILE_DIR:qpid-proton-cpp>") - else(WIN32) + # NOTE: need to escape semicolons as cmake uses them as list separators. + set(test_path "$<TARGET_FILE_DIR:broker>\;$<TARGET_FILE_DIR:qpid-proton-core>\;$<TARGET_FILE_DIR:qpid-proton-cpp>") + else() set(test_path "$<TARGET_FILE_DIR:broker>:$ENV{PATH}") - endif(WIN32) - add_test( - NAME ${name} - COMMAND ${PN_ENV_SCRIPT} + endif() + + set(test_env "PATH=${test_path}" - "PYTHONPATH=${CMAKE_SOURCE_DIR}/tests/py" + "PYTHONPATH=../../tests/py" "HAS_CPP11=$<$<BOOL:${HAS_ENOUGH_CPP11}>:1>" - ${TEST_ENV} -- - ${ARGN} - ) -endmacro() + ${TEST_ENV}) -add_cpp_example_test(cpp-example-container ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example_test.py -v ContainerExampleTest) + add_test( + NAME cpp-example-container + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND ${PYTHON_EXECUTABLE} testme -v ContainerExampleTest) + set_tests_properties(cpp-example-container PROPERTIES ENVIRONMENT "${test_env}") -if (NOT SSL_IMPL STREQUAL none) -add_cpp_example_test(cpp-example-container-ssl ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example_test.py -v ContainerExampleSSLTest) + if (NOT SSL_IMPL STREQUAL none) + add_test( + NAME cpp-example-container-ssl + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMAND ${PYTHON_EXECUTABLE} testme -v ContainerExampleSSLTest) + set_tests_properties(cpp-example-container-ssl PROPERTIES ENVIRONMENT "${test_env}") + endif() endif() http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/cpp/examples/example_test.py ---------------------------------------------------------------------- diff --git a/cpp/examples/example_test.py b/cpp/examples/example_test.py deleted file mode 100644 index 38a9a6e..0000000 --- a/cpp/examples/example_test.py +++ /dev/null @@ -1,216 +0,0 @@ -# -# 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 -# - -# Run the C++ examples and verify that they behave as expected. -# Example executables must be in PATH - -import unittest, sys, shutil, os -from test_subprocess import Popen, TestProcessError, check_output -from os.path import dirname -from string import Template - -class Server(Popen): - """A process that prints 'listening on <port>' to stdout""" - def __init__(self, *args, **kwargs): - super(Server, self).__init__(*args, **kwargs) - self.port = self.expect("listening on ([0-9]+)$").group(1) - - @property - def addr(self): - return ":%s/example" % self.port - -def _cyrusSetup(conf_dir): - """Write out simple SASL config.tests - """ - saslpasswd = os.getenv('SASLPASSWD') - if saslpasswd: - t = Template("""sasldb_path: ${db} -mech_list: EXTERNAL DIGEST-MD5 SCRAM-SHA-1 CRAM-MD5 PLAIN ANONYMOUS -""") - abs_conf_dir = os.path.abspath(conf_dir) - shutil.rmtree(abs_conf_dir, True) - os.mkdir(abs_conf_dir) - db = os.path.join(abs_conf_dir,'proton.sasldb') - conf = os.path.join(abs_conf_dir,'proton-server.conf') - with open(conf, 'w') as f: - f.write(t.substitute(db=db)) - cmd_template = Template("echo password | ${saslpasswd} -c -p -f ${db} -u proton user") - cmd = cmd_template.substitute(db=db, saslpasswd=saslpasswd) - check_output(args=cmd, shell=True) - os.environ['PN_SASL_CONFIG_PATH'] = abs_conf_dir - -# Globally initialize Cyrus SASL configuration -_cyrusSetup('sasl-conf') - -class Broker(Server): - def __init__(self): - super(Broker, self).__init__(["broker", "-a", "//:0"], kill_me=True) - -CLIENT_EXPECT="""Twas brillig, and the slithy toves => TWAS BRILLIG, AND THE SLITHY TOVES -Did gire and gymble in the wabe. => DID GIRE AND GYMBLE IN THE WABE. -All mimsy were the borogroves, => ALL MIMSY WERE THE BOROGROVES, -And the mome raths outgrabe. => AND THE MOME RATHS OUTGRABE. -""" - -def recv_expect(): - return "".join(['{"sequence"=%s}\n' % (i+1) for i in range(100)]) - -class ContainerExampleTest(unittest.TestCase): - """Run the container examples, verify they behave as expected.""" - - def test_helloworld(self): - self.assertMultiLineEqual('Hello World!\n', check_output(["helloworld", Broker.addr])) - - def test_simple_send_recv(self): - self.assertMultiLineEqual("all messages confirmed\n", check_output(["simple_send", "-a", Broker.addr])) - self.assertMultiLineEqual(recv_expect(), check_output(["simple_recv", "-a", Broker.addr])) - - def test_simple_recv_send(self): - recv = Popen(["simple_recv", "-a", Broker.addr]) - self.assertMultiLineEqual("all messages confirmed\n", check_output(["simple_send", "-a", Broker.addr])) - self.assertMultiLineEqual(recv_expect(), recv.communicate()[0]) - - def test_simple_send_direct_recv(self): - recv = Server(["direct_recv", "-a", "//:0"]) - self.assertMultiLineEqual("all messages confirmed\n", check_output(["simple_send", "-a", recv.addr])) - self.assertMultiLineEqual(recv_expect(), recv.communicate()[0]) - - def test_simple_recv_direct_send(self): - send = Server(["direct_send", "-a", "//:0"]) - self.assertMultiLineEqual(recv_expect(), check_output(["simple_recv", "-a", send.addr])) - self.assertMultiLineEqual("all messages confirmed\n", send.communicate()[0]) - - def test_request_response(self): - with Popen(["server", Broker.addr, "example"], kill_me=True) as server: - server.expect("connected to %s" % Broker.addr) - self.assertMultiLineEqual(CLIENT_EXPECT, check_output(["client", "-a", Broker.addr])) - - def test_request_response_direct(self): - with Server(["server_direct", "-a", "//:0"], kill_me=True) as server: - self.assertMultiLineEqual(CLIENT_EXPECT, check_output(["client", "-a", server.addr])) - - def test_flow_control(self): - want="""success: Example 1: simple credit -success: Example 2: basic drain -success: Example 3: drain without credit -success: Example 4: high/low watermark -""" - self.assertMultiLineEqual(want, check_output(["flow_control", "--quiet"])) - - def test_encode_decode(self): - want=""" -== Array, list and map of uniform type. -array<int>[int(1), int(2), int(3)] -[ 1 2 3 ] -list[int(1), int(2), int(3)] -[ 1 2 3 ] -map{string(one):int(1), string(two):int(2)} -{ one:1 two:2 } -map{string(z):int(3), string(a):int(4)} -[ z:3 a:4 ] -list[string(a), string(b), string(c)] - -== List and map of mixed type values. -list[int(42), string(foo)] -[ 42 foo ] -map{int(4):string(four), string(five):int(5)} -{ 4:four five:5 } - -== Insert with stream operators. -array<int>[int(1), int(2), int(3)] -list[int(42), boolean(0), symbol(x)] -map{string(k1):int(42), symbol(k2):boolean(0)} -""" - self.maxDiff = None - self.assertMultiLineEqual(want, check_output(["encode_decode"])) - - def test_scheduled_send_03(self): - # Output should be a bunch of "send" lines but can't guarantee exactly how many. - out = check_output(["scheduled_send_03", "-a", Broker.addr+"scheduled_send", "-t", "0.1", "-i", "0.001"]).split() - self.assertTrue(len(out) > 0); - self.assertEqual(["send"]*len(out), out) - - @unittest.skipUnless(os.getenv('HAS_CPP11'), "not a C++11 build") - def test_scheduled_send(self): - out = check_output(["scheduled_send", "-a", Broker.addr+"scheduled_send", "-t", "0.1", "-i", "0.001"]).split() - self.assertTrue(len(out) > 0); - self.assertEqual(["send"]*len(out), out) - - def test_message_properties(self): - expect="""using put/get: short=123 string=foo symbol=sym -using coerce: short(as long)=123 -props[short]=123 -props[string]=foo -props[symbol]=sym -short=42 string=bar -expected conversion_error: "unexpected type, want: uint got: int" -expected conversion_error: "unexpected type, want: uint got: string" -""" - self.assertMultiLineEqual(expect, check_output(["message_properties"])) - - @unittest.skipUnless(os.getenv('HAS_CPP11'), "not a C++11 build") - def test_multithreaded_client(self): - got = check_output(["multithreaded_client", Broker.addr, "examples", "10"]) - self.maxDiff = None - self.assertIn("10 messages sent and received", got); - -# @unittest.skipUnless(os.getenv('HAS_CPP11'), "not a C++11 build") - @unittest.skip("Test is unstable, will enable when fixed") - def test_multithreaded_client_flow_control(self): - got = check_output(["multithreaded_client_flow_control", Broker.addr, "examples", "10", "2"]) - self.maxDiff = None - self.assertIn("20 messages sent and received", got); - -class ContainerExampleSSLTest(unittest.TestCase): - """Run the SSL container examples, verify they behave as expected.""" - - def ssl_certs_dir(self): - """Absolute path to the test SSL certificates""" - return os.path.join(dirname(sys.argv[0]), "ssl-certs") - - def test_ssl(self): - # SSL without SASL, VERIFY_PEER_NAME - out = check_output(["ssl", "-c", self.ssl_certs_dir()]) - expect = "Server certificate identity CN=test_server\nHello World!" - self.assertIn(expect, out) - - def test_ssl_no_name(self): - out = check_output(["ssl", "-c", self.ssl_certs_dir(), "-v", "noname"]) - expect = "Outgoing client connection connected via SSL. Server certificate identity CN=test_server\nHello World!" - self.assertIn(expect, out) - - def test_ssl_bad_name(self): - # VERIFY_PEER - out = check_output(["ssl", "-c", self.ssl_certs_dir(), "-v", "fail"]) - expect = "Expected failure of connection with wrong peer name" - self.assertIn(expect, out) - - def test_ssl_client_cert(self): - # SSL with SASL EXTERNAL - expect="""Inbound client certificate identity CN=test_client -Outgoing client connection connected via SSL. Server certificate identity CN=test_server -Hello World! -""" - out = check_output(["ssl_client_cert", self.ssl_certs_dir()]) - self.assertIn(expect, out) - -if __name__ == "__main__": - with Broker() as b: - Broker.addr = b.addr - unittest.main() http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/cpp/examples/testme ---------------------------------------------------------------------- diff --git a/cpp/examples/testme b/cpp/examples/testme new file mode 100755 index 0000000..d4abc0a --- /dev/null +++ b/cpp/examples/testme @@ -0,0 +1,213 @@ +#!/usr/bin/python +# +# 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 +# + +# Run the C++ examples and verify that they behave as expected. +# Example executables must be in PATH + +import unittest, sys, shutil, os +from test_subprocess import Popen, TestProcessError, check_output +import test_subprocess +from os.path import dirname +from string import Template + +class Server(test_subprocess.Server): + @property + def addr(self): + return ":%s/example" % self.port + +def _cyrusSetup(conf_dir): + """Write out simple SASL config.tests + """ + saslpasswd = os.getenv('SASLPASSWD') + if saslpasswd: + t = Template("""sasldb_path: ${db} +mech_list: EXTERNAL DIGEST-MD5 SCRAM-SHA-1 CRAM-MD5 PLAIN ANONYMOUS +""") + abs_conf_dir = os.path.abspath(conf_dir) + shutil.rmtree(abs_conf_dir, True) + os.mkdir(abs_conf_dir) + db = os.path.join(abs_conf_dir,'proton.sasldb') + conf = os.path.join(abs_conf_dir,'proton-server.conf') + with open(conf, 'w') as f: + f.write(t.substitute(db=db)) + cmd_template = Template("echo password | ${saslpasswd} -c -p -f ${db} -u proton user") + cmd = cmd_template.substitute(db=db, saslpasswd=saslpasswd) + check_output(args=cmd, shell=True) + os.environ['PN_SASL_CONFIG_PATH'] = abs_conf_dir + +# Globally initialize Cyrus SASL configuration +_cyrusSetup('sasl-conf') + +class Broker(Server): + def __init__(self): + super(Broker, self).__init__(["broker", "-a", "//:0"], kill_me=True) + +CLIENT_EXPECT="""Twas brillig, and the slithy toves => TWAS BRILLIG, AND THE SLITHY TOVES +Did gire and gymble in the wabe. => DID GIRE AND GYMBLE IN THE WABE. +All mimsy were the borogroves, => ALL MIMSY WERE THE BOROGROVES, +And the mome raths outgrabe. => AND THE MOME RATHS OUTGRABE. +""" + +def recv_expect(): + return "".join(['{"sequence"=%s}\n' % (i+1) for i in range(100)]) + +class ContainerExampleTest(unittest.TestCase): + """Run the container examples, verify they behave as expected.""" + + def test_helloworld(self): + self.assertMultiLineEqual('Hello World!\n', check_output(["helloworld", Broker.addr])) + + def test_simple_send_recv(self): + self.assertMultiLineEqual("all messages confirmed\n", check_output(["simple_send", "-a", Broker.addr])) + self.assertMultiLineEqual(recv_expect(), check_output(["simple_recv", "-a", Broker.addr])) + + def test_simple_recv_send(self): + recv = Popen(["simple_recv", "-a", Broker.addr]) + self.assertMultiLineEqual("all messages confirmed\n", check_output(["simple_send", "-a", Broker.addr])) + self.assertMultiLineEqual(recv_expect(), recv.communicate()[0]) + + def test_simple_send_direct_recv(self): + recv = Server(["direct_recv", "-a", "//:0"]) + self.assertMultiLineEqual("all messages confirmed\n", check_output(["simple_send", "-a", recv.addr])) + self.assertMultiLineEqual(recv_expect(), recv.communicate()[0]) + + def test_simple_recv_direct_send(self): + send = Server(["direct_send", "-a", "//:0"]) + self.assertMultiLineEqual(recv_expect(), check_output(["simple_recv", "-a", send.addr])) + self.assertMultiLineEqual("all messages confirmed\n", send.communicate()[0]) + + def test_request_response(self): + with Popen(["server", Broker.addr, "example"], kill_me=True) as server: + server.expect("connected to %s" % Broker.addr) + self.assertMultiLineEqual(CLIENT_EXPECT, check_output(["client", "-a", Broker.addr])) + + def test_request_response_direct(self): + with Server(["server_direct", "-a", "//:0"], kill_me=True) as server: + self.assertMultiLineEqual(CLIENT_EXPECT, check_output(["client", "-a", server.addr])) + + def test_flow_control(self): + want="""success: Example 1: simple credit +success: Example 2: basic drain +success: Example 3: drain without credit +success: Example 4: high/low watermark +""" + self.assertMultiLineEqual(want, check_output(["flow_control", "--quiet"])) + + def test_encode_decode(self): + want=""" +== Array, list and map of uniform type. +array<int>[int(1), int(2), int(3)] +[ 1 2 3 ] +list[int(1), int(2), int(3)] +[ 1 2 3 ] +map{string(one):int(1), string(two):int(2)} +{ one:1 two:2 } +map{string(z):int(3), string(a):int(4)} +[ z:3 a:4 ] +list[string(a), string(b), string(c)] + +== List and map of mixed type values. +list[int(42), string(foo)] +[ 42 foo ] +map{int(4):string(four), string(five):int(5)} +{ 4:four five:5 } + +== Insert with stream operators. +array<int>[int(1), int(2), int(3)] +list[int(42), boolean(0), symbol(x)] +map{string(k1):int(42), symbol(k2):boolean(0)} +""" + self.maxDiff = None + self.assertMultiLineEqual(want, check_output(["encode_decode"])) + + def test_scheduled_send_03(self): + # Output should be a bunch of "send" lines but can't guarantee exactly how many. + out = check_output(["scheduled_send_03", "-a", Broker.addr+"scheduled_send", "-t", "0.1", "-i", "0.001"]).split() + self.assertTrue(len(out) > 0); + self.assertEqual(["send"]*len(out), out) + + @unittest.skipUnless(os.getenv('HAS_CPP11'), "not a C++11 build") + def test_scheduled_send(self): + out = check_output(["scheduled_send", "-a", Broker.addr+"scheduled_send", "-t", "0.1", "-i", "0.001"]).split() + self.assertTrue(len(out) > 0); + self.assertEqual(["send"]*len(out), out) + + def test_message_properties(self): + expect="""using put/get: short=123 string=foo symbol=sym +using coerce: short(as long)=123 +props[short]=123 +props[string]=foo +props[symbol]=sym +short=42 string=bar +expected conversion_error: "unexpected type, want: uint got: int" +expected conversion_error: "unexpected type, want: uint got: string" +""" + self.assertMultiLineEqual(expect, check_output(["message_properties"])) + + @unittest.skipUnless(os.getenv('HAS_CPP11'), "not a C++11 build") + def test_multithreaded_client(self): + got = check_output(["multithreaded_client", Broker.addr, "examples", "10"]) + self.maxDiff = None + self.assertIn("10 messages sent and received", got); + +# @unittest.skipUnless(os.getenv('HAS_CPP11'), "not a C++11 build") + @unittest.skip("Test is unstable, will enable when fixed") + def test_multithreaded_client_flow_control(self): + got = check_output(["multithreaded_client_flow_control", Broker.addr, "examples", "10", "2"]) + self.maxDiff = None + self.assertIn("20 messages sent and received", got); + +class ContainerExampleSSLTest(unittest.TestCase): + """Run the SSL container examples, verify they behave as expected.""" + + def ssl_certs_dir(self): + """Absolute path to the test SSL certificates""" + return os.path.join(dirname(sys.argv[0]), "ssl-certs") + + def test_ssl(self): + # SSL without SASL, VERIFY_PEER_NAME + out = check_output(["ssl", "-c", self.ssl_certs_dir()]) + expect = "Server certificate identity CN=test_server\nHello World!" + self.assertIn(expect, out) + + def test_ssl_no_name(self): + out = check_output(["ssl", "-c", self.ssl_certs_dir(), "-v", "noname"]) + expect = "Outgoing client connection connected via SSL. Server certificate identity CN=test_server\nHello World!" + self.assertIn(expect, out) + + def test_ssl_bad_name(self): + # VERIFY_PEER + out = check_output(["ssl", "-c", self.ssl_certs_dir(), "-v", "fail"]) + expect = "Expected failure of connection with wrong peer name" + self.assertIn(expect, out) + + def test_ssl_client_cert(self): + # SSL with SASL EXTERNAL + expect="""Inbound client certificate identity CN=test_client +Outgoing client connection connected via SSL. Server certificate identity CN=test_server +Hello World! +""" + out = check_output(["ssl_client_cert", self.ssl_certs_dir()]) + self.assertIn(expect, out) + +if __name__ == "__main__": + with Broker() as b: + Broker.addr = b.addr + unittest.main() http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/go/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/go/CMakeLists.txt b/go/CMakeLists.txt index 951f8a3..5887635 100644 --- a/go/CMakeLists.txt +++ b/go/CMakeLists.txt @@ -84,4 +84,7 @@ set (GO_INSTALL_DIR ${SHARE_INSTALL_DIR}/gocode/src CACHE PATH "Installation dir mark_as_advanced (GO_INSTALL_DIR) install(DIRECTORY src/qpid.apache.org DESTINATION ${GO_INSTALL_DIR} COMPONENT Go) -install(DIRECTORY examples/ DESTINATION "${PROTON_SHARE}/examples/go" COMPONENT Go) +install(DIRECTORY examples/ + DESTINATION "${PROTON_SHARE}/examples/go" + COMPONENT Go + PATTERN "CMakeLists.txt" EXCLUDE) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/python/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 181128c..c9e659e 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -151,10 +151,7 @@ install(TARGETS ${SWIG_MODULE_cproton_REAL_NAME} install(DIRECTORY examples/ DESTINATION "${PROTON_SHARE}/examples/python" COMPONENT Python - PATTERN "*.py" - PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ - GROUP_EXECUTE GROUP_READ - WORLD_EXECUTE WORLD_READ) + USE_SOURCE_PERMISSIONS) set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "html;tutorial") http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/ruby/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/ruby/CMakeLists.txt b/ruby/CMakeLists.txt index eb99907..ca342dc 100644 --- a/ruby/CMakeLists.txt +++ b/ruby/CMakeLists.txt @@ -112,11 +112,7 @@ install(DIRECTORY lib/ DESTINATION ${RUBY_ARCHLIB_DIR} COMPONENT Ruby) install(DIRECTORY examples/ DESTINATION "${PROTON_SHARE}/examples/ruby" COMPONENT Ruby - PATTERN "*.rb" - PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ - GROUP_EXECUTE GROUP_READ - WORLD_EXECUTE WORLD_READ) - + USE_SOURCE_PERMISSIONS) ## Tests to_native_path("${src}/lib;${src}/tests;${src}/spec;${bin};${c_lib_dir};$ENV{RUBYLIB}" RUBYLIB) @@ -138,10 +134,18 @@ if (result EQUAL 0) # Have minitest NAME ${name} COMMAND ${test_env} ${TEST_WRAP_PREFIX_CMD} ${RUBY_EXECUTABLE} ${script} -v ${ARGN}) - endmacro() - add_ruby_test(example_test.rb WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/examples) - add_ruby_test(old_example_test.rb WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/old-examples) + + add_test( + NAME ruby-example-test + COMMAND ${test_env} ${RUBY_EXECUTABLE} testme -v + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/examples) + + add_test( + NAME ruby-old-example-test + COMMAND ${test_env} ${RUBY_EXECUTABLE} old_example_test.rb -v + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/old-examples) + file(GLOB TESTS tests/test_*.rb) file(GLOB SPECS spec/*_spec.rb) foreach(t ${TESTS} ${SPECS}) http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/ruby/examples/example_test.rb ---------------------------------------------------------------------- diff --git a/ruby/examples/example_test.rb b/ruby/examples/example_test.rb deleted file mode 100755 index 576acf2..0000000 --- a/ruby/examples/example_test.rb +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env ruby -# -# 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. -# - -require 'minitest/autorun' -require 'qpid_proton' -require 'socket' -require 'rbconfig' - -begin - MiniTest::Test -rescue NameError # For older versions of MiniTest - MiniTest::Test = MiniTest::Unit::TestCase -end - -def listening_port(s) - /Listening on ([0-9]+)/.match(s)[1] -end - -def listening_url(s) - ":#{listening_port s}" -end - -class ExampleTest < MiniTest::Test - - def run_script(*args) - return IO.popen([ RbConfig.ruby ] + args.map { |a| a.to_s }) - end - - def assert_output(want, *args) - assert_equal(want.strip, run_script(*args).read.strip) - end - - def test_helloworld - assert_output("Hello world!", "helloworld.rb", $url, "examples") - end - - def test_client_server - want = <<EOS --> Twas brillig, and the slithy toves -<- TWAS BRILLIG, AND THE SLITHY TOVES --> Did gire and gymble in the wabe. -<- DID GIRE AND GYMBLE IN THE WABE. --> All mimsy were the borogroves, -<- ALL MIMSY WERE THE BOROGROVES, --> And the mome raths outgrabe. -<- AND THE MOME RATHS OUTGRABE. -EOS - server = run_script("server.rb", $url, "examples") - assert_output(want.strip, "client.rb", $url, "examples") - ensure - Process.kill :TERM, server.pid if server - end - - def test_send_recv - assert_output("All 10 messages confirmed!", "simple_send.rb", $url, "examples") - want = (0..9).reduce("") { |x,y| x << "Received: sequence #{y}\n" } - assert_output(want.strip, "simple_recv.rb", $url, "examples") - end - - def test_ssl_send_recv - skip 'SSL not available' unless Qpid::Proton::SSL.present? - out = run_script("ssl_send.rb", $url, "examples").read.strip - assert_match(/Connection secured with "...*\"\nAll 10 messages confirmed!/, out) - want = (0..9).reduce("") { |x,y| x << "Received: sequence #{y}\n" } - assert_output(want.strip, "simple_recv.rb", $url, "examples") - end - - def test_direct_recv - p = run_script("direct_recv.rb", ":0", "examples") - url = listening_url(p.readline) # Wait till ready - assert_output("All 10 messages confirmed!", "simple_send.rb", url, "examples") - want = (0..9).reduce("") { |x,y| x << "Received: sequence #{y}\n" } - assert_equal(want.strip, p.read.strip) - end - - def test_direct_send - p = run_script("direct_send.rb", ":0", "examples") - url = listening_url(p.readline) # Wait till ready - want = (0..9).reduce("") { |x,y| x << "Received: sequence #{y}\n" } - assert_output(want.strip, "simple_recv.rb", url, "examples") - assert_equal("All 10 messages confirmed!", p.read.strip) - end -end - -# Start the broker before all tests. -$broker = IO.popen([RbConfig.ruby, 'broker.rb', ":0"]) -l = $broker.readline -$url = listening_url(l) - -# Kill the broker after all tests -MiniTest.after_run do - Process.kill(:TERM, $broker.pid) if $broker -end http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/ruby/examples/testme ---------------------------------------------------------------------- diff --git a/ruby/examples/testme b/ruby/examples/testme new file mode 100755 index 0000000..5c0c59d --- /dev/null +++ b/ruby/examples/testme @@ -0,0 +1,110 @@ +#!/usr/bin/ruby +# +# 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. +# + +require 'minitest/autorun' +require 'qpid_proton' +require 'socket' +require 'rbconfig' + +begin + MiniTest::Test +rescue NameError # For older versions of MiniTest + MiniTest::Test = MiniTest::Unit::TestCase +end + +def listening_port(s) + /Listening on ([0-9]+)/.match(s)[1] +end + +def listening_url(s) + ":#{listening_port s}" +end + +class ExampleTest < MiniTest::Test + + def run_script(*args) + return IO.popen([ RbConfig.ruby ] + args.map { |a| a.to_s }) + end + + def assert_output(want, *args) + assert_equal(want.strip, run_script(*args).read.strip) + end + + def test_helloworld + assert_output("Hello world!", "helloworld.rb", $url, "examples") + end + + def test_client_server + want = <<EOS +-> Twas brillig, and the slithy toves +<- TWAS BRILLIG, AND THE SLITHY TOVES +-> Did gire and gymble in the wabe. +<- DID GIRE AND GYMBLE IN THE WABE. +-> All mimsy were the borogroves, +<- ALL MIMSY WERE THE BOROGROVES, +-> And the mome raths outgrabe. +<- AND THE MOME RATHS OUTGRABE. +EOS + server = run_script("server.rb", $url, "examples") + assert_output(want.strip, "client.rb", $url, "examples") + ensure + Process.kill :TERM, server.pid if server + end + + def test_send_recv + assert_output("All 10 messages confirmed!", "simple_send.rb", $url, "examples") + want = (0..9).reduce("") { |x,y| x << "Received: sequence #{y}\n" } + assert_output(want.strip, "simple_recv.rb", $url, "examples") + end + + def test_ssl_send_recv + skip 'SSL not available' unless Qpid::Proton::SSL.present? + out = run_script("ssl_send.rb", $url, "examples").read.strip + assert_match(/Connection secured with "...*\"\nAll 10 messages confirmed!/, out) + want = (0..9).reduce("") { |x,y| x << "Received: sequence #{y}\n" } + assert_output(want.strip, "simple_recv.rb", $url, "examples") + end + + def test_direct_recv + p = run_script("direct_recv.rb", ":0", "examples") + url = listening_url(p.readline) # Wait till ready + assert_output("All 10 messages confirmed!", "simple_send.rb", url, "examples") + want = (0..9).reduce("") { |x,y| x << "Received: sequence #{y}\n" } + assert_equal(want.strip, p.read.strip) + end + + def test_direct_send + p = run_script("direct_send.rb", ":0", "examples") + url = listening_url(p.readline) # Wait till ready + want = (0..9).reduce("") { |x,y| x << "Received: sequence #{y}\n" } + assert_output(want.strip, "simple_recv.rb", url, "examples") + assert_equal("All 10 messages confirmed!", p.read.strip) + end +end + +# Start the broker before all tests. +$broker = IO.popen([RbConfig.ruby, 'broker.rb', ":0"]) +l = $broker.readline +$url = listening_url(l) + +# Kill the broker after all tests +MiniTest.after_run do + Process.kill(:TERM, $broker.pid) if $broker +end http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/runtime_check.cmake ---------------------------------------------------------------------- diff --git a/runtime_check.cmake b/runtime_check.cmake deleted file mode 100644 index e1d76c3..0000000 --- a/runtime_check.cmake +++ /dev/null @@ -1,123 +0,0 @@ -# -# 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. -# - -# Configuration for code analysis tools: runtime checking and coverage. - -# Any test that needs runtime checks should use TEST_EXE_PREFIX and TEST_ENV. -# Normally they are set as a result of the RUNTIME_CHECK value, -# but can be set directly for unsupported tools or unusual flags -# e.g. -DTEST_EXE_PREFIX=rr or -DTEST_EXE_PREFIX="valgrind --tool=massif" - -set(TEST_EXE_PREFIX "" CACHE STRING "Prefix for test executable command line") -set(TEST_WRAP_PREFIX "" CACHE STRING "Prefix for interpreter tests (e.g. python, ruby) that load proton as an extension") -set(TEST_ENV "" CACHE STRING "Extra environment for tests: name1=value1;name2=value2") -mark_as_advanced(TEST_EXE_PREFIX TEST_WRAP_PREFIX TEST_ENV) - -# Check for valgrind -find_program(VALGRIND_EXECUTABLE valgrind DOC "location of valgrind program") -set(VALGRIND_SUPPRESSIONS "${CMAKE_SOURCE_DIR}/tests/valgrind.supp" CACHE STRING "Suppressions file for valgrind") -set(VALGRIND_COMMON_ARGS "--error-exitcode=42 --quiet --suppressions=${VALGRIND_SUPPRESSIONS}") -mark_as_advanced(VALGRIND_EXECUTABLE VALGRIND_SUPPRESSIONS VALGRIND_COMMON_ARGS) - -# Check for compiler sanitizers -if((CMAKE_C_COMPILER_ID MATCHES "GNU" - AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 4.8) - OR (CMAKE_C_COMPILER_ID MATCHES "Clang" - AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 4.1)) - set(HAS_SANITIZERS TRUE) -endif() - -# Valid values for RUNTIME_CHECK -set(runtime_checks OFF asan tsan memcheck helgrind) - -# Set the default -if(NOT CMAKE_BUILD_TYPE MATCHES "Coverage" AND VALGRIND_EXECUTABLE) - set(RUNTIME_CHECK_DEFAULT "memcheck") -endif() - -# Deprecated options to enable runtime checks -macro(deprecated_enable_check old new doc) - option(${old} ${doc} OFF) - if (${old}) - message("WARNING: option ${old} is deprecated, use RUNTIME_CHECK=${new} instead") - set(RUNTIME_CHECK_DEFAULT ${new}) - endif() -endmacro() -deprecated_enable_check(ENABLE_VALGRIND memcheck "Use valgrind to detect run-time problems") -deprecated_enable_check(ENABLE_SANITIZERS asan "Compile with memory sanitizers (asan, ubsan)") -deprecated_enable_check(ENABLE_TSAN tsan "Compile with thread sanitizer (tsan)") - -set(RUNTIME_CHECK ${RUNTIME_CHECK_DEFAULT} CACHE string "Enable runtime checks. Valid values: ${runtime_checks}") - -if(CMAKE_BUILD_TYPE MATCHES "Coverage" AND RUNTIME_CHECK) - message(FATAL_ERROR "Cannot set RUNTIME_CHECK with CMAKE_BUILD_TYPE=Coverage") -endif() - -macro(assert_has_sanitizers) - if(NOT HAS_SANITIZERS) - message(FATAL_ERROR "compiler sanitizers are not available") - endif() -endmacro() - -macro(assert_has_valgrind) - if(NOT VALGRIND_EXECUTABLE) - message(FATAL_ERROR "valgrind is not available") - endif() -endmacro() - -if(RUNTIME_CHECK STREQUAL "memcheck") - assert_has_valgrind() - message(STATUS "Runtime memory checker: valgrind memcheck") - set(TEST_EXE_PREFIX "${VALGRIND_EXECUTABLE} --tool=memcheck --leak-check=full ${VALGRIND_COMMON_ARGS}") - # FIXME aconway 2018-09-06: NO TEST_WRAP_PREFIX, need --trace-children + many suppressions - -elseif(RUNTIME_CHECK STREQUAL "helgrind") - assert_has_valgrind() - message(STATUS "Runtime race checker: valgrind helgrind") - set(TEST_EXE_PREFIX "${VALGRIND_EXECUTABLE} --tool=helgrind ${VALGRIND_COMMON_ARGS}") - # FIXME aconway 2018-09-06: NO TEST_WRAP_PREFIX, need --trace-children + many suppressions - -elseif(RUNTIME_CHECK STREQUAL "asan") - assert_has_sanitizers() - message(STATUS "Runtime memory checker: gcc/clang memory sanitizers") - set(SANITIZE_FLAGS "-g -fno-omit-frame-pointer -fsanitize=address,undefined") - set(TEST_WRAP_PREFIX "${CMAKE_SOURCE_DIR}/tests/preload_asan.sh $<TARGET_FILE:qpid-proton-core>") - -elseif(RUNTIME_CHECK STREQUAL "tsan") - assert_has_sanitizers() - message(STATUS "Runtime race checker: gcc/clang thread sanitizer") - set(SANITIZE_FLAGS "-g -fno-omit-frame-pointer -fsanitize=thread") - -elseif(RUNTIME_CHECK) - message(FATAL_ERROR "'RUNTIME_CHECK=${RUNTIME_CHECK}' is invalid, valid values: ${runtime_checks}") -endif() - -if(SANITIZE_FLAGS) - set(ENABLE_UNDEFINED_ERROR OFF CACHE BOOL "Disabled for sanitizers" FORCE) - string(APPEND CMAKE_C_FLAGS " ${SANITIZE_FLAGS}") - string(APPEND CMAKE_CXX_FLAGS "${SANITIZE_FLAGS}") -endif() - -if(TEST_EXE_PREFIX) - # Add TEST_EXE_PREFIX to TEST_ENV so test runner scripts can use it. - list(APPEND TEST_ENV "TEST_EXE_PREFIX=${TEST_EXE_PREFIX}") - # Make a CMake-list form of TEST_EXE_PREFIX for add_test() commands - separate_arguments(TEST_EXE_PREFIX_CMD UNIX_COMMAND "${TEST_EXE_PREFIX}") -endif() -separate_arguments(TEST_WRAP_PREFIX_CMD UNIX_COMMAND "${TEST_WRAP_PREFIX}") http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/tests/py/test_subprocess.py ---------------------------------------------------------------------- diff --git a/tests/py/test_subprocess.py b/tests/py/test_subprocess.py index 1c7d2b9..512123f 100644 --- a/tests/py/test_subprocess.py +++ b/tests/py/test_subprocess.py @@ -33,7 +33,7 @@ class TestProcessError(Exception): class Popen(subprocess.Popen): """ - Adds TEST_EXE_PREFIX to the command and checks stderr for runtime checker output. + Add TEST_EXE_PREFIX to the command, check stderr for runtime checker output. In a 'with' statement it runs check_wait() on exit from the block, or check_kill() if initialized with kill_me=True """ @@ -43,11 +43,13 @@ class Popen(subprocess.Popen): Takes all args and kwargs of subprocess.Popen except stdout, stderr, universal_newlines kill_me=True runs check_kill() in __exit__() instead of check_wait() """ - self.cmd = args[0] self.on_exit = self.check_kill if kwargs.pop('kill_me', False) else self.check_wait self.errfile = tempfile.NamedTemporaryFile(delete=False) kwargs.update({'universal_newlines': True, 'stdout': PIPE, 'stderr': self.errfile}) - args = ((os.environ.get("TEST_EXE_PREFIX", "").split() + args[0]),) + args[1:] + prefix = os.environ.get("TEST_EXE_PREFIX") + if prefix: + args = [prefix.split() + args[0]] + list(args[1:]) + self.cmd = args[0] super(Popen, self).__init__(*args, **kwargs) def check_wait(self): @@ -75,7 +77,7 @@ class Popen(subprocess.Popen): line = self.stdout.readline() match = re.search(pattern, line) if not match: - raise Exception("%s: can't find '%s' in '%s'" % (self.cmd, pattern, line)) + raise TestProcessError(self, "can't find '%s' in '%s'" % (pattern, line)) return match @property http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/tests/runtime_check.cmake ---------------------------------------------------------------------- diff --git a/tests/runtime_check.cmake b/tests/runtime_check.cmake new file mode 100644 index 0000000..e1d76c3 --- /dev/null +++ b/tests/runtime_check.cmake @@ -0,0 +1,123 @@ +# +# 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. +# + +# Configuration for code analysis tools: runtime checking and coverage. + +# Any test that needs runtime checks should use TEST_EXE_PREFIX and TEST_ENV. +# Normally they are set as a result of the RUNTIME_CHECK value, +# but can be set directly for unsupported tools or unusual flags +# e.g. -DTEST_EXE_PREFIX=rr or -DTEST_EXE_PREFIX="valgrind --tool=massif" + +set(TEST_EXE_PREFIX "" CACHE STRING "Prefix for test executable command line") +set(TEST_WRAP_PREFIX "" CACHE STRING "Prefix for interpreter tests (e.g. python, ruby) that load proton as an extension") +set(TEST_ENV "" CACHE STRING "Extra environment for tests: name1=value1;name2=value2") +mark_as_advanced(TEST_EXE_PREFIX TEST_WRAP_PREFIX TEST_ENV) + +# Check for valgrind +find_program(VALGRIND_EXECUTABLE valgrind DOC "location of valgrind program") +set(VALGRIND_SUPPRESSIONS "${CMAKE_SOURCE_DIR}/tests/valgrind.supp" CACHE STRING "Suppressions file for valgrind") +set(VALGRIND_COMMON_ARGS "--error-exitcode=42 --quiet --suppressions=${VALGRIND_SUPPRESSIONS}") +mark_as_advanced(VALGRIND_EXECUTABLE VALGRIND_SUPPRESSIONS VALGRIND_COMMON_ARGS) + +# Check for compiler sanitizers +if((CMAKE_C_COMPILER_ID MATCHES "GNU" + AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 4.8) + OR (CMAKE_C_COMPILER_ID MATCHES "Clang" + AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 4.1)) + set(HAS_SANITIZERS TRUE) +endif() + +# Valid values for RUNTIME_CHECK +set(runtime_checks OFF asan tsan memcheck helgrind) + +# Set the default +if(NOT CMAKE_BUILD_TYPE MATCHES "Coverage" AND VALGRIND_EXECUTABLE) + set(RUNTIME_CHECK_DEFAULT "memcheck") +endif() + +# Deprecated options to enable runtime checks +macro(deprecated_enable_check old new doc) + option(${old} ${doc} OFF) + if (${old}) + message("WARNING: option ${old} is deprecated, use RUNTIME_CHECK=${new} instead") + set(RUNTIME_CHECK_DEFAULT ${new}) + endif() +endmacro() +deprecated_enable_check(ENABLE_VALGRIND memcheck "Use valgrind to detect run-time problems") +deprecated_enable_check(ENABLE_SANITIZERS asan "Compile with memory sanitizers (asan, ubsan)") +deprecated_enable_check(ENABLE_TSAN tsan "Compile with thread sanitizer (tsan)") + +set(RUNTIME_CHECK ${RUNTIME_CHECK_DEFAULT} CACHE string "Enable runtime checks. Valid values: ${runtime_checks}") + +if(CMAKE_BUILD_TYPE MATCHES "Coverage" AND RUNTIME_CHECK) + message(FATAL_ERROR "Cannot set RUNTIME_CHECK with CMAKE_BUILD_TYPE=Coverage") +endif() + +macro(assert_has_sanitizers) + if(NOT HAS_SANITIZERS) + message(FATAL_ERROR "compiler sanitizers are not available") + endif() +endmacro() + +macro(assert_has_valgrind) + if(NOT VALGRIND_EXECUTABLE) + message(FATAL_ERROR "valgrind is not available") + endif() +endmacro() + +if(RUNTIME_CHECK STREQUAL "memcheck") + assert_has_valgrind() + message(STATUS "Runtime memory checker: valgrind memcheck") + set(TEST_EXE_PREFIX "${VALGRIND_EXECUTABLE} --tool=memcheck --leak-check=full ${VALGRIND_COMMON_ARGS}") + # FIXME aconway 2018-09-06: NO TEST_WRAP_PREFIX, need --trace-children + many suppressions + +elseif(RUNTIME_CHECK STREQUAL "helgrind") + assert_has_valgrind() + message(STATUS "Runtime race checker: valgrind helgrind") + set(TEST_EXE_PREFIX "${VALGRIND_EXECUTABLE} --tool=helgrind ${VALGRIND_COMMON_ARGS}") + # FIXME aconway 2018-09-06: NO TEST_WRAP_PREFIX, need --trace-children + many suppressions + +elseif(RUNTIME_CHECK STREQUAL "asan") + assert_has_sanitizers() + message(STATUS "Runtime memory checker: gcc/clang memory sanitizers") + set(SANITIZE_FLAGS "-g -fno-omit-frame-pointer -fsanitize=address,undefined") + set(TEST_WRAP_PREFIX "${CMAKE_SOURCE_DIR}/tests/preload_asan.sh $<TARGET_FILE:qpid-proton-core>") + +elseif(RUNTIME_CHECK STREQUAL "tsan") + assert_has_sanitizers() + message(STATUS "Runtime race checker: gcc/clang thread sanitizer") + set(SANITIZE_FLAGS "-g -fno-omit-frame-pointer -fsanitize=thread") + +elseif(RUNTIME_CHECK) + message(FATAL_ERROR "'RUNTIME_CHECK=${RUNTIME_CHECK}' is invalid, valid values: ${runtime_checks}") +endif() + +if(SANITIZE_FLAGS) + set(ENABLE_UNDEFINED_ERROR OFF CACHE BOOL "Disabled for sanitizers" FORCE) + string(APPEND CMAKE_C_FLAGS " ${SANITIZE_FLAGS}") + string(APPEND CMAKE_CXX_FLAGS "${SANITIZE_FLAGS}") +endif() + +if(TEST_EXE_PREFIX) + # Add TEST_EXE_PREFIX to TEST_ENV so test runner scripts can use it. + list(APPEND TEST_ENV "TEST_EXE_PREFIX=${TEST_EXE_PREFIX}") + # Make a CMake-list form of TEST_EXE_PREFIX for add_test() commands + separate_arguments(TEST_EXE_PREFIX_CMD UNIX_COMMAND "${TEST_EXE_PREFIX}") +endif() +separate_arguments(TEST_WRAP_PREFIX_CMD UNIX_COMMAND "${TEST_WRAP_PREFIX}") http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/tests/share/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/tests/share/CMakeLists.txt b/tests/share/CMakeLists.txt new file mode 100644 index 0000000..a50c0e9 --- /dev/null +++ b/tests/share/CMakeLists.txt @@ -0,0 +1,42 @@ +# +# 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. +# + +cmake_minimum_required(VERSION 2.8.12) + +project(ProtonExamples) +include(CTest) +enable_testing() +include("tests/runtime_check.cmake") + +# ind example sub-directories that contain "CMakeLists.txt" or "testme" +set(ex_dir "${CMAKE_SOURCE_DIR}/examples") +file(GLOB subs ${ex_dir}/*) +foreach(dir ${subs}) + get_filename_component(ex "${dir}" NAME) + if(EXISTS ${dir}/CMakeLists.txt) + # Has CMakeLists.txt to define example tests. + add_subdirectory(${dir}) + elseif(EXISTS ${dir}/testme) + # Has a "testme" script to run example tests. + add_test( + NAME ${ex}-example-tests + COMMAND ${dir}/testme + WORKING_DIRECTORY ${dir}) + endif() + endforeach() http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/tests/share/README.txt ---------------------------------------------------------------------- diff --git a/tests/share/README.txt b/tests/share/README.txt new file mode 100644 index 0000000..f7864b6 --- /dev/null +++ b/tests/share/README.txt @@ -0,0 +1,3 @@ +This directory is for files that should be installed at the top level +of the INSTALL_PREFIX/share/proton-VERSION directory to support +installed testing. http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/393f8a67/tests/share/examples-README.md ---------------------------------------------------------------------- diff --git a/tests/share/examples-README.md b/tests/share/examples-README.md new file mode 100644 index 0000000..6f7404c --- /dev/null +++ b/tests/share/examples-README.md @@ -0,0 +1,20 @@ +Verifying the examples +====================== + +If you have installed support for self-testing a proton installation you can +automatically run and verify the examples. + +To build C, C++ tests and run all tests: + + cd TEMP-BUILD-DIR + cmake INSTALL-PREFIX/share/proton-VERSION/examples + make + ctest + +To run an individual test that does not require CMake, (e.g. ruby): + + cd INSTALL-PREFIX/share/proton-VERSION/examples/ruby + ./testme + +Some testme scripts accept additional arguments (e.g. -v for verbose) + --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org