...22import org.openqa.selenium.grid.commands.Hub;23import org.openqa.selenium.grid.commands.Standalone;24import org.openqa.selenium.grid.config.CompoundConfig;25import org.openqa.selenium.grid.config.Config;26import org.openqa.selenium.grid.config.MapConfig;27import org.openqa.selenium.grid.config.MemoizedConfig;28import org.openqa.selenium.grid.config.TomlConfig;29import org.openqa.selenium.grid.distributor.httpd.DistributorServer;30import org.openqa.selenium.grid.node.httpd.NodeServer;31import org.openqa.selenium.grid.router.httpd.RouterServer;32import org.openqa.selenium.grid.server.Server;33import org.openqa.selenium.grid.sessionmap.httpd.SessionMapServer;34import org.openqa.selenium.grid.sessionqueue.httpd.NewSessionQueueServer;35import org.openqa.selenium.grid.web.Values;36import org.openqa.selenium.json.Json;37import org.openqa.selenium.json.JsonOutput;38import org.openqa.selenium.net.PortProber;39import org.openqa.selenium.remote.http.HttpClient;40import org.openqa.selenium.remote.http.HttpRequest;41import org.openqa.selenium.remote.http.HttpResponse;42import org.openqa.selenium.support.ui.FluentWait;43import org.openqa.selenium.testing.Safely;44import org.openqa.selenium.testing.TearDownFixture;45import java.io.IOException;46import java.io.StringReader;47import java.io.UncheckedIOException;48import java.net.ConnectException;49import java.time.Duration;50import java.util.Arrays;51import java.util.List;52import java.util.Map;53public enum DeploymentTypes {54 STANDALONE {55 @Override56 public Deployment start(Capabilities capabilities, Config additionalConfig) {57 StringBuilder rawCaps = new StringBuilder();58 try (JsonOutput out = new Json().newOutput(rawCaps)) {59 out.setPrettyPrint(false).write(capabilities);60 }61 String[] rawConfig = new String[]{62 "[network]",63 "relax-checks = true",64 "",65 "[server]",66 "registration-secret = \"provolone\"",67 "",68 "[sessionqueue]",69 "session-request-timeout = 100",70 "session-retry-interval = 1"71 };72 Config config = new MemoizedConfig(73 new CompoundConfig(74 additionalConfig,75 new TomlConfig(new StringReader(String.join("\n", rawConfig)))));76 Server<?> server = new Standalone().asServer(new CompoundConfig(setRandomPort(), config)).start();77 waitUntilReady(server, Duration.ofSeconds(5));78 return new Deployment(server, server::stop);79 }80 },81 HUB_AND_NODE {82 @Override83 public Deployment start(Capabilities capabilities, Config additionalConfig) {84 StringBuilder rawCaps = new StringBuilder();85 try (JsonOutput out = new Json().newOutput(rawCaps)) {86 out.setPrettyPrint(false).write(capabilities);87 }88 int publish = PortProber.findFreePort();89 int subscribe = PortProber.findFreePort();90 String[] rawConfig = new String[] {91 "[events]",92 "publish = \"tcp://localhost:" + publish + "\"",93 "subscribe = \"tcp://localhost:" + subscribe + "\"",94 "",95 "[network]",96 "relax-checks = true",97 "",98 "[server]",99 "registration-secret = \"feta\"",100 "",101 "[sessionqueue]",102 "session-request-timeout = 100",103 "session-retry-interval = 1"104 };105 Config baseConfig = new MemoizedConfig(106 new CompoundConfig(107 additionalConfig,108 new TomlConfig(new StringReader(String.join("\n", rawConfig)))));109 Config hubConfig = new MemoizedConfig(110 new CompoundConfig(111 setRandomPort(),112 new MapConfig(Map.of("events", Map.of("bind", true))),113 baseConfig));114 Server<?> hub = new Hub().asServer(hubConfig).start();115 MapConfig additionalNodeConfig = new MapConfig(Map.of("node", Map.of("hub", hub.getUrl())));116 Config nodeConfig = new MemoizedConfig(117 new CompoundConfig(118 additionalNodeConfig,119 setRandomPort(),120 baseConfig));121 Server<?> node = new NodeServer().asServer(nodeConfig).start();122 waitUntilReady(node, Duration.ofSeconds(5));123 waitUntilReady(hub, Duration.ofSeconds(5));124 return new Deployment(hub, hub::stop, node::stop);125 }126 },127 DISTRIBUTED {128 @Override129 public Deployment start(Capabilities capabilities, Config additionalConfig) {130 StringBuilder rawCaps = new StringBuilder();131 try (JsonOutput out = new Json().newOutput(rawCaps)) {132 out.setPrettyPrint(false).write(capabilities);133 }134 int publish = PortProber.findFreePort();135 int subscribe = PortProber.findFreePort();136 String[] rawConfig = new String[] {137 "[events]",138 "publish = \"tcp://localhost:" + publish + "\"",139 "subscribe = \"tcp://localhost:" + subscribe + "\"",140 "bind = false",141 "",142 "[network]",143 "relax-checks = true",144 "",145 "[server]",146 "",147 "registration-secret = \"colby\"",148 "",149 "[sessionqueue]",150 "session-request-timeout = 100",151 "session-retry-interval = 1"152 };153 Config sharedConfig = new MemoizedConfig(154 new CompoundConfig(155 additionalConfig,156 new TomlConfig(new StringReader(String.join("\n", rawConfig)))));157 Server<?> eventServer = new EventBusCommand()158 .asServer(new MemoizedConfig(new CompoundConfig(159 new TomlConfig(new StringReader(String.join("\n", new String[] {160 "[events]",161 "publish = \"tcp://localhost:" + publish + "\"",162 "subscribe = \"tcp://localhost:" + subscribe + "\"",163 "bind = true"}))),164 setRandomPort(),165 sharedConfig)))166 .start();167 waitUntilReady(eventServer, Duration.ofSeconds(5));168 Server<?> newSessionQueueServer = new NewSessionQueueServer()169 .asServer(new MemoizedConfig(new CompoundConfig(setRandomPort(), sharedConfig))).start();170 waitUntilReady(newSessionQueueServer, Duration.ofSeconds(5));171 Config newSessionQueueServerConfig = new TomlConfig(new StringReader(String.join(172 "\n",173 new String[] {174 "[sessionqueue]",175 "hostname = \"localhost\"",176 "port = " + newSessionQueueServer.getUrl().getPort()177 }178 )));179 Server<?> sessionMapServer = new SessionMapServer()180 .asServer(new MemoizedConfig(new CompoundConfig(setRandomPort(), sharedConfig))).start();181 Config sessionMapConfig = new TomlConfig(new StringReader(String.join(182 "\n",183 new String[] {184 "[sessions]",185 "hostname = \"localhost\"",186 "port = " + sessionMapServer.getUrl().getPort()187 }188 )));189 Server<?> distributorServer = new DistributorServer()190 .asServer(new MemoizedConfig(new CompoundConfig(191 setRandomPort(),192 sessionMapConfig,193 newSessionQueueServerConfig,194 sharedConfig)))195 .start();196 Config distributorConfig = new TomlConfig(new StringReader(String.join(197 "\n",198 new String[] {199 "[distributor]",200 "hostname = \"localhost\"",201 "port = " + distributorServer.getUrl().getPort()202 }203 )));204 Server<?> router = new RouterServer()205 .asServer(new MemoizedConfig(new CompoundConfig(206 setRandomPort(),207 sessionMapConfig,208 distributorConfig,209 newSessionQueueServerConfig,210 sharedConfig)))211 .start();212 MapConfig nodeConfig = new MapConfig(Map.of("node", Map.of("hub", router.getUrl())));213 Server<?> nodeServer = new NodeServer()214 .asServer(new MemoizedConfig(new CompoundConfig(215 nodeConfig,216 setRandomPort(),217 sharedConfig,218 sessionMapConfig,219 distributorConfig,220 newSessionQueueServerConfig)))221 .start();222 waitUntilReady(nodeServer, Duration.ofSeconds(5));223 waitUntilReady(router, Duration.ofSeconds(5));224 return new Deployment(225 router,226 router::stop,227 nodeServer::stop,228 distributorServer::stop,229 sessionMapServer::stop,230 newSessionQueueServer::stop,231 eventServer::stop);232 }233 };234 private static Config setRandomPort() {235 return new MapConfig(Map.of("server", Map.of("port", PortProber.findFreePort())));236 }237 private static void waitUntilReady(Server<?> server, Duration duration) {238 HttpClient client = HttpClient.Factory.createDefault().createClient(server.getUrl());239 try {240 new FluentWait<>(client)241 .withTimeout(duration)242 .pollingEvery(Duration.ofMillis(250))243 .ignoring(IOException.class)244 .ignoring(UncheckedIOException.class)245 .ignoring(ConnectException.class)246 .until(247 c -> {248 HttpResponse response = c.execute(new HttpRequest(GET, "/status"));249 Map<String, Object> status = Values.get(response, MAP_TYPE);...