From 4295210b2ce5fd8374dc66354965b8fc243ed649 Mon Sep 17 00:00:00 2001 From: Thierry Bordaz Date: Jul 25 2019 13:54:16 +0000 Subject: Ticket 50510 - etime can contain invalid nanosecond value Bug Description: When computing the etime, it takes into account the nanosecond. At border of a second, the ending nsec can be lower than starting nsec. In such case the computation is wrong as delta=(ending_nsec - starting_nsec) is negative. final_nsec = 1 - delta > 1sec Fix Description: if delta=(ending_nsec - starting_nsec) is negative final_nsec = 1 + delta < 1sec https://pagure.io/389-ds-base/issue/50510 Reviewed by: Mark Reynolds (Thanks!) Platforms tested: F28 Flag Day: no Doc impact: no --- diff --git a/dirsrvtests/tests/suites/ds_logs/ds_logs_test.py b/dirsrvtests/tests/suites/ds_logs/ds_logs_test.py index 07e8a97..bb45617 100644 --- a/dirsrvtests/tests/suites/ds_logs/ds_logs_test.py +++ b/dirsrvtests/tests/suites/ds_logs/ds_logs_test.py @@ -9,12 +9,13 @@ import os import logging import pytest +import subprocess from lib389.topologies import topology_st from lib389.plugins import AutoMembershipPlugin, ReferentialIntegrityPlugin, AutoMembershipDefinitions from lib389.idm.user import UserAccounts from lib389.idm.group import Groups from lib389.idm.organizationalunit import OrganizationalUnits -from lib389._constants import DEFAULT_SUFFIX, LOG_ACCESS_LEVEL +from lib389._constants import DEFAULT_SUFFIX, LOG_ACCESS_LEVEL, DN_CONFIG, HOST_STANDALONE, PORT_STANDALONE, DN_DM, PASSWORD from lib389.utils import ds_is_older import ldap @@ -664,7 +665,51 @@ def test_access_log_truncated_search_message(topology_st): log.info('Delete the previous access logs for the next test') topo.deleteAccessLogs() +@pytest.mark.bz1732053 +@pytest.mark.ds50510 +def test_etime_at_border_of_second(topology_st): + topo = topology_st.standalone + + # be sure to analyze only the following rapid OPs + topo.stop() + os.remove(topo.accesslog) + topo.start() + + prog = os.path.join(topo.ds_paths.bin_dir, 'rsearch') + + cmd = [prog] + + # base search + cmd.extend(['-s', DN_CONFIG]) + + # scope of the search + cmd.extend(['-S', '0']) + + # host / port + cmd.extend(['-h', HOST_STANDALONE]) + cmd.extend(['-p', str(PORT_STANDALONE)]) + + # bound as DM to make it faster + cmd.extend(['-D', DN_DM]) + cmd.extend(['-w', PASSWORD]) + + # filter + cmd.extend(['-f', "(cn=config)"]) + + # 2 samples SRCH + cmd.extend(['-C', "2"]) + + output = subprocess.check_output(cmd) + topo.stop() + + # No etime with 0.199xxx (everything should be few ms) + invalid_etime = topo.ds_access_log.match(r'.*etime=0\.19.*') + if invalid_etime: + for i in range(len(invalid_etime)): + log.error('It remains invalid or weird etime: %s' % invalid_etime[i]) + assert not invalid_etime + if __name__ == '__main__': # Run isolated # -s for DEBUG mode diff --git a/ldap/servers/slapd/time.c b/ldap/servers/slapd/time.c index 584bd1e..8048a33 100644 --- a/ldap/servers/slapd/time.c +++ b/ldap/servers/slapd/time.c @@ -235,8 +235,10 @@ slapi_timespec_diff(struct timespec *a, struct timespec *b, struct timespec *dif if (nsec < 0) { /* It's negative so take one second */ sec -= 1; - /* And set nsec to to a whole value */ - nsec = 1000000000 - nsec; + /* And set nsec to to a whole value + * nsec is negative => nsec = 1s - abs(nsec) + */ + nsec = 1000000000 + nsec; } diff->tv_sec = sec;