/*
* 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.replication.plugin;
import static org.forgerock.opendj.ldap.ModificationType.*;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
import static org.opends.server.util.CollectionUtils.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ModificationType;
import org.opends.server.TestCaseUtils;
import org.opends.server.replication.ReplicationTestCase;
import org.opends.server.replication.common.CSN;
import org.opends.server.replication.protocol.ModifyContext;
import org.opends.server.replication.protocol.OperationContext;
import org.opends.server.types.Attribute;
import org.opends.server.types.AttributeType;
import org.opends.server.types.Attributes;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.Entry;
import org.opends.server.types.Modification;
import org.opends.server.types.operation.PreOperationModifyOperation;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
* Tests the single valued attribute conflict resolution (part of modify replay).
*
* It produces series of changes and replay them out of order by generating all possible
* permutations. The goal is to end up in the same final state whatever the order.
*
* The tests are built this way:
*
*
Start from an entry without (resp. with) an initial value for the targeted single valued
* attribute
*
Replay a "seed" modify operation, that happened at time t1
*
Then replay any of all the possible operations that could come after, that happened at time
* t2
*
* All permutations for these sequence of operations are tested.
*
* The test finally asserts the {@code ds-sync-hist} attribute always end in the same state whatever
* the permutation.
*/
@SuppressWarnings("javadoc")
public class ModifyReplayTest extends ReplicationTestCase
{
private static final String ATTRIBUTE_NAME = "displayName";
private static final String SYNCHIST = "ds-sync-hist";
private Entry entry;
private static class Mod
{
private final int time;
private final Modification modification;
private Mod(ModificationType modType, int t)
{
this(modType, null, t);
}
private Mod(ModificationType modType, String value, int t)
{
this.modification = newModification(modType, value);
this.time = t;
}
private PreOperationModifyOperation toOperation()
{
final ModifyContext value = new ModifyContext(new CSN(0, time, 0), null);
PreOperationModifyOperation op = mock(PreOperationModifyOperation.class);
when(op.getModifications()).thenReturn(newArrayList(modification));
when(op.getAttachment(eq(OperationContext.SYNCHROCONTEXT))).thenReturn(value);
return op;
}
/** Implemented to get a nice display for each tests in Eclipse UI. */
@Override
public String toString()
{
String modType = modification.getModificationType().toString().toUpperCase();
Iterator it = modification.getAttribute().iterator();
String attrValue = it.hasNext() ? "\"" + it.next().toString() + "\" " : "";
return modType + " " + attrValue + "t" + time;
}
}
private static Object[][] generatePermutations(Object[][] scenarios)
{
List