Merge branch 'stable-2.16' * stable-2.16: Set next version to 3.1 Change-Id: I71973fc0b2e2764997f7007beabb2d257ca3f6eb
diff --git a/BUILD b/BUILD index fd1de6a..b047e31 100644 --- a/BUILD +++ b/BUILD
@@ -1,9 +1,9 @@ -load("//tools/bzl:plugin.bzl", "gerrit_plugin") +load("//tools/bzl:junit.bzl", "junit_tests") +load("//tools/bzl:plugin.bzl", "PLUGIN_TEST_DEPS", "gerrit_plugin") gerrit_plugin( name = "plugin-manager", srcs = glob(["src/main/java/**/*.java"]), - resources = glob(["src/main/resources/**/*"]), manifest_entries = [ "Gerrit-PluginName: plugin-manager", "Gerrit-HttpModule: com.googlesource.gerrit.plugins.manager.WebModule", @@ -12,4 +12,15 @@ "Implementation-Title: Plugin manager", "Implementation-URL: https://gerrit-review.googlesource.com/#/admin/projects/plugins/plugin-manager", ], + resources = glob(["src/main/resources/**/*"]), +) + +junit_tests( + name = "plugin_manager_tests", + srcs = glob(["src/test/java/**/*.java"]), + data = ["//:release.war"], + visibility = ["//visibility:public"], + deps = PLUGIN_TEST_DEPS + [ + ":plugin-manager__plugin", + ], )
diff --git a/README.md b/README.md index 6405b5c..4bbd207 100644 --- a/README.md +++ b/README.md
@@ -1,2 +1,4 @@ # plugin-manager -Gerrit web-based plugin manager +Gerrit web-based plugin manager. + +To enable this plugin, please look at the [configuration guide](src/main/resources/Documentation/config.md) \ No newline at end of file
diff --git a/src/main/java/com/googlesource/gerrit/plugins/manager/FirstWebLoginListener.java b/src/main/java/com/googlesource/gerrit/plugins/manager/FirstWebLoginListener.java index 722d406..f0c934c 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/manager/FirstWebLoginListener.java +++ b/src/main/java/com/googlesource/gerrit/plugins/manager/FirstWebLoginListener.java
@@ -14,6 +14,8 @@ package com.googlesource.gerrit.plugins.manager; +import static java.nio.charset.StandardCharsets.UTF_8; + import com.google.gerrit.extensions.annotations.PluginData; import com.google.gerrit.httpd.WebLoginListener; import com.google.gerrit.server.IdentifiedUser; @@ -53,7 +55,8 @@ if (!firstLoginFile.toFile().exists()) { response.sendRedirect(pluginUrlPath + "static/intro.html"); - Files.write(firstLoginFile, new Date().toString().getBytes(), StandardOpenOption.CREATE); + Files.write( + firstLoginFile, new Date().toString().getBytes(UTF_8), StandardOpenOption.CREATE); } } }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/manager/GerritVersionBranch.java b/src/main/java/com/googlesource/gerrit/plugins/manager/GerritVersionBranch.java index e138e92..11a13bf 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/manager/GerritVersionBranch.java +++ b/src/main/java/com/googlesource/gerrit/plugins/manager/GerritVersionBranch.java
@@ -34,7 +34,7 @@ if (versionNumbers.length > 2) { String fixVersionNumber = versionNumbers[2]; - if (fixVersionNumber.contains("-")) { + if (fixVersionNumber.contains("-g")) { String nextVersion = String.format("%s.%d", versionNumbers[0], Integer.parseInt(versionNumbers[1]) + 1); if (nextVersion.equals(GERRIT_NEXT_VERSION)) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/manager/ListAvailablePlugins.java b/src/main/java/com/googlesource/gerrit/plugins/manager/ListAvailablePlugins.java index 76e7669..ceeda09 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/manager/ListAvailablePlugins.java +++ b/src/main/java/com/googlesource/gerrit/plugins/manager/ListAvailablePlugins.java
@@ -17,12 +17,10 @@ import com.google.common.collect.Maps; import com.google.gerrit.common.data.GlobalCapability; import com.google.gerrit.extensions.annotations.RequiresCapability; +import com.google.gerrit.extensions.restapi.Response; import com.google.gerrit.extensions.restapi.RestApiException; import com.google.gerrit.extensions.restapi.RestReadView; import com.google.gerrit.extensions.restapi.TopLevelResource; -import com.google.gerrit.server.OutputFormat; -import com.google.gson.JsonElement; -import com.google.gson.reflect.TypeToken; import com.google.inject.Inject; import com.googlesource.gerrit.plugins.manager.repository.PluginInfo; import java.util.ArrayList; @@ -43,11 +41,8 @@ } @Override - public Object apply(TopLevelResource resource) throws RestApiException { - return display(); - } - - public JsonElement display() throws RestApiException { + public Response<Map<String, PluginInfo>> apply(TopLevelResource resource) + throws RestApiException { Map<String, PluginInfo> output = Maps.newTreeMap(); List<PluginInfo> plugins; try { @@ -68,8 +63,6 @@ output.put(p.name, p); } - return OutputFormat.JSON - .newGson() - .toJsonTree(output, new TypeToken<Map<String, Object>>() {}.getType()); + return Response.ok(output); } }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/manager/PluginCanonicalWebUrlPath.java b/src/main/java/com/googlesource/gerrit/plugins/manager/PluginCanonicalWebUrlPath.java index 3f17da8..2005bfa 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/manager/PluginCanonicalWebUrlPath.java +++ b/src/main/java/com/googlesource/gerrit/plugins/manager/PluginCanonicalWebUrlPath.java
@@ -16,12 +16,11 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; +import com.google.inject.BindingAnnotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import com.google.inject.BindingAnnotation; - /** * Annotation applied to a String containing the plugin canonical web URL path. *
diff --git a/src/main/java/com/googlesource/gerrit/plugins/manager/PluginCanonicalWebUrlPathProvider.java b/src/main/java/com/googlesource/gerrit/plugins/manager/PluginCanonicalWebUrlPathProvider.java index 6581f87..d5ece22 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/manager/PluginCanonicalWebUrlPathProvider.java +++ b/src/main/java/com/googlesource/gerrit/plugins/manager/PluginCanonicalWebUrlPathProvider.java
@@ -14,12 +14,11 @@ package com.googlesource.gerrit.plugins.manager; -import java.net.URI; - import com.google.gerrit.extensions.annotations.PluginCanonicalWebUrl; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; +import java.net.URI; @Singleton public class PluginCanonicalWebUrlPathProvider implements Provider<String> {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/manager/XAuthFilter.java b/src/main/java/com/googlesource/gerrit/plugins/manager/XAuthFilter.java index de1eb10..616b9a4 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/manager/XAuthFilter.java +++ b/src/main/java/com/googlesource/gerrit/plugins/manager/XAuthFilter.java
@@ -14,6 +14,8 @@ package com.googlesource.gerrit.plugins.manager; +import static java.nio.charset.StandardCharsets.UTF_8; + import com.google.gerrit.extensions.registration.DynamicItem; import com.google.gerrit.httpd.WebSession; import com.google.gerrit.server.AccessPath; @@ -85,8 +87,8 @@ return new TokenReplaceOutputStream( (HttpServletResponse) getResponse(), origContentLength, - "@X-Gerrit-Auth".getBytes(), - gerritAuth.getBytes()); + "@X-Gerrit-Auth".getBytes(UTF_8), + gerritAuth.getBytes(UTF_8)); } };
diff --git a/src/main/java/com/googlesource/gerrit/plugins/manager/gson/SmartGson.java b/src/main/java/com/googlesource/gerrit/plugins/manager/gson/SmartGson.java index f8516e2..ae339de 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/manager/gson/SmartGson.java +++ b/src/main/java/com/googlesource/gerrit/plugins/manager/gson/SmartGson.java
@@ -14,7 +14,9 @@ package com.googlesource.gerrit.plugins.manager.gson; -import com.google.gerrit.server.OutputFormat; +import static java.nio.charset.StandardCharsets.UTF_8; + +import com.google.gerrit.json.OutputFormat; import com.google.gson.Gson; import com.google.gson.JsonObject; import java.io.IOException; @@ -52,6 +54,6 @@ } catch (MalformedURLException e) { throw new IllegalArgumentException("Internal error: Gerrit CI URL seems to be malformed", e); } - return new InputStreamReader(ciUrl.openStream()); + return new InputStreamReader(ciUrl.openStream(), UTF_8); } }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/manager/repository/CorePluginsDescriptions.java b/src/main/java/com/googlesource/gerrit/plugins/manager/repository/CorePluginsDescriptions.java index 7e8c422..efb0e10 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/manager/repository/CorePluginsDescriptions.java +++ b/src/main/java/com/googlesource/gerrit/plugins/manager/repository/CorePluginsDescriptions.java
@@ -14,11 +14,10 @@ package com.googlesource.gerrit.plugins.manager.repository; -import java.util.HashMap; -import java.util.Optional; - import com.google.inject.Inject; import com.google.inject.Singleton; +import java.util.HashMap; +import java.util.Optional; @Singleton public class CorePluginsDescriptions { @@ -28,13 +27,22 @@ public CorePluginsDescriptions() { pluginsDescriptions = new HashMap<>(); pluginsDescriptions.put("codemirror-editor", "CodeMirror plugin for polygerrit"); - pluginsDescriptions.put("commit-message-length-validator", + pluginsDescriptions.put( + "commit-message-length-validator", "Plugin to validate that commit messages conform to length limits"); + pluginsDescriptions.put("delete-project", "Provides the ability to delete a project"); pluginsDescriptions.put("download-commands", "Adds the standard download schemes and commands"); + pluginsDescriptions.put("gitiles", "Plugin running Gitiles alongside a Gerrit server"); pluginsDescriptions.put("hooks", "Old-style fork+exec hooks"); + pluginsDescriptions.put( + "plugin-manager", "Adds support for discovering and installing other plugins"); pluginsDescriptions.put("replication", "Copies to other servers using the Git protocol"); - pluginsDescriptions.put("reviewnotes", "Annotates merged commits using notes on refs/notes/review"); - pluginsDescriptions.put("singleusergroup", "GroupBackend enabling users to be directly added to access rules"); + pluginsDescriptions.put( + "reviewnotes", "Annotates merged commits using notes on refs/notes/review"); + pluginsDescriptions.put( + "singleusergroup", "GroupBackend enabling users to be directly added to access rules"); + pluginsDescriptions.put( + "webhooks", "Allows to propagate Gerrit events to remote http endpoints"); } public Optional<String> get(String plugin) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/manager/repository/CorePluginsRepository.java b/src/main/java/com/googlesource/gerrit/plugins/manager/repository/CorePluginsRepository.java index 8e96e6a..96947aa 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/manager/repository/CorePluginsRepository.java +++ b/src/main/java/com/googlesource/gerrit/plugins/manager/repository/CorePluginsRepository.java
@@ -14,9 +14,12 @@ package com.googlesource.gerrit.plugins.manager.repository; -import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.collect.FluentIterable; +import static com.google.common.collect.ImmutableList.toImmutableList; +import static java.util.Comparator.comparing; +import static java.util.Objects.requireNonNull; + +import com.google.common.collect.ImmutableList; +import com.google.gerrit.common.Nullable; import com.google.gerrit.common.Version; import com.google.gerrit.server.config.SitePaths; import com.google.inject.Inject; @@ -25,9 +28,8 @@ import java.net.URISyntaxException; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; +import java.util.Objects; +import java.util.Optional; import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -49,97 +51,82 @@ this.pluginsDescriptions = pd; } - static class SelectPluginsFromJar implements Predicate<JarEntry> { - @Override - public boolean apply(JarEntry entry) { - String entryName = entry.getName(); - return (entryName.startsWith("WEB-INF/plugins") && entryName.endsWith(".jar")); - } - } - - class ExtractPluginInfoFromJarEntry implements Function<JarEntry, PluginInfo> { - private String gerritWarFilename; - - public ExtractPluginInfoFromJarEntry(String gerritWarFilename) { - this.gerritWarFilename = gerritWarFilename; - } - - @Override - public PluginInfo apply(JarEntry entry) { - try { - Path entryName = Paths.get(entry.getName()); - URI pluginUrl = new URI("jar:file:" + gerritWarFilename + "!/" + entry.getName()); - try (JarInputStream pluginJar = new JarInputStream(pluginUrl.toURL().openStream())) { - Manifest manifestJarEntry = getManifestEntry(pluginJar); - if (manifestJarEntry != null) { - Attributes pluginAttributes = manifestJarEntry.getMainAttributes(); - String pluginName = pluginAttributes.getValue("Gerrit-PluginName"); - return new PluginInfo( - pluginName, - pluginsDescriptions.get(pluginName).orElse(""), - pluginAttributes.getValue("Implementation-Version"), - "", - pluginUrl.toString()); - } - return new PluginInfo( - entryName.getFileName().toString(), "", "", "", pluginUrl.toString()); - } catch (IOException e) { - log.error("Unable to open plugin " + pluginUrl, e); - return null; - } - } catch (URISyntaxException e) { - log.error("Invalid plugin filename", e); + @Nullable + private PluginInfo extractPluginInfoFromJarEntry(JarEntry entry) { + try { + Path entryName = Paths.get(entry.getName()); + URI pluginUrl = + new URI("jar:file:" + requireNonNull(site.gerrit_war) + "!/" + entry.getName()); + try (JarInputStream pluginJar = new JarInputStream(pluginUrl.toURL().openStream())) { + return getManifestEntry(pluginJar) + .map( + m -> { + Attributes pluginAttributes = m.getMainAttributes(); + String pluginName = pluginAttributes.getValue("Gerrit-PluginName"); + return new PluginInfo( + pluginName, + pluginsDescriptions.get(pluginName).orElse(""), + pluginAttributes.getValue("Implementation-Version"), + "", + pluginUrl.toString()); + }) + .orElse( + new PluginInfo( + dropSuffix(entryName.getFileName().toString(), ".jar"), + "", + "", + "", + pluginUrl.toString())); + } catch (IOException e) { + log.error("Unable to open plugin " + pluginUrl, e); return null; } - } - - private Manifest getManifestEntry(JarInputStream pluginJar) throws IOException { - for (JarEntry entry = pluginJar.getNextJarEntry(); - entry != null; - entry = pluginJar.getNextJarEntry()) { - if (entry.getName().equals("META-INF/MANIFEST.MF")) { - return new Manifest(pluginJar); - } - } + } catch (URISyntaxException e) { + log.error("Invalid plugin filename", e); return null; } } + private String dropSuffix(String string, String suffix) { + return string.endsWith(suffix) + ? string.substring(0, string.length() - suffix.length()) + : string; + } + + @Nullable + private static Optional<Manifest> getManifestEntry(JarInputStream pluginJar) throws IOException { + for (JarEntry entry = pluginJar.getNextJarEntry(); + entry != null; + entry = pluginJar.getNextJarEntry()) { + if (entry.getName().equals(JarFile.MANIFEST_NAME)) { + return Optional.of(new Manifest(pluginJar)); + } + } + return Optional.empty(); + } + @Override - public Collection<PluginInfo> list(String gerritVersion) throws IOException { + public ImmutableList<PluginInfo> list(String gerritVersion) throws IOException { if (!gerritVersion.equals(GERRIT_VERSION)) { log.warn( "No core plugins available for version {} which is different than " + "the current running Gerrit", gerritVersion); - return Collections.emptyList(); + return ImmutableList.of(); } - final Path gerritWarPath = site.gerrit_war; - if (gerritWarPath == null) { + if (site.gerrit_war == null) { log.warn("Core plugins not available on non-war Gerrit distributions"); - return Collections.emptyList(); + return ImmutableList.of(); } - try (JarFile gerritWar = new JarFile(gerritWarPath.toFile())) { - - return FluentIterable.from(Collections.list(gerritWar.entries())) - .filter(new SelectPluginsFromJar()) - .transform(new ExtractPluginInfoFromJarEntry(gerritWarPath.toString())) - .filter( - new Predicate<PluginInfo>() { - @Override - public boolean apply(PluginInfo pluginInfo) { - return pluginInfo != null; - } - }) - .toSortedList( - new Comparator<PluginInfo>() { - @Override - public int compare(PluginInfo a, PluginInfo b) { - return a.name.compareTo(b.name); - } - }); + try (JarFile gerritWar = new JarFile(site.gerrit_war.toFile())) { + return gerritWar.stream() + .filter(e -> e.getName().startsWith("WEB-INF/plugins") && e.getName().endsWith(".jar")) + .map(this::extractPluginInfoFromJarEntry) + .filter(Objects::nonNull) + .sorted(comparing(p -> p.name)) + .collect(toImmutableList()); } } }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/manager/repository/JenkinsCiPluginsRepository.java b/src/main/java/com/googlesource/gerrit/plugins/manager/repository/JenkinsCiPluginsRepository.java index 31f77e7..66c4c8d 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/manager/repository/JenkinsCiPluginsRepository.java +++ b/src/main/java/com/googlesource/gerrit/plugins/manager/repository/JenkinsCiPluginsRepository.java
@@ -14,6 +14,8 @@ package com.googlesource.gerrit.plugins.manager.repository; +import static java.nio.charset.StandardCharsets.UTF_8; + import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.inject.Inject; @@ -168,7 +170,8 @@ "%s/artifact/%s", buildExecution.getString("url"), verArtifactJson.get().getString("relativePath")); try (BufferedReader reader = - new BufferedReader(new InputStreamReader(new URL(versionUrl).openStream()), 4096)) { + new BufferedReader( + new InputStreamReader(new URL(versionUrl).openStream(), UTF_8), 4096)) { String line; while ((line = reader.readLine()) != null) { if (artifactBody.length() > 0) {
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md new file mode 100644 index 0000000..bab92d3 --- /dev/null +++ b/src/main/resources/Documentation/about.md
@@ -0,0 +1,12 @@ +This plugin adds support for discovering and installing other plugins +to Gerrit. + +The list of plugins are taken from the following sources: + +- Internal core plugins contained in the gerrit.war +- Plugins built on the [Gerrit CI][1] or another configurable location + for the stable branch that Gerrit is built + +**NOTE**: Management of plugins is restricted to Gerrit Administrators. + +[1]: https://gerrit-ci.gerritforge.com \ No newline at end of file
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md new file mode 100644 index 0000000..ed9f9f0 --- /dev/null +++ b/src/main/resources/Documentation/config.md
@@ -0,0 +1,40 @@ +How to enable +------------- + +The plugin-manager requires the ability to administer the plugins in Gerrit, +using the [Gerrit's `plugins.allowRemoteAdmin = true`][1] setting. + +Configuration +------------- + +The other plugin-specific settings are defined in the `[plugin-manager]` section +in the gerrit.config. + +jenkinsUrl +: URL of the Jenkins CI responsible for building and validating the plugins for + the current stable branch of Gerrit. + Default value: https://gerrit-ci.gerritforge.com + + +Plugin discovery +---------------- + +The compatible plugins are retrieved from a site of build artifacts that are +following the view setup of the gerrit-ci-scripts project. There is one view +per Gerrit stable branch (e.g. `Plugins-stable-3.0` contains all the artifacts +of the plugins built against the Gerrit stable-3.0 branch). + +Only the plugins with a job in the corresponding view and having at least one +successful build will be shown in the list and be discoverable. + +It is possible to control the list of plugins discoverable by editing the +corresponding view. + +*DISCLAIMER*: The plugin-manager aims at allowing the discovery and easy +download and setup of plugins into Gerrit. It is the plugin's maintainer +responsibility to maintain the build an end-to-end test of the plugin itself. +One plugin that is building and passes the tests on the CI may well not work +on Gerrit: testing and validation are always recommended. + +[1]: https://gerrit-review.googlesource.com/Documentation/config-gerrit.html#plugins.allowRemoteAdmin +[2]: https://gerrit.googlesource.com/gerrit-ci-scripts \ No newline at end of file
diff --git a/src/test/java/com/google/gerrit/server/restapi/config/PluginManagerTopMenuIT.java b/src/test/java/com/google/gerrit/server/restapi/config/PluginManagerTopMenuIT.java new file mode 100644 index 0000000..7730ef8 --- /dev/null +++ b/src/test/java/com/google/gerrit/server/restapi/config/PluginManagerTopMenuIT.java
@@ -0,0 +1,75 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// 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.google.gerrit.server.restapi.config; // Needed to get access to the ListTopMenus + +import static com.google.common.truth.Truth.assertThat; + +import com.google.gerrit.acceptance.GerritConfig; +import com.google.gerrit.acceptance.LightweightPluginDaemonTest; +import com.google.gerrit.acceptance.NoHttpd; +import com.google.gerrit.acceptance.TestPlugin; +import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations; +import com.google.gerrit.extensions.client.MenuItem; +import com.google.gerrit.extensions.webui.TopMenu.MenuEntry; +import com.google.gerrit.server.config.ConfigResource; +import com.google.inject.Inject; +import java.util.List; +import java.util.Optional; +import org.junit.Test; + +@NoHttpd +@TestPlugin( + name = "plugin-manager", + sysModule = "com.googlesource.gerrit.plugins.manager.Module", + httpModule = "com.googlesource.gerrit.plugins.manager.WebModule") +public class PluginManagerTopMenuIT extends LightweightPluginDaemonTest { + + @Inject ListTopMenus topMenus; + + @Inject private RequestScopeOperations requestScopeOperations; + + @Test + @GerritConfig(name = "plugins.allowRemoteAdmin", value = "true") + public void showTopMenuForGerritAdministratorsWhenAllowRemoteAdmin() throws Exception { + assertThat(pluginTopMenuEntries()).isNotEmpty(); + } + + @Test + @GerritConfig(name = "plugins.allowRemoteAdmin", value = "true") + public void topMenuContainsPluginsManagementItem() throws Exception { + Optional<MenuEntry> topMenuEntry = pluginTopMenuEntries().stream().findFirst(); + assertThat(topMenuEntry.map(m -> m.name)).isEqualTo(Optional.of("Plugins")); + + Optional<MenuItem> pluginsMenuItem = topMenuEntry.flatMap(m -> m.items.stream().findFirst()); + assertThat(pluginsMenuItem.map(m -> m.name)).isEqualTo(Optional.of("Manage")); + } + + @Test + @GerritConfig(name = "plugins.allowRemoteAdmin", value = "true") + public void hideTopMenuForRegularUsersEvenWhenAllowRemoteAdmin() throws Exception { + requestScopeOperations.setApiUser(user.id()); + assertThat(pluginTopMenuEntries()).isEmpty(); + } + + @Test + public void hideTopMenuByDefault() throws Exception { + assertThat(pluginTopMenuEntries()).isEmpty(); + } + + private List<MenuEntry> pluginTopMenuEntries() throws Exception { + List<MenuEntry> topMenuItems = topMenus.apply(new ConfigResource()).value(); + return topMenuItems; + } +}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/manager/GerritVersionBranchTest.java b/src/test/java/com/googlesource/gerrit/plugins/manager/GerritVersionBranchTest.java new file mode 100644 index 0000000..8ab2fd4 --- /dev/null +++ b/src/test/java/com/googlesource/gerrit/plugins/manager/GerritVersionBranchTest.java
@@ -0,0 +1,73 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// 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.googlesource.gerrit.plugins.manager; + +import static com.google.common.truth.Truth.assertThat; +import static com.googlesource.gerrit.plugins.manager.GerritVersionBranch.getBranch; + +import org.junit.Test; + +public class GerritVersionBranchTest { + + @Test + public void getBranchReturnsCorrectBranchForTwoDigitsVersions() throws Exception { + // Regular 2.x versions + assertBranch("2.13", "stable-2.13"); + assertBranch("2.14", "stable-2.14"); + assertBranch("2.15", "stable-2.15"); + assertBranch("2.16", "stable-2.16"); + } + + @Test + public void getBranchReturnsCorrectBranchForThreeDigitsVersions() throws Exception { + // 2.x.y version + assertBranch("2.16.10", "stable-2.16"); + + // 3.0.0 version + assertBranch("3.0.0", "stable-3.0"); + } + + @Test + public void getBranchReturnsCorrectBranchForReleaseCandidates() throws Exception { + // 2.x-rcx version + assertBranch("2.16-rc1", "stable-2.16"); + + // 3.0.0-rcx version + assertBranch("3.0.0-rc3", "stable-3.0"); + } + + @Test + public void getBranchReturnsCorrectBranchForDevelopmentOnStableBranches() throws Exception { + assertBranch("2.16.8-17-gc8b633d5ce", "stable-2.16"); + } + + @Test + public void getBranchReturnsCorrectBranchForDevelopmentOnMaster() throws Exception { + assertBranch("3.0.0-rc2-237-gae0124c68e", "master"); + } + + @Test + public void getBranchReturnsMasterForUnknownVersions() throws Exception { + // Unknown versions + assertBranch(null, "master"); + assertBranch("", "master"); + assertBranch(" ", "master"); + assertBranch("foo", "master"); + } + + private static void assertBranch(String version, String expectedBranch) throws Exception { + assertThat(getBranch(version)).isEqualTo(expectedBranch); + } +}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/manager/repository/PluginsRepositoryTest.java b/src/test/java/com/googlesource/gerrit/plugins/manager/repository/PluginsRepositoryTest.java new file mode 100644 index 0000000..d01d287 --- /dev/null +++ b/src/test/java/com/googlesource/gerrit/plugins/manager/repository/PluginsRepositoryTest.java
@@ -0,0 +1,75 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// 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.googlesource.gerrit.plugins.manager.repository; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.TruthJUnit.assume; +import static java.util.stream.Collectors.toList; + +import com.google.common.collect.ImmutableList; +import com.google.gerrit.common.Version; +import com.google.gerrit.server.config.SitePaths; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collection; +import org.junit.Test; + +public class PluginsRepositoryTest { + + private static final ImmutableList<String> GERRIT_CORE_PLUGINS = + ImmutableList.of( + "codemirror-editor", + "commit-message-length-validator", + "delete-project", + "download-commands", + "gitiles", + "hooks", + "plugin-manager", + "replication", + "reviewnotes", + "singleusergroup", + "webhooks"); + + @Test + public void corePluginsRepositoryShouldReturnCorePluginsFromReleaseWar() throws IOException { + SitePaths site = new SitePaths(random()); + PluginsRepository pluginRepo = new CorePluginsRepository(site, new CorePluginsDescriptions()); + + Path pathToReleaseWar = + Paths.get(getenv("TEST_SRCDIR"), getenv("TEST_WORKSPACE"), "release.war"); + assume().that(pathToReleaseWar.toFile().exists()).isTrue(); + Files.createDirectories(site.bin_dir); + Files.createSymbolicLink(site.gerrit_war, pathToReleaseWar); + + Collection<PluginInfo> plugins = pluginRepo.list(Version.getVersion()); + assertThat(plugins.stream().map(p -> p.name).sorted().collect(toList())) + .containsExactlyElementsIn(GERRIT_CORE_PLUGINS) + .inOrder(); + } + + private static String getenv(String name) { + String value = System.getenv(name); + assume().that(value).isNotNull(); + return value; + } + + private static Path random() throws IOException { + Path tmp = Files.createTempFile("gerrit_", "_site"); + Files.deleteIfExists(tmp); + return tmp; + } +}