blob: 4dd83dba0cdaa34c692f30efacf4a6514ba21e01 [file] [log] [blame]
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.cfm.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Before;
import org.junit.Test;
import org.onlab.osgi.ServiceDirectory;
import org.onlab.osgi.TestServiceDirectory;
import org.onlab.packet.VlanId;
import org.onlab.rest.BaseResource;
import org.onosproject.cfm.CfmCodecContext;
import org.onosproject.codec.CodecService;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMep;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepLbCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepLtCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLbCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.MepLtCreate;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepService;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.Duration;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Collection;
import java.util.Optional;
import static junit.framework.TestCase.fail;
import static org.easymock.EasyMock.*;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
public class MepWebResourceTest extends CfmResourceTest {
private final CfmMepService mepService = createMock(CfmMepService.class);
private final CfmMdService mdService = createMock(CfmMdService.class);
private static final MdId MDNAME1 = MdIdCharStr.asMdId("md-1");
private static final MaIdShort MANAME1 = MaIdCharStr.asMaId("ma-1-1");
private static final MepId MEPID1 = MepId.valueOf((short) 1);
private MepEntry mepEntry1 = null;
@Before
public void setUpTest() throws CfmConfigException {
CfmCodecContext context = new CfmCodecContext();
ServiceDirectory testDirectory = new TestServiceDirectory()
.add(CfmMepService.class, mepService)
.add(CfmMdService.class, mdService)
.add(CodecService.class, context.codecManager());
BaseResource.setServiceDirectory(testDirectory);
mepEntry1 = DefaultMepEntry.builder(
MEPID1,
DeviceId.deviceId("netconf:1.2.3.4:830"),
PortNumber.portNumber(1),
Mep.MepDirection.UP_MEP, MDNAME1, MANAME1)
.buildEntry();
}
@Test
public void testGetAllMepsForMaEmpty() throws CfmConfigException {
expect(mepService.getAllMeps(MDNAME1, MANAME1)).andReturn(null).anyTimes();
replay(mepService);
final WebTarget wt = target();
final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep").request().get(String.class);
assertThat(response, is("{\"meps\":[[]]}"));
}
@Test
public void testGetAllMepsForMa1Mep() throws CfmConfigException {
Collection<MepEntry> meps = new ArrayList<>();
meps.add(mepEntry1);
expect(mepService.getAllMeps(MDNAME1, MANAME1)).andReturn(meps).anyTimes();
replay(mepService);
final WebTarget wt = target();
final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep").request().get(String.class);
assertThat(response, is("{\"meps\":" +
"[[{" +
"\"mepId\":" + MEPID1.value() + "," +
"\"deviceId\":\"netconf:1.2.3.4:830\"," +
"\"port\":1," +
"\"direction\":\"UP_MEP\"," +
"\"mdName\":\"" + MDNAME1.mdName() + "\"," +
"\"maName\":\"" + MANAME1.maName() + "\"," +
"\"administrative-state\":false," +
"\"cci-enabled\":false," +
"\"remoteMeps\":[]}]]}"));
}
@Test
public void testGetMepValid() throws CfmConfigException {
expect(mepService.getMep(MDNAME1, MANAME1, MepId.valueOf((short) 1)))
.andReturn(mepEntry1).anyTimes();
replay(mepService);
final WebTarget wt = target();
final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value()).request().get(String.class);
assertThat(response, is("{\"mep\":" +
"{" +
"\"mepId\":" + MEPID1.value() + "," +
"\"deviceId\":\"netconf:1.2.3.4:830\"," +
"\"port\":1," +
"\"direction\":\"UP_MEP\"," +
"\"mdName\":\"" + MDNAME1.mdName() + "\"," +
"\"maName\":\"" + MANAME1.maName() + "\"," +
"\"administrative-state\":false," +
"\"cci-enabled\":false," +
"\"remoteMeps\":[]}}"));
}
@Test
public void testGetMepNotFound() throws CfmConfigException, IOException {
expect(mepService.getMep(MDNAME1, MANAME1, MepId.valueOf((short) 2)))
.andReturn(null).anyTimes();
replay(mepService);
final WebTarget wt = target();
try {
final String response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + 2).request().get(String.class);
fail("Expected exception to be thrown");
} catch (InternalServerErrorException e) {
ByteArrayInputStream is = (ByteArrayInputStream) e.getResponse().getEntity();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
StringBuffer sb = new StringBuffer();
while ((line = br.readLine()) != null) {
sb.append(line);
}
assertEquals("{ \"failure\":\"MEP md-1/ma-1-1/2 not found\" }", sb.toString());
}
}
@Test
public void testDeleteMepValid() throws CfmConfigException {
expect(mepService.deleteMep(MDNAME1, MANAME1, MepId.valueOf((short) 1)))
.andReturn(true).anyTimes();
replay(mepService);
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value()).request().delete();
assertEquals("Expecting 200", 200, response.getStatus());
}
@Test
public void testDeleteMepNotFound() throws CfmConfigException {
expect(mepService.deleteMep(MDNAME1, MANAME1, MepId.valueOf((short) 2)))
.andReturn(false).anyTimes();
replay(mepService);
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/2").request().delete();
assertEquals("Expecting 304", 304, response.getStatus());
}
@Test
public void testCreateMep() throws CfmConfigException, IOException {
MepId mepId2 = MepId.valueOf((short) 2);
Mep mep2 = DefaultMep.builder(
mepId2,
DeviceId.deviceId("netconf:2.2.3.4:830"),
PortNumber.portNumber(2),
Mep.MepDirection.UP_MEP, MDNAME1, MANAME1).build();
MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
.builder(MANAME1, MDNAME1.getNameLength()).build();
expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
.andReturn(Optional.ofNullable(ma1)).anyTimes();
replay(mdService);
expect(mepService.createMep(MDNAME1, MANAME1, mep2))
.andReturn(true).anyTimes();
replay(mepService);
ObjectMapper mapper = new ObjectMapper();
CfmCodecContext context = new CfmCodecContext();
ObjectNode node = mapper.createObjectNode();
node.set("mep", context.codec(Mep.class).encode(mep2, context));
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep")
.request()
.post(Entity.json(node.toString()));
assertEquals("Expecting 201", 201, response.getStatus());
}
@Test
public void testCreateMepAlreadyExists() throws CfmConfigException, IOException {
MepId mepId3 = MepId.valueOf((short) 3);
Mep mep3 = DefaultMep.builder(
mepId3,
DeviceId.deviceId("netconf:3.2.3.4:830"),
PortNumber.portNumber(3),
Mep.MepDirection.UP_MEP, MDNAME1, MANAME1)
.cciEnabled(true)
.ccmLtmPriority(Mep.Priority.PRIO3)
.administrativeState(false)
.primaryVid(VlanId.vlanId((short) 3))
.defectAbsentTime(Duration.ofMinutes(2))
.defectPresentTime(Duration.ofMinutes(3))
.fngAddress(Mep.FngAddress.notSpecified())
.lowestFaultPriorityDefect(Mep.LowestFaultDefect.ALL_DEFECTS)
.build();
MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
.builder(MANAME1, MDNAME1.getNameLength()).build();
expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
.andReturn(Optional.ofNullable(ma1)).anyTimes();
replay(mdService);
expect(mepService.createMep(MDNAME1, MANAME1, mep3))
.andReturn(false).anyTimes();
replay(mepService);
ObjectMapper mapper = new ObjectMapper();
CfmCodecContext context = new CfmCodecContext();
ObjectNode node = mapper.createObjectNode();
node.set("mep", context.codec(Mep.class).encode(mep3, context));
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep")
.request()
.post(Entity.json(node.toString()));
assertEquals("Expecting 304", 304, response.getStatus());
}
@Test
public void testTransmitLoopback() throws CfmConfigException {
MepLbCreate mepLbCreate1 = DefaultMepLbCreate
.builder(MEPID1)
.numberMessages(20)
.dataTlvHex("AA:BB:CC:DD")
.vlanDropEligible(true)
.build();
MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
.builder(MANAME1, MDNAME1.getNameLength()).build();
MaintenanceDomain md1 = DefaultMaintenanceDomain.builder(MDNAME1)
.addToMaList(ma1).build();
expect(mdService.getMaintenanceDomain(MDNAME1))
.andReturn(Optional.ofNullable(md1)).anyTimes();
expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
.andReturn(Optional.ofNullable(ma1)).anyTimes();
replay(mdService);
ObjectMapper mapper = new ObjectMapper();
CfmCodecContext context = new CfmCodecContext();
ObjectNode node = mapper.createObjectNode();
node.set("loopback", context.codec(MepLbCreate.class).encode(mepLbCreate1, context));
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/transmit-loopback")
.request()
.put(Entity.json(node.toString()));
assertEquals("Expecting 202", 202, response.getStatus());
}
@Test
public void testAbortLoopback() throws CfmConfigException {
MepLbCreate mepLbCreate1 = DefaultMepLbCreate.builder(MEPID1).build();
MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
.builder(MANAME1, MDNAME1.getNameLength()).build();
MaintenanceDomain md1 = DefaultMaintenanceDomain.builder(MDNAME1)
.addToMaList(ma1).build();
expect(mdService.getMaintenanceDomain(MDNAME1))
.andReturn(Optional.ofNullable(md1)).anyTimes();
expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
.andReturn(Optional.ofNullable(ma1)).anyTimes();
replay(mdService);
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/abort-loopback")
.request()
.put(Entity.json(""));
assertEquals("Expecting 202", 202, response.getStatus());
}
@Test
public void testTransmitLinktrace() throws CfmConfigException {
MepLtCreate mepLtCreate1 = DefaultMepLtCreate
.builder(MEPID1)
.defaultTtl((short) 20)
.transmitLtmFlags(BitSet.valueOf(new byte[]{1}))
.build();
MaintenanceAssociation ma1 = DefaultMaintenanceAssociation
.builder(MANAME1, MDNAME1.getNameLength()).build();
MaintenanceDomain md1 = DefaultMaintenanceDomain.builder(MDNAME1)
.addToMaList(ma1).build();
expect(mdService.getMaintenanceDomain(MDNAME1))
.andReturn(Optional.ofNullable(md1)).anyTimes();
expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
.andReturn(Optional.ofNullable(ma1)).anyTimes();
replay(mdService);
ObjectMapper mapper = new ObjectMapper();
CfmCodecContext context = new CfmCodecContext();
ObjectNode node = mapper.createObjectNode();
node.set("linktrace", context.codec(MepLtCreate.class).encode(mepLtCreate1, context));
final WebTarget wt = target();
final Response response = wt.path("md/" + MDNAME1.mdName() + "/ma/" +
MANAME1.maName() + "/mep/" + MEPID1.value() + "/transmit-linktrace")
.request()
.put(Entity.json(node.toString()));
assertEquals("Expecting 202", 202, response.getStatus());
}
}