Repository: celix Updated Branches: refs/heads/develop 800fd35f0 -> 2cad0de88
CELIX-389: Adds pubsubmock library for testing component with a publisher dependency. Improve const correctness for the pubsub publisher api Project: http://git-wip-us.apache.org/repos/asf/celix/repo Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/2cad0de8 Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/2cad0de8 Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/2cad0de8 Branch: refs/heads/develop Commit: 2cad0de8832da65b13de89263bf98a225f6ffb1d Parents: 800fd35 Author: Pepijn Noltes <pepijnnol...@gmail.com> Authored: Tue Mar 28 21:03:57 2017 +0200 Committer: Pepijn Noltes <pepijnnol...@gmail.com> Committed: Tue Mar 28 21:03:57 2017 +0200 ---------------------------------------------------------------------- pubsub/CMakeLists.txt | 4 + pubsub/api/pubsub/publisher.h | 4 +- pubsub/mock/CMakeLists.txt | 44 +++++++++++ pubsub/mock/api/pubsub/publisher_mock.h | 43 +++++++++++ pubsub/mock/src/publisher_mock.cc | 68 +++++++++++++++++ pubsub/mock/tst/pubsubmock_test.cc | 77 ++++++++++++++++++++ pubsub/mock/tst/run_tests.cc | 25 +++++++ .../private/src/topic_publication.c | 4 +- .../private/src/topic_publication.c | 8 +- 9 files changed, 269 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/celix/blob/2cad0de8/pubsub/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/pubsub/CMakeLists.txt b/pubsub/CMakeLists.txt index 6b33a57..2b87af0 100644 --- a/pubsub/CMakeLists.txt +++ b/pubsub/CMakeLists.txt @@ -48,5 +48,9 @@ if (PUBSUB) add_subdirectory(examples) add_subdirectory(deploy) add_subdirectory(keygen) + add_subdirectory(mock) + + #install api + install(FILES api/pubsub/publisher.h api/pubsub/subscriber.h DESTINATION include/celix/pubsub COMPONENT framework) endif(PUBSUB) http://git-wip-us.apache.org/repos/asf/celix/blob/2cad0de8/pubsub/api/pubsub/publisher.h ---------------------------------------------------------------------- diff --git a/pubsub/api/pubsub/publisher.h b/pubsub/api/pubsub/publisher.h index 58ac589..4bc6c8c 100644 --- a/pubsub/api/pubsub/publisher.h +++ b/pubsub/api/pubsub/publisher.h @@ -70,7 +70,7 @@ struct pubsub_publisher { * send is a async function, but the msg can be safely deleted after send returns. * Returns 0 on success. */ - int (*send)(void *handle, unsigned int msgTypeId, void *msg); + int (*send)(void *handle, unsigned int msgTypeId, const void *msg); /** @@ -79,7 +79,7 @@ struct pubsub_publisher { * The last message of a multipart message must have the flag PUBLISHER_LAST_MSG * Returns 0 on success. */ - int (*sendMultipart)(void *handle, unsigned int msgTypeId, void *msg, int flags); + int (*sendMultipart)(void *handle, unsigned int msgTypeId, const void *msg, int flags); }; typedef struct pubsub_publisher pubsub_publisher_t; http://git-wip-us.apache.org/repos/asf/celix/blob/2cad0de8/pubsub/mock/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/pubsub/mock/CMakeLists.txt b/pubsub/mock/CMakeLists.txt new file mode 100644 index 0000000..09d7b2a --- /dev/null +++ b/pubsub/mock/CMakeLists.txt @@ -0,0 +1,44 @@ +# 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. + +#only install if CppuTest is available +find_package(CppUTest QUIET) +if (CPPUTEST_FOUND) + include_directories( + ../api + api + ${CPPUTEST_INCLUDE_DIR} + ) + + add_library(celix_pubsubmock STATIC + src/publisher_mock.cc + ) + target_link_libraries(celix_pubsubmock ${CPPUTEST_LIBRARY}) + + install(TARGETS celix_pubsubmock DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT framework) + install(FILES api/pubsub/publisher_mock.h DESTINATION include/celix/pubsub COMPONENT framework) + + if (ENABLE_TESTING) + add_executable(pubsubmock_test + tst/pubsubmock_test.cc + tst/run_tests.cc + ) + target_link_libraries(pubsubmock_test celix_pubsubmock ${CPPUTEST_LIBRARY} ${CPPUTEST_EXT_LIBRARY}) + add_test(NAME pubsubmock_test COMMAND pubsubmock_test) + endif() +endif() + http://git-wip-us.apache.org/repos/asf/celix/blob/2cad0de8/pubsub/mock/api/pubsub/publisher_mock.h ---------------------------------------------------------------------- diff --git a/pubsub/mock/api/pubsub/publisher_mock.h b/pubsub/mock/api/pubsub/publisher_mock.h new file mode 100644 index 0000000..45c69db --- /dev/null +++ b/pubsub/mock/api/pubsub/publisher_mock.h @@ -0,0 +1,43 @@ +/** + *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. + */ +#ifndef PUBSUB_PUBLISHER_MOCK_H_ +#define PUBSUB_PUBLISHER_MOCK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "pubsub/publisher.h" + +#define PUBSUB_PUBLISHERMOCK_SCOPE "pubsub_publisher" +#define PUBSUB_PUBLISHERMOCK_LOCAL_MSG_TYPE_ID_FOR_MSG_TYPE_METHOD "pubsub__publisherMock_localMsgTypeIdForMsgType" +#define PUBSUB_PUBLISHERMOCK_SEND_METHOD "pubsub__publisherMock_send" +#define PUBSUB_PUBLISHERMOCK_SEND_MULTIPART_METHOD "pubsub__publisherMock_sendMultipart" + + +/*============================================================================ + MOCK - intialize publisher mock + ============================================================================*/ +void pubsub_publisherMock_init(pubsub_publisher_t* srv, void* handle); + +#ifdef __cplusplus +} +#endif + +#endif //PUBSUB_PUBLISHER_MOCK_H_ http://git-wip-us.apache.org/repos/asf/celix/blob/2cad0de8/pubsub/mock/src/publisher_mock.cc ---------------------------------------------------------------------- diff --git a/pubsub/mock/src/publisher_mock.cc b/pubsub/mock/src/publisher_mock.cc new file mode 100644 index 0000000..e8902a8 --- /dev/null +++ b/pubsub/mock/src/publisher_mock.cc @@ -0,0 +1,68 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +#include "pubsub/publisher_mock.h" +#include "CppUTest/TestHarness.h" +#include "CppUTestExt/MockSupport.h" + +/*============================================================================ + MOCK - mock function for pubsub_publisher->localMsgTypeIdForMsgType + ============================================================================*/ +static int pubsub__publisherMock_localMsgTypeIdForMsgType(void *handle, const char *msgType, unsigned int *msgTypeId) { + return mock(PUBSUB_PUBLISHERMOCK_SCOPE) + .actualCall(PUBSUB_PUBLISHERMOCK_LOCAL_MSG_TYPE_ID_FOR_MSG_TYPE_METHOD) + .withPointerParameter("handle", handle) + .withParameter("msgType", msgType) + .withOutputParameter("msgTypeId", msgTypeId) + .returnIntValue(); +} + +/*============================================================================ + MOCK - mock function for pubsub_publisher->send + ============================================================================*/ +static int pubsub__publisherMock_send(void *handle, unsigned int msgTypeId, const void *msg) { + return mock(PUBSUB_PUBLISHERMOCK_SCOPE) + .actualCall(PUBSUB_PUBLISHERMOCK_SEND_METHOD) + .withPointerParameter("handle", handle) + .withParameter("msgTypeId", msgTypeId) + .withPointerParameter("msg", (void*)msg) + .returnIntValue(); +} + +/*============================================================================ + MOCK - mock function for pubsub_publisher->sendMultipart + ============================================================================*/ +static int pubsub__publisherMock_sendMultipart(void *handle, unsigned int msgTypeId, const void *msg, int flags) { + return mock(PUBSUB_PUBLISHERMOCK_SCOPE) + .actualCall(PUBSUB_PUBLISHERMOCK_SEND_MULTIPART_METHOD) + .withPointerParameter("handle", handle) + .withParameter("msgTypeId", msgTypeId) + .withPointerParameter("msg", (void*)msg) + .withParameter("flags", flags) + .returnIntValue(); +} + +/*============================================================================ + MOCK - mock setup for publisher service + ============================================================================*/ +void pubsub_publisherMock_init(pubsub_publisher_t* srv, void* handle) { + srv->handle = handle; + srv->localMsgTypeIdForMsgType = pubsub__publisherMock_localMsgTypeIdForMsgType; + srv->send = pubsub__publisherMock_send; + srv->sendMultipart = pubsub__publisherMock_sendMultipart; +} http://git-wip-us.apache.org/repos/asf/celix/blob/2cad0de8/pubsub/mock/tst/pubsubmock_test.cc ---------------------------------------------------------------------- diff --git a/pubsub/mock/tst/pubsubmock_test.cc b/pubsub/mock/tst/pubsubmock_test.cc new file mode 100644 index 0000000..16f2058 --- /dev/null +++ b/pubsub/mock/tst/pubsubmock_test.cc @@ -0,0 +1,77 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ + +#include <CppUTestExt/MockSupport.h> +#include <CppUTest/TestHarness.h> + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#include "pubsub/publisher_mock.h" + + +static pubsub_publisher_t mockSrv; +static void* mockHandle = (void*)0x42; + + +TEST_GROUP(pubsubmock) { + void setup(void) { + //setup mock + pubsub_publisherMock_init(&mockSrv, mockHandle); + } + + void teardown() { + mock().checkExpectations(); + mock().clear(); + } +}; + +TEST(pubsubmock, publishermock) { + const char* mockFqn = "example.Msg"; + unsigned int mockOutputTypeId = 11; + + mock(PUBSUB_PUBLISHERMOCK_SCOPE).expectOneCall(PUBSUB_PUBLISHERMOCK_LOCAL_MSG_TYPE_ID_FOR_MSG_TYPE_METHOD) + .withParameter("handle", mockHandle) + .withParameter("msgType", mockFqn) + .withOutputParameterReturning("msgTypeId", &mockOutputTypeId, sizeof(mockOutputTypeId)); + + mock(PUBSUB_PUBLISHERMOCK_SCOPE).expectOneCall(PUBSUB_PUBLISHERMOCK_SEND_METHOD) + .withParameter("handle", mockHandle) + .withParameter("msgTypeId", mockOutputTypeId) + .ignoreOtherParameters(); + + //This should normally be code which should be tested, for now it code to verify the mock + pubsub_publisher_t* srv = &mockSrv; + const char* msgFqn = "example.Msg"; + unsigned int msgId = 0; + + //get type id (normally only if type id is not yet set (e.g. 0)) + srv->localMsgTypeIdForMsgType(srv->handle, msgFqn, &msgId); + CHECK(msgId != 0); + + //set msg + void *dummyMsg = (void*)0x43; + srv->send(srv->handle, msgId, dummyMsg); //should satify the expectOneCalls + //srv->send(srv->handle, msgId, dummyMsg); //enabling this should fail the test + +} + http://git-wip-us.apache.org/repos/asf/celix/blob/2cad0de8/pubsub/mock/tst/run_tests.cc ---------------------------------------------------------------------- diff --git a/pubsub/mock/tst/run_tests.cc b/pubsub/mock/tst/run_tests.cc new file mode 100644 index 0000000..7f93791 --- /dev/null +++ b/pubsub/mock/tst/run_tests.cc @@ -0,0 +1,25 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ + +#include <CppUTest/TestHarness.h> +#include "CppUTest/CommandLineTestRunner.h" + +int main(int argc, char** argv) { + return RUN_ALL_TESTS(argc, argv); +} http://git-wip-us.apache.org/repos/asf/celix/blob/2cad0de8/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c ---------------------------------------------------------------------- diff --git a/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c b/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c index ce70385..0c79479 100644 --- a/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c +++ b/pubsub/pubsub_admin_udp_mc/private/src/topic_publication.c @@ -91,7 +91,7 @@ static celix_status_t pubsub_topicPublicationUngetService(void* handle, bundle_p static publish_bundle_bound_service_pt pubsub_createPublishBundleBoundService(topic_publication_pt tp,bundle_pt bundle); static void pubsub_destroyPublishBundleBoundService(publish_bundle_bound_service_pt boundSvc); -static int pubsub_topicPublicationSend(void* handle,unsigned int msgTypeId, void *msg); +static int pubsub_topicPublicationSend(void* handle, unsigned int msgTypeId, const void *msg); static int pubsub_localMsgTypeIdForUUID(void* handle, const char* msgType, unsigned int* msgTypeId); @@ -317,7 +317,7 @@ static bool send_pubsub_msg(publish_bundle_bound_service_pt bound, pubsub_msg_pt } -static int pubsub_topicPublicationSend(void* handle, unsigned int msgTypeId, void *msg) { +static int pubsub_topicPublicationSend(void* handle, unsigned int msgTypeId, const void *msg) { int status = 0; publish_bundle_bound_service_pt bound = (publish_bundle_bound_service_pt) handle; http://git-wip-us.apache.org/repos/asf/celix/blob/2cad0de8/pubsub/pubsub_admin_zmq/private/src/topic_publication.c ---------------------------------------------------------------------- diff --git a/pubsub/pubsub_admin_zmq/private/src/topic_publication.c b/pubsub/pubsub_admin_zmq/private/src/topic_publication.c index 5f6dcb5..e445753 100644 --- a/pubsub/pubsub_admin_zmq/private/src/topic_publication.c +++ b/pubsub/pubsub_admin_zmq/private/src/topic_publication.c @@ -100,8 +100,8 @@ static celix_status_t pubsub_topicPublicationUngetService(void* handle, bundle_p static publish_bundle_bound_service_pt pubsub_createPublishBundleBoundService(topic_publication_pt tp,bundle_pt bundle); static void pubsub_destroyPublishBundleBoundService(publish_bundle_bound_service_pt boundSvc); -static int pubsub_topicPublicationSend(void* handle,unsigned int msgTypeId, void *msg); -static int pubsub_topicPublicationSendMultipart(void *handle, unsigned int msgTypeId, void *msg, int flags); +static int pubsub_topicPublicationSend(void* handle,unsigned int msgTypeId, const void *msg); +static int pubsub_topicPublicationSendMultipart(void *handle, unsigned int msgTypeId, const void *msg, int flags); static int pubsub_localMsgTypeIdForUUID(void* handle, const char* msgType, unsigned int* msgTypeId); static void delay_first_send_for_late_joiners(void); @@ -442,13 +442,13 @@ static bool send_pubsub_mp_msg(zsock_t* zmq_socket, array_list_pt mp_msg_parts){ } -static int pubsub_topicPublicationSend(void* handle, unsigned int msgTypeId, void *msg) { +static int pubsub_topicPublicationSend(void* handle, unsigned int msgTypeId, const void *msg) { return pubsub_topicPublicationSendMultipart(handle,msgTypeId,msg, PUBSUB_PUBLISHER_FIRST_MSG | PUBSUB_PUBLISHER_LAST_MSG); } -static int pubsub_topicPublicationSendMultipart(void *handle, unsigned int msgTypeId, void *msg, int flags){ +static int pubsub_topicPublicationSendMultipart(void *handle, unsigned int msgTypeId, const void *msg, int flags){ int status = 0;