Commit 71d9b289 authored by Eyrak Paen-Rochlitz's avatar Eyrak Paen-Rochlitz
Browse files

Merge branch '46-invalid-connection-inherited-structure-diagram' into 'master'

[core.room] fix binding validation to check inherited external end ports

Closes #46

See merge request !15
parents 687d0d35 ce9cd336
Pipeline #4358 passed with stage
in 0 seconds
......@@ -29,7 +29,6 @@ import org.eclipse.etrice.core.room.ActorRef;
import org.eclipse.etrice.core.room.Binding;
import org.eclipse.etrice.core.room.BindingEndPoint;
import org.eclipse.etrice.core.room.CommunicationType;
import org.eclipse.etrice.core.room.ExternalPort;
import org.eclipse.etrice.core.room.InterfaceItem;
import org.eclipse.etrice.core.room.LayerConnection;
import org.eclipse.etrice.core.room.Port;
......@@ -68,12 +67,8 @@ public class ValidationUtil extends FSMValidationUtil {
if (!isMultipleConnectable(port, ref) && isConnected(port, ref, acc, exclude))
return Result.error("port with multiplicity 1 is already connected");
if (acc instanceof ActorClass) {
for (ExternalPort xp : ((ActorClass)acc).getExternalPorts()) {
if (xp.getInterfacePort()==port)
return Result.error("external end ports must not be connected");
}
}
if (roomHelpers.getInterfaceItems(acc, true).contains(port) && roomHelpers.isExternal(port))
return Result.error("external end ports must not be connected");
return Result.ok();
}
......
......@@ -83,6 +83,42 @@ RoomModel TestBindings {
}
}
ActorClass Example8_external_to_actorref {
Interface {
conjugated Port external_conj: PC1
}
Structure {
external Port external_conj
ActorRef aref: AC1
// This case is only relevant in diagram, since there the validation
// is used to check endpoints that could otherwise be out of scope
// according to the RoomScopeProvider. Binding is constructed in unit test.
//Binding aref.reg and external_conj
}
}
ActorClass Example9_inherited_external_to_local_actorref extends AC7 {
Structure {
ActorRef aref_sub: AC1
// This case is only relevant in diagram. See Example8 for details.
// Binding is constructed in unit test.
//Binding aref_sub.reg and external_conj
}
}
ActorClass Example10_inherited_external_to_inherited_actorref extends AC7 {
Structure {
// This case is only relevant in diagram. See Example8 for details.
// Binding is constructed in unit test.
//Binding aref.reg and external_conj
}
}
// helper actor classes
ActorClass AC1 {
......@@ -140,6 +176,16 @@ RoomModel TestBindings {
}
}
ActorClass AC7 {
Interface {
conjugated Port external_conj: PC1
}
Structure {
external Port external_conj
ActorRef aref: AC1
}
}
ProtocolClass PC1 {
incoming {
Message in1()
......
......@@ -19,8 +19,13 @@ import static org.junit.Assert.*;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.etrice.core.room.ActorClass;
import org.eclipse.etrice.core.room.ActorContainerRef;
import org.eclipse.etrice.core.room.Binding;
import org.eclipse.etrice.core.room.BindingEndPoint;
import org.eclipse.etrice.core.room.Port;
import org.eclipse.etrice.core.room.RoomFactory;
import org.eclipse.etrice.core.room.RoomModel;
import org.eclipse.etrice.core.room.StructureClass;
import org.junit.Before;
import org.junit.Test;
......@@ -81,6 +86,33 @@ public class TestBindings extends TestBase {
assertEquals("derived protocols not connectable (both directions extended)", diag.getMessage());
}
@Test
public void testLocalExternalToLocalRefValidation() {
ActorClass ac = getActorClass("Example8_external_to_actorref");
Binding bind = createBinding(createEndPoint(ac, "aref", "reg"), createEndPoint(ac, "external_conj"));
ac.getBindings().add(bind);
Diagnostic diag = getDiag(bind).getChildren().get(0);
assertEquals("expect error message", "external end ports must not be connected", diag.getMessage());
}
@Test
public void testInheritedExternalEndPointToLocalRefValidation() {
ActorClass ac = getActorClass("Example9_inherited_external_to_local_actorref");
Binding bind = createBinding(createEndPoint(ac, "aref_sub", "reg"), createEndPoint(ac, "external_conj"));
ac.getBindings().add(bind);
Diagnostic diag = getDiag(bind).getChildren().get(0);
assertEquals("expect error message", "external end ports must not be connected", diag.getMessage());
}
@Test
public void testInheritedExternalToInheritedRefValidation() {
ActorClass ac = getActorClass("Example10_inherited_external_to_inherited_actorref");
Binding bind = createBinding(createEndPoint(ac, "aref", "reg"), createEndPoint(ac, "external_conj"));
ac.getBindings().add(bind);
Diagnostic diag = getDiag(bind).getChildren().get(0);
assertEquals("expect error message", "external end ports must not be connected", diag.getMessage());
}
@Test
public void testProtocolValidation() {
RoomModel mdl = (RoomModel) resource.getContents().get(0);
......@@ -91,7 +123,52 @@ public class TestBindings extends TestBase {
}
private Binding getBinding(String acname, int idx) {
ActorClass ac = (ActorClass) resource.getEObject("ActorClass:"+acname);
ActorClass ac = getActorClass(acname);
return ac.getBindings().get(idx);
}
private ActorClass getActorClass(String acname) {
ActorClass ac = (ActorClass) resource.getEObject("ActorClass:"+acname);
return ac;
}
private Binding createBinding(BindingEndPoint ep1, BindingEndPoint ep2) {
Binding bind = RoomFactory.eINSTANCE.createBinding();
bind.setEndpoint1(ep1);
bind.setEndpoint2(ep2);
return bind;
}
private BindingEndPoint createEndPoint(ActorClass ac, String arefName, String portName) {
BindingEndPoint ep = RoomFactory.eINSTANCE.createBindingEndPoint();
ActorContainerRef aref = getRefByName(arefName, ac);
Port arefPort = getPortByName(portName, aref.getStructureClass());
ep.setActorRef(aref);
ep.setPort(arefPort);
return ep;
}
private BindingEndPoint createEndPoint(ActorClass ac, String portName) {
BindingEndPoint ep = RoomFactory.eINSTANCE.createBindingEndPoint();
Port port = getPortByName(portName, ac);
ep.setPort(port);
return ep;
}
private ActorContainerRef getRefByName(String name, StructureClass sc) {
ActorContainerRef aref = roomHelpers.getAllActorContainerRefs(sc).stream()
.filter(it -> it.getName().equals(name))
.findFirst()
.orElseThrow();
return aref;
}
private Port getPortByName(String name, StructureClass sc) throws ClassCastException {
ActorClass ac = (ActorClass)sc;
Port port = roomHelpers.getAllPorts(ac).stream()
.filter(it -> it.getName().equals(name))
.findFirst()
.orElseThrow();
return port;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment