Navigation Menu

Skip to content

Commit

Permalink
Merge pull request #353 from jenkinsci/JENKINS-41196
Browse files Browse the repository at this point in the history
[JENKINS-41196] demonstrate that core component override plugin can work in ATH
  • Loading branch information
olivergondza committed Sep 6, 2017
2 parents 6f23ea2 + 5d52afc commit 539505e
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 36 deletions.
9 changes: 2 additions & 7 deletions docs/SUT-VERSIONS.md
Expand Up @@ -21,15 +21,10 @@ When you are testing locally developed Jenkins plugin, you'd like the test harne
local version as opposed to download the plugin from update center. This can be done by instructing the harness
accordingly.

One way to do so is to set the environment variable:

$ env ldap.jpi=/path/to/your/ldap.jpi mvn test
$ env LOCAL_JARS=path/to/your/ldap.jpi:path/to/another.jpi

You can also do this from [the groovy wiring script](WIRING.md).

envs['ldap.jpi'] = '/path/to/your.ldap.jpi'

Since newer shells do not support environment variables with hyphens in the name, rather than `scm-api.jpi` you may use `SCM_API_JPI`.
This scheme also works for a plugin that's not yet released.

### Install plugins from local maven repository

Expand Down
@@ -1,18 +1,17 @@
package org.jenkinsci.test.acceptance.update_center;

import com.cloudbees.sdk.extensibility.Extension;
import java.io.File;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.util.version.GenericVersionScheme;
import org.eclipse.aether.version.Version;
import org.eclipse.aether.version.VersionScheme;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.util.Iterator;
import java.util.Map;

/**
* Allow local plugins specified via environment variables to override plugin metadata from update center.
*
Expand Down Expand Up @@ -59,34 +58,55 @@ public void decorate(UpdateCenterMetadata ucm) {
}
}
}

// deprecated mechanism, as of 1.57
for (Map.Entry<String,String> e : System.getenv().entrySet()) {
String key = e.getKey();
String name;
if (key.endsWith(".jpi")) {
name = key.replace(".jpi", "");
} else if (key.endsWith("_JPI")) { // http://stackoverflow.com/a/36992531/12916
name = null;
for (String _name : ucm.plugins.keySet()) {
if ((_name.toUpperCase(Locale.ENGLISH).replaceAll("[^A-Z0-9_]", "_") + "_JPI").equals(key)) {
name = _name;
break;
}
}
if (name == null) {
throw new IllegalArgumentException("Could not identify plugin name from " + key + " given " + ucm.plugins.keySet());
}
} else {
if (!isPluginEnvironmentVariable(key))
continue;

try {
override(ucm, e.getValue());
} catch (Exception x) {
throw new IllegalArgumentException("Unable to honor environment variable "+key, x);
}
PluginMetadata stock = ucm.plugins.get(name);
if (stock == null) {
throw new IllegalArgumentException("Plugin does not exists in update center: " + name);
}

// past 1.57, preferred way
String localJars = System.getenv("LOCAL_JARS");
if (localJars!=null) {
for (String jar : localJars.split(File.pathSeparator)) {
try {
override(ucm, jar);
} catch (Exception x) {
throw new IllegalArgumentException("Unable to honor LOCAL_JARS environment variable", x);
}
}
File file = new File(e.getValue());
if (!file.exists()) throw new IllegalArgumentException("Plugin file for " + name + " does not exist: " + file.getAbsolutePath());
PluginMetadata m = PluginMetadata.LocalOverride.create(file);
System.err.println("Overriding " + name + " " + stock.getVersion() + " with local build of " + m.getVersion());
ucm.plugins.put(m.getName(), m);
}
}

private void override(UpdateCenterMetadata ucm, String jpi) {
File file = new File(jpi);
if (!file.exists()) throw new IllegalArgumentException("Plugin file does not exist: " + file.getAbsolutePath());

PluginMetadata m = PluginMetadata.LocalOverride.create(file);
PluginMetadata stock = ucm.plugins.get(m.getName());
if (stock == null) {
System.err.println("Creating new plugin " + m.getName() + " with local build of " + m.getVersion());
} else {
System.err.println("Overriding " + m.getName() + " " + stock.getVersion() + " with local build of " + m.getVersion());
}
ucm.plugins.put(m.getName(), m);
}

/**
* Returns true if the given environment variable name is an override to point to a local JPI file.
*/
private boolean isPluginEnvironmentVariable(String name) {
if (name.endsWith(".jpi"))
return true;
if (name.endsWith("_JPI")) // http://stackoverflow.com/a/36992531/12916
return true;
return false;
}
}
Expand Up @@ -3,6 +3,9 @@
import com.cloudbees.sdk.extensibility.ExtensionPoint;

/**
* A hook to tweak {@link UpdateCenterMetadata} to allow plugins and versions that are not in the update
* center to be installed and tested.
*
* @author Kohsuke Kawaguchi
*/
@ExtensionPoint
Expand Down
67 changes: 67 additions & 0 deletions src/test/java/plugins/RemotingPluginTest.java
@@ -0,0 +1,67 @@
package plugins;

import hudson.util.VersionNumber;
import org.apache.commons.io.FileUtils;
import org.jenkinsci.test.acceptance.junit.AbstractJUnitTest;
import org.jenkinsci.test.acceptance.junit.WithPlugins;
import org.jenkinsci.test.acceptance.update_center.UpdateCenterMetadataProvider;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import javax.inject.Inject;
import java.io.File;
import java.io.IOException;
import java.util.jar.Attributes;
import java.util.jar.JarFile;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

/**
* @author Kohsuke Kawaguchi
*/
public class RemotingPluginTest extends AbstractJUnitTest {
@Rule
public TemporaryFolder tmp = new TemporaryFolder();

@Inject
UpdateCenterMetadataProvider ucmp;

/**
* When installing a core component override plugin, we should see that plugin functioning.
*
* <p>
* Run with environment variable: <tt>REMOTING_JPI=path/to/your-locally-build-remoting.hpi
* <p>
* We check this by:
* <ol>
* <li>Testing the version of the plugin as declared installed
* <li>Making sure that the actual jar file in the system is replaced
* </ol>
*/
@Test
@WithPlugins({"remoting"})
@Ignore // meant to be used to locally demonstrate JENKINS-41196 support
public void test() throws IOException, InterruptedException {
// expected version
final String version = ucmp.get(jenkins).plugins.get("remoting").getVersion();

assertThat(trimSnapshot(jenkins.getPlugin("remoting").getVersion()), is(version));

File jar = tmp.newFile();
FileUtils.copyURLToFile(jenkins.url("jnlpJars/slave.jar"),jar);
try (JarFile j = new JarFile(jar)) {// this is the copy of remoting jar
Attributes main = j.getManifest().getMainAttributes();
assertThat(main.getValue("Version"),is(version));
}
}

/**
* For version number like "1.0-SNAPSHOT (private-921e74fb-kohsuke)" trim off the whitespace and onward
*/
private String trimSnapshot(VersionNumber v) {
return v.toString().split(" ")[0];
}
}

0 comments on commit 539505e

Please sign in to comment.