Skip to content

Commit 68a0e76

Browse files
authored
Verify the node type before running the loadflow. (#799)
Signed-off-by: AAJELLAL <[email protected]>
1 parent 2979c4d commit 68a0e76

File tree

11 files changed

+106
-16
lines changed

11 files changed

+106
-16
lines changed

src/main/java/org/gridsuite/study/server/StudyConstants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ private StudyConstants() {
8484
public static final String QUERY_PARAM_STASHED = "stashed";
8585
public static final String QUERY_PARAM_ACTIVATED = "activated";
8686
public static final String PATH_PARAM_PARAMETERS = "parameters";
87+
public static final String DYNA_FLOW_PROVIDER = "DynaFlow";
88+
8789

8890
public enum SldDisplayMode {
8991
FEEDER_POSITION,

src/main/java/org/gridsuite/study/server/StudyException.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ public enum Type {
152152
CREATE_SPREADSHEET_CONFIG_COLLECTION_FAILED,
153153
UPDATE_SPREADSHEET_CONFIG_COLLECTION_FAILED,
154154
UPDATE_SPREADSHEET_CONFIG_FAILED,
155-
NETWORK_EXPORT_FAILED
155+
NETWORK_EXPORT_FAILED,
156+
GET_LOADFLOW_PROVIDER_FAILED
156157
}
157158

158159
private final Type type;

src/main/java/org/gridsuite/study/server/controller/StudyController.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@ public ResponseEntity<Void> runLoadFlow(
682682
@RequestHeader(HEADER_USER_ID) String userId) {
683683
studyService.assertIsNodeNotReadOnly(nodeUuid);
684684
studyService.assertNoBlockedBuildInNodeTree(nodeUuid, rootNetworkUuid);
685+
studyService.assertCanRunLoadFLow(studyUuid, nodeUuid);
685686
UUID prevResultUuid = rootNetworkNodeInfoService.getComputationResultUuid(nodeUuid, rootNetworkUuid, LOAD_FLOW);
686687
if (prevResultUuid != null) {
687688
handleRerunLoadFlow(studyUuid, nodeUuid, rootNetworkUuid, prevResultUuid, withRatioTapChangers, userId);
@@ -2397,4 +2398,11 @@ public ResponseEntity<Void> setNodeAliases(
23972398
studyService.updateNodeAliases(studyUuid, nodeAliases);
23982399
return ResponseEntity.ok().build();
23992400
}
2401+
2402+
@GetMapping(value = "/studies/{studyUuid}/loadflow/provider")
2403+
@Operation(summary = "Get loadflow provider for a specified study")
2404+
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The loadflow provider is returned")})
2405+
public ResponseEntity<String> getLoadFlowProvider(@PathVariable("studyUuid") UUID studyUuid) {
2406+
return ResponseEntity.ok().body(studyService.getLoadFlowProvider(studyUuid));
2407+
}
24002408
}

src/main/java/org/gridsuite/study/server/service/LoadFlowService.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,18 @@ public UUID getLoadFlowParametersOrDefaultsUuid(StudyEntity studyEntity) {
377377
return studyEntity.getLoadFlowParametersUuid();
378378
}
379379

380+
public String getLoadFlowProvider(UUID parametersUuid) {
381+
382+
String path = UriComponentsBuilder.fromPath(DELIMITER + LOADFLOW_API_VERSION + PARAMETERS_URI + "/provider")
383+
.buildAndExpand(parametersUuid).toUriString();
384+
385+
try {
386+
return restTemplate.getForObject(loadFlowServerBaseUri + path, String.class);
387+
} catch (HttpStatusCodeException e) {
388+
throw handleHttpError(e, GET_LOADFLOW_PROVIDER_FAILED);
389+
}
390+
}
391+
380392
@Override
381393
public List<String> getEnumValues(String enumName, UUID resultUuid) {
382394
return getEnumValues(enumName, resultUuid, LOADFLOW_API_VERSION, loadFlowServerBaseUri, LOADFLOW_NOT_FOUND, restTemplate);

src/main/java/org/gridsuite/study/server/service/NetworkModificationTreeService.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,11 +598,15 @@ private void assertNodeNameNotExist(UUID studyUuid, String nodeName) {
598598
}
599599

600600
public void assertIsRootOrConstructionNode(UUID nodeUuid) {
601-
if (!self.getNode(nodeUuid, null).getType().equals(NodeType.ROOT) && !getNetworkModificationNodeInfoEntity(nodeUuid).getNodeType().equals(NetworkModificationNodeType.CONSTRUCTION)) {
601+
if (!self.getNode(nodeUuid, null).getType().equals(NodeType.ROOT) && !isConstructionNode(nodeUuid)) {
602602
throw new StudyException(NOT_ALLOWED);
603603
}
604604
}
605605

606+
public boolean isConstructionNode(UUID nodeUuid) {
607+
return getNetworkModificationNodeInfoEntity(nodeUuid).getNodeType() == NetworkModificationNodeType.CONSTRUCTION;
608+
}
609+
606610
@Transactional(readOnly = true)
607611
public boolean isNodeNameExists(UUID studyUuid, String nodeName) {
608612
return ROOT_NODE_NAME.equals(nodeName) || !networkModificationNodeInfoRepository.findAllByNodeStudyIdAndName(studyUuid, nodeName).stream().filter(abstractNodeInfoEntity -> !abstractNodeInfoEntity.getNode().isStashed()).toList().isEmpty();

src/main/java/org/gridsuite/study/server/service/StudyService.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,7 @@
4141
import org.gridsuite.study.server.elasticsearch.EquipmentInfosService;
4242
import org.gridsuite.study.server.elasticsearch.StudyInfosService;
4343
import org.gridsuite.study.server.networkmodificationtree.dto.*;
44-
import org.gridsuite.study.server.networkmodificationtree.entities.NetworkModificationNodeInfoEntity;
45-
import org.gridsuite.study.server.networkmodificationtree.entities.NodeEntity;
46-
import org.gridsuite.study.server.networkmodificationtree.entities.NodeType;
47-
import org.gridsuite.study.server.networkmodificationtree.entities.RootNetworkNodeInfoEntity;
44+
import org.gridsuite.study.server.networkmodificationtree.entities.*;
4845
import org.gridsuite.study.server.notification.NotificationService;
4946
import org.gridsuite.study.server.notification.dto.NetworkImpactsInfos;
5047
import org.gridsuite.study.server.repository.*;
@@ -81,6 +78,7 @@
8178
import java.util.stream.Collectors;
8279
import java.util.stream.Stream;
8380

81+
import static org.gridsuite.study.server.StudyConstants.DYNA_FLOW_PROVIDER;
8482
import static org.gridsuite.study.server.StudyException.Type.*;
8583
import static org.gridsuite.study.server.dto.ComputationType.*;
8684
import static org.gridsuite.study.server.dto.InvalidateNodeTreeParameters.ALL_WITH_BLOCK_NODES;
@@ -959,6 +957,18 @@ public void assertIsNodeNotReadOnly(UUID nodeUuid) {
959957
}
960958
}
961959

960+
@Transactional(readOnly = true)
961+
public void assertCanRunLoadFLow(UUID studyUuid, UUID nodeUuid) {
962+
if (networkModificationTreeService.isConstructionNode(nodeUuid) && DYNA_FLOW_PROVIDER.equals(getLoadFlowProvider(studyUuid))) {
963+
throw new StudyException(NOT_ALLOWED, "DynaFlow must run only from a security type node !");
964+
}
965+
}
966+
967+
public String getLoadFlowProvider(UUID studyUuid) {
968+
StudyEntity studyEntity = studyRepository.findById(studyUuid).orElseThrow(() -> new StudyException(STUDY_NOT_FOUND));
969+
return loadflowService.getLoadFlowProvider(studyEntity.getLoadFlowParametersUuid());
970+
}
971+
962972
public void assertIsNodeExist(UUID studyUuid, UUID nodeUuid) {
963973
boolean exists = networkModificationTreeService.getAllNodes(studyUuid).stream()
964974
.anyMatch(nodeEntity -> nodeUuid.equals(nodeEntity.getIdNode()));

src/test/java/org/gridsuite/study/server/LoadFLowIntegrationTest.java

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import java.util.UUID;
5353

5454
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
55+
import static org.gridsuite.study.server.StudyConstants.DYNA_FLOW_PROVIDER;
5556
import static org.gridsuite.study.server.StudyConstants.*;
5657
import static org.junit.jupiter.api.Assertions.assertEquals;
5758
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -81,6 +82,7 @@ class LoadFLowIntegrationTest {
8182
String variantId = "variantId";
8283
UUID parametersUuid = UUID.randomUUID();
8384
UUID loadflowResultUuid = UUID.randomUUID();
85+
String testProvider = "test_provider";
8486

8587
String userId = "userId";
8688

@@ -172,20 +174,33 @@ void testRerunLoadFlowWithRatioTapChangers() throws Exception {
172174
Mockito.verify(networkModificationService, times(2)).deleteIndexedModifications(any(), any(UUID.class));
173175
}
174176

177+
@Test
178+
void testRerunLoadFlowNotAllowed() throws Exception {
179+
UUID loadFlowProviderStubUuid = wireMockUtils.stubLoadFlowProvider(parametersUuid, DYNA_FLOW_PROVIDER);
180+
mockMvc.perform(put("/v1/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/loadflow/run", studyUuid, rootNetworkUuid, nodeUuid, userId)
181+
.param(QUERY_WITH_TAP_CHANGER, "false")
182+
.header("userId", userId))
183+
.andExpect(status().isForbidden());
184+
wireMockUtils.verifyLoadFlowProviderGet(loadFlowProviderStubUuid, parametersUuid);
185+
}
186+
175187
private void runLoadFlow(boolean withRatioTapChangers) throws Exception {
176188
UUID runLoadflowStubUuid = wireMockUtils.stubRunLoadFlow(networkUuid, withRatioTapChangers, null, objectMapper.writeValueAsString(loadflowResultUuid));
177-
Mockito.doReturn(parametersUuid).when(loadFlowService).createDefaultLoadFlowParameters();
189+
UUID loadFlowProviderStubUuid = wireMockUtils.stubLoadFlowProvider(parametersUuid, testProvider);
178190
mockMvc.perform(put("/v1/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/loadflow/run", studyUuid, rootNetworkUuid, nodeUuid, userId)
179191
.param(QUERY_WITH_TAP_CHANGER, withRatioTapChangers ? "true" : "false")
180192
.header("userId", userId))
181193
.andExpect(status().isOk());
182194
wireMockUtils.verifyRunLoadflow(runLoadflowStubUuid, networkUuid, withRatioTapChangers, null);
195+
wireMockUtils.verifyLoadFlowProviderGet(loadFlowProviderStubUuid, parametersUuid);
183196
}
184197

185198
private void rerunLoadFlow(boolean withRatioTapChangers) throws Exception {
186199
UUID newLoadflowResultUuid = UUID.randomUUID();
187200
UUID stubDeleteLoadflowResultUuid = wireMockUtils.stubDeleteLoadFlowResults(List.of(loadflowResultUuid));
188201
UUID stubCreateRunningLoadflowStatusUuid = wireMockUtils.stubCreateRunningLoadflowStatus(objectMapper.writeValueAsString(newLoadflowResultUuid));
202+
UUID loadFlowProviderStubUuid = wireMockUtils.stubLoadFlowProvider(parametersUuid, testProvider);
203+
189204
Mockito.doReturn(parametersUuid).when(loadFlowService).createDefaultLoadFlowParameters();
190205

191206
assertNodeBlocked(nodeUuid, rootNetworkUuid, false);
@@ -195,12 +210,12 @@ private void rerunLoadFlow(boolean withRatioTapChangers) throws Exception {
195210
.header("userId", userId))
196211
.andExpect(status().isOk());
197212

198-
Mockito.verify(loadFlowService, times(1)).createDefaultLoadFlowParameters();
199213
wireMockUtils.verifyDeleteLoadFlowResults(stubDeleteLoadflowResultUuid, List.of(loadflowResultUuid));
200214
wireMockUtils.verifyCreateRunningLoadflowStatus(stubCreateRunningLoadflowStatusUuid);
201215
ArgumentCaptor<RerunLoadFlowInfos> rerunLoadFlowWorkflowInfosArgumentCaptor = ArgumentCaptor.forClass(RerunLoadFlowInfos.class);
202216
Mockito.verify(networkModificationService, times(1)).buildNode(eq(nodeUuid), eq(rootNetworkUuid), any(BuildInfos.class), rerunLoadFlowWorkflowInfosArgumentCaptor.capture());
203217
assertEquals(withRatioTapChangers, rerunLoadFlowWorkflowInfosArgumentCaptor.getValue().isWithRatioTapChangers());
218+
wireMockUtils.verifyLoadFlowProviderGet(loadFlowProviderStubUuid, parametersUuid);
204219

205220
// verify that the node is blocked
206221
// build is forbidden, for example
@@ -226,12 +241,13 @@ private StudyEntity insertStudy() {
226241
return StudyEntity.builder()
227242
.id(UUID.randomUUID())
228243
.voltageInitParameters(new StudyVoltageInitParametersEntity())
244+
.loadFlowParametersUuid(parametersUuid)
229245
.build();
230246
}
231247

232248
private NodeEntity insertNode(StudyEntity study, UUID nodeId, String variantId, UUID reportUuid, NodeEntity parentNode, RootNetworkEntity rootNetworkEntity, BuildStatus buildStatus) {
233249
NodeEntity nodeEntity = nodeRepository.save(new NodeEntity(nodeId, parentNode, NodeType.NETWORK_MODIFICATION, study, false, null));
234-
NetworkModificationNodeInfoEntity modificationNodeInfoEntity = networkModificationNodeInfoRepository.save(NetworkModificationNodeInfoEntity.builder().idNode(nodeEntity.getIdNode()).modificationGroupUuid(UUID.randomUUID()).build());
250+
NetworkModificationNodeInfoEntity modificationNodeInfoEntity = networkModificationNodeInfoRepository.save(NetworkModificationNodeInfoEntity.builder().idNode(nodeEntity.getIdNode()).modificationGroupUuid(UUID.randomUUID()).nodeType(NetworkModificationNodeType.CONSTRUCTION).build());
235251
createNodeLinks(rootNetworkEntity, modificationNodeInfoEntity, variantId, reportUuid, buildStatus);
236252
return nodeEntity;
237253
}

src/test/java/org/gridsuite/study/server/LoadFLowUnitTest.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,18 @@ class LoadFLowUnitTest {
7171
void testRunLoadFlow() {
7272
when(rootNetworkNodeInfoService.getComputationResultUuid(nodeUuid, rootNetworkUuid, LOAD_FLOW)).thenReturn(null);
7373
doReturn(loadflowResultUuid).when(studyService).sendLoadflowRequest(any(), any(), any(), any(), anyBoolean(), anyBoolean(), anyString());
74-
74+
doNothing().when(studyService).assertCanRunLoadFLow(any(), any());
7575
controller.runLoadFlow(studyUuid, nodeUuid, rootNetworkUuid, false, userId);
7676

7777
verify(studyService, times(1)).sendLoadflowRequest(any(), any(), any(), any(), anyBoolean(), anyBoolean(), anyString());
78+
verify(studyService, times(1)).assertCanRunLoadFLow(any(), any());
7879
}
7980

8081
@Test
8182
void testRunLoadFlowWithExistingResult() {
8283
UUID previousResultUuid = UUID.randomUUID();
8384
when(rootNetworkNodeInfoService.getComputationResultUuid(nodeUuid, rootNetworkUuid, LOAD_FLOW)).thenReturn(previousResultUuid);
85+
doNothing().when(studyService).assertCanRunLoadFLow(studyUuid, nodeUuid);
8486

8587
doNothing().when(studyService).deleteLoadflowResult(studyUuid, nodeUuid, rootNetworkUuid, previousResultUuid);
8688

@@ -92,6 +94,8 @@ void testRunLoadFlowWithExistingResult() {
9294
verify(studyService, times(1)).deleteLoadflowResult(studyUuid, nodeUuid, rootNetworkUuid, previousResultUuid);
9395
verify(studyService, times(1)).createLoadflowRunningStatus(studyUuid, nodeUuid, rootNetworkUuid, false);
9496
verify(studyService, times(1)).rerunLoadflow(studyUuid, nodeUuid, rootNetworkUuid, loadflowResultUuid, false, userId);
97+
verify(studyService, times(1)).assertCanRunLoadFLow(studyUuid, nodeUuid);
98+
9599
}
96100

97101
@Test

src/test/java/org/gridsuite/study/server/LoadFlowTest.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,9 @@ public MockResponse dispatch(RecordedRequest request) {
322322
} else if (path.matches("/v1/parameters/" + PROFILE_LOADFLOW_DUPLICATED_PARAMETERS_UUID_STRING + "/provider") && method.equals("PUT")) {
323323
// provider update in duplicated params OK
324324
return new MockResponse(200);
325+
} else if (path.matches("/v1/parameters/" + LOADFLOW_PARAMETERS_UUID + "/provider") && method.equals("GET")) {
326+
// provider update in duplicated params OK
327+
return new MockResponse.Builder().code(200).body(DEFAULT_PROVIDER).build();
325328
} else if (path.matches("/v1/parameters/default") && method.equals("POST")) {
326329
// create default parameters request
327330
return new MockResponse(200, Headers.of(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE),
@@ -376,7 +379,7 @@ void testLoadFlow(final MockWebServer server) throws Exception {
376379

377380
checkUpdateModelStatusMessagesReceived(studyNameUserIdUuid, NotificationService.UPDATE_TYPE_LOADFLOW_STATUS);
378381

379-
assertTrue(TestUtils.getRequestsDone(1, server).stream().anyMatch(r -> r.matches("/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?withRatioTapChangers=.*&receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID_2)));
382+
assertRequestsDone(server, List.of("/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?withRatioTapChangers=.*&receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID_2, "/v1/parameters/" + LOADFLOW_PARAMETERS_UUID + "/provider"));
380383

381384
// get loadflow result
382385
mvcResult = mockMvc.perform(get("/v1/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/loadflow/result", studyNameUserIdUuid, firstRootNetworkUuid, modificationNode3Uuid)).andExpectAll(
@@ -414,8 +417,14 @@ void testLoadFlow(final MockWebServer server) throws Exception {
414417
checkUpdateModelsStatusMessagesReceived(studyNameUserIdUuid, modificationNode2Uuid);
415418

416419
checkUpdateModelStatusMessagesReceived(studyNameUserIdUuid, NotificationService.UPDATE_TYPE_LOADFLOW_STATUS);
420+
assertRequestsDone(server, List.of("/v1/parameters/" + LOADFLOW_PARAMETERS_UUID + "/provider", "/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?withRatioTapChangers=.*&receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID));
421+
}
417422

418-
assertTrue(TestUtils.getRequestsDone(1, server).stream().anyMatch(r -> r.matches("/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?withRatioTapChangers=.*&receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID)));
423+
private static void assertRequestsDone(MockWebServer server, List<String> expectedPatterns) {
424+
var requests = TestUtils.getRequestsDone(2, server);
425+
for (String pattern : expectedPatterns) {
426+
assertTrue(requests.stream().anyMatch(r -> r.matches(pattern)));
427+
}
419428
}
420429

421430
@Test
@@ -441,7 +450,7 @@ void testGetLimitViolations(final MockWebServer server) throws Exception {
441450
checkUpdateModelsStatusMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid);
442451

443452
checkUpdateModelStatusMessagesReceived(studyNameUserIdUuid, NotificationService.UPDATE_TYPE_LOADFLOW_STATUS);
444-
assertTrue(TestUtils.getRequestsDone(1, server).stream().anyMatch(r -> r.matches("/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?withRatioTapChangers=.*&receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID_2)));
453+
assertRequestsDone(server, List.of("/v1/parameters/" + LOADFLOW_PARAMETERS_UUID + "/provider", "/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?withRatioTapChangers=.*&receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID_2));
445454

446455
// get computing status
447456
mockMvc.perform(get("/v1/studies/{studyUuid}/root-networks/{rootNetworkUuid}/nodes/{nodeUuid}/computation/result/enum-values?computingType={computingType}&enumName={enumName}",
@@ -498,7 +507,7 @@ void testInvalidateStatus(final MockWebServer server) throws Exception {
498507
checkUpdateModelsStatusMessagesReceived(studyNameUserIdUuid, modificationNode1Uuid);
499508

500509
checkUpdateModelStatusMessagesReceived(studyNameUserIdUuid, NotificationService.UPDATE_TYPE_LOADFLOW_STATUS);
501-
assertTrue(TestUtils.getRequestsDone(1, server).stream().anyMatch(r -> r.matches("/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?withRatioTapChangers=.*&receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID_2)));
510+
assertRequestsDone(server, List.of("/v1/parameters/" + LOADFLOW_PARAMETERS_UUID + "/provider", "/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?withRatioTapChangers=.*&receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID_2));
502511

503512
// invalidate status
504513
mockMvc.perform(put("/v1/studies/{studyUuid}/loadflow/invalidate-status", studyNameUserIdUuid)
@@ -543,8 +552,7 @@ void testDeleteLoadFlowResults(final MockWebServer server) throws Exception {
543552
checkUpdateModelsStatusMessagesReceived(studyNameUserIdUuid, modificationNode3Uuid);
544553

545554
checkUpdateModelStatusMessagesReceived(studyNameUserIdUuid, NotificationService.UPDATE_TYPE_LOADFLOW_STATUS);
546-
547-
assertTrue(TestUtils.getRequestsDone(1, server).stream().anyMatch(r -> r.matches("/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?withRatioTapChangers=.*&receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID_2)));
555+
assertRequestsDone(server, List.of("/v1/parameters/" + LOADFLOW_PARAMETERS_UUID + "/provider", "/v1/networks/" + NETWORK_UUID_STRING + "/run-and-save\\?withRatioTapChangers=.*&receiver=.*&reportUuid=.*&reporterId=.*&variantId=" + VARIANT_ID_2));
548556
//Test result count
549557
testResultCount(server);
550558
//Delete Voltage init results

0 commit comments

Comments
 (0)