blob: 4cc90532e60e84aa58fe874daec9d3a1986e654c [file] [log] [blame]
Pavlin Radoslavovdde22ae2014-11-24 11:47:17 -08001package org.onlab.onos.sdnip;
2
3import java.util.LinkedList;
4import java.util.List;
5
6import org.apache.commons.collections4.CollectionUtils;
7import org.easymock.IArgumentMatcher;
8import org.onlab.onos.net.intent.IntentId;
9import org.onlab.onos.net.intent.IntentOperation;
10import org.onlab.onos.net.intent.IntentOperations;
11import org.onlab.onos.net.intent.PointToPointIntent;
12import org.onlab.onos.sdnip.IntentSynchronizer.IntentKey;
13
14import static org.easymock.EasyMock.reportMatcher;
15
16/**
17 * Helper class for testing operations submitted to the IntentService.
18 */
19public final class TestIntentServiceHelper {
20 /**
21 * Default constructor to prevent instantiation.
22 */
23 private TestIntentServiceHelper() {
24 }
25
26 /**
27 * Matcher method to set the expected intent operations to match against
28 * (ignoring the intent ID for each intent).
29 *
30 * @param intentOperations the expected Intent Operations
31 * @return the submitted Intent Operations
32 */
33 static IntentOperations eqExceptId(IntentOperations intentOperations) {
34 reportMatcher(new IdAgnosticIntentOperationsMatcher(intentOperations));
35 return intentOperations;
36 }
37
38
39 /**
40 * Matcher method to set an expected point-to-point intent to match
41 * against (ignoring the intent ID).
42 *
43 * @param intent the expected point-to-point intent
44 * @return the submitted point-to-point intent
45 */
46 private static PointToPointIntent eqExceptId(
47 PointToPointIntent intent) {
48 reportMatcher(new IdAgnosticPointToPointIntentMatcher(intent));
49 return intent;
50 }
51
52 /*
53 * EasyMock matcher that matches {@link IntenOperations} but
54 * ignores the {@link IntentId} when matching.
55 * <p/>
56 * The normal intent equals method tests that the intent IDs are equal,
57 * however in these tests we can't know what the intent IDs will be in
58 * advance, so we can't set up expected intents with the correct IDs. Thus,
59 * the solution is to use an EasyMock matcher that verifies that all the
60 * value properties of the provided intent match the expected values, but
61 * ignores the intent ID when testing equality.
62 */
63 private static final class IdAgnosticIntentOperationsMatcher implements
64 IArgumentMatcher {
65
66 private final IntentOperations intentOperations;
67 private String providedString;
68
69 /**
70 * Constructor taking the expected intent operations to match against.
71 *
72 * @param intentOperations the expected intent operations
73 */
74 public IdAgnosticIntentOperationsMatcher(
75 IntentOperations intentOperations) {
76 this.intentOperations = intentOperations;
77 }
78
79 @Override
80 public void appendTo(StringBuffer strBuffer) {
81 strBuffer.append("IntentOperationsMatcher unable to match: "
82 + providedString);
83 }
84
85 @Override
86 public boolean matches(Object object) {
87 if (!(object instanceof IntentOperations)) {
88 return false;
89 }
90
91 IntentOperations providedIntentOperations =
92 (IntentOperations) object;
93 providedString = providedIntentOperations.toString();
94
95 List<IntentKey> thisSubmitIntents = new LinkedList<>();
96 List<IntentId> thisWithdrawIntentIds = new LinkedList<>();
97 List<IntentKey> thisReplaceIntents = new LinkedList<>();
98 List<IntentKey> thisUpdateIntents = new LinkedList<>();
99 List<IntentKey> providedSubmitIntents = new LinkedList<>();
100 List<IntentId> providedWithdrawIntentIds = new LinkedList<>();
101 List<IntentKey> providedReplaceIntents = new LinkedList<>();
102 List<IntentKey> providedUpdateIntents = new LinkedList<>();
103
104 extractIntents(intentOperations, thisSubmitIntents,
105 thisWithdrawIntentIds, thisReplaceIntents,
106 thisUpdateIntents);
107 extractIntents(providedIntentOperations, providedSubmitIntents,
108 providedWithdrawIntentIds, providedReplaceIntents,
109 providedUpdateIntents);
110
111 return CollectionUtils.isEqualCollection(thisSubmitIntents,
112 providedSubmitIntents) &&
113 CollectionUtils.isEqualCollection(thisWithdrawIntentIds,
114 providedWithdrawIntentIds) &&
115 CollectionUtils.isEqualCollection(thisUpdateIntents,
116 providedUpdateIntents) &&
117 CollectionUtils.isEqualCollection(thisReplaceIntents,
118 providedReplaceIntents);
119 }
120
121 /**
122 * Extracts the intents per operation type. Each intent is encapsulated
123 * in IntentKey so it can be compared by excluding the Intent ID.
124 *
125 * @param intentOperations the container with the intent operations
126 * to extract the intents from
127 * @param submitIntents the SUBMIT intents
128 * @param withdrawIntentIds the WITHDRAW intents IDs
129 * @param replaceIntents the REPLACE intents
130 * @param updateIntents the UPDATE intens
131 */
132 private void extractIntents(IntentOperations intentOperations,
133 List<IntentKey> submitIntents,
134 List<IntentId> withdrawIntentIds,
135 List<IntentKey> replaceIntents,
136 List<IntentKey> updateIntents) {
137 for (IntentOperation oper : intentOperations.operations()) {
138 IntentId intentId;
139 IntentKey intentKey;
140 switch (oper.type()) {
141 case SUBMIT:
142 intentKey = new IntentKey(oper.intent());
143 submitIntents.add(intentKey);
144 break;
145 case WITHDRAW:
146 intentId = oper.intentId();
147 withdrawIntentIds.add(intentId);
148 break;
149 case REPLACE:
150 intentKey = new IntentKey(oper.intent());
151 replaceIntents.add(intentKey);
152 break;
153 case UPDATE:
154 intentKey = new IntentKey(oper.intent());
155 updateIntents.add(intentKey);
156 break;
157 default:
158 break;
159 }
160 }
161 }
162 }
163
164 /*
165 * EasyMock matcher that matches {@link PointToPointIntent}s but
166 * ignores the {@link IntentId} when matching.
167 * <p/>
168 * The normal intent equals method tests that the intent IDs are equal,
169 * however in these tests we can't know what the intent IDs will be in
170 * advance, so we can't set up expected intents with the correct IDs. Thus,
171 * the solution is to use an EasyMock matcher that verifies that all the
172 * value properties of the provided intent match the expected values, but
173 * ignores the intent ID when testing equality.
174 */
175 private static final class IdAgnosticPointToPointIntentMatcher implements
176 IArgumentMatcher {
177
178 private final PointToPointIntent intent;
179 private String providedIntentString;
180
181 /**
182 * Constructor taking the expected intent to match against.
183 *
184 * @param intent the expected intent
185 */
186 public IdAgnosticPointToPointIntentMatcher(PointToPointIntent intent) {
187 this.intent = intent;
188 }
189
190 @Override
191 public void appendTo(StringBuffer strBuffer) {
192 strBuffer.append("PointToPointIntentMatcher unable to match: "
193 + providedIntentString);
194 }
195
196 @Override
197 public boolean matches(Object object) {
198 if (!(object instanceof PointToPointIntent)) {
199 return false;
200 }
201
202 PointToPointIntent providedIntent = (PointToPointIntent) object;
203 providedIntentString = providedIntent.toString();
204
205 PointToPointIntent matchIntent =
206 new PointToPointIntent(providedIntent.appId(),
207 intent.selector(), intent.treatment(),
208 intent.ingressPoint(), intent.egressPoint());
209
210 return matchIntent.equals(providedIntent);
211 }
212 }
213}