blob: 65251dd52d465d3bfc84c467faf0cc262ff3e812 [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2015-present 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
Pier Ventreffe88d62016-10-13 14:34:40 -070018import com.google.common.collect.ImmutableSet;
Ray Milkeyc0fa4db2014-10-17 08:49:54 -070019import org.hamcrest.Matchers;
Ray Milkey40f50b92014-11-07 13:25:53 -080020import org.junit.Test;
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -070021import org.onlab.util.Bandwidth;
Brian O'Connorabafb502014-12-02 22:26:20 -080022import org.onosproject.TestApplicationId;
23import org.onosproject.core.ApplicationId;
24import org.onosproject.net.ConnectPoint;
Pier Ventreffe88d62016-10-13 14:34:40 -070025import org.onosproject.net.FilteredConnectPoint;
Brian O'Connorabafb502014-12-02 22:26:20 -080026import org.onosproject.net.Link;
Brian O'Connorabafb502014-12-02 22:26:20 -080027import org.onosproject.net.flow.TrafficSelector;
28import org.onosproject.net.flow.TrafficTreatment;
29import org.onosproject.net.intent.AbstractIntentTest;
Sho SHIMIZU0e738802015-02-20 10:23:28 -080030import org.onosproject.net.intent.Constraint;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.net.intent.Intent;
32import org.onosproject.net.intent.IntentTestsMocks;
Pier Ventreffe88d62016-10-13 14:34:40 -070033import org.onosproject.net.intent.LinkCollectionIntent;
Brian O'Connorabafb502014-12-02 22:26:20 -080034import org.onosproject.net.intent.PointToPointIntent;
Sho SHIMIZU0e738802015-02-20 10:23:28 -080035import org.onosproject.net.intent.constraint.BandwidthConstraint;
Sho SHIMIZU6c28f832015-02-20 16:12:19 -080036import org.onosproject.net.intent.impl.PathNotFoundException;
Sho SHIMIZUe18cb122016-02-22 21:04:56 -080037import org.onosproject.net.resource.ResourceService;
Ray Milkeyc0fa4db2014-10-17 08:49:54 -070038
Sho SHIMIZU98ffca82015-05-11 08:39:24 -070039import java.util.Collections;
Thomas Vachuskab97cf282014-10-20 23:31:12 -070040import java.util.List;
Pier Ventreffe88d62016-10-13 14:34:40 -070041import java.util.Set;
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -070042import java.util.stream.Collectors;
Thomas Vachuskab97cf282014-10-20 23:31:12 -070043
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;
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -070047import static org.hamcrest.Matchers.everyItem;
Ray Milkeyc0fa4db2014-10-17 08:49:54 -070048import static org.hamcrest.Matchers.hasSize;
49import static org.hamcrest.Matchers.is;
Sho SHIMIZU0e738802015-02-20 10:23:28 -080050import static org.junit.Assert.fail;
Brian O'Connorabafb502014-12-02 22:26:20 -080051import 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)
Pier Ventreffe88d62016-10-13 14:34:40 -070080 .filteredIngressPoint(new FilteredConnectPoint(connectPoint(ingressIdString, 1)))
81 .filteredEgressPoint(new FilteredConnectPoint(connectPoint(egressIdString, 1)))
Ray Milkey3e3ec5f2015-03-17 17:00:38 -070082 .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)
Pier Ventreffe88d62016-10-13 14:34:40 -070099 .filteredIngressPoint(new FilteredConnectPoint(connectPoint(ingressIdString, 1)))
100 .filteredEgressPoint(new FilteredConnectPoint(connectPoint(egressIdString, 1)))
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700101 .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 SHIMIZUb1681bd2016-02-22 12:47:50 -0800124 private PointToPointIntentCompiler makeCompiler(String[] hops, ResourceService 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
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800142 List<Intent> result = compiler.compile(intent, 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);
Pier Ventreffe88d62016-10-13 14:34:40 -0700146 assertThat(forwardResultIntent instanceof LinkCollectionIntent, is(true));
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700147
Pier Ventreffe88d62016-10-13 14:34:40 -0700148 if (forwardResultIntent instanceof LinkCollectionIntent) {
149 LinkCollectionIntent forwardIntent = (LinkCollectionIntent) forwardResultIntent;
150 FilteredConnectPoint ingressPoint = new FilteredConnectPoint(connectPoint("d1", 1));
151 FilteredConnectPoint egressPoint = new FilteredConnectPoint(connectPoint("d8", 1));
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700152 // 7 links for the hops, plus one default lnk on ingress and egress
Pier Ventreffe88d62016-10-13 14:34:40 -0700153 assertThat(forwardIntent.links(), hasSize(hops.length - 1));
154 assertThat(forwardIntent.links(), linksHasPath("d1", "d2"));
155 assertThat(forwardIntent.links(), linksHasPath("d2", "d3"));
156 assertThat(forwardIntent.links(), linksHasPath("d3", "d4"));
157 assertThat(forwardIntent.links(), linksHasPath("d4", "d5"));
158 assertThat(forwardIntent.links(), linksHasPath("d5", "d6"));
159 assertThat(forwardIntent.links(), linksHasPath("d6", "d7"));
160 assertThat(forwardIntent.links(), linksHasPath("d7", "d8"));
161 assertThat(forwardIntent.filteredIngressPoints(), is(ImmutableSet.of(ingressPoint)));
162 assertThat(forwardIntent.filteredEgressPoints(), is(ImmutableSet.of(egressPoint)));
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700163 }
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -0700164 assertThat("key is inherited", forwardResultIntent.key(), is(intent.key()));
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700165 }
166
167 /**
168 * Tests a pair of devices in an 8 hop path, forward direction.
169 */
Ray Milkey40f50b92014-11-07 13:25:53 -0800170 @Test
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700171 public void testReversePathCompilation() {
172
173 PointToPointIntent intent = makeIntent("d8", "d1");
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700174
175 String[] hops = {"d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8"};
176 PointToPointIntentCompiler compiler = makeCompiler(hops);
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700177
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800178 List<Intent> result = compiler.compile(intent, null);
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700179 assertThat(result, is(Matchers.notNullValue()));
180 assertThat(result, hasSize(1));
181 Intent reverseResultIntent = result.get(0);
Pier Ventreffe88d62016-10-13 14:34:40 -0700182 assertThat(reverseResultIntent instanceof LinkCollectionIntent, is(true));
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700183
Pier Ventreffe88d62016-10-13 14:34:40 -0700184 if (reverseResultIntent instanceof LinkCollectionIntent) {
185 LinkCollectionIntent reverseLinkCollectionIntent = (LinkCollectionIntent) reverseResultIntent;
186 FilteredConnectPoint egressPoint = new FilteredConnectPoint(connectPoint("d1", 1));
187 FilteredConnectPoint ingressPoint = new FilteredConnectPoint(connectPoint("d8", 1));
188 assertThat(reverseLinkCollectionIntent.links(), hasSize(hops.length - 1));
189 assertThat(reverseLinkCollectionIntent.links(), linksHasPath("d2", "d1"));
190 assertThat(reverseLinkCollectionIntent.links(), linksHasPath("d3", "d2"));
191 assertThat(reverseLinkCollectionIntent.links(), linksHasPath("d4", "d3"));
192 assertThat(reverseLinkCollectionIntent.links(), linksHasPath("d5", "d4"));
193 assertThat(reverseLinkCollectionIntent.links(), linksHasPath("d6", "d5"));
194 assertThat(reverseLinkCollectionIntent.links(), linksHasPath("d7", "d6"));
195 assertThat(reverseLinkCollectionIntent.links(), linksHasPath("d8", "d7"));
196 assertThat(reverseLinkCollectionIntent.filteredIngressPoints(), is(ImmutableSet.of(ingressPoint)));
197 assertThat(reverseLinkCollectionIntent.filteredEgressPoints(), is(ImmutableSet.of(egressPoint)));
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700198 }
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -0700199 assertThat("key is inherited", reverseResultIntent.key(), is(intent.key()));
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700200 }
Sho SHIMIZUde8e6b52014-11-13 11:23:17 -0800201
202 /**
203 * Tests compilation of the intent which designates two different ports on the same switch.
204 */
205 @Test
206 public void testSameSwitchDifferentPortsIntentCompilation() {
Pier Ventreffe88d62016-10-13 14:34:40 -0700207 FilteredConnectPoint src = new FilteredConnectPoint(new ConnectPoint(deviceId("1"), portNumber(1)));
208 FilteredConnectPoint dst = new FilteredConnectPoint(new ConnectPoint(deviceId("1"), portNumber(2)));
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700209 PointToPointIntent intent = PointToPointIntent.builder()
210 .appId(APP_ID)
211 .selector(selector)
212 .treatment(treatment)
Pier Ventreffe88d62016-10-13 14:34:40 -0700213 .filteredIngressPoint(src)
214 .filteredEgressPoint(dst)
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700215 .build();
Sho SHIMIZUde8e6b52014-11-13 11:23:17 -0800216
217 String[] hops = {"1"};
218 PointToPointIntentCompiler sut = makeCompiler(hops);
219
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800220 List<Intent> compiled = sut.compile(intent, null);
Sho SHIMIZUde8e6b52014-11-13 11:23:17 -0800221
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -0700222 assertThat("key is inherited",
223 compiled.stream().map(Intent::key).collect(Collectors.toList()),
224 everyItem(is(intent.key())));
225
Sho SHIMIZUde8e6b52014-11-13 11:23:17 -0800226 assertThat(compiled, hasSize(1));
Pier Ventreffe88d62016-10-13 14:34:40 -0700227 assertThat(compiled.get(0), is(instanceOf(LinkCollectionIntent.class)));
228 LinkCollectionIntent linkCollectionIntent = (LinkCollectionIntent) compiled.get(0);
229 Set<Link> links = linkCollectionIntent.links();
Sho SHIMIZUde8e6b52014-11-13 11:23:17 -0800230
Pier Ventreffe88d62016-10-13 14:34:40 -0700231 assertThat(links, hasSize(0));
232 assertThat(linkCollectionIntent.filteredIngressPoints(), is(ImmutableSet.of(src)));
233 assertThat(linkCollectionIntent.filteredEgressPoints(), is(ImmutableSet.of(dst)));
Sho SHIMIZUde8e6b52014-11-13 11:23:17 -0800234 }
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800235
236 /**
237 * Tests that requests with sufficient available bandwidth succeed.
238 */
239 @Test
240 public void testBandwidthConstrainedIntentSuccess() {
241
Sho SHIMIZUb1681bd2016-02-22 12:47:50 -0800242 final ResourceService resourceService =
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800243 IntentTestsMocks.MockResourceService.makeBandwidthResourceService(1000.0);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700244 final List<Constraint> constraints =
Sho SHIMIZUa88db492015-11-23 13:21:04 -0800245 Collections.singletonList(new BandwidthConstraint(Bandwidth.bps(100.0)));
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800246
Sho SHIMIZUb7052172015-02-20 11:09:21 -0800247 final PointToPointIntent intent = makeIntent("s1", "s3", constraints);
248
249 String[] hops = {"s1", "s2", "s3"};
250 final PointToPointIntentCompiler compiler = makeCompiler(hops, resourceService);
251
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800252 final List<Intent> compiledIntents = compiler.compile(intent, null);
Sho SHIMIZUb7052172015-02-20 11:09:21 -0800253
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800254 assertThat(compiledIntents, Matchers.notNullValue());
255 assertThat(compiledIntents, hasSize(1));
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -0700256
257 assertThat("key is inherited",
258 compiledIntents.stream().map(Intent::key).collect(Collectors.toList()),
259 everyItem(is(intent.key())));
260
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800261 }
262
263 /**
264 * Tests that requests with insufficient available bandwidth fail.
265 */
266 @Test
267 public void testBandwidthConstrainedIntentFailure() {
268
Sho SHIMIZUb1681bd2016-02-22 12:47:50 -0800269 final ResourceService resourceService =
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800270 IntentTestsMocks.MockResourceService.makeBandwidthResourceService(10.0);
Sho SHIMIZU98ffca82015-05-11 08:39:24 -0700271 final List<Constraint> constraints =
Sho SHIMIZUa88db492015-11-23 13:21:04 -0800272 Collections.singletonList(new BandwidthConstraint(Bandwidth.bps(100.0)));
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800273
274 try {
Sho SHIMIZUb7052172015-02-20 11:09:21 -0800275 final PointToPointIntent intent = makeIntent("s1", "s3", constraints);
276
277 String[] hops = {"s1", "s2", "s3"};
278 final PointToPointIntentCompiler compiler = makeCompiler(hops, resourceService);
279
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800280 compiler.compile(intent, null);
Sho SHIMIZUb7052172015-02-20 11:09:21 -0800281
Sho SHIMIZU0e738802015-02-20 10:23:28 -0800282 fail("Point to Point compilation with insufficient bandwidth does "
283 + "not throw exception.");
284 } catch (PathNotFoundException noPath) {
285 assertThat(noPath.getMessage(), containsString("No path"));
286 }
287 }
Ray Milkeyc0fa4db2014-10-17 08:49:54 -0700288}