add osmo_gettimeofday as a shim around gettimeofday

This allows feeding a custom time for unit tests by overriding
osmo_gettimeofday.

Change-Id: Ic7a81a6eb51f27fe452962b91f2eae2070d87089
This commit is contained in:
Neels Hofmeyr 2016-09-22 03:58:13 +02:00
parent 13a8fb84f0
commit 8e2f7e87f4
10 changed files with 87 additions and 17 deletions

View File

@ -29,6 +29,7 @@
#pragma once
#include <sys/time.h>
#include <stdbool.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/linuxrbtree.h>
@ -83,4 +84,14 @@ void osmo_timers_prepare(void);
int osmo_timers_update(void);
int osmo_timers_check(void);
int osmo_gettimeofday(struct timeval *tv, struct timezone *tz);
/**
* timer override
*/
extern bool osmo_gettimeofday_override;
extern struct timeval osmo_gettimeofday_override_time;
void osmo_gettimeofday_override_add(time_t secs, suseconds_t usecs);
/*! @} */

View File

@ -8,7 +8,7 @@ AM_CFLAGS = -Wall $(TALLOC_CFLAGS)
lib_LTLIBRARIES = libosmocore.la
libosmocore_la_LIBADD = $(BACKTRACE_LIB) $(TALLOC_LIBS)
libosmocore_la_SOURCES = timer.c select.c signal.c msgb.c bits.c \
libosmocore_la_SOURCES = timer.c timer_gettimeofday.c select.c signal.c msgb.c bits.c \
bitvec.c bitcomp.c statistics.c fsm.c \
write_queue.c utils.c socket.c \
logging.c logging_syslog.c rate_ctr.c \

View File

