blob: 3727572efb2badc0b4003ed3b2865723947c967c [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
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 */
Ray Milkeye6684082014-10-16 16:59:47 -070016package org.onlab.onos.net.intent.impl;
17
Ray Milkeye6684082014-10-16 16:59:47 -070018import org.hamcrest.Matchers;
19import org.junit.Test;
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070020import org.onlab.onos.core.ApplicationId;
Thomas Vachuskab97cf282014-10-20 23:31:12 -070021import org.onlab.onos.TestApplicationId;
Ray Milkeye6684082014-10-16 16:59:47 -070022import org.onlab.onos.net.ConnectPoint;
23import org.onlab.onos.net.ElementId;
24import org.onlab.onos.net.Path;
25import org.onlab.onos.net.flow.TrafficSelector;
26import org.onlab.onos.net.flow.TrafficTreatment;
Brian O'Connor520c0522014-11-23 23:50:47 -080027import org.onlab.onos.net.intent.AbstractIntentTest;
Ray Milkeye6684082014-10-16 16:59:47 -070028import org.onlab.onos.net.intent.Intent;
Ray Milkeye6684082014-10-16 16:59:47 -070029import org.onlab.onos.net.intent.IntentTestsMocks;
30import org.onlab.onos.net.intent.LinkCollectionIntent;
31import org.onlab.onos.net.intent.MultiPointToSinglePointIntent;
32import org.onlab.onos.net.topology.LinkWeight;
33import org.onlab.onos.net.topology.PathService;
34
Thomas Vachuskab97cf282014-10-20 23:31:12 -070035import java.util.HashSet;
36import java.util.List;
37import java.util.Set;
38
Ray Milkeye6684082014-10-16 16:59:47 -070039import static org.hamcrest.CoreMatchers.notNullValue;
40import static org.hamcrest.MatcherAssert.assertThat;
41import static org.hamcrest.Matchers.hasSize;
42import static org.hamcrest.Matchers.is;
43import static org.onlab.onos.net.NetTestTools.connectPoint;
44import static org.onlab.onos.net.NetTestTools.createPath;
45import static org.onlab.onos.net.intent.LinksHaveEntryWithSourceDestinationPairMatcher.linksHasPath;
46
47/**
48 * Unit tests for the MultiPointToSinglePoint intent compiler.
49 */
Ray Milkey37f6a382014-11-25 14:54:42 -080050public class MultiPointToSinglePointIntentCompilerTest extends AbstractIntentTest {
Ray Milkeye6684082014-10-16 16:59:47 -070051
Thomas Vachuskab97cf282014-10-20 23:31:12 -070052 private static final ApplicationId APPID = new TestApplicationId("foo");
53
Ray Milkeye6684082014-10-16 16:59:47 -070054 private TrafficSelector selector = new IntentTestsMocks.MockSelector();
55 private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment();
56
57 /**
58 * Mock path service for creating paths within the test.
59 */
60 private static class MockPathService implements PathService {
61
62 final String[] pathHops;
63
64 /**
65 * Constructor that provides a set of hops to mock.
66 *
67 * @param pathHops path hops to mock
68 */
69 MockPathService(String[] pathHops) {
70 this.pathHops = pathHops;
71 }
72
73 @Override
74 public Set<Path> getPaths(ElementId src, ElementId dst) {
75 Set<Path> result = new HashSet<>();
76
77 String[] allHops = new String[pathHops.length + 1];
78 allHops[0] = src.toString();
79 System.arraycopy(pathHops, 0, allHops, 1, pathHops.length);
80
81 result.add(createPath(allHops));
82 return result;
83 }
84
85 @Override
86 public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) {
87 return null;
88 }
89 }
90
91 /**
92 * Creates a MultiPointToSinglePoint intent for a group of ingress points
93 * and an egress point.
94 *
95 * @param ingressIds array of ingress device ids
Thomas Vachuskab97cf282014-10-20 23:31:12 -070096 * @param egressId device id of the egress point
Ray Milkeye6684082014-10-16 16:59:47 -070097 * @return MultiPointToSinglePoint intent
98 */
99 private MultiPointToSinglePointIntent makeIntent(String[] ingressIds, String egressId) {
100 Set<ConnectPoint> ingressPoints = new HashSet<>();
101 ConnectPoint egressPoint = connectPoint(egressId, 1);
102
103 for (String ingressId : ingressIds) {
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700104 ingressPoints.add(connectPoint(ingressId, 1));
Ray Milkeye6684082014-10-16 16:59:47 -0700105 }
106
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700107 return new MultiPointToSinglePointIntent(APPID, selector, treatment,
108 ingressPoints, egressPoint);
Ray Milkeye6684082014-10-16 16:59:47 -0700109 }
110
111 /**
112 * Creates a compiler for MultiPointToSinglePoint intents.
113 *
114 * @param hops hops to use while computing paths for this intent
115 * @return MultiPointToSinglePoint intent
116 */
117 private MultiPointToSinglePointIntentCompiler makeCompiler(String[] hops) {
118 MultiPointToSinglePointIntentCompiler compiler =
119 new MultiPointToSinglePointIntentCompiler();
120 compiler.pathService = new MockPathService(hops);
Ray Milkeye6684082014-10-16 16:59:47 -0700121 return compiler;
122 }
123
124 /**
125 * Tests a single ingress point with 8 hops to its egress point.
126 */
127 @Test
128 public void testSingleLongPathCompilation() {
129
130 String[] ingress = {"ingress"};
131 String egress = "egress";
132
133 MultiPointToSinglePointIntent intent = makeIntent(ingress, egress);
134 assertThat(intent, is(notNullValue()));
135
136 String[] hops = {"h1", "h2", "h3", "h4", "h5", "h6", "h7", "h8",
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700137 egress};
Ray Milkeye6684082014-10-16 16:59:47 -0700138 MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops);
139 assertThat(compiler, is(notNullValue()));
140
Brian O'Connorfa81eae2014-10-30 13:20:05 -0700141 List<Intent> result = compiler.compile(intent, null, null);
Ray Milkeye6684082014-10-16 16:59:47 -0700142 assertThat(result, is(Matchers.notNullValue()));
143 assertThat(result, hasSize(1));
144 Intent resultIntent = result.get(0);
145 assertThat(resultIntent instanceof LinkCollectionIntent, is(true));
146
147 if (resultIntent instanceof LinkCollectionIntent) {
148 LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent;
149 assertThat(linkIntent.links(), hasSize(9));
150 assertThat(linkIntent.links(), linksHasPath("ingress", "h1"));
151 assertThat(linkIntent.links(), linksHasPath("h1", "h2"));
152 assertThat(linkIntent.links(), linksHasPath("h2", "h3"));
153 assertThat(linkIntent.links(), linksHasPath("h4", "h5"));
154 assertThat(linkIntent.links(), linksHasPath("h5", "h6"));
155 assertThat(linkIntent.links(), linksHasPath("h7", "h8"));
156 assertThat(linkIntent.links(), linksHasPath("h8", "egress"));
157 }
158 }
159
160 /**
161 * Tests a simple topology where two ingress points share some path segments
162 * and some path segments are not shared.
163 */
164 @Test
165 public void testTwoIngressCompilation() {
166 String[] ingress = {"ingress1", "ingress2"};
167 String egress = "egress";
168
169 MultiPointToSinglePointIntent intent = makeIntent(ingress, egress);
170 assertThat(intent, is(notNullValue()));
171
172 final String[] hops = {"inner1", "inner2", egress};
173 MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops);
174 assertThat(compiler, is(notNullValue()));
175
Brian O'Connorfa81eae2014-10-30 13:20:05 -0700176 List<Intent> result = compiler.compile(intent, null, null);
Ray Milkeye6684082014-10-16 16:59:47 -0700177 assertThat(result, is(notNullValue()));
178 assertThat(result, hasSize(1));
179 Intent resultIntent = result.get(0);
180 assertThat(resultIntent instanceof LinkCollectionIntent, is(true));
181
182 if (resultIntent instanceof LinkCollectionIntent) {
183 LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent;
184 assertThat(linkIntent.links(), hasSize(4));
185 assertThat(linkIntent.links(), linksHasPath("ingress1", "inner1"));
186 assertThat(linkIntent.links(), linksHasPath("ingress2", "inner1"));
187 assertThat(linkIntent.links(), linksHasPath("inner1", "inner2"));
188 assertThat(linkIntent.links(), linksHasPath("inner2", "egress"));
189 }
190 }
191
192 /**
193 * Tests a large number of ingress points that share a common path to the
194 * egress point.
195 */
196 @Test
197 public void testMultiIngressCompilation() {
198 String[] ingress = {"i1", "i2", "i3", "i4", "i5",
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700199 "i6", "i7", "i8", "i9", "i10"};
Ray Milkeye6684082014-10-16 16:59:47 -0700200 String egress = "e";
201
202 MultiPointToSinglePointIntent intent = makeIntent(ingress, egress);
203 assertThat(intent, is(notNullValue()));
204
205 final String[] hops = {"n1", egress};
206 MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops);
207 assertThat(compiler, is(notNullValue()));
208
Brian O'Connorfa81eae2014-10-30 13:20:05 -0700209 List<Intent> result = compiler.compile(intent, null, null);
Ray Milkeye6684082014-10-16 16:59:47 -0700210 assertThat(result, is(notNullValue()));
211 assertThat(result, hasSize(1));
212 Intent resultIntent = result.get(0);
213 assertThat(resultIntent instanceof LinkCollectionIntent, is(true));
214
215 if (resultIntent instanceof LinkCollectionIntent) {
216 LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent;
217 assertThat(linkIntent.links(), hasSize(ingress.length + 1));
218 for (String ingressToCheck : ingress) {
219 assertThat(linkIntent.links(),
220 linksHasPath(ingressToCheck,
221 "n1"));
222 }
223 assertThat(linkIntent.links(), linksHasPath("n1", egress));
224 }
225 }
226}