Make ThreadPantheonNodeRunner support plugin tests. (#1477)

* Do plugin lifecycle in ThreadPantheonNodeRunner
* Sniff out rendezvous directory for test during register call, it changes.
Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>
pull/2/head
Danno Ferrin 6 years ago committed by GitHub
parent f171a87049
commit f27c8d74fa
  1. 3
      acceptance-tests/build.gradle
  2. 30
      acceptance-tests/src/test/java/tech/pegasys/pantheon/tests/acceptance/dsl/node/ThreadPantheonNodeRunner.java
  3. 8
      plugins/src/test/java/tech/pegasys/pantheon/plugins/TestPantheonEventsPlugin.java
  4. 5
      plugins/src/test/java/tech/pegasys/pantheon/plugins/TestPicoCLIPlugin.java

@ -27,9 +27,11 @@ dependencies {
testImplementation project(':ethereum:eth')
testImplementation project(':ethereum:graphql')
testImplementation project(':ethereum:jsonrpc')
testImplementation project(':ethereum:p2p')
testImplementation project(':ethereum:permissioning')
testImplementation project(':ethereum:rlp')
testImplementation project(':metrics:core')
testImplementation project(':plugins')
testImplementation project(path: ':plugins', configuration: 'testArtifacts')
testImplementation project(':pantheon')
testImplementation project(':services:kvstore')
@ -38,6 +40,7 @@ dependencies {
testImplementation 'com.google.guava:guava'
testImplementation 'com.squareup.okhttp3:okhttp'
testImplementation 'info.picocli:picocli'
testImplementation 'io.reactivex.rxjava2:rxjava'
testImplementation 'io.vertx:vertx-core'
testImplementation 'junit:junit'

@ -26,9 +26,15 @@ import tech.pegasys.pantheon.ethereum.eth.transactions.PendingTransactions;
import tech.pegasys.pantheon.ethereum.graphql.GraphQLConfiguration;
import tech.pegasys.pantheon.metrics.MetricsSystem;
import tech.pegasys.pantheon.metrics.noop.NoOpMetricsSystem;
import tech.pegasys.pantheon.plugins.internal.PantheonPluginContextImpl;
import tech.pegasys.pantheon.plugins.services.PantheonEvents;
import tech.pegasys.pantheon.plugins.services.PicoCLIOptions;
import tech.pegasys.pantheon.services.PantheonEventsImpl;
import tech.pegasys.pantheon.services.PicoCLIOptionsImpl;
import tech.pegasys.pantheon.services.kvstore.RocksDbConfiguration;
import tech.pegasys.pantheon.util.enode.EnodeURL;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.time.Clock;
@ -45,6 +51,8 @@ import com.google.common.io.Files;
import io.vertx.core.Vertx;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import picocli.CommandLine;
import picocli.CommandLine.Model.CommandSpec;
public class ThreadPantheonNodeRunner implements PantheonNodeRunner {
@ -52,12 +60,28 @@ public class ThreadPantheonNodeRunner implements PantheonNodeRunner {
private final Map<String, Runner> pantheonRunners = new HashMap<>();
private ExecutorService nodeExecutor = Executors.newCachedThreadPool();
private final Map<Node, PantheonPluginContextImpl> pantheonPluginContextMap = new HashMap<>();
@Override
public void startNode(final PantheonNode node) {
if (nodeExecutor == null || nodeExecutor.isShutdown()) {
nodeExecutor = Executors.newCachedThreadPool();
}
final CommandLine commandLine = new CommandLine(CommandSpec.create());
final PantheonPluginContextImpl pantheonPluginContext =
pantheonPluginContextMap.computeIfAbsent(node, n -> new PantheonPluginContextImpl());
pantheonPluginContext.addService(PicoCLIOptions.class, new PicoCLIOptionsImpl(commandLine));
final Path pluginsPath = node.homeDirectory().resolve("plugins");
final File pluginsDirFile = pluginsPath.toFile();
if (!pluginsDirFile.isDirectory()) {
pluginsDirFile.mkdirs();
pluginsDirFile.deleteOnExit();
}
System.setProperty("pantheon.plugins.dir", pluginsPath.toString());
pantheonPluginContext.registerPlugins(pluginsPath);
commandLine.parseArgs(node.getConfiguration().getExtraCLIOptions().toArray(new String[0]));
final MetricsSystem noOpMetricsSystem = new NoOpMetricsSystem();
final List<EnodeURL> bootnodes =
node.getConfiguration().getBootnodes().stream()
@ -95,6 +119,11 @@ public class ThreadPantheonNodeRunner implements PantheonNodeRunner {
final RunnerBuilder runnerBuilder = new RunnerBuilder();
node.getPermissioningConfiguration().ifPresent(runnerBuilder::permissioningConfiguration);
pantheonPluginContext.addService(
PantheonEvents.class,
new PantheonEventsImpl(pantheonController.getProtocolManager().getBlockBroadcaster()));
pantheonPluginContext.startPlugins();
final Runner runner =
runnerBuilder
.vertx(Vertx.vertx())
@ -120,6 +149,7 @@ public class ThreadPantheonNodeRunner implements PantheonNodeRunner {
@Override
public void stopNode(final PantheonNode node) {
pantheonPluginContextMap.get(node).stopPlugins();
node.stop();
killRunner(node.getName());
}

@ -28,15 +28,18 @@ import org.apache.logging.log4j.Logger;
@AutoService(PantheonPlugin.class)
public class TestPantheonEventsPlugin implements PantheonPlugin {
private static final Logger LOG = LogManager.getLogger();
private Optional<Object> subscriptionId;
private PantheonContext context;
private Optional<Object> subscriptionId;
private final AtomicInteger blockCounter = new AtomicInteger();
private File callbackDir;
@Override
public void register(final PantheonContext context) {
this.context = context;
LOG.info("Registered");
callbackDir = new File(System.getProperty("pantheon.plugins.dir", "plugins"));
}
@Override
@ -62,8 +65,7 @@ public class TestPantheonEventsPlugin implements PantheonPlugin {
final int blockCount = blockCounter.incrementAndGet();
LOG.info("I got a new block! (I've seen {}) - {}", blockCount, json);
try {
final File callbackFile =
new File(System.getProperty("pantheon.plugins.dir", "plugins"), "newBlock." + blockCount);
final File callbackFile = new File(callbackDir, "newBlock." + blockCount);
if (!callbackFile.getParentFile().exists()) {
callbackFile.getParentFile().mkdirs();
callbackFile.getParentFile().deleteOnExit();

@ -32,6 +32,7 @@ public class TestPicoCLIPlugin implements PantheonPlugin {
String testOption = System.getProperty("testPicoCLIPlugin.testOption");
private String state = "uninited";
private File callbackDir;
@Override
public void register(final PantheonContext context) {
@ -49,6 +50,7 @@ public class TestPicoCLIPlugin implements PantheonPlugin {
picoCLIOptions ->
picoCLIOptions.addPicoCLIOptions("Test PicoCLI Plugin", TestPicoCLIPlugin.this));
callbackDir = new File(System.getProperty("pantheon.plugins.dir", "plugins"));
writeSignal("registered");
state = "registered";
}
@ -89,8 +91,7 @@ public class TestPicoCLIPlugin implements PantheonPlugin {
/** This is used to signal to the acceptance test that certain tasks were completed. */
private void writeSignal(final String signal) {
try {
final File callbackFile =
new File(System.getProperty("pantheon.plugins.dir", "plugins"), "testPlugin." + signal);
final File callbackFile = new File(callbackDir, "testPlugin." + signal);
if (!callbackFile.getParentFile().exists()) {
callbackFile.getParentFile().mkdirs();
callbackFile.getParentFile().deleteOnExit();

Loading…
Cancel
Save