2015-12-18 12:12:18 +02:00
|
|
|
/*
|
2016-01-28 15:07:31 +01:00
|
|
|
Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
|
2015-12-18 12:12:18 +02:00
|
|
|
|
|
|
|
This file is part of libzmq, the ZeroMQ core engine in C++.
|
|
|
|
|
|
|
|
libzmq is free software; you can redistribute it and/or modify it under
|
|
|
|
the terms of the GNU Lesser General Public License (LGPL) as published
|
|
|
|
by the Free Software Foundation; either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
As a special exception, the Contributors give you permission to link
|
|
|
|
this library with independent modules to produce an executable,
|
|
|
|
regardless of the license terms of these independent modules, and to
|
|
|
|
copy and distribute the resulting executable under terms of your choice,
|
|
|
|
provided that you also meet, for each linked independent module, the
|
|
|
|
terms and conditions of the license of that module. An independent
|
|
|
|
module is a module which is not derived from or based on this library.
|
|
|
|
If you modify this library, you must extend this exception to your
|
|
|
|
version of the library.
|
|
|
|
|
|
|
|
libzmq is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
|
|
License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2017-10-17 13:36:34 +01:00
|
|
|
#define __STDC_LIMIT_MACROS // to define SIZE_MAX with older compilers
|
2016-02-06 14:11:21 +01:00
|
|
|
#include "testutil.hpp"
|
2018-08-23 16:55:17 +02:00
|
|
|
#include "testutil_unity.hpp"
|
|
|
|
|
|
|
|
void setUp ()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void tearDown ()
|
|
|
|
{
|
|
|
|
}
|
2015-12-18 12:12:18 +02:00
|
|
|
|
2018-05-27 07:01:36 -04:00
|
|
|
void handler (int timer_id_, void *arg_)
|
2015-12-18 12:12:18 +02:00
|
|
|
{
|
2018-05-27 07:01:36 -04:00
|
|
|
(void) timer_id_; // Stop 'unused' compiler warnings
|
2019-12-08 14:26:57 +01:00
|
|
|
*(static_cast<bool *> (arg_)) = true;
|
2015-12-18 12:12:18 +02:00
|
|
|
}
|
|
|
|
|
2018-02-01 11:46:09 +01:00
|
|
|
int sleep_and_execute (void *timers_)
|
2016-05-05 14:17:35 +03:00
|
|
|
{
|
|
|
|
int timeout = zmq_timers_timeout (timers_);
|
|
|
|
|
|
|
|
// Sleep methods are inaccurate, so we sleep in a loop until time arrived
|
|
|
|
while (timeout > 0) {
|
2017-08-23 09:05:10 +02:00
|
|
|
msleep (timeout);
|
2018-02-01 11:46:09 +01:00
|
|
|
timeout = zmq_timers_timeout (timers_);
|
2016-05-05 14:17:35 +03:00
|
|
|
}
|
|
|
|
|
2018-02-01 11:46:09 +01:00
|
|
|
return zmq_timers_execute (timers_);
|
2016-05-05 14:17:35 +03:00
|
|
|
}
|
|
|
|
|
2017-08-23 09:13:07 +02:00
|
|
|
void test_null_timer_pointers ()
|
|
|
|
{
|
|
|
|
void *timers = NULL;
|
|
|
|
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FAILURE_ERRNO (EFAULT, zmq_timers_destroy (&timers));
|
2017-08-23 09:13:07 +02:00
|
|
|
|
|
|
|
// TODO this currently triggers an access violation
|
|
|
|
#if 0
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FAILURE_ERRNO(EFAULT, zmq_timers_destroy (NULL));
|
2017-08-23 09:13:07 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
const size_t dummy_interval = 100;
|
|
|
|
const int dummy_timer_id = 1;
|
|
|
|
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FAILURE_ERRNO (
|
|
|
|
EFAULT, zmq_timers_add (timers, dummy_interval, &handler, NULL));
|
|
|
|
TEST_ASSERT_FAILURE_ERRNO (
|
|
|
|
EFAULT, zmq_timers_add (&timers, dummy_interval, &handler, NULL));
|
2017-08-23 09:13:07 +02:00
|
|
|
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FAILURE_ERRNO (EFAULT,
|
|
|
|
zmq_timers_cancel (timers, dummy_timer_id));
|
|
|
|
TEST_ASSERT_FAILURE_ERRNO (EFAULT,
|
|
|
|
zmq_timers_cancel (&timers, dummy_timer_id));
|
2017-08-23 09:13:07 +02:00
|
|
|
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FAILURE_ERRNO (
|
|
|
|
EFAULT, zmq_timers_set_interval (timers, dummy_timer_id, dummy_interval));
|
|
|
|
TEST_ASSERT_FAILURE_ERRNO (
|
|
|
|
EFAULT,
|
|
|
|
zmq_timers_set_interval (&timers, dummy_timer_id, dummy_interval));
|
2017-08-23 09:13:07 +02:00
|
|
|
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FAILURE_ERRNO (EFAULT,
|
|
|
|
zmq_timers_reset (timers, dummy_timer_id));
|
|
|
|
TEST_ASSERT_FAILURE_ERRNO (EFAULT,
|
|
|
|
zmq_timers_reset (&timers, dummy_timer_id));
|
2017-08-23 09:13:07 +02:00
|
|
|
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FAILURE_ERRNO (EFAULT, zmq_timers_timeout (timers));
|
|
|
|
TEST_ASSERT_FAILURE_ERRNO (EFAULT, zmq_timers_timeout (&timers));
|
2017-08-23 09:13:07 +02:00
|
|
|
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FAILURE_ERRNO (EFAULT, zmq_timers_execute (timers));
|
|
|
|
TEST_ASSERT_FAILURE_ERRNO (EFAULT, zmq_timers_execute (&timers));
|
2017-08-23 09:13:07 +02:00
|
|
|
}
|
|
|
|
|
2017-08-23 09:39:51 +02:00
|
|
|
void test_corner_cases ()
|
|
|
|
{
|
|
|
|
void *timers = zmq_timers_new ();
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_NOT_NULL (timers);
|
2017-08-23 09:39:51 +02:00
|
|
|
|
|
|
|
const size_t dummy_interval = SIZE_MAX;
|
|
|
|
const int dummy_timer_id = 1;
|
|
|
|
|
|
|
|
// attempt to cancel non-existent timer
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FAILURE_ERRNO (EINVAL,
|
|
|
|
zmq_timers_cancel (timers, dummy_timer_id));
|
2017-08-23 09:39:51 +02:00
|
|
|
|
|
|
|
// attempt to set interval of non-existent timer
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FAILURE_ERRNO (
|
|
|
|
EINVAL, zmq_timers_set_interval (timers, dummy_timer_id, dummy_interval));
|
2017-08-23 09:39:51 +02:00
|
|
|
|
|
|
|
// attempt to reset non-existent timer
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FAILURE_ERRNO (EINVAL,
|
|
|
|
zmq_timers_reset (timers, dummy_timer_id));
|
2017-08-23 09:39:51 +02:00
|
|
|
|
|
|
|
// attempt to add NULL handler
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FAILURE_ERRNO (
|
|
|
|
EFAULT, zmq_timers_add (timers, dummy_interval, NULL, NULL));
|
2017-08-23 09:39:51 +02:00
|
|
|
|
2018-08-23 16:55:17 +02:00
|
|
|
const int timer_id = TEST_ASSERT_SUCCESS_ERRNO (
|
|
|
|
zmq_timers_add (timers, dummy_interval, handler, NULL));
|
2017-08-23 09:39:51 +02:00
|
|
|
|
|
|
|
// attempt to cancel timer twice
|
|
|
|
// TODO should this case really be an error? canceling twice could be allowed
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_SUCCESS_ERRNO (zmq_timers_cancel (timers, timer_id));
|
2017-08-23 09:39:51 +02:00
|
|
|
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FAILURE_ERRNO (EINVAL, zmq_timers_cancel (timers, timer_id));
|
2017-08-23 09:39:51 +02:00
|
|
|
|
2017-08-23 10:31:44 +02:00
|
|
|
// timeout without any timers active
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FAILURE_ERRNO (EINVAL, zmq_timers_timeout (timers));
|
2017-08-23 10:31:44 +02:00
|
|
|
|
2018-08-23 16:55:17 +02:00
|
|
|
// cleanup
|
|
|
|
TEST_ASSERT_SUCCESS_ERRNO (zmq_timers_destroy (&timers));
|
2017-08-23 09:39:51 +02:00
|
|
|
}
|
|
|
|
|
2018-08-23 16:55:17 +02:00
|
|
|
void test_timers ()
|
2015-12-18 12:12:18 +02:00
|
|
|
{
|
2018-02-01 11:46:09 +01:00
|
|
|
void *timers = zmq_timers_new ();
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_NOT_NULL (timers);
|
2015-12-18 12:12:18 +02:00
|
|
|
|
|
|
|
bool timer_invoked = false;
|
|
|
|
|
2018-02-10 17:08:01 +00:00
|
|
|
const unsigned long full_timeout = 100;
|
2018-02-03 12:31:39 +01:00
|
|
|
void *const stopwatch = zmq_stopwatch_start ();
|
|
|
|
|
2018-08-23 16:55:17 +02:00
|
|
|
const int timer_id = TEST_ASSERT_SUCCESS_ERRNO (
|
|
|
|
zmq_timers_add (timers, full_timeout, handler, &timer_invoked));
|
2015-12-18 12:12:18 +02:00
|
|
|
|
2018-02-03 12:31:39 +01:00
|
|
|
// Timer should not have been invoked yet
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_SUCCESS_ERRNO (zmq_timers_execute (timers));
|
2018-02-03 12:31:39 +01:00
|
|
|
|
|
|
|
if (zmq_stopwatch_intermediate (stopwatch) < full_timeout) {
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FALSE (timer_invoked);
|
2018-02-03 12:31:39 +01:00
|
|
|
}
|
2015-12-18 12:12:18 +02:00
|
|
|
|
|
|
|
// Wait half the time and check again
|
2018-08-23 16:55:17 +02:00
|
|
|
long timeout = TEST_ASSERT_SUCCESS_ERRNO (zmq_timers_timeout (timers));
|
2017-08-23 09:39:51 +02:00
|
|
|
msleep (timeout / 2);
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_SUCCESS_ERRNO (zmq_timers_execute (timers));
|
2018-02-03 12:31:39 +01:00
|
|
|
if (zmq_stopwatch_intermediate (stopwatch) < full_timeout) {
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FALSE (timer_invoked);
|
2018-02-03 12:31:39 +01:00
|
|
|
}
|
2015-12-18 12:12:18 +02:00
|
|
|
|
2018-02-01 11:46:09 +01:00
|
|
|
// Wait until the end
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_SUCCESS_ERRNO (sleep_and_execute (timers));
|
|
|
|
TEST_ASSERT_TRUE (timer_invoked);
|
2015-12-18 12:12:18 +02:00
|
|
|
timer_invoked = false;
|
|
|
|
|
|
|
|
// Wait half the time and check again
|
2018-08-23 16:55:17 +02:00
|
|
|
timeout = TEST_ASSERT_SUCCESS_ERRNO (zmq_timers_timeout (timers));
|
2017-08-23 09:05:10 +02:00
|
|
|
msleep (timeout / 2);
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_SUCCESS_ERRNO (zmq_timers_execute (timers));
|
2018-02-03 12:31:39 +01:00
|
|
|
if (zmq_stopwatch_intermediate (stopwatch) < 2 * full_timeout) {
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FALSE (timer_invoked);
|
2018-02-03 12:31:39 +01:00
|
|
|
}
|
2015-12-18 12:12:18 +02:00
|
|
|
|
|
|
|
// Reset timer and wait half of the time left
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_SUCCESS_ERRNO (zmq_timers_reset (timers, timer_id));
|
2017-08-23 09:05:10 +02:00
|
|
|
msleep (timeout / 2);
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_SUCCESS_ERRNO (zmq_timers_execute (timers));
|
2018-02-03 12:31:39 +01:00
|
|
|
if (zmq_stopwatch_stop (stopwatch) < 2 * full_timeout) {
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_FALSE (timer_invoked);
|
2018-02-03 12:31:39 +01:00
|
|
|
}
|
2015-12-18 12:12:18 +02:00
|
|
|
|
|
|
|
// Wait until the end
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_SUCCESS_ERRNO (sleep_and_execute (timers));
|
|
|
|
TEST_ASSERT_TRUE (timer_invoked);
|
2015-12-18 12:12:18 +02:00
|
|
|
timer_invoked = false;
|
|
|
|
|
|
|
|
// reschedule
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_SUCCESS_ERRNO (zmq_timers_set_interval (timers, timer_id, 50));
|
|
|
|
TEST_ASSERT_SUCCESS_ERRNO (sleep_and_execute (timers));
|
|
|
|
TEST_ASSERT_TRUE (timer_invoked);
|
2015-12-18 12:12:18 +02:00
|
|
|
timer_invoked = false;
|
|
|
|
|
|
|
|
// cancel timer
|
2018-08-23 16:55:17 +02:00
|
|
|
timeout = TEST_ASSERT_SUCCESS_ERRNO (zmq_timers_timeout (timers));
|
|
|
|
TEST_ASSERT_SUCCESS_ERRNO (zmq_timers_cancel (timers, timer_id));
|
2017-08-23 09:05:10 +02:00
|
|
|
msleep (timeout * 2);
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_SUCCESS_ERRNO (zmq_timers_execute (timers));
|
|
|
|
TEST_ASSERT_FALSE (timer_invoked);
|
2015-12-18 12:12:18 +02:00
|
|
|
|
2018-08-23 16:55:17 +02:00
|
|
|
TEST_ASSERT_SUCCESS_ERRNO (zmq_timers_destroy (&timers));
|
|
|
|
}
|
2015-12-18 12:12:18 +02:00
|
|
|
|
2018-08-23 16:55:17 +02:00
|
|
|
int main ()
|
|
|
|
{
|
|
|
|
setup_test_environment ();
|
2017-08-23 09:13:07 +02:00
|
|
|
|
2018-08-23 16:55:17 +02:00
|
|
|
UNITY_BEGIN ();
|
|
|
|
RUN_TEST (test_timers);
|
|
|
|
RUN_TEST (test_null_timer_pointers);
|
|
|
|
RUN_TEST (test_corner_cases);
|
|
|
|
return UNITY_END ();
|
2015-12-18 12:12:18 +02:00
|
|
|
}
|