blob: e57d9dbeeb694e635e47eceb25b71bb20563f4cf [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Sho SHIMIZU6c28f832015-02-20 16:12:19 -080016package org.onosproject.net.intent.impl.compiler;
Ray Milkeyc0fa4db2014-10-17 08:49:54 -070017
Ray Milkeyc0fa4db2014-10-17 08:49:54 -070018import org.hamcrest.Matchers;
Ray Milkey40f50b92014-11-07 13:25:53 -080019import org.junit.Test;
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -070020import org.onlab.util.Bandwidth;
Brian O'Connorabafb502014-12-02 22:26:20 -080021import org.onosproject.TestApplicationId;
22import org.onosproject.core.ApplicationId;
23import org.onosproject.net.ConnectPoint;
24import org.onosproject.net.Link;
25import org.onosproject.net.Path;
26import org.onosproject.net.flow.TrafficSelector;
27import org.onosproject.net.flow.TrafficTreatment;
28import org.onosproject.net.intent.AbstractIntentTest;
Sho SHIMIZU0e738802015-02-20 10:23:28 -080029import org.onosproject.net.intent.Constraint;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.net.intent.Intent;
31import org.onosproject.net.intent.IntentTestsMocks;
32import org.onosproject.net.intent.PathIntent;
33import org.onosproject.net.intent.PointToPointIntent;
Sho SHIMIZU0e738802015-02-20 10:23:28 -080034import org.onosproject.net.intent.constraint.BandwidthConstraint;
35import org.onosproject.net.intent.constraint.LambdaConstraint;
Sho SHIMIZU6c28f832015-02-20 16:12:19 -080036import org.onosproject.net.intent.impl.PathNotFoundException;
Brian O'Connor6de2e202015-05-21 14:30:41 -070037import org.onosproject.net.resource.link.BandwidthResource;
38import org.onosproject.net.resource.link.LambdaResource;
39import org.onosproject.net.resource.link.LinkResourceService;
Ray Milkeyc0fa4db2014-10-17 08:49:54 -070040
Sho SHIMIZU98ffca82015-05-11 08:39:24 -070041import java.util.Collections;
Thomas Vachuskab97cf282014-10-20 23:31:12 -070042import java.util.List;
43
Sho SHIMIZUde8e6b52014-11-13 11:23:17 -080044import static org.hamcrest.CoreMatchers.instanceOf;
Ray Milkeyc0fa4db2014-10-17 08:49:54 -070045import static org.hamcrest.MatcherAssert.assertThat;
Sho SHIMIZU0e738802015-02-20 10:23:28 -080046import static org.hamcrest.Matchers.containsString;
Ray Milkeyc0fa4db2014-10-17 08:49:54 -070047import static org.hamcrest.Matchers.hasSize;
48import static org.hamcrest.Matchers.is;
Sho SHIMIZU0e738802015-02-20 10:23:28 -080049import static org.junit.Assert.fail;
Brian O'Connorabafb502014-12-02 22:26:20 -080050import static org.onosproject.net.DefaultEdgeLink.createEdgeLink;
51import static org.onosproject.net.DeviceId.deviceId;
52import static org.onosproject.net.NetTestTools.APP_ID;
53import static org.onosproject.net.NetTestTools.connectPoint;
54import static org.onosproject.net.PortNumber.portNumber;
55import static org.onosproject.net.intent.LinksHaveEntryWithSourceDestinationPairMatcher.linksHasPath;
Ray Milkeyc0fa4db2014-10-17 08:49:54 -070056
57/**
58 * Unit tests for the HostToHost intent compiler.
59 */
Ray Milkey37f6a382014-11-25 14:54:42 -080060public class PointToPointIntentCompilerTest extends AbstractIntentTest {
Ray Milkeyc0fa4db2014-10-17 08:49:54 -070061
Thomas Vachuskab97cf282014-10-20 23:31:12 -070062 private static final ApplicationId APPID = new TestApplicationId("foo");
63
Ray Milkeyc0fa4db2014-10-17 08:49:54 -070064 private TrafficSelector selector = new IntentTestsMocks.MockSelector();
65 private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment();
66
67 /**
68 * Creates a PointToPoint intent based on ingress and egress device Ids.
69 *
70 * @param ingressIdString string for id of ingress device
Thomas Vachuskab97cf282014-10-20 23:31:12 -070071 * @param egressIdString string for id of egress device
Ray Milkeyc0fa4db2014-10-17 08:49:54 -070072 * @return PointToPointIntent for the two devices
73 */
74 private PointToPointIntent makeIntent(String ingressIdString,
75 String egressIdString) {
Ray Milkey3e3ec5f2015-03-17 17:00:38 -070076 return PointToPointIntent.builder()
77 .appId(APPID)
78 .selector(selector)
79 .treatment(treatment)
80 .ingressPoint(connectPoint(ingressIdString, 1))
81 .egressPoint(connectPoint(egressIdString, 1))
82 .build();
Ray Milkeyc0fa4db2014-10-17 08:49:54 -070083 }
84
85 /**
Sho SHIMIZUb7052172015-02-20 11:09:21 -080086 * Creates a PointToPoint intent based on ingress and egress deviceIds and constraints.
87 *
88 * @param ingressIdString string for id of ingress device
89 * @param egressIdString string for id of egress device
90 * @param constraints constraints
91 * @return PointToPointIntent for the two device with constraints
92 */
93 private PointToPointIntent makeIntent(String ingressIdString,
94 String egressIdString, List<Constraint> constraints) {
Ray Milkey3e3ec5f2015-03-17 17:00:38 -070095 return PointToPointIntent.builder()
96 .appId(APPID)
97 .selector(selector)
98 .treatment(treatment)
99 .ingressPoint(connectPoint(ingressIdString, 1))
100 .egressPoint(connectPoint(egressIdString, 1))
101 .constraints(constraints)
102 .build();
Sho SHIMIZUb7052172015-02-20 11:09:21 -0800103 }
104
105 /**
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700106 * Creates a compiler for HostToHost intents.
107 *
108 * @param hops string array describing the path hops to use when compiling
109 * @return HostToHost intent compiler
110 */
111 private PointToPointIntentCompiler makeCompiler(String[] hops) {
Sho SHIMIZUb7052172015-02-20 11:09:21 -0800112 PointToPointIntentCompiler compiler = new PointToPointIntentCompiler();
Ray Milkey40f50b92014-11-07 13:25:53 -0800113 compiler.pathService = new IntentTestsMocks.MockPathService(hops);
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700114 return compiler;
115 }
116
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800117 /**
118 * Creates a point to point intent compiler for a three switch linear
119 * topology.
120 *
121 * @param resourceService service to use for resource allocation requests
122 * @return point to point compiler
123 */
Sho SHIMIZUb7052172015-02-20 11:09:21 -0800124 private PointToPointIntentCompiler makeCompiler(String[] hops, LinkResourceService resourceService) {
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800125 final PointToPointIntentCompiler compiler = new PointToPointIntentCompiler();
126 compiler.resourceService = resourceService;
127 compiler.pathService = new IntentTestsMocks.MockPathService(hops);
128 return compiler;
129 }
130
131 /**
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700132 * Tests a pair of devices in an 8 hop path, forward direction.
133 */
Ray Milkey40f50b92014-11-07 13:25:53 -0800134 @Test
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700135 public void testForwardPathCompilation() {
136
137 PointToPointIntent intent = makeIntent("d1", "d8");
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700138
139 String[] hops = {"d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8"};
140 PointToPointIntentCompiler compiler = makeCompiler(hops);
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700141
Brian O'Connorfa81eae2014-10-30 13:20:05 -0700142 List<Intent> result = compiler.compile(intent, null, null);
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700143 assertThat(result, is(Matchers.notNullValue()));
144 assertThat(result, hasSize(1));
145 Intent forwardResultIntent = result.get(0);
146 assertThat(forwardResultIntent instanceof PathIntent, is(true));
147
148 if (forwardResultIntent instanceof PathIntent) {
149 PathIntent forwardPathIntent = (PathIntent) forwardResultIntent;
150 // 7 links for the hops, plus one default lnk on ingress and egress
151 assertThat(forwardPathIntent.path().links(), hasSize(hops.length + 1));
152 assertThat(forwardPathIntent.path().links(), linksHasPath("d1", "d2"));
153 assertThat(forwardPathIntent.path().links(), linksHasPath("d2", "d3"));
154 assertThat(forwardPathIntent.path().links(), linksHasPath("d3", "d4"));
155 assertThat(forwardPathIntent.path().links(), linksHasPath("d4", "d5"));
156 assertThat(forwardPathIntent.path().links(), linksHasPath("d5", "d6"));
157 assertThat(forwardPathIntent.path().links(), linksHasPath("d6", "d7"));
158 assertThat(forwardPathIntent.path().links(), linksHasPath("d7", "d8"));
159 }
160 }
161
162 /**
163 * Tests a pair of devices in an 8 hop path, forward direction.
164 */
Ray Milkey40f50b92014-11-07 13:25:53 -0800165 @Test
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700166 public void testReversePathCompilation() {
167
168 PointToPointIntent intent = makeIntent("d8", "d1");
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700169
170 String[] hops = {"d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8"};
171 PointToPointIntentCompiler compiler = makeCompiler(hops);
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700172
Brian O'Connorfa81eae2014-10-30 13:20:05 -0700173 List<Intent> result = compiler.compile(intent, null, null);
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700174 assertThat(result, is(Matchers.notNullValue()));
175 assertThat(result, hasSize(1));
176 Intent reverseResultIntent = result.get(0);
177 assertThat(reverseResultIntent instanceof PathIntent, is(true));
178
179 if (reverseResultIntent instanceof PathIntent) {
180 PathIntent reversePathIntent = (PathIntent) reverseResultIntent;
181 assertThat(reversePathIntent.path().links(), hasSize(hops.length + 1));
182 assertThat(reversePathIntent.path().links(), linksHasPath("d2", "d1"));
183 assertThat(reversePathIntent.path().links(), linksHasPath("d3", "d2"));
184 assertThat(reversePathIntent.path().links(), linksHasPath("d4", "d3"));
185 assertThat(reversePathIntent.path().links(), linksHasPath("d5", "d4"));
186 assertThat(reversePathIntent.path().links(), linksHasPath("d6", "d5"));
187 assertThat(reversePathIntent.path().links(), linksHasPath("d7", "d6"));
188 assertThat(reversePathIntent.path().links(), linksHasPath("d8", "d7"));
189 }
190 }
Sho SHIMIZUde8e6b52014-11-13 11:23:17 -0800191
192 /**
193 * Tests compilation of the intent which designates two different ports on the same switch.
194 */
195 @Test
196 public void testSameSwitchDifferentPortsIntentCompilation() {
197 ConnectPoint src = new ConnectPoint(deviceId("1"), portNumber(1));
198 ConnectPoint dst = new ConnectPoint(deviceId("1"), portNumber(2));
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700199 PointToPointIntent intent = PointToPointIntent.builder()
200 .appId(APP_ID)
201 .selector(selector)
202 .treatment(treatment)
203 .ingressPoint(src)
204 .egressPoint(dst)
205 .build();
Sho SHIMIZUde8e6b52014-11-13 11:23:17 -0800206
207 String[] hops = {"1"};
208 PointToPointIntentCompiler sut = makeCompiler(hops);
209
Brian O'Connorfa81eae2014-10-30 13:20:05 -0700210 List<Intent> compiled = sut.compile(intent, null, null);
Sho SHIMIZUde8e6b52014-11-13 11:23:17 -0800211
212 assertThat(compiled, hasSize(1));
213 assertThat(compiled.get(0), is(instanceOf(PathIntent.class)));
214 Path path = ((PathIntent) compiled.get(0)).path();
215
Sho SHIMIZU3908fde2014-11-19 16:30:22 -0800216 assertThat(path.links(), hasSize(2));
217 Link firstLink = path.links().get(0);
218 assertThat(firstLink, is(createEdgeLink(src, true)));
219 Link secondLink = path.links().get(1);
220 assertThat(secondLink, is(createEdgeLink(dst, false)));
Sho SHIMIZUde8e6b52014-11-13 11:23:17 -0800221 }
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800222
223 /**
224 * Tests that requests with sufficient available bandwidth succeed.
225 */
226 @Test
227 public void testBandwidthConstrainedIntentSuccess() {
228
229 final LinkResourceService resourceService =
230 IntentTestsMocks.MockResourceService.makeBandwidthResourceService(1000.0);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700231 final List<Constraint> constraints =
232 Collections.singletonList(new BandwidthConstraint(new BandwidthResource(Bandwidth.bps(100.0))));
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800233
Sho SHIMIZUb7052172015-02-20 11:09:21 -0800234 final PointToPointIntent intent = makeIntent("s1", "s3", constraints);
235
236 String[] hops = {"s1", "s2", "s3"};
237 final PointToPointIntentCompiler compiler = makeCompiler(hops, resourceService);
238
239 final List<Intent> compiledIntents = compiler.compile(intent, null, null);
240
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800241 assertThat(compiledIntents, Matchers.notNullValue());
242 assertThat(compiledIntents, hasSize(1));
243 }
244
245 /**
246 * Tests that requests with insufficient available bandwidth fail.
247 */
248 @Test
249 public void testBandwidthConstrainedIntentFailure() {
250
251 final LinkResourceService resourceService =
252 IntentTestsMocks.MockResourceService.makeBandwidthResourceService(10.0);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700253 final List<Constraint> constraints =
254 Collections.singletonList(new BandwidthConstraint(new BandwidthResource(Bandwidth.bps(100.0))));
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800255
256 try {
Sho SHIMIZUb7052172015-02-20 11:09:21 -0800257 final PointToPointIntent intent = makeIntent("s1", "s3", constraints);
258
259 String[] hops = {"s1", "s2", "s3"};
260 final PointToPointIntentCompiler compiler = makeCompiler(hops, resourceService);
261
262 compiler.compile(intent, null, null);
263
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800264 fail("Point to Point compilation with insufficient bandwidth does "
265 + "not throw exception.");
266 } catch (PathNotFoundException noPath) {
267 assertThat(noPath.getMessage(), containsString("No path"));
268 }
269 }
270
271 /**
272 * Tests that requests for available lambdas are successful.
273 */
274 @Test
275 public void testLambdaConstrainedIntentSuccess() {
276
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700277 final List<Constraint> constraints =
278 Collections.singletonList(new LambdaConstraint(LambdaResource.valueOf(1)));
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800279 final LinkResourceService resourceService =
280 IntentTestsMocks.MockResourceService.makeLambdaResourceService(1);
281
Sho SHIMIZUb7052172015-02-20 11:09:21 -0800282 final PointToPointIntent intent = makeIntent("s1", "s3", constraints);
283
284 String[] hops = {"s1", "s2", "s3"};
285 final PointToPointIntentCompiler compiler = makeCompiler(hops, resourceService);
286
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800287 final List<Intent> compiledIntents =
Sho SHIMIZUb7052172015-02-20 11:09:21 -0800288 compiler.compile(intent, null, null);
289
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800290 assertThat(compiledIntents, Matchers.notNullValue());
291 assertThat(compiledIntents, hasSize(1));
292 }
293
294 /**
295 * Tests that requests for lambdas when there are no available lambdas
296 * fail.
297 */
298 @Test
299 public void testLambdaConstrainedIntentFailure() {
300
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700301 final List<Constraint> constraints =
302 Collections.singletonList(new LambdaConstraint(LambdaResource.valueOf(1)));
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800303 final LinkResourceService resourceService =
304 IntentTestsMocks.MockResourceService.makeBandwidthResourceService(10.0);
305 try {
Sho SHIMIZUb7052172015-02-20 11:09:21 -0800306 final PointToPointIntent intent = makeIntent("s1", "s3", constraints);
307
308 String[] hops = {"s1", "s2", "s3"};
309 final PointToPointIntentCompiler compiler = makeCompiler(hops, resourceService);
310
311 compiler.compile(intent, null, null);
312
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800313 fail("Point to Point compilation with no available lambda does "
314 + "not throw exception.");
315 } catch (PathNotFoundException noPath) {
316 assertThat(noPath.getMessage(), containsString("No path"));
317 }
318 }
319
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700320}