blob: fde5428085979a85db171678b29790efef3cc5a3 [file] [log] [blame]
Sean Condon0e89bda2017-03-21 14:23:19 +00001/*
2 * Copyright 2017-present Open Networking Foundation
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 */
16package org.onosproject.cfm.impl;
17
18import com.fasterxml.jackson.databind.ObjectMapper;
19import com.fasterxml.jackson.databind.node.ObjectNode;
20import org.junit.Before;
21import org.junit.Test;
22import org.onlab.osgi.ServiceDirectory;
23import org.onlab.osgi.TestServiceDirectory;
24import org.onlab.packet.VlanId;
Sean Condon0e89bda2017-03-21 14:23:19 +000025import org.onosproject.cfm.CfmCodecContext;
26import org.onosproject.codec.CodecService;
27import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceAssociation;
28import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceDomain;
29import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMep;
30import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepEntry;
31import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepLbCreate;
32import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepLtCreate;
33import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
34import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
35import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
36import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
37import org.onosproject.incubator.net.l2monitoring.cfm.MepLbCreate;
38import org.onosproject.incubator.net.l2monitoring.cfm.MepLtCreate;
39import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
40import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
41import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
42import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
43import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
44import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
45import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
46import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepService;
47import org.onosproject.net.DeviceId;
48import org.onosproject.net.PortNumber;
49
50import javax.ws.rs.InternalServerErrorException;
51import javax.ws.rs.client.Entity;
52import javax.ws.rs.client.WebTarget;
53import javax.ws.rs.core.Response;
54
55import java.io.BufferedReader;
56import java.io.ByteArrayInputStream;
57import java.io.IOException;
58import java.io.InputStreamReader;
59import java.time.Duration;
60import java.util.ArrayList;
61import java.util.BitSet;
62import java.util.Collection;
63import java.util.Optional;
64
65import static junit.framework.TestCase.fail;
66import static org.easymock.EasyMock.*;
67import static org.hamcrest.Matchers.is;
68import static org.junit.Assert.assertEquals;
69import static org.junit.Assert.assertThat;
70
71public class MepWebResourceTest extends CfmResourceTest {
72 private final CfmMepService mepService = createMock(CfmMepService.class);
73 private final CfmMdService mdService = createMock(CfmMdService.class);
74
75 private static final MdId MDNAME1 = MdIdCharStr.asMdId("md-1");
76 private static final MaIdShort MANAME1 = MaIdCharStr.asMaId("ma-1-1");
77 private static final MepId MEPID1 = MepId.valueOf((short) 1);
78
79 private MepEntry mepEntry1 = null;
80
81 @Before
82 public void setUpTest() throws CfmConfigException {
83 CfmCodecContext context = new CfmCodecContext();
84 ServiceDirectory testDirectory = new TestServiceDirectory()
85 .add(CfmMepService.class, mepService)
86 .add(CfmMdService.class, mdService)
87 .add(CodecService.class, context.codecManager());
Ray Milkey094a1352018-01-22 14:03:54 -080088 setServiceDirectory(testDirectory);
Sean Condon0e89bda2017-03-21 14:23:19 +000089
90 mepEntry1 = DefaultMepEntry.builder(
91 MEPID1,
92 DeviceId.deviceId("netconf:1.2.3.4:830"),
93 PortNumber.portNumber(1),
94 Mep.MepDirection.UP_MEP, MDNAME1, MANAME1)
95 .buildEntry();
96
97 }
98
99 @Test
100 public void testGetAllMepsForMaEmpty() throws CfmConfigException {
101
102 expect(mepService.getAllMeps(MDNAME1, MANAME1)).andReturn(null).anyTimes();
103 replay(mepService);
104
105 final WebTarget wt = target();
106 final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
107 MANAME1.maName() + "/mep").request().get(String.class);
108 assertThat(response, is("{\"meps\":[[]]}"));
109 }
110
111 @Test
112 public void testGetAllMepsForMa1Mep() throws CfmConfigException {
113 Collection<MepEntry> meps = new ArrayList<>();
114 meps.add(mepEntry1);
115
116 expect(mepService.getAllMeps(MDNAME1, MANAME1)).andReturn(meps).anyTimes();
117 replay(mepService);
118
119 final WebTarget wt = target();
120 final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
121 MANAME1.maName() + "/mep").request().get(String.class);
122
123 assertThat(response, is("{\"meps\":" +
124 "[[{" +
125 "\"mepId\":" + MEPID1.value() + "," +
126 "\"deviceId\":\"netconf:1.2.3.4:830\"," +
127 "\"port\":1," +
128 "\"direction\":\"UP_MEP\"," +
129 "\"mdName\":\"" + MDNAME1.mdName() + "\"," +
130 "\"maName\":\"" + MANAME1.maName() + "\"," +
131 "\"administrative-state\":false," +
132 "\"cci-enabled\":false," +
133 "\"remoteMeps\":[]}]]}"));
134 }
135
136 @Test
137 public void testGetMepValid() throws CfmConfigException {
138
139 expect(mepService.getMep(MDNAME1, MANAME1, MepId.valueOf((short) 1)))
140 .andReturn(mepEntry1).anyTimes();
141 replay(mepService);
142
143 final WebTarget wt = target();
144 final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
145 MANAME1.maName() + "/mep/" + MEPID1.value()).request().get(String.class);
146
147 assertThat(response, is("{\"mep\":" +
148 "{" +
149 "\"mepId\":" + MEPID1.value() + "," +
150 "\"deviceId\":\"netconf:1.2.3.4:830\"," +
151 "\"port\":1," +
152 "\"direction\":\"UP_MEP\"," +
153 "\"mdName\":\"" + MDNAME1.mdName() + "\"," +
154 "\"maName\":\"" + MANAME1.maName() + "\"," +
155 "\"administrative-state\":false," +
156 "\"cci-enabled\":false," +
157 "\"remoteMeps\":[]}}"));
158 }
159
160 @Test
161 public void testGetMepNotFound() throws CfmConfigException, IOException {
162
163 expect(mepService.getMep(MDNAME1, MANAME1, MepId.valueOf((short) 2)))
164 .andReturn(null).anyTimes();
165 replay(mepService);
166
167 final WebTarget wt = target();
168
169 try {
170 final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
171 MANAME1.maName() + "/mep/" + 2).request().get(String.class);
172 fail("Expected exception to be thrown");
173 } catch (InternalServerErrorException e) {
174 ByteArrayInputStream is = (ByteArrayInputStream) e.getResponse().getEntity();
175 BufferedReader br = new BufferedReader(new InputStreamReader(is));
176 String line = null;
177 StringBuffer sb = new StringBuffer();
178 while ((line = br.readLine()) != null) {
179 sb.append(line);
180 }
181 assertEquals("{ \"failure\":\"MEP md-1/ma-1-1/2 not found\" }", sb.toString());
182 }
183 }
184
185 @Test
186 public void testDeleteMepValid() throws CfmConfigException {
187
188 expect(mepService.deleteMep(MDNAME1, MANAME1, MepId.valueOf((short) 1)))
189 .andReturn(true).anyTimes();
190 replay(mepService);
191
192 final WebTarget wt = target();
193 final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
194 MANAME1.maName() + "/mep/" + MEPID1.value()).request().delete();
195
196 assertEquals("Expecting 200", 200, response.getStatus());
197 }
198
199 @Test
200 public void testDeleteMepNotFound() throws CfmConfigException {
201
202 expect(mepService.deleteMep(MDNAME1, MANAME1, MepId.valueOf((short) 2)))
203 .andReturn(false).anyTimes();
204 replay(mepService);
205
206 final WebTarget wt = target();
207 final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
208 MANAME1.maName() + "/mep/2").request().delete();
209
210 assertEquals("Expecting 304", 304, response.getStatus());
211 }
212
213 @Test
214 public void testCreateMep() throws CfmConfigException, IOException {
215 MepId mepId2 = MepId.valueOf((short) 2);
216 Mep mep2 = DefaultMep.builder(
217 mepId2,
218 DeviceId.deviceId("netconf:2.2.3.4:830"),
219 PortNumber.portNumber(2),
220 Mep.MepDirection.UP_MEP, MDNAME1, MANAME1).build();
221
222 MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
223 .builder(MANAME1, MDNAME1.getNameLength()).build();
224
225 expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
226 .andReturn(Optional.ofNullable(ma1)).anyTimes();
227 replay(mdService);
228 expect(mepService.createMep(MDNAME1, MANAME1, mep2))
229 .andReturn(true).anyTimes();
230 replay(mepService);
231
232 ObjectMapper mapper = new ObjectMapper();
233 CfmCodecContext context = new CfmCodecContext();
234 ObjectNode node = mapper.createObjectNode();
235 node.set("mep", context.codec(Mep.class).encode(mep2, context));
236
237 final WebTarget wt = target();
238 final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
239 MANAME1.maName() + "/mep")
240 .request()
241 .post(Entity.json(node.toString()));
242
243 assertEquals("Expecting 201", 201, response.getStatus());
244 }
245
246 @Test
247 public void testCreateMepAlreadyExists() throws CfmConfigException, IOException {
248 MepId mepId3 = MepId.valueOf((short) 3);
249 Mep mep3 = DefaultMep.builder(
250 mepId3,
251 DeviceId.deviceId("netconf:3.2.3.4:830"),
252 PortNumber.portNumber(3),
253 Mep.MepDirection.UP_MEP, MDNAME1, MANAME1)
254 .cciEnabled(true)
255 .ccmLtmPriority(Mep.Priority.PRIO3)
256 .administrativeState(false)
257 .primaryVid(VlanId.vlanId((short) 3))
258 .defectAbsentTime(Duration.ofMinutes(2))
259 .defectPresentTime(Duration.ofMinutes(3))
260 .fngAddress(Mep.FngAddress.notSpecified())
261 .lowestFaultPriorityDefect(Mep.LowestFaultDefect.ALL_DEFECTS)
262 .build();
263
264 MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
265 .builder(MANAME1, MDNAME1.getNameLength()).build();
266
267 expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
268 .andReturn(Optional.ofNullable(ma1)).anyTimes();
269 replay(mdService);
270 expect(mepService.createMep(MDNAME1, MANAME1, mep3))
271 .andReturn(false).anyTimes();
272 replay(mepService);
273
274 ObjectMapper mapper = new ObjectMapper();
275 CfmCodecContext context = new CfmCodecContext();
276 ObjectNode node = mapper.createObjectNode();
277 node.set("mep", context.codec(Mep.class).encode(mep3, context));
278
279 final WebTarget wt = target();
280 final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
281 MANAME1.maName() + "/mep")
282 .request()
283 .post(Entity.json(node.toString()));
284
285 assertEquals("Expecting 304", 304, response.getStatus());
286 }
287
288 @Test
289 public void testTransmitLoopback() throws CfmConfigException {
290 MepLbCreate mepLbCreate1 = DefaultMepLbCreate
291 .builder(MEPID1)
292 .numberMessages(20)
293 .dataTlvHex("AA:BB:CC:DD")
294 .vlanDropEligible(true)
295 .build();
296
297 MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
298 .builder(MANAME1, MDNAME1.getNameLength()).build();
299 MaintenanceDomain md1 = DefaultMaintenanceDomain.builder(MDNAME1)
300 .addToMaList(ma1).build();
301 expect(mdService.getMaintenanceDomain(MDNAME1))
302 .andReturn(Optional.ofNullable(md1)).anyTimes();
303 expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
304 .andReturn(Optional.ofNullable(ma1)).anyTimes();
305 replay(mdService);
306
307 ObjectMapper mapper = new ObjectMapper();
308 CfmCodecContext context = new CfmCodecContext();
309 ObjectNode node = mapper.createObjectNode();
310 node.set("loopback", context.codec(MepLbCreate.class).encode(mepLbCreate1, context));
311
312 final WebTarget wt = target();
313 final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
314 MANAME1.maName() + "/mep/" + MEPID1.value() + "/transmit-loopback")
315 .request()
316 .put(Entity.json(node.toString()));
317
318 assertEquals("Expecting 202", 202, response.getStatus());
319 }
320
321 @Test
322 public void testAbortLoopback() throws CfmConfigException {
323
324 MepLbCreate mepLbCreate1 = DefaultMepLbCreate.builder(MEPID1).build();
325
326 MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
327 .builder(MANAME1, MDNAME1.getNameLength()).build();
328 MaintenanceDomain md1 = DefaultMaintenanceDomain.builder(MDNAME1)
329 .addToMaList(ma1).build();
330 expect(mdService.getMaintenanceDomain(MDNAME1))
331 .andReturn(Optional.ofNullable(md1)).anyTimes();
332 expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
333 .andReturn(Optional.ofNullable(ma1)).anyTimes();
334 replay(mdService);
335
336 final WebTarget wt = target();
337 final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
338 MANAME1.maName() + "/mep/" + MEPID1.value() + "/abort-loopback")
339 .request()
340 .put(Entity.json(""));
341
342 assertEquals("Expecting 202", 202, response.getStatus());
343
344 }
345
346 @Test
347 public void testTransmitLinktrace() throws CfmConfigException {
348 MepLtCreate mepLtCreate1 = DefaultMepLtCreate
349 .builder(MEPID1)
350 .defaultTtl((short) 20)
351 .transmitLtmFlags(BitSet.valueOf(new byte[]{1}))
352 .build();
353
354 MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
355 .builder(MANAME1, MDNAME1.getNameLength()).build();
356 MaintenanceDomain md1 = DefaultMaintenanceDomain.builder(MDNAME1)
357 .addToMaList(ma1).build();
358 expect(mdService.getMaintenanceDomain(MDNAME1))
359 .andReturn(Optional.ofNullable(md1)).anyTimes();
360 expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
361 .andReturn(Optional.ofNullable(ma1)).anyTimes();
362 replay(mdService);
363
364 ObjectMapper mapper = new ObjectMapper();
365 CfmCodecContext context = new CfmCodecContext();
366 ObjectNode node = mapper.createObjectNode();
367 node.set("linktrace", context.codec(MepLtCreate.class).encode(mepLtCreate1, context));
368
369 final WebTarget wt = target();
370 final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
371 MANAME1.maName() + "/mep/" + MEPID1.value() + "/transmit-linktrace")
372 .request()
373 .put(Entity.json(node.toString()));
374
375 assertEquals("Expecting 202", 202, response.getStatus());
376 }
377}