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