From 7b120fc196a0517c95a5d8f93c4b72c5b9a72a0b Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Thu, 31 Oct 2013 12:39:12 +0200 Subject: [PATCH] Tests for validating reconnect works for streaming and websockets (#12868,#12853,#12852) Change-Id: I0e1e51291e9275a78737ad0e70e63b75ef993a63 --- uitest/ivy.xml | 3 +- .../src/com/vaadin/tests/push/BasicPush.java | 70 ++++++---- .../com/vaadin/tests/push/BasicPushTest.java | 50 ++++--- .../vaadin/tests/push/PushReconnectTest.java | 123 ++++++++++++++++++ .../tests/push/StreamingReconnectTest.java | 25 ++++ .../tests/push/WebsocketReconnectTest.java | 36 +++++ .../com/vaadin/tests/tb3/AbstractTB3Test.java | 2 +- .../tests/tb3/MultiBrowserTestWithProxy.java | 92 +++++++++++++ .../tests/tb3/PrivateTB3Configuration.java | 9 +- 9 files changed, 362 insertions(+), 48 deletions(-) create mode 100644 uitest/src/com/vaadin/tests/push/PushReconnectTest.java create mode 100755 uitest/src/com/vaadin/tests/push/StreamingReconnectTest.java create mode 100644 uitest/src/com/vaadin/tests/push/WebsocketReconnectTest.java create mode 100755 uitest/src/com/vaadin/tests/tb3/MultiBrowserTestWithProxy.java diff --git a/uitest/ivy.xml b/uitest/ivy.xml index d75a591f94..9c86b2b68c 100644 --- a/uitest/ivy.xml +++ b/uitest/ivy.xml @@ -73,7 +73,8 @@ - + counter = new ObjectProperty(0); private ObjectProperty counter2 = new ObjectProperty(0); @@ -48,15 +58,19 @@ public class BasicPush extends AbstractTestUI { */ Label lbl = new Label(counter); lbl.setCaption("Client counter (click 'increment' to update):"); + lbl.setId(CLIENT_COUNTER_ID); addComponent(lbl); - addComponent(new Button("Increment", new Button.ClickListener() { + Button incrementButton = new Button("Increment", + new Button.ClickListener() { - @Override - public void buttonClick(ClickEvent event) { - counter.setValue(counter.getValue() + 1); - } - })); + @Override + public void buttonClick(ClickEvent event) { + counter.setValue(counter.getValue() + 1); + } + }); + incrementButton.setId(INCREMENT_BUTTON_ID); + addComponent(incrementButton); spacer(); @@ -65,33 +79,37 @@ public class BasicPush extends AbstractTestUI { */ lbl = new Label(counter2); lbl.setCaption("Server counter (updates each 3s by server thread) :"); + lbl.setId(SERVER_COUNTER_ID); addComponent(lbl); - addComponent(new Button("Start timer", new Button.ClickListener() { - - @Override - public void buttonClick(ClickEvent event) { - counter2.setValue(0); - if (task != null) { - task.cancel(); - } - task = new TimerTask() { + Button startTimer = new Button("Start timer", + new Button.ClickListener() { @Override - public void run() { - access(new Runnable() { + public void buttonClick(ClickEvent event) { + counter2.setValue(0); + if (task != null) { + task.cancel(); + } + task = new TimerTask() { + @Override public void run() { - counter2.setValue(counter2.getValue() + 1); + access(new Runnable() { + @Override + public void run() { + counter2.setValue(counter2.getValue() + 1); + } + }); } - }); + }; + timer.scheduleAtFixedRate(task, 3000, 3000); } - }; - timer.scheduleAtFixedRate(task, 3000, 3000); - } - })); + }); + startTimer.setId(START_TIMER_ID); + addComponent(startTimer); - addComponent(new Button("Stop timer", new Button.ClickListener() { + Button stopTimer = new Button("Stop timer", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { if (task != null) { @@ -99,7 +117,9 @@ public class BasicPush extends AbstractTestUI { task = null; } } - })); + }); + stopTimer.setId(STOP_TIMER_ID); + addComponent(stopTimer); } @Override diff --git a/uitest/src/com/vaadin/tests/push/BasicPushTest.java b/uitest/src/com/vaadin/tests/push/BasicPushTest.java index 57af8524bc..ef40ae09dc 100644 --- a/uitest/src/com/vaadin/tests/push/BasicPushTest.java +++ b/uitest/src/com/vaadin/tests/push/BasicPushTest.java @@ -19,6 +19,7 @@ import org.junit.Assert; import org.junit.Test; import org.openqa.selenium.WebElement; +import com.vaadin.tests.tb3.AbstractTB3Test; import com.vaadin.tests.tb3.MultiBrowserTest; public abstract class BasicPushTest extends MultiBrowserTest { @@ -30,15 +31,13 @@ public abstract class BasicPushTest extends MultiBrowserTest { // Test client initiated push Assert.assertEquals(0, getClientCounter()); getIncrementButton().click(); - Assert.assertEquals( - "Client counter not incremented by button click", 1, - getClientCounter()); + Assert.assertEquals("Client counter not incremented by button click", + 1, getClientCounter()); getIncrementButton().click(); getIncrementButton().click(); getIncrementButton().click(); - Assert.assertEquals( - "Four clicks should have incremented counter to 4", 4, - getClientCounter()); + Assert.assertEquals("Four clicks should have incremented counter to 4", + 4, getClientCounter()); // Test server initiated push getServerCounterStartButton().click(); @@ -63,30 +62,47 @@ public abstract class BasicPushTest extends MultiBrowserTest { } private int getServerCounter() { - return Integer.parseInt(getServerCounterElement().getText()); + return getServerCounter(this); } private int getClientCounter() { - return Integer.parseInt(getClientCounterElement().getText()); + return getClientCounter(this); } - private WebElement getServerCounterElement() { - return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[4]/VLabel[0]"); + public static int getClientCounter(AbstractTB3Test t) { + WebElement clientCounterElem = t + .vaadinElementById(BasicPush.CLIENT_COUNTER_ID); + return Integer.parseInt(clientCounterElem.getText()); } - private WebElement getServerCounterStartButton() { - return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[5]/VButton[0]/domChild[0]/domChild[0]"); + private WebElement getIncrementButton() { + return getIncrementButton(this); } private WebElement getServerCounterStopButton() { - return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[6]/VButton[0]/domChild[0]/domChild[0]"); + return getServerCounterStopButton(this); } - private WebElement getIncrementButton() { - return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[2]/VButton[0]/domChild[0]/domChild[0]"); + private WebElement getServerCounterStartButton() { + return getServerCounterStartButton(this); + } + + public static int getServerCounter(AbstractTB3Test t) { + WebElement serverCounterElem = t + .vaadinElementById(BasicPush.SERVER_COUNTER_ID); + return Integer.parseInt(serverCounterElem.getText()); } - private WebElement getClientCounterElement() { - return vaadinElement("/VVerticalLayout[0]/Slot[1]/VVerticalLayout[0]/Slot[1]/VLabel[0]"); + public static WebElement getServerCounterStartButton(AbstractTB3Test t) { + return t.vaadinElementById(BasicPush.START_TIMER_ID); } + + public static WebElement getServerCounterStopButton(AbstractTB3Test t) { + return t.vaadinElementById(BasicPush.STOP_TIMER_ID); + } + + public static WebElement getIncrementButton(AbstractTB3Test t) { + return t.vaadinElementById(BasicPush.INCREMENT_BUTTON_ID); + } + } \ No newline at end of file diff --git a/uitest/src/com/vaadin/tests/push/PushReconnectTest.java b/uitest/src/com/vaadin/tests/push/PushReconnectTest.java new file mode 100644 index 0000000000..951e1eb576 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/PushReconnectTest.java @@ -0,0 +1,123 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed 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 com.vaadin.tests.push; + +import org.junit.Assert; +import org.junit.Test; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.ExpectedCondition; + +import com.vaadin.tests.tb3.MultiBrowserTestWithProxy; + +public abstract class PushReconnectTest extends MultiBrowserTestWithProxy { + + @Test + public void testShortDisconnect() throws Exception { + setDebug(true); + openTestURL(); + startTimer(); + waitUntilServerCounterChanges(); + disconnectProxy(); + Thread.sleep(1000); + connectProxy(); + waitUntilServerCounterChanges(); + } + + @Test + public void testUserActionWhileDisconnected() throws Exception { + setDebug(true); + openTestURL(); + startTimer(); + waitUntilServerCounterChanges(); + disconnectProxy(); + Assert.assertEquals(0, getClientCounter()); + getIncrementClientCounterButton().click(); + // No change while disconnected + Assert.assertEquals(0, getClientCounter()); + Thread.sleep(1000); + connectProxy(); + waitUntilServerCounterChanges(); + // The change should have appeared when reconnected + Assert.assertEquals(1, getClientCounter()); + } + + @Test + public void testLongDisconnect() throws Exception { + setDebug(true); + openTestURL(); + startTimer(); + waitUntilServerCounterChanges(); + disconnectProxy(); + Thread.sleep(12000); + connectProxy(); + waitUntilServerCounterChanges(); + } + + @Test + public void testMultipleDisconnects() throws Exception { + setDebug(true); + openTestURL(); + startTimer(); + waitUntilServerCounterChanges(); + for (int i = 0; i < 5; i++) { + disconnectProxy(); + Thread.sleep(1000); + connectProxy(); + waitUntilServerCounterChanges(); + } + } + + @Test + public void testMultipleQuickReconnects() throws Exception { + setDebug(true); + openTestURL(); + startTimer(); + waitUntilServerCounterChanges(); + for (int i = 0; i < 50; i++) { + disconnectProxy(); + Thread.sleep(50); + connectProxy(); + Thread.sleep(50); + } + waitUntilServerCounterChanges(); + waitUntilServerCounterChanges(); + } + + private int getClientCounter() { + return BasicPushTest.getClientCounter(this); + } + + private WebElement getIncrementClientCounterButton() { + return BasicPushTest.getIncrementButton(this); + } + + private void waitUntilServerCounterChanges() { + final int counter = BasicPushTest.getServerCounter(this); + waitUntil(new ExpectedCondition() { + + @Override + public Boolean apply(WebDriver input) { + return BasicPushTest.getServerCounter(PushReconnectTest.this) > counter; + } + }); + } + + private void startTimer() { + BasicPushTest.getServerCounterStartButton(this).click(); + } + +} diff --git a/uitest/src/com/vaadin/tests/push/StreamingReconnectTest.java b/uitest/src/com/vaadin/tests/push/StreamingReconnectTest.java new file mode 100755 index 0000000000..24dfdd8ba1 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/StreamingReconnectTest.java @@ -0,0 +1,25 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed 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 com.vaadin.tests.push; + +public class StreamingReconnectTest extends PushReconnectTest { + + @Override + protected Class getUIClass() { + return BasicPushStreaming.class; + } + +} diff --git a/uitest/src/com/vaadin/tests/push/WebsocketReconnectTest.java b/uitest/src/com/vaadin/tests/push/WebsocketReconnectTest.java new file mode 100644 index 0000000000..075a18c0e7 --- /dev/null +++ b/uitest/src/com/vaadin/tests/push/WebsocketReconnectTest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed 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 com.vaadin.tests.push; + +import java.util.List; + +import org.openqa.selenium.remote.DesiredCapabilities; + +import com.vaadin.tests.tb3.WebsocketTest; + +public class WebsocketReconnectTest extends PushReconnectTest { + + @Override + public List getBrowsersToTest() { + return WebsocketTest.getWebsocketBrowsers(); + } + + @Override + protected Class getUIClass() { + return BasicPushWebsocket.class; + } + +} diff --git a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java index 218c532beb..f9df2f0a71 100644 --- a/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java +++ b/uitest/src/com/vaadin/tests/tb3/AbstractTB3Test.java @@ -197,7 +197,7 @@ public abstract class AbstractTB3Test extends TestBenchTestCase { * * @return The port teh test is running on, by default 8888 */ - protected abstract String getDeploymentPort(); + protected abstract int getDeploymentPort(); /** * Produces a collection of browsers to run the test on. This method is diff --git a/uitest/src/com/vaadin/tests/tb3/MultiBrowserTestWithProxy.java b/uitest/src/com/vaadin/tests/tb3/MultiBrowserTestWithProxy.java new file mode 100755 index 0000000000..d3488a98c4 --- /dev/null +++ b/uitest/src/com/vaadin/tests/tb3/MultiBrowserTestWithProxy.java @@ -0,0 +1,92 @@ +/* + * Copyright 2000-2013 Vaadin Ltd. + * + * Licensed 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 com.vaadin.tests.tb3; + +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.After; +import org.junit.Before; + +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.JSchException; +import com.jcraft.jsch.Session; + +public abstract class MultiBrowserTestWithProxy extends MultiBrowserTest { + + private static AtomicInteger availablePort = new AtomicInteger(2000); + private Session proxySession; + private Integer proxyPort = null; + + @Before + public void setupInitialProxy() throws JSchException { + connectProxy(); + } + + @After + public void teardownProxy() { + disconnectProxy(); + } + + protected Integer getProxyPort() { + if (proxyPort == null) { + // Assumes we can use any port >= 2000 + proxyPort = availablePort.addAndGet(1); + } + return proxyPort; + } + + /** + * Disconnects the proxy if active + */ + protected void disconnectProxy() { + if (proxySession == null) { + return; + } + proxySession.disconnect(); + proxySession = null; + } + + /** + * Ensure the proxy is active. Does nothing if the proxy is already active. + */ + protected void connectProxy() throws JSchException { + if (proxySession != null) { + return; + } + + createProxy(getProxyPort()); + } + + private void createProxy(int proxyPort) throws JSchException { + JSch j = new JSch(); + String keyFile = System.getProperty("sshkey.file"); + if (keyFile == null) { + keyFile = "~/.ssh/id_rsa"; + } + j.addIdentity(keyFile); + proxySession = j.getSession("localhost"); + proxySession.setConfig("StrictHostKeyChecking", "no"); + proxySession.setPortForwardingL("0.0.0.0", proxyPort, + super.getDeploymentHostname(), super.getDeploymentPort()); + proxySession.connect(); + } + + @Override + protected String getBaseURL() { + return "http://" + getDeploymentHostname() + ":" + getProxyPort(); + } + +} diff --git a/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java b/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java index a2922af28f..caa35732d6 100644 --- a/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java +++ b/uitest/src/com/vaadin/tests/tb3/PrivateTB3Configuration.java @@ -90,11 +90,12 @@ public abstract class PrivateTB3Configuration extends ScreenshotTB3Test { } @Override - protected String getDeploymentPort() { - String port = getProperty(PORT_PROPERTY); + protected int getDeploymentPort() { + String portString = getProperty(PORT_PROPERTY); - if (port == null || "".equals(port)) { - port = "8888"; + int port = 8888; + if (portString != null && !"".equals(portString)) { + port = Integer.parseInt(portString); } return port; -- 2.39.5