Skip to content

Commit

Permalink
JENKINS-13207 Provide ability for users to set the working directory …
Browse files Browse the repository at this point in the history
…for the Sauce Connect process
  • Loading branch information
rossrowe committed Mar 25, 2012
1 parent 9da10de commit 39d23bb
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 15 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Expand Up @@ -9,7 +9,7 @@
<artifactId>sauce-ondemand</artifactId>
<version>1.13-SNAPSHOT</version>
<packaging>hpi</packaging>
<name>Hudson Sauce OnDemand plugin</name>
<name>Jenkins Sauce OnDemand plugin</name>
<url>http://wiki.jenkins-ci.org/display/JENKINS/Sauce+OnDemand+Plugin</url>

<scm>
Expand Down Expand Up @@ -115,7 +115,7 @@
<dependency>
<groupId>com.saucelabs</groupId>
<artifactId>ci-sauce</artifactId>
<version>1.11</version>
<version>1.12</version>
<scope>compile</scope>
</dependency>
<dependency>
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/com/saucelabs/hudson/HudsonSauceConnectManager.java
@@ -0,0 +1,22 @@
package com.saucelabs.hudson;

import com.saucelabs.ci.sauceconnect.SauceConnectTwoManager;
import hudson.plugins.sauce_ondemand.PluginImpl;
import org.apache.commons.lang.StringUtils;

