<name>policy-validator-registry</name>
</policy-validator-registry>
- <renderer-name>ios-xe</renderer-name>
+ <renderer-name>ios-xe-renderer</renderer-name>
</module>
</modules>
</data>
package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.manager;
-import com.google.common.util.concurrent.ListenableFuture;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
+import com.google.common.util.concurrent.ListenableFuture;
+
/**
* Purpose: general policy manager prescription
*/
* synchronize given configuration with device
* @param dataBefore
* @param dataAfter
+ * @param version version needed to by apply
*/
- ListenableFuture<Boolean> syncPolicy(Configuration dataBefore, Configuration dataAfter);
+ ListenableFuture<Boolean> syncPolicy(Configuration dataBefore, Configuration dataAfter, long version);
@Override
void close();
package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.listener;
import com.google.common.base.Preconditions;
-import java.util.Collection;
-import javax.annotation.Nonnull;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.RendererKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.annotation.Nonnull;
+import java.util.Collection;
+import java.util.Optional;
+
/**
* Purpose: process changes of configured renderer policies
*/
final RendererPolicy dataBefore = rootNode.getDataBefore();
final RendererPolicy dataAfter = rootNode.getDataAfter();
- if (dataAfter != null && dataBefore == null) {
- policyManager.syncPolicy(dataAfter.getConfiguration(), null);
- }
- else if (dataAfter == null && dataBefore != null) {
- policyManager.syncPolicy(null, dataBefore.getConfiguration());
+ // Policy configuration
+ Configuration oldConfig = null;
+ Configuration newConfig = null;
+ long version = 0;
+ if (dataBefore != null) {
+ oldConfig = dataBefore.getConfiguration();
}
- else if (dataAfter != null) {
- policyManager.syncPolicy(dataAfter.getConfiguration(), dataBefore.getConfiguration());
+ if (dataAfter != null) {
+ newConfig = dataAfter.getConfiguration();
+ if (dataAfter.getVersion() != null) {
+ version = dataAfter.getVersion();
+ }
}
+ policyManager.syncPolicy(newConfig, oldConfig, version);
}
}
package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
+import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Create;
+import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Delete;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.manager.PolicyManager;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.RendererKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicyBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Create;
-import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Delete;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
public class PolicyManagerImpl implements PolicyManager {
}
@Override
- public ListenableFuture<Boolean> syncPolicy(final Configuration dataAfter, final Configuration dataBefore) {
+ public ListenableFuture<Boolean> syncPolicy(final Configuration dataAfter, final Configuration dataBefore,
+ long version) {
+ ListenableFuture<Boolean> result = Futures.immediateFuture(false);
if (dataBefore == null && dataAfter != null) {
- return createPolicy(dataAfter);
- }
- if (dataBefore != null && dataAfter != null) {
- return updatePolicy(dataAfter, dataBefore);
+ result = syncPolicy(dataAfter, Create);
+ } else if (dataBefore != null && dataAfter != null) {
+ // TODO implement
+ return Futures.immediateFuture(false);
+ } else if (dataBefore != null) {
+ result = syncPolicy(dataBefore, Delete);
}
- if (dataBefore != null) {
- return deletePolicy(dataBefore);
- }
- return Futures.immediateFuture(false);
+ reportVersion(version);
+ return result;
}
private ListenableFuture<Boolean> syncPolicy(final Configuration dataAfter, DsAction action) {
return Futures.immediateFuture(false);
}
- private ListenableFuture<Boolean> createPolicy(Configuration data) {
- return syncPolicy(data, Create);
- }
-
- private ListenableFuture<Boolean> deletePolicy(Configuration data) {
- return syncPolicy(data, Delete);
- }
-
- private ListenableFuture<Boolean> updatePolicy(Configuration dataAfter, Configuration dataBefore) {
- // TODO implement
- return null;
+ private void reportVersion(long version) {
+ WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
+ InstanceIdentifier<RendererPolicy> iid = InstanceIdentifier.create(Renderers.class)
+ .child(Renderer.class, new RendererKey(NodeManager.iosXeRenderer))
+ .child(RendererPolicy.class);
+ wtx.merge(LogicalDatastoreType.OPERATIONAL, iid, new RendererPolicyBuilder().setVersion(version).build());
+ wtx.submit();
}
@Override
package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.Callable;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BinaryOperator;
+
import org.apache.commons.lang3.tuple.MutablePair;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.manager.PolicyManager;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+
/**
* Purpose: wrap {@link PolicyManager} with state compression mechanism
*/
}
@Override
- public ListenableFuture<Boolean> syncPolicy(final Configuration dataBefore, final Configuration dataAfter) {
+ public ListenableFuture<Boolean> syncPolicy(final Configuration dataBefore, final Configuration dataAfter, final long version) {
LOG.trace("firing configuration zip");
// add config to zipping storage
final ConfigPairBox configPair = new ConfigPairBox(dataBefore, dataAfter);
public ListenableFuture<Boolean> call() throws Exception {
final ConfigPairBox configPairBox = configPairKeeper.getAndSet(null);
LOG.debug("delegating policy configuration");
- return delegate.syncPolicy(configPairBox.getLeft(), configPair.getRight());
+ return delegate.syncPolicy(configPairBox.getLeft(), configPair.getRight(), version);
}
}));
} else {
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
public class PolicyWriter {
}
}
+ CheckedFuture<Void, TransactionCommitFailedException> submitFuture = null;
try {
- CheckedFuture<Void, TransactionCommitFailedException> submitFuture = wtx.submit();
- submitFuture.checkedGet();
- // Clear cache
+ submitFuture = wtx.submit();
+ submitFuture.checkedGet(2, TimeUnit.SECONDS);
+ LOG.trace("configuration pushed to device: {}", submitFuture);
} catch (TransactionCommitFailedException e) {
LOG.error("Write transaction failed to {}", e.getMessage());
+ } catch (TimeoutException e) {
+ LOG.warn("Write transaction timed out: {}", submitFuture, e);
} catch (Exception e) {
LOG.error("Failed to .. {}", e.getMessage());
}
LOG.info("Local forwarder removed from node {}", nodeId.getValue());
}
+ CheckedFuture<Void, TransactionCommitFailedException> submitFuture = null;
try {
- CheckedFuture<Void, TransactionCommitFailedException> submitFuture = wtx.submit();
- submitFuture.checkedGet();
+ submitFuture = wtx.submit();
+ submitFuture.checkedGet(2, TimeUnit.SECONDS);
} catch (TransactionCommitFailedException e) {
LOG.error("Write transaction failed to {}", e.getMessage());
+ } catch (TimeoutException e) {
+ LOG.warn("Write transaction timed out: {}", submitFuture, e);
} catch (Exception e) {
LOG.error("Failed to .. {}", e.getMessage());
}
package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.listener;
import java.util.Collections;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
.build()))
.build())
.build())
+ .setVersion((long) order)
+ .build();
+ }
+
+ private RendererPolicy createVersion(final int order) {
+ return new RendererPolicyBuilder()
+ .setVersion((long) order)
.build();
}
Mockito.when(dataTreeModification.getRootNode()).thenReturn(rootNode);
listener.onDataTreeChanged(Collections.singleton(dataTreeModification));
- Mockito.verify(policyManager).syncPolicy(policy1.getConfiguration(), null);
+ Mockito.verify(policyManager).syncPolicy(policy1.getConfiguration(), null, 0);
}
@Test
Mockito.when(dataTreeModification.getRootNode()).thenReturn(rootNode);
listener.onDataTreeChanged(Collections.singleton(dataTreeModification));
- Mockito.verify(policyManager).syncPolicy(policy2.getConfiguration(), policy1.getConfiguration());
+ Mockito.verify(policyManager).syncPolicy(policy2.getConfiguration(), policy1.getConfiguration(), 1);
}
@Test
public void testOnDataTreeChanged_remove() throws Exception {
Mockito.when(rootNode.getDataBefore()).thenReturn(policy2);
- Mockito.when(rootNode.getDataAfter()).thenReturn(null);
+ Mockito.when(rootNode.getDataAfter()).thenReturn(createVersion(1));
Mockito.when(rootNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
Mockito.when(dataTreeModification.getRootNode()).thenReturn(rootNode);
listener.onDataTreeChanged(Collections.singleton(dataTreeModification));
- Mockito.verify(policyManager).syncPolicy(null, policy2.getConfiguration());
+ Mockito.verify(policyManager).syncPolicy(null, policy2.getConfiguration(), 1);
}
@Test
package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
-import com.google.common.util.concurrent.ListenableFuture;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction.Out;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation.PROVIDER;
+import static org.powermock.api.support.membermodification.MemberMatcher.method;
+import static org.powermock.api.support.membermodification.MemberModifier.stub;
+
+import java.util.Collections;
+import java.util.List;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.RendererPolicyUtil;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.ServiceChainingUtil;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriter;
import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.RspName;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfName;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
-import java.util.Collections;
-import java.util.List;
-
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction.Out;
-import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation.PROVIDER;
-import static org.powermock.api.support.membermodification.MemberMatcher.method;
-import static org.powermock.api.support.membermodification.MemberModifier.stub;
+import com.google.common.util.concurrent.ListenableFuture;
@RunWith(PowerMockRunner.class)
@PrepareForTest({RendererPolicyUtil.class, PolicyManagerUtil.class, SfcProviderServiceForwarderAPI.class})
@Test
public void testSyncPolicy_emptyConfiguration() throws Exception {
Configuration policyConfiguration = createTestConfiguration(null, null, null, null);
- ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null);
+ ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null, 0);
assertTrue((boolean) result.get());
}
RendererEndpoint rendererEndpoint = createRendererEndpoint(contextId_1, contextId_2, null);
Configuration policyConfiguration = createTestConfiguration(null, Collections.singletonList(rendererEndpoint),
null, null);
- ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null);
+ ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null, 0);
assertTrue((boolean) result.get());
}
stub(method(RendererPolicyUtil.class, "lookupEndpoint")).toReturn(lookupEndpoint);
when(nodeManager.getNodeMountPoint(eq(createMountpointIid()))).thenReturn(null);
- ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null);
+ ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null, 0);
assertTrue((boolean) result.get());
}
when(nodeManager.getNodeIdByMountpointIid(eq(createMountpointIid()))).thenReturn(nodeId);
when(nodeManager.getNodeManagementIpByMountPointIid(eq(createMountpointIid()))).thenReturn(ipAddress);
- ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null);
+ ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null, 0);
assertTrue((boolean) result.get());
}
when(nodeManager.getNodeIdByMountpointIid(eq(createMountpointIid()))).thenReturn(nodeId);
when(nodeManager.getNodeManagementIpByMountPointIid(eq(createMountpointIid()))).thenReturn(ipAddress);
- ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null);
+ ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null, 0);
assertTrue((boolean) result.get());
}
when(nodeManager.getNodeIdByMountpointIid(eq(createMountpointIid()))).thenReturn(nodeId);
when(nodeManager.getNodeManagementIpByMountPointIid(eq(createMountpointIid()))).thenReturn(ipAddress);
- ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null);
+ ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null, 0);
assertTrue((boolean) result.get());
}
when(nodeManager.getNodeIdByMountpointIid(eq(createMountpointIid()))).thenReturn(nodeId);
when(nodeManager.getNodeManagementIpByMountPointIid(eq(createMountpointIid()))).thenReturn(ipAddress);
- ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null);
+ ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null, 0);
assertTrue((boolean) result.get());
}
stub(method(SfcProviderServiceForwarderAPI.class, "readServiceFunctionForwarder"))
.toReturn(serviceFunctionForwarder);
- ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null);
+ ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null, 0);
assertTrue((boolean) result.get());
}
package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.manager.PolicyManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Matcher;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.ConfigurationBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
/**
* Test for {@link PolicyManagerZipImpl}.
*/
@Test
public void testSyncPolicy_add() throws Exception {
- policyManager.syncPolicy(null, configAfter);
+ policyManager.syncPolicy(null, configAfter, 0);
policyManager.close();
- Mockito.verify(delegate).syncPolicy(null, configAfter);
+ Mockito.verify(delegate).syncPolicy(null, configAfter, 0);
}
@Test
public void testSyncPolicy_update() throws Exception {
- policyManager.syncPolicy(configBefore, configAfter);
+ policyManager.syncPolicy(configBefore, configAfter, 0);
policyManager.close();
- Mockito.verify(delegate).syncPolicy(configBefore, configAfter);
+ Mockito.verify(delegate).syncPolicy(configBefore, configAfter, 0);
}
@Test
public void testSyncPolicy_remove() throws Exception {
- policyManager.syncPolicy(configBefore, null);
+ policyManager.syncPolicy(configBefore, null, 0);
policyManager.close();
- Mockito.verify(delegate).syncPolicy(configBefore, null);
+ Mockito.verify(delegate).syncPolicy(configBefore, null, 0);
}
@Test
final CountDownLatch latchForFirst = new CountDownLatch(1);
final CountDownLatch latchForOthers = new CountDownLatch(1);
- Mockito.when(delegate.syncPolicy(Matchers.<Configuration>any(), Matchers.<Configuration>any()))
+ Mockito.when(delegate.syncPolicy(Matchers.<Configuration>any(), Matchers.<Configuration>any(), Matchers.anyLong()))
.thenAnswer(new Answer<ListenableFuture<Boolean>>() {
@Override
public ListenableFuture<Boolean> answer(final InvocationOnMock invocationOnMock) throws Throwable {
.thenReturn(Futures.immediateFuture(true));
final List<ListenableFuture<Boolean>> allResults = new ArrayList<>();
- allResults.add(policyManager.syncPolicy(null, configBefore));
+ allResults.add(policyManager.syncPolicy(null, configBefore, 0));
latchForOthers.await(1, TimeUnit.SECONDS);
- allResults.add(policyManager.syncPolicy(configBefore, configAfter));
- allResults.add(policyManager.syncPolicy(configAfter, null));
- allResults.add(policyManager.syncPolicy(null, configAfter2));
+ allResults.add(policyManager.syncPolicy(configBefore, configAfter, 0));
+ allResults.add(policyManager.syncPolicy(configAfter, null, 0));
+ allResults.add(policyManager.syncPolicy(null, configAfter2, 0));
latchForFirst.countDown();
Futures.allAsList(allResults).get(1, TimeUnit.SECONDS);
LOG.info("all configs finished");
policyManager.close();
final InOrder inOrder = Mockito.inOrder(delegate);
- inOrder.verify(delegate).syncPolicy(null, configBefore);
- inOrder.verify(delegate).syncPolicy(configBefore, configAfter2);
+ inOrder.verify(delegate).syncPolicy(null, configBefore, 0);
+ inOrder.verify(delegate).syncPolicy(configBefore, configAfter2, 0);
}
}
\ No newline at end of file