Skip to content

Commit

Permalink
Do not connect backward dependencies to listener when invalidate - Test
Browse files Browse the repository at this point in the history
Signed-off-by: GONCALVES Bruno <[email protected]>
  • Loading branch information
GONCALVES Bruno committed Apr 24, 2024
1 parent a2b0dd6 commit 595bbed
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 137 deletions.
6 changes: 6 additions & 0 deletions afs-core/src/main/java/com/powsybl/afs/ProjectNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ public List<ProjectFile> getBackwardDependencies() {
return getBackwardDependencies(true);
}

/**
* Retrieve backward dependencies <br />
* Use connected to false if the node is used immediately in a local scope and if it doesn't need to update itself on events, as in {@link #invalidate()}
* @param connected connect the node to eventBus events
* @return dependencies
*/
public List<ProjectFile> getBackwardDependencies(boolean connected) {
return storage.getBackwardDependencies(info.getId())
.stream()
Expand Down
45 changes: 39 additions & 6 deletions afs-core/src/test/java/com/powsybl/afs/AfsBaseTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@
import com.google.common.jimfs.Configuration;
import com.google.common.jimfs.Jimfs;
import com.powsybl.afs.mapdb.storage.MapDbAppStorage;
import com.powsybl.afs.storage.AfsStorageException;
import com.powsybl.afs.storage.AppStorage;
import com.powsybl.afs.storage.InMemoryEventsBus;
import com.powsybl.afs.storage.NodeGenericMetadata;
import com.powsybl.afs.storage.NodeInfo;
import com.powsybl.afs.storage.*;
import com.powsybl.afs.storage.events.NodeEvent;
import com.powsybl.computation.ComputationManager;
import com.powsybl.iidm.network.NetworkFactoryService;
import com.powsybl.timeseries.RegularTimeSeriesIndex;
Expand Down Expand Up @@ -57,7 +54,7 @@ public void setup() {
fileSystem = Jimfs.newFileSystem(Configuration.unix());
ComputationManager computationManager = Mockito.mock(ComputationManager.class);
ad = new AppData(computationManager, computationManager, Collections.emptyList(),
Collections.emptyList(), Collections.singletonList(new FooFileExtension()), Collections.emptyList());
Collections.emptyList(), List.of(new FooFileExtension(), new WithDependencyFileExtension()), Collections.emptyList());

storage = MapDbAppStorage.createMem("mem", ad.getEventsBus());

Expand Down Expand Up @@ -566,4 +563,40 @@ void hasDeepDependencyTest() {
otherFile.setDependencies("dep", Collections.singletonList(createdFile));
assertTrue(createdFile.hasDeepDependency(createdFile, "dep"));
}

@Test
public void invalidate() {
Folder folder = afs.getRootFolder().createFolder("testFolder");
Project project = folder.createProject("test");
FooFile fooFile = project.getRootFolder().fileBuilder(FooFileBuilder.class).withName("Foo").build();
WithDependencyFile fileWithDep = project.getRootFolder().fileBuilder(WithDependencyFileBuilder.class).build();
fileWithDep.setFooDependency(fooFile);

// Previous code add connected WithDependencyFile with listeners
storage.getEventsBus().flush();
storage.getEventsBus().removeListeners();

fooFile.invalidate();

// WithDependencyFile is not connected => don't store event
String nodeEventType = "type";
storage.getEventsBus().pushEvent(new NodeEvent("id", nodeEventType) {
}, "Topic");
storage.getEventsBus().flush();
Optional<NodeEvent> updateEvent = fileWithDep.events.stream().filter(nodeEvent -> nodeEventType.equals(nodeEvent.getType())).findFirst();
assertTrue(updateEvent.isEmpty());

// WithDependencyFile is not connected => store event
List<ProjectFile> connectedBackwardDependencies = fooFile.getBackwardDependencies(true);
storage.getEventsBus().pushEvent(new NodeEvent("id", nodeEventType) {
}, "Topic");
storage.getEventsBus().flush();
assertEquals(1, connectedBackwardDependencies.size());
assertEquals(WithDependencyFile.class, connectedBackwardDependencies.get(0).getClass());
WithDependencyFile withDependencyFile = (WithDependencyFile) connectedBackwardDependencies.get(0);
Optional<NodeEvent> updateEvent2 = withDependencyFile.events.stream()
.filter(nodeEvent -> nodeEventType.equals(nodeEvent.getType()))
.findFirst();
assertFalse(updateEvent2.isEmpty());
}
}
137 changes: 6 additions & 131 deletions afs-core/src/test/java/com/powsybl/afs/DependencyCacheTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@
import com.powsybl.afs.mapdb.storage.MapDbAppStorage;
import com.powsybl.afs.storage.AppStorage;
import com.powsybl.afs.storage.InMemoryEventsBus;
import com.powsybl.afs.storage.NodeGenericMetadata;
import com.powsybl.afs.storage.NodeInfo;
import org.junit.jupiter.api.Test;