/**
* @author Ross Rowe
*/
public class HudsonSauceConnectManager extends SauceConnectTwoManager {

@Override
public String getSauceConnectWorkingDirectory() {
String workingDirectory = PluginImpl.get().getSauceConnectDirectory();
if (StringUtils.isBlank(workingDirectory)) {
return super.getSauceConnectWorkingDirectory();
} else {
return workingDirectory;
}

}
}
13 changes: 12 additions & 1 deletion src/main/java/hudson/plugins/sauce_ondemand/PluginImpl.java
Expand Up @@ -66,6 +66,8 @@ public class PluginImpl extends Plugin implements Describable<PluginImpl> {
private Secret apiKey;

private boolean reuseSauceAuth;

private String sauceConnectDirectory;

public String getUsername() {
return username;
Expand Down Expand Up @@ -98,6 +100,7 @@ public void configure(StaplerRequest req, JSONObject formData) throws IOExceptio
reuseSauceAuth = formData.getBoolean("reuseSauceAuth");
username = formData.getString("username");
apiKey = Secret.fromString(formData.getString("apiKey"));
sauceConnectDirectory = formData.getString("sauceConnectDirectory");
save();
}

Expand All @@ -113,14 +116,22 @@ public boolean isReuseSauceAuth() {
return reuseSauceAuth;
}

public String getSauceConnectDirectory() {
return sauceConnectDirectory;
}

public void setSauceConnectDirectory(String sauceConnectDirectory) {
this.sauceConnectDirectory = sauceConnectDirectory;
}

@Extension
public static final class DescriptorImpl extends Descriptor<PluginImpl> {
@Override
public String getDisplayName() {
return "Sauce OnDemand";
}

public FormValidation doValidate(@QueryParameter String username, @QueryParameter String apiKey, @QueryParameter boolean reuseSauceAuth) {
public FormValidation doValidate(@QueryParameter String username, @QueryParameter String apiKey, @QueryParameter boolean reuseSauceAuth ) {
try {
Credential credential = reuseSauceAuth ? new Credential() : new Credential(username, Secret.toString(Secret.fromString(apiKey)));
new SauceTunnelFactory(credential).list();
Expand Down
Expand Up @@ -55,6 +55,8 @@
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* {@link BuildWrapper} that sets up the Sauce OnDemand SSH tunnel.
Expand All @@ -76,18 +78,19 @@ public class SauceOnDemandBuildWrapper extends BuildWrapper implements Serializa

private ITunnelHolder tunnels;
private String seleniumHost;
private int seleniumPort;
private String seleniumPort;
private Credentials credentials;
private SeleniumInformation seleniumInformation;
private List<String> browsers;
/**
* TODO provide mechanism to set launchOnSlave via UI
*/
private boolean launchSauceConnectOnSlave = false;
public static final Pattern ENVIRONMENT_VARIABLE_PATTERN = Pattern.compile("[$|%]([A-Z]+)");

@DataBoundConstructor
public SauceOnDemandBuildWrapper(Credentials
credentials, SeleniumInformation seleniumInformation, String seleniumHost, int seleniumPort, boolean enableSauceConnect, List<String> browsers) {
credentials, SeleniumInformation seleniumInformation, String seleniumHost, String seleniumPort, boolean enableSauceConnect, List<String> browsers) {
this.credentials = credentials;
this.seleniumInformation = seleniumInformation;
this.enableSauceConnect = enableSauceConnect;
Expand Down Expand Up @@ -153,7 +156,13 @@ public void buildEnvVars(Map<String, String> env) {
}

private String getHostName() {

if (StringUtils.isNotBlank(seleniumHost)) {
Matcher matcher = ENVIRONMENT_VARIABLE_PATTERN.matcher(seleniumHost);
if (matcher.matches()) {
String variableName = matcher.group(1);
return System.getenv(variableName);
}
return seleniumHost;
} else {
if (isEnableSauceConnect()) {
Expand Down Expand Up @@ -199,8 +208,18 @@ private String getCurrentHostName() {
}

private int getPort() {
if (seleniumPort > 0) {
return seleniumPort;
if (StringUtils.isNotBlank(seleniumPort)) {
Matcher matcher = ENVIRONMENT_VARIABLE_PATTERN.matcher(seleniumPort);
if (matcher.matches()) {
String variableName = matcher.group(1);
String value = System.getenv(variableName);
if (value == null) {
value = "0";
}
return Integer.parseInt(value);
} else {
return Integer.parseInt(seleniumPort);
}
} else {
if (isEnableSauceConnect()) {
return 4445;
Expand Down Expand Up @@ -238,11 +257,11 @@ public void setSeleniumHost(String seleniumHost) {
this.seleniumHost = seleniumHost;
}

public int getSeleniumPort() {
public String getSeleniumPort() {
return seleniumPort;
}

public void setSeleniumPort(int seleniumPort) {
public void setSeleniumPort(String seleniumPort) {
this.seleniumPort = seleniumPort;
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/META-INF/plexus/components.xml
Expand Up @@ -20,7 +20,7 @@ under the License.
<components>
<component>
<role>com.saucelabs.ci.sauceconnect.SauceTunnelManager</role>
<implementation>com.saucelabs.ci.sauceconnect.SauceConnectTwoManager</implementation>
<implementation>com.saucelabs.hudson.HudsonSauceConnectManager</implementation>
</component>
</components>
</component-set>
Expand Up @@ -25,6 +25,9 @@
<f:entry title="${%API Access Key}" field="apiKey">
<f:password id="apiKeyBox"/>
</f:entry>
<f:entry title="${%Sauce Connect Working Directory}" field="sauceConnectDirectory">
<f:textbox id="directoryBox"/>
</f:entry>
<f:entry field="reuseSauceAuth">
<f:checkbox id="reuseSauceAuthCheckBox" onclick="debugger;enableDisable();" title="${%Use authentication details in ~/.sauce-ondemand?}"/>
</f:entry>
Expand Down
@@ -0,0 +1,4 @@
<div>
Specify the directory where the Sauce Connect process should be run from. By default, the plugin will attempt to
launch Sauce Connect using the USER_HOME directory as the working directory.
</div>
Expand Up @@ -37,7 +37,7 @@ public class SauceOnDemandBuildWrapperTest extends BaseTezt {
*/
public void configRoundtrip() throws Exception {
FreeStyleProject p = createFreeStyleProject();
SauceOnDemandBuildWrapper before = new SauceOnDemandBuildWrapper(new Credentials("username", "accessKey"), new SeleniumInformation( "http://localhost"), "abc", 1, true, null);
SauceOnDemandBuildWrapper before = new SauceOnDemandBuildWrapper(new Credentials("username", "accessKey"), new SeleniumInformation( "http://localhost"), "abc", "1", true, null);
p.getBuildWrappersList().add(before);
configRoundtrip(p);
SauceOnDemandBuildWrapper after = p.getBuildWrappersList().get(SauceOnDemandBuildWrapper.class);
Expand All @@ -52,7 +52,7 @@ public void testFullConfig() throws Exception {
setCredential();

FreeStyleProject p = createFreeStyleProject();
SauceOnDemandBuildWrapper before = new SauceOnDemandBuildWrapper(null, new SeleniumInformation("http://localhost:8080/"), "localhost", 4445, true, null);
SauceOnDemandBuildWrapper before = new SauceOnDemandBuildWrapper(null, new SeleniumInformation("http://localhost:8080/"), "localhost", "4445", true, null);
p.getBuildWrappersList().add(before);
invokeSeleniumFromBuild(p, new SauceBuilder());
}
Expand All @@ -64,7 +64,7 @@ public void testMinimalConfig() throws Exception {
setCredential();

FreeStyleProject p = createFreeStyleProject();
SauceOnDemandBuildWrapper before = new SauceOnDemandBuildWrapper(null, null, null, 0, true, null);
SauceOnDemandBuildWrapper before = new SauceOnDemandBuildWrapper(null, null, null, "0", true, null);
p.getBuildWrappersList().add(before);
invokeSeleniumFromBuild(p, new SauceBuilder());
}
Expand All @@ -77,7 +77,7 @@ public void runFromSlave() throws Exception {

FreeStyleProject p = createFreeStyleProject();
p.setAssignedNode(s);
SauceOnDemandBuildWrapper before = new SauceOnDemandBuildWrapper(null, new SeleniumInformation("http://localhost:8080/"), "localhost", 4445, true, null);
SauceOnDemandBuildWrapper before = new SauceOnDemandBuildWrapper(null, new SeleniumInformation("http://localhost:8080/"), "localhost", "4445", true, null);
p.getBuildWrappersList().add(before);
invokeSeleniumFromBuild(p, new SauceBuilder());
}
Expand Down
Expand Up @@ -57,7 +57,7 @@ private void testReportEmbedding(String testReport, boolean oldStyle) throws Exc
setCredential();
FreeStyleProject p = createFreeStyleProject();

SauceOnDemandBuildWrapper before = new SauceOnDemandBuildWrapper(null, new SeleniumInformation("http://localhost:8080/"), "localhost", 4445, true, null);
SauceOnDemandBuildWrapper before = new SauceOnDemandBuildWrapper(null, new SeleniumInformation("http://localhost:8080/"), "localhost", "4445", true, null);
p.getBuildWrappersList().add(before);
JUnitResultArchiver junit = new JUnitResultArchiver(
"test.xml",
Expand Down

0 comments on commit 39d23bb

Please sign in to comment.