Skip to content
This repository has been archived by the owner on Sep 21, 2021. It is now read-only.

Commit

Permalink
Merge pull request #24 from zalando-incubator/improve-startup
Browse files Browse the repository at this point in the history
* Improve startup 
* fix little bug in start script when docker version is not matching
* Improve coverage
  • Loading branch information
diemol authored Nov 18, 2016
2 parents b09a432 + bd160cd commit 51ea2bb
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 17 deletions.
11 changes: 10 additions & 1 deletion scripts/zalenium.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ EnsureCleanEnv()
fi
}

EnsureDockerWorks()
{
if ! docker images elgalu/selenium >/dev/null; then
echo "Docker seems to be not working properly, check the above error."
exit 1
fi
}

DockerTerminate()
{
echo "Trapped SIGTERM/SIGINT so shutting down Zalenium gracefully..."
Expand All @@ -37,6 +45,7 @@ trap DockerTerminate SIGTERM SIGINT SIGKILL

StartUp()
{
EnsureDockerWorks
EnsureCleanEnv

DOCKER_SELENIUM_IMAGE_COUNT=$(docker images | grep "elgalu/selenium" | wc -l)
Expand Down Expand Up @@ -110,7 +119,7 @@ StartUp()
if [ "${IN_TRAVIS}" = "true" ]; then
sleep 20
else
sleep 10
sleep 2
fi
echo "DockerSeleniumStarter node started!"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public class DockerSeleniumStarterRemoteProxy extends DefaultRemoteProxy impleme
private static CommonProxyUtilities commonProxyUtilities = defaultCommonProxyUtilities;

private static final String LOGGING_PREFIX = "[DS] ";
private boolean setupCompleted;

private static int chromeContainersOnStartup;
private static int firefoxContainersOnStartup;
Expand Down Expand Up @@ -134,20 +135,14 @@ public TestSession getNewSession(Map<String, Object> requestedCapability) {

/*
Starting a few containers (Firefox, Chrome), so they are ready when the tests come.
Executed in a thread so we don't wait for the containers to be created and the node
registration is not delayed.
*/
@Override
public void beforeRegistration() {
readConfigurationFromEnvVariables();
if (getChromeContainersOnStartup() > 0 || getFirefoxContainersOnStartup() > 0) {
LOGGER.log(Level.INFO, LOGGING_PREFIX + "Setting up {0} Firefox nodes and {1} Chrome nodes ready to use.",
new Object[]{getFirefoxContainersOnStartup(), getChromeContainersOnStartup()});
for (int i = 0; i < getChromeContainersOnStartup(); i++) {
startDockerSeleniumContainer(BrowserType.CHROME);
}
for (int i = 0; i < getFirefoxContainersOnStartup(); i++) {
startDockerSeleniumContainer(BrowserType.FIREFOX);
}
}
setupCompleted = false;
createStartupContainers();
}

/*
Expand Down Expand Up @@ -216,7 +211,7 @@ public static List<DesiredCapabilities> getCapabilities(String url) {
}

@VisibleForTesting
protected void startDockerSeleniumContainer(String browser) {
protected boolean startDockerSeleniumContainer(String browser) {

if (validateAmountOfDockerSeleniumContainers()) {

Expand Down Expand Up @@ -273,10 +268,12 @@ protected void startDockerSeleniumContainer(String browser) {
final ContainerCreation dockerSeleniumContainer = dockerClient.createContainer(containerConfig,
containerName);
dockerClient.startContainer(dockerSeleniumContainer.id());
return true;
} catch (Exception e) {
LOGGER.log(Level.SEVERE, LOGGING_PREFIX + e.toString(), e);
}
}
return false;
}

private String getLatestDownloadedImage(String imageName) throws DockerException, InterruptedException {
Expand Down Expand Up @@ -369,6 +366,10 @@ public static void setScreenHeight(int screenHeight) {
DockerSeleniumStarterRemoteProxy.screenHeight = screenHeight <= 0 ? DEFAULT_SCREEN_HEIGHT : screenHeight;
}

public boolean isSetupCompleted() {
return setupCompleted;
}

@VisibleForTesting
protected static void setEnv(final Environment env) {
DockerSeleniumStarterRemoteProxy.env = env;
Expand Down Expand Up @@ -416,7 +417,32 @@ protected static List<DesiredCapabilities> getDockerSeleniumFallbackCapabilities
return dsCapabilities;
}

private boolean validateAmountOfDockerSeleniumContainers() {
private void createStartupContainers() {
int configuredContainers = getChromeContainersOnStartup() + getFirefoxContainersOnStartup();
int containersToCreate = configuredContainers > getMaxDockerSeleniumContainers() ?
getMaxDockerSeleniumContainers() : configuredContainers;
new Thread() {
@Override
public void run() {
LOGGER.log(Level.INFO, String.format("%s Setting up %s nodes...", LOGGING_PREFIX, configuredContainers));
int createdContainers = 0;
while (createdContainers < containersToCreate &&
getNumberOfRunningContainers() <= getMaxDockerSeleniumContainers()) {
boolean wasContainerCreated;
if (createdContainers < getChromeContainersOnStartup()) {
wasContainerCreated = startDockerSeleniumContainer(BrowserType.CHROME);
} else {
wasContainerCreated = startDockerSeleniumContainer(BrowserType.FIREFOX);
}
createdContainers = wasContainerCreated ? createdContainers + 1 : createdContainers;
}
LOGGER.log(Level.INFO, String.format("%s containers were created.", createdContainers));
setupCompleted = true;
}
}.start();
}

private int getNumberOfRunningContainers() {
try {
List<Container> containerList = dockerClient.listContainers(DockerClient.ListContainersParam.allContainers());
int numberOfDockerSeleniumContainers = 0;
Expand All @@ -426,6 +452,16 @@ private boolean validateAmountOfDockerSeleniumContainers() {
numberOfDockerSeleniumContainers++;
}
}
return numberOfDockerSeleniumContainers;
} catch (Exception e) {
LOGGER.log(Level.SEVERE, LOGGING_PREFIX + e.toString(), e);
}
return 0;
}

private boolean validateAmountOfDockerSeleniumContainers() {
try {
int numberOfDockerSeleniumContainers = getNumberOfRunningContainers();

/*
Validation to avoid the situation where 20 containers are running and only 4 proxies are registered.
Expand All @@ -441,10 +477,11 @@ private boolean validateAmountOfDockerSeleniumContainers() {
return false;
}

LOGGER.log(Level.FINE, LOGGING_PREFIX + "{0} docker-selenium containers running", containerList.size());
LOGGER.log(Level.FINE, String.format("%s %s docker-selenium containers running", LOGGING_PREFIX,
numberOfDockerSeleniumContainers));
if (numberOfDockerSeleniumContainers >= getMaxDockerSeleniumContainers()) {
LOGGER.log(Level.FINE, LOGGING_PREFIX + "Max. number of docker-selenium containers has been reached, no more " +
"will be created until the number decreases below {0}.", getMaxDockerSeleniumContainers());
LOGGER.log(Level.FINE, LOGGING_PREFIX + "Max. number of docker-selenium containers has been reached, " +
"no more will be created until the number decreases below {0}.", getMaxDockerSeleniumContainers());
return false;
}
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ private static RegistrationRequest addCapabilitiesToRegistrationRequest(Registra
for (JsonElement cap : slCapabilities.getAsJsonArray()) {
JsonObject capAsJsonObject = cap.getAsJsonObject();
DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
desiredCapabilities.setCapability(RegistrationRequest.MAX_INSTANCES, 10);
desiredCapabilities.setCapability(RegistrationRequest.MAX_INSTANCES, 1);
desiredCapabilities.setBrowserName(capAsJsonObject.get("api_name").getAsString());
desiredCapabilities.setPlatform(getPlatform(capAsJsonObject.get("os").getAsString()));
desiredCapabilities.setVersion(capAsJsonObject.get("long_version").getAsString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ public void videoRecordingIsStartedAndStopped() throws DockerException, Interrup
DockerSeleniumStarterRemoteProxy.class.getCanonicalName());
DockerSeleniumStarterRemoteProxy dsProxy = new DockerSeleniumStarterRemoteProxy(request, registry);
DockerSeleniumStarterRemoteProxy.setMaxDockerSeleniumContainers(1);
DockerSeleniumStarterRemoteProxy.setScreenHeight(DockerSeleniumStarterRemoteProxy.DEFAULT_SCREEN_HEIGHT);
DockerSeleniumStarterRemoteProxy.setScreenWidth(DockerSeleniumStarterRemoteProxy.DEFAULT_SCREEN_WIDTH);
DockerSeleniumStarterRemoteProxy.setTimeZone(DockerSeleniumStarterRemoteProxy.DEFAULT_TZ);
dsProxy.getNewSession(getCapabilitySupportedByDockerSelenium());

// Creating a spy proxy to verify the invoked methods
Expand Down Expand Up @@ -243,6 +246,9 @@ public void videoRecordingIsDisabled() throws DockerException, InterruptedExcept
DockerSeleniumStarterRemoteProxy.class.getCanonicalName());
DockerSeleniumStarterRemoteProxy dsProxy = new DockerSeleniumStarterRemoteProxy(request, registry);
DockerSeleniumStarterRemoteProxy.setMaxDockerSeleniumContainers(1);
DockerSeleniumStarterRemoteProxy.setScreenHeight(DockerSeleniumStarterRemoteProxy.DEFAULT_SCREEN_HEIGHT);
DockerSeleniumStarterRemoteProxy.setScreenWidth(DockerSeleniumStarterRemoteProxy.DEFAULT_SCREEN_WIDTH);
DockerSeleniumStarterRemoteProxy.setTimeZone(DockerSeleniumStarterRemoteProxy.DEFAULT_TZ);
dsProxy.getNewSession(getCapabilitySupportedByDockerSelenium());

// Mocking the environment variable to return false for video recording enabled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.verify;
Expand All @@ -32,6 +36,7 @@
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.withSettings;
import static org.awaitility.Awaitility.await;


public class DockerSeleniumStarterRemoteProxyTest {
Expand Down Expand Up @@ -125,6 +130,17 @@ public void containerIsStartedWhenFirefoxCapabilitiesAreSupported() {
verify(spyProxy, times(1)).startDockerSeleniumContainer(BrowserType.FIREFOX);
}

@Test
public void noContainerIsStartedWhenBrowserCapabilityIsAbsent() {
// Browser is absent
Map<String, Object> nonSupportedCapability = new HashMap<>();
nonSupportedCapability.put(CapabilityType.PLATFORM, Platform.LINUX);
TestSession testSession = spyProxy.getNewSession(nonSupportedCapability);

Assert.assertNull(testSession);
verify(spyProxy, never()).startDockerSeleniumContainer(anyString());
}

/*
The following tests check that if for any reason the capabilities from DockerSelenium cannot be
fetched, it should fallback to the default ones.
Expand Down Expand Up @@ -286,6 +302,8 @@ public void amountOfCreatedContainersIsTheConfiguredOne() {

registry.add(spyProxy);

Callable<Boolean> callable = () -> spyProxy.isSetupCompleted();
await().atMost(1, SECONDS).pollInterval(100, MILLISECONDS).until(callable);
verify(spyProxy, times(amountOfChromeContainers)).startDockerSeleniumContainer(BrowserType.CHROME);
verify(spyProxy, times(amountOfFirefoxContainers)).startDockerSeleniumContainer(BrowserType.FIREFOX);
Assert.assertEquals(amountOfChromeContainers, DockerSeleniumStarterRemoteProxy.getChromeContainersOnStartup());
Expand Down

0 comments on commit 51ea2bb

Please sign in to comment.