blob: 8d286cf63da529544030cbddff7b4e860455a48b [file] [log] [blame]
Ray Milkeye6684082014-10-16 16:59:47 -07001package org.onlab.onos.net.intent.impl;
2
3import java.util.HashSet;
4import java.util.List;
5import java.util.Set;
6
7import org.hamcrest.Matchers;
8import org.junit.Test;
9import org.onlab.onos.net.ConnectPoint;
10import org.onlab.onos.net.ElementId;
11import org.onlab.onos.net.Path;
12import org.onlab.onos.net.flow.TrafficSelector;
13import org.onlab.onos.net.flow.TrafficTreatment;
14import org.onlab.onos.net.intent.Intent;
15import org.onlab.onos.net.intent.IntentId;
16import org.onlab.onos.net.intent.IntentTestsMocks;
17import org.onlab.onos.net.intent.LinkCollectionIntent;
18import org.onlab.onos.net.intent.MultiPointToSinglePointIntent;
19import org.onlab.onos.net.topology.LinkWeight;
20import org.onlab.onos.net.topology.PathService;
21
22import static org.hamcrest.CoreMatchers.notNullValue;
23import static org.hamcrest.MatcherAssert.assertThat;
24import static org.hamcrest.Matchers.hasSize;
25import static org.hamcrest.Matchers.is;
26import static org.onlab.onos.net.NetTestTools.connectPoint;
27import static org.onlab.onos.net.NetTestTools.createPath;
28import static org.onlab.onos.net.intent.LinksHaveEntryWithSourceDestinationPairMatcher.linksHasPath;
29
30/**
31 * Unit tests for the MultiPointToSinglePoint intent compiler.
32 */
33public class TestMultiPointToSinglePointIntentCompiler {
34
35 private TrafficSelector selector = new IntentTestsMocks.MockSelector();
36 private TrafficTreatment treatment = new IntentTestsMocks.MockTreatment();
37
38 /**
39 * Mock path service for creating paths within the test.
40 */
41 private static class MockPathService implements PathService {
42
43 final String[] pathHops;
44
45 /**
46 * Constructor that provides a set of hops to mock.
47 *
48 * @param pathHops path hops to mock
49 */
50 MockPathService(String[] pathHops) {
51 this.pathHops = pathHops;
52 }
53
54 @Override
55 public Set<Path> getPaths(ElementId src, ElementId dst) {
56 Set<Path> result = new HashSet<>();
57
58 String[] allHops = new String[pathHops.length + 1];
59 allHops[0] = src.toString();
60 System.arraycopy(pathHops, 0, allHops, 1, pathHops.length);
61
62 result.add(createPath(allHops));
63 return result;
64 }
65
66 @Override
67 public Set<Path> getPaths(ElementId src, ElementId dst, LinkWeight weight) {
68 return null;
69 }
70 }
71
72 /**
73 * Creates a MultiPointToSinglePoint intent for a group of ingress points
74 * and an egress point.
75 *
76 * @param ingressIds array of ingress device ids
77 * @param egressId device id of the egress point
78 * @return MultiPointToSinglePoint intent
79 */
80 private MultiPointToSinglePointIntent makeIntent(String[] ingressIds, String egressId) {
81 Set<ConnectPoint> ingressPoints = new HashSet<>();
82 ConnectPoint egressPoint = connectPoint(egressId, 1);
83
84 for (String ingressId : ingressIds) {
85 ingressPoints.add(connectPoint(ingressId, 1));
86 }
87
88 return new MultiPointToSinglePointIntent(
89 new IntentId(12),
90 selector,
91 treatment,
92 ingressPoints,
93 egressPoint);
94 }
95
96 /**
97 * Creates a compiler for MultiPointToSinglePoint intents.
98 *
99 * @param hops hops to use while computing paths for this intent
100 * @return MultiPointToSinglePoint intent
101 */
102 private MultiPointToSinglePointIntentCompiler makeCompiler(String[] hops) {
103 MultiPointToSinglePointIntentCompiler compiler =
104 new MultiPointToSinglePointIntentCompiler();
105 compiler.pathService = new MockPathService(hops);
106 IdBlockAllocator idBlockAllocator = new DummyIdBlockAllocator();
107 compiler.intentIdGenerator =
108 new IdBlockAllocatorBasedIntentIdGenerator(idBlockAllocator);
109 return compiler;
110 }
111
112 /**
113 * Tests a single ingress point with 8 hops to its egress point.
114 */
115 @Test
116 public void testSingleLongPathCompilation() {
117
118 String[] ingress = {"ingress"};
119 String egress = "egress";
120
121 MultiPointToSinglePointIntent intent = makeIntent(ingress, egress);
122 assertThat(intent, is(notNullValue()));
123
124 String[] hops = {"h1", "h2", "h3", "h4", "h5", "h6", "h7", "h8",
125 egress};
126 MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops);
127 assertThat(compiler, is(notNullValue()));
128
129 List<Intent> result = compiler.compile(intent);
130 assertThat(result, is(Matchers.notNullValue()));
131 assertThat(result, hasSize(1));
132 Intent resultIntent = result.get(0);
133 assertThat(resultIntent instanceof LinkCollectionIntent, is(true));
134
135 if (resultIntent instanceof LinkCollectionIntent) {
136 LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent;
137 assertThat(linkIntent.links(), hasSize(9));
138 assertThat(linkIntent.links(), linksHasPath("ingress", "h1"));
139 assertThat(linkIntent.links(), linksHasPath("h1", "h2"));
140 assertThat(linkIntent.links(), linksHasPath("h2", "h3"));
141 assertThat(linkIntent.links(), linksHasPath("h4", "h5"));
142 assertThat(linkIntent.links(), linksHasPath("h5", "h6"));
143 assertThat(linkIntent.links(), linksHasPath("h7", "h8"));
144 assertThat(linkIntent.links(), linksHasPath("h8", "egress"));
145 }
146 }
147
148 /**
149 * Tests a simple topology where two ingress points share some path segments
150 * and some path segments are not shared.
151 */
152 @Test
153 public void testTwoIngressCompilation() {
154 String[] ingress = {"ingress1", "ingress2"};
155 String egress = "egress";
156
157 MultiPointToSinglePointIntent intent = makeIntent(ingress, egress);
158 assertThat(intent, is(notNullValue()));
159
160 final String[] hops = {"inner1", "inner2", egress};
161 MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops);
162 assertThat(compiler, is(notNullValue()));
163
164 List<Intent> result = compiler.compile(intent);
165 assertThat(result, is(notNullValue()));
166 assertThat(result, hasSize(1));
167 Intent resultIntent = result.get(0);
168 assertThat(resultIntent instanceof LinkCollectionIntent, is(true));
169
170 if (resultIntent instanceof LinkCollectionIntent) {
171 LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent;
172 assertThat(linkIntent.links(), hasSize(4));
173 assertThat(linkIntent.links(), linksHasPath("ingress1", "inner1"));
174 assertThat(linkIntent.links(), linksHasPath("ingress2", "inner1"));
175 assertThat(linkIntent.links(), linksHasPath("inner1", "inner2"));
176 assertThat(linkIntent.links(), linksHasPath("inner2", "egress"));
177 }
178 }
179
180 /**
181 * Tests a large number of ingress points that share a common path to the
182 * egress point.
183 */
184 @Test
185 public void testMultiIngressCompilation() {
186 String[] ingress = {"i1", "i2", "i3", "i4", "i5",
187 "i6", "i7", "i8", "i9", "i10"};
188 String egress = "e";
189
190 MultiPointToSinglePointIntent intent = makeIntent(ingress, egress);
191 assertThat(intent, is(notNullValue()));
192
193 final String[] hops = {"n1", egress};
194 MultiPointToSinglePointIntentCompiler compiler = makeCompiler(hops);
195 assertThat(compiler, is(notNullValue()));
196
197 List<Intent> result = compiler.compile(intent);
198 assertThat(result, is(notNullValue()));
199 assertThat(result, hasSize(1));
200 Intent resultIntent = result.get(0);
201 assertThat(resultIntent instanceof LinkCollectionIntent, is(true));
202
203 if (resultIntent instanceof LinkCollectionIntent) {
204 LinkCollectionIntent linkIntent = (LinkCollectionIntent) resultIntent;
205 assertThat(linkIntent.links(), hasSize(ingress.length + 1));
206 for (String ingressToCheck : ingress) {
207 assertThat(linkIntent.links(),
208 linksHasPath(ingressToCheck,
209 "n1"));
210 }
211 assertThat(linkIntent.links(), linksHasPath("n1", egress));
212 }
213 }
214}