Repository: incubator-ignite Updated Branches: refs/heads/ignite-1201 0a31799b4 -> 9c4b87ef3
IGNITE-1201 Add tests. Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/9c4b87ef Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/9c4b87ef Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/9c4b87ef Branch: refs/heads/ignite-1201 Commit: 9c4b87ef3c67bead76e371228127d0ceb4f100cf Parents: 0a31799 Author: sevdokimov <sevdoki...@gridgain.com> Authored: Mon Aug 10 18:58:00 2015 +0300 Committer: sevdokimov <sevdoki...@gridgain.com> Committed: Mon Aug 10 18:58:00 2015 +0300 ---------------------------------------------------------------------- modules/control-center-agent/pom.xml | 37 +++ .../org/apache/ignite/agent/AgentLauncher.java | 7 + .../org/apache/ignite/agent/AgentSocket.java | 10 +- .../org/apache/ignite/agent/AgentUtils.java | 8 + .../ignite/agent/AbstractAgentTestCase.java | 266 +++++++++++++++++++ .../java/org/apache/ignite/agent/AgentTest.java | 132 +++++++++ 6 files changed, 452 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9c4b87ef/modules/control-center-agent/pom.xml ---------------------------------------------------------------------- diff --git a/modules/control-center-agent/pom.xml b/modules/control-center-agent/pom.xml index 63f0dcd..7acbfea 100644 --- a/modules/control-center-agent/pom.xml +++ b/modules/control-center-agent/pom.xml @@ -67,6 +67,43 @@ <artifactId>httpclient</artifactId> <version>4.5</version> </dependency> + + <!--Test dependencies--> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-core</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.ignite</groupId> + <artifactId>ignite-rest-http</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.eclipse.jetty.websocket</groupId> + <artifactId>websocket-server</artifactId> + <version>${jetty.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.eclipse.jetty.websocket</groupId> + <artifactId>javax-websocket-server-impl</artifactId> + <version>${jetty.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> </dependencies> <build> http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9c4b87ef/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentLauncher.java ---------------------------------------------------------------------- diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentLauncher.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentLauncher.java index 2b43a79..e00d40a 100644 --- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentLauncher.java +++ b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentLauncher.java @@ -124,4 +124,11 @@ public class AgentLauncher { agentLauncher.run(); } + + /** + * @return Config. + */ + public AgentConfiguration config() { + return cfg; + } } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9c4b87ef/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentSocket.java ---------------------------------------------------------------------- diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentSocket.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentSocket.java index a1f23f2..e77aa51 100644 --- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentSocket.java +++ b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentSocket.java @@ -37,12 +37,6 @@ public class AgentSocket implements WebSocketSender { private static final Logger log = Logger.getLogger(AgentSocket.class.getName()); /** */ - public static final Gson GSON = new Gson(); - - /** */ - public static final JsonParser PARSER = new JsonParser(); - - /** */ private final CountDownLatch closeLatch = new CountDownLatch(1); /** */ @@ -109,7 +103,7 @@ public class AgentSocket implements WebSocketSender { * @return Whether or not message was sent. */ @Override public boolean send(JsonObject msg) { - return send(GSON.toJson(msg)); + return send(AgentUtils.GSON.toJson(msg)); } /** @@ -151,7 +145,7 @@ public class AgentSocket implements WebSocketSender { */ @OnWebSocketMessage public void onMessage(String msg) { - JsonElement jsonElement = PARSER.parse(msg); + JsonElement jsonElement = AgentUtils.PARSER.parse(msg); remote.onMessage((JsonObject)jsonElement); } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9c4b87ef/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentUtils.java ---------------------------------------------------------------------- diff --git a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentUtils.java b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentUtils.java index 0675e3f..827645a 100644 --- a/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentUtils.java +++ b/modules/control-center-agent/src/main/java/org/apache/ignite/agent/AgentUtils.java @@ -17,6 +17,8 @@ package org.apache.ignite.agent; +import com.google.gson.*; + import java.io.*; import java.net.*; @@ -24,6 +26,12 @@ import java.net.*; * Utility methods. */ public class AgentUtils { + /** */ + public static final Gson GSON = new Gson(); + + /** */ + public static final JsonParser PARSER = new JsonParser(); + /** * Default constructor. */ http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9c4b87ef/modules/control-center-agent/src/test/java/org/apache/ignite/agent/AbstractAgentTestCase.java ---------------------------------------------------------------------- diff --git a/modules/control-center-agent/src/test/java/org/apache/ignite/agent/AbstractAgentTestCase.java b/modules/control-center-agent/src/test/java/org/apache/ignite/agent/AbstractAgentTestCase.java new file mode 100644 index 0000000..7e57130 --- /dev/null +++ b/modules/control-center-agent/src/test/java/org/apache/ignite/agent/AbstractAgentTestCase.java @@ -0,0 +1,266 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.agent; + +import com.google.gson.*; +import org.apache.ignite.*; +import org.apache.ignite.configuration.*; +import org.apache.ignite.spi.discovery.tcp.*; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.*; +import org.eclipse.jetty.server.*; +import org.eclipse.jetty.servlet.*; +import org.eclipse.jetty.websocket.jsr356.server.ServerContainer; +import org.eclipse.jetty.websocket.jsr356.server.deploy.*; +import org.eclipse.jetty.websocket.server.*; +import org.jetbrains.annotations.*; +import org.junit.*; + +import javax.websocket.*; +import javax.websocket.server.*; +import java.io.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; + +import static org.junit.Assert.*; + +/** + * + */ +public class AbstractAgentTestCase { + /** */ + protected static final int REST_PORT = 8792; + + /** */ + protected static final int WEB_SOCKET_PORT = 8387; + + /** */ + protected static final BlockingQueue<EventSocket> clientConns = new LinkedBlockingQueue<>(); + + /** + * + */ + @BeforeClass + public static void startIgnite() { + IgniteConfiguration cfg = new IgniteConfiguration(); + + cfg.setLocalHost("127.0.0.1"); + + cfg.setDiscoverySpi(new TcpDiscoverySpi().setIpFinder(new TcpDiscoveryVmIpFinder(true))); + + ConnectorConfiguration ccfg = new ConnectorConfiguration(); + + cfg.setConnectorConfiguration(ccfg); + + System.setProperty(IgniteSystemProperties.IGNITE_JETTY_PORT, String.valueOf(REST_PORT)); + + Ignition.start(cfg); + } + + /** + * + */ + protected Server startWebSocket() throws Exception { + WebSocketServerFactory s = new WebSocketServerFactory(); + + Server webSockSrv = new Server(); + ServerConnector connector = new ServerConnector(webSockSrv); + connector.setPort(WEB_SOCKET_PORT); + webSockSrv.addConnector(connector); + + // Setup the basic application "context" for this application at "/" + // This is also known as the handler tree (in jetty speak) + ServletContextHandler ctx = new ServletContextHandler(ServletContextHandler.SESSIONS); + ctx.setContextPath("/"); + webSockSrv.setHandler(ctx); + + // Initialize javax.websocket layer + ServerContainer wscontainer = WebSocketServerContainerInitializer.configureContext(ctx); + + // Add WebSocket endpoint to javax.websocket layer + wscontainer.addEndpoint(EventSocket.class); + + webSockSrv.start(); + + s.start(); + + return webSockSrv; + } + + /** + * + */ + @Before + public void validate() { + assert clientConns.isEmpty(); + } + + /** + * @return REST port. + */ + protected int restPort() { + return REST_PORT; + } + + /** + * + */ + @AfterClass + public static void stopIgnite() { + Ignite ignite = Ignition.ignite(); + + ignite.close(); + } + + /** + * + */ + @ClientEndpoint + @ServerEndpoint(value = "/") + public static class EventSocket { + /** */ + private final AtomicLong msgCnt = new AtomicLong(); + + /** */ + private Session ses; + + /** */ + private final SynchronousQueue<String> incomeMsgQueue = new SynchronousQueue<>(); + + /** + * @param ses Session. + */ + @OnOpen + public void onWebSocketConnect(Session ses) { + this.ses = ses; + + clientConns.add(this); + } + + /** + * @param msg Message. + */ + @OnMessage + public void onWebSocketText(String msg) { + incomeMsgQueue.add(msg); + } + +// /** +// * @param reason Reason. +// */ +// @OnClose +// public void onWebSocketClose(CloseReason reason) { +// // No +// } + + /** + * @param cause Cause. + */ + @OnError + public void onWebSocketError(Throwable cause) { + cause.printStackTrace(System.err); + } + + /** + * @return Session. + */ + public Session session() { + return ses; + } + + /** + * @return Incoming message. + */ + public JsonObject receiveMessage() throws InterruptedException { + String msgStr = incomeMsgQueue.take(); + + return (JsonObject)AgentUtils.PARSER.parse(msgStr); + } + + /** + * @param mtdName Method name. + * @param args Args. + */ + public JsonElement sendAndWait(String mtdName, Object ... args) throws IOException, InterruptedException { + long reqId = msgCnt.incrementAndGet(); + + sendMessage(reqId, mtdName, args); + + JsonObject res = receiveMessage(); + + assertEquals(reqId, res.get("reqId").getAsLong()); + + return res.get("res"); + } + + /** + * @param mtdName Method name. + * @param args Args. + */ + public void sendMessage(String mtdName, Object ... args) throws IOException { + sendMessage(null, mtdName, args); + } + + /** + * @param reqId Request id. + * @param mtdName Method name. + * @param args Args. + */ + private void sendMessage(@Nullable Long reqId, String mtdName, Object ... args) throws IOException { + JsonObject json = new JsonObject(); + + json.addProperty("mtdName", mtdName); + + if (reqId != null) + json.addProperty("reqId", reqId); + + JsonArray argsJson = new JsonArray(); + + for (Object arg : args) + argsJson.add(AgentUtils.GSON.toJsonTree(arg)); + + json.add("args", argsJson); + + ses.getBasicRemote().sendText(AgentUtils.GSON.toJson(json)); + } + } + + /** + * @param login Login. + */ + protected AgentConfiguration createAgentConfig(String login) { + AgentConfiguration agentCfg = new AgentConfiguration(); + agentCfg.setLogin(login); + agentCfg.setPassword("1"); + + agentCfg.setServerUri("ws://localhost:" + WEB_SOCKET_PORT); + agentCfg.setNodeUri("http://localhost:" + restPort()); + + return agentCfg; + } + + /** + * @param msg Message. + * @param login Login. + * @param pwd Password. + */ + protected void validateAuth(JsonObject msg, String login, String pwd) { + assertEquals("AuthMessage", msg.get("type").getAsString()); + assertEquals(login, msg.get("login").getAsString()); + assertEquals(pwd, msg.get("password").getAsString()); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/9c4b87ef/modules/control-center-agent/src/test/java/org/apache/ignite/agent/AgentTest.java ---------------------------------------------------------------------- diff --git a/modules/control-center-agent/src/test/java/org/apache/ignite/agent/AgentTest.java b/modules/control-center-agent/src/test/java/org/apache/ignite/agent/AgentTest.java new file mode 100644 index 0000000..fd9669a --- /dev/null +++ b/modules/control-center-agent/src/test/java/org/apache/ignite/agent/AgentTest.java @@ -0,0 +1,132 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.agent; + +import com.google.gson.*; +import org.eclipse.jetty.server.*; +import org.junit.*; + +/** + * + */ +public class AgentTest extends AbstractAgentTestCase { + /** + * + */ + @Test + public void testAvailableDrivers() throws Exception { + Server srv = startWebSocket(); + + try { + final AgentLauncher l = new AgentLauncher(createAgentConfig("1")); + + Thread agentThread = new Thread(new Runnable() { + @Override public void run() { + try { + l.run(); + } + catch (InterruptedException ignored) { + // No-op. + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + }); + + agentThread.start(); + + try { + EventSocket conn = clientConns.take(); + + JsonObject msg = conn.receiveMessage(); + + validateAuth(msg, l.config().getLogin(), l.config().getPassword()); + + conn.sendMessage("authResult", (Object)null); + + JsonElement resp = conn.sendAndWait("availableDrivers"); + + Assert.assertTrue(resp instanceof JsonArray); + } + finally { + agentThread.interrupt(); + + agentThread.join(); + } + } + finally { + srv.stop(); + } + } + + /** + * + */ + @Test + public void testAgentReconnect() throws Exception { + final AgentLauncher l = new AgentLauncher(createAgentConfig("1")); + + Thread agentThread = new Thread(new Runnable() { + @Override public void run() { + try { + l.run(); + } + catch (InterruptedException ignored) { + // No-op. + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + }); + + agentThread.start(); + + try { + Server srv = startWebSocket(); + + try { + clientConns.take(); // Wait for agent connection. + } + finally { + srv.stop(); + } + + srv = startWebSocket(); + + try { + EventSocket conn = clientConns.take(); + + JsonObject msg = conn.receiveMessage(); + + validateAuth(msg, l.config().getLogin(), l.config().getPassword()); + + conn.sendMessage("authResult", (Object)null); + } + finally { + srv.stop(); + } + } + finally { + agentThread.interrupt(); + + agentThread.join(); + } + } +}