From 231a096f050f4422194068695b32388c7e633b2e Mon Sep 17 00:00:00 2001 From: Gert van Dijk Date: Thu, 16 Aug 2018 11:51:51 +0200 Subject: [PATCH 01/14] Documentation: Remove 'install-quick' page in favour of 'linux-quickstart' The 'install-quick' page wasn't referenced any longer on index pages and used outdated instructions based on Gerrit 2.2. Change-Id: Ib3647767522ec5dcfff5d68d30cfed8706e3fcc5 --- Documentation/database-setup.txt | 3 +- Documentation/install-quick.txt | 227 ------------------------------- polygerrit-ui/README.md | 4 +- 3 files changed, 4 insertions(+), 230 deletions(-) delete mode 100644 Documentation/install-quick.txt diff --git a/Documentation/database-setup.txt b/Documentation/database-setup.txt index d35772e83b..2153751208 100644 --- a/Documentation/database-setup.txt +++ b/Documentation/database-setup.txt @@ -16,7 +16,8 @@ corporate installations. This is because there is no easy way to interact with the database while Gerrit is offline, it's not easy to backup the data, and it's not possible to set up H2 in a load balanced/hotswap configuration. -If this option interests you, you might want to consider link:install-quick.html[the quick guide]. +If this option interests you, you might want to consider +link:linux-quickstart.html[the quick guide]. [[createdb_derby]] === Apache Derby diff --git a/Documentation/install-quick.txt b/Documentation/install-quick.txt deleted file mode 100644 index 7b80229d40..0000000000 --- a/Documentation/install-quick.txt +++ /dev/null @@ -1,227 +0,0 @@ -= Gerrit Code Review - Quick get started guide - -**** -This guide was made with the impatient in mind, ready to try out Gerrit on their -own server but not prepared to make the full installation procedure yet. - -Explanation is sparse and you should not use a server installed this way in a -live setup, this is made with proof of concept activities in mind. - -It is presumed you install it on a Unix based server such as any of the Linux -flavors or BSD. - -It's also presumed that you have access to an OpenID enabled email address. -Examples of OpenID enable email providers are Gmail, Yahoo! Mail and Hotmail. -It's also possible to register a custom email address with OpenID, but that is -outside the scope of this quick installation guide. For testing purposes one of -the above providers should be fine. Please note that network access to the -OpenID provider you choose is necessary for both you and your Gerrit instance. -**** - - -[[requirements]] -== Requirements - -Most distributions come with Java today. Do you already have Java installed? - ----- - $ java -version - openjdk version "1.8.0_72" - OpenJDK Runtime Environment (build 1.8.0_72-b15) - OpenJDK 64-Bit Server VM (build 25.72-b15, mixed mode) ----- - -If Java isn't installed, get it: - -* JRE, minimum version 1.8 http://www.oracle.com/technetwork/java/javase/downloads/index.html[Download] - - -[[user]] -== Create a user to host the Gerrit service - -We will run the service as a non-privileged user on your system. -First create the user and then become the user: - ----- - $ sudo adduser gerrit - $ sudo su gerrit ----- - -If you don't have root privileges you could skip this step and run Gerrit -as your own user as well. - - -[[download]] -== Download Gerrit - -It's time to download the archive that contains the Gerrit web and ssh service. - -You can choose from different versions to download from here: - -* https://www.gerritcodereview.com/download/index.html[A list of releases available] - -This tutorial is based on version 2.2.2, and you can download that from this link - -* https://www.gerritcodereview.com/download/gerrit-2.2.2.war[Link to the 2.2.2 war archive] - - -[[initialization]] -== Initialize the Site - -It's time to run the initialization, and with the batch switch enabled, we don't have to answer any questions at all: - ----- - gerrit@host:~$ java -jar gerrit.war init --batch -d ~/gerrit_testsite - Generating SSH host key ... rsa(simple)... done - Initialized /home/gerrit/gerrit_testsite - Executing /home/gerrit/gerrit_testsite/bin/gerrit.sh start - Starting Gerrit Code Review: OK - gerrit@host:~$ ----- - -When the init is complete, you can review your settings in the -file `'$site_path/etc/gerrit.config'`. - -Note that initialization also starts the server. If any settings changes are -made, the server must be restarted before they will take effect. - ----- - gerrit@host:~$ ~/gerrit_testsite/bin/gerrit.sh restart - Stopping Gerrit Code Review: OK - Starting Gerrit Code Review: OK - gerrit@host:~$ ----- - -The server can be also stopped and started by passing the `stop` and `start` -commands to gerrit.sh. - ----- - gerrit@host:~$ ~/gerrit_testsite/bin/gerrit.sh stop - Stopping Gerrit Code Review: OK - gerrit@host:~$ - gerrit@host:~$ ~/gerrit_testsite/bin/gerrit.sh start - Starting Gerrit Code Review: OK - gerrit@host:~$ ----- - -include::config-login-register.txt[] - -== Project creation - -Your base Gerrit server is now running and you have a user that's ready -to interact with it. You now have two options, either you create a new -test project to work with or you already have a git with history that -you would like to import into Gerrit and try out code review on. - -=== New project from scratch -If you choose to create a new repository from scratch, it's easier for -you to create a project with an initial commit in it. That way first -time setup between client and server is easier. - -This is done via the SSH port: - ----- - user@host:~$ ssh -p 29418 user@localhost gerrit create-project demo-project --empty-commit - user@host:~$ ----- - -This will create a repository that you can clone to work with. - -=== Already existing project - -The other alternative is if you already have a git project that you -want to try out Gerrit on. -First you have to create the project. This is done via the SSH port: - ----- - user@host:~$ ssh -p 29418 user@localhost gerrit create-project demo-project - user@host:~$ ----- - -You need to make sure that at least initially your account is granted -"Create Reference" privileges for the refs/heads/* reference. -This is done via the web interface in the Admin/Projects/Access page -that correspond to your project. - -After that it's time to upload the previous history to the server: - ----- - user@host:~/my-project$ git push ssh://user@localhost:29418/demo-project *:* - Counting objects: 2011, done. - Writing objects: 100% (2011/2011), 456293 bytes, done. - Total 2011 (delta 0), reused 0 (delta 0) - To ssh://user@localhost:29418/demo-project - * [new branch] master -> master - user@host:~/my-project$ ----- - -This will create a repository that you can clone to work with. - - -== My first change - -Download a local clone of the repository and move into it - ----- - user@host:~$ git clone ssh://user@localhost:29418/demo-project - Cloning into demo-project... - remote: Counting objects: 2, done - remote: Finding sources: 100% (2/2) - remote: Total 2 (delta 0), reused 0 (delta 0) - user@host:~$ cd demo-project - user@host:~/demo-project$ ----- - -Then make a change to it and upload it as a reviewable change in Gerrit. - ----- - user@host:~/demo-project$ date > testfile.txt - user@host:~/demo-project$ git add testfile.txt - user@host:~/demo-project$ git commit -m "My pretty test commit" - [master ff643a5] My pretty test commit - 1 files changed, 1 insertions(+), 0 deletions(-) - create mode 100644 testfile.txt - user@host:~/demo-project$ ----- - -Usually when you push to a remote git, you push to the reference -`'/refs/heads/branch'`, but when working with Gerrit you have to push to a -virtual branch representing "code review before submission to branch". -This virtual name space is known as /refs/for/ - ----- - user@host:~/demo-project$ git push origin HEAD:refs/for/master - Counting objects: 4, done. - Writing objects: 100% (3/3), 293 bytes, done. - Total 3 (delta 0), reused 0 (delta 0) - remote: - remote: New Changes: - remote: http://localhost:8080/1 - remote: - To ssh://user@localhost:29418/demo-project - * [new branch] HEAD -> refs/for/master - user@host:~/demo-project$ ----- - -You should now be able to access your change by browsing to the http URL -suggested above, http://localhost:8080/1 - - -== Quick Installation Complete - -This covers the scope of getting Gerrit started and your first change uploaded. -It doesn't give any clue as to how the review workflow works, please read -link:http://source.android.com/source/life-of-a-patch[Default Workflow] to -learn more about the workflow of Gerrit. - -To read more on the installation of Gerrit please see link:install.html[the detailed -installation page]. - - -GERRIT ------- - -Part of link:index.html[Gerrit Code Review] - -SEARCHBOX ---------- diff --git a/polygerrit-ui/README.md b/polygerrit-ui/README.md index 6532f4b605..fb41dc17cf 100644 --- a/polygerrit-ui/README.md +++ b/polygerrit-ui/README.md @@ -63,7 +63,7 @@ One-time setup: 1. [Build Gerrit](https://gerrit-review.googlesource.com/Documentation/dev-bazel.html#_gerrit_development_war_file) 2. Set up a local test site. Docs - [here](https://gerrit-review.googlesource.com/Documentation/install-quick.html) and + [here](https://gerrit-review.googlesource.com/Documentation/linux-quickstart.html) and [here](https://gerrit-review.googlesource.com/Documentation/dev-readme.html#init). When your project is set up and works using the classic UI, run a test server @@ -205,4 +205,4 @@ bazel test //polygerrit-ui/app:template_test_ --test_arg= Date: Thu, 16 Aug 2018 12:07:13 +0200 Subject: [PATCH 02/14] Documentation: Include Java 8 requirement in installation notes Bug: Issue 7843 Change-Id: I763800eab693c357eace4182c3bafa28c622b94d --- Documentation/install.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/install.txt b/Documentation/install.txt index 2adc343468..87d757e550 100644 --- a/Documentation/install.txt +++ b/Documentation/install.txt @@ -5,7 +5,9 @@ To run the Gerrit service, the following requirements must be met on the host: -* JRE, minimum version 1.8 http://www.oracle.com/technetwork/java/javase/downloads/index.html[Download] +* JRE, version 1.8 http://www.oracle.com/technetwork/java/javase/downloads/index.html[Download] ++ +Gerrit is not yet compatible with Java 9 or newer at this time. You'll also need an SQL database to house the review metadata. You have the choice of either using the embedded H2 or to host your own MySQL or PostgreSQL. From f1f5f08683a5292c6d11b506cc8698aa1a07583f Mon Sep 17 00:00:00 2001 From: Gert van Dijk Date: Thu, 16 Aug 2018 11:46:46 +0200 Subject: [PATCH 03/14] Documentation: linux-quickstart - include Java 8 requirement Bug: Issue 7843 Change-Id: Ic1ff71e7e0c3b4a079e585ff04bc3b29869d1ff6 --- Documentation/linux-quickstart.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/linux-quickstart.txt b/Documentation/linux-quickstart.txt index 84deeb5d7e..ee7fb16973 100644 --- a/Documentation/linux-quickstart.txt +++ b/Documentation/linux-quickstart.txt @@ -17,7 +17,9 @@ link:install.html[Standalone Daemon Installation Guide]. To complete this quickstart, you need: . A Unix-based server such as any of the Linux flavors or BSD. -. Java SE Runtime Environment version 1.8 or later. +. Java SE Runtime Environment version 1.8 ++ +Gerrit is not compatible with Java 9 or newer yet. == Download Gerrit From f60ea967ae01bcc27aaa78f6251586911fde1f4d Mon Sep 17 00:00:00 2001 From: David Pursehouse Date: Tue, 14 Aug 2018 20:47:47 +0100 Subject: [PATCH 04/14] ProjectIT: Factor out a method to set the max object size limit Change-Id: Iea22ff442f4fe6b577fe5fbce42496abc422eae8 --- .../acceptance/api/project/ProjectIT.java | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/project/ProjectIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/project/ProjectIT.java index 272e2c585e..cc88a6d121 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/project/ProjectIT.java +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/project/ProjectIT.java @@ -150,16 +150,13 @@ public class ProjectIT extends AbstractDaemonTest { @Test public void maxObjectSizeCanBeSetAndCleared() throws Exception { // Set a value - ConfigInput input = new ConfigInput(); - input.maxObjectSizeLimit = "100k"; - ConfigInfo info = setConfig(input); + ConfigInfo info = setMaxObjectSize("100k"); assertThat(info.maxObjectSizeLimit.value).isEqualTo("100k"); assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("100k"); assertThat(info.maxObjectSizeLimit.inheritedValue).isNull(); // Clear the value - input.maxObjectSizeLimit = "0"; - info = setConfig(input); + info = setMaxObjectSize("0"); assertThat(info.maxObjectSizeLimit.value).isNull(); assertThat(info.maxObjectSizeLimit.configuredValue).isNull(); assertThat(info.maxObjectSizeLimit.inheritedValue).isNull(); @@ -169,9 +166,7 @@ public class ProjectIT extends AbstractDaemonTest { public void maxObjectSizeIsNotInheritedFromParentProject() throws Exception { Project.NameKey child = createProject(name("child"), project); - ConfigInput input = new ConfigInput(); - input.maxObjectSizeLimit = "100k"; - ConfigInfo info = setConfig(input); + ConfigInfo info = setMaxObjectSize("100k"); assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("100k"); assertThat(info.maxObjectSizeLimit.inheritedValue).isNull(); @@ -193,9 +188,7 @@ public class ProjectIT extends AbstractDaemonTest { @Test @GerritConfig(name = "receive.maxObjectSizeLimit", value = "200k") public void maxObjectSizeOverridesGlobalConfigWhenLower() throws Exception { - ConfigInput input = new ConfigInput(); - input.maxObjectSizeLimit = "100k"; - ConfigInfo info = setConfig(input); + ConfigInfo info = setMaxObjectSize("100k"); assertThat(info.maxObjectSizeLimit.value).isEqualTo("100k"); assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("100k"); assertThat(info.maxObjectSizeLimit.inheritedValue).isEqualTo("200k"); @@ -204,9 +197,7 @@ public class ProjectIT extends AbstractDaemonTest { @Test @GerritConfig(name = "receive.maxObjectSizeLimit", value = "200k") public void maxObjectSizeDoesNotOverrideGlobalConfigWhenHigher() throws Exception { - ConfigInput input = new ConfigInput(); - input.maxObjectSizeLimit = "300k"; - ConfigInfo info = setConfig(input); + ConfigInfo info = setMaxObjectSize("300k"); assertThat(info.maxObjectSizeLimit.value).isEqualTo("200k"); assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("300k"); assertThat(info.maxObjectSizeLimit.inheritedValue).isEqualTo("200k"); @@ -214,11 +205,9 @@ public class ProjectIT extends AbstractDaemonTest { @Test public void invalidMaxObjectSizeIsRejected() throws Exception { - ConfigInput input = new ConfigInput(); - input.maxObjectSizeLimit = "100 foo"; exception.expect(ResourceConflictException.class); exception.expectMessage("100 foo"); - setConfig(input); + setMaxObjectSize("100 foo"); } private ConfigInfo setConfig(Project.NameKey name, ConfigInput input) throws Exception { @@ -229,6 +218,12 @@ public class ProjectIT extends AbstractDaemonTest { return setConfig(project, input); } + private ConfigInfo setMaxObjectSize(String value) throws Exception { + ConfigInput input = new ConfigInput(); + input.maxObjectSizeLimit = value; + return setConfig(input); + } + private ConfigInfo getConfig(Project.NameKey name) throws Exception { return gApi.projects().name(name.get()).config(); } From a801ff9d6dd4e6d6e1e78aec8be465d050309717 Mon Sep 17 00:00:00 2001 From: David Pursehouse Date: Tue, 14 Aug 2018 17:15:12 +0100 Subject: [PATCH 05/14] TransferConfig: Move getEffectiveMaxObjectSizeLimit to ProjectState This is a preparatory change towards implementing support for inheriting the max object size limit from parent projects. Change-Id: Ib92f064fe9d71a04555d94b770faf351cb42c12f --- .../google/gerrit/server/git/ReceiveCommits.java | 3 +-- .../google/gerrit/server/git/TransferConfig.java | 11 ----------- .../gerrit/server/project/ConfigInfoImpl.java | 3 +-- .../google/gerrit/server/project/ProjectState.java | 13 +++++++++++++ .../gerrit/server/project/RefControlTest.java | 3 +++ 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java index 7ee855d216..cd974647dd 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ReceiveCommits.java @@ -446,8 +446,7 @@ public class ReceiveCommits { rp.setAllowNonFastForwards(true); rp.setRefLogIdent(user.newRefLogIdent()); rp.setTimeout(transferConfig.getTimeout()); - rp.setMaxObjectSizeLimit( - transferConfig.getEffectiveMaxObjectSizeLimit(projectControl.getProjectState())); + rp.setMaxObjectSizeLimit(projectControl.getProjectState().getEffectiveMaxObjectSizeLimit()); rp.setCheckReceivedObjects(ps.getConfig().getCheckReceivedObjects()); rp.setRefFilter( new RefFilter() { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/TransferConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/TransferConfig.java index 4ac9071f45..28432f56a9 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/TransferConfig.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/TransferConfig.java @@ -16,7 +16,6 @@ package com.google.gerrit.server.git; import com.google.gerrit.server.config.ConfigUtil; import com.google.gerrit.server.config.GerritServerConfig; -import com.google.gerrit.server.project.ProjectState; import com.google.inject.Inject; import com.google.inject.Singleton; import java.util.concurrent.TimeUnit; @@ -66,14 +65,4 @@ public class TransferConfig { public String getFormattedMaxObjectSizeLimit() { return maxObjectSizeLimitFormatted; } - - public long getEffectiveMaxObjectSizeLimit(ProjectState p) { - long global = getMaxObjectSizeLimit(); - long local = p.getMaxObjectSizeLimit(); - if (global > 0 && local > 0) { - return Math.min(global, local); - } - // zero means "no limit", in this case the max is more limiting - return Math.max(global, local); - } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ConfigInfoImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ConfigInfoImpl.java index b80442b086..0ddb8475ec 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ConfigInfoImpl.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ConfigInfoImpl.java @@ -126,8 +126,7 @@ public class ConfigInfoImpl extends ConfigInfo { ProjectState projectState, TransferConfig transferConfig, Project p) { MaxObjectSizeLimitInfo info = new MaxObjectSizeLimitInfo(); info.value = - transferConfig.getEffectiveMaxObjectSizeLimit(projectState) - == transferConfig.getMaxObjectSizeLimit() + projectState.getEffectiveMaxObjectSizeLimit() == transferConfig.getMaxObjectSizeLimit() ? transferConfig.getFormattedMaxObjectSizeLimit() : p.getMaxObjectSizeLimit(); info.configuredValue = p.getMaxObjectSizeLimit(); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java index 95a89a3714..681515bbaf 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectState.java @@ -46,6 +46,7 @@ import com.google.gerrit.server.git.BranchOrderSection; import com.google.gerrit.server.git.GitRepositoryManager; import com.google.gerrit.server.git.ProjectConfig; import com.google.gerrit.server.git.ProjectLevelConfig; +import com.google.gerrit.server.git.TransferConfig; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; import com.googlecode.prolog_cafe.exceptions.CompileException; @@ -93,6 +94,7 @@ public class ProjectState { private final ProjectConfig config; private final Map configs; private final Set localOwners; + private final long globalMaxObjectSizeLimit; /** Prolog rule state. */ private volatile PrologMachineCopy rulesMachine; @@ -121,6 +123,7 @@ public class ProjectState { RulesCache rulesCache, List commentLinks, CapabilityCollection.Factory capabilityFactory, + TransferConfig transferConfig, @Assisted ProjectConfig config) { this.sitePaths = sitePaths; this.projectCache = projectCache; @@ -138,6 +141,7 @@ public class ProjectState { isAllProjects ? capabilityFactory.create(config.getAccessSection(AccessSection.GLOBAL_CAPABILITIES)) : null; + this.globalMaxObjectSizeLimit = transferConfig.getMaxObjectSizeLimit(); if (isAllProjects && !Permission.canBeOnAllProjects(AccessSection.ALL, Permission.OWNER)) { localOwners = Collections.emptySet(); @@ -245,6 +249,15 @@ public class ProjectState { return config.getMaxObjectSizeLimit(); } + public long getEffectiveMaxObjectSizeLimit() { + long local = getMaxObjectSizeLimit(); + if (globalMaxObjectSizeLimit > 0 && local > 0) { + return Math.min(globalMaxObjectSizeLimit, local); + } + // zero means "no limit", in this case the max is more limiting + return Math.max(globalMaxObjectSizeLimit, local); + } + /** Get the sections that pertain only to this project. */ List getLocalAccessSections() { List sm = localAccessSections; diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java index 00141a9d0a..4f2284cb40 100644 --- a/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java +++ b/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java @@ -57,6 +57,7 @@ import com.google.gerrit.server.config.AllUsersName; import com.google.gerrit.server.config.AllUsersNameProvider; import com.google.gerrit.server.config.SitePaths; import com.google.gerrit.server.git.ProjectConfig; +import com.google.gerrit.server.git.TransferConfig; import com.google.gerrit.server.index.SingleVersionModule.SingleVersionListener; import com.google.gerrit.server.query.change.InternalChangeQuery; import com.google.gerrit.server.schema.SchemaCreator; @@ -204,6 +205,7 @@ public class RefControlTest { @Inject private ThreadLocalRequestContext requestContext; @Inject private Provider queryProvider; @Inject private ProjectControl.Metrics metrics; + @Inject private TransferConfig transferConfig; @Before public void setUp() throws Exception { @@ -883,6 +885,7 @@ public class RefControlTest { rulesCache, commentLinks, capabilityCollectionFactory, + transferConfig, pc)); return repo; } From 33f544a0759e6e0e820583492fc77ef433ef54d7 Mon Sep 17 00:00:00 2001 From: David Pursehouse Date: Mon, 20 Aug 2018 12:20:18 +0900 Subject: [PATCH 06/14] ConfigInfoImpl: Return raw byte value for effective value The 'value' field of the info shows the effective value that gets applied. Set it as the actual byte value rather than the formatted value which could be using any arbitrary unit suffix (within the scope of the suffixes actually supported). In the UI, always show the effective value, rather than only when there is a global value, and explicitly say when there is no value configured. Note that the UI changes are only in GWT because the project info screen is not implemented for Polygerrit on this branch. The same changes can be applied to Polygerrit in a follow-up commit after this has been merged up to stable-2.15/master. Change-Id: Ibb88d734e6a322ee90f66d1b4c4a3882d2e0654a --- Documentation/rest-api-projects.txt | 2 +- .../gerrit/acceptance/api/project/ProjectIT.java | 9 +++++---- .../com/google/gerrit/client/admin/AdminMessages.java | 2 ++ .../gerrit/client/admin/AdminMessages.properties | 3 ++- .../google/gerrit/client/admin/ProjectInfoScreen.java | 11 ++++++----- .../google/gerrit/server/project/ConfigInfoImpl.java | 6 ++---- 6 files changed, 18 insertions(+), 15 deletions(-) diff --git a/Documentation/rest-api-projects.txt b/Documentation/rest-api-projects.txt index 6e460d6efa..eee31519f1 100644 --- a/Documentation/rest-api-projects.txt +++ b/Documentation/rest-api-projects.txt @@ -2805,7 +2805,7 @@ limit] of a project. |=============================== |Field Name ||Description |`value` |optional| -The effective value of the max object size limit as a formatted string. + +The effective value in bytes of the max object size limit. + Not set if there is no limit for the object size. |`configured_value`|optional| The max object size limit that is configured on the project as a diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/project/ProjectIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/project/ProjectIT.java index cc88a6d121..7c62302192 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/project/ProjectIT.java +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/project/ProjectIT.java @@ -151,7 +151,7 @@ public class ProjectIT extends AbstractDaemonTest { public void maxObjectSizeCanBeSetAndCleared() throws Exception { // Set a value ConfigInfo info = setMaxObjectSize("100k"); - assertThat(info.maxObjectSizeLimit.value).isEqualTo("100k"); + assertThat(info.maxObjectSizeLimit.value).isEqualTo("102400"); assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("100k"); assertThat(info.maxObjectSizeLimit.inheritedValue).isNull(); @@ -167,6 +167,7 @@ public class ProjectIT extends AbstractDaemonTest { Project.NameKey child = createProject(name("child"), project); ConfigInfo info = setMaxObjectSize("100k"); + assertThat(info.maxObjectSizeLimit.value).isEqualTo("102400"); assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("100k"); assertThat(info.maxObjectSizeLimit.inheritedValue).isNull(); @@ -180,7 +181,7 @@ public class ProjectIT extends AbstractDaemonTest { @GerritConfig(name = "receive.maxObjectSizeLimit", value = "200k") public void maxObjectSizeIsInheritedFromGlobalConfig() throws Exception { ConfigInfo info = getConfig(); - assertThat(info.maxObjectSizeLimit.value).isEqualTo("200k"); + assertThat(info.maxObjectSizeLimit.value).isEqualTo("204800"); assertThat(info.maxObjectSizeLimit.configuredValue).isNull(); assertThat(info.maxObjectSizeLimit.inheritedValue).isEqualTo("200k"); } @@ -189,7 +190,7 @@ public class ProjectIT extends AbstractDaemonTest { @GerritConfig(name = "receive.maxObjectSizeLimit", value = "200k") public void maxObjectSizeOverridesGlobalConfigWhenLower() throws Exception { ConfigInfo info = setMaxObjectSize("100k"); - assertThat(info.maxObjectSizeLimit.value).isEqualTo("100k"); + assertThat(info.maxObjectSizeLimit.value).isEqualTo("102400"); assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("100k"); assertThat(info.maxObjectSizeLimit.inheritedValue).isEqualTo("200k"); } @@ -198,7 +199,7 @@ public class ProjectIT extends AbstractDaemonTest { @GerritConfig(name = "receive.maxObjectSizeLimit", value = "200k") public void maxObjectSizeDoesNotOverrideGlobalConfigWhenHigher() throws Exception { ConfigInfo info = setMaxObjectSize("300k"); - assertThat(info.maxObjectSizeLimit.value).isEqualTo("200k"); + assertThat(info.maxObjectSizeLimit.value).isEqualTo("204800"); assertThat(info.maxObjectSizeLimit.configuredValue).isEqualTo("300k"); assertThat(info.maxObjectSizeLimit.inheritedValue).isEqualTo("200k"); } diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminMessages.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminMessages.java index 0c2f6fa80c..fe27e9c7cf 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminMessages.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminMessages.java @@ -38,6 +38,8 @@ public interface AdminMessages extends Messages { String globalMaxObjectSizeLimit(String globalMaxObjectSizeLimit); + String noMaxObjectSizeLimit(); + String pluginProjectOptionsTitle(String pluginName); String pluginProjectInheritedValue(String value); diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminMessages.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminMessages.properties index 6338920c6e..f746365f18 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminMessages.properties +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminMessages.properties @@ -5,8 +5,9 @@ project = Project {0} deletedGroup = Deleted Group {0} deletedReference = Reference {0} was deleted deletedSection = Section {0} was deleted -effectiveMaxObjectSizeLimit = effective: {0} +effectiveMaxObjectSizeLimit = effective: {0} bytes globalMaxObjectSizeLimit = The global max object size limit is set to {0}. The limit cannot be increased on project level. +noMaxObjectSizeLimit = No max object size limit is set. pluginProjectOptionsTitle = {0} Plugin Options pluginProjectOptionsTitle = {0} Plugin pluginProjectInheritedValue = inherited: {0} diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java index 144a152373..0e185eb130 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java @@ -401,14 +401,15 @@ public class ProjectInfoScreen extends ProjectScreen { setSubmitType(result.submitType()); setState(result.state()); maxObjectSizeLimit.setText(result.maxObjectSizeLimit().configuredValue()); - if (result.maxObjectSizeLimit().inheritedValue() != null) { - effectiveMaxObjectSizeLimit.setVisible(true); + if (result.maxObjectSizeLimit().value() != null) { effectiveMaxObjectSizeLimit.setText( AdminMessages.I.effectiveMaxObjectSizeLimit(result.maxObjectSizeLimit().value())); - effectiveMaxObjectSizeLimit.setTitle( - AdminMessages.I.globalMaxObjectSizeLimit(result.maxObjectSizeLimit().inheritedValue())); + if (result.maxObjectSizeLimit().inheritedValue() != null) { + effectiveMaxObjectSizeLimit.setTitle( + AdminMessages.I.globalMaxObjectSizeLimit(result.maxObjectSizeLimit().inheritedValue())); + } } else { - effectiveMaxObjectSizeLimit.setVisible(false); + effectiveMaxObjectSizeLimit.setText(AdminMessages.I.noMaxObjectSizeLimit()); } saveProject.setEnabled(false); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ConfigInfoImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ConfigInfoImpl.java index 0ddb8475ec..24760b7b10 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ConfigInfoImpl.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ConfigInfoImpl.java @@ -125,10 +125,8 @@ public class ConfigInfoImpl extends ConfigInfo { private MaxObjectSizeLimitInfo getMaxObjectSizeLimit( ProjectState projectState, TransferConfig transferConfig, Project p) { MaxObjectSizeLimitInfo info = new MaxObjectSizeLimitInfo(); - info.value = - projectState.getEffectiveMaxObjectSizeLimit() == transferConfig.getMaxObjectSizeLimit() - ? transferConfig.getFormattedMaxObjectSizeLimit() - : p.getMaxObjectSizeLimit(); + long value = projectState.getEffectiveMaxObjectSizeLimit(); + info.value = value == 0 ? null : String.valueOf(value); info.configuredValue = p.getMaxObjectSizeLimit(); info.inheritedValue = transferConfig.getFormattedMaxObjectSizeLimit(); return info; From 6a3fa83072e93ade48fc445500341a5d08e1ffa8 Mon Sep 17 00:00:00 2001 From: Edwin Kempin Date: Mon, 20 Aug 2018 11:51:18 +0200 Subject: [PATCH 07/14] Fix http_archive rule in WORKSPACE Building the Eclipse project on Mac failed for me with: ERROR: /Users/ekempin/git/gerrit/WORKSPACE:15:1: //external:io_bazel_rules_closure: no such attribute 'url' in 'http_archive' rule ERROR: /Users/ekempin/git/gerrit/WORKSPACE:15:1: //external:io_bazel_rules_closure: missing value for mandatory attribute 'urls' in 'http_archive' rule Change-Id: I03620a3eaf74138c15ff205dbcb349fcb7845f46 Signed-off-by: Edwin Kempin --- WORKSPACE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WORKSPACE b/WORKSPACE index 59b8dc41d9..1e53592aca 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -16,7 +16,7 @@ http_archive( name = "io_bazel_rules_closure", sha256 = "4dd84dd2bdd6c9f56cb5a475d504ea31d199c34309e202e9379501d01c3067e5", strip_prefix = "rules_closure-3103a773820b59b76345f94c231cb213e0d404e2", - url = "https://github.com/bazelbuild/rules_closure/archive/3103a773820b59b76345f94c231cb213e0d404e2.tar.gz", + urls = ["https://github.com/bazelbuild/rules_closure/archive/3103a773820b59b76345f94c231cb213e0d404e2.tar.gz"], ) # File is specific to Polymer and copied from the Closure Github -- should be From 9d18f269480a15cd3996624e78f932caa3a34495 Mon Sep 17 00:00:00 2001 From: David Pursehouse Date: Tue, 13 Jun 2017 19:32:32 +0900 Subject: [PATCH 08/14] GetReflog: Move ReflogEntryInfo to a separate class in extension API Change-Id: Ib9ab9b16cacaed88c5e1d901af37be086b635d0b --- .../api/projects/ReflogEntryInfo.java | 31 +++++++++++++++++++ .../gerrit/server/project/GetReflog.java | 22 +++++-------- 2 files changed, 39 insertions(+), 14 deletions(-) create mode 100644 gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/ReflogEntryInfo.java diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/ReflogEntryInfo.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/ReflogEntryInfo.java new file mode 100644 index 0000000000..a0984ec311 --- /dev/null +++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/ReflogEntryInfo.java @@ -0,0 +1,31 @@ +// Copyright (C) 2017 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.extensions.api.projects; + +import com.google.gerrit.extensions.common.GitPerson; + +public class ReflogEntryInfo { + public String oldId; + public String newId; + public GitPerson who; + public String comment; + + public ReflogEntryInfo(String oldId, String newId, GitPerson who, String comment) { + this.oldId = oldId; + this.newId = newId; + this.who = who; + this.comment = comment; + } +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/GetReflog.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/GetReflog.java index f51528ddc3..abb7c5fbc8 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/GetReflog.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/GetReflog.java @@ -15,7 +15,7 @@ package com.google.gerrit.server.project; import com.google.common.collect.Lists; -import com.google.gerrit.extensions.common.GitPerson; +import com.google.gerrit.extensions.api.projects.ReflogEntryInfo; import com.google.gerrit.extensions.restapi.AuthException; import com.google.gerrit.extensions.restapi.ResourceNotFoundException; import com.google.gerrit.extensions.restapi.RestReadView; @@ -106,21 +106,15 @@ public class GetReflog implements RestReadView { } } } - return Lists.transform(entries, ReflogEntryInfo::new); + return Lists.transform(entries, e -> newReflogEntryInfo(e)); } } - public static class ReflogEntryInfo { - public String oldId; - public String newId; - public GitPerson who; - public String comment; - - public ReflogEntryInfo(ReflogEntry e) { - oldId = e.getOldId().getName(); - newId = e.getNewId().getName(); - who = CommonConverters.toGitPerson(e.getWho()); - comment = e.getComment(); - } + private ReflogEntryInfo newReflogEntryInfo(ReflogEntry e) { + return new ReflogEntryInfo( + e.getOldId().getName(), + e.getNewId().getName(), + CommonConverters.toGitPerson(e.getWho()), + e.getComment()); } } From 8f84ab89700b4d9a191ca08be8b3344366756208 Mon Sep 17 00:00:00 2001 From: David Pursehouse Date: Tue, 13 Jun 2017 19:42:53 +0900 Subject: [PATCH 09/14] BranchApi: Add method to get the branch's reflog GetReflog uses Repository#getReflogReader, but this is not implemented by DfsRepository which is used in the test framework. As a result, calls to this API method from tests results in UnsupportedOperationException. Modify GetReflog to catch the UOE and rethrow as MethodNotAllowed, so we get a graceful failure rather than "internal server error". In the tests, expect MethodNotAllowed, with a TODO to rework when/if the implementation of getReflogReader is done in DfsRepository. Change-Id: I0d0d718ca4e4ecf2c544ea6e912397c20e2fd7e3 --- .../acceptance/api/change/ChangeIT.java | 10 ++++++++++ .../extensions/api/projects/BranchApi.java | 8 ++++++++ .../server/api/projects/BranchApiImpl.java | 15 +++++++++++++++ .../gerrit/server/project/GetReflog.java | 19 +++++++++++++++---- 4 files changed, 48 insertions(+), 4 deletions(-) diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java index 1bde86833a..ead0b063ed 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java @@ -160,6 +160,16 @@ public class ChangeIT extends AbstractDaemonTest { System.setProperty("user.timezone", systemTimeZone); } + @Test + public void reflog() throws Exception { + // Tests are using DfsRepository which does not implement getReflogReader, + // so this will always fail. + // TODO: change this if/when DfsRepository#getReflogReader is implemented. + exception.expect(MethodNotAllowedException.class); + exception.expectMessage("reflog not supported"); + gApi.projects().name(project.get()).branch("master").reflog(); + } + @Test public void get() throws Exception { PushOneCommit.Result r = createChange(); diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/BranchApi.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/BranchApi.java index 995f41ab09..250eca4984 100644 --- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/BranchApi.java +++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/BranchApi.java @@ -17,6 +17,7 @@ package com.google.gerrit.extensions.api.projects; import com.google.gerrit.extensions.restapi.BinaryResult; import com.google.gerrit.extensions.restapi.NotImplementedException; import com.google.gerrit.extensions.restapi.RestApiException; +import java.util.List; public interface BranchApi { BranchApi create(BranchInput in) throws RestApiException; @@ -28,6 +29,8 @@ public interface BranchApi { /** Returns the content of a file from the HEAD revision. */ BinaryResult file(String path) throws RestApiException; + List reflog() throws RestApiException; + /** * A default implementation which allows source compatibility when adding new methods to the * interface. @@ -52,5 +55,10 @@ public interface BranchApi { public BinaryResult file(String path) throws RestApiException { throw new NotImplementedException(); } + + @Override + public List reflog() { + throw new NotImplementedException(); + } } } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/projects/BranchApiImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/projects/BranchApiImpl.java index 2fc78337ee..348b4e8876 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/api/projects/BranchApiImpl.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/projects/BranchApiImpl.java @@ -17,6 +17,7 @@ package com.google.gerrit.server.api.projects; import com.google.gerrit.extensions.api.projects.BranchApi; import com.google.gerrit.extensions.api.projects.BranchInfo; import com.google.gerrit.extensions.api.projects.BranchInput; +import com.google.gerrit.extensions.api.projects.ReflogEntryInfo; import com.google.gerrit.extensions.restapi.BinaryResult; import com.google.gerrit.extensions.restapi.IdString; import com.google.gerrit.extensions.restapi.RestApiException; @@ -27,11 +28,13 @@ import com.google.gerrit.server.project.DeleteBranch; import com.google.gerrit.server.project.FileResource; import com.google.gerrit.server.project.FilesCollection; import com.google.gerrit.server.project.GetContent; +import com.google.gerrit.server.project.GetReflog; import com.google.gerrit.server.project.ProjectResource; import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; import java.io.IOException; +import java.util.List; public class BranchApiImpl implements BranchApi { interface Factory { @@ -43,6 +46,7 @@ public class BranchApiImpl implements BranchApi { private final DeleteBranch deleteBranch; private final FilesCollection filesCollection; private final GetContent getContent; + private final GetReflog getReflog; private final String ref; private final ProjectResource project; @@ -53,6 +57,7 @@ public class BranchApiImpl implements BranchApi { DeleteBranch deleteBranch, FilesCollection filesCollection, GetContent getContent, + GetReflog getReflog, @Assisted ProjectResource project, @Assisted String ref) { this.branches = branches; @@ -60,6 +65,7 @@ public class BranchApiImpl implements BranchApi { this.deleteBranch = deleteBranch; this.filesCollection = filesCollection; this.getContent = getContent; + this.getReflog = getReflog; this.project = project; this.ref = ref; } @@ -102,6 +108,15 @@ public class BranchApiImpl implements BranchApi { } } + @Override + public List reflog() throws RestApiException { + try { + return getReflog.apply(resource()); + } catch (IOException e) { + throw new RestApiException("Cannot retrieve reflog", e); + } + } + private BranchResource resource() throws RestApiException, IOException { return branches.parse(project, IdString.fromDecoded(ref)); } diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/GetReflog.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/GetReflog.java index abb7c5fbc8..81f08731be 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/GetReflog.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/GetReflog.java @@ -17,7 +17,9 @@ package com.google.gerrit.server.project; import com.google.common.collect.Lists; import com.google.gerrit.extensions.api.projects.ReflogEntryInfo; import com.google.gerrit.extensions.restapi.AuthException; +import com.google.gerrit.extensions.restapi.MethodNotAllowedException; import com.google.gerrit.extensions.restapi.ResourceNotFoundException; +import com.google.gerrit.extensions.restapi.RestApiException; import com.google.gerrit.extensions.restapi.RestReadView; import com.google.gerrit.server.CommonConverters; import com.google.gerrit.server.args4j.TimestampHandler; @@ -27,13 +29,16 @@ import java.io.IOException; import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; -import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.lib.ReflogEntry; import org.eclipse.jgit.lib.ReflogReader; import org.eclipse.jgit.lib.Repository; import org.kohsuke.args4j.Option; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class GetReflog implements RestReadView { + private static final Logger log = LoggerFactory.getLogger(GetReflog.class); + private final GitRepositoryManager repoManager; @Option( @@ -80,14 +85,20 @@ public class GetReflog implements RestReadView { } @Override - public List apply(BranchResource rsrc) - throws AuthException, ResourceNotFoundException, RepositoryNotFoundException, IOException { + public List apply(BranchResource rsrc) throws RestApiException, IOException { if (!rsrc.getControl().isOwner()) { throw new AuthException("not project owner"); } try (Repository repo = repoManager.openRepository(rsrc.getNameKey())) { - ReflogReader r = repo.getReflogReader(rsrc.getRef()); + ReflogReader r; + try { + r = repo.getReflogReader(rsrc.getRef()); + } catch (UnsupportedOperationException e) { + String msg = "reflog not supported on repo " + rsrc.getNameKey().get(); + log.error(msg); + throw new MethodNotAllowedException(msg); + } if (r == null) { throw new ResourceNotFoundException(rsrc.getRef()); } From d4b863a4a606315a208b216dcd91e0836bf5c645 Mon Sep 17 00:00:00 2001 From: David Pursehouse Date: Wed, 15 Aug 2018 09:07:06 +0100 Subject: [PATCH 10/14] ChangeIT: Fix and expand reflog test The reflog API was not being fully tested because the underlying JGit implementation (DfsRepository) does not support reflog. However, annotating the test as @UseLocalDisk results in a different implementation being used that does support reflog. Rewrite the test to perform a basic test on the reflog API. That is, by submitting a change the size of the reflog increases. More in depth tests can be added later in follow up commits if necessary. Change-Id: I743f1f52010c8a0a036918f3a3b0f5c54f4e3705 --- .../acceptance/api/change/ChangeIT.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java index ead0b063ed..2a4cf83d9f 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java @@ -49,6 +49,7 @@ import com.google.gerrit.acceptance.PushOneCommit; import com.google.gerrit.acceptance.Sandboxed; import com.google.gerrit.acceptance.TestAccount; import com.google.gerrit.acceptance.TestProjectInput; +import com.google.gerrit.acceptance.UseLocalDisk; import com.google.gerrit.common.FooterConstants; import com.google.gerrit.common.TimeUtil; import com.google.gerrit.common.data.LabelType; @@ -64,9 +65,11 @@ import com.google.gerrit.extensions.api.changes.ReviewInput; import com.google.gerrit.extensions.api.changes.ReviewInput.DraftHandling; import com.google.gerrit.extensions.api.changes.RevisionApi; import com.google.gerrit.extensions.api.groups.GroupApi; +import com.google.gerrit.extensions.api.projects.BranchApi; import com.google.gerrit.extensions.api.projects.BranchInput; import com.google.gerrit.extensions.api.projects.ProjectApi; import com.google.gerrit.extensions.api.projects.ProjectInput; +import com.google.gerrit.extensions.api.projects.ReflogEntryInfo; import com.google.gerrit.extensions.client.ChangeKind; import com.google.gerrit.extensions.client.ChangeStatus; import com.google.gerrit.extensions.client.Comment.Range; @@ -161,13 +164,26 @@ public class ChangeIT extends AbstractDaemonTest { } @Test + @UseLocalDisk public void reflog() throws Exception { - // Tests are using DfsRepository which does not implement getReflogReader, - // so this will always fail. - // TODO: change this if/when DfsRepository#getReflogReader is implemented. - exception.expect(MethodNotAllowedException.class); - exception.expectMessage("reflog not supported"); - gApi.projects().name(project.get()).branch("master").reflog(); + BranchApi branchApi = gApi.projects().name(project.get()).branch("master"); + List reflog = branchApi.reflog(); + assertThat(reflog).isNotEmpty(); + + // Current number of entries in the reflog + int refLogLen = reflog.size(); + + // Create and submit a change + PushOneCommit.Result r = createChange(); + String changeId = r.getChangeId(); + String revision = r.getCommit().name(); + ReviewInput in = ReviewInput.approve(); + gApi.changes().id(changeId).revision(revision).review(in); + gApi.changes().id(changeId).revision(revision).submit(); + + // Submitting the change causes a new entry in the reflog + reflog = branchApi.reflog(); + assertThat(reflog).hasSize(refLogLen + 1); } @Test From e530b33cd57418f0556596381758073f98e66a2d Mon Sep 17 00:00:00 2001 From: David Pursehouse Date: Wed, 15 Aug 2018 10:04:54 +0100 Subject: [PATCH 11/14] ChangeIT: Move reflog test to ReflogIT Change-Id: Iaca8427db6c0af3c8b7fa620b708268f69023eb3 --- .../acceptance/api/change/ChangeIT.java | 26 ---------- .../acceptance/server/project/ReflogIT.java | 51 +++++++++++++++++++ 2 files changed, 51 insertions(+), 26 deletions(-) create mode 100644 gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/ReflogIT.java diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java index 2a4cf83d9f..1bde86833a 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java @@ -49,7 +49,6 @@ import com.google.gerrit.acceptance.PushOneCommit; import com.google.gerrit.acceptance.Sandboxed; import com.google.gerrit.acceptance.TestAccount; import com.google.gerrit.acceptance.TestProjectInput; -import com.google.gerrit.acceptance.UseLocalDisk; import com.google.gerrit.common.FooterConstants; import com.google.gerrit.common.TimeUtil; import com.google.gerrit.common.data.LabelType; @@ -65,11 +64,9 @@ import com.google.gerrit.extensions.api.changes.ReviewInput; import com.google.gerrit.extensions.api.changes.ReviewInput.DraftHandling; import com.google.gerrit.extensions.api.changes.RevisionApi; import com.google.gerrit.extensions.api.groups.GroupApi; -import com.google.gerrit.extensions.api.projects.BranchApi; import com.google.gerrit.extensions.api.projects.BranchInput; import com.google.gerrit.extensions.api.projects.ProjectApi; import com.google.gerrit.extensions.api.projects.ProjectInput; -import com.google.gerrit.extensions.api.projects.ReflogEntryInfo; import com.google.gerrit.extensions.client.ChangeKind; import com.google.gerrit.extensions.client.ChangeStatus; import com.google.gerrit.extensions.client.Comment.Range; @@ -163,29 +160,6 @@ public class ChangeIT extends AbstractDaemonTest { System.setProperty("user.timezone", systemTimeZone); } - @Test - @UseLocalDisk - public void reflog() throws Exception { - BranchApi branchApi = gApi.projects().name(project.get()).branch("master"); - List reflog = branchApi.reflog(); - assertThat(reflog).isNotEmpty(); - - // Current number of entries in the reflog - int refLogLen = reflog.size(); - - // Create and submit a change - PushOneCommit.Result r = createChange(); - String changeId = r.getChangeId(); - String revision = r.getCommit().name(); - ReviewInput in = ReviewInput.approve(); - gApi.changes().id(changeId).revision(revision).review(in); - gApi.changes().id(changeId).revision(revision).submit(); - - // Submitting the change causes a new entry in the reflog - reflog = branchApi.reflog(); - assertThat(reflog).hasSize(refLogLen + 1); - } - @Test public void get() throws Exception { PushOneCommit.Result r = createChange(); diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/ReflogIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/ReflogIT.java new file mode 100644 index 0000000000..1bf2f92214 --- /dev/null +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/ReflogIT.java @@ -0,0 +1,51 @@ +// Copyright (C) 2017 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.acceptance.server.project; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.gerrit.acceptance.AbstractDaemonTest; +import com.google.gerrit.acceptance.PushOneCommit; +import com.google.gerrit.acceptance.UseLocalDisk; +import com.google.gerrit.extensions.api.changes.ReviewInput; +import com.google.gerrit.extensions.api.projects.BranchApi; +import com.google.gerrit.extensions.api.projects.ReflogEntryInfo; +import java.util.List; +import org.junit.Test; + +@UseLocalDisk +public class ReflogIT extends AbstractDaemonTest { + @Test + public void reflogUpdatedBySubmittingChange() throws Exception { + BranchApi branchApi = gApi.projects().name(project.get()).branch("master"); + List reflog = branchApi.reflog(); + assertThat(reflog).isNotEmpty(); + + // Current number of entries in the reflog + int refLogLen = reflog.size(); + + // Create and submit a change + PushOneCommit.Result r = createChange(); + String changeId = r.getChangeId(); + String revision = r.getCommit().name(); + ReviewInput in = ReviewInput.approve(); + gApi.changes().id(changeId).revision(revision).review(in); + gApi.changes().id(changeId).revision(revision).submit(); + + // Submitting the change causes a new entry in the reflog + reflog = branchApi.reflog(); + assertThat(reflog).hasSize(refLogLen + 1); + } +} From 9f486bd587571f3d286b7fe624eb4b6052fa4771 Mon Sep 17 00:00:00 2001 From: David Pursehouse Date: Wed, 22 Aug 2018 13:24:07 +0900 Subject: [PATCH 12/14] ReflogIT: Add test coverage for reflog permissions Test that owners and admins can access the reflog, but regular users cannot. Change-Id: I358802d190ca12f3bae506aef2acc459478a5269 --- .../acceptance/server/project/ReflogIT.java | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/ReflogIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/ReflogIT.java index 1bf2f92214..31617bf63f 100644 --- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/ReflogIT.java +++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/ReflogIT.java @@ -19,15 +19,21 @@ import static com.google.common.truth.Truth.assertThat; import com.google.gerrit.acceptance.AbstractDaemonTest; import com.google.gerrit.acceptance.PushOneCommit; import com.google.gerrit.acceptance.UseLocalDisk; +import com.google.gerrit.common.data.Permission; import com.google.gerrit.extensions.api.changes.ReviewInput; +import com.google.gerrit.extensions.api.groups.GroupApi; import com.google.gerrit.extensions.api.projects.BranchApi; import com.google.gerrit.extensions.api.projects.ReflogEntryInfo; +import com.google.gerrit.extensions.restapi.AuthException; +import com.google.gerrit.reviewdb.client.AccountGroup; +import com.google.gerrit.server.git.ProjectConfig; +import com.google.gerrit.server.project.Util; import java.util.List; import org.junit.Test; -@UseLocalDisk public class ReflogIT extends AbstractDaemonTest { @Test + @UseLocalDisk public void reflogUpdatedBySubmittingChange() throws Exception { BranchApi branchApi = gApi.projects().name(project.get()).branch("master"); List reflog = branchApi.reflog(); @@ -48,4 +54,33 @@ public class ReflogIT extends AbstractDaemonTest { reflog = branchApi.reflog(); assertThat(reflog).hasSize(refLogLen + 1); } + + @Test + @UseLocalDisk + public void regularUserIsNotAllowedToGetReflog() throws Exception { + setApiUser(user); + exception.expect(AuthException.class); + gApi.projects().name(project.get()).branch("master").reflog(); + } + + @Test + @UseLocalDisk + public void ownerUserIsAllowedToGetReflog() throws Exception { + GroupApi groupApi = gApi.groups().create(name("get-reflog")); + groupApi.addMembers("user"); + + ProjectConfig cfg = projectCache.checkedGet(project).getConfig(); + Util.allow(cfg, Permission.OWNER, new AccountGroup.UUID(groupApi.get().id), "refs/*"); + saveProjectConfig(project, cfg); + + setApiUser(user); + gApi.projects().name(project.get()).branch("master").reflog(); + } + + @Test + @UseLocalDisk + public void adminUserIsAllowedToGetReflog() throws Exception { + setApiUser(admin); + gApi.projects().name(project.get()).branch("master").reflog(); + } } From 2a107d74a134cbf757584606f770dc26f82ff1f6 Mon Sep 17 00:00:00 2001 From: David Ostrovsky Date: Wed, 22 Aug 2018 07:32:21 +0200 Subject: [PATCH 13/14] FormatUtil: Fix Math#round() truncation error flagged by error-prone Building with Bazel@HEAD: [1] is failing with this error message: FormatUtil.java:129: error: [MathRoundIntLong] Math.round(Integer) results in truncation | int p = Math.abs(Math.round(delta * 100 / size)); | ^ | (see https://errorprone.info/bugpattern/MathRoundIntLong) | Did you mean 'int p = Math.abs(Ints.saturatedCast(delta * 100 / size));'? To rectify, replace Math.round() with Ints.saturatedCast() and borrow this method from Guava library because Guava cannot be currently used in GWT client code. [1] https://github.com/bazelbuild/bazel/issues/5944 Change-Id: I1c88102d4d027796594fb7cdcde4f0ec4921d4ad --- .../com/google/gerrit/client/FormatUtil.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/FormatUtil.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/FormatUtil.java index 730726436e..878abd2502 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/FormatUtil.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/FormatUtil.java @@ -137,7 +137,25 @@ public class FormatUtil { if (size == 0) { return Resources.C.notAvailable(); } - int p = Math.abs(Math.round(delta * 100 / size)); + int p = Math.abs(saturatedCast(delta * 100 / size)); return p + "%"; } + + /** + * Returns the {@code int} nearest in value to {@code value}. + * + * @param value any {@code long} value + * @return the same value cast to {@code int} if it is in the range of the {@code int} type, + * {@link Integer#MAX_VALUE} if it is too large, or {@link Integer#MIN_VALUE} if it is too + * small + */ + private static int saturatedCast(long value) { + if (value > Integer.MAX_VALUE) { + return Integer.MAX_VALUE; + } + if (value < Integer.MIN_VALUE) { + return Integer.MIN_VALUE; + } + return (int) value; + } } From 27757966a8a3585f1e69536834eadd8e81e08abe Mon Sep 17 00:00:00 2001 From: David Pursehouse Date: Wed, 22 Aug 2018 15:40:44 +0900 Subject: [PATCH 14/14] BranchApi: Add missing throws declaration on NotImplemented#reflog Change-Id: I9d8d8324ce1b92a2b8f7080953469a992e68d630 --- .../com/google/gerrit/extensions/api/projects/BranchApi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/BranchApi.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/BranchApi.java index 250eca4984..a1f7327b7c 100644 --- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/BranchApi.java +++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/projects/BranchApi.java @@ -57,7 +57,7 @@ public interface BranchApi { } @Override - public List reflog() { + public List reflog() throws RestApiException { throw new NotImplementedException(); } }