blob: 4cc90532e60e84aa58fe874daec9d3a1986e654c [file] [log] [blame]
package org.onlab.onos.sdnip;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
import org.easymock.IArgumentMatcher;
import org.onlab.onos.net.intent.IntentId;
import org.onlab.onos.net.intent.IntentOperation;
import org.onlab.onos.net.intent.IntentOperations;
import org.onlab.onos.net.intent.PointToPointIntent;
import org.onlab.onos.sdnip.IntentSynchronizer.IntentKey;
import static org.easymock.EasyMock.reportMatcher;
/**
* Helper class for testing operations submitted to the IntentService.
*/
public final class TestIntentServiceHelper {
/**
* Default constructor to prevent instantiation.
*/
private TestIntentServiceHelper() {
}
/**
* Matcher method to set the expected intent operations to match against
* (ignoring the intent ID for each intent).
*
* @param intentOperations the expected Intent Operations
* @return the submitted Intent Operations
*/
static IntentOperations eqExceptId(IntentOperations intentOperations) {
reportMatcher(new IdAgnosticIntentOperationsMatcher(intentOperations));
return intentOperations;
}
/**
* Matcher method to set an expected point-to-point intent to match
* against (ignoring the intent ID).
*
* @param intent the expected point-to-point intent
* @return the submitted point-to-point intent
*/
private static PointToPointIntent eqExceptId(
PointToPointIntent intent) {
reportMatcher(new IdAgnosticPointToPointIntentMatcher(intent));
return intent;
}
/*
* EasyMock matcher that matches {@link IntenOperations} but
* ignores the {@link IntentId} when matching.
* <p/>
* The normal intent equals method tests that the intent IDs are equal,
* however in these tests we can't know what the intent IDs will be in
* advance, so we can't set up expected intents with the correct IDs. Thus,
* the solution is to use an EasyMock matcher that verifies that all the
* value properties of the provided intent match the expected values, but
* ignores the intent ID when testing equality.
*/
private static final class IdAgnosticIntentOperationsMatcher implements
IArgumentMatcher {
private final IntentOperations intentOperations;
private String providedString;
/**
* Constructor taking the expected intent operations to match against.
*
* @param intentOperations the expected intent operations
*/
public IdAgnosticIntentOperationsMatcher(
IntentOperations intentOperations) {
this.intentOperations = intentOperations;
}
@Override
public void appendTo(StringBuffer strBuffer) {
strBuffer.append("IntentOperationsMatcher unable to match: "
+ providedString);
}
@Override
public boolean matches(Object object) {
if (!(object instanceof IntentOperations)) {
return false;
}
IntentOperations providedIntentOperations =
(IntentOperations) object;
providedString = providedIntentOperations.toString();
List<IntentKey> thisSubmitIntents = new LinkedList<>();
List<IntentId> thisWithdrawIntentIds = new LinkedList<>();
List<IntentKey> thisReplaceIntents = new LinkedList<>();
List<IntentKey> thisUpdateIntents = new LinkedList<>();
List<IntentKey> providedSubmitIntents = new LinkedList<>();
List<IntentId> providedWithdrawIntentIds = new LinkedList<>();
List<IntentKey> providedReplaceIntents = new LinkedList<>();
List<IntentKey> providedUpdateIntents = new LinkedList<>();
extractIntents(intentOperations, thisSubmitIntents,
thisWithdrawIntentIds, thisReplaceIntents,
thisUpdateIntents);
extractIntents(providedIntentOperations, providedSubmitIntents,
providedWithdrawIntentIds, providedReplaceIntents,
providedUpdateIntents);
return CollectionUtils.isEqualCollection(thisSubmitIntents,
providedSubmitIntents) &&
CollectionUtils.isEqualCollection(thisWithdrawIntentIds,
providedWithdrawIntentIds) &&
CollectionUtils.isEqualCollection(thisUpdateIntents,
providedUpdateIntents) &&
CollectionUtils.isEqualCollection(thisReplaceIntents,
providedReplaceIntents);
}
/**
* Extracts the intents per operation type. Each intent is encapsulated
* in IntentKey so it can be compared by excluding the Intent ID.
*
* @param intentOperations the container with the intent operations
* to extract the intents from
* @param submitIntents the SUBMIT intents
* @param withdrawIntentIds the WITHDRAW intents IDs
* @param replaceIntents the REPLACE intents
* @param updateIntents the UPDATE intens
*/
private void extractIntents(IntentOperations intentOperations,
List<IntentKey> submitIntents,
List<IntentId> withdrawIntentIds,
List<IntentKey> replaceIntents,
List<IntentKey> updateIntents) {
for (IntentOperation oper : intentOperations.operations()) {
IntentId intentId;
IntentKey intentKey;
switch (oper.type()) {
case SUBMIT:
intentKey = new IntentKey(oper.intent());
submitIntents.add(intentKey);
break;
case WITHDRAW:
intentId = oper.intentId();
withdrawIntentIds.add(intentId);
break;
case REPLACE:
intentKey = new IntentKey(oper.intent());
replaceIntents.add(intentKey);
break;
case UPDATE:
intentKey = new IntentKey(oper.intent());
updateIntents.add(intentKey);
break;
default:
break;
}
}
}
}
/*
* EasyMock matcher that matches {@link PointToPointIntent}s but
* ignores the {@link IntentId} when matching.
* <p/>
* The normal intent equals method tests that the intent IDs are equal,
* however in these tests we can't know what the intent IDs will be in
* advance, so we can't set up expected intents with the correct IDs. Thus,
* the solution is to use an EasyMock matcher that verifies that all the
* value properties of the provided intent match the expected values, but
* ignores the intent ID when testing equality.
*/
private static final class IdAgnosticPointToPointIntentMatcher implements
IArgumentMatcher {
private final PointToPointIntent intent;
private String providedIntentString;
/**
* Constructor taking the expected intent to match against.
*
* @param intent the expected intent
*/
public IdAgnosticPointToPointIntentMatcher(PointToPointIntent intent) {
this.intent = intent;
}
@Override
public void appendTo(StringBuffer strBuffer) {
strBuffer.append("PointToPointIntentMatcher unable to match: "
+ providedIntentString);
}
@Override
public boolean matches(Object object) {
if (!(object instanceof PointToPointIntent)) {
return false;
}
PointToPointIntent providedIntent = (PointToPointIntent) object;
providedIntentString = providedIntent.toString();
PointToPointIntent matchIntent =
new PointToPointIntent(providedIntent.appId(),
intent.selector(), intent.treatment(),
intent.ingressPoint(), intent.egressPoint());
return matchIntent.equals(providedIntent);
}
}
}