From 054849011dfed22c5b07e26225678e436232752f Mon Sep 17 00:00:00 2001 From: William Brown Date: Jun 29 2017 00:41:05 +0000 Subject: Ticket 49290 - unindexed range searches don't provide notes=U Bug Description: An unindexed range search would not issue notes=U in the access log. Fix Description: When an unindexed range search is found, add the operation note that the query is unindexed. https://pagure.io/389-ds-base/issue/49290 Author: wibrown Review by: tbordaz (Thanks!) --- diff --git a/dirsrvtests/tests/tickets/ticket49290_test.py b/dirsrvtests/tests/tickets/ticket49290_test.py new file mode 100644 index 0000000..72ba9f9 --- /dev/null +++ b/dirsrvtests/tests/tickets/ticket49290_test.py @@ -0,0 +1,66 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2017 Red Hat, Inc. +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK --- +# + +import pytest +import ldap + +from lib389.topologies import topology_st +from lib389._constants import DEFAULT_SUFFIX, DEFAULT_BENAME + +from lib389.backend import Backends + +def test_49290_range_unindexed_notes(topology_st): + """ + Ticket 49290 had a small collection of issues - the primary issue is + that range requests on an attribute that is unindexed was not reporting + notes=U. This asserts that: + + * When unindexed, the attr shows notes=U + * when indexed, the attr does not + """ + + # First, assert that modifyTimestamp does not have an index. If it does, + # delete it. + topology_st.standalone.config.set('nsslapd-accesslog-logbuffering', 'off') + backends = Backends(topology_st.standalone) + backend = backends.get(DEFAULT_BENAME) + indexes = backend.get_indexes() + + for i in indexes.list(): + i_cn = i.get_attr_val_utf8('cn') + if i_cn.lower() == 'modifytimestamp': + i.delete() + topology_st.standalone.restart() + + # Now restart the server, and perform a modifyTimestamp range operation. + # in access, we should see notes=U (or notes=A) + results = topology_st.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(modifyTimestamp>=0)', ['nsUniqueId',]) + access_lines_unindexed = topology_st.standalone.ds_access_log.match('.*notes=U.*') + assert len(access_lines_unindexed) == 1 + + # Now add the modifyTimestamp index and run db2index. This will restart + # the server + indexes.create(properties={ + 'cn': 'modifytimestamp', + 'nsSystemIndex': 'false', + 'nsIndexType' : 'eq', + }) + topology_st.standalone.stop() + topology_st.standalone.db2index(DEFAULT_BENAME) + topology_st.standalone.start() + + # Now run the modifyTimestamp range query again. Assert that there is no + # notes=U/A in the log + results = topology_st.standalone.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, '(modifyTimestamp>=0)', ['nsUniqueId',]) + access_lines_indexed = topology_st.standalone.ds_access_log.match('.*notes=U.*') + # Remove the old lines too. + access_lines_final = set(access_lines_unindexed) - set(access_lines_indexed) + # Make sure we have no unindexed notes in the log. + assert len(access_lines_final) == 0 + diff --git a/ldap/servers/slapd/back-ldbm/index.c b/ldap/servers/slapd/back-ldbm/index.c index a3dac66..4d74484 100644 --- a/ldap/servers/slapd/back-ldbm/index.c +++ b/ldap/servers/slapd/back-ldbm/index.c @@ -1298,6 +1298,13 @@ index_range_read_ext( slapi_log_err(SLAPI_LOG_ARGS, "index_range_read_ext", "indextype: \"%s\" indexmask: 0x%x\n", indextype, ai->ai_indexmask); if ( !is_indexed( indextype, ai->ai_indexmask, ai->ai_index_rules )) { + + /* Mark that the search has an unindexed component */ + uint32_t opnote = 0; + slapi_pblock_get( pb, SLAPI_OPERATION_NOTES, &opnote ); + opnote |= SLAPI_OP_NOTE_UNINDEXED; + slapi_pblock_set( pb, SLAPI_OPERATION_NOTES, &opnote ); + idl = idl_allids( be ); slapi_log_err(SLAPI_LOG_TRACE, "index_range_read_ext", "(%s,%s) %lu candidates (allids)\n",