Skip to content

Commit 5670a41

Browse files
Merge pull request #491 from com-pas/fix/inRef_processing
fix: InRef processing closes #490
2 parents 546b8c1 + e318b5d commit 5670a41

File tree

9 files changed

+293
-82
lines changed

9 files changed

+293
-82
lines changed

sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapter.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,7 @@ public List<SclReportItem> updateDaiFromExtRef(List<TExtRef> tExtRefs) {
126126
updateDAI(SETTSTCB_DA_NAME, valueTstCb).ifPresent(sclReportItems::add);
127127
}
128128
}
129-
} else {
130-
sclReportItems.add(SclReportItem.warning(getXPath(), "The DOI %s can't be bound with an ExtRef".formatted(getXPath())));
131129
}
132-
133130
return sclReportItems;
134131
}
135132

sct-commons/src/test/java/org/lfenergy/compas/sct/commons/SclServiceTest.java

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -386,15 +386,68 @@ void updateDoInRef_should_not_update_DAI(String testName, String ldInst, String
386386
}
387387

388388
@Test
389-
@Tag("issue-321")
390-
void updateDoInRef_when_ExtRefNotCoherent_shouldReturnReportWithError() {
389+
void updateDoInRef_when_No_ExtRef_for_InRef_should_not_return_error() {
391390
// Given
392-
SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_issue_231_test_ko.xml");
391+
SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_no_Extref.xml");
393392
// When
394393
List<SclReportItem> sclReportItems = sclService.updateDoInRef(givenScl);
395394
// Then
396-
assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue();
397-
assertThat(sclReportItems).hasSize(4);
395+
assertThat(sclReportItems).isEmpty();
396+
}
397+
398+
@Test
399+
void updateDoInRef_when_ExtRef_bind_and_desc_suffix_not_match_should_not_return_error() {
400+
// Given
401+
SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_extref_bind_desc_suffix_not_match.xml");
402+
// When
403+
List<SclReportItem> sclReportItems = sclService.updateDoInRef(givenScl);
404+
// Then
405+
assertThat(sclReportItems).isEmpty();
406+
}
407+
408+
@Test
409+
void updateDoInRef_when_ExtRef_bind_should_succeed() {
410+
// Given
411+
SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_extref_bind.xml");
412+
// When
413+
List<SclReportItem> sclReportItems = sclService.updateDoInRef(givenScl);
414+
// Then
415+
assertThat(sclReportItems).isEmpty();
416+
assertThat(givenScl.getIED())
417+
.filteredOn(tied -> tied.getName().equals("IED_NAME1"))
418+
.flatExtracting(TIED::getAccessPoint)
419+
.extracting(TAccessPoint::getServer)
420+
.flatExtracting(TServer::getLDevice)
421+
.filteredOn(tlDevice -> tlDevice.getInst().equals("LD1"))
422+
.map(TLDevice::getLN0)
423+
.flatExtracting(TAnyLN::getDOI)
424+
.filteredOn(tdoi -> tdoi.getName().equals("InRef1"))
425+
.flatExtracting(TDOI::getSDIOrDAI)
426+
.filteredOn(tUnNaming -> tUnNaming.getClass().equals(TDAI.class) && ((TDAI)tUnNaming).getName().equals("setSrcRef"))
427+
.map(tUnNaming -> ((TDAI)tUnNaming).getVal().getFirst().getValue())
428+
.containsExactly("IED_NAME1LD2/PRANCR1.Do11.sdo11");
429+
}
430+
431+
@Test
432+
void updateDoInRef_when_ExtRef_bind_should_not_return_error() {
433+
// Given
434+
SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_extref_not_bind.xml");
435+
// When
436+
List<SclReportItem> sclReportItems = sclService.updateDoInRef(givenScl);
437+
// Then
438+
assertThat(sclReportItems).isEmpty();
439+
}
440+
441+
@Test
442+
void updateDoInRef_when_Inref_purpose_not_set_should_return_report_with_warning() {
443+
// Given
444+
SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_when_inref_purpose_not_set.xml");
445+
// When
446+
List<SclReportItem> sclReportItems = sclService.updateDoInRef(givenScl);
447+
// Then
448+
assertThat(sclReportItems.stream().filter(sclReportItem -> !sclReportItem.isError()).map(SclReportItem::message))
449+
.hasSize(1)
450+
.containsExactly("The DOI /SCL/IED[@name=\"IED_NAME1\"]/AccessPoint/Server/LDevice[@inst=\"LD_Without_Val_in_DAI_purpose\"]/LN0 can't be bound with an ExtRef");
398451
}
399452

400453
private Optional<TVal> getValFromDaiName(SCL scl, String iedName, String ldInst, String doiName, String daiName) {

sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapterTest.java

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ void updateDaiFromExtRef_when_ExtRef_desc_suffix_ends_with_1_and_3_without_CB_sh
451451
}
452452

453453
@Test
454-
void updateDaiFromExtRef_when_none_ExtRef_endin_with_1_should_return_warning_report() {
454+
void updateDaiFromExtRef_when_none_ExtRef_endin_with_1_should_not_return_error() {
455455
// Given
456456
DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "da");
457457
DOIAdapter doiAdapter = daiAdapter.getParentAdapter();
@@ -465,10 +465,7 @@ void updateDaiFromExtRef_when_none_ExtRef_endin_with_1_should_return_warning_rep
465465
List<SclReportItem> sclReportItems = doiAdapter.updateDaiFromExtRef(List.of(extRef3));
466466

467467
// Then
468-
assertThat(sclReportItems)
469-
.isNotEmpty()
470-
.extracting(SclReportItem::message)
471-
.contains("The DOI /DOI[@name=\"Do\"] can't be bound with an ExtRef");
468+
assertThat(sclReportItems).isEmpty();
472469
assertThat(doiAdapter.getDataAdapterByName(SETSRCREF_DA_NAME)).isNotNull();
473470
assertThat(getDaiValOfDoi(doiAdapter, SETSRCREF_DA_NAME)).isNotPresent();
474471
}
@@ -493,7 +490,7 @@ void updateDaiFromExtRef_when_no_DAI_name_setSrcRef_should_create_DAI() {
493490
}
494491

495492
@Test
496-
void updateDaiFromExtRef_when_no_ExtRef_in_LNode_should_return_filled_ReportItem() {
493+
void updateDaiFromExtRef_when_no_ExtRef_in_LNode_should_not_return_error() {
497494
// Given
498495
DOIAdapter.DAIAdapter daiAdapter = initInnerDAIAdapter("Do", "da");
499496
DOIAdapter doiAdapter = daiAdapter.getParentAdapter();
@@ -502,11 +499,7 @@ void updateDaiFromExtRef_when_no_ExtRef_in_LNode_should_return_filled_ReportItem
502499
List<SclReportItem> sclReportItems = doiAdapter.updateDaiFromExtRef(List.of());
503500

504501
// Then
505-
assertThat(sclReportItems)
506-
.isNotEmpty();
507-
assertThat(sclReportItems)
508-
.extracting(SclReportItem::message)
509-
.contains("The DOI /DOI[@name=\"Do\"] can't be bound with an ExtRef");
502+
assertThat(sclReportItems).isEmpty();
510503
}
511504

512505
@Test

sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ln/LN0AdapterTest.java

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import org.junit.jupiter.api.Test;
99
import org.junit.jupiter.params.ParameterizedTest;
1010
import org.junit.jupiter.params.provider.Arguments;
11-
import org.junit.jupiter.params.provider.CsvSource;
1211
import org.junit.jupiter.params.provider.EnumSource;
1312
import org.junit.jupiter.params.provider.MethodSource;
1413
import org.lfenergy.compas.scl2007b4.model.*;
@@ -1002,26 +1001,6 @@ void getFCDAs_when_DataSet_not_present_should_throw_Exception() {
10021001
.hasMessage("Control Block smv1 not found in /LN0");
10031002
}
10041003

1005-
@ParameterizedTest(name = "{0}")
1006-
@CsvSource({
1007-
"Case without InRef,LD_WITHOUT_InRef,InRef1",
1008-
"Case with no InRef finishing with _1,LD_WITH_1_Bad_InRef,InRef4",
1009-
"Case with several ExtRef desc finishing with _1,LD_WITH_2_InRef_same_SUFFIX,InRef5"
1010-
})
1011-
void updateDoInRef_should_return_error_message(String testName, String ldInst, String doiName) {
1012-
// Given
1013-
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_test.xml");
1014-
LN0Adapter sourceLn0 = findLn0(scd, "IED_NAME1", ldInst);
1015-
1016-
// When
1017-
List<SclReportItem> sclReportItems = sourceLn0.updateDoInRef();
1018-
1019-
// Then
1020-
assertThat(sclReportItems).hasSize(1)
1021-
.extracting(SclReportItem::message)
1022-
.containsExactly("The DOI /SCL/IED[@name=\"IED_NAME1\"]/AccessPoint/Server/LDevice[@inst=\"" + ldInst + "\"]/LN0/DOI[@name=\"" + doiName + "\"] can't be bound with an ExtRef");
1023-
}
1024-
10251004
@Test
10261005
void updateDoInRef_when_no_Val_in_DAI_purpose_should_return_error_message() {
10271006
// Given
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<!-- SPDX-FileCopyrightText: 2021 2025 RTE FRANCE -->
3+
<!-- -->
4+
<!-- SPDX-License-Identifier: Apache-2.0 -->
5+
6+
<SCL version="2007" revision="B" release="4" xmlns="http://www.iec.ch/61850/2003/SCL">
7+
<Header id="hId" version="2007" revision="B" toolID="COMPAS"/>
8+
<IED name="IED_NAME1">
9+
<AccessPoint name="AP_NAME">
10+
<Server>
11+
<Authentication/>
12+
<LDevice inst="LD1" ldName="IED_NAME1LD_INST12">
13+
<LN0 lnClass="LLN0" inst="" lnType="LN11">
14+
<DOI name="InRef1">
15+
<DAI name="purpose">
16+
<Val>purpose value</Val>
17+
</DAI>
18+
<DAI name="setSrcRef" valKind="RO" valImport="true"/>
19+
<DAI name="setSrcCB" valKind="RO" valImport="true"/>
20+
<DAI name="setTstRef" valKind="RO" valImport="true"/>
21+
<DAI name="setTstCB" valKind="RO" valImport="true"/>
22+
</DOI>
23+
<Inputs>
24+
<ExtRef iedName="IED_NAME1" ldInst="LD2" desc="purpose value AA_1"
25+
lnClass="ANCR" lnInst="1" prefix="PR" intAddr="INT_ADDR11" pDO="Do11.sdo11"
26+
doName="Do11.sdo11"/>
27+
</Inputs>
28+
</LN0>
29+
</LDevice>
30+
</Server>
31+
</AccessPoint>
32+
</IED>
33+
<DataTypeTemplates>
34+
<LNodeType lnClass="LLN0" id="LN11">
35+
<DO name="Do11" type="DO11" transient="true"/>
36+
<DO name="InRef1" type="DOType_13"/>
37+
</LNodeType>
38+
<LNodeType lnClass="ANCR" id="LN12">
39+
<DO name="Do21" type="DO11"/>
40+
</LNodeType>
41+
<DOType cdc="WYE" id="DO11">
42+
<SDO name="sdo11" type="DO12"/>
43+
</DOType>
44+
<DOType cdc="WYE" id="DO12">
45+
<SDO name="sdo11" type="DO12"/>
46+
</DOType>
47+
<DOType cdc="ORG" id="DOType_13">
48+
<DA fc="SP" dchg="true" name="setSrcRef" bType="ObjRef"/>
49+
<DA fc="SP" dchg="true" name="setSrcCB" bType="ObjRef"/>
50+
<DA fc="SP" dchg="true" name="intAddr" bType="VisString255"/>
51+
<DA fc="DC" name="purpose" bType="VisString255"/>
52+
<DA fc="DC" name="d" bType="VisString255" valKind="RO" valImport="false"/>
53+
</DOType>
54+
</DataTypeTemplates>
55+
</SCL>
Lines changed: 10 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2-
<!-- SPDX-FileCopyrightText: 2021 RTE FRANCE -->
2+
<!-- SPDX-FileCopyrightText: 2021 2025 RTE FRANCE -->
33
<!-- -->
44
<!-- SPDX-License-Identifier: Apache-2.0 -->
55

@@ -9,17 +9,6 @@
99
<AccessPoint name="AP_NAME">
1010
<Server>
1111
<Authentication/>
12-
<!-- Case when No InRef in LDevice-->
13-
<LDevice inst="LD_WITHOUT_InRef" ldName="IED_NAME1LD_INST11">
14-
<LN0 lnClass="LLN0" inst="" lnType="LN11">
15-
<DOI name="InRef1">
16-
<DAI name="purpose">
17-
<Val>LD_WITHOUT_InRef_DOI_InRef1</Val>
18-
</DAI>
19-
</DOI>
20-
</LN0>
21-
</LDevice>
22-
2312
<!-- Case with ExtRef.desc suffix not ending with "_1" -->
2413
<LDevice inst="LD_WITH_1_Bad_InRef" ldName="IED_NAME1LD_INST12">
2514
<LN0 lnClass="LLN0" inst="" lnType="LN11">
@@ -41,7 +30,6 @@
4130
</Inputs>
4231
</LN0>
4332
</LDevice>
44-
4533
<!-- Case with ExtRef.desc with 2 suffix ending with "_1" -->
4634
<LDevice inst="LD_WITH_2_InRef_same_SUFFIX" ldName="IED_NAME1LD_INST12">
4735
<LN0 lnClass="LLN0" inst="" lnType="LN11">
@@ -66,41 +54,14 @@
6654
</Inputs>
6755
</LN0>
6856
</LDevice>
69-
70-
<!-- Case without DAI.name set to "purpose" -->
71-
<LDevice inst="LD_Without_purpose" ldName="IED_NAME1LD_INST12">
72-
<LN0 lnClass="LLN0" inst="" lnType="LN11">
73-
<DOI name="InRef6">
74-
<DAI name="setSrcRef" valKind="RO" valImport="true"/>
75-
<DAI name="setSrcCB" valKind="RO" valImport="false">
76-
<Val>OLD_VAL</Val>
77-
</DAI>
78-
<DAI name="setTstRef" valKind="RO" valImport="false"/>
79-
<DAI name="setTstCB" valKind="RO" valImport="false"/>
80-
</DOI>
81-
<Inputs>
82-
<ExtRef iedName="IED_NAME1" desc="LD_Without_purpose_DOI_InRef6_1" ldInst="LD_WITH_1_InRef"
83-
lnClass="ANCR" lnInst="1" prefix="PR" intAddr="INT_ADDR11" pDO="Do11.sdo11"
84-
doName="Do11.sdo11"/>
85-
</Inputs>
86-
</LN0>
87-
</LDevice>
88-
89-
<!-- Case where DAI purpose without Val -->
90-
<LDevice inst="LD_Without_Val_in_DAI_purpose" ldName="IED_NAME1LD_INST12">
91-
<LN0 lnClass="LLN0" inst="" lnType="LN11">
92-
<DOI name="InRef8">
93-
<DAI name="purpose"/>
94-
<DAI name="setSrcRef" valKind="RO" valImport="true"/>
95-
</DOI>
96-
</LN0>
97-
</LDevice>
9857
</Server>
9958
</AccessPoint>
10059
</IED>
10160
<DataTypeTemplates>
10261
<LNodeType lnClass="LLN0" id="LN11">
10362
<DO name="Do11" type="DO11" transient="true"/>
63+
<DO name="InRef4" type="DOType_13"/>
64+
<DO name="InRef5" type="DOType_13"/>
10465
</LNodeType>
10566
<LNodeType lnClass="ANCR" id="LN12">
10667
<DO name="Do21" type="DO11"/>
@@ -111,5 +72,12 @@
11172
<DOType cdc="WYE" id="DO12">
11273
<SDO name="sdo11" type="DO12"/>
11374
</DOType>
75+
<DOType cdc="ORG" id="DOType_13">
76+
<DA fc="SP" dchg="true" name="setSrcRef" bType="ObjRef"/>
77+
<DA fc="SP" dchg="true" name="setSrcCB" bType="ObjRef"/>
78+
<DA fc="SP" dchg="true" name="intAddr" bType="VisString255"/>
79+
<DA fc="DC" name="purpose" bType="VisString255"/>
80+
<DA fc="DC" name="d" bType="VisString255" valKind="RO" valImport="false"/>
81+
</DOType>
11482
</DataTypeTemplates>
11583
</SCL>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<!-- SPDX-FileCopyrightText: 2021 2025 RTE FRANCE -->
3+
<!-- -->
4+
<!-- SPDX-License-Identifier: Apache-2.0 -->
5+
6+
<SCL version="2007" revision="B" release="4" xmlns="http://www.iec.ch/61850/2003/SCL">
7+
<Header id="hId" version="2007" revision="B" toolID="COMPAS"/>
8+
<IED name="IED_NAME1">
9+
<AccessPoint name="AP_NAME">
10+
<Server>
11+
<Authentication/>
12+
<LDevice inst="LD1" ldName="IED_NAME1LD_INST12">
13+
<LN0 lnClass="LLN0" inst="" lnType="LN11">
14+
<DOI name="InRef1">
15+
<DAI name="purpose">
16+
<Val>purpose value</Val>
17+
</DAI>
18+
<DAI name="setSrcRef" valKind="RO" valImport="true"/>
19+
<DAI name="setSrcCB" valKind="RO" valImport="true"/>
20+
<DAI name="setTstRef" valKind="RO" valImport="true"/>
21+
<DAI name="setTstCB" valKind="RO" valImport="true"/>
22+
</DOI>
23+
<Inputs>
24+
<ExtRef intAddr="INT_ADDR11" pDO="Do11.sdo11" desc="purpose value AA_1"/>
25+
</Inputs>
26+
</LN0>
27+
</LDevice>
28+
</Server>
29+
</AccessPoint>
30+
</IED>
31+
<DataTypeTemplates>
32+
<LNodeType lnClass="LLN0" id="LN11">
33+
<DO name="Do11" type="DO11" transient="true"/>
34+
<DO name="InRef1" type="DOType_13"/>
35+
</LNodeType>
36+
<LNodeType lnClass="ANCR" id="LN12">
37+
<DO name="Do21" type="DO11"/>
38+
</LNodeType>
39+
<DOType cdc="WYE" id="DO11">
40+
<SDO name="sdo11" type="DO12"/>
41+
</DOType>
42+
<DOType cdc="WYE" id="DO12">
43+
<SDO name="sdo11" type="DO12"/>
44+
</DOType>
45+
<DOType cdc="ORG" id="DOType_13">
46+
<DA fc="SP" dchg="true" name="setSrcRef" bType="ObjRef"/>
47+
<DA fc="SP" dchg="true" name="setSrcCB" bType="ObjRef"/>
48+
<DA fc="SP" dchg="true" name="intAddr" bType="VisString255"/>
49+
<DA fc="DC" name="purpose" bType="VisString255"/>
50+
<DA fc="DC" name="d" bType="VisString255" valKind="RO" valImport="false"/>
51+
</DOType>
52+
</DataTypeTemplates>
53+
</SCL>

0 commit comments

Comments
 (0)