import java.util.Collections;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
Expand All @@ -25,149 +22,27 @@
*/
class DependencyCacheTest extends AbstractProjectFileTest {

class Tic extends ProjectFile {

Tic(ProjectFileCreationContext context) {
super(context, 0);
}
}

class TicBuilder implements ProjectFileBuilder<Tic> {

private final ProjectFileBuildContext context;

private String name;

TicBuilder(ProjectFileBuildContext context) {
this.context = context;
}

public TicBuilder setName(String name) {
this.name = name;
return this;
}

@Override
public Tic build() {
NodeInfo info = context.getStorage().createNode(context.getFolderInfo().getId(), name, "TIC", "", 0, new NodeGenericMetadata());
context.getStorage().setConsistent(info.getId());
return new Tic(new ProjectFileCreationContext(info, context.getStorage(), context.getProject()));
}
}

class TicExtension implements ProjectFileExtension<Tic, TicBuilder> {

@Override
public Class<Tic> getProjectFileClass() {
return Tic.class;
}

@Override
public String getProjectFilePseudoClass() {
return "TIC";
}

@Override
public Class<TicBuilder> getProjectFileBuilderClass() {
return TicBuilder.class;
}

@Override
public Tic createProjectFile(ProjectFileCreationContext context) {
return new Tic(context);
}

@Override
public ProjectFileBuilder<Tic> createProjectFileBuilder(ProjectFileBuildContext context) {
return new TicBuilder(context);
}
}

class Tac extends ProjectFile {

private static final String DEP_NAME = "dep";

private final DependencyCache<ProjectFile> cache = new DependencyCache<>(this, DEP_NAME, ProjectFile.class);

Tac(ProjectFileCreationContext context) {
super(context, 0);
}

ProjectFile getTicDependency() {
return cache.getFirst().orElse(null);
}

void setTicDependency(Tic tic) {
setDependencies(DEP_NAME, Collections.singletonList(tic));
cache.invalidate();
}
}

class TacBuilder implements ProjectFileBuilder<Tac> {

private final ProjectFileBuildContext context;

TacBuilder(ProjectFileBuildContext context) {
this.context = context;
}

@Override
public Tac build() {
NodeInfo info = context.getStorage().createNode(context.getFolderInfo().getId(), "tac", "TAC", "", 0, new NodeGenericMetadata());
context.getStorage().setConsistent(info.getId());
return new Tac(new ProjectFileCreationContext(info, context.getStorage(), context.getProject()));
}
}

class TacExtension implements ProjectFileExtension<Tac, TacBuilder> {

@Override
public Class<Tac> getProjectFileClass() {
return Tac.class;
}

@Override
public String getProjectFilePseudoClass() {
return "TAC";
}

@Override
public Class<TacBuilder> getProjectFileBuilderClass() {
return TacBuilder.class;
}

@Override
public Tac createProjectFile(ProjectFileCreationContext context) {
return new Tac(context);
}

@Override
public ProjectFileBuilder<Tac> createProjectFileBuilder(ProjectFileBuildContext context) {
return new TacBuilder(context);
}
}

@Override
protected AppStorage createStorage() {
return MapDbAppStorage.createMem("mem", new InMemoryEventsBus());
}

@Override
protected List<ProjectFileExtension> getProjectFileExtensions() {
return ImmutableList.of(new TicExtension(), new TacExtension());
return ImmutableList.of(new FooFileExtension(), new WithDependencyFileExtension());
}

@Test
void test() {
Project project = afs.getRootFolder().createProject("project");
Tic tic = project.getRootFolder().fileBuilder(TicBuilder.class).setName("tic").build();
Tic tic2 = project.getRootFolder().fileBuilder(TicBuilder.class).setName("tic2").build();
Tac tac = project.getRootFolder().fileBuilder(TacBuilder.class).build();
FooFile tic = project.getRootFolder().fileBuilder(FooFileBuilder.class).withName("tic").build();
FooFile tic2 = project.getRootFolder().fileBuilder(FooFileBuilder.class).withName("tic2").build();
WithDependencyFile tac = project.getRootFolder().fileBuilder(WithDependencyFileBuilder.class).build();
assertNull(tac.getTicDependency());
tac.setTicDependency(tic);
tac.setFooDependency(tic);
assertNotNull(tac.getTicDependency());
assertEquals(tic.getId(), tac.getTicDependency().getId());
tac.setTicDependency(tic2);
tac.setFooDependency(tic2);
assertNotNull(tac.getTicDependency());
assertEquals(tic2.getId(), tac.getTicDependency().getId());
}
Expand Down
31 changes: 31 additions & 0 deletions afs-core/src/test/java/com/powsybl/afs/WithDependencyFile.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.powsybl.afs;

import com.powsybl.afs.storage.events.NodeEvent;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class WithDependencyFile extends ProjectFile {

private static final String DEP_NAME = "dep";

private final DependencyCache<ProjectFile> cache = new DependencyCache<>(this, DEP_NAME, ProjectFile.class);
final List<NodeEvent> events = new ArrayList<>();

WithDependencyFile(ProjectFileCreationContext context) {
super(context, 0);
if (context.isConnected()) {
context.getStorage().getEventsBus().addListener(eventList -> events.addAll(eventList.getEvents()));
}
}

ProjectFile getTicDependency() {
return cache.getFirst().orElse(null);
}

void setFooDependency(FooFile foo) {
setDependencies(DEP_NAME, Collections.singletonList(foo));
cache.invalidate();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.powsybl.afs;

import com.powsybl.afs.storage.NodeGenericMetadata;
import com.powsybl.afs.storage.NodeInfo;

public class WithDependencyFileBuilder implements ProjectFileBuilder<WithDependencyFile> {

private final ProjectFileBuildContext context;

WithDependencyFileBuilder(ProjectFileBuildContext context) {
this.context = context;
}

@Override
public WithDependencyFile build() {
NodeInfo info = context.getStorage().createNode(context.getFolderInfo().getId(), "WithDependencyFile", "WITH_DEPENDENCY_FILE", "", 0, new NodeGenericMetadata());
context.getStorage().setConsistent(info.getId());
return new WithDependencyFile(new ProjectFileCreationContext(info, context.getStorage(), context.getProject()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.powsybl.afs;

public class WithDependencyFileExtension implements ProjectFileExtension<WithDependencyFile, WithDependencyFileBuilder> {

@Override
public Class<WithDependencyFile> getProjectFileClass() {
return WithDependencyFile.class;
}

@Override
public String getProjectFilePseudoClass() {
return "WITH_DEPENDENCY_FILE";
}

@Override
public Class<WithDependencyFileBuilder> getProjectFileBuilderClass() {
return WithDependencyFileBuilder.class;
}

@Override
public WithDependencyFile createProjectFile(ProjectFileCreationContext context) {
return new WithDependencyFile(context);
}

@Override
public ProjectFileBuilder<WithDependencyFile> createProjectFileBuilder(ProjectFileBuildContext context) {
return new WithDependencyFileBuilder(context);
}
}

0 comments on commit 595bbed

Please sign in to comment.