Introduce PluginDependencyTracker

This commit is contained in:
Rene Pfeuffer
2019-09-16 11:42:26 +02:00
parent 0142258705
commit 14451897b2
2 changed files with 123 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
package sonia.scm.plugin;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import static sonia.scm.ScmConstraintViolationException.Builder.doThrow;
class PluginDependencyTracker {
private final Map<String, Collection<String>> plugins = new HashMap<>();
void addInstalled(PluginDescriptor plugin) {
plugin.getDependencies().forEach(dependency -> addDependency(plugin.getInformation().getName(), dependency));
}
void removeInstalled(PluginDescriptor plugin) {
doThrow()
.violation("Plugin is needed as a dependency for other plugins", "plugin")
.when(!mayUninstall(plugin.getInformation().getName()));
plugin.getDependencies().forEach(dependency -> removeDependency(plugin.getInformation().getName(), dependency));
}
boolean mayUninstall(String name) {
return plugins.computeIfAbsent(name, x -> new HashSet<>()).isEmpty();
}
private void addDependency(String from, String to) {
plugins.computeIfAbsent(to, name -> createInitialDependencyCollection(from));
}
private void removeDependency(String from, String to) {
plugins.get(to).remove(from);
}
private Collection<String> createInitialDependencyCollection(String from) {
Collection<String> dependencies = new HashSet<>();
dependencies.add(from);
return dependencies;
}
}

View File

@@ -0,0 +1,81 @@
package sonia.scm.plugin;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import sonia.scm.ScmConstraintViolationException;
import static java.util.Collections.emptySet;
import static java.util.Collections.singleton;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
import static sonia.scm.plugin.PluginTestHelper.createInstalled;
class PluginDependencyTrackerTest {
@Test
void simpleInstalledPluginWithoutDependingPluginsCanBeUninstalled() {
PluginDescriptor mail = createInstalled("scm-mail-plugin").getDescriptor();
when(mail.getDependencies()).thenReturn(emptySet());
PluginDependencyTracker pluginDependencyTracker = new PluginDependencyTracker();
pluginDependencyTracker.addInstalled(mail);
boolean mayUninstall = pluginDependencyTracker.mayUninstall("scm-mail-plugin");
assertThat(mayUninstall).isTrue();
}
@Test
void installedPluginWithDependingPluginCannotBeUninstalled() {
PluginDescriptor review = createInstalled("scm-review-plugin").getDescriptor();
when(review.getDependencies()).thenReturn(singleton("scm-mail-plugin"));
PluginDependencyTracker pluginDependencyTracker = new PluginDependencyTracker();
pluginDependencyTracker.addInstalled(review);
boolean mayUninstall = pluginDependencyTracker.mayUninstall("scm-mail-plugin");
assertThat(mayUninstall).isFalse();
}
@Test
void uninstallOfRequiredPluginShouldThrowException() {
PluginDescriptor review = createInstalled("scm-review-plugin").getDescriptor();
when(review.getDependencies()).thenReturn(singleton("scm-mail-plugin"));
PluginDependencyTracker pluginDependencyTracker = new PluginDependencyTracker();
pluginDependencyTracker.addInstalled(review);
Assertions.assertThrows(
ScmConstraintViolationException.class,
() -> pluginDependencyTracker.removeInstalled(createInstalled("scm-mail-plugin").getDescriptor())
);
}
@Test
void installedPluginWithDependingPluginCanBeUninstalledAfterDependingPluginIsUninstalled() {
PluginDescriptor review = createInstalled("scm-review-plugin").getDescriptor();
when(review.getDependencies()).thenReturn(singleton("scm-mail-plugin"));
PluginDependencyTracker pluginDependencyTracker = new PluginDependencyTracker();
pluginDependencyTracker.addInstalled(review);
pluginDependencyTracker.removeInstalled(review);
boolean mayUninstall = pluginDependencyTracker.mayUninstall("scm-mail-plugin");
assertThat(mayUninstall).isTrue();
}
@Test
void installedPluginWithMultipleDependingPluginCannotBeUninstalledAfterOnlyOneDependingPluginIsUninstalled() {
PluginDescriptor review = createInstalled("scm-review-plugin").getDescriptor();
when(review.getDependencies()).thenReturn(singleton("scm-mail-plugin"));
PluginDescriptor jira = createInstalled("scm-jira-plugin").getDescriptor();
when(jira.getDependencies()).thenReturn(singleton("scm-mail-plugin"));
PluginDependencyTracker pluginDependencyTracker = new PluginDependencyTracker();
pluginDependencyTracker.addInstalled(review);
pluginDependencyTracker.addInstalled(jira);
pluginDependencyTracker.removeInstalled(jira);
boolean mayUninstall = pluginDependencyTracker.mayUninstall("scm-mail-plugin");
assertThat(mayUninstall).isFalse();
}
}