From 05d69c6f9c226c38e40ca7a105b8ea9791ff4b50 Mon Sep 17 00:00:00 2001
From: Jean-Noël Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Thu, 05 Nov 2015 12:25:29 +0000
Subject: [PATCH] TimeBasedMatchingRuleTest.java: Added tests for indexing Removed code duplication
---
opendj-server-legacy/src/test/java/org/opends/server/schema/FakeByteStringIndex.java | 154 ++++++++++++
opendj-server-legacy/src/test/java/org/opends/server/schema/FakeIndexQueryFactory.java | 126 ++++++++++
opendj-server-legacy/src/test/java/org/opends/server/schema/FakeEntryIndex.java | 180 +++++++++++++++
opendj-server-legacy/src/test/java/org/opends/server/schema/TimeBasedMatchingRuleTest.java | 243 +++++++++-----------
4 files changed, 569 insertions(+), 134 deletions(-)
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/schema/FakeByteStringIndex.java b/opendj-server-legacy/src/test/java/org/opends/server/schema/FakeByteStringIndex.java
new file mode 100644
index 0000000..bd96d0d
--- /dev/null
+++ b/opendj-server-legacy/src/test/java/org/opends/server/schema/FakeByteStringIndex.java
@@ -0,0 +1,154 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright 2015 ForgeRock AS
+ */
+package org.opends.server.schema;
+
+import static org.mockito.Mockito.*;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.forgerock.opendj.ldap.Assertion;
+import org.forgerock.opendj.ldap.ByteString;
+import org.forgerock.opendj.ldap.DecodeException;
+import org.forgerock.opendj.ldap.schema.MatchingRule;
+import org.forgerock.opendj.ldap.schema.Schema;
+import org.forgerock.opendj.ldap.spi.Indexer;
+import org.forgerock.opendj.ldap.spi.IndexingOptions;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.FilterType;
+
+class FakeByteStringIndex
+{
+ private MatchingRule matchingRule;
+ private Indexer indexer;
+ private final NavigableMap<ByteString, Set<ByteString>> index = new TreeMap<>();
+
+ FakeByteStringIndex(String mrName) throws DecodeException
+ {
+ matchingRule = DirectoryServer.getMatchingRule(mrName.toLowerCase());
+ IndexingOptions options = mock(IndexingOptions.class);
+ indexer = matchingRule.createIndexers(options).iterator().next();
+ }
+
+ void addAll(List<ByteString> attrValues) throws DecodeException
+ {
+ for (ByteString attrValue : attrValues)
+ {
+ add(attrValue);
+ }
+ }
+
+ void add(ByteString attrValue) throws DecodeException
+ {
+ for (ByteString key : index(attrValue))
+ {
+ Set<ByteString> entries = index.get(key);
+ if (entries == null)
+ {
+ entries = new HashSet<>();
+ index.put(key, entries);
+ }
+ entries.add(attrValue);
+ }
+ }
+
+ private Collection<ByteString> index(ByteString attrValue) throws DecodeException
+ {
+ Collection<ByteString> keys = new TreeSet<>();
+ indexer.createKeys(Schema.getDefaultSchema(), attrValue, keys);
+ return keys;
+ }
+
+ public Set<ByteString> evaluateAssertionValue(ByteString assertionValue, FilterType filterType)
+ throws DirectoryException, DecodeException
+ {
+ Assertion assertion = getAssertion(assertionValue, filterType);
+ return assertion.createIndexQuery(new FakeIndexQueryFactory<ByteString>(index));
+ }
+
+ private Assertion getAssertion(ByteString assertionValue, FilterType filterType) throws DecodeException
+ {
+ switch (filterType)
+ {
+ case EQUALITY:
+ case EXTENSIBLE_MATCH:
+ return matchingRule.getAssertion(assertionValue);
+
+ case LESS_OR_EQUAL:
+ return matchingRule.getLessOrEqualAssertion(assertionValue);
+
+ case GREATER_OR_EQUAL:
+ return matchingRule.getGreaterOrEqualAssertion(assertionValue);
+
+ default:
+ throw new RuntimeException("Not implemented for filter type " + filterType);
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+ for (Map.Entry<ByteString, Set<ByteString>> mapEntry : index.entrySet())
+ {
+ String key = mapEntry.getKey().toHexString();
+ Set<ByteString> value = mapEntry.getValue();
+ Iterator<ByteString> it = value.iterator();
+ if (!it.hasNext())
+ {
+ continue;
+ }
+ sb.append(key).append("\t").append(firstLine(it.next())).append("\n");
+ while (it.hasNext())
+ {
+ sb.append(emptyString(key.length())).append("\t").append(firstLine(it.next())).append("\n");
+ }
+ }
+ return sb.toString();
+ }
+
+ private String firstLine(ByteString attrValue)
+ {
+ return attrValue.toString().split("\\n")[0] + " ...";
+ }
+
+ private String emptyString(int length)
+ {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < length; i++)
+ {
+ sb.append(" ");
+ }
+ return sb.toString();
+ }
+}
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/schema/FakeEntryIndex.java b/opendj-server-legacy/src/test/java/org/opends/server/schema/FakeEntryIndex.java
new file mode 100644
index 0000000..f4e8d0a
--- /dev/null
+++ b/opendj-server-legacy/src/test/java/org/opends/server/schema/FakeEntryIndex.java
@@ -0,0 +1,180 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright 2015 ForgeRock AS
+ */
+package org.opends.server.schema;
+
+import static org.mockito.Mockito.*;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.forgerock.opendj.ldap.Assertion;
+import org.forgerock.opendj.ldap.ByteString;
+import org.forgerock.opendj.ldap.DecodeException;
+import org.forgerock.opendj.ldap.schema.MatchingRule;
+import org.forgerock.opendj.ldap.schema.Schema;
+import org.forgerock.opendj.ldap.spi.Indexer;
+import org.forgerock.opendj.ldap.spi.IndexingOptions;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeType;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.Entry;
+import org.opends.server.types.SearchFilter;
+
+class FakeEntryIndex
+{
+ private AttributeType attrType;
+ private MatchingRule matchingRule;
+ private Indexer indexer;
+ private final NavigableMap<ByteString, Set<Entry>> index = new TreeMap<>();
+
+ FakeEntryIndex(String attrName) throws DecodeException
+ {
+ attrType = DirectoryServer.getAttributeTypeOrNull(attrName);
+ if (attrType == null)
+ {
+ throw new IllegalArgumentException("Cannot find attribute with name \"" + attrName + "\"");
+ }
+ matchingRule = attrType.getEqualityMatchingRule();
+ IndexingOptions options = mock(IndexingOptions.class);
+ indexer = matchingRule.createIndexers(options).iterator().next();
+ }
+
+ void addAll(List<Entry> entries) throws DecodeException
+ {
+ for (Entry entry : entries)
+ {
+ add(entry);
+ }
+ }
+
+ void add(Entry entry) throws DecodeException
+ {
+ Attribute attribute = entry.getExactAttribute(attrType, Collections.<String>emptySet());
+ for (ByteString key : index(attribute))
+ {
+ Set<Entry> entries = index.get(key);
+ if (entries == null)
+ {
+ entries = new HashSet<>();
+ index.put(key, entries);
+ }
+ entries.add(entry);
+ }
+ }
+
+ private Collection<ByteString> index(Attribute attribute) throws DecodeException
+ {
+ if (attribute == null)
+ {
+ return Collections.emptySet();
+ }
+ Collection<ByteString> keys = new TreeSet<>();
+ for (ByteString attrValue : attribute)
+ {
+ indexer.createKeys(Schema.getDefaultSchema(), attrValue, keys);
+ }
+ return keys;
+ }
+
+ public Set<Entry> evaluateFilter(String filterString) throws DirectoryException, DecodeException
+ {
+ SearchFilter filter = SearchFilter.createFilterFromString(filterString);
+ if (!attrType.equals(filter.getAttributeType()))
+ {
+ throw new IllegalArgumentException("The search filter \"" + filterString
+ + "\" should target the same attribute type as this index \"" + attrType.getNameOrOID() + "\"");
+ }
+ Assertion assertion = getAssertion(filter);
+ return assertion.createIndexQuery(new FakeIndexQueryFactory<Entry>(index));
+ }
+
+ private Assertion getAssertion(SearchFilter filter) throws DecodeException
+ {
+ switch (filter.getFilterType())
+ {
+ case EQUALITY:
+ return matchingRule.getAssertion(filter.getAssertionValue());
+
+ case LESS_OR_EQUAL:
+ return matchingRule.getLessOrEqualAssertion(filter.getAssertionValue());
+
+ case GREATER_OR_EQUAL:
+ return matchingRule.getGreaterOrEqualAssertion(filter.getAssertionValue());
+
+ case EXTENSIBLE_MATCH:
+ MatchingRule rule = DirectoryServer.getMatchingRule(filter.getMatchingRuleID());
+ return rule.getAssertion(filter.getAssertionValue());
+
+ default:
+ throw new RuntimeException("Not implemented for search filter type " + filter.getFilterType());
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+ for (Map.Entry<ByteString, Set<Entry>> mapEntry : index.entrySet())
+ {
+ String key = mapEntry.getKey().toHexString();
+ Set<Entry> value = mapEntry.getValue();
+ Iterator<Entry> it = value.iterator();
+ if (!it.hasNext())
+ {
+ continue;
+ }
+ sb.append(key).append("\t").append(firstLine(it.next())).append("\n");
+ while (it.hasNext())
+ {
+ sb.append(emptyString(key.length())).append("\t").append(firstLine(it.next())).append("\n");
+ }
+ }
+ return sb.toString();
+ }
+
+ private String firstLine(Entry entry)
+ {
+ return entry.toString().split("\\n")[0] + " ...";
+ }
+
+ private String emptyString(int length)
+ {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < length; i++)
+ {
+ sb.append(" ");
+ }
+ return sb.toString();
+ }
+}
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/schema/FakeIndexQueryFactory.java b/opendj-server-legacy/src/test/java/org/opends/server/schema/FakeIndexQueryFactory.java
new file mode 100644
index 0000000..1c86fd5
--- /dev/null
+++ b/opendj-server-legacy/src/test/java/org/opends/server/schema/FakeIndexQueryFactory.java
@@ -0,0 +1,126 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ * Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright 2015 ForgeRock AS
+ */
+package org.opends.server.schema;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.NavigableMap;
+import java.util.Set;
+
+import org.forgerock.opendj.ldap.ByteSequence;
+import org.forgerock.opendj.ldap.ByteString;
+import org.forgerock.opendj.ldap.spi.IndexQueryFactory;
+import org.forgerock.opendj.ldap.spi.IndexingOptions;
+
+/**
+ * {@link IndexQueryFactory} implementation which evaluates queries instead of creating them.
+ * The queries are evaluated against a provided {@code NavigableMap<ByteString, Set>} (SetMultimap)
+ * which acts as an index.
+ *
+ * @param <T> type of the values
+ */
+final class FakeIndexQueryFactory<T> implements IndexQueryFactory<Set<T>>
+{
+ private final NavigableMap<ByteString, Set<T>> index;
+
+ FakeIndexQueryFactory(NavigableMap<ByteString, Set<T>> index)
+ {
+ this.index = index;
+ }
+
+ @Override
+ public Set<T> createExactMatchQuery(String indexID, ByteSequence key)
+ {
+ Set<T> results = index.get(key);
+ return results != null ? new HashSet<>(results) : Collections.<T> emptySet();
+ }
+
+ @Override
+ public Set<T> createMatchAllQuery()
+ {
+ return flatten(index.values());
+ }
+
+ @Override
+ public Set<T> createRangeMatchQuery(String indexID, ByteSequence lower, ByteSequence upper,
+ boolean lowerIncluded, boolean upperIncluded)
+ {
+ NavigableMap<ByteString, Set<T>> map = index;
+ if (lower.length() > 0)
+ {
+ map = map.tailMap(lower.toByteString(), lowerIncluded);
+ }
+ if (upper.length() > 0)
+ {
+ map = map.headMap(upper.toByteString(), upperIncluded);
+ }
+ return flatten(map.values());
+ }
+
+ private Set<T> flatten(Collection<? extends Collection<T>> values)
+ {
+ Set<T> results = new HashSet<>();
+ for (Collection<T> entries : values)
+ {
+ results.addAll(entries);
+ }
+ return results;
+ }
+
+ @Override
+ public Set<T> createIntersectionQuery(Collection<Set<T>> subResults)
+ {
+ Iterator<Set<T>> it = subResults.iterator();
+ if (!it.hasNext())
+ {
+ return Collections.emptySet();
+ }
+ Set<T> results = new HashSet<>(it.next());
+ while (it.hasNext())
+ {
+ results.retainAll(it.next());
+ }
+ return results;
+ }
+
+ @Override
+ public Set<T> createUnionQuery(Collection<Set<T>> subResults)
+ {
+ Set<T> results = new HashSet<>();
+ for (Collection<T> entries : subResults)
+ {
+ results.addAll(entries);
+ }
+ return results;
+ }
+
+ @Override
+ public IndexingOptions getIndexingOptions()
+ {
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/schema/TimeBasedMatchingRuleTest.java b/opendj-server-legacy/src/test/java/org/opends/server/schema/TimeBasedMatchingRuleTest.java
index 71a2830..a18c815 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/schema/TimeBasedMatchingRuleTest.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/schema/TimeBasedMatchingRuleTest.java
@@ -26,34 +26,41 @@
*/
package org.opends.server.schema;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.List;
+import java.util.Set;
import java.util.TimeZone;
-import org.assertj.core.api.Assertions;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.schema.MatchingRule;
import org.opends.server.TestCaseUtils;
import org.opends.server.core.DirectoryServer;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.protocols.internal.SearchRequest;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeType;
import org.opends.server.types.DN;
-import org.opends.server.types.SearchResultEntry;
+import org.opends.server.types.Entry;
+import org.opends.server.types.FilterType;
+import org.opends.server.types.SearchFilter;
import org.opends.server.util.TimeThread;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
+import static org.assertj.core.api.Assertions.*;
import static org.opends.server.protocols.internal.InternalClientConnection.*;
import static org.opends.server.protocols.internal.Requests.*;
import static org.opends.server.schema.GeneralizedTimeSyntax.*;
import static org.opends.server.schema.SchemaConstants.*;
import static org.testng.Assert.*;
-/**
- * This class tests various time-based matching rules.
- */
+/** This class tests various time-based matching rules. */
@SuppressWarnings("javadoc")
public final class TimeBasedMatchingRuleTest
extends SchemaTestCase
@@ -112,24 +119,33 @@
assertEquals(0, resultCode);
}
+ @DataProvider
+ public Object[][] relativeTime()
+ {
+ return new Object[][] {
+ // relativeTime less than expired events
+ { TIME_ATTR + ":" + EXT_OMR_RELATIVE_TIME_LT_OID + ":=-60m", new DN[] { user1, user2, } },
+ // relativeTime less than future events
+ { TIME_ATTR + ":" + EXT_OMR_RELATIVE_TIME_LT_OID + ":=1d", new DN[] { user1, user2, user3, user5, } },
+ // relativeTime greater than expired events
+ { TIME_ATTR + ":" + EXT_OMR_RELATIVE_TIME_GT_OID + ":=-1h", new DN[] { user3, user4, user5, } },
+ // relativeTime greater than future events
+ { TIME_ATTR + ":" + EXT_OMR_RELATIVE_TIME_GT_OID + ":=0s", new DN[] { user3, user4, } },
+ };
+ }
-
- /**
- * Test to search using the less-than relative time matching rule for expired events.
- */
- @Test
- public void testRTLessThanExpiredEvents() throws Exception
+ /** Test to search using the relative time matching rule. */
+ @Test(dataProvider = "relativeTime")
+ public void testRelativeTimeUsingSearch(String filterString, DN[] expectedDNs) throws Exception
{
try
{
populateEntries();
- String filter = TIME_ATTR + ":" + EXT_OMR_RELATIVE_TIME_LT_OID + ":=-60m";
- SearchRequest request = newSearchRequest("dc=example,dc=com", SearchScope.WHOLE_SUBTREE, filter);
+ SearchRequest request = newSearchRequest("dc=example,dc=com", SearchScope.WHOLE_SUBTREE, filterString);
InternalSearchOperation searchOperation = getRootConnection().processSearch(request);
assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
- List<SearchResultEntry> entries = searchOperation.getSearchEntries();
- assertTrue(dnFoundInEntryList(entries,user1,user2));
+ assertThat(toNames(searchOperation.getSearchEntries())).containsOnly(expectedDNs);
}
finally
{
@@ -137,84 +153,45 @@
}
}
-
-
- /**
- * Test to search using the less-than relative time matching rule for future events.
- */
- @Test
- public void testRTLessThanFutureEvents() throws Exception
+ @Test(dataProvider = "relativeTime")
+ public void testRelativeTimeUsingAssertion(String filterString, DN[] expectedDNs) throws Exception
{
- try
- {
- populateEntries();
-
- String filter = TIME_ATTR + ":" + EXT_OMR_RELATIVE_TIME_LT_OID + ":=1d";
- SearchRequest request = newSearchRequest("dc=example,dc=com", SearchScope.WHOLE_SUBTREE, filter);
- InternalSearchOperation searchOperation = getRootConnection().processSearch(request);
- assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
- List<SearchResultEntry> entries = searchOperation.getSearchEntries();
- assertTrue(entries.size() == 4 && dnFoundInEntryList(entries,user1,user2,user3,user5));
- }
- finally
- {
- TestCaseUtils.clearJEBackend("userRoot");
- }
+ SearchFilter filter = SearchFilter.createFilterFromString(filterString);
+ assertThat(getMatchingEntryDNs(filter)).containsOnly(expectedDNs);
}
-
-
- /**
- * Test to search using the greater-than relative time matching rule for expired events.
- */
- @Test
- public void testRTGreaterThanExpiredEvents() throws Exception
+ private Collection<DN> getMatchingEntryDNs(SearchFilter filter) throws Exception
{
- try
- {
- populateEntries();
+ AttributeType attrType = filter.getAttributeType();
+ MatchingRule rule = DirectoryServer.getMatchingRule(filter.getMatchingRuleID());
+ Assertion assertion = rule.getAssertion(filter.getAssertionValue());
- String filter = TIME_ATTR + ":" + EXT_OMR_RELATIVE_TIME_GT_OID + ":=-1h";
- SearchRequest request = newSearchRequest("dc=example,dc=com", SearchScope.WHOLE_SUBTREE, filter);
- InternalSearchOperation searchOperation = getRootConnection().processSearch(request);
- assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
- List<SearchResultEntry> entries = searchOperation.getSearchEntries();
- Assertions.assertThat(entries).hasSize(3);
- assertTrue(dnFoundInEntryList(entries, user3, user4, user5));
- }
- finally
+ Collection<DN> results = new ArrayList<>();
+ for (Entry entry : makeEntries())
{
- TestCaseUtils.clearJEBackend("userRoot");
+ Attribute attribute = entry.getExactAttribute(attrType, Collections.<String> emptySet());
+ if (attribute != null)
+ {
+ ByteString attrValue = rule.normalizeAttributeValue(attribute.iterator().next());
+ if (assertion.matches(attrValue).toBoolean())
+ {
+ results.add(entry.getName());
+ }
+ }
}
+ return results;
}
-
-
- /**
- * Test to search using the greater-than relative time matching rule for future events.
- */
- @Test
- public void testRTGreaterThanFutureEvents() throws Exception
+ /** Test to search using the relative time matching rule with index. */
+ @Test(dataProvider = "relativeTime")
+ public void testRelativeTimeWithIndex(String filterString, DN[] expectedDNs) throws Exception
{
- try
- {
- populateEntries();
-
- String filter = TIME_ATTR + ":" + EXT_OMR_RELATIVE_TIME_GT_OID + ":=0s";
- SearchRequest request = newSearchRequest("dc=example,dc=com", SearchScope.WHOLE_SUBTREE, filter);
- InternalSearchOperation searchOperation = getRootConnection().processSearch(request);
- assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
- List<SearchResultEntry> entries = searchOperation.getSearchEntries();
- assertTrue(entries.size()==2 && dnFoundInEntryList(entries,user3,user4));
- }
- finally
- {
- TestCaseUtils.clearJEBackend("userRoot");
- }
+ FakeEntryIndex index = new FakeEntryIndex(TIME_ATTR);
+ index.addAll(makeEntries());
+ Collection<Entry> entries = index.evaluateFilter(filterString);
+ assertThat(toNames(entries)).containsOnly(expectedDNs);
}
-
-
/**
* Test to search using the partial date and time matching rule
* for an assertion value.
@@ -233,8 +210,7 @@
SearchRequest request = newSearchRequest("dc=example,dc=com", SearchScope.WHOLE_SUBTREE, filter);
InternalSearchOperation searchOperation = getRootConnection().processSearch(request);
assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
- List<SearchResultEntry> entries = searchOperation.getSearchEntries();
- assertTrue(entries.size()==1 && dnFoundInEntryList(entries,user6));
+ assertThat(toNames(searchOperation.getSearchEntries())).containsOnly(user6);
}
finally
{
@@ -242,25 +218,46 @@
}
}
+ private List<DN> toNames(Collection<? extends Entry> entries)
+ {
+ List<DN> results = new ArrayList<>();
+ for (Entry entry : entries)
+ {
+ results.add(entry.getName());
+ }
+ return results;
+ }
/**
* Test to match the attribute and the assertion values using a partial date and time
* matching rule.
*/
@Test(dataProvider="partialDateTimeValues")
- public void testPartialDateNTimeMatch(long attributeValue,String assertionValue) throws Exception
+ public void testPartialDateNTimeMatch(long timeInMillis, String generalizedTime, String assertionValue)
+ throws Exception
{
MatchingRule partialTimeRule = DirectoryServer.getMatchingRule(
EXT_PARTIAL_DATE_TIME_NAME.toLowerCase());
Assertion assertion = partialTimeRule.getAssertion(ByteString.valueOfUtf8(assertionValue));
- assertEquals(assertion.matches(ByteString.valueOfLong(attributeValue)), ConditionResult.TRUE);
+ assertEquals(assertion.matches(ByteString.valueOfLong(timeInMillis)), ConditionResult.TRUE);
+ }
+
+ @Test(dataProvider="partialDateTimeValues")
+ public void testPartialDateNTimeMatchViaIndex(long timeInMillis, String generalizedTime, String assertionValue)
+ throws Exception
+ {
+ ByteString attrValue = ByteString.valueOfUtf8(generalizedTime);
+ ByteString assertValue = ByteString.valueOfUtf8(assertionValue);
+
+ FakeByteStringIndex fakeIndex = new FakeByteStringIndex(EXT_PARTIAL_DATE_TIME_NAME);
+ fakeIndex.add(attrValue);
+ Set<ByteString> attrValues = fakeIndex.evaluateAssertionValue(assertValue, FilterType.EXTENSIBLE_MATCH);
+ assertThat(attrValues).containsOnly(attrValue);
}
- /**
- * Tests the assertion syntax of the relative time matching rules.
- */
+ /** Tests the assertion syntax of the relative time matching rules. */
@Test(dataProvider= "relativeTimeValues")
public void testRelativeTimeMatchingRuleAssertionSyntax(String assertion,boolean isValid)
{
@@ -281,9 +278,7 @@
- /**
- * Tests the assertion syntax of the partial date and time matching rules.
- */
+ /** Tests the assertion syntax of the partial date and time matching rules. */
@Test(dataProvider= "partialDateTimeSyntaxes")
public void testPartialDateTimeMatchingRuleAssertionSyntax(String assertion,boolean isValid)
{
@@ -303,9 +298,7 @@
- /**
- * Generates data for testing relative time matching rule assertion syntax.
- */
+ /** Generates data for testing relative time matching rule assertion syntax. */
@DataProvider(name="relativeTimeValues")
private Object[][] createRelativeTimeValues()
{
@@ -322,43 +315,42 @@
{"12w-2d",false},
{"1s2s",false},
{"1d4s5d",false}
-
};
}
- /**
- * Generates the data for testing partial time date and time values.
- */
- @DataProvider(name="partialDateTimeValues")
- private Object[][] createPartialDateTimeValues()
+ /** Generates the data for testing partial time date and time values. */
+ @DataProvider
+ private Object[][] partialDateTimeValues()
{
+ SimpleDateFormat sdf = new SimpleDateFormat("YYYYMMddHHmmssZ");
GregorianCalendar c = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
c.setLenient(false);
c.clear();
+ sdf.setCalendar(c);
c.set(Calendar.HOUR_OF_DAY,23);
c.set(Calendar.MINUTE,0);
c.set(Calendar.SECOND,0);
long time1 = c.getTimeInMillis();
+ String format1 = sdf.format(c.getTime());
c.set(Calendar.HOUR_OF_DAY,00);
c.set(Calendar.MINUTE,59);
c.set(Calendar.SECOND,59);
long time2 = c.getTimeInMillis();
+ String format2 = sdf.format(c.getTime());
return new Object[][] {
- {time1,"0s"},
- {time1,"0m"},
- {time1,"23h"},
- {time2,"59m59s"},
- {time2,"0h59m59s"}
+ { time1, format1, "0s" },
+ { time1, format1, "0m" },
+ { time1, format1, "23h" },
+ { time2, format2, "59m59s" },
+ { time2, format2, "0h59m59s" }
};
}
- /**
- * Generates data for testing partial date and time assertion syntax.
- */
+ /** Generates data for testing partial date and time assertion syntax. */
@DataProvider(name="partialDateTimeSyntaxes")
private Object[][] createPartialDateTimeSyntaxes()
{
@@ -407,37 +399,20 @@
};
}
- /** Validate if the args are found in the entries list. */
- private boolean dnFoundInEntryList(List<SearchResultEntry> entries, DN... dns)
- {
- for (DN dn : dns)
- {
- assertTrue(find(entries, dn), "Could not find dn " + dn + " in list " + entries);
- }
- return true;
- }
-
- private boolean find(List<SearchResultEntry> entries, DN dn)
- {
- for (SearchResultEntry entry : entries)
- {
- if (entry.getName().equals(dn))
- {
- return true;
- }
- }
- return false;
- }
-
/** Creates the entries. */
private void populateEntries() throws Exception
{
- //Get the current time from the TimeThread. Using the current time from new
+ TestCaseUtils.clearJEBackend("userRoot", "dc=example,dc=com");
+ TestCaseUtils.addEntries(makeEntries());
+ }
+
+ private List<Entry> makeEntries() throws Exception
+ {
+ // Get the current time from the TimeThread. Using the current time from new
// calendar may fail if the time thread using a stale time.
long currentTime = TimeThread.getTime();
- TestCaseUtils.clearJEBackend("userRoot", "dc=example,dc=com");
- TestCaseUtils.addEntries(
+ return TestCaseUtils.makeEntries(
"dn: cn=user1,dc=example,dc=com",
"objectclass: person",
"objectclass: testoc",
@@ -495,4 +470,4 @@
DATE_ATTR + ": 20000101000000Z" // Jan 1st 2000
);
}
- }
+}
--
Gitblit v1.10.0