blob: 173742b16d695e502799ca0d5c20cfeeac33a257 [file] [log] [blame]
/*
Copyright 2011 Selenium committers
Copyright 2011 Software Freedom Conservancy
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 org.openqa.grid.internal;
import static org.openqa.grid.common.RegistrationRequest.APP;
import static org.openqa.grid.common.RegistrationRequest.CLEAN_UP_CYCLE;
import static org.openqa.grid.common.RegistrationRequest.ID;
import static org.openqa.grid.common.RegistrationRequest.TIME_OUT;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.grid.common.RegistrationRequest;
import org.openqa.grid.internal.listeners.TimeoutListener;
import org.openqa.grid.internal.mock.GridHelper;
import org.openqa.grid.web.servlet.handler.RequestHandler;
public class SessionTimesOutTest {
private static RegistrationRequest req = new RegistrationRequest();
private static Map<String, Object> app1 = new HashMap<String, Object>();
// create a request for a proxy that times out after 0.5 sec.
@BeforeClass
public static void setup() {
app1.put(APP, "app1");
req.addDesiredCapability(app1);
Map<String, Object> config = new HashMap<String, Object>();
// a test is timed out is inactive for more than 0.5 sec.
config.put(TIME_OUT, 50);
// every 0.5 sec, the proxy check is something has timed out.
config.put(CLEAN_UP_CYCLE, 400);
config.put(ID, "abc");
config.put("host", "localhost");
req.setConfiguration(config);
}
class MyRemoteProxyTimeout extends BaseRemoteProxy implements TimeoutListener {
public MyRemoteProxyTimeout(RegistrationRequest request, Registry registry) {
super(request, registry);
}
public void beforeRelease(TestSession session) {
}
}
/**
* check that the proxy is freed after it times out.
*/
@Test(timeout = 2000)
public void testTimeout() throws InterruptedException {
Registry registry = Registry.newInstance();
RemoteProxy p1 = new MyRemoteProxyTimeout(req, registry);
p1.setupTimeoutListener();
try {
registry.add(p1);
RequestHandler newSessionRequest = GridHelper.createNewSessionHandler(registry, app1);
newSessionRequest.process();
TestSession session = newSessionRequest.getSession();
// wait for a timeout
Thread.sleep(500);
RequestHandler newSessionRequest2 = GridHelper.createNewSessionHandler(registry, app1);
newSessionRequest2.process();
TestSession session2 = newSessionRequest2.getSession();
Assert.assertNotNull(session2);
Assert.assertNotSame(session, session2);
} finally {
registry.stop();
}
}
private static boolean timeoutDone = false;
class MyRemoteProxyTimeoutSlow extends BaseRemoteProxy implements TimeoutListener {
public MyRemoteProxyTimeoutSlow(RegistrationRequest request, Registry registry) {
super(request, registry);
}
public void beforeRelease(TestSession session) {
try {
Thread.sleep(1000);
timeoutDone = true;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Test(timeout = 5000)
public void testTimeoutSlow() throws InterruptedException {
Registry registry = Registry.newInstance();
RemoteProxy p1 = new MyRemoteProxyTimeoutSlow(req, registry);
p1.setupTimeoutListener();
try {
registry.add(p1);
RequestHandler newSessionRequest = GridHelper.createNewSessionHandler(registry, app1);
newSessionRequest.process();
TestSession session = newSessionRequest.getSession();
// timeout cleanup will start
Thread.sleep(500);
// but the session finishes before the timeout cleanup finishes
registry.terminate(session, SessionTerminationReason.CLIENT_STOPPED_SESSION);
// wait to have the slow time out process finished
int i = 0;
while (timeoutDone == false) {
if (i >= 4) {
throw new RuntimeException("should be true");
}
Thread.sleep(250);
}
Assert.assertTrue(timeoutDone);
RequestHandler newSessionRequest2 = GridHelper.createNewSessionHandler(registry, app1);
newSessionRequest2.process();
TestSession session2 = newSessionRequest2.getSession();
Assert.assertNotNull(session2);
Assert.assertTrue(session.equals(session));
Assert.assertFalse(session2.equals(session));
} finally {
registry.stop();
}
}
class MyBuggyRemoteProxyTimeout extends BaseRemoteProxy implements TimeoutListener {
public MyBuggyRemoteProxyTimeout(RegistrationRequest request, Registry registry) {
super(request, registry);
}
public void beforeRelease(TestSession session) {
throw new NullPointerException();
}
}
// a proxy throwing an exception will end up not releasing the resources.
@Test(timeout = 1000)
public void testTimeoutBug() throws InterruptedException {
final Registry registry = Registry.newInstance();
RemoteProxy p1 = new MyBuggyRemoteProxyTimeout(req, registry);
p1.setupTimeoutListener();
try {
registry.add(p1);
RequestHandler newSessionRequest = GridHelper.createNewSessionHandler(registry, app1);
newSessionRequest.process();
final RequestHandler newSessionRequest2 =
GridHelper.createNewSessionHandler(registry, app1);
new Thread(new Runnable() { // Thread safety reviewed
public void run() {
// the request should never be processed because the
// resource is not released by the buggy proxy
newSessionRequest2.process();
}
}).start();
// wait for a timeout
Thread.sleep(500);
// the request has not been processed yet.
Assert.assertNull(newSessionRequest2.getServerSession());
} finally {
registry.stop();
}
}
class MyStupidConfig extends BaseRemoteProxy implements TimeoutListener {
public MyStupidConfig(RegistrationRequest request, Registry registry) {
super(request, registry);
}
public void beforeRelease(TestSession session) {
session.put("FLAG", true);
session.put("MustSupportNullValue", null);
session.put(null, "MustSupportNullKey");
}
}
@Test(timeout = 10000)
public void stupidConfig() throws InterruptedException {
Object[][] configs = new Object[][]{
// correct config, just to check something happens
{5, 5},
// and invalid ones
{-1, 5}, {5, -1}, {-1, -1}, {0, 0}};
java.util.List<Registry> registryList = new ArrayList<Registry>();
try {
for (Object[] c : configs) {
int timeout = (Integer) c[0];
int cycle = (Integer) c[1];
Registry registry = Registry.newInstance();
registryList.add(registry);
RegistrationRequest req = new RegistrationRequest();
Map<String, Object> app1 = new HashMap<String, Object>();
app1.put(APP, "app1");
req.addDesiredCapability(app1);
Map<String, Object> config = new HashMap<String, Object>();
config.put(TIME_OUT, timeout);
config.put(CLEAN_UP_CYCLE, cycle);
config.put(ID, "abc");
config.put("host", "localhost");
req.setConfiguration(config);
final MyStupidConfig proxy = new MyStupidConfig(req, registry);
proxy.setupTimeoutListener();
registry.add(proxy);
RequestHandler newSessionRequest = GridHelper.createNewSessionHandler(registry, app1);
newSessionRequest.process();
TestSession session = newSessionRequest.getSession();
// wait -> timed out and released.
Thread.sleep(500);
boolean shouldTimeout = timeout > 0 && cycle > 0;
if (shouldTimeout) {
Assert.assertEquals(session.get("FLAG"), true);
Assert.assertNull(session.getSlot().getSession());
} else {
Assert.assertNull(session.get("FLAG"));
Assert.assertNotNull(session.getSlot().getSession());
}
}
} finally {
for (Registry registry : registryList) {
registry.stop();
}
}
}
}