blob: 52c1d118b893920e3708223e5a01fc6b8dcc8970 [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 Milkeye6684082014-10-16 16:59:47 -070017
Pier Ventre98308ab2016-10-12 14:35:05 -070018import com.google.common.collect.ImmutableSet;
Luca Pretede10c782017-01-05 17:23:08 -080019import com.google.common.collect.Lists;
Ray Milkeye6684082014-10-16 16:59:47 -070020import org.hamcrest.Matchers;
21import org.junit.Before;
22import org.junit.Test;
Pier Ventre98308ab2016-10-12 14:35:05 -070023import org.onlab.packet.MacAddress;
24import org.onlab.packet.VlanId;
Luca Pretede10c782017-01-05 17:23:08 -080025import org.onlab.util.Bandwidth;
Brian O'Connorabafb502014-12-02 22:26:20 -080026import org.onosproject.TestApplicationId;
Pier Ventre98308ab2016-10-12 14:35:05 -070027import org.onosproject.core.ApplicationId;
Luca Pretede10c782017-01-05 17:23:08 -080028import org.onosproject.net.ConnectPoint;
29import org.onosproject.net.DeviceId;
Pier Ventre98308ab2016-10-12 14:35:05 -070030import org.onosproject.net.FilteredConnectPoint;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.net.Host;
32import org.onosproject.net.HostId;
Pier Ventre98308ab2016-10-12 14:35:05 -070033import org.onosproject.net.Link;
Luca Pretede10c782017-01-05 17:23:08 -080034import org.onosproject.net.PortNumber;
Brian O'Connorabafb502014-12-02 22:26:20 -080035import org.onosproject.net.flow.TrafficSelector;
36import org.onosproject.net.flow.TrafficTreatment;
37import org.onosproject.net.host.HostService;
38import org.onosproject.net.intent.AbstractIntentTest;
Luca Pretede10c782017-01-05 17:23:08 -080039import org.onosproject.net.intent.Constraint;
Brian O'Connorabafb502014-12-02 22:26:20 -080040import org.onosproject.net.intent.HostToHostIntent;
41import org.onosproject.net.intent.Intent;
42import org.onosproject.net.intent.IntentTestsMocks;
Luca Pretede10c782017-01-05 17:23:08 -080043import org.onosproject.net.intent.Key;
Pier Ventre98308ab2016-10-12 14:35:05 -070044import org.onosproject.net.intent.LinkCollectionIntent;
Luca Pretede10c782017-01-05 17:23:08 -080045import org.onosproject.net.intent.constraint.BandwidthConstraint;
46import org.onosproject.net.resource.ContinuousResource;
Yuta HIGUCHId95d5902016-06-27 00:18:45 -070047import org.onosproject.net.resource.MockResourceService;
Luca Pretede10c782017-01-05 17:23:08 -080048import org.onosproject.net.resource.ResourceAllocation;
49import org.onosproject.net.resource.ResourceService;
50import org.onosproject.net.resource.Resources;
Ray Milkeye6684082014-10-16 16:59:47 -070051
Luca Pretede10c782017-01-05 17:23:08 -080052import java.util.Collections;
Thomas Vachuskab97cf282014-10-20 23:31:12 -070053import java.util.List;
Pier Ventre98308ab2016-10-12 14:35:05 -070054import java.util.Set;
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -070055import java.util.stream.Collectors;
Thomas Vachuskab97cf282014-10-20 23:31:12 -070056
57import static org.easymock.EasyMock.*;
Ray Milkeye6684082014-10-16 16:59:47 -070058import static org.hamcrest.CoreMatchers.notNullValue;
59import static org.hamcrest.MatcherAssert.assertThat;
Luca Pretede10c782017-01-05 17:23:08 -080060import static org.hamcrest.Matchers.*;
61import static org.junit.Assert.assertEquals;
Brian O'Connorabafb502014-12-02 22:26:20 -080062import static org.onosproject.net.NetTestTools.hid;
63import static org.onosproject.net.intent.LinksHaveEntryWithSourceDestinationPairMatcher.linksHasPath;
Ray Milkeye6684082014-10-16 16:59:47 -070064
65/**
66 * Unit tests for the HostToHost intent compiler.
67 */
Ray Milkey37f6a382014-11-25 14:54:42 -080068public class HostToHostIntentCompilerTest extends AbstractIntentTest {
Luca Pretede10c782017-01-05 17:23:08 -080069 private static final ApplicationId APPID = new TestApplicationId("foo");
70
Ray Milkeye6684082014-10-16 16:59:47 -070071 private static final String HOST_ONE_MAC = "00:00:00:00:00:01";
72 private static final String HOST_TWO_MAC = "00:00:00:00:00:02";
Luca Prete283a9622016-03-29 16:12:20 -070073 private static final String HOST_ONE_VLAN = "None";
74 private static final String HOST_TWO_VLAN = "None";
Ray Milkeye6684082014-10-16 16:59:47 -070075 private static final String HOST_ONE = HOST_ONE_MAC + "/" + HOST_ONE_VLAN;
76 private static final String HOST_TWO = HOST_TWO_MAC + "/" + HOST_TWO_VLAN;
77
Luca Pretede10c782017-01-05 17:23:08 -080078 private static final String S1 = "s1";
79 private static final String S2 = "s2";
80 private static final String S3 = "s3";
81 private static final String S4 = "s4";
82 private static final String S5 = "s5";
83 private static final String S6 = "s6";
84 private static final String S7 = "s7";
85 private static final String S8 = "s8";
Pier Ventre98308ab2016-10-12 14:35:05 -070086
Luca Pretede10c782017-01-05 17:23:08 -080087 private static final DeviceId DID_S1 = DeviceId.deviceId("of:" + S1);
88 private static final DeviceId DID_S2 = DeviceId.deviceId("of:" + S2);
89 private static final DeviceId DID_S3 = DeviceId.deviceId("of:" + S3);
90 private static final DeviceId DID_S8 = DeviceId.deviceId("of:" + S8);
Pier Ventre98308ab2016-10-12 14:35:05 -070091
Luca Pretede10c782017-01-05 17:23:08 -080092 private static final PortNumber PORT_1 = PortNumber.portNumber(1);
93 private static final PortNumber PORT_2 = PortNumber.portNumber(2);
Thomas Vachuskab97cf282014-10-20 23:31:12 -070094
Ray Milkeye6684082014-10-16 16:59:47 -070095 private TrafficSelector selector = new IntentTestsMocks.MockSelector();
96 private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment();
97
98 private HostId hostOneId = HostId.hostId(HOST_ONE);
99 private HostId hostTwoId = HostId.hostId(HOST_TWO);
Luca Pretede10c782017-01-05 17:23:08 -0800100
Ray Milkeye6684082014-10-16 16:59:47 -0700101 private HostService mockHostService;
102
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -0700103 @Override
Ray Milkeye6684082014-10-16 16:59:47 -0700104 @Before
Thomas Vachuska2048c1f2017-05-10 19:32:22 -0700105 public void setUp() {
Brian O'Connor520c0522014-11-23 23:50:47 -0800106 super.setUp();
Ray Milkeye6684082014-10-16 16:59:47 -0700107 Host hostOne = createMock(Host.class);
108 expect(hostOne.mac()).andReturn(new MacAddress(HOST_ONE_MAC.getBytes())).anyTimes();
109 expect(hostOne.vlan()).andReturn(VlanId.vlanId()).anyTimes();
110 replay(hostOne);
111
112 Host hostTwo = createMock(Host.class);
113 expect(hostTwo.mac()).andReturn(new MacAddress(HOST_TWO_MAC.getBytes())).anyTimes();
114 expect(hostTwo.vlan()).andReturn(VlanId.vlanId()).anyTimes();
115 replay(hostTwo);
116
117 mockHostService = createMock(HostService.class);
118 expect(mockHostService.getHost(eq(hostOneId))).andReturn(hostOne).anyTimes();
119 expect(mockHostService.getHost(eq(hostTwoId))).andReturn(hostTwo).anyTimes();
120 replay(mockHostService);
121 }
122
123 /**
124 * Creates a HostToHost intent based on two host Ids.
125 *
Luca Pretede10c782017-01-05 17:23:08 -0800126 * @param oneIdString the string for host one id
127 * @param twoIdString the string for host two id
Ray Milkeye6684082014-10-16 16:59:47 -0700128 * @return HostToHostIntent for the two hosts
129 */
Luca Pretede10c782017-01-05 17:23:08 -0800130 private HostToHostIntent makeIntent(String oneIdString,
131 String twoIdString) {
132 return makeIntent(oneIdString, twoIdString, Lists.newArrayList());
133 }
134
135 /**
136 * Creates a HostToHost intent based on two host Ids and a list of
137 * constraints.
138 *
139 * @param oneIdString the string for host one id
140 * @param twoIdString the string for host two id
141 * @param constraints the intent constraints
142 * @return HostToHostIntent for the two hosts
143 */
144 private HostToHostIntent makeIntent(String oneIdString,
145 String twoIdString,
146 List<Constraint> constraints) {
Ray Milkeyebc5d222015-03-18 15:45:36 -0700147 return HostToHostIntent.builder()
148 .appId(APPID)
149 .one(hid(oneIdString))
150 .two(hid(twoIdString))
151 .selector(selector)
152 .treatment(treatment)
Luca Pretede10c782017-01-05 17:23:08 -0800153 .constraints(constraints)
Ray Milkeyebc5d222015-03-18 15:45:36 -0700154 .build();
Ray Milkeye6684082014-10-16 16:59:47 -0700155 }
156
157 /**
158 * Creates a compiler for HostToHost intents.
159 *
160 * @param hops string array describing the path hops to use when compiling
161 * @return HostToHost intent compiler
162 */
163 private HostToHostIntentCompiler makeCompiler(String[] hops) {
Luca Pretede10c782017-01-05 17:23:08 -0800164 return makeCompiler(hops, null);
165 }
166
167 /**
168 * Creates a compiler for HostToHost intents.
169 *
170 * @param hops string array describing the path hops to use when compiling
171 * @param resourceService the resource service
172 * @return HostToHost intent compiler
173 */
174 private HostToHostIntentCompiler makeCompiler(String[] hops,
175 ResourceService resourceService) {
Ray Milkeye6684082014-10-16 16:59:47 -0700176 HostToHostIntentCompiler compiler =
177 new HostToHostIntentCompiler();
178 compiler.pathService = new IntentTestsMocks.MockPathService(hops);
179 compiler.hostService = mockHostService;
Luca Pretede10c782017-01-05 17:23:08 -0800180
181 if (resourceService == null) {
182 compiler.resourceService = new MockResourceService();
183 } else {
184 compiler.resourceService = resourceService;
185 }
186
Ray Milkeye6684082014-10-16 16:59:47 -0700187 return compiler;
188 }
189
190
191 /**
192 * Tests a pair of hosts with 8 hops between them.
193 */
194 @Test
195 public void testSingleLongPathCompilation() {
196
197 HostToHostIntent intent = makeIntent(HOST_ONE,
198 HOST_TWO);
199 assertThat(intent, is(notNullValue()));
200
Luca Pretede10c782017-01-05 17:23:08 -0800201 String[] hops = {HOST_ONE, S1, S2, S3, S4, S5, S6, S7, S8, HOST_TWO};
Ray Milkeye6684082014-10-16 16:59:47 -0700202 HostToHostIntentCompiler compiler = makeCompiler(hops);
203 assertThat(compiler, is(notNullValue()));
204
Sho SHIMIZUec07ffd2016-02-22 20:45:21 -0800205 List<Intent> result = compiler.compile(intent, null);
Ray Milkeye6684082014-10-16 16:59:47 -0700206 assertThat(result, is(Matchers.notNullValue()));
207 assertThat(result, hasSize(2));
Pier Ventre98308ab2016-10-12 14:35:05 -0700208 Intent forwardIntent = result.get(0);
209 assertThat(forwardIntent instanceof LinkCollectionIntent, is(true));
210 Intent reverseIntent = result.get(1);
211 assertThat(reverseIntent instanceof LinkCollectionIntent, is(true));
Ray Milkeye6684082014-10-16 16:59:47 -0700212
Pier Ventre98308ab2016-10-12 14:35:05 -0700213 LinkCollectionIntent forwardLCIntent = (LinkCollectionIntent) forwardIntent;
214 Set<Link> links = forwardLCIntent.links();
215 assertThat(links, hasSize(7));
216 Set<FilteredConnectPoint> ingressPoints = ImmutableSet.of(
Luca Pretede10c782017-01-05 17:23:08 -0800217 new FilteredConnectPoint(new ConnectPoint(DID_S1, PORT_1))
Pier Ventre98308ab2016-10-12 14:35:05 -0700218 );
219 assertThat(forwardLCIntent.filteredIngressPoints(), is(ingressPoints));
Luca Pretede10c782017-01-05 17:23:08 -0800220 assertThat(links, linksHasPath(S1, S2));
221 assertThat(links, linksHasPath(S2, S3));
222 assertThat(links, linksHasPath(S3, S4));
223 assertThat(links, linksHasPath(S4, S5));
224 assertThat(links, linksHasPath(S5, S6));
225 assertThat(links, linksHasPath(S6, S7));
226 assertThat(links, linksHasPath(S7, S8));
Pier Ventre98308ab2016-10-12 14:35:05 -0700227 Set<FilteredConnectPoint> egressPoints = ImmutableSet.of(
Luca Pretede10c782017-01-05 17:23:08 -0800228 new FilteredConnectPoint(new ConnectPoint(DID_S8, PORT_2))
Pier Ventre98308ab2016-10-12 14:35:05 -0700229 );
230 assertThat(forwardLCIntent.filteredEgressPoints(), is(egressPoints));
Ray Milkeye6684082014-10-16 16:59:47 -0700231
Pier Ventre98308ab2016-10-12 14:35:05 -0700232 LinkCollectionIntent reverseLCIntent = (LinkCollectionIntent) reverseIntent;
233 links = reverseLCIntent.links();
234 assertThat(reverseLCIntent.links(), hasSize(7));
Luca Pretede10c782017-01-05 17:23:08 -0800235 ingressPoints = ImmutableSet.of(new FilteredConnectPoint(new ConnectPoint(DID_S8, PORT_2)));
Pier Ventre98308ab2016-10-12 14:35:05 -0700236 assertThat(reverseLCIntent.filteredIngressPoints(), is(ingressPoints));
Luca Pretede10c782017-01-05 17:23:08 -0800237 assertThat(links, linksHasPath(S2, S1));
238 assertThat(links, linksHasPath(S3, S2));
239 assertThat(links, linksHasPath(S4, S3));
240 assertThat(links, linksHasPath(S5, S4));
241 assertThat(links, linksHasPath(S6, S5));
242 assertThat(links, linksHasPath(S7, S6));
243 assertThat(links, linksHasPath(S8, S7));
244 egressPoints = ImmutableSet.of(new FilteredConnectPoint(new ConnectPoint(DID_S1, PORT_1)));
Pier Ventre98308ab2016-10-12 14:35:05 -0700245 assertThat(reverseLCIntent.filteredEgressPoints(), is(egressPoints));
246
Yuta HIGUCHI652f27f2016-10-31 16:54:30 -0700247
248 assertThat("key is inherited",
249 result.stream().map(Intent::key).collect(Collectors.toList()),
250 everyItem(is(intent.key())));
Ray Milkeye6684082014-10-16 16:59:47 -0700251 }
Luca Pretede10c782017-01-05 17:23:08 -0800252
253 /**
254 * Tests if bandwidth resources get allocated correctly.
255 */
256 @Test
257 public void testBandwidthConstrainedIntentAllocation() {
258 final double bpsTotal = 1000.0;
259 final double bpsToReserve = 100.0;
260
261 ContinuousResource resourceSw1P1 =
262 Resources.continuous(DID_S1, PORT_1, Bandwidth.class)
263 .resource(bpsToReserve);
264 ContinuousResource resourceSw1P2 =
265 Resources.continuous(DID_S1, PORT_2, Bandwidth.class)
266 .resource(bpsToReserve);
267 ContinuousResource resourceSw2P1 =
268 Resources.continuous(DID_S2, PORT_1, Bandwidth.class)
269 .resource(bpsToReserve);
270 ContinuousResource resourceSw2P2 =
271 Resources.continuous(DID_S2, PORT_2, Bandwidth.class)
272 .resource(bpsToReserve);
273 ContinuousResource resourceSw3P1 =
274 Resources.continuous(DID_S3, PORT_1, Bandwidth.class)
275 .resource(bpsToReserve);
276 ContinuousResource resourceSw3P2 =
277 Resources.continuous(DID_S3, PORT_2, Bandwidth.class)
278 .resource(bpsToReserve);
279
280 String[] hops = {HOST_ONE, S1, S2, S3, HOST_TWO};
281
282 final ResourceService resourceService =
283 MockResourceService.makeCustomBandwidthResourceService(bpsTotal);
284 final List<Constraint> constraints =
285 Collections.singletonList(new BandwidthConstraint(Bandwidth.bps(bpsToReserve)));
286
287 final HostToHostIntent intent = makeIntent(HOST_ONE, HOST_TWO, constraints);
288
289 HostToHostIntentCompiler compiler = makeCompiler(hops, resourceService);
290
291 compiler.compile(intent, null);
292
293 Key intentKey = intent.key();
294
295 ResourceAllocation rAOne = new ResourceAllocation(resourceSw1P1, intentKey);
296 ResourceAllocation rATwo = new ResourceAllocation(resourceSw1P2, intentKey);
297 ResourceAllocation rAThree = new ResourceAllocation(resourceSw2P1, intentKey);
298 ResourceAllocation rAFour = new ResourceAllocation(resourceSw2P2, intentKey);
299 ResourceAllocation rAFive = new ResourceAllocation(resourceSw3P1, intentKey);
300 ResourceAllocation rASix = new ResourceAllocation(resourceSw3P2, intentKey);
301
302 Set<ResourceAllocation> expectedresourceAllocations =
303 ImmutableSet.of(rAOne, rATwo, rAThree, rAFour, rAFive, rASix);
304
305 Set<ResourceAllocation> resourceAllocations =
306 ImmutableSet.copyOf(resourceService.getResourceAllocations(intentKey));
307
308 assertThat(resourceAllocations, hasSize(6));
309 assertEquals(expectedresourceAllocations, resourceAllocations);
310 }
Ray Milkeye6684082014-10-16 16:59:47 -0700311}