TimeBasedMatchingRuleTest.java revision ea1068c292e9b341af6d6b563cd8988a96be20a9
2852N/A/*
2887N/A * CDDL HEADER START
2852N/A *
2852N/A * The contents of this file are subject to the terms of the
2852N/A * Common Development and Distribution License, Version 1.0 only
2852N/A * (the "License"). You may not use this file except in compliance
2852N/A * with the License.
2852N/A *
2852N/A * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
2852N/A * or http://forgerock.org/license/CDDLv1.0.html.
2852N/A * See the License for the specific language governing permissions
2852N/A * and limitations under the License.
2852N/A *
2852N/A * When distributing Covered Code, include this CDDL HEADER in each
2852N/A * file and include the License file at legal-notices/CDDLv1_0.txt.
2852N/A * If applicable, add the following below this CDDL HEADER, with the
2852N/A * fields enclosed by brackets "[]" replaced with your own identifying
2852N/A * information:
2852N/A * Portions Copyright [yyyy] [name of copyright owner]
2852N/A *
2852N/A * CDDL HEADER END
2852N/A *
2852N/A *
2852N/A * Copyright 2009-2010 Sun Microsystems, Inc.
2852N/A * Portions Copyright 2010-2015 ForgeRock AS.
4347N/A */
2938N/Apackage org.opends.server.schema;
2852N/A
2852N/Aimport java.util.Calendar;
2852N/Aimport java.util.GregorianCalendar;
2852N/Aimport java.util.List;
4618N/Aimport java.util.TimeZone;
4618N/A
4618N/Aimport org.assertj.core.api.Assertions;
4618N/Aimport org.forgerock.opendj.ldap.*;
4618N/Aimport org.forgerock.opendj.ldap.schema.MatchingRule;
4618N/Aimport org.opends.server.TestCaseUtils;
4618N/Aimport org.opends.server.core.DirectoryServer;
4618N/Aimport org.opends.server.protocols.internal.InternalSearchOperation;
4618N/Aimport org.opends.server.protocols.internal.SearchRequest;
4618N/Aimport org.opends.server.types.DN;
4618N/Aimport org.opends.server.types.SearchResultEntry;
4618N/Aimport org.opends.server.util.TimeThread;
4618N/Aimport org.testng.annotations.BeforeClass;
4618N/Aimport org.testng.annotations.DataProvider;
4618N/Aimport org.testng.annotations.Test;
4618N/A
4618N/Aimport static org.opends.server.protocols.internal.InternalClientConnection.*;
4618N/Aimport static org.opends.server.protocols.internal.Requests.*;
4618N/Aimport static org.opends.server.schema.GeneralizedTimeSyntax.*;
4618N/Aimport static org.opends.server.schema.SchemaConstants.*;
4618N/Aimport static org.testng.Assert.*;
4618N/A
4618N/A/**
4618N/A * This class tests various time-based matching rules.
4618N/A */
4618N/A@SuppressWarnings("javadoc")
4618N/Apublic final class TimeBasedMatchingRuleTest
4618N/A extends SchemaTestCase
4618N/A{
4618N/A //User DNs to be used in tests.
4618N/A private DN user1;
4618N/A private DN user2;
4618N/A private DN user3;
4618N/A private DN user4;
4618N/A private DN user5;
4618N/A private DN user6;
4618N/A
4618N/A private final static String TIME_ATTR = "test-time";
4618N/A private final static String DATE_ATTR = "test-date";
4618N/A
4618N/A
4618N/A /**
4618N/A * Ensures that the Directory Server is running before executing the
4618N/A * testcases.
4618N/A *
4618N/A * @throws Exception If an unexpected problem occurs.
4618N/A */
4618N/A @BeforeClass
4618N/A public void startServer()
4618N/A throws Exception
4618N/A {
4618N/A TestCaseUtils.startServer();
4618N/A
4618N/A TestCaseUtils.initializeTestBackend(true);
4618N/A
4618N/A user1 = DN.valueOf("cn=user1,dc=example,dc=com");
4618N/A user2 = DN.valueOf("cn=user2,dc=example,dc=com");
4618N/A user3 = DN.valueOf("cn=user3,dc=example,dc=com");
4618N/A user4 = DN.valueOf("cn=user4,dc=example,dc=com");
4618N/A user5 = DN.valueOf("cn=user5,dc=example,dc=com");
4618N/A user6 = DN.valueOf("cn=user6,dc=example,dc=com");
4618N/A
4618N/A /**
4618N/A Extend the schema and add an attribute which is based on
4618N/A generalizedTimeSyntax. Since all the existing attributes based
4618N/A on that syntax are read-only, let us create a new attribute and
4618N/A add it.*/
4618N/A int resultCode = TestCaseUtils.applyModifications(true,
4618N/A "dn: cn=schema",
4618N/A "changetype: modify",
4618N/A "add: attributeTypes",
4618N/A "attributeTypes: ( test-time-oid NAME 'test-time' DESC 'Test time attribute' EQUALITY " +
4618N/A "generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )",
4618N/A "attributeTypes: ( test-date-oid NAME 'test-date' DESC 'Test date attribute' EQUALITY " +
4618N/A "generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 SINGLE-VALUE )",
4618N/A "-",
4618N/A "add: objectclasses",
4618N/A "objectclasses: ( testoc-oid NAME 'testOC' SUP top AUXILIARY MUST test-time)",
4618N/A "objectclasses: ( testoc2-oid NAME 'testOC2' SUP top AUXILIARY MUST test-date)"
4618N/A );
4618N/A assertEquals(0, resultCode);
4618N/A }
4618N/A
4618N/A
4618N/A
4618N/A /**
4618N/A * Test to search using the less-than relative time matching rule for expired events.
4618N/A */
4618N/A @Test
4618N/A public void testRTLessThanExpiredEvents() throws Exception
4618N/A {
4618N/A try
4618N/A {
4618N/A populateEntries();
4618N/A
4618N/A String filter = TIME_ATTR + ":" + EXT_OMR_RELATIVE_TIME_LT_OID + ":=-60m";
4618N/A SearchRequest request = newSearchRequest("dc=example,dc=com", SearchScope.WHOLE_SUBTREE, filter);
4618N/A InternalSearchOperation searchOperation = getRootConnection().processSearch(request);
4618N/A assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
4618N/A List<SearchResultEntry> entries = searchOperation.getSearchEntries();
4618N/A assertTrue(dnFoundInEntryList(entries,user1,user2));
4618N/A }
4618N/A finally
4618N/A {
4618N/A TestCaseUtils.clearJEBackend("userRoot");
3175N/A }
4618N/A }
4618N/A
4618N/A
4618N/A
4618N/A /**
4618N/A * Test to search using the less-than relative time matching rule for future events.
4618N/A */
4618N/A @Test
4618N/A public void testRTLessThanFutureEvents() throws Exception
4618N/A {
4618N/A try
4618N/A {
4618N/A populateEntries();
4618N/A
4618N/A String filter = TIME_ATTR + ":" + EXT_OMR_RELATIVE_TIME_LT_OID + ":=1d";
4618N/A SearchRequest request = newSearchRequest("dc=example,dc=com", SearchScope.WHOLE_SUBTREE, filter);
4618N/A InternalSearchOperation searchOperation = getRootConnection().processSearch(request);
4618N/A assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
4618N/A List<SearchResultEntry> entries = searchOperation.getSearchEntries();
4618N/A assertTrue(entries.size() == 4 && dnFoundInEntryList(entries,user1,user2,user3,user5));
4618N/A }
4618N/A finally
4618N/A {
4618N/A TestCaseUtils.clearJEBackend("userRoot");
4618N/A }
4618N/A }
4618N/A
4618N/A
4713N/A
4713N/A /**
4713N/A * Test to search using the greater-than relative time matching rule for expired events.
4713N/A */
4713N/A @Test
4713N/A public void testRTGreaterThanExpiredEvents() throws Exception
4713N/A {
4713N/A try
4713N/A {
4713N/A populateEntries();
4713N/A
4713N/A String filter = TIME_ATTR + ":" + EXT_OMR_RELATIVE_TIME_GT_OID + ":=-1h";
4713N/A SearchRequest request = newSearchRequest("dc=example,dc=com", SearchScope.WHOLE_SUBTREE, filter);
4713N/A InternalSearchOperation searchOperation = getRootConnection().processSearch(request);
4713N/A assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
4713N/A List<SearchResultEntry> entries = searchOperation.getSearchEntries();
4713N/A Assertions.assertThat(entries).hasSize(3);
4713N/A assertTrue(dnFoundInEntryList(entries, user3, user4, user5));
4713N/A }
4713N/A finally
4713N/A {
4713N/A TestCaseUtils.clearJEBackend("userRoot");
4713N/A }
4713N/A }
4713N/A
4713N/A
4713N/A
4713N/A /**
4713N/A * Test to search using the greater-than relative time matching rule for future events.
4713N/A */
4713N/A @Test
4713N/A public void testRTGreaterThanFutureEvents() throws Exception
4618N/A {
4618N/A try
4618N/A {
4618N/A populateEntries();
4618N/A
4618N/A String filter = TIME_ATTR + ":" + EXT_OMR_RELATIVE_TIME_GT_OID + ":=0s";
4618N/A SearchRequest request = newSearchRequest("dc=example,dc=com", SearchScope.WHOLE_SUBTREE, filter);
4618N/A InternalSearchOperation searchOperation = getRootConnection().processSearch(request);
4618N/A assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
4618N/A List<SearchResultEntry> entries = searchOperation.getSearchEntries();
4618N/A assertTrue(entries.size()==2 && dnFoundInEntryList(entries,user3,user4));
4618N/A }
4618N/A finally
4618N/A {
4618N/A TestCaseUtils.clearJEBackend("userRoot");
4618N/A }
4618N/A }
4618N/A
4618N/A
4618N/A
4618N/A /**
4618N/A * Test to search using the partial date and time matching rule
4618N/A * for an assertion value.
4618N/A * Dates for this test are hardcoded to avoid test failures depending
4618N/A * on when the tests are launched.
4618N/A */
4618N/A @Test
4618N/A public void testPartialDateNTimeMatchingRuleUsingSearch() throws Exception
4618N/A {
4618N/A try
4618N/A {
4618N/A populateEntries();
4618N/A
4618N/A String assertion = "01D11M";
4618N/A String filter = DATE_ATTR + ":" + EXT_PARTIAL_DATE_TIME_OID + ":=" + assertion;
4618N/A SearchRequest request = newSearchRequest("dc=example,dc=com", SearchScope.WHOLE_SUBTREE, filter);
4618N/A InternalSearchOperation searchOperation = getRootConnection().processSearch(request);
4618N/A assertEquals(searchOperation.getResultCode(), ResultCode.SUCCESS);
4618N/A List<SearchResultEntry> entries = searchOperation.getSearchEntries();
4618N/A assertTrue(entries.size()==1 && dnFoundInEntryList(entries,user6));
4618N/A }
4618N/A finally
4618N/A {
4618N/A TestCaseUtils.clearJEBackend("userRoot");
4618N/A }
4618N/A }
4618N/A
4618N/A
4618N/A /**
4618N/A * Test to match the attribute and the assertion values using a partial date and time
4618N/A * matching rule.
4618N/A */
4618N/A @Test(dataProvider="partialDateTimeValues")
4618N/A public void testPartialDateNTimeMatch(long attributeValue,String assertionValue) throws Exception
4618N/A {
4618N/A MatchingRule partialTimeRule = DirectoryServer.getMatchingRule(
4618N/A EXT_PARTIAL_DATE_TIME_NAME.toLowerCase());
4347N/A Assertion assertion = partialTimeRule.getAssertion(ByteString.valueOf(assertionValue));
4618N/A assertEquals(assertion.matches(ByteString.valueOf(attributeValue)), ConditionResult.TRUE);
4618N/A }
4618N/A
4618N/A
4618N/A
4618N/A /**
4618N/A * Tests the assertion syntax of the relative time matching rules.
4618N/A */
4618N/A @Test(dataProvider= "relativeTimeValues")
4618N/A public void testRelativeTimeMatchingRuleAssertionSyntax(String assertion,boolean isValid)
4618N/A {
4618N/A MatchingRule relativeTimeLTRule =
4618N/A DirectoryServer.getMatchingRule(EXT_OMR_RELATIVE_TIME_LT_ALT_NAME.toLowerCase());
4618N/A try
4618N/A {
4618N/A relativeTimeLTRule.getAssertion(ByteString.valueOf(assertion));
4618N/A // An invalid value can't get away without throwing exception.
4618N/A assertTrue(isValid);
4618N/A }
4618N/A catch (DecodeException e)
4618N/A {
4618N/A //invalid values will throw an exception.
4618N/A assertFalse(isValid);
4618N/A }
4618N/A }
4618N/A
4618N/A
4618N/A
4618N/A /**
4618N/A * Tests the assertion syntax of the partial date and time matching rules.
4618N/A */
4618N/A @Test(dataProvider= "partialDateTimeSyntaxes")
4618N/A public void testPartialDateTimeMatchingRuleAssertionSyntax(String assertion,boolean isValid)
4618N/A {
4618N/A MatchingRule partialDTRule =
4618N/A DirectoryServer.getMatchingRule(EXT_PARTIAL_DATE_TIME_OID);
4618N/A try
4618N/A {
4618N/A partialDTRule.getAssertion(ByteString.valueOf(assertion));
4618N/A assertTrue(isValid);
4618N/A }
4618N/A catch (DecodeException e)
4618N/A {
4618N/A //invalid values will throw an exception.
4618N/A assertFalse(isValid);
4618N/A }
4618N/A }
4618N/A
4618N/A
4618N/A
4618N/A /**
4618N/A * Generates data for testing relative time matching rule assertion syntax.
4618N/A */
4618N/A @DataProvider(name="relativeTimeValues")
4618N/A private Object[][] createRelativeTimeValues()
4618N/A {
4618N/A return new Object[][] {
4618N/A {"1s",true},
4618N/A {"1s0d",false},
4618N/A {"-1d",true},
4618N/A {"2h",true},
4618N/A {"+2w",true},
4618N/A {"0",true},
4618N/A {"0s",true},
4618N/A {"0d",true},
4618N/A {"xyz",false},
4618N/A {"12w-2d",false},
4618N/A {"1s2s",false},
4618N/A {"1d4s5d",false}
4618N/A
4618N/A };
4618N/A }
4618N/A
4618N/A
4618N/A /**
4618N/A * Generates the data for testing partial time date and time values.
4618N/A */
4618N/A @DataProvider(name="partialDateTimeValues")
4618N/A private Object[][] createPartialDateTimeValues()
4618N/A {
4680N/A GregorianCalendar c = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
4618N/A c.setLenient(false);
4618N/A c.clear();
4618N/A c.set(Calendar.HOUR_OF_DAY,23);
4618N/A c.set(Calendar.MINUTE,0);
4618N/A c.set(Calendar.SECOND,0);
4618N/A long time1 = c.getTimeInMillis();
4618N/A c.set(Calendar.HOUR_OF_DAY,00);
4618N/A c.set(Calendar.MINUTE,59);
4618N/A c.set(Calendar.SECOND,59);
4618N/A long time2 = c.getTimeInMillis();
4618N/A
4618N/A return new Object[][] {
4618N/A {time1,"0s"},
4618N/A {time1,"0m"},
4618N/A {time1,"23h"},
4618N/A {time2,"59m59s"},
4618N/A {time2,"0h59m59s"}
4618N/A };
4618N/A }
4618N/A
4618N/A
4618N/A
4618N/A /**
4618N/A * Generates data for testing partial date and time assertion syntax.
4618N/A */
4618N/A @DataProvider(name="partialDateTimeSyntaxes")
4618N/A private Object[][] createPartialDateTimeSyntaxes()
4618N/A {
4618N/A //Get the current time.
4618N/A GregorianCalendar cal =
4618N/A new GregorianCalendar(TimeZone.getTimeZone("UTC"));
4618N/A cal.setLenient(false);
4618N/A
4618N/A //Get the date today.
4618N/A int second = cal.get(Calendar.SECOND);
4618N/A int minute = cal.get(Calendar.MINUTE);
4618N/A int hour = cal.get(Calendar.HOUR);
4618N/A int date = cal.get(Calendar.DATE);
4618N/A int month = cal.get(Calendar.MONTH) + 1;
4618N/A int year = cal.get(Calendar.YEAR);
4618N/A
4618N/A return new Object[][] {
4618N/A {"20MM30DD1978YY",false},
4618N/A {"02MM29DD2009YY",false},
4618N/A {"02MM31DD2010YY",false},
4618N/A {"-1s",false},
4618N/A {"02M29D2008Y",true},
4618N/A {"DDYY",false},
4618N/A {"02D",true},
4618N/A {"12M",true},
4618N/A {"1978Y",true},
4618N/A {"0MM",false},
4618N/A {"20MM03DD10MM",false},
4618N/A {"00s12m13h",true},
4618N/A {"00s12m14h1M3D1978Y",true},
4618N/A {"1s",true},
4618N/A {"12m",true},
4618N/A {"23h",true},
4618N/A {"61s",false},
4618N/A {"60m",false},
4618N/A {"24h",false},
4618N/A {second+"s",true},
4618N/A {minute+"m",true},
4618N/A {hour+"h",true},
4618N/A {date+"D",true},
4618N/A {month+"M",true},
4618N/A {year+"Y",true},
2938N/A {month+"M"+date+"D",true},
4618N/A {year+"Y"+date+"D",true},
4618N/A {month+"M"+year+"Y"+date+"D",true}
4618N/A };
4618N/A }
4618N/A
4618N/A // validate if the args are found in the entries list.
4618N/A private boolean dnFoundInEntryList(List<SearchResultEntry> entries, DN... dns)
4618N/A {
4618N/A for (DN dn : dns)
4618N/A {
4618N/A assertTrue(find(entries, dn), "Could not find dn " + dn + " in list " + entries);
4618N/A }
4618N/A return true;
2938N/A }
4618N/A
4618N/A private boolean find(List<SearchResultEntry> entries, DN dn)
4618N/A {
2938N/A for (SearchResultEntry entry : entries)
2938N/A {
2852N/A 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
// calendar may fail if the time thread using a stale time.
long currentTime = TimeThread.getTime();
TestCaseUtils.clearJEBackend("userRoot", "dc=example,dc=com");
TestCaseUtils.addEntries(
"dn: cn=user1,dc=example,dc=com",
"objectclass: person",
"objectclass: testoc",
"cn: user1",
"sn: user1",
TIME_ATTR + ": "+ format(currentTime-4000*1000), //more than 1 hour old.
"",
"dn: cn=user2,dc=example,dc=com",
"objectclass: person",
"objectclass: testoc",
"cn: user2",
"sn: user2",
TIME_ATTR + ": " + format(currentTime-25*3600*1000), //more than a day old.
"",
"dn: cn=user3,dc=example,dc=com",
"objectclass: person",
"objectclass: testoc",
"cn: user3",
"sn: user3",
TIME_ATTR + ": " + format(currentTime+4000*1000), //more than 1 hour in advance.
"",
"dn: cn=user4,dc=example,dc=com",
"objectclass: person",
"objectclass: testoc",
"cn: user4",
"sn: user4",
TIME_ATTR + ": " + format(currentTime+25*3600*1000), // more than 1 day in advance
"",
"dn: cn=user5,dc=example,dc=com",
"objectclass: person",
"objectclass: testoc",
"cn: user5",
"sn: user5",
TIME_ATTR + ": " + format(currentTime), // now.
"",
"dn: cn=user6,dc=example,dc=com",
"objectclass: person",
"objectclass: testoc2",
"cn: user6",
"sn: user6",
DATE_ATTR + ": 19651101000000Z", // Nov 1st 1965
"",
"dn: cn=user7,dc=example,dc=com",
"objectclass: person",
"objectclass: testoc2",
"cn: user7",
"sn: user7",
DATE_ATTR + ": 20101104000000Z", // Nov 4th 2010
"",
"dn: cn=user8,dc=example,dc=com",
"objectclass: person",
"objectclass: testoc2",
"cn: user8",
"sn: user8",
DATE_ATTR + ": 20000101000000Z" // Jan 1st 2000
);
}
}