@ -603,7 +603,7 @@ static void fc_timer_cb(void *data)
fc->queue_depth--;
/* record the time we transmitted this PDU */
gettimeofday(&time_now, NULL);
osmo_gettimeofday(&time_now, NULL);
fc->time_last_pdu = time_now;
/* call the output callback for this FC instance */
@ -688,7 +688,7 @@ static int bssgp_fc_needs_queueing(struct bssgp_flow_control *fc, uint32_t pdu_l
/* compute number of centi-seconds that have elapsed since transmitting
* the last PDU (Tc - Tp) */
gettimeofday(&time_now, NULL);
osmo_gettimeofday(&time_now, NULL);
timersub(&time_now, &fc->time_last_pdu, &time_diff);
csecs_elapsed = time_diff.tv_sec*100 + time_diff.tv_usec/10000;
@ -747,7 +747,7 @@ int bssgp_fc_in(struct bssgp_flow_control *fc, struct msgb *msg,
return fc_enqueue(fc, msg, llc_pdu_len, priv);
} else {
/* record the time we transmitted this PDU */
gettimeofday(&time_now, NULL);
osmo_gettimeofday(&time_now, NULL);
fc->time_last_pdu = time_now;
return fc->out_cb(priv, msg, llc_pdu_len, NULL);
}
@ -766,7 +766,7 @@ void bssgp_fc_init(struct bssgp_flow_control *fc,
fc->bucket_leak_rate = bucket_leak_rate;
fc->max_queue_depth = max_queue_depth;
INIT_LLIST_HEAD(&fc->queue);
gettimeofday(&fc->time_last_pdu, NULL);
osmo_gettimeofday(&fc->time_last_pdu, NULL);
}
/* Initialize the Flow Control parameters for a new MS according to

View File

@ -556,7 +556,7 @@ static void nsvc_start_timer(struct gprs_nsvc *nsvc, enum nsvc_timer_mode mode)
if (osmo_timer_pending(&nsvc->timer))
osmo_timer_del(&nsvc->timer);
gettimeofday(&nsvc->timer_started, NULL);
osmo_gettimeofday(&nsvc->timer_started, NULL);
nsvc->timer_mode = mode;
osmo_timer_schedule(&nsvc->timer, seconds, 0);
}
@ -564,7 +564,7 @@ static void nsvc_start_timer(struct gprs_nsvc *nsvc, enum nsvc_timer_mode mode)
static int nsvc_timer_elapsed_ms(struct gprs_nsvc *nsvc)
{
struct timeval now, elapsed;
gettimeofday(&now, NULL);
osmo_gettimeofday(&now, NULL);
timersub(&now, &nsvc->timer_started, &elapsed);
return 1000 * elapsed.tv_sec + elapsed.tv_usec / 1000;

View File

@ -44,6 +44,7 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/timer.h>
#include <osmocom/vty/logging.h> /* for LOGGING_STR. */
@ -268,7 +269,7 @@ static void _output(struct log_target *target, unsigned int subsys,
if (target->print_ext_timestamp) {
struct tm tm;
struct timeval tv;
gettimeofday(&tv, NULL);
osmo_gettimeofday(&tv, NULL);
localtime_r(&tv.tv_sec, &tm);
ret = snprintf(buf + offset, rem, "%04d%02d%02d%02d%02d%02d%03d ",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,

View File

@ -91,7 +91,7 @@ osmo_timer_schedule(struct osmo_timer_list *timer, int seconds, int microseconds
{
struct timeval current_time;
gettimeofday(&current_time, NULL);
osmo_gettimeofday(&current_time, NULL);
timer->timeout.tv_sec = seconds;
timer->timeout.tv_usec = microseconds;
timeradd(&timer->timeout, &current_time, &timer->timeout);
@ -143,7 +143,7 @@ int osmo_timer_remaining(const struct osmo_timer_list *timer,
struct timeval current_time;
if (!now)
gettimeofday(&current_time, NULL);
osmo_gettimeofday(&current_time, NULL);
else
current_time = *now;
@ -193,7 +193,7 @@ void osmo_timers_prepare(void)
struct rb_node *node;
struct timeval current;
gettimeofday(&current, NULL);
osmo_gettimeofday(&current, NULL);
node = rb_first(&timer_root);
if (node) {
@ -214,7 +214,7 @@ int osmo_timers_update(void)
struct osmo_timer_list *this;
int work = 0;
gettimeofday(&current_time, NULL);
osmo_gettimeofday(&current_time, NULL);
INIT_LLIST_HEAD(&timer_eviction_list);
for (node = rb_first(&timer_root); node; node = rb_next(node)) {

58
src/timer_gettimeofday.c Normal file
View File

@ -0,0 +1,58 @@
/*
* (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
* All Rights Reserved
*
* Authors: Neels Hofmeyr <nhofmeyr@sysmocom.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
/*! \addtogroup timer
* @{
*/
/*! \file timer_gettimeofday.c
*/
#include <stdbool.h>
#include <sys/time.h>
bool osmo_gettimeofday_override = false;
struct timeval osmo_gettimeofday_override_time = { 23, 424242 };
/*! \brief shim around gettimeofday to be able to set the time manually.
* To override, set osmo_gettimeofday_override == true and set the desired
* current time in osmo_gettimeofday_override_time. */
int osmo_gettimeofday(struct timeval *tv, struct timezone *tz)
{
if (osmo_gettimeofday_override) {
*tv = osmo_gettimeofday_override_time;
return 0;
}
return gettimeofday(tv, tz);
}
/*! \brief convenience function to advance the fake time.
* Add the given values to osmo_gettimeofday_override_time. */
void osmo_gettimeofday_override_add(time_t secs, suseconds_t usecs)
{
struct timeval val = { secs, usecs };
timeradd(&osmo_gettimeofday_override_time, &val,
&osmo_gettimeofday_override_time);
}
/*! @} */

View File

@ -637,7 +637,7 @@ static char *zencrypt(const char *passwd)
struct timeval tv;
char *crypt(const char *, const char *);
gettimeofday(&tv, 0);
osmo_gettimeofday(&tv, 0);
to64(&salt[0], random(), 3);
to64(&salt[3], tv.tv_usec, 3);

View File

@ -22,7 +22,7 @@ int get_centisec_diff(void)
{
struct timeval tv;
struct timeval now;
gettimeofday(&now, NULL);
osmo_gettimeofday(&now, NULL);
timersub(&now, &tv_start, &tv);
@ -73,7 +73,7 @@ static void test_fc(uint32_t bucket_size_max, uint32_t bucket_leak_rate,
bssgp_fc_init(fc, bucket_size_max, bucket_leak_rate, max_queue_depth,
fc_out_cb);
gettimeofday(&tv_start, NULL);
osmo_gettimeofday(&tv_start, NULL);
for (i = 0; i < pdu_count; i++) {
fc_in(fc, pdu_len);

View File

@ -87,7 +87,7 @@ static void main_timer_fired(void *data)
fprintf(stderr, "timer_test: OOM!\n");
return;
}
gettimeofday(&v->start, NULL);
osmo_gettimeofday(&v->start, NULL);
v->timer.cb = secondary_timer_fired;
v->timer.data = v;
unsigned int seconds = (random() % 10) + 1;
@ -108,7 +108,7 @@ static void secondary_timer_fired(void *data)
struct test_timer *v = data, *this, *tmp;
struct timeval current, res, precision = { 1, 0 };
gettimeofday(&current, NULL);
osmo_gettimeofday(&current, NULL);
timersub(&current, &v->stop, &res);
if (timercmp(&res, &precision, >)) {