Merge "Remove unused constructor"
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index f0ab339..f10623f 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -842,7 +842,7 @@
----
[commentlink "changeid"]
match = (I[0-9a-f]{8,40})
- link = "#q,$1,n,z"
+ link = "#q,$1"
[commentlink "bugzilla"]
match = "(bug\\s+#?)(\\d+)"
@@ -1889,7 +1889,8 @@
+
* `SOLR`
+
-A link:http://lucene.apache.org/solr/[Solr] index is used.
+A link:https://cwiki.apache.org/confluence/display/solr/SolrCloud[
+SolrCloud] index is used.
+
By default, `LUCENE`.
@@ -1901,6 +1902,12 @@
Open and closed changes are indexed in separate indexes named
'changes_open' and 'changes_closed' respectively.
+[[index.url]]index.url::
++
+Only used when the type is `SOLR`.
++
+URL of the index server.
+
[[index.name.ramBufferSize]]index.name.ramBufferSize::
+
Only used when the type is `LUCENE`.
diff --git a/Documentation/config-project-config.txt b/Documentation/config-project-config.txt
index e86cdae..2fb256f 100644
--- a/Documentation/config-project-config.txt
+++ b/Documentation/config-project-config.txt
@@ -129,6 +129,21 @@
+
Common unit suffixes of k, m, or g are supported.
+[[receive.checkReceivedObjects]]receive.checkReceivedObjects::
++
+Controls whether or not the JGit functionality for checking received objects
+is enabled.
++
+By default Gerrit checks the validity of git objects. Setting this variable to
+false should not be used unless a project with history containing invalid
+objects needs to be pushed into a Gerrit repository.
++
+This functionality is provided as some other git implementations have allowed
+bad history to be written into git repositories. If these repositories need pushing
+up to Gerrit then the JGit checks need to be disabled.
++
+The default value for this is true, false disables the checks.
+
[[submit-section]]
=== Submit section
diff --git a/Documentation/dev-buck.txt b/Documentation/dev-buck.txt
index b6c1411..b48671e 100644
--- a/Documentation/dev-buck.txt
+++ b/Documentation/dev-buck.txt
@@ -322,6 +322,47 @@
)
----
+== Building against unpublished JARs, that change frequently
+
+If a dependent Gerrit library is undergoing active development it must be
+recompiled and the change must be reflected in the Buck build process. For
+example testing Gerrit against changed JGit snapshot version. After building
+JGit library, the artifacts are created in local Maven build directory, e. g.:
+
+----
+ mvn package
+ /home/<user>/projects/jgit/org.eclipse.jgit/target/org.eclipse.jgit-3.3.0-SNAPSHOT.jar
+ /home/<user>/projects/jgit/org.eclipse.jgit/target/org.eclipse.jgit-3.3.0-SNAPSHOT-sources.jar
+----
+
+If as usual, installation of the build artifacts takes place in local maven
+repository, then the Buck build must fetch them from there with normal
+`download_file.py` process. Disadvantage of this approach is that Buck cache
+invalidation must occur to refresh the artifacts after next
+change-compile-install round trip.
+
+To shorten that workflow and take the installation of the artifacts to the
+local Maven repository and fetching it again from there out of the picture,
+`local_jar()` method is used instead of `maven_jar()`:
+
+[source,python]
+----
+ local_jar(
+ name = 'jgit',
+ jar = '/home/<user>/projects/jgit/org.eclipse.jgit/target/org.eclipse.jgit-3.3.0-SNAPSHOT.jar',
+ src = '/home/<user>/projects/jgit/org.eclipse.jgit/target/org.eclipse.jgit-3.3.0-SNAPSHOT-sources.jar',
+ deps = [':ewah']
+ )
+----
+
+This creates a symlink to the Buck targets direct against artifacts in
+another project's Maven target directory:
+
+----
+ buck-out/gen/lib/jgit/jgit.jar ->
+ /home/<user>/projects/jgit/org.eclipse.jgit/target/org.eclipse.jgit-3.3.0-SNAPSHOT.jar
+----
+
== Building against artifacts from custom Maven repositories
To build against custom Maven repositories, two modes of operations are
diff --git a/Documentation/dev-contributing.txt b/Documentation/dev-contributing.txt
index d16734f..5e307f9 100644
--- a/Documentation/dev-contributing.txt
+++ b/Documentation/dev-contributing.txt
@@ -6,7 +6,15 @@
* https://gerrit-review.googlesource.com/
-The Contributor License Agreements:
+A Contributor License Agreement must be completed before contributions
+are accepted. To view and accept the agreements do the following:
+
+* Click "Sign In" at the top right corner of https://gerrit-review.googlesource.com/
+* Sign In with your Google account
+* After signing in, go to https://gerrit-review.googlesource.com/#/settings/agreements
+* Click "New Contributor Agreement" and follow the instructions
+
+For reference, the actual agreements are linked below
* https://gerrit-review.googlesource.com/static/cla_individual.html
* https://gerrit-review.googlesource.com/static/cla_corporate.html
@@ -19,7 +27,7 @@
your change. You can view the pending Gerrit contributions and
their statuses here:
-* https://gerrit-review.googlesource.com/#/q/status:open+project:gerrit,n,z
+* https://gerrit-review.googlesource.com/#/q/status:open+project:gerrit
Depending on the size of that list it might take a while for
your change to get reviewed. Naturally there are fewer
diff --git a/Documentation/dev-plugins.txt b/Documentation/dev-plugins.txt
index 14470b0..e0824ca 100644
--- a/Documentation/dev-plugins.txt
+++ b/Documentation/dev-plugins.txt
@@ -437,9 +437,10 @@
import com.google.gerrit.sshd.SshCommand;
import com.google.gerrit.sshd.CommandMetaData;
-@CommandMetaData(name="print", descr="Print hello command")
+@CommandMetaData(name="print", description="Print hello command")
class PrintHello extends SshCommand {
- protected abstract void run() {
+ @Override
+ protected void run() {
stdout.print("Hello\n");
}
}
@@ -455,7 +456,8 @@
@Export("print")
class PrintHello extends SshCommand {
- protected abstract void run() {
+ @Override
+ protected void run() {
stdout.print("Hello\n");
}
}
@@ -470,6 +472,7 @@
import com.google.gerrit.sshd.PluginCommandModule;
class MyCommands extends PluginCommandModule {
+ @Override
protected void configureCommands() {
command(PrintHello.class);
}
@@ -1602,6 +1605,13 @@
}
----
+[[settings-screen]]
+== Plugin Settings Screen
+
+If a plugin implements a screen for administrating its settings that is
+available under "#/x/<plugin-name>/settings" it is automatically linked
+from the plugin list screen.
+
[[http]]
== HTTP Servlets
diff --git a/Documentation/intro-change-screen.txt b/Documentation/intro-change-screen.txt
index 0aa6fd5..8bf9e27 100644
--- a/Documentation/intro-change-screen.txt
+++ b/Documentation/intro-change-screen.txt
@@ -28,8 +28,10 @@
The new change screen is activated by default. It can be deactivated
system-wide by changing the link:config-gerrit.html[gerrit.changeScreen]
-setting to `OLD_UI`. Users can deactivate it by setting `OLD_UI` on their
-user preferences page.
+setting to `OLD_UI`.
+
+Users can switch between the old and new screens by selecting "Old Screen" or
+"New Screen" in the "Change View" setting on their user preferences page.
[[switching-between-patch-sets]]
== Switching between patch sets
diff --git a/Documentation/user-search.txt b/Documentation/user-search.txt
index 0c6abb8..b28cbdb 100644
--- a/Documentation/user-search.txt
+++ b/Documentation/user-search.txt
@@ -64,6 +64,20 @@
* mon, month, months (`1 month` is treated as `30 days`)
* y, year, years (`1 year` is treated as `365 days`)
+[[before_until]]
+before:'TIME'/until:'TIME'
++
+Changes modified before the given 'TIME', inclusive. With no time,
+assumes 00:00:00 in the local time zone. Supports many formats supported
+by `git log`.
+
+[[after_since]]
+after:'TIME'/since:'TIME'
++
+Changes modified before the given 'TIME', inclusive. With no time,
+assumes 00:00:00 in the local time zone. Supports many formats supported
+by `git log`.
+
[[change]]
change:'ID'::
+
@@ -455,21 +469,6 @@
preferences. Including it in a web query may lead to unpredictable
results with regards to pagination.
-resume_sortkey:'KEY'::
-+
-Positions the low level scan routine to start from 'KEY' and
-continue through changes from this point. This is most often used
-for paginating result sets. Including this in a web query may lead
-to unpredictable results.
-
-sortkey_after:'KEY', sortkey_before:'KEY'::
-+
-Restart the low level scan routine from 'KEY'. This is automatically
-set by the pagination system as the user navigates through results
-of a query. Including either value in a web query may lead to
-unpredictable results.
-
-
GERRIT
------
Part of link:index.html[Gerrit Code Review]
diff --git a/ReleaseNotes/ReleaseNotes-2.8.2.txt b/ReleaseNotes/ReleaseNotes-2.8.2.txt
index 6d0f995..0307b59 100644
--- a/ReleaseNotes/ReleaseNotes-2.8.2.txt
+++ b/ReleaseNotes/ReleaseNotes-2.8.2.txt
@@ -36,6 +36,23 @@
If HEAD was detached the `GetHead` REST endpoint refused to resolve HEAD
when the user was not a project owner.
+* link:https://code.google.com/p/gerrit/issues/detail?id=2932[Issue 2932]:
+Keep `status:closed` limit below MySQL Connector/J's hard limit.
++
+Since MySQL Connector/J 5.1.21 does not allow limits above 50M rows
+and aborts them with 'setMaxRows() out of range', we cannot use `MAX_VALUE`
+as limit for plain `status:closed` queries.
+
+* Fix IllegalArgumentException when running query with `limit:0` on secondary
+index.
++
+Running a query with `limit:0` when the secondary index is enabled was causing
+an internal server error.
+
+* Remove dependency on joda time library in gerrit launcher.
++
+The joda time library was being unnecessarily packaged in the root of
+the gerrit.war file.
Change Screen / Diff Screen
---------------------------
@@ -65,6 +82,40 @@
+
The action was using the cherry-pick button instead of the revert button.
+* Improve the error message shown when cherry picking a change fails.
++
+The error message "Could not create merge commit during cherry pick" was
+confusing for users, and is replaced with simply "Cherry pick failed".
+
+* Add newline on commit messages created by cherry picking a change in the UI
+or via the REST API.
++
+If a commit was cherry-picked from the UI or via the REST API, the
+trailing newline on the end of the commit message was lost.
+
+* link:https://code.google.com/p/gerrit/issues/detail?id=2405[Issue 2405]:
+Update change to invalidate cache after deletion of draft revision.
++
+When a non-current draft patch set was deleted no update of the change
+was made, causing the change screen to not work properly because it
+relied on cached data.
+
+* Extend change screen's horizontal bars to full width.
++
+This allows the title of the change message to have some padding within
+the bar.
+
+* Fix tab alignment to be correct width in side-by-side diff.
++
+This fixes the tab width to be the user's preference, rather than
+1 + user's preference when show tabs is enabled.
+
+* Fill the browser width in side-by-side diff.
++
+Filling the browser available space with each side of the diff at
+50% size allows the user to more easily view long lines if they
+have a wide display, and better fit on more narrow displays by
+splitting the available width at 50%.
ssh
---
@@ -93,6 +144,8 @@
The `replication` command is provided by the replication plugin, so it is no
longer relevant to mention this in the description of a core command.
+* Fix aliasing of SSH commands.
+
Replication Plugin
------------------
@@ -118,6 +171,11 @@
* Update documentation to clarify replication of refs/meta/config when
refspec is 'all refs'.
+Upgrades
+--------
+
+
+* JGit is upgraded to 3.2.0.201312181205-r
Documentation
-------------
diff --git a/contrib/trivial_rebase.py b/contrib/trivial_rebase.py
deleted file mode 100755
index c97172e..0000000
--- a/contrib/trivial_rebase.py
+++ /dev/null
@@ -1,253 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2010, Code Aurora Forum. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# # Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# # Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following
-# disclaimer in the documentation and/or other materials provided
-# with the distribution.
-# # Neither the name of Code Aurora Forum, Inc. nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-""" This script is designed to detect when a patchset uploaded to Gerrit is
-'identical' (determined via git-patch-id) and reapply reviews onto the new
-patchset from the previous patchset.
-
-Get usage and help info by running: ./trivial_rebase.py --help
-Documentation is available here: https://www.codeaurora.org/xwiki/bin/QAEP/Gerrit
-
-"""
-
-from __future__ import print_function
-
-import argparse
-import json
-import re
-import subprocess
-import sys
-
-class TrivialRebase:
- def __init__(self):
- usage = "%(prog)s <required options> [--server-port=PORT]"
- parser = argparse.ArgumentParser(usage=usage)
- parser.add_argument("--change-url", dest="changeUrl", help="Change URL")
- parser.add_argument("--project", help="Project path in Gerrit")
- parser.add_argument("--commit", help="Git commit-ish for this patchset")
- parser.add_argument("--patchset", type=int, help="The patchset number")
- parser.add_argument("--private-key-path", dest="private_key_path",
- help="Full path to Gerrit SSH daemon's private host key")
- parser.add_argument("--server", default='localhost',
- help="Gerrit SSH server [default: %(default)s]")
- parser.add_argument("--server-port", dest="port", default='29418',
- help="Port to connect to Gerrit's SSH daemon "
- "[default: %(default)s]")
- parser.add_argument("--ssh", default="ssh", help="SSH executable")
- parser.add_argument("--ssh-port-flag", dest="ssh_port_flag", default="-p", help="SSH port flag")
-
- args = parser.parse_known_args()[0]
- if None in [args.changeUrl, args.project, args.commit, args.patchset]:
- parser.error("Incomplete arguments")
- try:
- self.changeId = re.search(r'\d+$', args.changeUrl).group()
- except AttributeError:
- parser.error("Invalid changeId")
- self.project = args.project
- self.commit = args.commit
- self.patchset = args.patchset
- self.private_key_path = args.private_key_path
- self.server = args.server
- self.port = args.port
- self.ssh = args.ssh
- self.ssh_port_flag = args.ssh_port_flag
-
- class CheckCallError(OSError):
- """CheckCall() returned non-0."""
- def __init__(self, command, cwd, retcode, stdout, stderr=None):
- OSError.__init__(self, command, cwd, retcode, stdout, stderr)
- self.command = command
- self.cwd = cwd
- self.retcode = retcode
- self.stdout = stdout
- self.stderr = stderr
-
- def CheckCall(self, command, cwd=None):
- """Like subprocess.check_call() but returns stdout.
-
- Works on python 2.4
-
- """
- try:
- process = subprocess.Popen(command, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- std_out, std_err = process.communicate()
- except OSError as e:
- raise self.CheckCallError(command, cwd, e.errno, None)
- if process.returncode:
- raise self.CheckCallError(command, cwd, process.returncode, std_out, std_err)
- return std_out, std_err
-
- def GsqlQuery(self, sql_query):
- """Run a gerrit gsql query and return the result."""
- gsql_cmd = [self.ssh, self.ssh_port_flag, self.port, self.server, 'gerrit', 'gsql',
- '--format', 'JSON', '-c', sql_query]
- try:
- (gsql_out, _gsql_stderr) = self.CheckCall(gsql_cmd)
- except self.CheckCallError as e:
- print("return code is %s" % e.retcode)
- print("stdout and stderr is\n%s%s" % (e.stdout, e.stderr))
- raise
-
- new_out = gsql_out.replace('}}\n', '}}\nsplit here\n')
- return new_out.split('split here\n')
-
- def FindPrevRev(self):
- """Find the revision of the previous patch set on the change."""
- sql_query = ("\"SELECT revision FROM patch_sets WHERE "
- "change_id = %s AND patch_set_id = %s\"" %
- (self.changeId, (self.patchset - 1)))
- revisions = self.GsqlQuery(sql_query)
-
- json_dict = json.loads(revisions[0], strict=False)
- return json_dict["columns"]["revision"]
-
- def GetApprovals(self):
- """Get all the approvals on a specific patch set.
-
- Returns a list of approval dicts.
-
- """
- sql_query = ("\"SELECT value,account_id,category_id AS label FROM patch_set_approvals "
- "WHERE change_id = %s AND patch_set_id = %s AND value != 0\""
- % (self.changeId, (self.patchset - 1)))
- gsql_out = self.GsqlQuery(sql_query)
- approvals = []
- for json_str in gsql_out:
- data = json.loads(json_str, strict=False)
- if data["type"] == "row":
- approvals.append(data["columns"])
- return approvals
-
- def AppendAcctApproval(self, account_id, value):
- try:
- newval = self.acct_approvals[account_id] + ' ' + value
- except KeyError:
- newval = value
- self.acct_approvals[account_id] = newval
-
- def GetEmailFromAcctId(self, account_id):
- """Return the preferred email address associated with the account_id."""
- sql_query = ("\"SELECT preferred_email FROM accounts WHERE account_id = %s\""
- % account_id)
- email_addr = self.GsqlQuery(sql_query)
-
- json_dict = json.loads(email_addr[0], strict=False)
- return json_dict["columns"]["preferred_email"]
-
- def GetPatchId(self, revision):
- git_show_cmd = ['git', 'show', revision]
- patch_id_cmd = ['git', 'patch-id']
- git_show_process = subprocess.Popen(git_show_cmd, stdout=subprocess.PIPE)
- patch_id_process = subprocess.Popen(patch_id_cmd, stdout=subprocess.PIPE,
- stdin=git_show_process.stdout)
- res = patch_id_process.communicate()[0] or '0'
- return res.split()[0]
-
- def SuExec(self, as_user, cmd):
- suexec_cmd = [self.ssh, '-l', "Gerrit Code Review", self.ssh_port_flag, self.port, self.server]
- if self.private_key_path:
- suexec_cmd += ['-i', self.private_key_path]
- suexec_cmd += ['suexec', '--as', as_user, '--', cmd]
- self.CheckCall(suexec_cmd)
-
- def DiffCommitMessages(self, prev_commit):
- log_cmd1 = ['git', 'log', '--pretty=format:"%an %ae%n%s%n%b"',
- prev_commit + '^!']
- commit1_log = self.CheckCall(log_cmd1)
- log_cmd2 = ['git', 'log', '--pretty=format:"%an %ae%n%s%n%b"',
- self.commit + '^!']
- commit2_log = self.CheckCall(log_cmd2)
- if commit1_log != commit2_log:
- return True
- return False
-
- def Run(self):
- if self.patchset == 1:
- # Nothing to detect on first patchset
- return
- prev_revision = self.FindPrevRev()
- assert prev_revision, "Previous revision not found"
- prev_patch_id = self.GetPatchId(prev_revision)
- cur_patch_id = self.GetPatchId(self.commit)
- if prev_patch_id == '0' and cur_patch_id == '0':
- print("commits %s and %s are both empty or merge commits" % (prev_revision, self.commit))
- return
- if cur_patch_id != prev_patch_id:
- # patch-ids don't match
- return
- # Patch ids match. This is a trivial rebase.
- # In addition to patch-id we should check if the commit message changed. Most
- # approvers would want to re-review changes when the commit message changes.
- changed = self.DiffCommitMessages(prev_revision)
- if changed:
- # Insert a comment into the change letting the approvers know only the
- # commit message changed
- comment_msg = ("\'--message=New patchset patch-id matches previous patchset"
- ", but commit message has changed.'")
- comment_cmd = [self.ssh, self.ssh_port_flag, self.port, self.server, 'gerrit',
- 'review', '--project', self.project, comment_msg, self.commit]
- self.CheckCall(comment_cmd)
- return
-
- # Need to get all approvals on prior patch set, then suexec them onto
- # this patchset.
- approvals = self.GetApprovals()
- self.acct_approvals = dict()
- for approval in approvals:
- # Note: Sites with different 'copy_min_score' values in the
- # approval_categories DB table might want different behavior here.
- # Additional categories should also be added if desired.
- if approval["label"] == "Code-Review":
- if approval['value'] != '-2':
- self.AppendAcctApproval(approval['account_id'],
- '--label Code-Review=%s' % approval['value'])
- elif approval["label"] == "Verified":
- # Don't re-add verifies
- # self.AppendAcctApproval(approval['account_id'], '--label Verified=%s' % approval['value'])
- continue
- elif approval["label"] == "SUBM":
- # We don't care about previous submit attempts
- continue
- else:
- self.AppendAcctApproval(approval['account_id'], '--label %s=%s' %
- (approval['label'], approval['value']))
-
- gerrit_review_msg = ("\'Automatically re-added by Gerrit trivial rebase "
- "detection script.\'")
- for acct, flags in list(self.acct_approvals.items()):
- gerrit_review_cmd = ['gerrit', 'review', '--project', self.project,
- '--message', gerrit_review_msg, flags, self.commit]
- email_addr = self.GetEmailFromAcctId(acct)
- self.SuExec(email_addr, ' '.join(gerrit_review_cmd))
-
-if __name__ == "__main__":
- try:
- TrivialRebase().Run()
- except AssertionError as e:
- print(e, file=sys.stderr)
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/AbstractDaemonTest.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
index 66e00b7..14571cd 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
@@ -14,18 +14,31 @@
package com.google.gerrit.acceptance;
+import static com.google.gerrit.acceptance.GitUtil.cloneProject;
+import static com.google.gerrit.acceptance.GitUtil.createProject;
import static com.google.gerrit.acceptance.GitUtil.initSsh;
import static org.junit.Assert.assertEquals;
import com.google.common.base.Joiner;
+import com.google.common.primitives.Chars;
+import com.google.gerrit.extensions.api.GerritApi;
+import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.ListChangesOption;
+import com.google.gerrit.extensions.restapi.RestApiException;
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.OutputFormat;
-import com.google.gerrit.server.change.ChangeJson.ChangeInfo;
+import com.google.gerrit.server.change.ChangeJson;
import com.google.gerrit.testutil.ConfigSuite;
import com.google.gson.Gson;
+import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
+import com.google.inject.util.Providers;
import org.apache.http.HttpStatus;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Config;
import org.junit.Rule;
import org.junit.rules.TestRule;
@@ -34,6 +47,10 @@
import org.junit.runners.model.Statement;
import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.List;
@RunWith(ConfigSuite.class)
public abstract class AbstractDaemonTest {
@@ -43,9 +60,30 @@
@Inject
protected AccountCreator accounts;
+ @Inject
+ private SchemaFactory<ReviewDb> reviewDbProvider;
+
+ @Inject
+ protected GerritApi gApi;
+
+ @Inject
+ private AcceptanceTestRequestScope atrScope;
+
+ @Inject
+ private IdentifiedUser.GenericFactory identifiedUserFactory;
+
+ @Inject
+ protected PushOneCommit.Factory pushFactory;
+
+ protected Git git;
protected GerritServer server;
protected TestAccount admin;
+ protected TestAccount user;
protected RestSession adminSession;
+ protected RestSession userSession;
+ protected SshSession sshSession;
+ protected ReviewDb db;
+ protected Project.NameKey project;
@Rule
public TestRule testRunner = new TestRule() {
@@ -55,7 +93,9 @@
@Override
public void evaluate() throws Throwable {
boolean mem = description.getAnnotation(UseLocalDisk.class) == null;
- beforeTest(config(description), mem);
+ boolean enableHttpd = description.getAnnotation(NoHttpd.class) == null
+ && description.getTestClass().getAnnotation(NoHttpd.class) == null;
+ beforeTest(config(description), mem, enableHttpd);
base.evaluate();
afterTest();
}
@@ -78,33 +118,79 @@
}
}
- private void beforeTest(Config cfg, boolean memory) throws Exception {
- server = startServer(cfg, memory);
+ private void beforeTest(Config cfg, boolean memory, boolean enableHttpd) throws Exception {
+ server = startServer(cfg, memory, enableHttpd);
server.getTestInjector().injectMembers(this);
admin = accounts.admin();
+ user = accounts.user();
adminSession = new RestSession(server, admin);
+ userSession = new RestSession(server, user);
initSsh(admin);
+ db = reviewDbProvider.open();
+ atrScope.set(atrScope.newContext(reviewDbProvider, sshSession,
+ identifiedUserFactory.create(Providers.of(db), admin.getId())));
+ sshSession = new SshSession(server, admin);
+ project = new Project.NameKey("p");
+ createProject(sshSession, project.get());
+ git = cloneProject(sshSession.getUrl() + "/" + project.get());
}
- protected GerritServer startServer(Config cfg, boolean memory) throws Exception {
- return GerritServer.start(cfg, memory);
+ protected GerritServer startServer(Config cfg, boolean memory,
+ boolean enableHttpd) throws Exception {
+ return GerritServer.start(cfg, memory, enableHttpd);
}
private void afterTest() throws Exception {
+ db.close();
+ sshSession.close();
server.stop();
}
- protected ChangeInfo getChange(String changeId, ListChangesOption... options)
+ protected PushOneCommit.Result createChange() throws GitAPIException,
+ IOException {
+ PushOneCommit push = pushFactory.create(db, admin.getIdent());
+ return push.to(git, "refs/for/master");
+ }
+
+ private static final List<Character> RANDOM =
+ Chars.asList(new char[]{'a','b','c','d','e','f','g','h'});
+ protected PushOneCommit.Result ammendChange(String changeId)
+ throws GitAPIException, IOException {
+ Collections.shuffle(RANDOM);
+ PushOneCommit push =
+ pushFactory.create(db, admin.getIdent(), PushOneCommit.SUBJECT,
+ PushOneCommit.FILE_NAME, new String(Chars.toArray(RANDOM)), changeId);
+ return push.to(git, "refs/for/master");
+ }
+
+ protected ChangeJson.ChangeInfo getChange(String changeId, ListChangesOption... options)
throws IOException {
return getChange(adminSession, changeId, options);
}
- protected ChangeInfo getChange(RestSession session, String changeId,
+ protected ChangeJson.ChangeInfo getChange(RestSession session, String changeId,
ListChangesOption... options) throws IOException {
String q = options.length > 0 ? "?o=" + Joiner.on("&o=").join(options) : "";
RestResponse r = session.get("/changes/" + changeId + q);
assertEquals(HttpStatus.SC_OK, r.getStatusCode());
- return newGson().fromJson(r.getReader(), ChangeInfo.class);
+ return newGson().fromJson(r.getReader(), ChangeJson.ChangeInfo.class);
+ }
+
+ protected ChangeInfo info(String id)
+ throws RestApiException {
+ return gApi.changes().id(id).info();
+ }
+
+ protected ChangeInfo get(String id)
+ throws RestApiException {
+ return gApi.changes().id(id).get();
+ }
+
+ protected ChangeInfo get(String id, ListChangesOption... options)
+ throws RestApiException {
+ EnumSet<ListChangesOption> s = EnumSet.noneOf(ListChangesOption.class);
+ s.addAll(Arrays.asList(options));
+ return gApi.changes().id(id).get(s);
}
protected static Gson newGson() {
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/GerritServer.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/GerritServer.java
index 272b5ab..a8ce229 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/GerritServer.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/GerritServer.java
@@ -49,7 +49,8 @@
public class GerritServer {
/** Returns fully started Gerrit server */
- static GerritServer start(Config cfg, boolean memory) throws Exception {
+ static GerritServer start(Config cfg, boolean memory, boolean enableHttpd)
+ throws Exception {
final CyclicBarrier serverStarted = new CyclicBarrier(2);
final Daemon daemon = new Daemon(new Runnable() {
public void run() {
@@ -71,6 +72,7 @@
cfg.setBoolean("httpd", null, "requestLog", false);
cfg.setBoolean("sshd", null, "requestLog", false);
cfg.setBoolean("index", "lucene", "testInmemory", true);
+ daemon.setEnableHttpd(enableHttpd);
daemon.setLuceneModule(new LuceneIndexModule(
ChangeSchemas.getLatest().getVersion(),
Runtime.getRuntime().availableProcessors(), null));
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/NoHttpd.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/NoHttpd.java
new file mode 100644
index 0000000..378439c
--- /dev/null
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/NoHttpd.java
@@ -0,0 +1,27 @@
+// Copyright (C) 2014 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;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Target({TYPE, METHOD})
+@Retention(RUNTIME)
+public @interface NoHttpd {
+}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/PushOneCommit.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/PushOneCommit.java
index 9aed646..cc19c15 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/PushOneCommit.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/PushOneCommit.java
@@ -56,8 +56,7 @@
public class PushOneCommit {
public static final String SUBJECT = "test commit";
-
- private static final String FILE_NAME = "a.txt";
+ static final String FILE_NAME = "a.txt";
private static final String FILE_CONTENT = "some content";
public interface Factory {
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 ec0f72e..6dff20a 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
@@ -14,87 +14,32 @@
package com.google.gerrit.acceptance.api.change;
-import static com.google.gerrit.acceptance.GitUtil.cloneProject;
-import static com.google.gerrit.acceptance.GitUtil.createProject;
import static org.junit.Assert.assertEquals;
import com.google.gerrit.acceptance.AbstractDaemonTest;
-import com.google.gerrit.acceptance.AcceptanceTestRequestScope;
+import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
-import com.google.gerrit.acceptance.SshSession;
-import com.google.gerrit.acceptance.TestAccount;
-import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.extensions.api.changes.AddReviewerInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.ChangeStatus;
-import com.google.gerrit.extensions.common.ListChangesOption;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gwtorm.server.SchemaFactory;
-import com.google.inject.Inject;
-import com.google.inject.util.Providers;
-import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
-import java.util.EnumSet;
+@NoHttpd
public class ChangeIT extends AbstractDaemonTest {
- @Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
- @Inject
- private GerritApi gApi;
-
- @Inject
- private AcceptanceTestRequestScope atrScope;
-
- @Inject
- private IdentifiedUser.GenericFactory identifiedUserFactory;
-
- @Inject
- private PushOneCommit.Factory pushFactory;
-
- private TestAccount user;
-
- private Git git;
- private ReviewDb db;
-
- @Before
- public void setUp() throws Exception {
- user = accounts.user();
- Project.NameKey project = new Project.NameKey("p");
- SshSession sshSession = new SshSession(server, admin);
- createProject(sshSession, project.get());
- git = cloneProject(sshSession.getUrl() + "/" + project.get());
- db = reviewDbProvider.open();
- atrScope.set(atrScope.newContext(reviewDbProvider, sshSession,
- identifiedUserFactory.create(Providers.of(db), admin.getId())));
- }
-
- @After
- public void cleanup() {
- db.close();
- }
-
@Test
public void get() throws GitAPIException,
IOException, RestApiException {
PushOneCommit.Result r = createChange();
String triplet = "p~master~" + r.getChangeId();
- ChangeInfo c =
- gApi.changes()
- .id(triplet)
- .get(EnumSet.noneOf(ListChangesOption.class));
+ ChangeInfo c = info(triplet);
assertEquals(triplet, c.id);
assertEquals("p", c.project);
assertEquals("master", c.branch);
@@ -164,10 +109,4 @@
.id("p~master~" + r.getChangeId())
.addReviewer(in);
}
-
- private PushOneCommit.Result createChange() throws GitAPIException,
- IOException {
- PushOneCommit push = pushFactory.create(db, admin.getIdent());
- return push.to(git, "refs/for/master");
- }
}
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 93b275f..54afd0b 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
@@ -14,60 +14,19 @@
package com.google.gerrit.acceptance.api.project;
-import static com.google.gerrit.acceptance.GitUtil.createProject;
-
import com.google.gerrit.acceptance.AbstractDaemonTest;
-import com.google.gerrit.acceptance.AcceptanceTestRequestScope;
-import com.google.gerrit.acceptance.SshSession;
-import com.google.gerrit.extensions.api.GerritApi;
+import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.extensions.api.projects.BranchInput;
import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gwtorm.server.SchemaFactory;
-import com.google.inject.Inject;
-import com.google.inject.util.Providers;
import org.eclipse.jgit.api.errors.GitAPIException;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
+@NoHttpd
public class ProjectIT extends AbstractDaemonTest {
- @Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
- @Inject
- private GerritApi gApi;
-
- @Inject
- private AcceptanceTestRequestScope atrScope;
-
- @Inject
- private IdentifiedUser.GenericFactory identifiedUserFactory;
-
- private ReviewDb db;
- Project.NameKey project;
-
- @Before
- public void setUp() throws Exception {
- project = new Project.NameKey("p");
- SshSession sshSession = new SshSession(server, admin);
- createProject(sshSession, project.get());
- db = reviewDbProvider.open();
- atrScope.set(atrScope.newContext(reviewDbProvider, sshSession,
- identifiedUserFactory.create(Providers.of(db), admin.getId())));
- }
-
- @After
- public void cleanup() {
- db.close();
- }
-
@Test
public void createBranch() throws GitAPIException,
IOException, RestApiException {
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java
index 02959f1d..72b7ff1 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RevisionIT.java
@@ -14,71 +14,23 @@
package com.google.gerrit.acceptance.api.revision;
-import static com.google.gerrit.acceptance.GitUtil.cloneProject;
-import static com.google.gerrit.acceptance.GitUtil.createProject;
-
import com.google.gerrit.acceptance.AbstractDaemonTest;
-import com.google.gerrit.acceptance.AcceptanceTestRequestScope;
+import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
-import com.google.gerrit.acceptance.SshSession;
-import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.extensions.api.changes.ChangeApi;
import com.google.gerrit.extensions.api.changes.CherryPickInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.projects.BranchInput;
import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gwtorm.server.SchemaFactory;
-import com.google.inject.Inject;
-import com.google.inject.util.Providers;
-import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
+@NoHttpd
public class RevisionIT extends AbstractDaemonTest {
- @Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
- @Inject
- private GerritApi gApi;
-
- @Inject
- private AcceptanceTestRequestScope atrScope;
-
- @Inject
- private IdentifiedUser.GenericFactory identifiedUserFactory;
-
- @Inject
- private PushOneCommit.Factory pushFactory;
-
- private Git git;
- private ReviewDb db;
- private Project.NameKey project;
-
- @Before
- public void setUp() throws Exception {
- project = new Project.NameKey("p");
- SshSession sshSession = new SshSession(server, admin);
- createProject(sshSession, project.get());
- git = cloneProject(sshSession.getUrl() + "/" + project.get());
- db = reviewDbProvider.open();
- atrScope.set(atrScope.newContext(reviewDbProvider, sshSession,
- identifiedUserFactory.create(Providers.of(db), admin.getId())));
- }
-
- @After
- public void cleanup() {
- db.close();
- }
-
@Test
public void reviewTriplet() throws GitAPIException,
IOException, RestApiException {
@@ -160,13 +112,6 @@
.submit();
}
- private PushOneCommit.Result createChange() throws GitAPIException,
- IOException {
- PushOneCommit push = pushFactory.create(db, admin.getIdent(),
- "test commit", "a.txt", "some content");
- return push.to(git, "refs/for/master");
- }
-
private PushOneCommit.Result updateChange(PushOneCommit.Result r,
String content) throws GitAPIException, IOException {
PushOneCommit push = pushFactory.create(db, admin.getIdent(),
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
index 203735f..5a8ba0c 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/AbstractPushForReview.java
@@ -15,24 +15,16 @@
package com.google.gerrit.acceptance.git;
import static com.google.gerrit.acceptance.GitUtil.cloneProject;
-import static com.google.gerrit.acceptance.GitUtil.createProject;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
-import com.google.gerrit.acceptance.SshSession;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gwtorm.server.OrmException;
-import com.google.gwtorm.server.SchemaFactory;
-import com.google.inject.Inject;
import com.jcraft.jsch.JSchException;
-import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -43,26 +35,11 @@
SSH, HTTP
}
- @Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
- @Inject
- protected PushOneCommit.Factory pushFactory;
-
- private Project.NameKey project;
- private Git git;
- private ReviewDb db;
private String sshUrl;
@Before
public void setUp() throws Exception {
- project = new Project.NameKey("p");
- SshSession sshSession = new SshSession(server, admin);
- createProject(sshSession, project.get());
sshUrl = sshSession.getUrl();
- sshSession.close();
-
- db = reviewDbProvider.open();
}
protected void selectProtocol(Protocol p) throws GitAPIException, IOException {
@@ -80,11 +57,6 @@
git = cloneProject(url + "/" + project.get());
}
- @After
- public void cleanup() {
- db.close();
- }
-
@Test
public void testPushForMaster() throws GitAPIException, OrmException,
IOException {
@@ -112,7 +84,6 @@
public void testPushForMasterWithCc() throws GitAPIException, OrmException,
IOException, JSchException {
// cc one user
- TestAccount user = accounts.create("user", "user@example.com", "User");
String topic = "my/topic";
PushOneCommit.Result r = pushTo("refs/for/master/" + topic + "%cc=" + user.email);
r.assertOkStatus();
@@ -137,7 +108,6 @@
public void testPushForMasterWithReviewer() throws GitAPIException,
OrmException, IOException, JSchException {
// add one reviewer
- TestAccount user = accounts.create("user", "user@example.com", "User");
String topic = "my/topic";
PushOneCommit.Result r = pushTo("refs/for/master/" + topic + "%r=" + user.email);
r.assertOkStatus();
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/DraftChangeBlockedIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/DraftChangeBlockedIT.java
index a428ee3..b69c264 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/DraftChangeBlockedIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/DraftChangeBlockedIT.java
@@ -14,38 +14,30 @@
package com.google.gerrit.acceptance.git;
-import static com.google.gerrit.acceptance.GitUtil.cloneProject;
-import static com.google.gerrit.acceptance.GitUtil.createProject;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
import static com.google.gerrit.server.project.Util.grant;
import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
-import com.google.gerrit.acceptance.SshSession;
import com.google.gerrit.common.data.Permission;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gwtorm.server.OrmException;
-import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
-import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
+@NoHttpd
public class DraftChangeBlockedIT extends AbstractDaemonTest {
@Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
- @Inject
private ProjectCache projectCache;
@Inject
@@ -54,27 +46,13 @@
@Inject
private MetaDataUpdate.Server metaDataUpdateFactory;
- @Inject
- private PushOneCommit.Factory pushFactory;
-
- private Project.NameKey project;
- private Git git;
- private ReviewDb db;
-
@Before
public void setUp() throws Exception {
ProjectConfig cfg = projectCache.checkedGet(allProjects).getConfig();
grant(cfg, Permission.PUSH, ANONYMOUS_USERS,
"refs/drafts/*").setBlock();
saveProjectConfig(cfg);
-
- project = new Project.NameKey("p");
- SshSession sshSession = new SshSession(server, admin);
- createProject(sshSession, project.get());
-
- db = reviewDbProvider.open();
- git = cloneProject(sshSession.getUrl() + "/" + project.get());
- sshSession.close();
+ projectCache.evict(cfg.getProject());
}
@Test
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SshPushForReviewIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SshPushForReviewIT.java
index 5251d2d..c037e76 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SshPushForReviewIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SshPushForReviewIT.java
@@ -14,11 +14,14 @@
package com.google.gerrit.acceptance.git;
+import com.google.gerrit.acceptance.NoHttpd;
+
import org.eclipse.jgit.api.errors.GitAPIException;
import org.junit.Before;
import java.io.IOException;
+@NoHttpd
public class SshPushForReviewIT extends AbstractPushForReview {
@Before
public void selectSshUrl() throws GitAPIException, IOException {
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmitOnPushIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmitOnPushIT.java
index f350909..a73169d 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmitOnPushIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/SubmitOnPushIT.java
@@ -22,6 +22,7 @@
import com.google.common.collect.Iterables;
import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.SshSession;
import com.google.gerrit.common.data.AccessSection;
@@ -62,6 +63,7 @@
import java.io.IOException;
+@NoHttpd
public class SubmitOnPushIT extends AbstractDaemonTest {
@Inject
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/account/CapabilitiesIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/account/CapabilitiesIT.java
index 4175550..9d22ee4 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/account/CapabilitiesIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/account/CapabilitiesIT.java
@@ -21,7 +21,6 @@
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
-import com.google.gerrit.acceptance.RestSession;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.common.data.Permission;
@@ -36,7 +35,6 @@
import com.google.inject.Inject;
import org.eclipse.jgit.errors.ConfigInvalidException;
-import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
@@ -52,13 +50,6 @@
@Inject
private ProjectCache projectCache;
- private RestSession userSession;
-
- @Before
- public void setUp() throws Exception {
- userSession = new RestSession(server, accounts.user());
- }
-
@Test
public void testCapabilitiesUser() throws IOException,
ConfigInvalidException, IllegalArgumentException,
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/account/StarredChangesIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/account/StarredChangesIT.java
index 605dd21..9470df0 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/account/StarredChangesIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/account/StarredChangesIT.java
@@ -14,58 +14,23 @@
package com.google.gerrit.acceptance.rest.account;
-import static com.google.gerrit.acceptance.GitUtil.cloneProject;
-import static com.google.gerrit.acceptance.GitUtil.createProject;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import com.google.gerrit.acceptance.AbstractDaemonTest;
-import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.PushOneCommit.Result;
import com.google.gerrit.acceptance.RestResponse;
-import com.google.gerrit.acceptance.SshSession;
import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gwtorm.server.OrmException;
-import com.google.gwtorm.server.SchemaFactory;
-import com.google.inject.Inject;
-import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
public class StarredChangesIT extends AbstractDaemonTest {
- @Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
- @Inject
- private PushOneCommit.Factory pushFactory;
-
- private Git git;
- private ReviewDb db;
-
- @Before
- public void setUp() throws Exception {
- Project.NameKey project = new Project.NameKey("p");
- SshSession sshSession = new SshSession(server, admin);
- createProject(sshSession, project.get());
- git = cloneProject(sshSession.getUrl() + "/" + project.get());
- sshSession.close();
- db = reviewDbProvider.open();
- }
-
- @After
- public void cleanup() {
- db.close();
- }
-
@Test
public void starredChangeState() throws GitAPIException, IOException,
OrmException {
@@ -93,9 +58,4 @@
assertEquals(204, r.getStatusCode());
}
}
-
- private Result createChange() throws GitAPIException, IOException {
- PushOneCommit push = pushFactory.create(db, admin.getIdent());
- return push.to(git, "refs/for/master");
- }
}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
index 1ec6a8e..797a20e 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
@@ -36,7 +36,6 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.Project.InheritableBoolean;
import com.google.gerrit.reviewdb.client.Project.SubmitType;
-import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.change.ChangeJson.ChangeInfo;
import com.google.gerrit.server.change.ChangeJson.LabelInfo;
@@ -45,7 +44,6 @@
import com.google.gerrit.server.project.PutConfig;
import com.google.gson.reflect.TypeToken;
import com.google.gwtorm.server.OrmException;
-import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
import com.jcraft.jsch.JSchException;
@@ -68,9 +66,6 @@
public abstract class AbstractSubmit extends AbstractDaemonTest {
@Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
- @Inject
private GitRepositoryManager repoManager;
@Inject
@@ -79,16 +74,10 @@
@Inject
private ApprovalsUtil approvalsUtil;
- @Inject
- protected PushOneCommit.Factory pushFactory;
-
- private Project.NameKey project;
- private ReviewDb db;
@Before
public void setUp() throws Exception {
- project = new Project.NameKey("p");
- db = reviewDbProvider.open();
+ project = new Project.NameKey("p2");
}
@After
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ChangeMessagesIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ChangeMessagesIT.java
index fff1d1d..6352b50 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ChangeMessagesIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ChangeMessagesIT.java
@@ -14,106 +14,50 @@
package com.google.gerrit.acceptance.rest.change;
-import static com.google.gerrit.acceptance.GitUtil.cloneProject;
-import static com.google.gerrit.acceptance.GitUtil.createProject;
-import static com.google.gerrit.extensions.common.ListChangesOption.MESSAGES;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import com.google.gerrit.acceptance.AbstractDaemonTest;
-import com.google.gerrit.acceptance.AcceptanceTestRequestScope;
-import com.google.gerrit.acceptance.PushOneCommit;
-import com.google.gerrit.acceptance.SshSession;
-import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.ChangeMessageInfo;
-import com.google.gerrit.extensions.common.ListChangesOption;
import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gwtorm.server.SchemaFactory;
-import com.google.inject.Inject;
-import com.google.inject.util.Providers;
-import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
-import java.util.EnumSet;
import java.util.Iterator;
public class ChangeMessagesIT extends AbstractDaemonTest {
- @Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
- @Inject
- private GerritApi gApi;
-
- @Inject
- private AcceptanceTestRequestScope atrScope;
-
- @Inject
- private IdentifiedUser.GenericFactory identifiedUserFactory;
-
- @Inject
- private PushOneCommit.Factory pushFactory;
-
- private Git git;
- private ReviewDb db;
-
- @Before
- public void setUp() throws Exception {
- Project.NameKey project = new Project.NameKey("p");
- SshSession sshSession = new SshSession(server, admin);
- createProject(sshSession, project.get());
- git = cloneProject(sshSession.getUrl() + "/" + project.get());
- sshSession.close();
- db = reviewDbProvider.open();
- atrScope.set(atrScope.newContext(reviewDbProvider, sshSession,
- identifiedUserFactory.create(Providers.of(db), admin.getId())));
- }
-
- @After
- public void cleanup() {
- db.close();
- }
-
@Test
- public void messagesNotReturnedByDefault() throws GitAPIException,
- IOException, RestApiException {
- String changeId = createChange();
+ public void messagesNotReturnedByDefault() throws Exception {
+ String changeId = createChange().getChangeId();
postMessage(changeId, "Some nits need to be fixed.");
- ChangeInfo c = getChange("p~master~" + changeId,
- EnumSet.noneOf(ListChangesOption.class));
+ ChangeInfo c = info(changeId);
assertNull(c.messages);
}
@Test
public void defaultMessage() throws GitAPIException, IOException,
RestApiException {
- String changeId = createChange();
- ChangeInfo c = getChange("p~master~" + changeId, EnumSet.of(MESSAGES));
+ String changeId = createChange().getChangeId();
+ ChangeInfo c = get(changeId);
assertNotNull(c.messages);
assertEquals(1, c.messages.size());
assertEquals("Uploaded patch set 1.", c.messages.iterator().next().message);
}
@Test
- public void messagesReturnedInChronologicalOrder() throws GitAPIException,
- IOException, RestApiException {
- String changeId = createChange();
+ public void messagesReturnedInChronologicalOrder() throws Exception {
+ String changeId = createChange().getChangeId();
String firstMessage = "Some nits need to be fixed.";
postMessage(changeId, firstMessage);
String secondMessage = "I like this feature.";
postMessage(changeId, secondMessage);
- ChangeInfo c = getChange("p~master~" + changeId, EnumSet.of(MESSAGES));
+ ChangeInfo c = get(changeId);
assertNotNull(c.messages);
assertEquals(3, c.messages.size());
Iterator<ChangeMessageInfo> it = c.messages.iterator();
@@ -122,25 +66,13 @@
assertMessage(secondMessage, it.next().message);
}
- private String createChange() throws GitAPIException,
- IOException {
- PushOneCommit push = pushFactory.create(db, admin.getIdent());
- return push.to(git, "refs/for/master").getChangeId();
- }
-
private void assertMessage(String expected, String actual) {
assertEquals("Patch Set 1:\n\n" + expected, actual);
}
- private void postMessage(String changeId, String msg) throws IOException {
+ private void postMessage(String changeId, String msg) throws Exception {
ReviewInput in = new ReviewInput();
in.message = msg;
- adminSession.post("/changes/" + changeId + "/revisions/1/review", in)
- .consume();
- }
-
- private ChangeInfo getChange(String triplet, EnumSet<ListChangesOption> s)
- throws RestApiException {
- return gApi.changes().id(triplet).get(s);
+ gApi.changes().id(changeId).current().review(in);
}
}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ChangeOwnerIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ChangeOwnerIT.java
index ee86e11..83efd30 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ChangeOwnerIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ChangeOwnerIT.java
@@ -30,91 +30,65 @@
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.extensions.api.changes.ReviewInput;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gwtorm.server.OrmException;
-import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
-import com.jcraft.jsch.JSchException;
-
import org.apache.http.HttpStatus;
-import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.ConfigInvalidException;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
public class ChangeOwnerIT extends AbstractDaemonTest {
@Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
- @Inject
private MetaDataUpdate.Server metaDataUpdateFactory;
@Inject
private ProjectCache projectCache;
- @Inject
- private PushOneCommit.Factory pushFactory;
-
- private TestAccount owner;
- private TestAccount dev;
+ private TestAccount user2;
private RestSession sessionOwner;
private RestSession sessionDev;
- private Git git;
- private ReviewDb db;
- private Project.NameKey project;
@Before
public void setUp() throws Exception {
- newProject();
- owner = accounts.user();
- sessionOwner = new RestSession(server, owner);
- SshSession sshSession = new SshSession(server, owner);
- initSsh(owner);
+ sessionOwner = new RestSession(server, user);
+ SshSession sshSession = new SshSession(server, user);
+ initSsh(user);
// need to initialize intern session
createProject(sshSession, "foo");
git = cloneProject(sshSession.getUrl() + "/" + project.get());
sshSession.close();
- dev = accounts.user2();
- sessionDev = new RestSession(server, dev);
- db = reviewDbProvider.open();
- }
-
- @After
- public void cleanup() {
- db.close();
+ user2 = accounts.user2();
+ sessionDev = new RestSession(server, user2);
}
@Test
public void testChangeOwner_OwnerACLNotGranted() throws GitAPIException,
IOException, OrmException, ConfigInvalidException {
- approve(sessionOwner, createChange(), HttpStatus.SC_FORBIDDEN);
+ approve(sessionOwner, createMyChange(), HttpStatus.SC_FORBIDDEN);
}
@Test
public void testChangeOwner_OwnerACLGranted() throws GitAPIException,
IOException, OrmException, ConfigInvalidException {
grantApproveToChangeOwner();
- approve(sessionOwner, createChange(), HttpStatus.SC_OK);
+ approve(sessionOwner, createMyChange(), HttpStatus.SC_OK);
}
@Test
public void testChangeOwner_NotOwnerACLGranted() throws GitAPIException,
IOException, OrmException, ConfigInvalidException {
grantApproveToChangeOwner();
- approve(sessionDev, createChange(), HttpStatus.SC_FORBIDDEN);
+ approve(sessionDev, createMyChange(), HttpStatus.SC_FORBIDDEN);
}
private void approve(RestSession s, String changeId, int expected)
@@ -142,17 +116,9 @@
projectCache.evict(config.getProject());
}
- private String createChange() throws GitAPIException,
+ private String createMyChange() throws GitAPIException,
IOException {
- PushOneCommit push = pushFactory.create(db, owner.getIdent());
+ PushOneCommit push = pushFactory.create(db, user.getIdent());
return push.to(git, "refs/for/master").getChangeId();
}
-
- private void newProject() throws UnsupportedEncodingException,
- OrmException, JSchException, IOException {
- project = new Project.NameKey("p");
- SshSession sshSession = new SshSession(server, admin);
- createProject(sshSession, project.get());
- sshSession.close();
- }
}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ConflictsOperatorIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ConflictsOperatorIT.java
index c8d8caf..3370cb6 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ConflictsOperatorIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ConflictsOperatorIT.java
@@ -15,7 +15,6 @@
package com.google.gerrit.acceptance.rest.change;
import static com.google.gerrit.acceptance.GitUtil.checkout;
-import static com.google.gerrit.acceptance.GitUtil.cloneProject;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -23,23 +22,16 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.gerrit.acceptance.AbstractDaemonTest;
-import com.google.gerrit.acceptance.GitUtil;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.RestResponse;
-import com.google.gerrit.acceptance.SshSession;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.change.ChangeJson.ChangeInfo;
import com.google.gson.reflect.TypeToken;
-import com.google.gwtorm.server.SchemaFactory;
-import com.google.inject.Inject;
import com.jcraft.jsch.JSchException;
import org.apache.http.HttpStatus;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
-import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
@@ -47,27 +39,11 @@
public class ConflictsOperatorIT extends AbstractDaemonTest {
- @Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
- @Inject
- private PushOneCommit.Factory pushFactory;
-
- private Project.NameKey project;
- private ReviewDb db;
private int count;
- @Before
- public void setUp() throws Exception {
- project = new Project.NameKey("p");
-
- db = reviewDbProvider.open();
- }
-
@Test
public void noConflictingChanges() throws JSchException, IOException,
GitAPIException {
- Git git = createProject();
PushOneCommit.Result change = createChange(git, true);
createChange(git, false);
@@ -78,7 +54,6 @@
@Test
public void conflictingChanges() throws JSchException, IOException,
GitAPIException {
- Git git = createProject();
PushOneCommit.Result change = createChange(git, true);
PushOneCommit.Result conflictingChange1 = createChange(git, true);
PushOneCommit.Result conflictingChange2 = createChange(git, true);
@@ -88,17 +63,6 @@
assertChanges(changes, conflictingChange1, conflictingChange2);
}
- private Git createProject() throws JSchException, IOException,
- GitAPIException {
- SshSession sshSession = new SshSession(server, admin);
- try {
- GitUtil.createProject(sshSession, project.get(), null, true);
- return cloneProject(sshSession.getUrl() + "/" + project.get());
- } finally {
- sshSession.close();
- }
- }
-
private PushOneCommit.Result createChange(Git git, boolean conflicting)
throws GitAPIException, IOException {
checkout(git, "origin/master");
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/DeleteDraftChangeIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/DeleteDraftChangeIT.java
index de7c263..3ba5ed7 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/DeleteDraftChangeIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/DeleteDraftChangeIT.java
@@ -14,8 +14,6 @@
package com.google.gerrit.acceptance.rest.change;
-import static com.google.gerrit.acceptance.GitUtil.cloneProject;
-import static com.google.gerrit.acceptance.GitUtil.createProject;
import static org.junit.Assert.assertEquals;
import com.google.common.collect.Iterables;
@@ -23,57 +21,28 @@
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.RestSession;
-import com.google.gerrit.acceptance.SshSession;
+import com.google.gerrit.extensions.common.ChangeInfo;
+import com.google.gerrit.extensions.common.ChangeStatus;
+import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.change.ChangeJson.ChangeInfo;
import com.google.gwtorm.server.OrmException;
-import com.google.gwtorm.server.SchemaFactory;
-import com.google.inject.Inject;
-import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
public class DeleteDraftChangeIT extends AbstractDaemonTest {
- @Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
- @Inject
- private PushOneCommit.Factory pushFactory;
-
- private Git git;
- private ReviewDb db;
-
- @Before
- public void setUp() throws Exception {
- Project.NameKey project = new Project.NameKey("p");
- SshSession sshSession = new SshSession(server, admin);
- createProject(sshSession, project.get());
- git = cloneProject(sshSession.getUrl() + "/" + project.get());
- sshSession.close();
- db = reviewDbProvider.open();
- }
-
- @After
- public void cleanup() {
- db.close();
- }
-
@Test
public void deleteChange() throws GitAPIException,
- IOException {
- String changeId = createChange();
- ChangeInfo c = getChange(changeId);
- assertEquals("p~master~" + changeId, c.id);
- assertEquals(Change.Status.NEW, c.status);
+ IOException, RestApiException {
+ String changeId = createChange().getChangeId();
+ String triplet = "p~master~" + changeId;
+ ChangeInfo c = get(triplet);
+ assertEquals(triplet, c.id);
+ assertEquals(ChangeStatus.NEW, c.status);
RestResponse r = deleteChange(changeId, adminSession);
assertEquals("Change is not a draft", r.getEntityContent());
assertEquals(409, r.getStatusCode());
@@ -81,45 +50,41 @@
@Test
public void deleteDraftChange() throws GitAPIException,
- IOException, OrmException {
+ IOException, RestApiException, OrmException {
String changeId = createDraftChange();
- ChangeInfo c = getChange(changeId);
- assertEquals("p~master~" + changeId, c.id);
- assertEquals(Change.Status.DRAFT, c.status);
+ String triplet = "p~master~" + changeId;
+ ChangeInfo c = get(triplet);
+ assertEquals(triplet, c.id);
+ assertEquals(ChangeStatus.DRAFT, c.status);
RestResponse r = deleteChange(changeId, adminSession);
assertEquals(204, r.getStatusCode());
}
@Test
public void publishDraftChange() throws GitAPIException,
- IOException {
+ IOException, RestApiException {
String changeId = createDraftChange();
- ChangeInfo c = getChange(changeId);
- assertEquals("p~master~" + changeId, c.id);
- assertEquals(Change.Status.DRAFT, c.status);
+ String triplet = "p~master~" + changeId;
+ ChangeInfo c = get(triplet);
+ assertEquals(triplet, c.id);
+ assertEquals(ChangeStatus.DRAFT, c.status);
RestResponse r = publishChange(changeId);
assertEquals(204, r.getStatusCode());
- c = getChange(changeId);
- assertEquals(Change.Status.NEW, c.status);
+ c = get(triplet);
+ assertEquals(ChangeStatus.NEW, c.status);
}
@Test
public void publishDraftPatchSet() throws GitAPIException,
- IOException, OrmException {
+ IOException, OrmException, RestApiException {
String changeId = createDraftChange();
- ChangeInfo c = getChange(changeId);
- assertEquals("p~master~" + changeId, c.id);
- assertEquals(Change.Status.DRAFT, c.status);
+ String triplet = "p~master~" + changeId;
+ ChangeInfo c = get(triplet);
+ assertEquals(triplet, c.id);
+ assertEquals(ChangeStatus.DRAFT, c.status);
RestResponse r = publishPatchSet(changeId);
assertEquals(204, r.getStatusCode());
- c = getChange(changeId);
- assertEquals(Change.Status.NEW, c.status);
- }
-
- private String createChange() throws GitAPIException,
- IOException {
- PushOneCommit push = pushFactory.create(db, admin.getIdent());
- return push.to(git, "refs/for/master").getChangeId();
+ assertEquals(ChangeStatus.NEW, get(triplet).status);
}
private String createDraftChange() throws GitAPIException, IOException {
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/DeleteDraftPatchSetIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/DeleteDraftPatchSetIT.java
index 3da0e6a..10fbed0 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/DeleteDraftPatchSetIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/DeleteDraftPatchSetIT.java
@@ -14,8 +14,6 @@
package com.google.gerrit.acceptance.rest.change;
-import static com.google.gerrit.acceptance.GitUtil.cloneProject;
-import static com.google.gerrit.acceptance.GitUtil.createProject;
import static org.junit.Assert.assertEquals;
import com.google.common.collect.Iterables;
@@ -24,90 +22,53 @@
import com.google.gerrit.acceptance.PushOneCommit.Result;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.RestSession;
-import com.google.gerrit.acceptance.SshSession;
-import com.google.gerrit.acceptance.TestAccount;
+import com.google.gerrit.extensions.common.ChangeInfo;
+import com.google.gerrit.extensions.common.ChangeStatus;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.change.ChangeJson.ChangeInfo;
import com.google.gwtorm.server.OrmException;
-import com.google.gwtorm.server.SchemaFactory;
-import com.google.inject.Inject;
-import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
public class DeleteDraftPatchSetIT extends AbstractDaemonTest {
- @Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
- @Inject
- private PushOneCommit.Factory pushFactory;
-
- private TestAccount user;
-
- private RestSession userSession;
- private Git git;
- private ReviewDb db;
-
- @Before
- public void setUp() throws Exception {
- user = accounts.create("user", "user@example.com", "User");
- userSession = new RestSession(server, user);
- Project.NameKey project = new Project.NameKey("p");
- SshSession sshSession = new SshSession(server, admin);
- createProject(sshSession, project.get());
- git = cloneProject(sshSession.getUrl() + "/" + project.get());
- sshSession.close();
- db = reviewDbProvider.open();
- }
-
- @After
- public void cleanup() {
- db.close();
- }
-
@Test
- public void deletePatchSet() throws GitAPIException,
- IOException, OrmException {
- String changeId = createChangeWith2PS("refs/for/master");
+ public void deletePatchSet() throws Exception {
+ String changeId = createChange().getChangeId();
PatchSet ps = getCurrentPatchSet(changeId);
- ChangeInfo c = getChange(changeId);
- assertEquals("p~master~" + changeId, c.id);
- assertEquals(Change.Status.NEW, c.status);
+ String triplet = "p~master~" + changeId;
+ ChangeInfo c = get(triplet);
+ assertEquals(triplet, c.id);
+ assertEquals(ChangeStatus.NEW, c.status);
RestResponse r = deletePatchSet(changeId, ps, adminSession);
assertEquals("Patch set is not a draft.", r.getEntityContent());
assertEquals(409, r.getStatusCode());
}
@Test
- public void deleteDraftPatchSetNoACL() throws GitAPIException,
- IOException, OrmException {
- String changeId = createChangeWith2PS("refs/drafts/master");
+ public void deleteDraftPatchSetNoACL() throws Exception {
+ String changeId = createDraftChangeWith2PS();
PatchSet ps = getCurrentPatchSet(changeId);
- ChangeInfo c = getChange(changeId);
- assertEquals("p~master~" + changeId, c.id);
- assertEquals(Change.Status.DRAFT, c.status);
+ String triplet = "p~master~" + changeId;
+ ChangeInfo c = get(triplet);
+ assertEquals(triplet, c.id);
+ assertEquals(ChangeStatus.DRAFT, c.status);
RestResponse r = deletePatchSet(changeId, ps, userSession);
assertEquals("Not found", r.getEntityContent());
assertEquals(404, r.getStatusCode());
}
@Test
- public void deleteDraftPatchSetAndChange() throws GitAPIException,
- IOException, OrmException {
- String changeId = createChangeWith2PS("refs/drafts/master");
+ public void deleteDraftPatchSetAndChange() throws Exception {
+ String changeId = createDraftChangeWith2PS();
PatchSet ps = getCurrentPatchSet(changeId);
- ChangeInfo c = getChange(changeId);
- assertEquals("p~master~" + changeId, c.id);
- assertEquals(Change.Status.DRAFT, c.status);
+ String triplet = "p~master~" + changeId;
+ ChangeInfo c = get(triplet);
+ assertEquals(triplet, c.id);
+ assertEquals(ChangeStatus.DRAFT, c.status);
RestResponse r = deletePatchSet(changeId, ps, adminSession);
assertEquals(204, r.getStatusCode());
Change change = Iterables.getOnlyElement(db.changes().byKey(
@@ -121,13 +82,13 @@
.toList().size());
}
- private String createChangeWith2PS(String ref) throws GitAPIException,
+ private String createDraftChangeWith2PS() throws GitAPIException,
IOException {
PushOneCommit push = pushFactory.create(db, admin.getIdent());
- Result result = push.to(git, ref);
+ Result result = push.to(git, "refs/drafts/master");
push = pushFactory.create(db, admin.getIdent(), PushOneCommit.SUBJECT,
"b.txt", "4711", result.getChangeId());
- return push.to(git, ref).getChangeId();
+ return push.to(git, "refs/drafts/master").getChangeId();
}
private PatchSet getCurrentPatchSet(String changeId) throws OrmException {
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ListChangesOptionsIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ListChangesOptionsIT.java
index 3cecfc5..97ae2fd 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ListChangesOptionsIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/ListChangesOptionsIT.java
@@ -14,8 +14,6 @@
package com.google.gerrit.acceptance.rest.change;
-import static com.google.gerrit.acceptance.GitUtil.cloneProject;
-import static com.google.gerrit.acceptance.GitUtil.createProject;
import static com.google.gerrit.extensions.common.ListChangesOption.ALL_REVISIONS;
import static com.google.gerrit.extensions.common.ListChangesOption.CURRENT_REVISION;
import static org.junit.Assert.assertEquals;
@@ -24,43 +22,23 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
-import com.google.gerrit.acceptance.SshSession;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.change.ChangeJson.ChangeInfo;
-import com.google.gwtorm.server.SchemaFactory;
-import com.google.inject.Inject;
+import com.google.gerrit.extensions.common.ChangeInfo;
-import org.eclipse.jgit.api.Git;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
+@NoHttpd
public class ListChangesOptionsIT extends AbstractDaemonTest {
- @Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
- @Inject
- protected PushOneCommit.Factory pushFactory;
-
- private Project.NameKey project;
- private Git git;
- private ReviewDb db;
private String changeId;
private List<PushOneCommit.Result> results;
@Before
public void setUp() throws Exception {
- project = new Project.NameKey("p");
- db = reviewDbProvider.open();
- SshSession sshSession = new SshSession(server, admin);
- createProject(sshSession, project.get());
- git = cloneProject(sshSession.getUrl() + "/" + project.get());
-
results = Lists.newArrayList();
results.add(push("file contents", null));
changeId = results.get(0).getChangeId();
@@ -79,21 +57,16 @@
return r;
}
- @After
- public void cleanup() {
- db.close();
- }
-
@Test
public void noRevisionOptions() throws Exception {
- ChangeInfo c = getChange(changeId);
+ ChangeInfo c = info(changeId);
assertNull(c.currentRevision);
assertNull(c.revisions);
}
@Test
public void currentRevision() throws Exception {
- ChangeInfo c = getChange(changeId, CURRENT_REVISION);
+ ChangeInfo c = get(changeId, CURRENT_REVISION);
assertEquals(commitId(2), c.currentRevision);
assertEquals(ImmutableSet.of(commitId(2)), c.revisions.keySet());
assertEquals(3, c.revisions.get(commitId(2))._number);
@@ -101,7 +74,7 @@
@Test
public void allRevisions() throws Exception {
- ChangeInfo c = getChange(changeId, ALL_REVISIONS);
+ ChangeInfo c = get(changeId, ALL_REVISIONS);
assertEquals(commitId(2), c.currentRevision);
assertEquals(ImmutableSet.of(commitId(0), commitId(1), commitId(2)),
c.revisions.keySet());
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SuggestReviewersIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SuggestReviewersIT.java
index 7808ccb..f52104d 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SuggestReviewersIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SuggestReviewersIT.java
@@ -14,26 +14,15 @@
package com.google.gerrit.acceptance.rest.change;
-import static com.google.gerrit.acceptance.GitUtil.cloneProject;
-import static com.google.gerrit.acceptance.GitUtil.createProject;
import static org.junit.Assert.assertEquals;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GerritConfig;
import com.google.gerrit.acceptance.GerritConfigs;
-import com.google.gerrit.acceptance.PushOneCommit;
-import com.google.gerrit.acceptance.SshSession;
-import com.google.gerrit.acceptance.TestAccount;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.change.SuggestReviewers.SuggestedReviewerInfo;
import com.google.gson.reflect.TypeToken;
-import com.google.gwtorm.server.SchemaFactory;
-import com.google.inject.Inject;
-import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -42,16 +31,6 @@
public class SuggestReviewersIT extends AbstractDaemonTest {
- @Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
- @Inject
- private PushOneCommit.Factory pushFactory;
-
- private Git git;
- private ReviewDb db;
- private Project.NameKey project;
-
@Before
public void setUp() throws Exception {
group("users1");
@@ -61,25 +40,13 @@
accounts.create("user1", "user1@example.com", "User1", "users1");
accounts.create("user2", "user2@example.com", "User2", "users2");
accounts.create("user3", "user3@example.com", "User3", "users1", "users2");
-
- project = new Project.NameKey("p");
- SshSession sshSession = new SshSession(server, admin);
- createProject(sshSession, project.get());
- git = cloneProject(sshSession.getUrl() + "/" + project.get());
- sshSession.close();
- db = reviewDbProvider.open();
- }
-
- @After
- public void cleanup() {
- db.close();
}
@Test
@GerritConfig(name = "suggest.accounts", value = "false")
public void suggestReviewersNoResult1() throws GitAPIException, IOException,
Exception {
- String changeId = createChange(admin);
+ String changeId = createChange().getChangeId();
List<SuggestedReviewerInfo> reviewers = suggestReviewers(changeId, "u", 6);
assertEquals(reviewers.size(), 0);
}
@@ -92,7 +59,7 @@
})
public void suggestReviewersNoResult2() throws GitAPIException, IOException,
Exception {
- String changeId = createChange(admin);
+ String changeId = createChange().getChangeId();
List<SuggestedReviewerInfo> reviewers = suggestReviewers(changeId, "u", 6);
assertEquals(reviewers.size(), 0);
}
@@ -101,7 +68,7 @@
@GerritConfig(name = "suggest.from", value = "2")
public void suggestReviewersNoResult3() throws GitAPIException, IOException,
Exception {
- String changeId = createChange(admin);
+ String changeId = createChange().getChangeId();
List<SuggestedReviewerInfo> reviewers = suggestReviewers(changeId, "u", 6);
assertEquals(reviewers.size(), 0);
}
@@ -109,7 +76,7 @@
@Test
public void suggestReviewersChange() throws GitAPIException,
IOException, Exception {
- String changeId = createChange(admin);
+ String changeId = createChange().getChangeId();
List<SuggestedReviewerInfo> reviewers = suggestReviewers(changeId, "u", 6);
assertEquals(reviewers.size(), 6);
reviewers = suggestReviewers(changeId, "u", 5);
@@ -136,10 +103,4 @@
private void group(String name) throws IOException {
adminSession.put("/groups/" + name, new Object()).consume();
}
-
- private String createChange(TestAccount account) throws GitAPIException,
- IOException {
- PushOneCommit push = pushFactory.create(db, account.getIdent());
- return push.to(git, "refs/for/master").getChangeId();
- }
}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group/AddRemoveGroupMembersIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group/AddRemoveGroupMembersIT.java
index 50857ec..3646e57 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group/AddRemoveGroupMembersIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group/AddRemoveGroupMembersIT.java
@@ -89,12 +89,11 @@
@Test
public void addRemoveMember() throws Exception {
- TestAccount u = accounts.create("user", "user@example.com", "Full Name");
RestResponse r = PUT("/groups/Administrators/members/user");
assertEquals(HttpStatus.SC_CREATED, r.getStatusCode());
AccountInfo ai = newGson().fromJson(r.getReader(), AccountInfo.class);
- assertAccountInfo(u, ai);
- assertMembers("Administrators", admin, u);
+ assertAccountInfo(user, ai);
+ assertMembers("Administrators", admin, user);
r.consume();
assertEquals(HttpStatus.SC_NO_CONTENT,
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group/CreateGroupIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group/CreateGroupIT.java
index 90ebb06..a6954b2 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group/CreateGroupIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group/CreateGroupIT.java
@@ -21,7 +21,6 @@
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.RestSession;
-import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.group.CreateGroup;
@@ -71,7 +70,6 @@
@Test
public void testCreateGroupWithoutCapability_Forbidden() throws OrmException,
JSchException, IOException {
- TestAccount user = accounts.create("user", "user@example.com", "User");
RestResponse r = (new RestSession(server, user)).put("/groups/newGroup");
assertEquals(HttpStatus.SC_FORBIDDEN, r.getStatusCode());
}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group/DefaultGroupsIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group/DefaultGroupsIT.java
index f1d4f3c..0d229ca 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group/DefaultGroupsIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group/DefaultGroupsIT.java
@@ -22,12 +22,9 @@
import com.google.gerrit.acceptance.RestSession;
import com.google.gerrit.acceptance.SshSession;
import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.group.GroupJson.GroupInfo;
import com.google.gson.reflect.TypeToken;
import com.google.gwtorm.server.OrmException;
-import com.google.gwtorm.server.SchemaFactory;
-import com.google.inject.Inject;
import com.jcraft.jsch.JSchException;
@@ -46,9 +43,6 @@
*/
public class DefaultGroupsIT extends AbstractDaemonTest {
- @Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
@Test
public void defaultGroupsCreated_ssh() throws JSchException, IOException {
SshSession session = new SshSession(server, admin);
@@ -72,16 +66,11 @@
@Test
public void defaultGroupsCreated_internals() throws OrmException {
- ReviewDb db = reviewDbProvider.open();
- try {
- Set<String> names = Sets.newHashSet();
- for (AccountGroup g : db.accountGroups().all()) {
- names.add(g.getName());
- }
- assertTrue(names.contains("Administrators"));
- assertTrue(names.contains("Non-Interactive Users"));
- } finally {
- db.close();
+ Set<String> names = Sets.newHashSet();
+ for (AccountGroup g : db.accountGroups().all()) {
+ names.add(g.getName());
}
+ assertTrue(names.contains("Administrators"));
+ assertTrue(names.contains("Non-Interactive Users"));
}
}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group/ListGroupsIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group/ListGroupsIT.java
index be601a5..8b5dde6 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group/ListGroupsIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/group/ListGroupsIT.java
@@ -24,8 +24,6 @@
import com.google.common.collect.Sets;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
-import com.google.gerrit.acceptance.RestSession;
-import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.account.GroupCache;
@@ -69,9 +67,6 @@
@Test
public void testOnlyVisibleGroupsReturned() throws OrmException,
JSchException, IOException {
- TestAccount user = accounts.create("user", "user@example.com", "User");
- RestSession userSession = new RestSession(server, user);
-
String newGroupName = "newGroup";
CreateGroup.Input in = new CreateGroup.Input();
in.description = "a hidden group";
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateBranchIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateBranchIT.java
index 116ea22..a4bcdf2 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateBranchIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateBranchIT.java
@@ -14,19 +14,14 @@
package com.google.gerrit.acceptance.rest.project;
-import static com.google.gerrit.acceptance.GitUtil.createProject;
import static org.junit.Assert.assertEquals;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
-import com.google.gerrit.acceptance.RestSession;
-import com.google.gerrit.acceptance.SshSession;
-import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.reviewdb.client.Branch;
-import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.AllProjectsNameProvider;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
@@ -51,25 +46,11 @@
@Inject
private AllProjectsNameProvider allProjects;
- private RestSession userSession;
-
- private Project.NameKey project;
private Branch.NameKey branch;
@Before
public void setUp() throws Exception {
- TestAccount user = accounts.create("user", "user@example.com", "User");
- userSession = new RestSession(server, user);
-
- project = new Project.NameKey("p");
branch = new Branch.NameKey(project, "test");
-
- SshSession sshSession = new SshSession(server, admin);
- try {
- createProject(sshSession, project.get(), null, true);
- } finally {
- sshSession.close();
- }
}
@Test
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
index 7177155..b593840 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
@@ -24,8 +24,6 @@
import com.google.common.collect.Sets;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
-import com.google.gerrit.acceptance.RestSession;
-import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.Project.InheritableBoolean;
@@ -194,8 +192,7 @@
@Test
public void testCreateProjectWithoutCapability_Forbidden() throws OrmException,
JSchException, IOException {
- TestAccount user = accounts.create("user", "user@example.com", "User");
- RestResponse r = new RestSession(server, user).put("/projects/newProject");
+ RestResponse r = userSession.put("/projects/newProject");
assertEquals(HttpStatus.SC_FORBIDDEN, r.getStatusCode());
}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/DeleteBranchIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/DeleteBranchIT.java
index 5193be7..020fd43 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/DeleteBranchIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/DeleteBranchIT.java
@@ -14,19 +14,14 @@
package com.google.gerrit.acceptance.rest.project;
-import static com.google.gerrit.acceptance.GitUtil.createProject;
import static org.junit.Assert.assertEquals;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
-import com.google.gerrit.acceptance.RestSession;
-import com.google.gerrit.acceptance.SshSession;
-import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.reviewdb.client.Branch;
-import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.AllProjectsNameProvider;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
@@ -52,26 +47,11 @@
@Inject
private AllProjectsNameProvider allProjects;
- private RestSession userSession;
-
- private Project.NameKey project;
private Branch.NameKey branch;
@Before
public void setUp() throws Exception {
- TestAccount user = accounts.create("user", "user@example.com", "User");
- userSession = new RestSession(server, user);
-
- project = new Project.NameKey("p");
branch = new Branch.NameKey(project, "test");
-
- SshSession sshSession = new SshSession(server, admin);
- try {
- createProject(sshSession, project.get(), null, true);
- } finally {
- sshSession.close();
- }
-
adminSession.put("/projects/" + project.get()
+ "/branches/" + branch.getShortName()).consume();
}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/GarbageCollectionIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/GarbageCollectionIT.java
index 9368593..26585ba 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/GarbageCollectionIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/GarbageCollectionIT.java
@@ -20,8 +20,6 @@
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GcAssert;
import com.google.gerrit.acceptance.RestResponse;
-import com.google.gerrit.acceptance.RestSession;
-import com.google.gerrit.acceptance.SshSession;
import com.google.gerrit.acceptance.UseLocalDisk;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.AllProjectsName;
@@ -49,14 +47,11 @@
@Before
public void setUp() throws Exception {
- SshSession sshSession = new SshSession(server, admin);
-
project1 = new Project.NameKey("p1");
createProject(sshSession, project1.get());
project2 = new Project.NameKey("p2");
createProject(sshSession, project2.get());
- sshSession.close();
}
@Test
@@ -65,10 +60,11 @@
}
@Test
- public void testGcNotAllowed_Forbidden() throws IOException, OrmException, JSchException {
+ public void testGcNotAllowed_Forbidden() throws IOException, OrmException,
+ JSchException {
assertEquals(HttpStatus.SC_FORBIDDEN,
- new RestSession(server, accounts.create("user", "user@example.com", "User"))
- .post("/projects/" + allProjects.get() + "/gc").getStatusCode());
+ userSession.post("/projects/" + allProjects.get() + "/gc")
+ .getStatusCode());
}
@Test
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ListBranchesIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ListBranchesIT.java
index 8b5b50a..52bb623 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ListBranchesIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ListBranchesIT.java
@@ -14,7 +14,6 @@
package com.google.gerrit.acceptance.rest.project;
-import static com.google.gerrit.acceptance.GitUtil.cloneProject;
import static com.google.gerrit.acceptance.GitUtil.createProject;
import static com.google.gerrit.acceptance.rest.project.BranchAssert.assertBranches;
import static org.junit.Assert.assertEquals;
@@ -23,13 +22,10 @@
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.RestResponse;
-import com.google.gerrit.acceptance.RestSession;
-import com.google.gerrit.acceptance.SshSession;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.group.SystemGroupBackend;
@@ -37,18 +33,14 @@
import com.google.gerrit.server.project.ProjectCache;
import com.google.gson.reflect.TypeToken;
import com.google.gwtorm.server.OrmException;
-import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
import com.jcraft.jsch.JSchException;
import org.apache.http.HttpStatus;
-import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
@@ -63,32 +55,6 @@
@Inject
private ProjectCache projectCache;
- @Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
- @Inject
- private PushOneCommit.Factory pushFactory;
-
- private SshSession sshSession;
- private Project.NameKey project;
- private Git git;
- private ReviewDb db;
-
- @Before
- public void setUp() throws Exception {
- project = new Project.NameKey("p");
- sshSession = new SshSession(server, admin);
- createProject(sshSession, project.get());
- git = cloneProject(sshSession.getUrl() + "/" + project.get());
- db = reviewDbProvider.open();
- }
-
- @After
- public void cleanup() {
- sshSession.close();
- db.close();
- }
-
@Test
public void listBranchesOfNonExistingProject_NotFound() throws IOException {
assertEquals(HttpStatus.SC_NOT_FOUND,
@@ -99,9 +65,8 @@
public void listBranchesOfNonVisibleProject_NotFound() throws IOException,
OrmException, JSchException, ConfigInvalidException {
blockRead(project, "refs/*");
- RestSession session = new RestSession(server, accounts.user());
assertEquals(HttpStatus.SC_NOT_FOUND,
- session.get("/projects/" + project.get() + "/branches").getStatusCode());
+ userSession.get("/projects/" + project.get() + "/branches").getStatusCode());
}
@Test
@@ -145,12 +110,10 @@
public void listBranchesSomeHidden() throws IOException, GitAPIException,
ConfigInvalidException, OrmException, JSchException {
blockRead(project, "refs/heads/dev");
- RestSession session =
- new RestSession(server, accounts.create("user", "user@example.com", "User"));
pushTo("refs/heads/master");
String masterCommit = git.getRepository().getRef("master").getTarget().getObjectId().getName();
pushTo("refs/heads/dev");
- RestResponse r = session.get("/projects/" + project.get() + "/branches");
+ RestResponse r = userSession.get("/projects/" + project.get() + "/branches");
// refs/meta/config is hidden since user is no project owner
List<BranchInfo> expected = Lists.asList(
new BranchInfo("HEAD", "master", false),
@@ -164,12 +127,10 @@
public void listBranchesHeadHidden() throws IOException, GitAPIException,
ConfigInvalidException, OrmException, JSchException {
blockRead(project, "refs/heads/master");
- RestSession session =
- new RestSession(server, accounts.create("user", "user@example.com", "User"));
pushTo("refs/heads/master");
pushTo("refs/heads/dev");
String devCommit = git.getRepository().getRef("master").getTarget().getObjectId().getName();
- RestResponse r = session.get("/projects/" + project.get() + "/branches");
+ RestResponse r = userSession.get("/projects/" + project.get() + "/branches");
// refs/meta/config is hidden since user is no project owner
assertBranches(Collections.singletonList(new BranchInfo("refs/heads/dev",
devCommit, false)), toBranchInfoList(r));
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ListChildProjectsIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ListChildProjectsIT.java
index a275314..c61764b 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ListChildProjectsIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/ListChildProjectsIT.java
@@ -21,7 +21,6 @@
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
-import com.google.gerrit.acceptance.SshSession;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.project.ProjectJson.ProjectInfo;
@@ -52,27 +51,27 @@
public void listNoChildren() throws IOException {
RestResponse r = GET("/projects/" + allProjects.get() + "/children/");
assertEquals(HttpStatus.SC_OK, r.getStatusCode());
- assertTrue(toProjectInfoList(r).isEmpty());
+ List<ProjectInfo> projectInfoList = toProjectInfoList(r);
+ // Project 'p' was already created in the base class
+ assertTrue(projectInfoList.size() == 1);
}
@Test
public void listChildren() throws IOException, JSchException {
- SshSession sshSession = new SshSession(server, admin);
+ Project.NameKey existingProject = new Project.NameKey("p");
Project.NameKey child1 = new Project.NameKey("p1");
createProject(sshSession, child1.get());
Project.NameKey child2 = new Project.NameKey("p2");
createProject(sshSession, child2.get());
createProject(sshSession, "p1.1", child1);
- sshSession.close();
RestResponse r = GET("/projects/" + allProjects.get() + "/children/");
assertEquals(HttpStatus.SC_OK, r.getStatusCode());
- assertProjects(Arrays.asList(child1, child2), toProjectInfoList(r));
+ assertProjects(Arrays.asList(existingProject, child1, child2), toProjectInfoList(r));
}
@Test
public void listChildrenRecursively() throws IOException, JSchException {
- SshSession sshSession = new SshSession(server, admin);
Project.NameKey child1 = new Project.NameKey("p1");
createProject(sshSession, child1.get());
createProject(sshSession, "p2");
@@ -84,12 +83,11 @@
createProject(sshSession, child1_1_1.get(), child1_1);
Project.NameKey child1_1_1_1 = new Project.NameKey("p1.1.1.1");
createProject(sshSession, child1_1_1_1.get(), child1_1_1);
- sshSession.close();
RestResponse r = GET("/projects/" + child1.get() + "/children/?recursive");
assertEquals(HttpStatus.SC_OK, r.getStatusCode());
- assertProjects(Arrays.asList(child1_1, child1_2, child1_1_1, child1_1_1_1),
- toProjectInfoList(r));
+ assertProjects(Arrays.asList(child1_1, child1_2,
+ child1_1_1, child1_1_1_1), toProjectInfoList(r));
}
private static List<ProjectInfo> toProjectInfoList(RestResponse r)
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/SetParentIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/SetParentIT.java
index 2510a03..7c6f280 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/SetParentIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/project/SetParentIT.java
@@ -19,9 +19,6 @@
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
-import com.google.gerrit.acceptance.RestSession;
-import com.google.gerrit.acceptance.SshSession;
-import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.AllProjectsNameProvider;
import com.google.gerrit.server.project.SetParent;
@@ -30,8 +27,6 @@
import com.jcraft.jsch.JSchException;
import org.apache.http.HttpStatus;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
@@ -41,32 +36,12 @@
@Inject
private AllProjectsNameProvider allProjects;
- private RestSession userSession;
- private SshSession sshSession;
-
- private String project;
-
- @Before
- public void setUp() throws Exception {
- TestAccount user = accounts.user();
- userSession = new RestSession(server, user);
-
- sshSession = new SshSession(server, admin);
- project = "p";
- createProject(sshSession, project, null, true);
- }
-
- @After
- public void cleanup() {
- sshSession.close();
- }
-
@Test
public void setParent_Forbidden() throws IOException, JSchException {
String parent = "parent";
createProject(sshSession, parent, null, true);
RestResponse r =
- userSession.put("/projects/" + project + "/parent",
+ userSession.put("/projects/" + project.get() + "/parent",
newParentInput(parent));
assertEquals(HttpStatus.SC_FORBIDDEN, r.getStatusCode());
r.consume();
@@ -77,12 +52,12 @@
String parent = "parent";
createProject(sshSession, parent, null, true);
RestResponse r =
- adminSession.put("/projects/" + project + "/parent",
+ adminSession.put("/projects/" + project.get() + "/parent",
newParentInput(parent));
assertEquals(HttpStatus.SC_OK, r.getStatusCode());
r.consume();
- r = adminSession.get("/projects/" + project + "/parent");
+ r = adminSession.get("/projects/" + project.get() + "/parent");
assertEquals(HttpStatus.SC_OK, r.getStatusCode());
String newParent =
newGson().fromJson(r.getReader(), String.class);
@@ -94,7 +69,7 @@
public void setParentForAllProjects_Conflict() throws IOException {
RestResponse r =
adminSession.put("/projects/" + allProjects.get() + "/parent",
- newParentInput(project));
+ newParentInput(project.get()));
assertEquals(HttpStatus.SC_CONFLICT, r.getStatusCode());
r.consume();
}
@@ -102,21 +77,21 @@
@Test
public void setInvalidParent_Conflict() throws IOException, JSchException {
RestResponse r =
- adminSession.put("/projects/" + project + "/parent",
- newParentInput(project));
+ adminSession.put("/projects/" + project.get() + "/parent",
+ newParentInput(project.get()));
assertEquals(HttpStatus.SC_CONFLICT, r.getStatusCode());
r.consume();
String child = "child";
- createProject(sshSession, child, new Project.NameKey(project), true);
- r = adminSession.put("/projects/" + project + "/parent",
+ createProject(sshSession, child, project, true);
+ r = adminSession.put("/projects/" + project.get() + "/parent",
newParentInput(child));
assertEquals(HttpStatus.SC_CONFLICT, r.getStatusCode());
r.consume();
String grandchild = "grandchild";
createProject(sshSession, grandchild, new Project.NameKey(child), true);
- r = adminSession.put("/projects/" + project + "/parent",
+ r = adminSession.put("/projects/" + project.get() + "/parent",
newParentInput(grandchild));
assertEquals(HttpStatus.SC_CONFLICT, r.getStatusCode());
r.consume();
@@ -125,7 +100,7 @@
@Test
public void setNonExistingParent_UnprocessibleEntity() throws IOException {
RestResponse r =
- adminSession.put("/projects/" + project + "/parent",
+ adminSession.put("/projects/" + project.get() + "/parent",
newParentInput("non-existing"));
assertEquals(HttpStatus.SC_UNPROCESSABLE_ENTITY, r.getStatusCode());
r.consume();
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/GetRelatedIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/GetRelatedIT.java
index dbd34fe..1456086 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/GetRelatedIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/change/GetRelatedIT.java
@@ -15,9 +15,7 @@
package com.google.gerrit.acceptance.server.change;
import static com.google.gerrit.acceptance.GitUtil.add;
-import static com.google.gerrit.acceptance.GitUtil.cloneProject;
import static com.google.gerrit.acceptance.GitUtil.createCommit;
-import static com.google.gerrit.acceptance.GitUtil.createProject;
import static com.google.gerrit.acceptance.GitUtil.pushHead;
import static org.junit.Assert.assertEquals;
@@ -26,22 +24,14 @@
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GitUtil.Commit;
import com.google.gerrit.acceptance.PushOneCommit;
-import com.google.gerrit.acceptance.SshSession;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.change.GetRelated.ChangeAndCommit;
import com.google.gerrit.server.change.GetRelated.RelatedInfo;
import com.google.gwtorm.server.OrmException;
-import com.google.gwtorm.server.SchemaFactory;
-import com.google.inject.Inject;
-import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ResetCommand.ResetType;
import org.eclipse.jgit.api.errors.GitAPIException;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
@@ -49,30 +39,6 @@
public class GetRelatedIT extends AbstractDaemonTest {
- @Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
- @Inject
- private PushOneCommit.Factory pushFactory;
-
- private Git git;
- private ReviewDb db;
-
- @Before
- public void setUp() throws Exception {
- Project.NameKey project = new Project.NameKey("p");
- SshSession sshSession = new SshSession(server, admin);
- createProject(sshSession, project.get());
- git = cloneProject(sshSession.getUrl() + "/" + project.get());
- sshSession.close();
- db = reviewDbProvider.open();
- }
-
- @After
- public void cleanup() {
- db.close();
- }
-
@Test
public void getRelatedNoResult() throws GitAPIException,
IOException, Exception {
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/LabelTypeIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/LabelTypeIT.java
index 44f3771..ce722fa 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/LabelTypeIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/LabelTypeIT.java
@@ -15,65 +15,35 @@
package com.google.gerrit.acceptance.server.project;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.gerrit.acceptance.GitUtil.cloneProject;
-import static com.google.gerrit.acceptance.GitUtil.createProject;
import static com.google.gerrit.extensions.common.ListChangesOption.DETAILED_LABELS;
-import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
-import static com.google.gerrit.server.project.Util.grant;
import static org.junit.Assert.assertEquals;
import com.google.gerrit.acceptance.AbstractDaemonTest;
-import com.google.gerrit.acceptance.AcceptanceTestRequestScope;
+import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
-import com.google.gerrit.acceptance.SshSession;
-import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.common.data.LabelType;
-import com.google.gerrit.common.data.Permission;
-import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.changes.RevisionApi;
-import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.change.ChangeJson.ChangeInfo;
-import com.google.gerrit.server.change.ChangeJson.LabelInfo;
+import com.google.gerrit.extensions.common.ChangeInfo;
+import com.google.gerrit.extensions.common.LabelInfo;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
-import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.project.ProjectCache;
-import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
-import com.google.inject.util.Providers;
-import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.Repository;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import java.io.IOException;
-
+@NoHttpd
public class LabelTypeIT extends AbstractDaemonTest {
@Inject
- private SchemaFactory<ReviewDb> reviewDbProvider;
-
- @Inject
private GitRepositoryManager repoManager;
@Inject
- private GerritApi gApi;
-
- @Inject
- private AcceptanceTestRequestScope atrScope;
-
- @Inject
- private IdentifiedUser.GenericFactory identifiedUserFactory;
-
- @Inject
private ProjectCache projectCache;
@Inject
@@ -82,36 +52,11 @@
@Inject
private MetaDataUpdate.Server metaDataUpdateFactory;
- @Inject
- private PushOneCommit.Factory pushFactory;
-
- private Project.NameKey project;
private LabelType codeReview;
- private TestAccount user;
- private Git git;
- private ReviewDb db;
@Before
public void setUp() throws Exception {
- user = accounts.user();
- project = new Project.NameKey("p");
- SshSession sshSession = new SshSession(server, admin);
- try {
- createProject(sshSession, project.get());
- git = cloneProject(sshSession.getUrl() + "/" + project.get());
- db = reviewDbProvider.open();
- atrScope.set(atrScope.newContext(reviewDbProvider, sshSession,
- identifiedUserFactory.create(Providers.of(db), user.getId())));
- } finally {
- sshSession.close();
- }
-
ProjectConfig cfg = projectCache.checkedGet(allProjects).getConfig();
- AccountGroup.UUID anonymousUsers =
- SystemGroupBackend.getGroup(ANONYMOUS_USERS).getUUID();
- grant(cfg, Permission.forLabel("Code-Review"), -2, 2, anonymousUsers,
- "refs/heads/*");
- grant(cfg, Permission.SUBMIT, anonymousUsers, "refs/heads/*");
codeReview = checkNotNull(cfg.getLabelSections().get("Code-Review"));
codeReview.setCopyMinScore(false);
codeReview.setCopyMaxScore(false);
@@ -120,120 +65,69 @@
saveProjectConfig(cfg);
}
- @After
- public void cleanup() {
- db.close();
- }
-
@Test
public void noCopyMinScoreOnRework() throws Exception {
- String subject = "test commit";
- String file = "a.txt";
-
- PushOneCommit push = pushFactory.create(db, user.getIdent(),
- subject, file, "first contents");
- PushOneCommit.Result r = push.to(git, "refs/for/master");
+ PushOneCommit.Result r = createChange();
revision(r).review(ReviewInput.reject());
assertApproval(r, -2);
-
- push = pushFactory.create(db, user.getIdent(),
- subject, file, "second contents", r.getChangeId());
- r = push.to(git, "refs/for/master");
+ r = ammendChange(r.getChangeId());
assertApproval(r, 0);
}
@Test
public void copyMinScoreOnRework() throws Exception {
- String subject = "test commit";
- String file = "a.txt";
codeReview.setCopyMinScore(true);
saveLabelConfig();
-
- PushOneCommit push = pushFactory.create(db, user.getIdent(),
- subject, file, "first contents");
- PushOneCommit.Result r = push.to(git, "refs/for/master");
+ PushOneCommit.Result r = createChange();
revision(r).review(ReviewInput.reject());
assertApproval(r, -2);
-
- push = pushFactory.create(db, user.getIdent(),
- subject, file, "second contents", r.getChangeId());
- r = push.to(git, "refs/for/master");
+ r = ammendChange(r.getChangeId());
assertApproval(r, -2);
}
@Test
public void noCopyMaxScoreOnRework() throws Exception {
- String subject = "test commit";
- String file = "a.txt";
-
- PushOneCommit push = pushFactory.create(db, user.getIdent(),
- subject, file, "first contents");
- PushOneCommit.Result r = push.to(git, "refs/for/master");
+ PushOneCommit.Result r = createChange();
revision(r).review(ReviewInput.approve());
assertApproval(r, 2);
-
- push = pushFactory.create(db, user.getIdent(),
- subject, file, "second contents", r.getChangeId());
- r = push.to(git, "refs/for/master");
+ r = ammendChange(r.getChangeId());
assertApproval(r, 0);
}
@Test
public void copyMaxScoreOnRework() throws Exception {
- String subject = "test commit";
- String file = "a.txt";
codeReview.setCopyMaxScore(true);
saveLabelConfig();
-
- PushOneCommit push = pushFactory.create(db, user.getIdent(),
- subject, file, "first contents");
- PushOneCommit.Result r = push.to(git, "refs/for/master");
+ PushOneCommit.Result r = createChange();
revision(r).review(ReviewInput.approve());
assertApproval(r, 2);
-
- push = pushFactory.create(db, user.getIdent(),
- subject, file, "second contents", r.getChangeId());
- r = push.to(git, "refs/for/master");
+ r = ammendChange(r.getChangeId());
assertApproval(r, 2);
}
@Test
public void noCopyNonMaxScoreOnRework() throws Exception {
- String subject = "test commit";
- String file = "a.txt";
codeReview.setCopyMinScore(true);
codeReview.setCopyMaxScore(true);
saveLabelConfig();
- PushOneCommit push = pushFactory.create(db, user.getIdent(),
- subject, file, "first contents");
- PushOneCommit.Result r = push.to(git, "refs/for/master");
+ PushOneCommit.Result r = createChange();
revision(r).review(ReviewInput.recommend());
assertApproval(r, 1);
-
- push = pushFactory.create(db, user.getIdent(),
- subject, file, "second contents", r.getChangeId());
- r = push.to(git, "refs/for/master");
+ r = ammendChange(r.getChangeId());
assertApproval(r, 0);
}
@Test
public void noCopyNonMinScoreOnRework() throws Exception {
- String subject = "test commit";
- String file = "a.txt";
codeReview.setCopyMinScore(true);
codeReview.setCopyMaxScore(true);
saveLabelConfig();
- PushOneCommit push = pushFactory.create(db, user.getIdent(),
- subject, file, "first contents");
- PushOneCommit.Result r = push.to(git, "refs/for/master");
+ PushOneCommit.Result r = createChange();
revision(r).review(ReviewInput.dislike());
assertApproval(r, -1);
-
- push = pushFactory.create(db, user.getIdent(),
- subject, file, "second contents", r.getChangeId());
- r = push.to(git, "refs/for/master");
+ r = ammendChange(r.getChangeId());
assertApproval(r, 0);
}
@@ -242,13 +136,13 @@
String file = "a.txt";
String contents = "contents";
- PushOneCommit push = pushFactory.create(db, user.getIdent(),
+ PushOneCommit push = pushFactory.create(db, admin.getIdent(),
"first subject", file, contents);
PushOneCommit.Result r = push.to(git, "refs/for/master");
revision(r).review(ReviewInput.recommend());
assertApproval(r, 1);
- push = pushFactory.create(db, user.getIdent(),
+ push = pushFactory.create(db, admin.getIdent(),
"second subject", file, contents, r.getChangeId());
r = push.to(git, "refs/for/master");
assertApproval(r, 0);
@@ -261,13 +155,13 @@
codeReview.setCopyAllScoresIfNoCodeChange(true);
saveLabelConfig();
- PushOneCommit push = pushFactory.create(db, user.getIdent(),
+ PushOneCommit push = pushFactory.create(db, admin.getIdent(),
"first subject", file, contents);
PushOneCommit.Result r = push.to(git, "refs/for/master");
revision(r).review(ReviewInput.recommend());
assertApproval(r, 1);
- push = pushFactory.create(db, user.getIdent(),
+ push = pushFactory.create(db, admin.getIdent(),
"second subject", file, contents, r.getChangeId());
r = push.to(git, "refs/for/master");
assertApproval(r, 1);
@@ -279,17 +173,17 @@
String file = "a.txt";
String contents = "contents";
- PushOneCommit push = pushFactory.create(db, user.getIdent());
+ PushOneCommit push = pushFactory.create(db, admin.getIdent());
PushOneCommit.Result r1 = push.to(git, "refs/for/master");
merge(r1);
- push = pushFactory.create(db, user.getIdent(),
+ push = pushFactory.create(db, admin.getIdent(),
"non-conflicting", "b.txt", "other contents");
PushOneCommit.Result r2 = push.to(git, "refs/for/master");
merge(r2);
git.checkout().setName(r1.getCommit().name()).call();
- push = pushFactory.create(db, user.getIdent(), subject, file, contents);
+ push = pushFactory.create(db, admin.getIdent(), subject, file, contents);
PushOneCommit.Result r3 = push.to(git, "refs/for/master");
revision(r3).review(ReviewInput.recommend());
assertApproval(r3, 1);
@@ -306,17 +200,17 @@
codeReview.setCopyAllScoresOnTrivialRebase(true);
saveLabelConfig();
- PushOneCommit push = pushFactory.create(db, user.getIdent());
+ PushOneCommit push = pushFactory.create(db, admin.getIdent());
PushOneCommit.Result r1 = push.to(git, "refs/for/master");
merge(r1);
- push = pushFactory.create(db, user.getIdent(),
+ push = pushFactory.create(db, admin.getIdent(),
"non-conflicting", "b.txt", "other contents");
PushOneCommit.Result r2 = push.to(git, "refs/for/master");
merge(r2);
git.checkout().setName(r1.getCommit().name()).call();
- push = pushFactory.create(db, user.getIdent(), subject, file, contents);
+ push = pushFactory.create(db, admin.getIdent(), subject, file, contents);
PushOneCommit.Result r3 = push.to(git, "refs/for/master");
revision(r3).review(ReviewInput.recommend());
assertApproval(r3, 1);
@@ -344,7 +238,7 @@
private RevisionApi revision(PushOneCommit.Result r) throws Exception {
return gApi.changes()
.id(r.getChangeId())
- .revision(r.getCommit().name());
+ .current();
}
private void merge(PushOneCommit.Result r) throws Exception {
@@ -367,13 +261,10 @@
throws Exception {
// Don't use asserts from PushOneCommit so we can test the round-trip
// through JSON instead of querying the DB directly.
- LabelInfo cr = getChange(r).labels.get("Code-Review");
+ ChangeInfo c = get(r.getChangeId(), DETAILED_LABELS);
+ LabelInfo cr = c.labels.get("Code-Review");
assertEquals(1, cr.all.size());
- assertEquals("User", cr.all.get(0).name);
+ assertEquals("Administrator", cr.all.get(0).name);
assertEquals(expected, cr.all.get(0).value.intValue());
}
-
- private ChangeInfo getChange(PushOneCommit.Result pr) throws IOException {
- return getChange(pr.getChangeId(), DETAILED_LABELS);
- }
}
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/ssh/GarbageCollectionIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/ssh/GarbageCollectionIT.java
index ddc78ab..9f859dc 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/ssh/GarbageCollectionIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/ssh/GarbageCollectionIT.java
@@ -33,7 +33,6 @@
import com.jcraft.jsch.JSchException;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -55,15 +54,12 @@
@Inject
private GcAssert gcAssert;
- private SshSession sshSession;
private Project.NameKey project1;
private Project.NameKey project2;
private Project.NameKey project3;
@Before
public void setUp() throws Exception {
- sshSession = new SshSession(server, admin);
-
project1 = new Project.NameKey("p1");
createProject(sshSession, project1.get());
@@ -74,11 +70,6 @@
createProject(sshSession, project3.get());
}
- @After
- public void cleanup() {
- sshSession.close();
- }
-
@Test
@UseLocalDisk
public void testGc() throws JSchException, IOException {
@@ -103,7 +94,7 @@
@Test
public void testGcWithoutCapability_Error() throws IOException, OrmException,
JSchException {
- SshSession s = new SshSession(server, accounts.create("user", "user@example.com", "User"));
+ SshSession s = new SshSession(server, user);
s.exec("gerrit gc --all");
assertError("Capability runGC is required to access this resource", s.getError());
s.close();
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/PageLinks.java b/gerrit-common/src/main/java/com/google/gerrit/common/PageLinks.java
index deb6dc3..e4199c2 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/PageLinks.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/PageLinks.java
@@ -35,9 +35,8 @@
public static final String SETTINGS_NEW_AGREEMENT = "/settings/new-agreement";
public static final String REGISTER = "/register";
- public static final String TOP = "n,z";
-
public static final String MINE = "/";
+ public static final String QUERY = "/q/";
public static final String PROJECTS = "/projects/";
public static final String DASHBOARDS = ",dashboards/";
public static final String ADMIN_GROUPS = "/admin/groups/";
@@ -84,7 +83,7 @@
}
public static String toAccountQuery(String fullname, Status status) {
- return toChangeQuery(op("owner", fullname) + " " + status(status), TOP);
+ return toChangeQuery(op("owner", fullname) + " " + status(status));
}
public static String toCustomDashboard(final String params) {
@@ -95,12 +94,13 @@
return ADMIN_PROJECTS + proj.get() + ",dashboards";
}
- public static String toChangeQuery(final String query) {
- return toChangeQuery(query, TOP);
+ public static String toChangeQuery(String query) {
+ return QUERY + KeyUtil.encode(query);
}
- public static String toChangeQuery(String query, String page) {
- return "/q/" + KeyUtil.encode(query) + "," + page;
+ public static String toChangeQuery(String query, String start) {
+ int s = Integer.parseInt(start);
+ return QUERY + KeyUtil.encode(query) + (s > 0 ? "," + s : "");
}
public static String toProjectDashboard(Project.NameKey name, String id) {
diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/ChangeApi.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/ChangeApi.java
index 3d06d7c..f0a9e4d 100644
--- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/ChangeApi.java
+++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/ChangeApi.java
@@ -40,4 +40,9 @@
void addReviewer(String in) throws RestApiException;
ChangeInfo get(EnumSet<ListChangesOption> options) throws RestApiException;
+
+ /** {@code get} with {@link ListChangesOption} set to ALL. */
+ ChangeInfo get() throws RestApiException;
+ /** {@code get} with {@link ListChangesOption} set to NONE. */
+ ChangeInfo info() throws RestApiException;
}
diff --git a/gerrit-gwtdebug/src/main/java/com/google/gerrit/gwtdebug/GerritDebugLauncher.java b/gerrit-gwtdebug/src/main/java/com/google/gerrit/gwtdebug/GerritDebugLauncher.java
index 7ba2a3e..09a7fb6 100644
--- a/gerrit-gwtdebug/src/main/java/com/google/gerrit/gwtdebug/GerritDebugLauncher.java
+++ b/gerrit-gwtdebug/src/main/java/com/google/gerrit/gwtdebug/GerritDebugLauncher.java
@@ -202,7 +202,7 @@
@Override
public String getName() {
- return this.getName();
+ return this.getClass().getName();
}
/**
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
index 3879df9..a1ca5a1 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
@@ -22,6 +22,7 @@
import static com.google.gerrit.common.PageLinks.DASHBOARDS;
import static com.google.gerrit.common.PageLinks.MINE;
import static com.google.gerrit.common.PageLinks.PROJECTS;
+import static com.google.gerrit.common.PageLinks.QUERY;
import static com.google.gerrit.common.PageLinks.REGISTER;
import static com.google.gerrit.common.PageLinks.SETTINGS;
import static com.google.gerrit.common.PageLinks.SETTINGS_AGREEMENTS;
@@ -34,6 +35,7 @@
import static com.google.gerrit.common.PageLinks.SETTINGS_SSHKEYS;
import static com.google.gerrit.common.PageLinks.SETTINGS_WEBIDENT;
import static com.google.gerrit.common.PageLinks.op;
+import static com.google.gerrit.common.PageLinks.toChangeQuery;
import com.google.gerrit.client.account.MyAgreementsScreen;
import com.google.gerrit.client.account.MyContactInformationScreen;
@@ -83,8 +85,8 @@
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.common.data.PatchSetDetail;
import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DiffView;
import com.google.gerrit.reviewdb.client.AccountGeneralPreferences;
+import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DiffView;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Patch;
@@ -218,7 +220,7 @@
}
private static void select(final String token) {
- if (matchPrefix("/q/", token)) {
+ if (matchPrefix(QUERY, token)) {
query(token);
} else if (matchPrefix("/Documentation/", token)) {
@@ -291,19 +293,19 @@
}
if (matchExact("mine,starred", token)) {
- return PageLinks.toChangeQuery("is:starred");
+ return toChangeQuery("is:starred");
}
if (matchExact("mine,drafts", token)) {
- return PageLinks.toChangeQuery("is:draft");
+ return toChangeQuery("is:draft");
}
if (matchExact("mine,comments", token)) {
- return PageLinks.toChangeQuery("has:draft");
+ return toChangeQuery("has:draft");
}
if (matchPrefix("mine,watched,", token)) {
- return PageLinks.toChangeQuery("is:watched status:open", skip(token));
+ return toChangeQuery("is:watched status:open");
}
return null;
@@ -311,15 +313,15 @@
private static String legacyAll(final String token) {
if (matchPrefix("all,abandoned,", token)) {
- return PageLinks.toChangeQuery("status:abandoned", skip(token));
+ return toChangeQuery("status:abandoned");
}
if (matchPrefix("all,merged,", token)) {
- return PageLinks.toChangeQuery("status:merged", skip(token));
+ return toChangeQuery("status:merged");
}
if (matchPrefix("all,open,", token)) {
- return PageLinks.toChangeQuery("status:open", skip(token));
+ return toChangeQuery("status:open");
}
return null;
@@ -330,27 +332,21 @@
final String s = skip(token);
final int c = s.indexOf(',');
Project.NameKey proj = Project.NameKey.parse(s.substring(0, c));
- return PageLinks.toChangeQuery( //
- "status:open " + op("project", proj.get()), //
- s.substring(c + 1));
+ return toChangeQuery("status:open " + op("project", proj.get()));
}
if (matchPrefix("project,merged,", token)) {
final String s = skip(token);
final int c = s.indexOf(',');
Project.NameKey proj = Project.NameKey.parse(s.substring(0, c));
- return PageLinks.toChangeQuery( //
- "status:merged " + op("project", proj.get()), //
- s.substring(c + 1));
+ return toChangeQuery("status:merged " + op("project", proj.get()));
}
if (matchPrefix("project,abandoned,", token)) {
final String s = skip(token);
final int c = s.indexOf(',');
Project.NameKey proj = Project.NameKey.parse(s.substring(0, c));
- return PageLinks.toChangeQuery( //
- "status:abandoned " + op("project", proj.get()), //
- s.substring(c + 1));
+ return toChangeQuery("status:abandoned " + op("project", proj.get()));
}
return null;
@@ -408,10 +404,22 @@
return null;
}
- private static void query(final String token) {
- final String s = skip(token);
- final int c = s.indexOf(',');
- Gerrit.display(token, new QueryScreen(s.substring(0, c), s.substring(c + 1)));
+ private static void query(String token) {
+ String s = skip(token);
+ int c = s.indexOf(',');
+ Screen screen;
+ if (c >= 0) {
+ String prefix = s.substring(0, c);
+ if (s.substring(c).equals(",n,z")) {
+ // Respect legacy token with max sortkey.
+ screen = new QueryScreen(prefix, 0);
+ } else {
+ screen = new QueryScreen(prefix, Integer.parseInt(s.substring(c + 1)));
+ }
+ } else {
+ screen = new QueryScreen(s, 0);
+ }
+ Gerrit.display(token, screen);
}
private static Screen mine(final String token) {
@@ -462,7 +470,7 @@
@Override
public void onFailure(Throwable caught) {
if ("default".equals(dashboardId) && RestApi.isNotFound(caught)) {
- Gerrit.display(PageLinks.toChangeQuery(
+ Gerrit.display(toChangeQuery(
PageLinks.projectQuery(new Project.NameKey(project))));
} else {
super.onFailure(caught);
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritResources.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritResources.java
index 8937bcc..3319457 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritResources.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritResources.java
@@ -61,6 +61,9 @@
@Source("readOnly.png")
public ImageResource readOnly();
+ @Source("gear.png")
+ public ImageResource gear();
+
@Source("info.png")
public ImageResource info();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
index 2f26ad9..1458976 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
@@ -110,8 +110,10 @@
String plugins();
String pluginEnabled();
String pluginDisabled();
+ String pluginSettingsToolTip();
String columnPluginName();
+ String columnPluginSettings();
String columnPluginVersion();
String columnPluginStatus();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
index f06d657..14dbab2 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
@@ -89,7 +89,9 @@
plugins = Plugins
pluginEnabled = Enabled
pluginDisabled = Disabled
+pluginSettingsToolTip = Plugin Settings
columnPluginName = Plugin Name
+columnPluginSettings = Settings
columnPluginVersion = Version
columnPluginStatus = Status
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/PluginListScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/PluginListScreen.java
index 7f85f51..e1c73fa 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/PluginListScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/PluginListScreen.java
@@ -15,14 +15,17 @@
package com.google.gerrit.client.admin;
import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.api.ExtensionScreen;
import com.google.gerrit.client.plugins.PluginInfo;
import com.google.gerrit.client.plugins.PluginMap;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.rpc.ScreenLoadCallback;
import com.google.gerrit.client.ui.FancyFlexTable;
+import com.google.gerrit.client.ui.InlineHyperlink;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.ImageResourceRenderer;
import com.google.gwt.user.client.ui.Panel;
public class PluginListScreen extends PluginScreen {
@@ -60,13 +63,15 @@
private class PluginTable extends FancyFlexTable<PluginInfo> {
PluginTable() {
table.setText(0, 1, Util.C.columnPluginName());
- table.setText(0, 2, Util.C.columnPluginVersion());
- table.setText(0, 3, Util.C.columnPluginStatus());
+ table.setText(0, 2, Util.C.columnPluginSettings());
+ table.setText(0, 3, Util.C.columnPluginVersion());
+ table.setText(0, 4, Util.C.columnPluginStatus());
final FlexCellFormatter fmt = table.getFlexCellFormatter();
fmt.addStyleName(0, 1, Gerrit.RESOURCES.css().dataHeader());
fmt.addStyleName(0, 2, Gerrit.RESOURCES.css().dataHeader());
fmt.addStyleName(0, 3, Gerrit.RESOURCES.css().dataHeader());
+ fmt.addStyleName(0, 4, Gerrit.RESOURCES.css().dataHeader());
}
void display(final PluginMap plugins) {
@@ -86,16 +91,20 @@
if (plugin.disabled() || plugin.indexUrl() == null) {
table.setText(row, 1, plugin.name());
} else {
- table.setWidget(
- row,
- 1,
- new Anchor(
- plugin.name(),
- Gerrit.selfRedirect(plugin.indexUrl()),
- "_blank"));
+ table.setWidget(row, 1, new Anchor(plugin.name(),
+ Gerrit.selfRedirect(plugin.indexUrl()), "_blank"));
+
+ if (new ExtensionScreen(plugin.name() + "/settings").isFound()) {
+ InlineHyperlink adminScreenLink = new InlineHyperlink();
+ adminScreenLink.setHTML(new ImageResourceRenderer().render(Gerrit.RESOURCES.gear()));
+ adminScreenLink.setTargetHistoryToken("/x/" + plugin.name() + "/settings");
+ adminScreenLink.setTitle(Util.C.pluginSettingsToolTip());
+ table.setWidget(row, 2, adminScreenLink);
+ }
}
- table.setText(row, 2, plugin.version());
- table.setText(row, 3, plugin.disabled()
+
+ table.setText(row, 3, plugin.version());
+ table.setText(row, 4, plugin.disabled()
? Util.C.pluginDisabled()
: Util.C.pluginEnabled());
@@ -103,6 +112,7 @@
fmt.addStyleName(row, 1, Gerrit.RESOURCES.css().dataCell());
fmt.addStyleName(row, 2, Gerrit.RESOURCES.css().dataCell());
fmt.addStyleName(row, 3, Gerrit.RESOURCES.css().dataCell());
+ fmt.addStyleName(row, 4, Gerrit.RESOURCES.css().dataCell());
setRowItem(row, plugin);
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Reviewers.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Reviewers.java
index 2ca424c..57ba4b9 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Reviewers.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/Reviewers.java
@@ -18,18 +18,20 @@
import com.google.gerrit.client.ConfirmationDialog;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.account.AccountInfo;
-import com.google.gerrit.client.changes.ApprovalTable.PostInput;
-import com.google.gerrit.client.changes.ApprovalTable.PostResult;
import com.google.gerrit.client.changes.ChangeApi;
import com.google.gerrit.client.changes.ChangeInfo;
import com.google.gerrit.client.changes.ChangeInfo.ApprovalInfo;
import com.google.gerrit.client.changes.ChangeInfo.LabelInfo;
import com.google.gerrit.client.changes.Util;
import com.google.gerrit.client.rpc.GerritCallback;
+import com.google.gerrit.client.rpc.NativeMap;
+import com.google.gerrit.client.rpc.NativeString;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.ui.HintTextBox;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.core.client.JsArray;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
@@ -57,7 +59,7 @@
import java.util.Set;
/** Add reviewers. */
-class Reviewers extends Composite {
+public class Reviewers extends Composite {
interface Binder extends UiBinder<HTMLPanel, Reviewers> {}
private static final Binder uiBinder = GWT.create(Binder.class);
@@ -262,4 +264,43 @@
}
return d;
}
+
+
+ public static class PostInput extends JavaScriptObject {
+ public static PostInput create(String reviewer, boolean confirmed) {
+ PostInput input = createObject().cast();
+ input.init(reviewer, confirmed);
+ return input;
+ }
+
+ private native void init(String reviewer, boolean confirmed) /*-{
+ this.reviewer = reviewer;
+ if (confirmed) {
+ this.confirmed = true;
+ }
+ }-*/;
+
+ protected PostInput() {
+ }
+ }
+
+ public static class ReviewerInfo extends AccountInfo {
+ final Set<String> approvals() {
+ return Natives.keys(_approvals());
+ }
+ final native String approval(String l) /*-{ return this.approvals[l]; }-*/;
+ private final native NativeMap<NativeString> _approvals() /*-{ return this.approvals; }-*/;
+
+ protected ReviewerInfo() {
+ }
+ }
+
+ public static class PostResult extends JavaScriptObject {
+ public final native JsArray<ReviewerInfo> reviewers() /*-{ return this.reviewers; }-*/;
+ public final native boolean confirm() /*-{ return this.confirm || false; }-*/;
+ public final native String error() /*-{ return this.error; }-*/;
+
+ protected PostResult() {
+ }
+ }
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ApprovalTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ApprovalTable.java
index 0ac487b..fbbff76 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ApprovalTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ApprovalTable.java
@@ -21,11 +21,11 @@
import com.google.gerrit.client.ErrorDialog;
import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.account.AccountInfo;
+import com.google.gerrit.client.change.Reviewers.PostInput;
+import com.google.gerrit.client.change.Reviewers.PostResult;
import com.google.gerrit.client.changes.ChangeInfo.ApprovalInfo;
import com.google.gerrit.client.changes.ChangeInfo.LabelInfo;
import com.google.gerrit.client.rpc.GerritCallback;
-import com.google.gerrit.client.rpc.NativeMap;
-import com.google.gerrit.client.rpc.NativeString;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.ui.AccountLinkPanel;
import com.google.gerrit.client.ui.AddMemberBox;
@@ -35,7 +35,6 @@
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArray;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
@@ -251,44 +250,6 @@
}
}
- public static class PostInput extends JavaScriptObject {
- public static PostInput create(String reviewer, boolean confirmed) {
- PostInput input = createObject().cast();
- input.init(reviewer, confirmed);
- return input;
- }
-
- private native void init(String reviewer, boolean confirmed) /*-{
- this.reviewer = reviewer;
- if (confirmed) {
- this.confirmed = true;
- }
- }-*/;
-
- protected PostInput() {
- }
- }
-
- public static class ReviewerInfo extends AccountInfo {
- final Set<String> approvals() {
- return Natives.keys(_approvals());
- }
- final native String approval(String l) /*-{ return this.approvals[l]; }-*/;
- private final native NativeMap<NativeString> _approvals() /*-{ return this.approvals; }-*/;
-
- protected ReviewerInfo() {
- }
- }
-
- public static class PostResult extends JavaScriptObject {
- public final native JsArray<ReviewerInfo> reviewers() /*-{ return this.reviewers; }-*/;
- public final native boolean confirm() /*-{ return this.confirm || false; }-*/;
- public final native String error() /*-{ return this.error; }-*/;
-
- protected PostResult() {
- }
- }
-
private void addReviewer(final String reviewer, boolean confirmed) {
ChangeApi.reviewers(lastChange.legacy_id().get()).post(
PostInput.create(reviewer, confirmed),
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeList.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeList.java
index ab9592c..97ba3b1 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeList.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeList.java
@@ -51,30 +51,16 @@
call.get(callback);
}
- public static void prev(String query,
- int limit, String sortkey,
- AsyncCallback<ChangeList> callback) {
- RestApi call = newQuery(query);
- if (limit > 0) {
- call.addParameter("n", limit);
- }
- addOptions(call, EnumSet.of(ListChangesOption.LABELS));
- if (!PagedSingleListScreen.MIN_SORTKEY.equals(sortkey)) {
- call.addParameter("P", sortkey);
- }
- call.get(callback);
- }
-
public static void next(String query,
- int limit, String sortkey,
+ int start, int limit,
AsyncCallback<ChangeList> callback) {
RestApi call = newQuery(query);
if (limit > 0) {
call.addParameter("n", limit);
}
addOptions(call, EnumSet.of(ListChangesOption.LABELS));
- if (!PagedSingleListScreen.MAX_SORTKEY.equals(sortkey)) {
- call.addParameter("N", sortkey);
+ if (start != 0) {
+ call.addParameter("S", start);
}
call.get(callback);
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DashboardTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DashboardTable.java
index 34b6dee..ac68722 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DashboardTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DashboardTable.java
@@ -95,7 +95,7 @@
if (queries.size() == 1) {
ChangeList.next(queries.get(0),
- 0, PagedSingleListScreen.MAX_SORTKEY,
+ 0, 0,
new GerritCallback<ChangeList>() {
@Override
public void onSuccess(ChangeList result) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PagedSingleListScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PagedSingleListScreen.java
index 8cfb09c..f98ac78 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PagedSingleListScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/PagedSingleListScreen.java
@@ -26,25 +26,19 @@
import com.google.gwtexpui.globalkey.client.KeyCommand;
public abstract class PagedSingleListScreen extends Screen {
- protected static final String MIN_SORTKEY = "";
- protected static final String MAX_SORTKEY = "z";
-
protected final int pageSize;
+ protected final int start;
+ private final String anchorPrefix;
+
+ protected ChangeList changes;
private ChangeTable2 table;
private ChangeTable2.Section section;
- protected Hyperlink prev;
- protected Hyperlink next;
- protected ChangeList changes;
+ private Hyperlink prev;
+ private Hyperlink next;
- protected final String anchorPrefix;
- protected boolean useLoadPrev;
- protected String pos;
-
- protected PagedSingleListScreen(final String anchorToken,
- final String positionToken) {
+ protected PagedSingleListScreen(String anchorToken, int start) {
anchorPrefix = anchorToken;
- useLoadPrev = positionToken.startsWith("p,");
- pos = positionToken.substring(2);
+ this.start = start;
if (Gerrit.isSignedIn()) {
final AccountGeneralPreferences p =
@@ -96,25 +90,11 @@
}
@Override
- protected void onLoad() {
- super.onLoad();
- if (useLoadPrev) {
- loadPrev();
- } else {
- loadNext();
- }
- }
-
- @Override
public void registerKeys() {
super.registerKeys();
table.setRegisterKeys(true);
}
- protected abstract void loadPrev();
-
- protected abstract void loadNext();
-
protected AsyncCallback<ChangeList> loadCallback() {
return new ScreenLoadCallback<ChangeList>(this) {
@Override
@@ -124,22 +104,20 @@
};
}
- protected void display(final ChangeList result) {
+ protected void display(ChangeList result) {
changes = result;
if (changes.length() != 0) {
- final ChangeInfo f = changes.get(0);
- final ChangeInfo l = changes.get(changes.length() - 1);
-
- prev.setTargetHistoryToken(anchorPrefix + ",p," + f._sortkey());
- next.setTargetHistoryToken(anchorPrefix + ",n," + l._sortkey());
-
- if (useLoadPrev) {
- prev.setVisible(f._more_changes());
- next.setVisible(!MIN_SORTKEY.equals(pos));
+ if (start > 0) {
+ int p = start - pageSize;
+ prev.setTargetHistoryToken(anchorPrefix + (p > 0 ? "," + p : ""));
+ prev.setVisible(true);
} else {
- prev.setVisible(!MAX_SORTKEY.equals(pos));
- next.setVisible(l._more_changes());
+ prev.setVisible(false);
}
+
+ int n = start + changes.length();
+ next.setTargetHistoryToken(anchorPrefix + "," + n);
+ next.setVisible(changes.get(changes.length() - 1)._more_changes());
}
table.updateColumnsForLabels(result);
section.display(result);
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/QueryScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/QueryScreen.java
index 12bcf63..488b34b 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/QueryScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/QueryScreen.java
@@ -25,17 +25,17 @@
public class QueryScreen extends PagedSingleListScreen implements
ChangeListScreen {
public static QueryScreen forQuery(String query) {
- return forQuery(query, PageLinks.TOP);
+ return forQuery(query, 0);
}
- public static QueryScreen forQuery(String query, String position) {
- return new QueryScreen(KeyUtil.encode(query), position);
+ public static QueryScreen forQuery(String query, int start) {
+ return new QueryScreen(KeyUtil.encode(query), start);
}
private final String query;
- public QueryScreen(final String encQuery, final String positionToken) {
- super("/q/" + encQuery, positionToken);
+ public QueryScreen(String encQuery, int start) {
+ super(PageLinks.QUERY + encQuery, start);
query = KeyUtil.decode(encQuery);
}
@@ -72,13 +72,9 @@
}
@Override
- protected void loadPrev() {
- ChangeList.prev(query, pageSize, pos, loadCallback());
- }
-
- @Override
- protected void loadNext() {
- ChangeList.next(query, pageSize, pos, loadCallback());
+ protected void onLoad() {
+ super.onLoad();
+ ChangeList.next(query, start, pageSize, loadCallback());
}
private static boolean isSingleQuery(String query) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gear.png b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gear.png
new file mode 100644
index 0000000..2f84e47
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gear.png
Binary files differ
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/DirectChangeByCommit.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/DirectChangeByCommit.java
index 7163983..402ea1b 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/DirectChangeByCommit.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/DirectChangeByCommit.java
@@ -58,9 +58,9 @@
q = Predicate.and(q, builder.sortkey_before("z"), builder.limit(2), visibleToMe);
ChangeQueryRewriter rewriter = queryRewriter.get();
- Predicate<ChangeData> s = rewriter.rewrite(q);
+ Predicate<ChangeData> s = rewriter.rewrite(q, 0);
if (!(s instanceof ChangeDataSource)) {
- s = rewriter.rewrite(Predicate.and(builder.status_open(), q));
+ s = rewriter.rewrite(Predicate.and(builder.status_open(), q), 0);
}
if (s instanceof ChangeDataSource) {
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/gitweb/GitWebServlet.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/gitweb/GitWebServlet.java
index 6aa3895..c2b0cc8 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/gitweb/GitWebServlet.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/gitweb/GitWebServlet.java
@@ -261,15 +261,15 @@
p.print(" my $h = shift;\n");
p.print(" my $q;\n");
p.print(" if (!$h || $h eq 'HEAD') {\n");
- p.print(" $q = qq{#q,project:$ENV{'GERRIT_PROJECT_NAME'},n,z};\n");
+ p.print(" $q = qq{#q,project:$ENV{'GERRIT_PROJECT_NAME'}};\n");
p.print(" } elsif ($h =~ /^refs\\/heads\\/([-\\w]+)$/) {\n");
p.print(" $q = qq{#q,project:$ENV{'GERRIT_PROJECT_NAME'}");
- p.print("+branch:$1,n,z};\n"); // wrapped
+ p.print("+branch:$1};\n"); // wrapped
p.print(" } elsif ($h =~ /^refs\\/changes\\/\\d{2}\\/(\\d+)\\/\\d+$/) ");
p.print("{\n"); // wrapped
p.print(" $q = qq{#/c/$1};\n");
p.print(" } else {\n");
- p.print(" $q = qq{#/q/$h,n,z};\n");
+ p.print(" $q = qq{#/q/$h};\n");
p.print(" }\n");
p.print(" my $r = qq{$ENV{'GERRIT_CONTEXT_PATH'}$q};\n");
p.print(" push @{$feature{'actions'}{'default'}},\n");
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/restapi/RestApiServlet.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
index 26c4206..ce450dc 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
@@ -270,7 +270,7 @@
|| "PUT".equals(req.getMethod()))) {
@SuppressWarnings("unchecked")
AcceptsCreate<RestResource> ac = (AcceptsCreate<RestResource>) c;
- viewData = new ViewData(null, ac.create(rsrc, id));
+ viewData = new ViewData(viewData.pluginName, ac.create(rsrc, id));
status = SC_CREATED;
} else {
throw e;
diff --git a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java
index 73b1be3..4150c82 100644
--- a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java
+++ b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/LuceneChangeIndex.java
@@ -48,6 +48,7 @@
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.ChangeDataSource;
import com.google.gerrit.server.query.change.ChangeQueryBuilder;
+import com.google.gerrit.server.query.change.SortKeyPredicate;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.ResultSet;
import com.google.inject.Provider;
@@ -134,6 +135,18 @@
LUCENE_VERSIONS = versions.build();
}
+ public static void setReady(SitePaths sitePaths, int version, boolean ready)
+ throws IOException {
+ try {
+ FileBasedConfig cfg =
+ LuceneVersionManager.loadGerritIndexConfig(sitePaths);
+ LuceneVersionManager.setReady(cfg, version, ready);
+ cfg.save();
+ } catch (ConfigInvalidException e) {
+ throw new IOException(e);
+ }
+ }
+
static interface Factory {
LuceneChangeIndex create(Schema<ChangeData> schema, String base);
}
@@ -288,8 +301,8 @@
}
@Override
- public ChangeDataSource getSource(Predicate<ChangeData> p, int limit)
- throws QueryParseException {
+ public ChangeDataSource getSource(Predicate<ChangeData> p, int start,
+ int limit) throws QueryParseException {
Set<Change.Status> statuses = IndexRewriteImpl.getPossibleStatus(p);
List<SubIndex> indexes = Lists.newArrayListWithCapacity(2);
if (!Sets.intersection(statuses, OPEN_STATUSES).isEmpty()) {
@@ -298,36 +311,50 @@
if (!Sets.intersection(statuses, CLOSED_STATUSES).isEmpty()) {
indexes.add(closedIndex);
}
- return new QuerySource(indexes, queryBuilder.toQuery(p), limit,
- ChangeQueryBuilder.hasNonTrivialSortKeyAfter(schema, p));
+ return new QuerySource(indexes, queryBuilder.toQuery(p), start, limit,
+ getSort(schema, p));
}
@Override
public void markReady(boolean ready) throws IOException {
- try {
- FileBasedConfig cfg = LuceneVersionManager.loadGerritIndexConfig(sitePaths);
- LuceneVersionManager.setReady(cfg, schema.getVersion(), ready);
- cfg.save();
- } catch (ConfigInvalidException e) {
- throw new IOException(e);
- }
+ setReady(sitePaths, schema.getVersion(), ready);
}
private static final ImmutableSet<String> FIELDS =
ImmutableSet.of(ID_FIELD, CHANGE_FIELD, APPROVAL_FIELD);
+ @SuppressWarnings("deprecation")
+ private static Sort getSort(Schema<ChangeData> schema,
+ Predicate<ChangeData> p) {
+ // Standard order is descending by sort key, unless reversed due to a
+ // sortkey_before predicate.
+ if (SortKeyPredicate.hasSortKeyField(schema)) {
+ boolean reverse = ChangeQueryBuilder.hasNonTrivialSortKeyAfter(schema, p);
+ return new Sort(new SortField(
+ ChangeField.SORTKEY.getName(), SortField.Type.LONG, !reverse));
+ } else {
+ return new Sort(
+ new SortField(
+ ChangeField.UPDATED.getName(), SortField.Type.LONG, true),
+ new SortField(
+ ChangeField.LEGACY_ID.getName(), SortField.Type.INT, true));
+ }
+ }
+
private class QuerySource implements ChangeDataSource {
private final List<SubIndex> indexes;
private final Query query;
+ private final int start;
private final int limit;
- private final boolean reverse;
+ private final Sort sort;
- private QuerySource(List<SubIndex> indexes, Query query, int limit,
- boolean reverse) {
+ private QuerySource(List<SubIndex> indexes, Query query, int start,
+ int limit, Sort sort) {
this.indexes = indexes;
this.query = query;
+ this.start = start;
this.limit = limit;
- this.reverse = reverse;
+ this.sort = sort;
}
@Override
@@ -348,24 +375,19 @@
@Override
public ResultSet<ChangeData> read() throws OrmException {
IndexSearcher[] searchers = new IndexSearcher[indexes.size()];
- Sort sort = new Sort(
- new SortField(
- ChangeField.SORTKEY.getName(),
- SortField.Type.LONG,
- // Standard order is descending by sort key, unless reversed due
- // to a sortkey_before predicate.
- !reverse));
try {
+ int realLimit = start + limit;
TopDocs[] hits = new TopDocs[indexes.size()];
for (int i = 0; i < indexes.size(); i++) {
searchers[i] = indexes.get(i).acquire();
- hits[i] = searchers[i].search(query, limit, sort);
+ hits[i] = searchers[i].search(query, realLimit, sort);
}
- TopDocs docs = TopDocs.merge(sort, limit, hits);
+ TopDocs docs = TopDocs.merge(sort, realLimit, hits);
List<ChangeData> result =
Lists.newArrayListWithCapacity(docs.scoreDocs.length);
- for (ScoreDoc sd : docs.scoreDocs) {
+ for (int i = start; i < docs.scoreDocs.length; i++) {
+ ScoreDoc sd = docs.scoreDocs[i];
Document doc = searchers[sd.shardIndex].doc(sd.doc, FIELDS);
result.add(toChangeData(doc));
}
@@ -456,9 +478,17 @@
doc.add(new LongField(name, (Long) value, store));
}
} else if (type == FieldType.TIMESTAMP) {
- for (Object value : values.getValues()) {
- int t = QueryBuilder.toIndexTime((Timestamp) value);
- doc.add(new IntField(name, t, store));
+ @SuppressWarnings("deprecation")
+ boolean legacy = values.getField() == ChangeField.LEGACY_UPDATED;
+ if (legacy) {
+ for (Object value : values.getValues()) {
+ int t = queryBuilder.toIndexTimeInMinutes((Timestamp) value);
+ doc.add(new IntField(name, (int) t, store));
+ }
+ } else {
+ for (Object value : values.getValues()) {
+ doc.add(new LongField(name, ((Timestamp) value).getTime(), store));
+ }
}
} else if (type == FieldType.EXACT
|| type == FieldType.PREFIX) {
diff --git a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/QueryBuilder.java b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/QueryBuilder.java
index faa9fe0..3221b8a 100644
--- a/gerrit-lucene/src/main/java/com/google/gerrit/lucene/QueryBuilder.java
+++ b/gerrit-lucene/src/main/java/com/google/gerrit/lucene/QueryBuilder.java
@@ -45,7 +45,7 @@
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.NumericUtils;
-import java.sql.Timestamp;
+import java.util.Date;
import java.util.List;
public class QueryBuilder {
@@ -179,28 +179,46 @@
false, false);
}
+ @SuppressWarnings("deprecation")
private Query timestampQuery(IndexPredicate<ChangeData> p)
throws QueryParseException {
if (p instanceof TimestampRangePredicate) {
TimestampRangePredicate<ChangeData> r =
(TimestampRangePredicate<ChangeData>) p;
- return NumericRangeQuery.newIntRange(
- r.getField().getName(),
- toIndexTime(r.getMinTimestamp()),
- toIndexTime(r.getMaxTimestamp()),
- true, true);
+ if (r.getField() == ChangeField.LEGACY_UPDATED) {
+ return NumericRangeQuery.newIntRange(
+ r.getField().getName(),
+ toIndexTimeInMinutes(r.getMinTimestamp()),
+ toIndexTimeInMinutes(r.getMaxTimestamp()),
+ true, true);
+ } else {
+ return NumericRangeQuery.newLongRange(
+ r.getField().getName(),
+ r.getMinTimestamp().getTime(),
+ r.getMaxTimestamp().getTime(),
+ true, true);
+ }
}
throw new QueryParseException("not a timestamp: " + p);
}
+ @SuppressWarnings("deprecation")
private Query notTimestamp(TimestampRangePredicate<ChangeData> r)
throws QueryParseException {
if (r.getMinTimestamp().getTime() == 0) {
- return NumericRangeQuery.newIntRange(
- r.getField().getName(),
- toIndexTime(r.getMaxTimestamp()),
- null,
- true, true);
+ if (r.getField() == ChangeField.LEGACY_UPDATED) {
+ return NumericRangeQuery.newIntRange(
+ r.getField().getName(),
+ toIndexTimeInMinutes(r.getMaxTimestamp()),
+ null,
+ true, true);
+ } else {
+ return NumericRangeQuery.newLongRange(
+ r.getField().getName(),
+ r.getMaxTimestamp().getTime(),
+ null,
+ true, true);
+ }
}
throw new QueryParseException("cannot negate: " + r);
}
@@ -232,7 +250,7 @@
return queryBuilder.createPhraseQuery(p.getField().getName(), p.getValue());
}
- public static int toIndexTime(Timestamp ts) {
+ public int toIndexTimeInMinutes(Date ts) {
return (int) (ts.getTime() / 60000);
}
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
index aba492d..9d10e66 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java
@@ -71,8 +71,7 @@
import com.google.gerrit.sshd.SshHostKeyModule;
import com.google.gerrit.sshd.SshKeyCacheImpl;
import com.google.gerrit.sshd.SshModule;
-import com.google.gerrit.sshd.commands.MasterCommandModule;
-import com.google.gerrit.sshd.commands.SlaveCommandModule;
+import com.google.gerrit.sshd.commands.DefaultCommandModule;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
@@ -155,6 +154,10 @@
this.serverStarted = serverStarted;
}
+ public void setEnableHttpd(boolean enable) {
+ httpd = enable;
+ }
+
@Override
public int run() throws Exception {
if (doInit) {
@@ -378,11 +381,8 @@
if (!test) {
modules.add(new SshHostKeyModule());
}
- if (slave) {
- modules.add(new SlaveCommandModule());
- } else {
- modules.add(new MasterCommandModule());
- }
+ modules.add(new DefaultCommandModule(slave));
+
return sysInjector.createChildInjector(modules);
}
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Reindex.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Reindex.java
index 5b59a25..2b0850e 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Reindex.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Reindex.java
@@ -143,11 +143,15 @@
sysManager.start();
index = sysInjector.getInstance(IndexCollection.class).getSearchIndex();
- index.markReady(false);
- index.deleteAll();
- int result = indexAll();
- index.markReady(true);
-
+ int result = 0;
+ try {
+ index.markReady(false);
+ index.deleteAll();
+ result = indexAll();
+ index.markReady(true);
+ } catch (Exception e) {
+ throw die(e.getMessage());
+ }
sysManager.stop();
dbManager.stop();
return result;
@@ -191,8 +195,26 @@
// once, so don't worry about cache removal.
bind(new TypeLiteral<DynamicSet<CacheRemovalListener>>() {})
.toInstance(DynamicSet.<CacheRemovalListener> emptySet());
+ bind(new TypeLiteral<List<CommentLinkInfo>>() {})
+ .toProvider(CommentLinkProvider.class).in(SINGLETON);
+ bind(String.class).annotatedWith(CanonicalWebUrl.class)
+ .toProvider(CanonicalWebUrlProvider.class);
+ bind(IdentifiedUser.class)
+ .toProvider(Providers. <IdentifiedUser>of(null));
+ bind(CurrentUser.class).to(IdentifiedUser.class);
+ install(new AccessControlModule());
install(new DefaultCacheFactory.Module());
+ install(new GroupModule());
+ install(new PrologModule());
+ install(AccountByEmailCacheImpl.module());
+ install(AccountCacheImpl.module());
+ install(GroupCacheImpl.module());
+ install(GroupIncludeCacheImpl.module());
+ install(ProjectCacheImpl.module());
+ install(SectionSortCache.module());
+ factory(CapabilityControl.Factory.class);
factory(ChangeData.Factory.class);
+ factory(ProjectState.Factory.class);
if (recheckMergeable) {
install(new MergeabilityModule());
@@ -250,38 +272,20 @@
private static class MergeabilityModule extends FactoryModule {
@Override
public void configure() {
- factory(ProjectState.Factory.class);
- bind(new TypeLiteral<List<CommentLinkInfo>>() {})
- .toProvider(CommentLinkProvider.class).in(SINGLETON);
- bind(IdentifiedUser.class).toProvider(Providers.<IdentifiedUser>of(null));
- bind(CurrentUser.class).to(IdentifiedUser.class);
- bind(String.class).annotatedWith(CanonicalWebUrl.class)
- .toProvider(CanonicalWebUrlProvider.class);
-
factory(PatchSetInserter.Factory.class);
bind(ChangeHooks.class).to(DisabledChangeHooks.class);
bind(ReplacePatchSetSender.Factory.class).toProvider(
Providers.<ReplacePatchSetSender.Factory>of(null));
- factory(CapabilityControl.Factory.class);
factory(MergeUtil.Factory.class);
DynamicSet.setOf(binder(), GitReferenceUpdatedListener.class);
DynamicSet.setOf(binder(), CommitValidationListener.class);
factory(CommitValidators.Factory.class);
- install(AccountCacheImpl.module());
- install(AccountByEmailCacheImpl.module());
install(ChangeKindCache.module());
- install(GroupCacheImpl.module());
- install(GroupIncludeCacheImpl.module());
- install(ProjectCacheImpl.module());
- install(SectionSortCache.module());
- install(new AccessControlModule());
install(new GitModule());
- install(new GroupModule());
install(new NoteDbModule());
- install(new PrologModule());
}
@Provides
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitIndex.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitIndex.java
index b4d3ae4..9966fda 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitIndex.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/init/InitIndex.java
@@ -14,47 +14,15 @@
package com.google.gerrit.pgm.init;
-import com.google.common.collect.Sets;
import com.google.gerrit.lucene.LuceneChangeIndex;
-import com.google.gerrit.lucene.LuceneIndexModule;
import com.google.gerrit.pgm.util.ConsoleUI;
-import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.client.Project.NameKey;
-import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.config.FactoryModule;
-import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
-import com.google.gerrit.server.config.TrackingFooter;
-import com.google.gerrit.server.config.TrackingFooters;
-import com.google.gerrit.server.git.GitRepositoryManager;
-import com.google.gerrit.server.index.ChangeIndex;
import com.google.gerrit.server.index.ChangeSchemas;
import com.google.gerrit.server.index.IndexModule.IndexType;
-import com.google.gerrit.server.patch.IntraLineDiff;
-import com.google.gerrit.server.patch.IntraLineDiffKey;
-import com.google.gerrit.server.patch.PatchList;
-import com.google.gerrit.server.patch.PatchListCache;
-import com.google.gerrit.server.patch.PatchListKey;
-import com.google.gerrit.server.patch.PatchListNotAvailableException;
-import com.google.gerrit.server.query.change.ChangeData;
-import com.google.gwtorm.server.OrmException;
-import com.google.gwtorm.server.SchemaFactory;
-import com.google.inject.Guice;
import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.Provides;
-import com.google.inject.ProvisionException;
import com.google.inject.Singleton;
-import org.eclipse.jgit.errors.RepositoryNotFoundException;
-import org.eclipse.jgit.lib.Config;
-import org.eclipse.jgit.lib.Repository;
-
import java.io.IOException;
-import java.util.Collections;
-import java.util.SortedSet;
/** Initialize the {@code index} configuration section. */
@Singleton
@@ -79,105 +47,22 @@
ui.header("Index");
IndexType type = index.select("Type", "type", IndexType.LUCENE);
+ if (type == IndexType.SOLR) {
+ index.string("Solr Index URL", "url", "localhost:9983");
+ }
if (site.isNew && type == IndexType.LUCENE) {
- createLuceneIndex();
+ LuceneChangeIndex.setReady(
+ site, ChangeSchemas.getLatest().getVersion(), true);
} else {
- ui.message("The index must be built before starting Gerrit:\n"
- + " java -jar gerrit.war reindex -d site_path\n");
+ final String message = String.format(
+ "\nThe index must be %sbuilt before starting Gerrit:\n"
+ + " java -jar gerrit.war reindex -d site_path\n",
+ site.isNew ? "" : "re");
+ ui.message(message);
initFlags.autoStart = false;
}
}
- private void createLuceneIndex() throws IOException {
- Injector injector = Guice.createInjector(
- new LuceneIndexModule(ChangeSchemas.getLatest().getVersion(), 0, null),
- new MockIndexSupportModule());
-
- ChangeIndex index = injector.getInstance(LuceneChangeIndex.class);
- index.markReady(true);
- index.close();
- }
-
- private class MockIndexSupportModule extends FactoryModule {
- @Override
- protected void configure() {
- bind(SitePaths.class).toInstance(site);
- factory(ChangeData.Factory.class);
- }
-
- @Provides @GerritServerConfig Config getConfig() {
- return new Config();
- }
-
- @Provides TrackingFooters newTrackingFooters() {
- return new TrackingFooters(Collections.<TrackingFooter> emptyList());
- }
-
- @Provides ReviewDb getReviewDb() {
- throw new ProvisionException("database not initialized");
- }
-
- @Provides SchemaFactory<ReviewDb> getSchemaFactory() {
- return new SchemaFactory<ReviewDb>() {
- @Override
- public ReviewDb open() throws OrmException {
- return getReviewDb();
- }
- };
- }
-
- @Provides GitRepositoryManager getGitRepositoryManager() {
- return new GitRepositoryManager() {
- @Override
- public Repository openRepository(Project.NameKey name)
- throws RepositoryNotFoundException{
- throw new RepositoryNotFoundException(name.get());
- }
-
- @Override
- public Repository createRepository(Project.NameKey name)
- throws RepositoryNotFoundException {
- throw new RepositoryNotFoundException(name.get());
- }
-
- @Override
- public SortedSet<Project.NameKey> list() {
- return Sets.newTreeSet();
- }
-
- @Override
- public String getProjectDescription(Project.NameKey name) {
- return null;
- }
-
- @Override
- public void setProjectDescription(NameKey name, String description) {
- }
- };
- }
-
- @Provides PatchListCache newPatchListCache() {
- return new PatchListCache() {
- @Override
- public PatchList get(PatchListKey key)
- throws PatchListNotAvailableException {
- throw new PatchListNotAvailableException("new site, no changes");
- }
-
- @Override
- public PatchList get(Change change, PatchSet patchSet)
- throws PatchListNotAvailableException {
- throw new PatchListNotAvailableException("new site, no changes");
- }
-
- @Override
- public IntraLineDiff getIntraLineDiff(IntraLineDiffKey key) {
- return null;
- }
- };
- }
- }
-
@Override
public void postRun() throws Exception {
}
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteLibraryBasedDataSourceProvider.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteLibraryBasedDataSourceProvider.java
index 6ab7395..0614b53 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteLibraryBasedDataSourceProvider.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteLibraryBasedDataSourceProvider.java
@@ -14,7 +14,6 @@
package com.google.gerrit.pgm.util;
-import com.google.common.primitives.Longs;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.schema.DataSourceProvider;
@@ -68,7 +67,7 @@
@Override
public int compare(File a, File b) {
// Sort by reverse last-modified time so newer JARs are first.
- int cmp = Longs.compare(b.lastModified(), a.lastModified());
+ int cmp = Long.compare(b.lastModified(), a.lastModified());
if (cmp != 0) {
return cmp;
}
diff --git a/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/rpc/NativeString.java b/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/rpc/NativeString.java
index fe65857..13c8b1d 100644
--- a/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/rpc/NativeString.java
+++ b/gerrit-plugin-gwtui/src/main/java/com/google/gerrit/plugin/client/rpc/NativeString.java
@@ -25,7 +25,7 @@
/*-{ return $wnd.Gerrit.JsonString }-*/;
public final native String asString()
- /*-{ return this.get(); }-*/;
+ /*-{ return this; }-*/;
public static final
AsyncCallback<NativeString> unwrap(final AsyncCallback<String> cb) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java
index e57dc7f..939be28 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java
@@ -86,7 +86,7 @@
* We overrun approximately 4,083 years later, so ~6092.
*/
@VisibleForTesting
- public static final long SORT_KEY_EPOCH_MINS =
+ private static final long SORT_KEY_EPOCH_MINS =
MINUTES.convert(1222819200L, SECONDS);
private static final Object uuidLock = new Object();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountsCollection.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountsCollection.java
index 7d3c06e..213ecd1 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountsCollection.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountsCollection.java
@@ -59,7 +59,7 @@
@Override
public AccountResource parse(TopLevelResource root, IdString id)
throws ResourceNotFoundException, AuthException, OrmException {
- IdentifiedUser user = _parse(id.get());
+ IdentifiedUser user = parseId(id.get());
if (user == null) {
throw new ResourceNotFoundException(id);
} else if (!accountControlFactory.get().canSee(user.getAccount())) {
@@ -81,18 +81,33 @@
*/
public IdentifiedUser parse(String id) throws AuthException,
UnprocessableEntityException, OrmException {
- IdentifiedUser user = _parse(id);
+ IdentifiedUser user = parseId(id);
if (user == null) {
throw new UnprocessableEntityException(String.format(
"Account Not Found: %s", id));
+ } else if (!accountControlFactory.get().canSee(user.getAccount())) {
+ throw new UnprocessableEntityException(String.format(
+ "Account Not Found: %s", id));
}
return user;
}
- private IdentifiedUser _parse(String id) throws AuthException, OrmException {
- CurrentUser user = self.get();
-
+ /**
+ * Parses an account ID and returns the user without making any permission
+ * check whether the current user can see the account.
+ *
+ * @param id ID of the account, can be a string of the format
+ * "Full Name <email@example.com>", just the email address, a full name
+ * if it is unique, an account ID, a user name or 'self' for the
+ * calling user
+ * @return the user, null if no user is found for the given account ID
+ * @throws AuthException thrown if 'self' is used as account ID and the
+ * current user is not authenticated
+ * @throws OrmException
+ */
+ public IdentifiedUser parseId(String id) throws AuthException, OrmException {
if (id.equals("self")) {
+ CurrentUser user = self.get();
if (user.isIdentifiedUser()) {
return (IdentifiedUser) user;
} else if (user instanceof AnonymousUser) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/AddSshKey.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/AddSshKey.java
index 0d672d1..4d73fe1 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/AddSshKey.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/AddSshKey.java
@@ -26,6 +26,7 @@
import com.google.gerrit.reviewdb.client.AccountSshKey;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AddSshKey.Input;
import com.google.gerrit.server.account.GetSshKeys.SshKeyInfo;
import com.google.gerrit.server.ssh.SshKeyCache;
@@ -61,6 +62,11 @@
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("not allowed to add SSH keys");
}
+ return apply(rsrc.getUser(), input);
+ }
+
+ public Response<SshKeyInfo> apply(IdentifiedUser user, Input input)
+ throws BadRequestException, OrmException, IOException {
if (input == null) {
input = new Input();
}
@@ -70,7 +76,7 @@
int max = 0;
for (AccountSshKey k : dbProvider.get().accountSshKeys()
- .byAccount(rsrc.getUser().getAccountId())) {
+ .byAccount(user.getAccountId())) {
max = Math.max(max, k.getKey().get());
}
@@ -85,9 +91,9 @@
try {
AccountSshKey sshKey =
sshKeyCache.create(new AccountSshKey.Id(
- rsrc.getUser().getAccountId(), max + 1), sshPublicKey);
+ user.getAccountId(), max + 1), sshPublicKey);
dbProvider.get().accountSshKeys().insert(Collections.singleton(sshKey));
- sshKeyCache.evict(rsrc.getUser().getUserName());
+ sshKeyCache.evict(user.getUserName());
return Response.<SshKeyInfo>created(new SshKeyInfo(sshKey));
} catch (InvalidSshKeyException e) {
throw new BadRequestException(e.getMessage());
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityControl.java
index c5ccaf0..beef976 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/CapabilityControl.java
@@ -204,7 +204,11 @@
/** True if the user has this permission. Works only for non labels. */
public boolean canPerform(String permissionName) {
- return !access(permissionName).isEmpty();
+ if (GlobalCapability.ADMINISTRATE_SERVER.equals(permissionName)) {
+ return canAdministrateServer();
+ } else {
+ return !access(permissionName).isEmpty();
+ }
}
/** The range of permitted values associated with a label permission. */
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/CreateAccount.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/CreateAccount.java
index 3b03c3a..b657281 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/CreateAccount.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/CreateAccount.java
@@ -41,6 +41,7 @@
import com.google.gwtorm.server.OrmDuplicateKeyException;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
+import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted;
import java.util.Collections;
@@ -64,7 +65,7 @@
}
private final ReviewDb db;
- private final IdentifiedUser currentUser;
+ private final Provider<IdentifiedUser> currentUser;
private final GroupsCollection groupsCollection;
private final SshKeyCache sshKeyCache;
private final AccountCache accountCache;
@@ -73,7 +74,7 @@
private final String username;
@Inject
- CreateAccount(ReviewDb db, IdentifiedUser currentUser,
+ CreateAccount(ReviewDb db, Provider<IdentifiedUser> currentUser,
GroupsCollection groupsCollection, SshKeyCache sshKeyCache,
AccountCache accountCache, AccountByEmailCache byEmailCache,
AccountInfo.Loader.Factory infoLoader,
@@ -164,7 +165,7 @@
new AccountGroupMember(new AccountGroupMember.Key(id, groupId));
db.accountGroupMembersAudit().insert(Collections.singleton(
new AccountGroupMemberAudit(
- m, currentUser.getAccountId(), TimeUtil.nowTs())));
+ m, currentUser.get().getAccountId(), TimeUtil.nowTs())));
db.accountGroupMembers().insert(Collections.singleton(m));
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/CreateEmail.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/CreateEmail.java
index 675ab96..b9ef19e 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/CreateEmail.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/CreateEmail.java
@@ -26,6 +26,7 @@
import com.google.gerrit.reviewdb.client.AuthType;
import com.google.gerrit.reviewdb.client.Account.FieldName;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.CreateEmail.Input;
import com.google.gerrit.server.account.GetEmails.EmailInfo;
import com.google.gerrit.server.config.AuthConfig;
@@ -87,36 +88,43 @@
throw new AuthException("not allowed to add email address");
}
- if (!realm.allowsEdit(FieldName.REGISTER_NEW_EMAIL)) {
- throw new MethodNotAllowedException("realm does not allow adding emails");
- }
-
if (input == null) {
input = new Input();
}
- if (input.email != null && !email.equals(input.email)) {
- throw new BadRequestException("email address must match URL");
- }
-
if (input.noConfirmation
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("must be administrator to use no_confirmation");
}
+ return apply(rsrc.getUser(), input);
+ }
+
+ public Response<EmailInfo> apply(IdentifiedUser user, Input input)
+ throws AuthException, BadRequestException, ResourceConflictException,
+ ResourceNotFoundException, OrmException, EmailException,
+ MethodNotAllowedException {
+ if (!realm.allowsEdit(FieldName.REGISTER_NEW_EMAIL)) {
+ throw new MethodNotAllowedException("realm does not allow adding emails");
+ }
+
+ if (input.email != null && !email.equals(input.email)) {
+ throw new BadRequestException("email address must match URL");
+ }
+
EmailInfo info = new EmailInfo();
info.email = email;
if (input.noConfirmation
|| authConfig.getAuthType() == AuthType.DEVELOPMENT_BECOME_ANY_ACCOUNT) {
try {
- accountManager.link(rsrc.getUser().getAccountId(),
+ accountManager.link(user.getAccountId(),
AuthRequest.forEmail(email));
} catch (AccountException e) {
throw new ResourceConflictException(e.getMessage());
}
if (input.preferred) {
putPreferredProvider.get().apply(
- new AccountResource.Email(rsrc.getUser(), email),
+ new AccountResource.Email(user, email),
null);
info.preferred = true;
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteEmail.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteEmail.java
index b38c49b..5e0597b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteEmail.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/DeleteEmail.java
@@ -24,6 +24,7 @@
import com.google.gerrit.reviewdb.client.AccountExternalId;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.DeleteEmail.Input;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
@@ -55,18 +56,24 @@
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("not allowed to delete email address");
}
+ return apply(rsrc.getUser(), rsrc.getEmail());
+ }
+
+ public Response<?> apply(IdentifiedUser user, String email)
+ throws ResourceNotFoundException, ResourceConflictException,
+ MethodNotAllowedException, OrmException {
if (!realm.allowsEdit(FieldName.REGISTER_NEW_EMAIL)) {
throw new MethodNotAllowedException("realm does not allow deleting emails");
}
AccountExternalId.Key key = new AccountExternalId.Key(
- AccountExternalId.SCHEME_MAILTO, rsrc.getEmail());
+ AccountExternalId.SCHEME_MAILTO, email);
AccountExternalId extId = dbProvider.get().accountExternalIds().get(key);
if (extId == null) {
- throw new ResourceNotFoundException(rsrc.getEmail());
+ throw new ResourceNotFoundException(email);
}
try {
- accountManager.unlink(rsrc.getUser().getAccountId(),
- AuthRequest.forEmail(rsrc.getEmail()));
+ accountManager.unlink(user.getAccountId(),
+ AuthRequest.forEmail(email));
} catch (AccountException e) {
throw new ResourceConflictException(e.getMessage());
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/GetSshKeys.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/GetSshKeys.java
index f198b77..8c878d75 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/GetSshKeys.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/GetSshKeys.java
@@ -21,6 +21,7 @@
import com.google.gerrit.reviewdb.client.AccountSshKey;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.IdentifiedUser;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -45,10 +46,13 @@
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("not allowed to get SSH keys");
}
+ return apply(rsrc.getUser());
+ }
+ public List<SshKeyInfo> apply(IdentifiedUser user) throws OrmException {
List<SshKeyInfo> sshKeys = Lists.newArrayList();
for (AccountSshKey sshKey : dbProvider.get().accountSshKeys()
- .byAccount(rsrc.getUser().getAccountId()).toList()) {
+ .byAccount(user.getAccountId()).toList()) {
sshKeys.add(new SshKeyInfo(sshKey));
}
return sshKeys;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutHttpPassword.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutHttpPassword.java
index 0601b8d..f7061e3 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutHttpPassword.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutHttpPassword.java
@@ -25,6 +25,7 @@
import com.google.gerrit.reviewdb.client.AccountExternalId;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.PutHttpPassword.Input;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
@@ -94,21 +95,24 @@
}
newPassword = input.httpPassword;
}
+ return apply(rsrc.getUser(), newPassword);
+ }
- if (rsrc.getUser().getUserName() == null) {
+ public Response<String> apply(IdentifiedUser user, String newPassword)
+ throws ResourceNotFoundException, ResourceConflictException, OrmException {
+ if (user.getUserName() == null) {
throw new ResourceConflictException("username must be set");
}
AccountExternalId id = dbProvider.get().accountExternalIds()
.get(new AccountExternalId.Key(
- SCHEME_USERNAME,
- rsrc.getUser().getUserName()));
+ SCHEME_USERNAME, user.getUserName()));
if (id == null) {
throw new ResourceNotFoundException();
}
id.setPassword(newPassword);
dbProvider.get().accountExternalIds().update(Collections.singleton(id));
- accountCache.evict(rsrc.getUser().getAccountId());
+ accountCache.evict(user.getAccountId());
return Strings.isNullOrEmpty(newPassword)
? Response.<String>none()
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutName.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutName.java
index 50497c7..6f3c032 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutName.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutName.java
@@ -25,6 +25,7 @@
import com.google.gerrit.reviewdb.client.Account.FieldName;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.PutName.Input;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
@@ -60,7 +61,11 @@
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("not allowed to change name");
}
+ return apply(rsrc.getUser(), input);
+ }
+ public Response<String> apply(IdentifiedUser user, Input input)
+ throws MethodNotAllowedException, ResourceNotFoundException, OrmException {
if (!realm.allowsEdit(FieldName.FULL_NAME)) {
throw new MethodNotAllowedException("realm does not allow editing name");
}
@@ -69,7 +74,7 @@
input = new Input();
}
- Account a = dbProvider.get().accounts().get(rsrc.getUser().getAccountId());
+ Account a = dbProvider.get().accounts().get(user.getAccountId());
if (a == null) {
throw new ResourceNotFoundException("account not found");
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutPreferred.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutPreferred.java
index d81f361..8fc2e6c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/PutPreferred.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/PutPreferred.java
@@ -21,6 +21,7 @@
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.PutPreferred.Input;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
@@ -52,15 +53,19 @@
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new AuthException("not allowed to set preferred email address");
}
+ return apply(rsrc.getUser(), rsrc.getEmail());
+ }
- Account a = dbProvider.get().accounts().get(rsrc.getUser().getAccountId());
+ public Response<String> apply(IdentifiedUser user, String email)
+ throws ResourceNotFoundException, OrmException {
+ Account a = dbProvider.get().accounts().get(user.getAccountId());
if (a == null) {
throw new ResourceNotFoundException("account not found");
}
- if (rsrc.getEmail().equals(a.getPreferredEmail())) {
+ if (email.equals(a.getPreferredEmail())) {
return Response.ok("");
}
- a.setPreferredEmail(rsrc.getEmail());
+ a.setPreferredEmail(email);
dbProvider.get().accounts().update(Collections.singleton(a));
byIdCache.evict(a.getId());
return Response.created("");
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/SshKeys.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/SshKeys.java
index 5578c3f..69acd1e 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/SshKeys.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/SshKeys.java
@@ -22,6 +22,7 @@
import com.google.gerrit.reviewdb.client.AccountSshKey;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.IdentifiedUser;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -55,16 +56,20 @@
&& !self.get().getCapabilities().canAdministrateServer()) {
throw new ResourceNotFoundException();
}
+ return parse(rsrc.getUser(), id);
+ }
+ public AccountResource.SshKey parse(IdentifiedUser user, IdString id)
+ throws ResourceNotFoundException, OrmException {
try {
int seq = Integer.parseInt(id.get(), 10);
AccountSshKey sshKey =
dbProvider.get().accountSshKeys()
- .get(new AccountSshKey.Id(rsrc.getUser().getAccountId(), seq));
+ .get(new AccountSshKey.Id(user.getAccountId(), seq));
if (sshKey == null) {
throw new ResourceNotFoundException(id);
}
- return new AccountResource.SshKey(rsrc.getUser(), sshKey);
+ return new AccountResource.SshKey(user, sshKey);
} catch (NumberFormatException e) {
throw new ResourceNotFoundException(id);
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
index 0817250..0bcfd65 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
@@ -170,4 +170,14 @@
throw new RestApiException("Cannot retrieve change", e);
}
}
+
+ @Override
+ public ChangeInfo get() throws RestApiException {
+ return get(EnumSet.allOf(ListChangesOption.class));
+ }
+
+ @Override
+ public ChangeInfo info() throws RestApiException {
+ return get(EnumSet.noneOf(ListChangesOption.class));
+ }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeInfoMapper.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeInfoMapper.java
index 1459b03..4faae5d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeInfoMapper.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeInfoMapper.java
@@ -118,9 +118,11 @@
lo.value = li.value;
lo.optional = li.optional;
lo.values = li.values;
- lo.all = Lists.newArrayListWithExpectedSize(li.all.size());
- for (ChangeJson.ApprovalInfo ai : li.all) {
- lo.all.add(fromApprovalInfo(ai));
+ if (li.all != null) {
+ lo.all = Lists.newArrayListWithExpectedSize(li.all.size());
+ for (ChangeJson.ApprovalInfo ai : li.all) {
+ lo.all.add(fromApprovalInfo(ai));
+ }
}
r.put(e.getKey(), lo);
}
@@ -141,6 +143,9 @@
private static AccountInfo fromAcountInfo(
com.google.gerrit.server.account.AccountInfo i) {
+ if (i == null) {
+ return null;
+ }
AccountInfo ai = new AccountInfo();
fromAccount(i, ai);
return ai;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Abandon.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Abandon.java
index a42827a..33d161c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Abandon.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Abandon.java
@@ -77,6 +77,8 @@
throw new AuthException("abandon not permitted");
} else if (!change.getStatus().isOpen()) {
throw new ResourceConflictException("change is " + status(change));
+ } else if (change.getStatus() == Change.Status.DRAFT) {
+ throw new ResourceConflictException("draft changes cannot be abandoned");
}
ChangeMessage message;
@@ -133,6 +135,7 @@
.setLabel("Abandon")
.setTitle("Abandon the change")
.setVisible(resource.getChange().getStatus().isOpen()
+ && resource.getChange().getStatus() != Change.Status.DRAFT
&& resource.getControl().canAbandon());
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java
index 5da693d..1236985 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java
@@ -86,6 +86,7 @@
import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.project.ChangeControl;
+import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.query.change.ChangeData;
@@ -226,6 +227,9 @@
private ChangeInfo format(ChangeData cd, Optional<PatchSet.Id> limitToPsId)
throws OrmException {
accountLoader = accountLoaderFactory.create(has(DETAILED_ACCOUNTS));
+ if (has(REVIEWED)) {
+ ensureReviewedLoaded(Collections.singleton(cd));
+ }
ChangeInfo res = toChangeInfo(cd, limitToPsId);
accountLoader.fill();
return res;
@@ -349,22 +353,20 @@
}
private ChangeControl control(ChangeData cd) throws OrmException {
- ChangeControl ctrl = cd.changeControl();
- if (ctrl != null && ctrl.getCurrentUser() == userProvider.get()) {
- return ctrl;
- } else if (lastControl != null
+ if (lastControl != null
&& cd.getId().equals(lastControl.getChange().getId())) {
return lastControl;
}
-
+ ChangeControl ctrl;
try {
- Change change = cd.change();
- if (change == null) {
- return null;
+ if (cd.hasChangeControl()) {
+ ctrl = cd.changeControl().forUser(userProvider.get());
+ } else {
+ ctrl = projectControls.get(cd.change().getProject())
+ .controlFor(cd.change());
}
- ctrl = projectControls.get(change.getProject()).controlFor(change);
- } catch (ExecutionException e) {
- return null;
+ } catch (NoSuchChangeException | ExecutionException e) {
+ throw new OrmException(e);
}
lastControl = ctrl;
return ctrl;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/CherryPickChange.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/CherryPickChange.java
index 22d3e9a..45e57fa 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/CherryPickChange.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/CherryPickChange.java
@@ -135,7 +135,8 @@
ChangeIdUtil
.computeChangeId(commitToCherryPick.getTree(), mergeTip,
commitToCherryPick.getAuthorIdent(), myIdent, message);
- String commitMessage = ChangeIdUtil.insertId(message, computedChangeId);
+ String commitMessage =
+ ChangeIdUtil.insertId(message, computedChangeId).trim() + '\n';
RevCommit cherryPickCommit;
ObjectInserter oi = git.newObjectInserter();
@@ -149,8 +150,7 @@
}
if (cherryPickCommit == null) {
- throw new MergeException(
- "Could not create a merge commit during the cherry pick");
+ throw new MergeException("Cherry pick failed");
}
Change.Key changeKey;
@@ -170,7 +170,7 @@
if (destChanges.size() > 1) {
throw new InvalidChangeOperationException("Several changes with key "
- + changeKey + " resides on the same branch. "
+ + changeKey + " reside on the same branch. "
+ "Cannot create a new patch set.");
} else if (destChanges.size() == 1) {
// The change key exists on the destination branch. The cherry pick
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java
index a975c9c..4e45b1e 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java
@@ -309,16 +309,14 @@
}
List<PatchLineComment> del = Lists.newArrayList();
- List<PatchLineComment> ins = Lists.newArrayList();
- List<PatchLineComment> upd = Lists.newArrayList();
+ List<PatchLineComment> ups = Lists.newArrayList();
for (Map.Entry<String, List<Comment>> ent : in.entrySet()) {
String path = ent.getKey();
for (Comment c : ent.getValue()) {
String parent = Url.decode(c.inReplyTo);
PatchLineComment e = drafts.remove(Url.decode(c.id));
- boolean create = e == null;
- if (create) {
+ if (e == null) {
e = new PatchLineComment(
new PatchLineComment.Key(
new Patch.Key(rsrc.getPatchSet().getId(), path),
@@ -340,7 +338,7 @@
c.range.endLine,
c.range.endCharacter));
}
- (create ? ins : upd).add(e);
+ ups.add(e);
}
}
@@ -355,16 +353,14 @@
for (PatchLineComment e : drafts.values()) {
e.setStatus(PatchLineComment.Status.PUBLISHED);
e.setWrittenOn(timestamp);
- upd.add(e);
+ ups.add(e);
}
break;
}
db.get().patchComments().delete(del);
- db.get().patchComments().insert(ins);
- db.get().patchComments().update(upd);
- comments.addAll(ins);
- comments.addAll(upd);
- return !del.isEmpty() || !ins.isEmpty() || !upd.isEmpty();
+ db.get().patchComments().upsert(ups);
+ comments.addAll(ups);
+ return !del.isEmpty() || !ups.isEmpty();
}
private Map<String, PatchLineComment> scanDraftComments(
@@ -385,8 +381,7 @@
}
List<PatchSetApproval> del = Lists.newArrayList();
- List<PatchSetApproval> ins = Lists.newArrayList();
- List<PatchSetApproval> upd = Lists.newArrayList();
+ List<PatchSetApproval> ups = Lists.newArrayList();
Map<String, PatchSetApproval> current = scanLabels(rsrc, del);
LabelTypes labelTypes = rsrc.getControl().getLabelTypes();
@@ -412,7 +407,7 @@
} else if (c != null && c.getValue() != ent.getValue()) {
c.setValue(ent.getValue());
c.setGranted(timestamp);
- upd.add(c);
+ ups.add(c);
addLabelDelta(normName, c.getValue());
categories.put(normName, c.getValue());
update.putApproval(ent.getKey(), ent.getValue());
@@ -425,24 +420,23 @@
lt.getLabelId()),
ent.getValue(), TimeUtil.nowTs());
c.setGranted(timestamp);
- ins.add(c);
+ ups.add(c);
addLabelDelta(normName, c.getValue());
categories.put(normName, c.getValue());
update.putApproval(ent.getKey(), ent.getValue());
}
}
- forceCallerAsReviewer(rsrc, current, ins, upd, del);
+ forceCallerAsReviewer(rsrc, current, ups, del);
db.get().patchSetApprovals().delete(del);
- db.get().patchSetApprovals().insert(ins);
- db.get().patchSetApprovals().update(upd);
- return !del.isEmpty() || !ins.isEmpty() || !upd.isEmpty();
+ db.get().patchSetApprovals().upsert(ups);
+ return !del.isEmpty() || !ups.isEmpty();
}
private void forceCallerAsReviewer(RevisionResource rsrc,
- Map<String, PatchSetApproval> current, List<PatchSetApproval> ins,
- List<PatchSetApproval> upd, List<PatchSetApproval> del) {
- if (current.isEmpty() && ins.isEmpty() && upd.isEmpty()) {
+ Map<String, PatchSetApproval> current, List<PatchSetApproval> ups,
+ List<PatchSetApproval> del) {
+ if (current.isEmpty() && ups.isEmpty()) {
// TODO Find another way to link reviewers to changes.
if (del.isEmpty()) {
// If no existing label is being set to 0, hack in the caller
@@ -454,7 +448,7 @@
.getLabelId()),
(short) 0, TimeUtil.nowTs());
c.setGranted(timestamp);
- ins.add(c);
+ ups.add(c);
} else {
// Pick a random label that is about to be deleted and keep it.
Iterator<PatchSetApproval> i = del.iterator();
@@ -462,7 +456,7 @@
c.setValue((short) 0);
c.setGranted(timestamp);
i.remove();
- upd.add(c);
+ ups.add(c);
}
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/RebaseChange.java b/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/RebaseChange.java
index 66af2f1..b0fe0b5 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/RebaseChange.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/changedetail/RebaseChange.java
@@ -292,7 +292,7 @@
rebasedCommit = revWalk.parseCommit(newId);
final ChangeControl changeControl =
- changeControlFactory.validateFor(change.getId(), uploader);
+ changeControlFactory.validateFor(change, uploader);
PatchSetInserter patchSetInserter = patchSetInserterFactory
.create(git, revWalk, changeControl, rebasedCommit)
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/CherryPick.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/CherryPick.java
index a72297d..56a5ae1 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/CherryPick.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/CherryPick.java
@@ -22,8 +22,10 @@
import com.google.gerrit.reviewdb.client.RevId;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil;
+import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
+import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.util.TimeUtil;
import com.google.gwtorm.server.OrmException;
@@ -118,29 +120,30 @@
}
}
- } catch (IOException e) {
- throw new MergeException("Cannot merge " + n.name(), e);
- } catch (OrmException e) {
+ } catch (NoSuchChangeException | IOException | OrmException e) {
throw new MergeException("Cannot merge " + n.name(), e);
}
}
return newMergeTip;
}
- private CodeReviewCommit writeCherryPickCommit(final CodeReviewCommit mergeTip, final CodeReviewCommit n)
- throws IOException, OrmException {
+ private CodeReviewCommit writeCherryPickCommit(CodeReviewCommit mergeTip,
+ CodeReviewCommit n) throws IOException, OrmException,
+ NoSuchChangeException {
args.rw.parseBody(n);
final PatchSetApproval submitAudit = args.mergeUtil.getSubmitter(n);
+ IdentifiedUser cherryPickUser;
PersonIdent cherryPickCommitterIdent;
if (submitAudit != null) {
- cherryPickCommitterIdent =
- args.identifiedUserFactory.create(submitAudit.getAccountId())
- .newCommitterIdent(submitAudit.getGranted(),
- args.myIdent.getTimeZone());
+ cherryPickUser =
+ args.identifiedUserFactory.create(submitAudit.getAccountId());
+ cherryPickCommitterIdent = cherryPickUser.newCommitterIdent(
+ submitAudit.getGranted(), args.myIdent.getTimeZone());
} else {
+ cherryPickUser = args.identifiedUserFactory.create(n.change().getOwner());
cherryPickCommitterIdent = args.myIdent;
}
@@ -156,7 +159,7 @@
}
PatchSet.Id id =
- ChangeUtil.nextPatchSetId(args.repo, n.getChange().currentPatchSetId());
+ ChangeUtil.nextPatchSetId(args.repo, n.change().currentPatchSetId());
final PatchSet ps = new PatchSet(id);
ps.setCreatedOn(TimeUtil.nowTs());
ps.setUploader(submitAudit.getAccountId());
@@ -164,17 +167,17 @@
final RefUpdate ru;
- args.db.changes().beginTransaction(n.getChange().getId());
+ args.db.changes().beginTransaction(n.change().getId());
try {
insertAncestors(args.db, ps.getId(), newCommit);
args.db.patchSets().insert(Collections.singleton(ps));
- n.getChange()
+ n.change()
.setCurrentPatchSet(patchSetInfoFactory.get(newCommit, ps.getId()));
- args.db.changes().update(Collections.singletonList(n.getChange()));
+ args.db.changes().update(Collections.singletonList(n.change()));
final List<PatchSetApproval> approvals = Lists.newArrayList();
for (PatchSetApproval a
- : args.approvalsUtil.byPatchSet(args.db, n.notes, n.patchsetId)) {
+ : args.approvalsUtil.byPatchSet(args.db, n.notes(), n.patchsetId)) {
approvals.add(new PatchSetApproval(ps.getId(), a));
}
// TODO(dborowitz): This doesn't copy labels in the notedb. We should
@@ -188,7 +191,7 @@
ru.disableRefLog();
if (ru.update(args.rw) != RefUpdate.Result.NEW) {
throw new IOException(String.format(
- "Failed to create ref %s in %s: %s", ps.getRefName(), n.getChange()
+ "Failed to create ref %s in %s: %s", ps.getRefName(), n.change()
.getDest().getParentKey().get(), ru.getResult()));
}
@@ -197,10 +200,12 @@
args.db.rollback();
}
- gitRefUpdated.fire(n.getChange().getProject(), ru);
+ gitRefUpdated.fire(n.change().getProject(), ru);
newCommit.copyFrom(n);
newCommit.statusCode = CommitMergeStatus.CLEAN_PICK;
+ newCommit.control =
+ args.changeControlFactory.controlFor(n.change(), cherryPickUser);
newCommits.put(newCommit.patchsetId.getParentKey(), newCommit);
setRefLogIdent(submitAudit);
return newCommit;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/CodeReviewCommit.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/CodeReviewCommit.java
index 789be78..edd62af 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/CodeReviewCommit.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/CodeReviewCommit.java
@@ -17,6 +17,7 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.notedb.ChangeNotes;
+import com.google.gerrit.server.project.ChangeControl;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId;
@@ -40,8 +41,8 @@
*/
PatchSet.Id patchsetId;
- /** Change info loaded from notes. */
- public ChangeNotes notes;
+ /** Change control for the change owner. */
+ ChangeControl control;
/**
* Ordinal position of this commit within the submit queue.
@@ -64,15 +65,19 @@
super(id);
}
+ public ChangeNotes notes() {
+ return control.getNotes();
+ }
+
void copyFrom(final CodeReviewCommit src) {
+ control = src.control;
patchsetId = src.patchsetId;
- notes = src.notes;
originalOrder = src.originalOrder;
statusCode = src.statusCode;
missing = src.missing;
}
- Change getChange() {
- return notes.getChange();
+ Change change() {
+ return control.getChange();
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
index b146f48..d187708 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
@@ -279,8 +279,8 @@
for (final CodeReviewCommit commit : potentiallyStillSubmittableOnNextRun) {
final Capable capable = isSubmitStillPossible(commit);
if (capable != Capable.OK) {
- sendMergeFail(commit.notes,
- message(commit.getChange(), capable.getMessage()), false);
+ sendMergeFail(commit.notes(),
+ message(commit.change(), capable.getMessage()), false);
}
}
} catch (NoSuchProjectException noProject) {
@@ -327,7 +327,12 @@
}
for (CodeReviewCommit missingCommit : commit.missing) {
- loadChangeInfo(missingCommit);
+ try {
+ loadChangeInfo(missingCommit);
+ } catch (NoSuchChangeException | OrmException e) {
+ log.error("Cannot check if missing commits can be submitted", e);
+ return false;
+ }
if (missingCommit.patchsetId == null) {
// The commit doesn't have a patch set, so it cannot be
@@ -336,7 +341,7 @@
return false;
}
- if (!missingCommit.getChange().currentPatchSetId().equals(
+ if (!missingCommit.change().currentPatchSetId().equals(
missingCommit.patchsetId)) {
// If the missing commit is not the current patch set,
// the change must be rebased to use the proper parent.
@@ -519,7 +524,12 @@
continue;
}
- commit.notes = notesFactory.create(chg);
+ try {
+ commit.control = changeControlFactory.controlFor(chg,
+ identifiedUserFactory.create(chg.getOwner()));
+ } catch (NoSuchChangeException e) {
+ throw new MergeException("Failed to validate changes", e);
+ }
commit.patchsetId = ps.getId();
commit.originalOrder = commitOrder++;
commits.put(changeId, commit);
@@ -544,7 +554,7 @@
}
}
- final SubmitType submitType = getSubmitType(chg, ps);
+ final SubmitType submitType = getSubmitType(commit.control, ps);
if (submitType == null) {
commits.put(changeId,
CodeReviewCommit.error(CommitMergeStatus.NO_SUBMIT_TYPE));
@@ -559,21 +569,13 @@
return toSubmit;
}
- private SubmitType getSubmitType(final Change change, final PatchSet ps) {
- try {
- final SubmitTypeRecord r =
- changeControlFactory.controlFor(change,
- identifiedUserFactory.create(change.getOwner()))
- .getSubmitTypeRecord(db, ps);
- if (r.status != SubmitTypeRecord.Status.OK) {
- log.error("Failed to get submit type for " + change.getKey());
- return null;
- }
- return r.type;
- } catch (NoSuchChangeException e) {
- log.error("Failed to get submit type for " + change.getKey(), e);
+ private SubmitType getSubmitType(ChangeControl ctl, PatchSet ps) {
+ SubmitTypeRecord r = ctl.getSubmitTypeRecord(db, ps);
+ if (r.status != SubmitTypeRecord.Status.OK) {
+ log.error("Failed to get submit type for " + ctl.getChange().getKey());
return null;
}
+ return r.type;
}
private void updateBranch(final SubmitStrategy strategy,
@@ -623,7 +625,7 @@
Account account = null;
PatchSetApproval submitter = approvalsUtil.getSubmitter(
- db, mergeTip.notes, mergeTip.patchsetId);
+ db, mergeTip.notes(), mergeTip.patchsetId);
if (submitter != null) {
account = accountCache.get(submitter.getAccountId()).getAccount();
}
@@ -723,7 +725,7 @@
private Capable isSubmitStillPossible(final CodeReviewCommit commit) {
final Capable capable;
- final Change c = commit.getChange();
+ final Change c = commit.change();
final boolean submitStillPossible = isSubmitForMissingCommitsStillPossible(commit);
final long now = TimeUtil.nowMs();
final long waitUntil = c.getLastUpdatedOn().getTime() + DEPENDENCY_DELAY;
@@ -748,7 +750,7 @@
m.append("\n");
for (CodeReviewCommit missingCommit : commit.missing) {
m.append("* ");
- m.append(missingCommit.getChange().getKey().get());
+ m.append(missingCommit.change().getKey().get());
m.append("\n");
}
capable = new Capable(m.toString());
@@ -767,10 +769,10 @@
m.append("* Depends on patch set ");
m.append(missingCommit.patchsetId.get());
m.append(" of ");
- m.append(missingCommit.getChange().getKey().abbreviate());
- if (missingCommit.patchsetId.get() != missingCommit.getChange().currentPatchSetId().get()) {
+ m.append(missingCommit.change().getKey().abbreviate());
+ if (missingCommit.patchsetId.get() != missingCommit.change().currentPatchSetId().get()) {
m.append(", however the current patch set is ");
- m.append(missingCommit.getChange().currentPatchSetId().get());
+ m.append(missingCommit.change().currentPatchSetId().get());
}
m.append(".\n");
@@ -788,18 +790,16 @@
return capable;
}
- private void loadChangeInfo(final CodeReviewCommit commit) {
- if (commit.notes == null) {
- try {
- List<PatchSet> matches =
- db.patchSets().byRevision(new RevId(commit.name())).toList();
- if (matches.size() == 1) {
- final PatchSet ps = matches.get(0);
- commit.patchsetId = ps.getId();
- commit.notes =
- notesFactory.create(db.changes().get(ps.getId().getParentKey()));
- }
- } catch (OrmException e) {
+ private void loadChangeInfo(final CodeReviewCommit commit)
+ throws NoSuchChangeException, OrmException {
+ if (commit.control == null) {
+ List<PatchSet> matches =
+ db.patchSets().byRevision(new RevId(commit.name())).toList();
+ if (matches.size() == 1) {
+ PatchSet ps = matches.get(0);
+ commit.patchsetId = ps.getId();
+ commit.control =
+ changeControl(db.changes().get(ps.getId().getParentKey()));
}
}
}
@@ -825,10 +825,10 @@
// We must pull the patchset out of commits, because the patchset ID is
// modified when using the cherry-pick merge strategy.
CodeReviewCommit commit = commits.get(c.getId());
- PatchSet.Id merged = commit.getChange().currentPatchSetId();
+ PatchSet.Id merged = commit.change().currentPatchSetId();
c = setMergedPatchSet(c.getId(), merged);
PatchSetApproval submitter =
- approvalsUtil.getSubmitter(db, commit.notes, merged);
+ approvalsUtil.getSubmitter(db, commit.notes(), merged);
addMergedMessage(submitter, msg);
db.commit();
@@ -838,7 +838,7 @@
try {
hooks.doChangeMergedHook(c,
accountCache.get(submitter.getAccountId()).getAccount(),
- db.patchSets().get(commit.patchsetId), db);
+ db.patchSets().get(merged), db);
} catch (OrmException ex) {
log.error("Cannot run hook for submitted patch set " + c.getId(), ex);
}
@@ -904,9 +904,7 @@
}
try {
- final ChangeControl control = changeControlFactory.controlFor(c,
- identifiedUserFactory.create(c.getOwner()));
- final MergedSender cm = mergedSenderFactory.create(control);
+ MergedSender cm = mergedSenderFactory.create(changeControl(c));
if (from != null) {
cm.setFrom(from.getAccountId());
}
@@ -924,8 +922,13 @@
}));
}
+ private ChangeControl changeControl(Change c) throws NoSuchChangeException {
+ return changeControlFactory.controlFor(
+ c, identifiedUserFactory.create(c.getOwner()));
+ }
+
private void setNew(CodeReviewCommit c, ChangeMessage msg) {
- sendMergeFail(c.notes, msg, true);
+ sendMergeFail(c.notes(), msg, true);
}
private void setNew(Change c, ChangeMessage msg) throws OrmException {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeUtil.java
index 09a0e68..a6acf60 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeUtil.java
@@ -168,7 +168,7 @@
}
PatchSetApproval getSubmitter(CodeReviewCommit c) {
- return approvalsUtil.getSubmitter(db.get(), c.notes, c.patchsetId);
+ return approvalsUtil.getSubmitter(db.get(), c.notes(), c.patchsetId);
}
public RevCommit createCherryPickFromCommit(Repository repo,
@@ -217,10 +217,10 @@
msgbuf.append('\n');
}
- if (!contains(footers, CHANGE_ID, n.getChange().getKey().get())) {
+ if (!contains(footers, CHANGE_ID, n.change().getKey().get())) {
msgbuf.append(CHANGE_ID.getName());
msgbuf.append(": ");
- msgbuf.append(n.getChange().getKey().get());
+ msgbuf.append(n.change().getKey().get());
msgbuf.append('\n');
}
@@ -313,7 +313,7 @@
private List<PatchSetApproval> safeGetApprovals(CodeReviewCommit n) {
try {
- return approvalsUtil.byPatchSet(db.get(), n.notes, n.patchsetId);
+ return approvalsUtil.byPatchSet(db.get(), n.notes(), n.patchsetId);
} catch (OrmException e) {
log.error("Can't read approval records for " + n.patchsetId, e);
return Collections.emptyList();
@@ -587,7 +587,10 @@
mergeCommit.setCommitter(myIdent);
mergeCommit.setMessage(msgbuf.toString());
- return (CodeReviewCommit) rw.parseCommit(commit(inserter, mergeCommit));
+ CodeReviewCommit mergeResult =
+ (CodeReviewCommit) rw.parseCommit(commit(inserter, mergeCommit));
+ mergeResult.control = n.control;
+ return mergeResult;
}
private String summarize(RevWalk rw, List<CodeReviewCommit> merged)
@@ -600,8 +603,8 @@
LinkedHashSet<String> topics = new LinkedHashSet<>(4);
for (CodeReviewCommit c : merged) {
- if (!Strings.isNullOrEmpty(c.getChange().getTopic())) {
- topics.add(c.getChange().getTopic());
+ if (!Strings.isNullOrEmpty(c.change().getTopic())) {
+ topics.add(c.change().getTopic());
}
}
@@ -616,7 +619,7 @@
new Function<CodeReviewCommit, String>() {
@Override
public String apply(CodeReviewCommit in) {
- return in.getChange().getKey().abbreviate();
+ return in.change().getKey().abbreviate();
}
})),
merged.size() > 5 ? ", ..." : "");
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
index 1db7b4a..55f4ff7 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
@@ -114,6 +114,7 @@
private static final String KEY_MAX_OBJECT_SIZE_LIMIT = "maxObjectSizeLimit";
private static final String KEY_REQUIRE_CONTRIBUTOR_AGREEMENT =
"requireContributorAgreement";
+ private static final String KEY_CHECK_RECEIVED_OBJECTS = "checkReceivedObjects";
private static final String SUBMIT = "submit";
private static final String KEY_ACTION = "action";
@@ -157,6 +158,7 @@
private ObjectId rulesId;
private long maxObjectSizeLimit;
private Map<String, Config> pluginConfigs;
+ private boolean checkReceivedObjects;
public static ProjectConfig read(MetaDataUpdate update) throws IOException,
ConfigInvalidException {
@@ -339,6 +341,13 @@
}
/**
+ * @return the checkReceivedObjects for this project, default is true.
+ */
+ public boolean getCheckReceivedObjects() {
+ return checkReceivedObjects;
+ }
+
+ /**
* Check all GroupReferences use current group name, repairing stale ones.
*
* @param groupBackend cache to use when looking up group information by UUID.
@@ -408,8 +417,7 @@
loadLabelSections(rc);
loadCommentLinkSections(rc);
loadPluginSections(rc);
-
- maxObjectSizeLimit = rc.getLong(RECEIVE, null, KEY_MAX_OBJECT_SIZE_LIMIT, 0);
+ loadReceiveSection(rc);
}
private void loadAccountsSection(
@@ -696,6 +704,11 @@
commentLinkSections = ImmutableList.copyOf(commentLinkSections);
}
+ private void loadReceiveSection(Config rc) {
+ checkReceivedObjects = rc.getBoolean(RECEIVE, KEY_CHECK_RECEIVED_OBJECTS, true);
+ maxObjectSizeLimit = rc.getLong(RECEIVE, null, KEY_MAX_OBJECT_SIZE_LIMIT, 0);
+ }
+
private void loadPluginSections(Config rc) {
pluginConfigs = Maps.newHashMap();
for (String plugin : rc.getSubsections(PLUGIN)) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/RebaseIfNecessary.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/RebaseIfNecessary.java
index 01d37dc..a5b0034 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/RebaseIfNecessary.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/RebaseIfNecessary.java
@@ -22,6 +22,7 @@
import com.google.gerrit.server.change.PatchSetInserter.ValidatePolicy;
import com.google.gerrit.server.changedetail.PathConflictException;
import com.google.gerrit.server.changedetail.RebaseChange;
+import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gwtorm.server.OrmException;
@@ -35,14 +36,17 @@
import java.util.Map;
public class RebaseIfNecessary extends SubmitStrategy {
-
+ private final PatchSetInfoFactory patchSetInfoFactory;
private final RebaseChange rebaseChange;
private final Map<Change.Id, CodeReviewCommit> newCommits;
private final PersonIdent committerIdent;
- RebaseIfNecessary(final SubmitStrategy.Arguments args,
- final RebaseChange rebaseChange, PersonIdent committerIdent) {
+ RebaseIfNecessary(SubmitStrategy.Arguments args,
+ PatchSetInfoFactory patchSetInfoFactory,
+ RebaseChange rebaseChange,
+ PersonIdent committerIdent) {
super(args);
+ this.patchSetInfoFactory = patchSetInfoFactory;
this.rebaseChange = rebaseChange;
this.newCommits = new HashMap<Change.Id, CodeReviewCommit>();
this.committerIdent = committerIdent;
@@ -82,7 +86,7 @@
args.mergeUtil.getSubmitter(n).getAccountId());
final PatchSet newPatchSet =
rebaseChange.rebase(args.repo, args.rw, args.inserter,
- n.patchsetId, n.getChange(), uploader,
+ n.patchsetId, n.change(), uploader,
newMergeTip, args.mergeUtil, committerIdent,
false, false, ValidatePolicy.NONE);
@@ -91,7 +95,7 @@
// describes the change being submitted.
List<PatchSetApproval> approvals = Lists.newArrayList();
for (PatchSetApproval a : args.approvalsUtil.byPatchSet(
- args.db, n.notes, n.patchsetId)) {
+ args.db, n.notes(), n.patchsetId)) {
approvals.add(new PatchSetApproval(newPatchSet.getId(), a));
}
args.db.patchSetApprovals().insert(approvals);
@@ -99,22 +103,19 @@
newMergeTip =
(CodeReviewCommit) args.rw.parseCommit(ObjectId
.fromString(newPatchSet.getRevision().get()));
+ n.change().setCurrentPatchSet(
+ patchSetInfoFactory.get(newMergeTip, newPatchSet.getId()));
newMergeTip.copyFrom(n);
+ newMergeTip.control =
+ args.changeControlFactory.controlFor(n.change(), uploader);
newMergeTip.patchsetId = newPatchSet.getId();
- newMergeTip.notes = args.notesFactory.create(
- args.db.changes().get(newPatchSet.getId().getParentKey()));
newMergeTip.statusCode = CommitMergeStatus.CLEAN_REBASE;
newCommits.put(newPatchSet.getId().getParentKey(), newMergeTip);
setRefLogIdent(args.mergeUtil.getSubmitter(n));
} catch (PathConflictException e) {
n.statusCode = CommitMergeStatus.PATH_CONFLICT;
- } catch (NoSuchChangeException e) {
- throw new MergeException("Cannot rebase " + n.name(), e);
- } catch (OrmException e) {
- throw new MergeException("Cannot rebase " + n.name(), e);
- } catch (IOException e) {
- throw new MergeException("Cannot rebase " + n.name(), e);
- } catch (InvalidChangeOperationException e) {
+ } catch (NoSuchChangeException | OrmException | IOException
+ | InvalidChangeOperationException e) {
throw new MergeException("Cannot rebase " + n.name(), e);
}
}
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 29efb81..e602ccb 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
@@ -406,10 +406,12 @@
this.messageSender = new ReceivePackMessageSender();
+ ProjectState ps = projectControl.getProjectState();
+
rp.setAllowCreates(true);
rp.setAllowDeletes(true);
rp.setAllowNonFastForwards(true);
- rp.setCheckReceivedObjects(true);
+ rp.setCheckReceivedObjects(ps.getConfig().getCheckReceivedObjects());
rp.setRefFilter(new RefFilter() {
@Override
public Map<String, Ref> filter(Map<String, Ref> refs) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmitStrategy.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmitStrategy.java
index 8fc1c35..078fa9f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmitStrategy.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmitStrategy.java
@@ -22,9 +22,7 @@
import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.index.ChangeIndexer;
-
-import com.google.gerrit.server.notedb.ChangeNotes;
-import com.google.gerrit.server.notedb.ChangeUpdate;
+import com.google.gerrit.server.project.ChangeControl;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.PersonIdent;
@@ -52,8 +50,7 @@
protected final IdentifiedUser.GenericFactory identifiedUserFactory;
protected final PersonIdent myIdent;
protected final ReviewDb db;
- protected final ChangeNotes.Factory notesFactory;
- protected final ChangeUpdate.Factory updateFactory;
+ protected final ChangeControl.GenericFactory changeControlFactory;
protected final Repository repo;
protected final RevWalk rw;
@@ -68,17 +65,15 @@
Arguments(final IdentifiedUser.GenericFactory identifiedUserFactory,
final PersonIdent myIdent, final ReviewDb db,
- final ChangeNotes.Factory notesFactory,
- final ChangeUpdate.Factory updateFactory, final Repository repo,
- final RevWalk rw, final ObjectInserter inserter,
+ final ChangeControl.GenericFactory changeControlFactory,
+ final Repository repo, final RevWalk rw, final ObjectInserter inserter,
final RevFlag canMergeFlag, final Set<RevCommit> alreadyAccepted,
final Branch.NameKey destBranch, final ApprovalsUtil approvalsUtil,
final MergeUtil mergeUtil, final ChangeIndexer indexer) {
this.identifiedUserFactory = identifiedUserFactory;
this.myIdent = myIdent;
this.db = db;
- this.notesFactory = notesFactory;
- this.updateFactory = updateFactory;
+ this.changeControlFactory = changeControlFactory;
this.repo = repo;
this.rw = rw;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmitStrategyFactory.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmitStrategyFactory.java
index 4b183b8..d818b5c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmitStrategyFactory.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmitStrategyFactory.java
@@ -23,9 +23,8 @@
import com.google.gerrit.server.changedetail.RebaseChange;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.index.ChangeIndexer;
-import com.google.gerrit.server.notedb.ChangeNotes;
-import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
+import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchProjectException;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectState;
@@ -49,8 +48,7 @@
private final IdentifiedUser.GenericFactory identifiedUserFactory;
private final PersonIdent myIdent;
- private final ChangeNotes.Factory notesFactory;
- private final ChangeUpdate.Factory updateFactory;
+ private final ChangeControl.GenericFactory changeControlFactory;
private final PatchSetInfoFactory patchSetInfoFactory;
private final GitReferenceUpdated gitRefUpdated;
private final RebaseChange rebaseChange;
@@ -63,8 +61,7 @@
SubmitStrategyFactory(
final IdentifiedUser.GenericFactory identifiedUserFactory,
@GerritPersonIdent final PersonIdent myIdent,
- final ChangeNotes.Factory notesFactory,
- final ChangeUpdate.Factory updateFactory,
+ final ChangeControl.GenericFactory changeControlFactory,
final PatchSetInfoFactory patchSetInfoFactory,
final GitReferenceUpdated gitRefUpdated, final RebaseChange rebaseChange,
final ProjectCache projectCache,
@@ -73,8 +70,7 @@
final ChangeIndexer indexer) {
this.identifiedUserFactory = identifiedUserFactory;
this.myIdent = myIdent;
- this.notesFactory = notesFactory;
- this.updateFactory = updateFactory;
+ this.changeControlFactory = changeControlFactory;
this.patchSetInfoFactory = patchSetInfoFactory;
this.gitRefUpdated = gitRefUpdated;
this.rebaseChange = rebaseChange;
@@ -92,7 +88,7 @@
ProjectState project = getProject(destBranch);
final SubmitStrategy.Arguments args =
new SubmitStrategy.Arguments(identifiedUserFactory, myIdent, db,
- notesFactory, updateFactory, repo, rw, inserter, canMergeFlag,
+ changeControlFactory, repo, rw, inserter, canMergeFlag,
alreadyAccepted, destBranch,approvalsUtil,
mergeUtilFactory.create(project), indexer);
switch (submitType) {
@@ -105,7 +101,8 @@
case MERGE_IF_NECESSARY:
return new MergeIfNecessary(args);
case REBASE_IF_NECESSARY:
- return new RebaseIfNecessary(args, rebaseChange, myIdent);
+ return new RebaseIfNecessary(
+ args, patchSetInfoFactory, rebaseChange, myIdent);
default:
final String errorMsg = "No submit strategy for: " + submitType;
log.error(errorMsg);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/MergeValidators.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/MergeValidators.java
index 519fc41..76998b7 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/MergeValidators.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/MergeValidators.java
@@ -125,7 +125,7 @@
} else {
if (!oldParent.equals(newParent)) {
PatchSetApproval psa =
- approvalsUtil.getSubmitter(db, commit.notes, patchSetId);
+ approvalsUtil.getSubmitter(db, commit.notes(), patchSetId);
if (psa == null) {
throw new MergeValidationException(CommitMergeStatus.
SETTING_PARENT_PROJECT_ONLY_ALLOWED_BY_ADMIN);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/GroupsCollection.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/GroupsCollection.java
index 91da748..7f9fe77 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/group/GroupsCollection.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/GroupsCollection.java
@@ -84,7 +84,7 @@
throw new ResourceNotFoundException(id);
}
- GroupDescription.Basic group = _parse(id.get());
+ GroupDescription.Basic group = parseId(id.get());
if (group == null) {
throw new ResourceNotFoundException(id.get());
}
@@ -106,7 +106,7 @@
*/
public GroupDescription.Basic parse(String id)
throws UnprocessableEntityException {
- GroupDescription.Basic group = _parse(id);
+ GroupDescription.Basic group = parseId(id);
if (group == null || !groupControlFactory.controlFor(group).isVisible()) {
throw new UnprocessableEntityException(String.format(
"Group Not Found: %s", id));
@@ -135,7 +135,15 @@
return group;
}
- private GroupDescription.Basic _parse(String id) {
+ /**
+ * Parses a group ID and returns the group without making any permission
+ * check whether the current user can see the group.
+ *
+ * @param id ID of the group, can be a group UUID, a group name or a legacy
+ * group ID
+ * @return the group, null if no group is found for the given group ID
+ */
+ public GroupDescription.Basic parseId(String id) {
AccountGroup.UUID uuid = new AccountGroup.UUID(id);
if (groupBackend.handles(uuid)) {
GroupDescription.Basic d = groupBackend.get(uuid);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/ListMembers.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/ListMembers.java
index 5c5e741..c4b2ae2 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/group/ListMembers.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/ListMembers.java
@@ -57,6 +57,10 @@
this.accountLoader = accountLoaderFactory.create(true);
}
+ public void setRecursive(boolean recursive) {
+ this.recursive = recursive;
+ }
+
@Override
public List<AccountInfo> apply(final GroupResource resource)
throws MethodNotAllowedException, OrmException {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeField.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeField.java
index cca9d8f..afa516f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeField.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeField.java
@@ -115,10 +115,24 @@
}
};
+ // Same value as UPDATED, but implementations truncated to minutes.
+ @Deprecated
+ /** Last update time since January 1, 1970. */
+ public static final FieldDef<ChangeData, Timestamp> LEGACY_UPDATED =
+ new FieldDef.Single<ChangeData, Timestamp>(
+ "updated", FieldType.TIMESTAMP, true) {
+ @Override
+ public Timestamp get(ChangeData input, FillArgs args)
+ throws OrmException {
+ return input.change().getLastUpdatedOn();
+ }
+ };
+
+
/** Last update time since January 1, 1970. */
public static final FieldDef<ChangeData, Timestamp> UPDATED =
new FieldDef.Single<ChangeData, Timestamp>(
- "updated", FieldType.TIMESTAMP, true) {
+ "updated2", FieldType.TIMESTAMP, true) {
@Override
public Timestamp get(ChangeData input, FillArgs args)
throws OrmException {
@@ -152,6 +166,7 @@
* Redundant with {@link #UPDATED} and {@link #LEGACY_ID}, but secondary index
* implementations may not be able to search over tuples of values.
*/
+ @Deprecated
public static final FieldDef<ChangeData, Long> SORTKEY =
new FieldDef.Single<ChangeData, Long>(
"sortkey2", FieldType.LONG, true) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeIndex.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeIndex.java
index 201c983..a710a10 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeIndex.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeIndex.java
@@ -91,6 +91,7 @@
* @param p the predicate to match. Must be a tree containing only AND, OR,
* or NOT predicates as internal nodes, and {@link IndexPredicate}s as
* leaves.
+ * @param start offset in results list at which to start returning results.
* @param limit maximum number of results to return.
* @return a source of documents matching the predicate. Documents must be
* returned in descending sort key order, unless a {@code sortkey_after}
@@ -101,8 +102,8 @@
* @throws QueryParseException if the predicate could not be converted to an
* indexed data source.
*/
- public ChangeDataSource getSource(Predicate<ChangeData> p, int limit)
- throws QueryParseException;
+ public ChangeDataSource getSource(Predicate<ChangeData> p, int start,
+ int limit) throws QueryParseException;
/**
* Mark whether this index is up-to-date and ready to serve reads.
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeSchemas.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeSchemas.java
index 475e7d1..a46b22d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeSchemas.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/ChangeSchemas.java
@@ -38,7 +38,7 @@
ChangeField.PROJECT,
ChangeField.REF,
ChangeField.TOPIC,
- ChangeField.UPDATED,
+ ChangeField.LEGACY_UPDATED,
ChangeField.LEGACY_SORTKEY,
ChangeField.PATH,
ChangeField.OWNER,
@@ -58,7 +58,7 @@
ChangeField.PROJECT,
ChangeField.REF,
ChangeField.TOPIC,
- ChangeField.UPDATED,
+ ChangeField.LEGACY_UPDATED,
ChangeField.LEGACY_SORTKEY,
ChangeField.PATH,
ChangeField.OWNER,
@@ -72,6 +72,7 @@
ChangeField.CHANGE,
ChangeField.APPROVAL);
+ @SuppressWarnings("deprecation")
static final Schema<ChangeData> V3 = release(
ChangeField.LEGACY_ID,
ChangeField.ID,
@@ -79,7 +80,7 @@
ChangeField.PROJECT,
ChangeField.REF,
ChangeField.TOPIC,
- ChangeField.UPDATED,
+ ChangeField.LEGACY_UPDATED,
ChangeField.SORTKEY,
ChangeField.PATH,
ChangeField.OWNER,
@@ -96,6 +97,7 @@
// For upgrade to Lucene 4.4.0 index format only.
static final Schema<ChangeData> V4 = release(V3.getFields().values());
+ @SuppressWarnings("deprecation")
static final Schema<ChangeData> V5 = release(
ChangeField.LEGACY_ID,
ChangeField.ID,
@@ -103,7 +105,7 @@
ChangeField.PROJECT,
ChangeField.REF,
ChangeField.TOPIC,
- ChangeField.UPDATED,
+ ChangeField.LEGACY_UPDATED,
ChangeField.SORTKEY,
ChangeField.PATH,
ChangeField.OWNER,
@@ -121,6 +123,7 @@
// For upgrade to Lucene 4.6.0 index format only.
static final Schema<ChangeData> V6 = release(V5.getFields().values());
+ @SuppressWarnings("deprecation")
static final Schema<ChangeData> V7 = release(
ChangeField.LEGACY_ID,
ChangeField.ID,
@@ -128,7 +131,7 @@
ChangeField.PROJECT,
ChangeField.REF,
ChangeField.TOPIC,
- ChangeField.UPDATED,
+ ChangeField.LEGACY_UPDATED,
ChangeField.SORTKEY,
ChangeField.FILE_PART,
ChangeField.PATH,
@@ -144,6 +147,28 @@
ChangeField.APPROVAL,
ChangeField.MERGEABLE);
+ static final Schema<ChangeData> V8 = release(
+ ChangeField.LEGACY_ID,
+ ChangeField.ID,
+ ChangeField.STATUS,
+ ChangeField.PROJECT,
+ ChangeField.REF,
+ ChangeField.TOPIC,
+ ChangeField.UPDATED,
+ ChangeField.FILE_PART,
+ ChangeField.PATH,
+ ChangeField.OWNER,
+ ChangeField.REVIEWER,
+ ChangeField.COMMIT,
+ ChangeField.TR,
+ ChangeField.LABEL,
+ ChangeField.REVIEWED,
+ ChangeField.COMMIT_MESSAGE,
+ ChangeField.COMMENT,
+ ChangeField.CHANGE,
+ ChangeField.APPROVAL,
+ ChangeField.MERGEABLE);
+
private static Schema<ChangeData> release(Collection<FieldDef<ChangeData, ?>> fields) {
return new Schema<ChangeData>(true, fields);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexRewriteImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexRewriteImpl.java
index 3e2ed0a..345f5b2 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexRewriteImpl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexRewriteImpl.java
@@ -15,6 +15,7 @@
package com.google.gerrit.server.index;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gerrit.reviewdb.client.Change;
@@ -130,13 +131,17 @@
}
@Override
- public Predicate<ChangeData> rewrite(Predicate<ChangeData> in)
+ public Predicate<ChangeData> rewrite(Predicate<ChangeData> in, int start)
throws QueryParseException {
ChangeIndex index = indexes.getSearchIndex();
in = basicRewrites.rewrite(in);
- int limit = ChangeQueryBuilder.hasLimit(in)
- ? ChangeQueryBuilder.getLimit(in)
- : MAX_LIMIT;
+ int limit =
+ Objects.firstNonNull(ChangeQueryBuilder.getLimit(in), MAX_LIMIT);
+ // Increase the limit rather than skipping, since we don't know how many
+ // skipped results would have been filtered out by the enclosing AndSource.
+ limit += start;
+ limit = Math.max(limit, 1);
+ limit = Math.min(limit, MAX_LIMIT);
Predicate<ChangeData> out = rewriteImpl(in, index, limit);
if (in == out || out instanceof IndexPredicate) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexedChangeQuery.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexedChangeQuery.java
index e506217..09d66e5 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexedChangeQuery.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/IndexedChangeQuery.java
@@ -89,7 +89,7 @@
this.index = index;
this.limit = limit;
this.pred = pred;
- this.source = index.getSource(pred, limit);
+ this.source = index.getSource(pred, 0, limit);
}
@Override
@@ -166,7 +166,20 @@
public ResultSet<ChangeData> restart(ChangeData last) throws OrmException {
pred = replaceSortKeyPredicates(pred, last.change().getSortKey());
try {
- source = index.getSource(pred, limit);
+ source = index.getSource(pred, 0, limit);
+ } catch (QueryParseException e) {
+ // Don't need to show this exception to the user; the only thing that
+ // changed about pred was its SortKeyPredicates, and any other QPEs
+ // that might happen should have already thrown from the constructor.
+ throw new OrmException(e);
+ }
+ return read();
+ }
+
+ @Override
+ public ResultSet<ChangeData> restart(int start) throws OrmException {
+ try {
+ source = index.getSource(pred, start, limit);
} catch (QueryParseException e) {
// Don't need to show this exception to the user; the only thing that
// changed about pred was its SortKeyPredicates, and any other QPEs
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/TimestampRangePredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/TimestampRangePredicate.java
index 62fba12..0ba20e2 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/TimestampRangePredicate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/TimestampRangePredicate.java
@@ -14,14 +14,57 @@
package com.google.gerrit.server.index;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.gerrit.server.index.ChangeField.UPDATED;
+
+import com.google.gerrit.server.query.QueryParseException;
+import com.google.gerrit.server.query.change.ChangeData;
+
+import org.eclipse.jgit.util.GitDateParser;
+import org.joda.time.DateTime;
+
import java.sql.Timestamp;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.Locale;
public abstract class TimestampRangePredicate<I> extends IndexPredicate<I> {
+ @SuppressWarnings({"deprecation", "unchecked"})
+ protected static FieldDef<ChangeData, Timestamp> updatedField(
+ Schema<ChangeData> schema) {
+ if (schema == null) {
+ return ChangeField.LEGACY_UPDATED;
+ }
+ FieldDef<ChangeData, ?> f = schema.getFields().get(UPDATED.getName());
+ if (f == null) {
+ f = schema.getFields().get(ChangeField.LEGACY_UPDATED.getName());
+ checkNotNull(f, "schema missing updated field, found: %s", schema);
+ }
+ checkArgument(f.getType() == FieldType.TIMESTAMP,
+ "expected %s to be TIMESTAMP, found %s", f.getName(), f.getType());
+ return (FieldDef<ChangeData, Timestamp>) f;
+ }
+
+ protected static Date parse(String value) throws QueryParseException {
+ try {
+ return GitDateParser.parse(value, DateTime.now().toCalendar(Locale.US));
+ } catch (ParseException e) {
+ // ParseException's message is specific and helpful, so preserve it.
+ throw new QueryParseException(e.getMessage(), e);
+ }
+ }
+
protected TimestampRangePredicate(FieldDef<I, Timestamp> def,
String name, String value) {
super(def, name, value);
}
- public abstract Timestamp getMinTimestamp();
- public abstract Timestamp getMaxTimestamp();
+ public abstract Date getMinTimestamp();
+ public abstract Date getMaxTimestamp();
+
+ @Override
+ public int getCost() {
+ return 1;
+ }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
index 102a136..c0cfe90 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
@@ -217,6 +217,9 @@
}
public ChangeControl forUser(final CurrentUser who) {
+ if (getCurrentUser().equals(who)) {
+ return this;
+ }
return new ChangeControl(approvalsUtil, changeDataFactory,
getRefControl().forUser(who), notes);
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/AfterPredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/AfterPredicate.java
new file mode 100644
index 0000000..cb0038c
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/AfterPredicate.java
@@ -0,0 +1,47 @@
+// Copyright (C) 2014 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.query.change;
+
+import com.google.gerrit.server.index.Schema;
+import com.google.gerrit.server.index.TimestampRangePredicate;
+import com.google.gerrit.server.query.QueryParseException;
+import com.google.gwtorm.server.OrmException;
+
+import java.util.Date;
+
+public class AfterPredicate extends TimestampRangePredicate<ChangeData> {
+ private final Date cut;
+
+ AfterPredicate(Schema<ChangeData> schema, String value)
+ throws QueryParseException {
+ super(updatedField(schema), ChangeQueryBuilder.FIELD_BEFORE, value);
+ cut = parse(value);
+ }
+
+ @Override
+ public Date getMinTimestamp() {
+ return cut;
+ }
+
+ @Override
+ public Date getMaxTimestamp() {
+ return new Date(Long.MAX_VALUE);
+ }
+
+ @Override
+ public boolean match(ChangeData cd) throws OrmException {
+ return cd.change().getLastUpdatedOn().getTime() >= cut.getTime();
+ }
+}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/AgePredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/AgePredicate.java
index 1913791..1894596 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/AgePredicate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/AgePredicate.java
@@ -19,7 +19,7 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.server.config.ConfigUtil;
-import com.google.gerrit.server.index.ChangeField;
+import com.google.gerrit.server.index.Schema;
import com.google.gerrit.server.index.TimestampRangePredicate;
import com.google.gerrit.server.util.TimeUtil;
import com.google.gwtorm.server.OrmException;
@@ -29,34 +29,27 @@
public class AgePredicate extends TimestampRangePredicate<ChangeData> {
private final long cut;
- AgePredicate(String value) {
- super(ChangeField.UPDATED, ChangeQueryBuilder.FIELD_AGE, value);
+ AgePredicate(Schema<ChangeData> schema, String value) {
+ super(updatedField(schema), ChangeQueryBuilder.FIELD_AGE, value);
long s = ConfigUtil.getTimeUnit(getValue(), 0, SECONDS);
long ms = MILLISECONDS.convert(s, SECONDS);
this.cut = TimeUtil.nowMs() - ms;
}
+ @Override
public Timestamp getMinTimestamp() {
return new Timestamp(0);
}
+ @Override
public Timestamp getMaxTimestamp() {
return new Timestamp(cut);
}
- long getCut() {
- return cut + 1;
- }
-
@Override
public boolean match(final ChangeData object) throws OrmException {
Change change = object.change();
return change != null && change.getLastUpdatedOn().getTime() <= cut;
}
-
- @Override
- public int getCost() {
- return 1;
- }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/AndSource.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/AndSource.java
index a641edd..ad0ec3c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/AndSource.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/AndSource.java
@@ -14,9 +14,12 @@
package com.google.gerrit.server.query.change;
+import static com.google.common.base.Preconditions.checkArgument;
+
import com.google.common.base.Function;
import com.google.common.base.Throwables;
import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.gerrit.server.query.AndPredicate;
@@ -71,10 +74,18 @@
return r;
}
+ private final int start;
private int cardinality = -1;
public AndSource(Collection<? extends Predicate<ChangeData>> that) {
+ this(that, 0);
+ }
+
+ public AndSource(Collection<? extends Predicate<ChangeData>> that,
+ int start) {
super(sort(that));
+ checkArgument(start >= 0, "negative start: %s", start);
+ this.start = start;
}
@Override
@@ -98,9 +109,13 @@
if (source == null) {
throw new OrmException("No ChangeDataSource: " + this);
}
+ @SuppressWarnings("unchecked")
+ Predicate<ChangeData> pred = (Predicate<ChangeData>) source;
+ boolean useSortKey = ChangeQueryBuilder.hasSortKey(pred);
List<ChangeData> r = Lists.newArrayList();
ChangeData last = null;
+ int nextStart = 0;
boolean skipped = false;
for (ChangeData data : buffer(source, source.read())) {
if (match(data)) {
@@ -109,6 +124,7 @@
skipped = true;
}
last = data;
+ nextStart++;
}
if (skipped && last != null && source instanceof Paginated) {
@@ -117,21 +133,31 @@
// limit the caller wants. Restart the source and continue.
//
Paginated p = (Paginated) source;
- while (skipped && r.size() < p.limit()) {
+ while (skipped && r.size() < p.limit() + start) {
ChangeData lastBeforeRestart = last;
skipped = false;
last = null;
- for (ChangeData data : buffer(source, p.restart(lastBeforeRestart))) {
+ ResultSet<ChangeData> next = useSortKey
+ ? p.restart(lastBeforeRestart)
+ : p.restart(nextStart);
+
+ for (ChangeData data : buffer(source, next)) {
if (match(data)) {
r.add(data);
} else {
skipped = true;
}
last = data;
+ nextStart++;
}
}
}
+ if (start >= r.size()) {
+ r = ImmutableList.of();
+ } else if (start > 0) {
+ r = ImmutableList.copyOf(r.subList(start, r.size()));
+ }
return new ListResultSet<ChangeData>(r);
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/BasicChangeRewrites.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/BasicChangeRewrites.java
index 0ec4b5b..8ce6fa3 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/BasicChangeRewrites.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/BasicChangeRewrites.java
@@ -14,13 +14,8 @@
package com.google.gerrit.server.query.change;
-import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.ChangeUtil;
-import com.google.gerrit.server.index.ChangeIndex;
-import com.google.gerrit.server.index.IndexCollection;
-import com.google.gerrit.server.index.Schema;
import com.google.gerrit.server.query.IntPredicate;
import com.google.gerrit.server.query.Predicate;
import com.google.gerrit.server.query.QueryRewriter;
@@ -41,19 +36,12 @@
new QueryRewriter.Definition<ChangeData, BasicChangeRewrites>(
BasicChangeRewrites.class, BUILDER);
- static Schema<ChangeData> schema(@Nullable IndexCollection indexes) {
- ChangeIndex index = indexes != null ? indexes.getSearchIndex() : null;
- return index != null ? index.getSchema() : null;
- }
-
protected final Provider<ReviewDb> dbProvider;
- private final IndexCollection indexes;
@Inject
- public BasicChangeRewrites(Provider<ReviewDb> dbProvider, IndexCollection indexes) {
+ public BasicChangeRewrites(Provider<ReviewDb> dbProvider) {
super(mydef);
this.dbProvider = dbProvider;
- this.indexes = indexes;
}
@Rewrite("-status:open")
@@ -84,14 +72,6 @@
new ChangeStatusPredicate(Change.Status.MERGED));
}
- @SuppressWarnings("unchecked")
- @NoCostComputation
- @Rewrite("sortkey_before:z A=(age:*)")
- public Predicate<ChangeData> r00_ageToSortKey(@Named("A") AgePredicate a) {
- String cut = ChangeUtil.sortKey(a.getCut(), Integer.MAX_VALUE);
- return and(new SortKeyPredicate.Before(schema(indexes), dbProvider, cut), a);
- }
-
@NoCostComputation
@Rewrite("A=(limit:*) B=(limit:*)")
public Predicate<ChangeData> r00_smallestLimit(
@@ -100,21 +80,6 @@
return a.intValue() <= b.intValue() ? a : b;
}
- @NoCostComputation
- @Rewrite("A=(sortkey_before:*) B=(sortkey_before:*)")
- public Predicate<ChangeData> r00_oldestSortKey(
- @Named("A") SortKeyPredicate.Before a,
- @Named("B") SortKeyPredicate.Before b) {
- return a.getValue().compareTo(b.getValue()) <= 0 ? a : b;
- }
-
- @NoCostComputation
- @Rewrite("A=(sortkey_after:*) B=(sortkey_after:*)")
- public Predicate<ChangeData> r00_newestSortKey(
- @Named("A") SortKeyPredicate.After a, @Named("B") SortKeyPredicate.After b) {
- return a.getValue().compareTo(b.getValue()) >= 0 ? a : b;
- }
-
private static final class InvalidProvider<T> implements Provider<T> {
@Override
public T get() {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/BeforePredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/BeforePredicate.java
new file mode 100644
index 0000000..f724676
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/BeforePredicate.java
@@ -0,0 +1,47 @@
+// Copyright (C) 2014 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.query.change;
+
+import com.google.gerrit.server.index.Schema;
+import com.google.gerrit.server.index.TimestampRangePredicate;
+import com.google.gerrit.server.query.QueryParseException;
+import com.google.gwtorm.server.OrmException;
+
+import java.util.Date;
+
+public class BeforePredicate extends TimestampRangePredicate<ChangeData> {
+ private final Date cut;
+
+ BeforePredicate(Schema<ChangeData> schema, String value)
+ throws QueryParseException {
+ super(updatedField(schema), ChangeQueryBuilder.FIELD_BEFORE, value);
+ cut = parse(value);
+ }
+
+ @Override
+ public Date getMinTimestamp() {
+ return new Date(0);
+ }
+
+ @Override
+ public Date getMaxTimestamp() {
+ return cut;
+ }
+
+ @Override
+ public boolean match(ChangeData cd) throws OrmException {
+ return cd.change().getLastUpdatedOn().getTime() <= cut.getTime();
+ }
+}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeData.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeData.java
index 968b2c04..333c343 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeData.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeData.java
@@ -33,6 +33,7 @@
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.NotesMigration;
@@ -150,11 +151,13 @@
* @return instance for testing.
*/
static ChangeData createForTest(Change.Id id) {
- return new ChangeData(null, null, null, null, null, null, id);
+ return new ChangeData(null, null, null, null, null, null, null, null, id);
}
private final ReviewDb db;
private final GitRepositoryManager repoManager;
+ private final ChangeControl.GenericFactory changeControlFactory;
+ private final IdentifiedUser.GenericFactory userFactory;
private final ChangeNotes.Factory notesFactory;
private final ApprovalsUtil approvalsUtil;
private final PatchListCache patchListCache;
@@ -180,6 +183,8 @@
@AssistedInject
private ChangeData(
GitRepositoryManager repoManager,
+ ChangeControl.GenericFactory changeControlFactory,
+ IdentifiedUser.GenericFactory userFactory,
ChangeNotes.Factory notesFactory,
ApprovalsUtil approvalsUtil,
PatchListCache patchListCache,
@@ -188,6 +193,8 @@
@Assisted Change.Id id) {
this.db = db;
this.repoManager = repoManager;
+ this.changeControlFactory = changeControlFactory;
+ this.userFactory = userFactory;
this.notesFactory = notesFactory;
this.approvalsUtil = approvalsUtil;
this.patchListCache = patchListCache;
@@ -198,6 +205,8 @@
@AssistedInject
private ChangeData(
GitRepositoryManager repoManager,
+ ChangeControl.GenericFactory changeControlFactory,
+ IdentifiedUser.GenericFactory userFactory,
ChangeNotes.Factory notesFactory,
ApprovalsUtil approvalsUtil,
PatchListCache patchListCache,
@@ -206,6 +215,8 @@
@Assisted Change c) {
this.db = db;
this.repoManager = repoManager;
+ this.changeControlFactory = changeControlFactory;
+ this.userFactory = userFactory;
this.notesFactory = notesFactory;
this.approvalsUtil = approvalsUtil;
this.patchListCache = patchListCache;
@@ -217,6 +228,8 @@
@AssistedInject
private ChangeData(
GitRepositoryManager repoManager,
+ ChangeControl.GenericFactory changeControlFactory,
+ IdentifiedUser.GenericFactory userFactory,
ChangeNotes.Factory notesFactory,
ApprovalsUtil approvalsUtil,
PatchListCache patchListCache,
@@ -225,6 +238,8 @@
@Assisted ChangeControl c) {
this.db = db;
this.repoManager = repoManager;
+ this.changeControlFactory = changeControlFactory;
+ this.userFactory = userFactory;
this.notesFactory = notesFactory;
this.approvalsUtil = approvalsUtil;
this.patchListCache = patchListCache;
@@ -324,7 +339,17 @@
return visibleTo == user;
}
- public ChangeControl changeControl() {
+ public boolean hasChangeControl() {
+ return changeControl != null;
+ }
+
+ public ChangeControl changeControl() throws NoSuchChangeException,
+ OrmException {
+ if (changeControl == null) {
+ Change c = change();
+ changeControl =
+ changeControlFactory.controlFor(c, userFactory.create(c.getOwner()));
+ }
return changeControl;
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index 01c0e4a..bf92867 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -16,6 +16,7 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
+import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
@@ -84,7 +85,9 @@
// NOTE: As new search operations are added, please keep the
// SearchSuggestOracle up to date.
+ public static final String FIELD_AFTER = "after";
public static final String FIELD_AGE = "age";
+ public static final String FIELD_BEFORE = "before";
public static final String FIELD_BRANCH = "branch";
public static final String FIELD_CHANGE = "change";
public static final String FIELD_COMMENT = "comment";
@@ -122,13 +125,10 @@
ChangeQueryBuilder.class);
@SuppressWarnings("unchecked")
- public static boolean hasLimit(Predicate<ChangeData> p) {
- return find(p, IntPredicate.class, FIELD_LIMIT) != null;
- }
-
- @SuppressWarnings("unchecked")
- public static int getLimit(Predicate<ChangeData> p) {
- return ((IntPredicate<?>) find(p, IntPredicate.class, FIELD_LIMIT)).intValue();
+ public static Integer getLimit(Predicate<ChangeData> p) {
+ IntPredicate<?> ip =
+ (IntPredicate<?>) find(p, IntPredicate.class, FIELD_LIMIT);
+ return ip != null ? ip.intValue() : null;
}
public static boolean hasNonTrivialSortKeyAfter(Schema<ChangeData> schema,
@@ -235,7 +235,27 @@
@Operator
public Predicate<ChangeData> age(String value) {
- return new AgePredicate(value);
+ return new AgePredicate(schema(args.indexes), value);
+ }
+
+ @Operator
+ public Predicate<ChangeData> before(String value) throws QueryParseException {
+ return new BeforePredicate(schema(args.indexes), value);
+ }
+
+ @Operator
+ public Predicate<ChangeData> until(String value) throws QueryParseException {
+ return before(value);
+ }
+
+ @Operator
+ public Predicate<ChangeData> after(String value) throws QueryParseException {
+ return new AfterPredicate(schema(args.indexes), value);
+ }
+
+ @Operator
+ public Predicate<ChangeData> since(String value) throws QueryParseException {
+ return after(value);
}
@Operator
@@ -638,16 +658,18 @@
return new LimitPredicate(limit);
}
+ boolean supportsSortKey() {
+ return SortKeyPredicate.hasSortKeyField(schema(args.indexes));
+ }
+
@Operator
public Predicate<ChangeData> sortkey_after(String sortKey) {
- return new SortKeyPredicate.After(
- BasicChangeRewrites.schema(args.indexes), args.db, sortKey);
+ return new SortKeyPredicate.After(schema(args.indexes), args.db, sortKey);
}
@Operator
public Predicate<ChangeData> sortkey_before(String sortKey) {
- return new SortKeyPredicate.Before(
- BasicChangeRewrites.schema(args.indexes), args.db, sortKey);
+ return new SortKeyPredicate.Before(schema(args.indexes), args.db, sortKey);
}
@Operator
@@ -756,4 +778,9 @@
}
throw new IllegalArgumentException();
}
+
+ private static Schema<ChangeData> schema(@Nullable IndexCollection indexes) {
+ ChangeIndex index = indexes != null ? indexes.getSearchIndex() : null;
+ return index != null ? index.getSchema() : null;
+ }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryRewriter.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryRewriter.java
index bd186c7..bbf235b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryRewriter.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryRewriter.java
@@ -18,6 +18,6 @@
import com.google.gerrit.server.query.QueryParseException;
public interface ChangeQueryRewriter {
- Predicate<ChangeData> rewrite(Predicate<ChangeData> in)
+ Predicate<ChangeData> rewrite(Predicate<ChangeData> in, int start)
throws QueryParseException;
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/CommentPredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/CommentPredicate.java
index 6cfb897..5994e5c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/CommentPredicate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/CommentPredicate.java
@@ -36,7 +36,7 @@
public boolean match(ChangeData object) throws OrmException {
try {
for (ChangeData cData : index.getSource(
- Predicate.and(new LegacyChangeIdPredicate(args, object.getId()), this), 1)
+ Predicate.and(new LegacyChangeIdPredicate(args, object.getId()), this), 0, 1)
.read()) {
if (cData.getId().equals(object.getId())) {
return true;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/MessagePredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/MessagePredicate.java
index f81cf51..04bdb1e 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/MessagePredicate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/MessagePredicate.java
@@ -40,7 +40,7 @@
public boolean match(ChangeData object) throws OrmException {
try {
for (ChangeData cData : index.getSource(
- Predicate.and(new LegacyChangeIdPredicate(args, object.getId()), this), 1)
+ Predicate.and(new LegacyChangeIdPredicate(args, object.getId()), this), 0, 1)
.read()) {
if (cData.getId().equals(object.getId())) {
return true;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/Paginated.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/Paginated.java
index d9ff80c..e411cf9 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/Paginated.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/Paginated.java
@@ -21,4 +21,6 @@
int limit();
ResultSet<ChangeData> restart(ChangeData last) throws OrmException;
+
+ ResultSet<ChangeData> restart(int start) throws OrmException;
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryChanges.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryChanges.java
index 081f135..41c2e23 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryChanges.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryChanges.java
@@ -80,6 +80,11 @@
imp.setSortkeyBefore(key);
}
+ @Option(name = "-S", metaVar = "CNT", usage = "Number of changes to skip")
+ public void setStart(int start) {
+ imp.setStart(start);
+ }
+
@Inject
QueryChanges(ChangeJson json, QueryProcessor qp, Provider<CurrentUser> user) {
this.json = json;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryProcessor.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryProcessor.java
index 81767ae..33208863 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryProcessor.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/QueryProcessor.java
@@ -14,6 +14,7 @@
package com.google.gerrit.server.query.change;
+import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.gerrit.common.data.GlobalCapability;
@@ -97,13 +98,13 @@
private final ChangeQueryBuilder queryBuilder;
private final ChangeQueryRewriter queryRewriter;
private final Provider<ReviewDb> db;
- private final ChangeControl.GenericFactory changeControlFactory;
private final TrackingFooters trackingFooters;
private final CurrentUser user;
private final int maxLimit;
private OutputFormat outputFormat = OutputFormat.TEXT;
private int limit;
+ private int start;
private String sortkeyAfter;
private String sortkeyBefore;
private boolean includePatchSets;
@@ -124,14 +125,12 @@
QueryProcessor(EventFactory eventFactory,
ChangeQueryBuilder.Factory queryBuilder, CurrentUser currentUser,
ChangeQueryRewriter queryRewriter, Provider<ReviewDb> db,
- TrackingFooters trackingFooters,
- ChangeControl.GenericFactory changeControlFactory) {
+ TrackingFooters trackingFooters) {
this.eventFactory = eventFactory;
this.queryBuilder = queryBuilder.create(currentUser);
this.queryRewriter = queryRewriter;
this.db = db;
this.trackingFooters = trackingFooters;
- this.changeControlFactory = changeControlFactory;
this.user = currentUser;
this.maxLimit = currentUser.getCapabilities()
.getRange(GlobalCapability.QUERY_LIMIT)
@@ -147,6 +146,10 @@
limit = n;
}
+ void setStart(int n) {
+ start = n;
+ }
+
void setSortkeyAfter(String sortkey) {
sortkeyAfter = sortkey;
}
@@ -243,17 +246,17 @@
List<ChangeDataSource> sources = Lists.newArrayListWithCapacity(cnt);
for (String query : queries) {
Predicate<ChangeData> q = parseQuery(query, visibleToMe);
- Predicate<ChangeData> s = queryRewriter.rewrite(q);
+ Predicate<ChangeData> s = queryRewriter.rewrite(q, start);
if (!(s instanceof ChangeDataSource)) {
q = Predicate.and(queryBuilder.status_open(), q);
- s = queryRewriter.rewrite(q);
+ s = queryRewriter.rewrite(q, start);
}
if (!(s instanceof ChangeDataSource)) {
throw new QueryParseException("invalid query: " + s);
}
// Don't trust QueryRewriter to have left the visible predicate.
- AndSource a = new AndSource(ImmutableList.of(s, visibleToMe));
+ AndSource a = new AndSource(ImmutableList.of(s, visibleToMe), start);
limits.add(limit(q));
sources.add(a);
}
@@ -267,7 +270,11 @@
List<List<ChangeData>> out = Lists.newArrayListWithCapacity(cnt);
for (int i = 0; i < cnt; i++) {
List<ChangeData> results = matches.get(i).toList();
- Collections.sort(results, sortkeyAfter != null ? cmpAfter : cmpBefore);
+ if (sortkeyAfter != null) {
+ Collections.sort(results, cmpAfter);
+ } else if (sortkeyBefore != null) {
+ Collections.sort(results, cmpBefore);
+ }
if (results.size() > maxLimit) {
moreResults = true;
}
@@ -302,10 +309,7 @@
List<ChangeData> results = queryChanges(queryString);
ChangeAttribute c = null;
for (ChangeData d : results) {
- ChangeControl cc = d.changeControl();
- if (cc == null || cc.getCurrentUser() != user) {
- cc = changeControlFactory.controlFor(d.change(), user);
- }
+ ChangeControl cc = d.changeControl().forUser(user);
LabelTypes labelTypes = cc.getLabelTypes();
c = eventFactory.asChangeAttribute(d.change());
@@ -412,16 +416,14 @@
}
private int limit(Predicate<ChangeData> s) {
- int n = ChangeQueryBuilder.hasLimit(s)
- ? ChangeQueryBuilder.getLimit(s)
- : maxLimit;
+ int n = Objects.firstNonNull(ChangeQueryBuilder.getLimit(s), maxLimit);
return limit > 0 ? Math.min(n, limit) + 1 : n + 1;
}
private Predicate<ChangeData> parseQuery(String queryString,
final Predicate<ChangeData> visibleToMe) throws QueryParseException {
Predicate<ChangeData> q = queryBuilder.parse(queryString);
- if (!ChangeQueryBuilder.hasSortKey(q)) {
+ if (queryBuilder.supportsSortKey() && !ChangeQueryBuilder.hasSortKey(q)) {
if (sortkeyBefore != null) {
q = Predicate.and(q, queryBuilder.sortkey_before(sortkeyBefore));
} else if (sortkeyAfter != null) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/SortKeyPredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/SortKeyPredicate.java
index 720027b..6fa11fd 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/SortKeyPredicate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/SortKeyPredicate.java
@@ -29,6 +29,10 @@
import com.google.inject.Provider;
public abstract class SortKeyPredicate extends IndexPredicate<ChangeData> {
+ public static boolean hasSortKeyField(Schema<ChangeData> schema) {
+ return sortkeyFieldOrNull(schema) != null;
+ }
+
@SuppressWarnings("deprecation")
private static long parseSortKey(Schema<ChangeData> schema, String value) {
FieldDef<ChangeData, ?> field = schema.getFields().get(SORTKEY.getName());
@@ -40,7 +44,8 @@
}
@SuppressWarnings("deprecation")
- private static FieldDef<ChangeData, ?> sortkeyField(Schema<ChangeData> schema) {
+ private static FieldDef<ChangeData, ?> sortkeyFieldOrNull(
+ Schema<ChangeData> schema) {
if (schema == null) {
return ChangeField.LEGACY_SORTKEY;
}
@@ -48,9 +53,13 @@
if (f != null) {
return f;
}
+ return schema.getFields().get(ChangeField.LEGACY_SORTKEY.getName());
+ }
+
+ private static FieldDef<ChangeData, ?> sortkeyField(Schema<ChangeData> schema) {
return checkNotNull(
- schema.getFields().get(ChangeField.LEGACY_SORTKEY.getName()),
- "schema missing sortkey field, found: %s", schema.getFields().keySet());
+ sortkeyFieldOrNull(schema),
+ "schema missing sortkey field, found: %s", schema);
}
protected final Schema<ChangeData> schema;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_65.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_65.java
index 624a51b..636e0c6 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_65.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_65.java
@@ -17,7 +17,6 @@
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-import com.google.common.primitives.Longs;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.ContributorAgreement;
import com.google.gerrit.common.data.GlobalCapability;
@@ -448,7 +447,7 @@
@Override
public int compare(
AccountGroupAgreement a1, AccountGroupAgreement a2) {
- return Longs.compare(a1.getTime(), a2.getTime());
+ return Long.compare(a1.getTime(), a2.getTime());
}
});
return groupAgreements;
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/git/SubmoduleOpTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/git/SubmoduleOpTest.java
index eb92bf9..33ba36e 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/git/SubmoduleOpTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/git/SubmoduleOpTest.java
@@ -30,8 +30,6 @@
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.reviewdb.server.SubmoduleSubscriptionAccess;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
-
-import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.util.TimeUtil;
import com.google.gwtorm.client.KeyUtil;
import com.google.gwtorm.server.ListResultSet;
@@ -81,7 +79,6 @@
private Provider<String> urlProvider;
private GitRepositoryManager repoManager;
private GitReferenceUpdated gitRefUpdated;
- private ChangeNotes.Factory notesFactory;
@SuppressWarnings("unchecked")
@Override
@@ -95,7 +92,6 @@
urlProvider = createStrictMock(Provider.class);
repoManager = createStrictMock(GitRepositoryManager.class);
gitRefUpdated = createStrictMock(GitReferenceUpdated.class);
- notesFactory = new ChangeNotes.Factory(repoManager);
}
private void doReplay() {
@@ -616,11 +612,10 @@
final Change submittedChange = new Change(
new Change.Key(sourceMergeTip.toObjectId().getName()), new Change.Id(1),
new Account.Id(1), sourceBranchNameKey, TimeUtil.nowTs());
- codeReviewCommit.notes = notesFactory.create(submittedChange);
final Map<Change.Id, CodeReviewCommit> mergedCommits =
new HashMap<Change.Id, CodeReviewCommit>();
- mergedCommits.put(codeReviewCommit.notes.getChangeId(), codeReviewCommit);
+ mergedCommits.put(submittedChange.getId(), codeReviewCommit);
final List<Change> submitted = new ArrayList<Change>();
submitted.add(submittedChange);
@@ -720,11 +715,10 @@
final Change submittedChange = new Change(
new Change.Key(sourceMergeTip.toObjectId().getName()), new Change.Id(1),
new Account.Id(1), sourceBranchNameKey, TimeUtil.nowTs());
- codeReviewCommit.notes = notesFactory.create(submittedChange);
final Map<Change.Id, CodeReviewCommit> mergedCommits =
new HashMap<Change.Id, CodeReviewCommit>();
- mergedCommits.put(codeReviewCommit.notes.getChangeId(), codeReviewCommit);
+ mergedCommits.put(submittedChange.getId(), codeReviewCommit);
final List<Change> submitted = new ArrayList<Change>();
submitted.add(submittedChange);
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/index/FakeIndex.java b/gerrit-server/src/test/java/com/google/gerrit/server/index/FakeIndex.java
index 339a1bb..4db3b27 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/index/FakeIndex.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/index/FakeIndex.java
@@ -31,7 +31,7 @@
ImmutableList.of(
ChangeField.STATUS,
ChangeField.PATH,
- ChangeField.SORTKEY));
+ ChangeField.UPDATED));
private static class Source implements ChangeDataSource {
private final Predicate<ChangeData> p;
@@ -88,8 +88,8 @@
}
@Override
- public ChangeDataSource getSource(Predicate<ChangeData> p, int limit)
- throws QueryParseException {
+ public ChangeDataSource getSource(Predicate<ChangeData> p, int start,
+ int limit) throws QueryParseException {
return new FakeIndex.Source(p);
}
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/index/IndexRewriteTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/index/IndexRewriteTest.java
index 87683e1..c8275e8 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/index/IndexRewriteTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/index/IndexRewriteTest.java
@@ -37,6 +37,7 @@
import org.junit.Before;
import org.junit.Test;
+import java.util.Arrays;
import java.util.EnumSet;
import java.util.Set;
@@ -54,7 +55,7 @@
queryBuilder = new FakeQueryBuilder(indexes);
rewrite = new IndexRewriteImpl(
indexes,
- new BasicChangeRewrites(null, indexes));
+ new BasicChangeRewrites(null));
}
@Test
@@ -97,7 +98,7 @@
parse("-status:abandoned (status:open OR status:merged)");
assertEquals(
query(parse("status:new OR status:submitted OR status:draft OR status:merged")),
- rewrite.rewrite(in));
+ rewrite.rewrite(in, 0));
}
@Test
@@ -169,6 +170,23 @@
}
@Test
+ public void testStartIncreasesLimit() throws Exception {
+ Predicate<ChangeData> f = parse("file:a");
+ Predicate<ChangeData> l = parse("limit:3");
+ Predicate<ChangeData> in = and(f, l);
+ assertEquals(and(query(f, 3), l), rewrite.rewrite(in, 0));
+ assertEquals(and(query(f, 4), l), rewrite.rewrite(in, 1));
+ assertEquals(and(query(f, 5), l), rewrite.rewrite(in, 2));
+ }
+
+ @Test
+ public void testStartDoesNotExceedMaxLimit() throws Exception {
+ Predicate<ChangeData> in = parse("file:a");
+ assertEquals(query(in), rewrite.rewrite(in, 0));
+ assertEquals(query(in), rewrite.rewrite(in, 1));
+ }
+
+ @Test
public void testGetPossibleStatus() throws Exception {
assertEquals(EnumSet.allOf(Change.Status.class), status("file:a"));
assertEquals(EnumSet.of(NEW), status("is:new"));
@@ -203,9 +221,14 @@
return queryBuilder.parse(query);
}
+ @SafeVarargs
+ private static AndSource and(Predicate<ChangeData>... preds) {
+ return new AndSource(Arrays.asList(preds));
+ }
+
private Predicate<ChangeData> rewrite(Predicate<ChangeData> in)
throws QueryParseException {
- return rewrite.rewrite(in);
+ return rewrite.rewrite(in, 0);
}
private IndexedChangeQuery query(Predicate<ChangeData> p)
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/index/IndexedChangeQueryTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/index/IndexedChangeQueryTest.java
deleted file mode 100644
index 3d21902..0000000
--- a/gerrit-server/src/test/java/com/google/gerrit/server/index/IndexedChangeQueryTest.java
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (C) 2013 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.index;
-
-import static com.google.gerrit.server.index.IndexedChangeQuery.replaceSortKeyPredicates;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-
-import com.google.gerrit.server.query.Predicate;
-import com.google.gerrit.server.query.QueryParseException;
-import com.google.gerrit.server.query.change.ChangeData;
-import com.google.gerrit.server.query.change.ChangeQueryBuilder;
-import org.junit.Before;
-import org.junit.Test;
-
-public class IndexedChangeQueryTest {
- private FakeIndex index;
- private ChangeQueryBuilder queryBuilder;
-
- @Before
- public void setUp() throws Exception {
- index = new FakeIndex(FakeIndex.V2);
- IndexCollection indexes = new IndexCollection();
- indexes.setSearchIndex(index);
- queryBuilder = new FakeQueryBuilder(indexes);
- }
-
- @Test
- public void testReplaceSortKeyPredicate_NoSortKey() throws Exception {
- Predicate<ChangeData> p = parse("foo:a bar:b OR (foo:b bar:a)");
- assertSame(p, replaceSortKeyPredicates(p, "1234"));
- }
-
- @Test
- public void testReplaceSortKeyPredicate_TopLevelSortKey() throws Exception {
- Predicate<ChangeData> p;
- p = parse("foo:a bar:b sortkey_before:1234 OR (foo:b bar:a)");
- assertEquals(parse("foo:a bar:b sortkey_before:5678 OR (foo:b bar:a)"),
- replaceSortKeyPredicates(p, "5678"));
- p = parse("foo:a bar:b sortkey_after:1234 OR (foo:b bar:a)");
- assertEquals(parse("foo:a bar:b sortkey_after:5678 OR (foo:b bar:a)"),
- replaceSortKeyPredicates(p, "5678"));
- }
-
- @Test
- public void testReplaceSortKeyPredicate_NestedSortKey() throws Exception {
- Predicate<ChangeData> p;
- p = parse("foo:a bar:b OR (foo:b bar:a AND sortkey_before:1234)");
- assertEquals(parse("foo:a bar:b OR (foo:b bar:a sortkey_before:5678)"),
- replaceSortKeyPredicates(p, "5678"));
- p = parse("foo:a bar:b OR (foo:b bar:a AND sortkey_after:1234)");
- assertEquals(parse("foo:a bar:b OR (foo:b bar:a sortkey_after:5678)"),
- replaceSortKeyPredicates(p, "5678"));
- }
-
- private Predicate<ChangeData> parse(String query) throws QueryParseException {
- return queryBuilder.parse(query);
- }
-}
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeNotesTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeNotesTest.java
index b3def07..0d7bb9f 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeNotesTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/notedb/ChangeNotesTest.java
@@ -19,9 +19,7 @@
import static com.google.gerrit.server.project.Util.category;
import static com.google.gerrit.server.project.Util.value;
import static com.google.inject.Scopes.SINGLETON;
-import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.easymock.EasyMock.expect;
import static org.junit.Assert.assertEquals;
@@ -38,7 +36,6 @@
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountCache;
@@ -73,6 +70,7 @@
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
+import org.joda.time.DateTime;
import org.joda.time.DateTimeUtils;
import org.joda.time.DateTimeUtils.MillisProvider;
import org.junit.After;
@@ -107,11 +105,12 @@
private IdentifiedUser changeOwner;
private IdentifiedUser otherUser;
private Injector injector;
+ private String systemTimeZone;
private volatile long clockStepMs;
@Before
public void setUp() throws Exception {
- setMillisProvider();
+ setTimeForTesting();
serverIdent = new PersonIdent(
"Gerrit Server", "noreply@gerrit.com", TimeUtil.nowTs(), TZ);
@@ -159,11 +158,11 @@
otherUser = userFactory.create(ou.getId());
}
- private void setMillisProvider() {
+ private void setTimeForTesting() {
+ systemTimeZone = System.setProperty("user.timezone", "US/Eastern");
clockStepMs = MILLISECONDS.convert(1, SECONDS);
final AtomicLong clockMs = new AtomicLong(
- MILLISECONDS.convert(ChangeUtil.SORT_KEY_EPOCH_MINS, MINUTES)
- + MILLISECONDS.convert(60, DAYS));
+ new DateTime(2009, 9, 30, 17, 0, 0).getMillis());
DateTimeUtils.setCurrentMillisProvider(new MillisProvider() {
@Override
@@ -174,8 +173,9 @@
}
@After
- public void resetMillisProvider() {
+ public void resetTime() {
DateTimeUtils.setCurrentMillisSystem();
+ System.setProperty("user.timezone", systemTimeZone);
}
@Test
@@ -207,7 +207,7 @@
assertEquals("1@gerrit", author.getEmailAddress());
assertEquals(new Date(c.getCreatedOn().getTime() + 1000),
author.getWhen());
- assertEquals(TimeZone.getTimeZone("GMT-8:00"), author.getTimeZone());
+ assertEquals(TimeZone.getTimeZone("GMT-7:00"), author.getTimeZone());
PersonIdent committer = commit.getCommitterIdent();
assertEquals("Gerrit Server", committer.getName());
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/project/Util.java b/gerrit-server/src/test/java/com/google/gerrit/server/project/Util.java
index d248c54..e4de9ed 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/project/Util.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/project/Util.java
@@ -29,20 +29,29 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.Project.NameKey;
+import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.rules.PrologEnvironment;
import com.google.gerrit.rules.RulesCache;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.CapabilityControl;
+import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.account.GroupMembership;
import com.google.gerrit.server.account.ListGroupMembership;
import com.google.gerrit.server.config.AllProjectsName;
+import com.google.gerrit.server.config.AnonymousCowardName;
+import com.google.gerrit.server.config.AnonymousCowardNameProvider;
+import com.google.gerrit.server.config.CanonicalWebUrl;
+import com.google.gerrit.server.config.CanonicalWebUrlProvider;
import com.google.gerrit.server.config.FactoryModule;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.ProjectConfig;
+import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.testutil.FakeAccountCache;
import com.google.gerrit.testutil.InMemoryRepositoryManager;
import com.google.inject.Guice;
import com.google.inject.Injector;
@@ -193,6 +202,7 @@
protected void configure() {
bind(Config.class).annotatedWith(GerritServerConfig.class).toInstance(
new Config());
+ bind(ReviewDb.class).toProvider(Providers.<ReviewDb> of(null));
bind(GitRepositoryManager.class).toInstance(repoManager);
bind(PatchListCache.class)
.toProvider(Providers.<PatchListCache> of(null));
@@ -201,6 +211,12 @@
factory(ChangeControl.AssistedFactory.class);
factory(ChangeData.Factory.class);
bind(ProjectCache.class).toInstance(projectCache);
+ bind(AccountCache.class).toInstance(new FakeAccountCache());
+ bind(GroupBackend.class).to(SystemGroupBackend.class);
+ bind(String.class).annotatedWith(CanonicalWebUrl.class)
+ .toProvider(CanonicalWebUrlProvider.class);
+ bind(String.class).annotatedWith(AnonymousCowardName.class)
+ .toProvider(AnonymousCowardNameProvider.class);
}
});
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
index 93300e3..295f841 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
@@ -15,7 +15,7 @@
package com.google.gerrit.server.query.change;
import static java.nio.charset.StandardCharsets.UTF_8;
-import static java.util.concurrent.TimeUnit.DAYS;
+import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.MINUTES;
import static org.junit.Assert.assertEquals;
@@ -35,7 +35,6 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountManager;
@@ -61,6 +60,7 @@
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.revwalk.RevCommit;
+import org.joda.time.DateTime;
import org.joda.time.DateTimeUtils;
import org.joda.time.DateTimeUtils.MillisProvider;
import org.junit.After;
@@ -94,6 +94,8 @@
protected CurrentUser user;
protected volatile long clockStepMs;
+ private String systemTimeZone;
+
protected abstract Injector createInjector();
@Before
@@ -136,11 +138,11 @@
}
@Before
- public void setMillisProvider() {
+ public void setTimeForTesting() {
+ systemTimeZone = System.setProperty("user.timezone", "US/Eastern");
clockStepMs = 1;
final AtomicLong clockMs = new AtomicLong(
- MILLISECONDS.convert(ChangeUtil.SORT_KEY_EPOCH_MINS, MINUTES)
- + MILLISECONDS.convert(60, DAYS));
+ new DateTime(2009, 9, 30, 17, 0, 0).getMillis());
DateTimeUtils.setCurrentMillisProvider(new MillisProvider() {
@Override
@@ -151,8 +153,9 @@
}
@After
- public void resetMillisProvider() {
+ public void resetTime() {
DateTimeUtils.setCurrentMillisSystem();
+ System.setProperty("user.timezone", systemTimeZone);
}
@Test
@@ -429,51 +432,104 @@
}
@Test
- public void pagination() throws Exception {
+ public void start() throws Exception {
TestRepository<InMemoryRepository> repo = createProject("repo");
List<Change> changes = Lists.newArrayList();
- for (int i = 0; i < 5; i++) {
+ for (int i = 0; i < 2; i++) {
changes.add(newChange(repo, null, null, null, null).insert());
}
- // Page forward and back through 3 pages of results.
+ QueryChanges q;
+ List<ChangeInfo> results;
+ results = query("status:new");
+ assertEquals(2, results.size());
+ assertResultEquals(changes.get(1), results.get(0));
+ assertResultEquals(changes.get(0), results.get(1));
+
+ q = newQuery("status:new");
+ q.setStart(1);
+ results = query(q);
+ assertEquals(1, results.size());
+ assertResultEquals(changes.get(0), results.get(0));
+
+ q = newQuery("status:new");
+ q.setStart(2);
+ results = query(q);
+ assertEquals(0, results.size());
+
+ q = newQuery("status:new");
+ q.setStart(3);
+ results = query(q);
+ assertEquals(0, results.size());
+ }
+
+ @Test
+ public void startWithLimit() throws Exception {
+ TestRepository<InMemoryRepository> repo = createProject("repo");
+ List<Change> changes = Lists.newArrayList();
+ for (int i = 0; i < 3; i++) {
+ changes.add(newChange(repo, null, null, null, null).insert());
+ }
+
QueryChanges q;
List<ChangeInfo> results;
results = query("status:new limit:2");
assertEquals(2, results.size());
- assertResultEquals(changes.get(4), results.get(0));
- assertResultEquals(changes.get(3), results.get(1));
-
- q = newQuery("status:new limit:2");
- q.setSortKeyBefore(results.get(1)._sortkey);
- results = query(q);
- assertEquals(2, results.size());
assertResultEquals(changes.get(2), results.get(0));
assertResultEquals(changes.get(1), results.get(1));
q = newQuery("status:new limit:2");
- q.setSortKeyBefore(results.get(1)._sortkey);
+ q.setStart(1);
+ results = query(q);
+ assertEquals(2, results.size());
+ assertResultEquals(changes.get(1), results.get(0));
+ assertResultEquals(changes.get(0), results.get(1));
+
+ q = newQuery("status:new limit:2");
+ q.setStart(2);
results = query(q);
assertEquals(1, results.size());
assertResultEquals(changes.get(0), results.get(0));
q = newQuery("status:new limit:2");
- q.setSortKeyAfter(results.get(0)._sortkey);
+ q.setStart(3);
results = query(q);
- assertEquals(2, results.size());
- assertResultEquals(changes.get(2), results.get(0));
- assertResultEquals(changes.get(1), results.get(1));
-
- q = newQuery("status:new limit:2");
- q.setSortKeyAfter(results.get(0)._sortkey);
- results = query(q);
- assertEquals(2, results.size());
- assertResultEquals(changes.get(4), results.get(0));
- assertResultEquals(changes.get(3), results.get(1));
+ assertEquals(0, results.size());
}
@Test
- public void sortKeyWithMinuteResolution() throws Exception {
+ public void updateOrder() throws Exception {
+ clockStepMs = MILLISECONDS.convert(2, MINUTES);
+ TestRepository<InMemoryRepository> repo = createProject("repo");
+ List<ChangeInserter> inserters = Lists.newArrayList();
+ List<Change> changes = Lists.newArrayList();
+ for (int i = 0; i < 5; i++) {
+ inserters.add(newChange(repo, null, null, null, null));
+ changes.add(inserters.get(i).insert());
+ }
+
+ for (int i : ImmutableList.of(2, 0, 1, 4, 3)) {
+ ReviewInput input = new ReviewInput();
+ input.message = "modifying " + i;
+ postReview.apply(
+ new RevisionResource(
+ this.changes.parse(changes.get(i).getId()),
+ inserters.get(i).getPatchSet()),
+ input);
+ changes.set(i, db.changes().get(changes.get(i).getId()));
+ }
+
+ List<ChangeInfo> results = query("status:new");
+ assertEquals(5, results.size());
+ assertResultEquals(changes.get(3), results.get(0));
+ assertResultEquals(changes.get(4), results.get(1));
+ assertResultEquals(changes.get(1), results.get(2));
+ assertResultEquals(changes.get(0), results.get(3));
+ assertResultEquals(changes.get(2), results.get(4));
+ }
+
+ @Test
+ public void updatedOrderWithMinuteResolution() throws Exception {
clockStepMs = MILLISECONDS.convert(2, MINUTES);
TestRepository<InMemoryRepository> repo = createProject("repo");
ChangeInserter ins1 = newChange(repo, null, null, null, null);
@@ -506,7 +562,7 @@
}
@Test
- public void sortKeyWithSubMinuteResolution() throws Exception {
+ public void updatedOrderWithSubMinuteResolution() throws Exception {
TestRepository<InMemoryRepository> repo = createProject("repo");
ChangeInserter ins1 = newChange(repo, null, null, null, null);
Change change1 = ins1.insert();
@@ -532,23 +588,9 @@
results = query("status:new");
assertEquals(2, results.size());
- // Same order as before change1 was modified.
- assertResultEquals(change2, results.get(0));
- assertResultEquals(change1, results.get(1));
- }
-
- @Test
- public void sortKeyBreaksTiesOnChangeId() throws Exception {
- clockStepMs = 0;
- TestRepository<InMemoryRepository> repo = createProject("repo");
- Change change1 = newChange(repo, null, null, null, null).insert();
- Change change2 = newChange(repo, null, null, null, null).insert();
- assertEquals(change1.getLastUpdatedOn(), change2.getLastUpdatedOn());
-
- List<ChangeInfo> results = query("status:new");
- assertEquals(2, results.size());
- assertResultEquals(change2, results.get(0));
- assertResultEquals(change1, results.get(1));
+ // change1 moved to the top.
+ assertResultEquals(change1, results.get(0));
+ assertResultEquals(change2, results.get(1));
}
@Test
@@ -561,7 +603,7 @@
newChange(repo, null, null, user2, null).insert();
}
- assertResultEquals(change, queryOne("status:new ownerin:Administrators"));
+ //assertResultEquals(change, queryOne("status:new ownerin:Administrators"));
assertResultEquals(change,
queryOne("status:new ownerin:Administrators limit:2"));
}
@@ -661,6 +703,130 @@
assertResultEquals(change, queryOne("comment:inline"));
}
+ @Test
+ public void byAge() throws Exception {
+ long thirtyHours = MILLISECONDS.convert(30, HOURS);
+ clockStepMs = thirtyHours;
+ TestRepository<InMemoryRepository> repo = createProject("repo");
+ Change change1 = newChange(repo, null, null, null, null).insert();
+ Change change2 = newChange(repo, null, null, null, null).insert();
+ clockStepMs = 0; // Queried by AgePredicate constructor.
+ long now = TimeUtil.nowMs();
+ assertEquals(thirtyHours, lastUpdatedMs(change2) - lastUpdatedMs(change1));
+ assertEquals(thirtyHours, now - lastUpdatedMs(change2));
+ assertEquals(now, TimeUtil.nowMs());
+
+ assertTrue(query("-age:1d").isEmpty());
+ assertTrue(query("-age:" + (30*60-1) + "m").isEmpty());
+ assertResultEquals(change2, queryOne("-age:2d"));
+
+ List<ChangeInfo> results;
+ results = query("-age:3d");
+ assertEquals(2, results.size());
+ assertResultEquals(change2, results.get(0));
+ assertResultEquals(change1, results.get(1));
+
+ assertTrue(query("age:3d").isEmpty());
+ assertResultEquals(change1, queryOne("age:2d"));
+
+ results = query("age:1d");
+ assertEquals(2, results.size());
+ assertResultEquals(change2, results.get(0));
+ assertResultEquals(change1, results.get(1));
+ }
+
+ @Test
+ public void byBeforeAbsolute() throws Exception {
+ clockStepMs = MILLISECONDS.convert(30, HOURS);
+ TestRepository<InMemoryRepository> repo = createProject("repo");
+ Change change1 = newChange(repo, null, null, null, null).insert();
+ Change change2 = newChange(repo, null, null, null, null).insert();
+ clockStepMs = 0;
+
+ // GitDateParser drops unparsed portions of the string, so be very careful
+ // with formats.
+ assertTrue(query("before:2009-09-29").isEmpty());
+ assertTrue(query("before:2009-09-30").isEmpty());
+ assertTrue(query("before:\"2009-09-30 16:59:00 -0400\"").isEmpty());
+ assertResultEquals(change1,
+ queryOne("before:\"2009-09-30 21:02:00 -0400\""));
+ assertResultEquals(change1, queryOne("before:2009-10-01"));
+
+ List<ChangeInfo> results;
+ results = query("before:2009-10-03");
+ assertEquals(2, results.size());
+ assertResultEquals(change2, results.get(0));
+ assertResultEquals(change1, results.get(1));
+ }
+
+ @Test
+ public void byBeforeRelative() throws Exception {
+ clockStepMs = MILLISECONDS.convert(30, HOURS);
+ TestRepository<InMemoryRepository> repo = createProject("repo");
+ Change change1 = newChange(repo, null, null, null, null).insert();
+ Change change2 = newChange(repo, null, null, null, null).insert();
+ clockStepMs = 0;
+
+ assertTrue(query("before:\"3 days ago\"").isEmpty());
+ assertResultEquals(change1, queryOne("before:\"2 days ago\""));
+
+ List<ChangeInfo> results;
+ results = query("before:\"1 day ago\"");
+ assertEquals(2, results.size());
+ assertResultEquals(change2, results.get(0));
+ assertResultEquals(change1, results.get(1));
+
+ results = query("before:\"12 hours ago\"");
+ assertEquals(2, results.size());
+ assertResultEquals(change2, results.get(0));
+ assertResultEquals(change1, results.get(1));
+ }
+
+ @Test
+ public void byAfterAbsolute() throws Exception {
+ clockStepMs = MILLISECONDS.convert(30, HOURS);
+ TestRepository<InMemoryRepository> repo = createProject("repo");
+ Change change1 = newChange(repo, null, null, null, null).insert();
+ Change change2 = newChange(repo, null, null, null, null).insert();
+ clockStepMs = 0;
+
+ // GitDateParser drops unparsed portions of the string, so be very careful
+ // with formats.
+ assertTrue(query("after:2009-10-02").isEmpty());
+ assertResultEquals(change2,
+ queryOne("after:\"2009-10-01 20:59:59 -0400\""));
+ assertResultEquals(change2, queryOne("after:2009-10-01"));
+
+ List<ChangeInfo> results;
+ results = query("after:2009-09-30");
+ assertEquals(2, results.size());
+ assertResultEquals(change2, results.get(0));
+ assertResultEquals(change1, results.get(1));
+ }
+
+ @Test
+ public void byAfterRelative() throws Exception {
+ clockStepMs = MILLISECONDS.convert(30, HOURS);
+ TestRepository<InMemoryRepository> repo = createProject("repo");
+ Change change1 = newChange(repo, null, null, null, null).insert();
+ Change change2 = newChange(repo, null, null, null, null).insert();
+ clockStepMs = 0;
+
+ assertTrue(query("after:\"1 days ago\"").isEmpty());
+ assertResultEquals(change2, queryOne("after:\"2 days ago\""));
+
+ List<ChangeInfo> results;
+ results = query("after:\"3 days ago\"");
+ assertEquals(2, results.size());
+ assertResultEquals(change2, results.get(0));
+ assertResultEquals(change1, results.get(1));
+
+ results = query("after:\"72 hours ago\"");
+ assertEquals(2, results.size());
+ assertResultEquals(change2, results.get(0));
+ assertResultEquals(change1, results.get(1));
+ }
+
protected ChangeInserter newChange(
TestRepository<InMemoryRepository> repo,
@Nullable RevCommit commit, @Nullable String key, @Nullable Integer owner,
@@ -750,7 +916,7 @@
return results.get(0);
}
- private static long lastUpdatedMs(Change c) {
+ protected static long lastUpdatedMs(Change c) {
return c.getLastUpdatedOn().getTime();
}
}
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/query/change/LuceneQueryChangesV7Test.java b/gerrit-server/src/test/java/com/google/gerrit/server/query/change/LuceneQueryChangesV7Test.java
new file mode 100644
index 0000000..948626e
--- /dev/null
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/query/change/LuceneQueryChangesV7Test.java
@@ -0,0 +1,145 @@
+// Copyright (C) 2013 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.query.change;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.Lists;
+import com.google.gerrit.extensions.api.changes.ReviewInput;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.server.change.ChangeInserter;
+import com.google.gerrit.server.change.ChangeJson.ChangeInfo;
+import com.google.gerrit.server.change.RevisionResource;
+import com.google.gerrit.testutil.InMemoryModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+
+import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.Config;
+import org.junit.Test;
+
+import java.util.List;
+
+public class LuceneQueryChangesV7Test extends AbstractQueryChangesTest {
+ protected Injector createInjector() {
+ Config cfg = InMemoryModule.newDefaultConfig();
+ cfg.setInt("index", "lucene", "testVersion", 7);
+ return Guice.createInjector(new InMemoryModule(cfg));
+ }
+
+ @Test
+ public void pagination() throws Exception {
+ TestRepository<InMemoryRepository> repo = createProject("repo");
+ List<Change> changes = Lists.newArrayList();
+ for (int i = 0; i < 5; i++) {
+ changes.add(newChange(repo, null, null, null, null).insert());
+ }
+
+ // Page forward and back through 3 pages of results.
+ QueryChanges q;
+ List<ChangeInfo> results;
+ results = query("status:new limit:2");
+ assertEquals(2, results.size());
+ assertResultEquals(changes.get(4), results.get(0));
+ assertResultEquals(changes.get(3), results.get(1));
+
+ q = newQuery("status:new limit:2");
+ q.setSortKeyBefore(results.get(1)._sortkey);
+ results = query(q);
+ assertEquals(2, results.size());
+ assertResultEquals(changes.get(2), results.get(0));
+ assertResultEquals(changes.get(1), results.get(1));
+
+ q = newQuery("status:new limit:2");
+ q.setSortKeyBefore(results.get(1)._sortkey);
+ results = query(q);
+ assertEquals(1, results.size());
+ assertResultEquals(changes.get(0), results.get(0));
+
+ q = newQuery("status:new limit:2");
+ q.setSortKeyAfter(results.get(0)._sortkey);
+ results = query(q);
+ assertEquals(2, results.size());
+ assertResultEquals(changes.get(2), results.get(0));
+ assertResultEquals(changes.get(1), results.get(1));
+
+ q = newQuery("status:new limit:2");
+ q.setSortKeyAfter(results.get(0)._sortkey);
+ results = query(q);
+ assertEquals(2, results.size());
+ assertResultEquals(changes.get(4), results.get(0));
+ assertResultEquals(changes.get(3), results.get(1));
+ }
+
+ @Override
+ @Test
+ public void updatedOrderWithSubMinuteResolution() throws Exception {
+ TestRepository<InMemoryRepository> repo = createProject("repo");
+ ChangeInserter ins1 = newChange(repo, null, null, null, null);
+ Change change1 = ins1.insert();
+ Change change2 = newChange(repo, null, null, null, null).insert();
+
+ assertTrue(lastUpdatedMs(change1) < lastUpdatedMs(change2));
+
+ List<ChangeInfo> results;
+ results = query("status:new");
+ assertEquals(2, results.size());
+ assertResultEquals(change2, results.get(0));
+ assertResultEquals(change1, results.get(1));
+
+ ReviewInput input = new ReviewInput();
+ input.message = "toplevel";
+ postReview.apply(new RevisionResource(
+ changes.parse(change1.getId()), ins1.getPatchSet()), input);
+ change1 = db.changes().get(change1.getId());
+
+ assertTrue(lastUpdatedMs(change1) > lastUpdatedMs(change2));
+ assertTrue(lastUpdatedMs(change1) - lastUpdatedMs(change2)
+ < MILLISECONDS.convert(1, MINUTES));
+
+ results = query("status:new");
+ assertEquals(2, results.size());
+ // Same order as before change1 was modified.
+ assertResultEquals(change2, results.get(0));
+ assertResultEquals(change1, results.get(1));
+ }
+
+ @Test
+ public void sortKeyBreaksTiesOnChangeId() throws Exception {
+ clockStepMs = 0;
+ TestRepository<InMemoryRepository> repo = createProject("repo");
+ ChangeInserter ins1 = newChange(repo, null, null, null, null);
+ Change change1 = ins1.insert();
+ Change change2 = newChange(repo, null, null, null, null).insert();
+
+ ReviewInput input = new ReviewInput();
+ input.message = "toplevel";
+ postReview.apply(new RevisionResource(
+ changes.parse(change1.getId()), ins1.getPatchSet()), input);
+ change1 = db.changes().get(change1.getId());
+
+ assertEquals(change1.getLastUpdatedOn(), change2.getLastUpdatedOn());
+
+ List<ChangeInfo> results = query("status:new");
+ assertEquals(2, results.size());
+ // Updated at the same time, 2 > 1.
+ assertResultEquals(change2, results.get(0));
+ assertResultEquals(change1, results.get(1));
+ }
+}
diff --git a/gerrit-solr/src/main/java/com/google/gerrit/solr/SolrChangeIndex.java b/gerrit-solr/src/main/java/com/google/gerrit/solr/SolrChangeIndex.java
index cf9c733..8c8b007 100644
--- a/gerrit-solr/src/main/java/com/google/gerrit/solr/SolrChangeIndex.java
+++ b/gerrit-solr/src/main/java/com/google/gerrit/solr/SolrChangeIndex.java
@@ -20,6 +20,7 @@
import static com.google.gerrit.solr.IndexVersionCheck.solrIndexConfig;
import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gerrit.extensions.events.LifecycleListener;
@@ -41,6 +42,7 @@
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.ChangeDataSource;
import com.google.gerrit.server.query.change.ChangeQueryBuilder;
+import com.google.gerrit.server.query.change.SortKeyPredicate;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.ResultSet;
import com.google.inject.Provider;
@@ -50,6 +52,7 @@
import org.apache.lucene.search.Query;
import org.apache.lucene.util.Version;
import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.SolrQuery.SortClause;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CloudSolrServer;
@@ -100,9 +103,9 @@
this.indexes = indexes;
this.schema = schema;
- String url = cfg.getString("index", "solr", "url");
+ String url = cfg.getString("index", null, "url");
if (Strings.isNullOrEmpty(url)) {
- throw new IllegalStateException("index.solr.url must be supplied");
+ throw new IllegalStateException("index.url must be supplied");
}
// Version is only used to determine the list of stop words used by the
@@ -210,7 +213,7 @@
}
@Override
- public ChangeDataSource getSource(Predicate<ChangeData> p, int limit)
+ public ChangeDataSource getSource(Predicate<ChangeData> p, int start, int limit)
throws QueryParseException {
Set<Change.Status> statuses = IndexRewriteImpl.getPossibleStatus(p);
List<SolrServer> indexes = Lists.newArrayListWithCapacity(2);
@@ -220,8 +223,24 @@
if (!Sets.intersection(statuses, CLOSED_STATUSES).isEmpty()) {
indexes.add(closedIndex);
}
- return new QuerySource(indexes, queryBuilder.toQuery(p), limit,
- ChangeQueryBuilder.hasNonTrivialSortKeyAfter(schema, p));
+ return new QuerySource(indexes, queryBuilder.toQuery(p), start, limit,
+ getSorts(schema, p));
+ }
+
+ @SuppressWarnings("deprecation")
+ private static List<SortClause> getSorts(Schema<ChangeData> schema,
+ Predicate<ChangeData> p) {
+ if (SortKeyPredicate.hasSortKeyField(schema)) {
+ boolean reverse = ChangeQueryBuilder.hasNonTrivialSortKeyAfter(schema, p);
+ return ImmutableList.of(new SortClause(ChangeField.SORTKEY.getName(),
+ !reverse ? SolrQuery.ORDER.desc : SolrQuery.ORDER.asc));
+ } else {
+ return ImmutableList.of(
+ new SortClause(
+ ChangeField.UPDATED.getName(), SolrQuery.ORDER.desc),
+ new SortClause(
+ ChangeField.LEGACY_ID.getName(), SolrQuery.ORDER.desc));
+ }
}
private void commit(SolrServer server) throws IOException {
@@ -236,17 +255,18 @@
private final List<SolrServer> indexes;
private final SolrQuery query;
- public QuerySource(List<SolrServer> indexes, Query q, int limit,
- boolean reverse) {
+ public QuerySource(List<SolrServer> indexes, Query q, int start, int limit,
+ List<SortClause> sorts) {
this.indexes = indexes;
query = new SolrQuery(q.toString());
query.setParam("shards.tolerant", true);
query.setParam("rows", Integer.toString(limit));
+ if (start != 0) {
+ query.setParam("start", Integer.toString(start));
+ }
query.setFields(ID_FIELD);
- query.setSort(
- ChangeField.SORTKEY.getName(),
- !reverse ? SolrQuery.ORDER.desc : SolrQuery.ORDER.asc);
+ query.setSorts(sorts);
}
@Override
@@ -329,8 +349,17 @@
doc.addField(name, (Long) value);
}
} else if (type == FieldType.TIMESTAMP) {
- for (Object v : values.getValues()) {
- doc.addField(name, QueryBuilder.toIndexTime((Timestamp) v));
+ @SuppressWarnings("deprecation")
+ boolean legacy = values.getField() == ChangeField.LEGACY_UPDATED;
+ if (legacy) {
+ for (Object value : values.getValues()) {
+ int t = queryBuilder.toIndexTimeInMinutes((Timestamp) value);
+ doc.addField(name, t);
+ }
+ } else {
+ for (Object value : values.getValues()) {
+ doc.addField(name, ((Timestamp) value).getTime());
+ }
}
} else if (type == FieldType.EXACT
|| type == FieldType.PREFIX
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/CommandMetaData.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/CommandMetaData.java
index e0fe7de..7fb9226 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/CommandMetaData.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/CommandMetaData.java
@@ -21,11 +21,19 @@
import java.lang.annotation.Target;
/**
- * Annotation tagged on a concrete Command to describe what it is doing
+ * Annotation tagged on a concrete Command to describe what it is doing and
+ * whether it can be run on slaves.
*/
-@Target( {ElementType.TYPE})
+@Target({ElementType.TYPE})
@Retention(RUNTIME)
public @interface CommandMetaData {
+ public enum Mode {
+ MASTER, MASTER_OR_SLAVE;
+ public boolean isSupported(boolean slaveMode) {
+ return this == MASTER_OR_SLAVE || !slaveMode;
+ }
+ }
String name();
String description() default "";
+ Mode runsAt() default Mode.MASTER;
}
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/CommandModule.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/CommandModule.java
index bfa4051..1e409d2 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/CommandModule.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/CommandModule.java
@@ -21,6 +21,8 @@
/** Module to register commands in the SSH daemon. */
public abstract class CommandModule extends LifecycleModule {
+ protected boolean slaveMode;
+
/**
* Configure a command to be invoked by name.
*
@@ -74,7 +76,9 @@
if (meta == null) {
throw new IllegalStateException("no CommandMetaData annotation found");
}
- bind(Commands.key(parent, meta.name(), meta.description())).to(clazz);
+ if (meta.runsAt().isSupported(slaveMode)) {
+ bind(Commands.key(parent, meta.name(), meta.description())).to(clazz);
+ }
}
/**
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java
index 8dc3f2c..40e58f2 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DatabasePubKeyAuth.java
@@ -140,14 +140,13 @@
}
}
- if (!SshUtil.createUser(sd, userFactory, key.getAccount())
- .getAccount().isActive()) {
+ IdentifiedUser cu = SshUtil.createUser(sd, userFactory, key.getAccount());
+ if (!cu.getAccount().isActive()) {
sd.authenticationError(username, "inactive-account");
return false;
}
- return SshUtil.success(username, session, sshScope, sshLog, sd,
- SshUtil.createUser(sd, userFactory, key.getAccount()));
+ return SshUtil.success(username, session, sshScope, sshLog, sd, cu);
}
private Set<PublicKey> getPeerKeys() {
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DispatchCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DispatchCommand.java
index d548d34..fa5ab53 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DispatchCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/DispatchCommand.java
@@ -21,7 +21,6 @@
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.account.CapabilityUtils;
import com.google.gerrit.server.args4j.SubcommandHandler;
-import com.google.gerrit.sshd.commands.ErrorSlaveMode;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted;
@@ -155,13 +154,9 @@
String format = "%-" + maxLength + "s %s";
for (String name : Sets.newTreeSet(commands.keySet())) {
final CommandProvider p = commands.get(name);
- Command c = p.getProvider().get();
- String description = c instanceof ErrorSlaveMode
- ? "Command disabled: server is running in slave mode"
- : Strings.nullToEmpty(p.getDescription());
-
usage.append(" ");
- usage.append(String.format(format, name, description));
+ usage.append(String.format(format, name,
+ Strings.nullToEmpty(p.getDescription())));
usage.append("\n");
}
usage.append("\n");
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshModule.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshModule.java
index 2c5499a..50ab639 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshModule.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshModule.java
@@ -31,7 +31,6 @@
import com.google.gerrit.server.plugins.StartPluginListener;
import com.google.gerrit.server.ssh.SshInfo;
import com.google.gerrit.server.util.RequestScopePropagator;
-import com.google.gerrit.sshd.commands.DefaultCommandModule;
import com.google.gerrit.sshd.commands.QueryShell;
import com.google.inject.Inject;
import com.google.inject.internal.UniqueAnnotations;
@@ -84,8 +83,6 @@
bind(GSSAuthenticator.class).to(GerritGSSAuthenticator.class);
bind(PublickeyAuthenticator.class).to(DatabasePubKeyAuth.class);
- install(new DefaultCommandModule());
-
bind(ModuleGenerator.class).to(SshAutoRegisterModuleGenerator.class);
bind(SshPluginStarterCallback.class);
bind(StartPluginListener.class)
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/AproposCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/AproposCommand.java
index a27027c..0aa12c4 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/AproposCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/AproposCommand.java
@@ -14,6 +14,8 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.documentation.QueryDocumentationExecutor;
import com.google.gerrit.server.documentation.QueryDocumentationExecutor.DocQueryException;
@@ -26,7 +28,8 @@
import java.util.List;
-@CommandMetaData(name = "apropos", description = "Search in Gerrit documentation")
+@CommandMetaData(name = "apropos", description = "Search in Gerrit documentation",
+ runsAt = MASTER_OR_SLAVE)
final class AproposCommand extends SshCommand {
@Inject
private QueryDocumentationExecutor searcher;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/BanCommitCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/BanCommitCommand.java
index dc22a29..1d4b900 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/BanCommitCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/BanCommitCommand.java
@@ -14,6 +14,8 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.gerrit.common.errors.PermissionDeniedException;
import com.google.gerrit.server.git.BanCommit;
import com.google.gerrit.server.git.BanCommitResult;
@@ -33,7 +35,8 @@
import java.util.ArrayList;
import java.util.List;
-@CommandMetaData(name = "ban-commit", description = "Ban a commit from a project's repository")
+@CommandMetaData(name = "ban-commit", description = "Ban a commit from a project's repository",
+ runsAt = MASTER_OR_SLAVE)
public class BanCommitCommand extends SshCommand {
@Option(name = "--reason", aliases = {"-r"}, metaVar = "REASON", usage = "reason for banning the commit")
private String reason;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/DefaultCommandModule.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/DefaultCommandModule.java
index 75743b0..f905c5b 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/DefaultCommandModule.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/DefaultCommandModule.java
@@ -21,18 +21,18 @@
import com.google.gerrit.sshd.SuExec;
-/** Register the basic commands any Gerrit server should support. */
+/** Register the commands a Gerrit server supports. */
public class DefaultCommandModule extends CommandModule {
+ public DefaultCommandModule(boolean slave) {
+ slaveMode = slave;
+ }
+
@Override
protected void configure() {
final CommandName git = Commands.named("git");
final CommandName gerrit = Commands.named("gerrit");
final CommandName plugin = Commands.named(gerrit, "plugin");
-
- // The following commands can be ran on a server in either Master or Slave
- // mode. If a command should only be used on a server in one mode, but not
- // both, it should be bound in both MasterCommandModule and
- // SlaveCommandModule.
+ final CommandName testSubmit = Commands.named(gerrit, "test-submit");
command(gerrit).toProvider(new DispatchCommandProvider(gerrit));
command(gerrit, AproposCommand.class);
@@ -49,7 +49,6 @@
command(gerrit, StreamEvents.class);
command(gerrit, VersionCommand.class);
command(gerrit, GarbageCollectionCommand.class);
-
command(gerrit, "plugin").toProvider(new DispatchCommandProvider(plugin));
command(plugin, PluginLsCommand.class);
@@ -61,21 +60,43 @@
alias(plugin, "rm", PluginRemoveCommand.class);
command(git).toProvider(new DispatchCommandProvider(git));
- command(git, "receive-pack").to(Commands.key(gerrit, "receive-pack"));
- command(git, "upload-pack").to(Upload.class);
command("ps").to(ShowQueue.class);
command("kill").to(KillCommand.class);
command("scp").to(ScpCommand.class);
// Honor the legacy hyphenated forms as aliases for the non-hyphenated forms
- //
command("git-upload-pack").to(Commands.key(git, "upload-pack"));
- command("git-receive-pack").to(Commands.key(git, "receive-pack"));
- command("gerrit-receive-pack").to(Commands.key(git, "receive-pack"));
-
+ command(git, "upload-pack").to(Upload.class);
command("suexec").to(SuExec.class);
-
listener().to(ShowCaches.StartupListener.class);
+
+ // The following commands can only be ran on a server in Master mode
+ command(gerrit, CreateAccountCommand.class);
+ command(gerrit, CreateGroupCommand.class);
+ command(gerrit, CreateProjectCommand.class);
+ command(gerrit, AdminQueryShell.class);
+ if (!slaveMode) {
+ command("git-receive-pack").to(Commands.key(git, "receive-pack"));
+ command("gerrit-receive-pack").to(Commands.key(git, "receive-pack"));
+ command(git, "receive-pack").to(Commands.key(gerrit, "receive-pack"));
+ command(gerrit, "test-submit").toProvider(
+ new DispatchCommandProvider(testSubmit));
+ }
+ command(gerrit, Receive.class);
+
+ command(gerrit, RenameGroupCommand.class);
+ command(gerrit, ReviewCommand.class);
+ command(gerrit, SetProjectCommand.class);
+ command(gerrit, SetReviewersCommand.class);
+
+ command(gerrit, SetMembersCommand.class);
+ command(gerrit, CreateBranchCommand.class);
+ command(gerrit, SetAccountCommand.class);
+ command(gerrit, AdminSetParent.class);
+
+ command(gerrit, CreateAccountCommand.class);
+ command(testSubmit, TestSubmitRuleCommand.class);
+ command(testSubmit, TestSubmitTypeCommand.class);
}
}
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ErrorSlaveMode.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ErrorSlaveMode.java
deleted file mode 100644
index 32c72038..0000000
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ErrorSlaveMode.java
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (C) 2009 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.sshd.commands;
-
-import com.google.gerrit.sshd.BaseCommand;
-
-import org.apache.sshd.server.Environment;
-
-import java.io.IOException;
-
-/**
- * A command which just throws an error because it shouldn't be ran on this
- * server. This is used when a user tries to run a command on a server in Slave
- * Mode, but the command only applies to the Master server.
- */
-public final class ErrorSlaveMode extends BaseCommand {
- @Override
- public void start(final Environment env) {
- String msg =
- "error: That command is disabled on this server.\n\n"
- + "Please use the master server URL.\n";
- try {
- err.write(msg.getBytes(ENC));
- err.flush();
- } catch (IOException e) {
- // Ignore errors writing to the client
- }
- onExit(1);
- }
-}
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/FlushCaches.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/FlushCaches.java
index 6c07ddd..40152b0 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/FlushCaches.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/FlushCaches.java
@@ -14,6 +14,8 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.common.cache.Cache;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
@@ -31,7 +33,8 @@
/** Causes the caches to purge all entries and reload. */
@RequiresCapability(GlobalCapability.FLUSH_CACHES)
-@CommandMetaData(name = "flush-caches", description = "Flush some/all server caches from memory")
+@CommandMetaData(name = "flush-caches", description = "Flush some/all server caches from memory",
+ runsAt = MASTER_OR_SLAVE)
final class FlushCaches extends CacheCommand {
private static final String WEB_SESSIONS = "web_sessions";
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/GarbageCollectionCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/GarbageCollectionCommand.java
index 81af0d8..821701d 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/GarbageCollectionCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/GarbageCollectionCommand.java
@@ -14,6 +14,8 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.common.collect.Lists;
import com.google.gerrit.common.data.GarbageCollectionResult;
import com.google.gerrit.common.data.GlobalCapability;
@@ -37,7 +39,8 @@
/** Runs the Git garbage collection. */
@RequiresCapability(GlobalCapability.RUN_GC)
-@CommandMetaData(name = "gc", description = "Run Git garbage collection")
+@CommandMetaData(name = "gc", description = "Run Git garbage collection",
+ runsAt = MASTER_OR_SLAVE)
public class GarbageCollectionCommand extends BaseCommand {
@Option(name = "--all", usage = "runs the Git garbage collection for all projects")
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListGroupsCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListGroupsCommand.java
index aadb1d9..f0169a8 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListGroupsCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListGroupsCommand.java
@@ -14,6 +14,8 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.gerrit.extensions.restapi.Url;
@@ -37,7 +39,8 @@
import java.io.PrintWriter;
-@CommandMetaData(name = "ls-groups", description = "List groups visible to the caller")
+@CommandMetaData(name = "ls-groups", description = "List groups visible to the caller",
+ runsAt = MASTER_OR_SLAVE)
public class ListGroupsCommand extends BaseCommand {
@Inject
private MyListGroups impl;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListMembersCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListMembersCommand.java
index b7dd380..2f367de 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListMembersCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListMembersCommand.java
@@ -14,6 +14,8 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
@@ -39,7 +41,8 @@
/**
* Implements a command that allows the user to see the members of a group.
*/
-@CommandMetaData(name = "ls-members", description = "Lists the members of a given group")
+@CommandMetaData(name = "ls-members", description = "Lists the members of a given group",
+ runsAt = MASTER_OR_SLAVE)
public class ListMembersCommand extends BaseCommand {
@Inject
ListMembersCommandImpl impl;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListProjectsCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListProjectsCommand.java
index 8bcae4b..78034fc 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListProjectsCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ListProjectsCommand.java
@@ -14,6 +14,8 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.gerrit.server.project.ListProjects;
import com.google.gerrit.sshd.BaseCommand;
import com.google.gerrit.sshd.CommandMetaData;
@@ -23,7 +25,8 @@
import java.util.List;
-@CommandMetaData(name = "ls-projects", description = "List projects visible to the caller")
+@CommandMetaData(name = "ls-projects", description = "List projects visible to the caller",
+ runsAt = MASTER_OR_SLAVE)
final class ListProjectsCommand extends BaseCommand {
@Inject
private ListProjects impl;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/LsUserRefs.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/LsUserRefs.java
index 207e5c2..c41fcdc 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/LsUserRefs.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/LsUserRefs.java
@@ -14,6 +14,7 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
import static org.eclipse.jgit.lib.RefDatabase.ALL;
import com.google.gerrit.common.data.GlobalCapability;
@@ -42,7 +43,8 @@
import java.util.Map;
@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
-@CommandMetaData(name = "ls-user-refs", description = "List refs visible to a specific user")
+@CommandMetaData(name = "ls-user-refs", description = "List refs visible to a specific user",
+ runsAt = MASTER_OR_SLAVE)
public class LsUserRefs extends SshCommand {
@Inject
private AccountResolver accountResolver;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/MasterCommandModule.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/MasterCommandModule.java
deleted file mode 100644
index a79e862..0000000
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/MasterCommandModule.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (C) 2009 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.sshd.commands;
-
-import com.google.gerrit.sshd.CommandModule;
-import com.google.gerrit.sshd.CommandName;
-import com.google.gerrit.sshd.Commands;
-import com.google.gerrit.sshd.DispatchCommandProvider;
-
-
-/** Register the commands a Gerrit server in master mode supports. */
-public class MasterCommandModule extends CommandModule {
- @Override
- protected void configure() {
- final CommandName gerrit = Commands.named("gerrit");
- final CommandName testSubmit = Commands.named(gerrit, "test-submit");
-
- command(gerrit, CreateAccountCommand.class);
- command(gerrit, CreateGroupCommand.class);
- command(gerrit, RenameGroupCommand.class);
- command(gerrit, CreateProjectCommand.class);
- command(gerrit, CreateBranchCommand.class);
- command(gerrit, AdminQueryShell.class);
- command(gerrit, SetReviewersCommand.class);
- command(gerrit, Receive.class);
- command(gerrit, AdminSetParent.class);
- command(gerrit, ReviewCommand.class);
- command(gerrit, SetAccountCommand.class);
- command(gerrit, SetMembersCommand.class);
- command(gerrit, SetProjectCommand.class);
-
- command(gerrit, "test-submit").toProvider(new DispatchCommandProvider(testSubmit));
- command(testSubmit, TestSubmitRuleCommand.class);
- command(testSubmit, TestSubmitTypeCommand.class);
- }
-}
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginEnableCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginEnableCommand.java
index 47c2d68..b2afde1 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginEnableCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginEnableCommand.java
@@ -14,6 +14,8 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.common.collect.Sets;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
@@ -28,7 +30,8 @@
import java.util.List;
@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
-@CommandMetaData(name = "enable", description = "Enable plugins")
+@CommandMetaData(name = "enable", description = "Enable plugins",
+ runsAt = MASTER_OR_SLAVE)
final class PluginEnableCommand extends SshCommand {
@Argument(index = 0, metaVar = "NAME", required = true, usage = "plugin(s) to enable")
List<String> names;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginInstallCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginInstallCommand.java
index 1e8035d..71f1517 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginInstallCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginInstallCommand.java
@@ -14,6 +14,8 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.common.base.Strings;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
@@ -35,7 +37,8 @@
import java.net.URL;
@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
-@CommandMetaData(name = "install", description = "Install/Add a plugin")
+@CommandMetaData(name = "install", description = "Install/Add a plugin",
+ runsAt = MASTER_OR_SLAVE)
final class PluginInstallCommand extends SshCommand {
@Option(name = "--name", aliases = {"-n"}, usage = "install under name")
private String name;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginLsCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginLsCommand.java
index 7e44641..9f6bb50 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginLsCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginLsCommand.java
@@ -14,6 +14,8 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.server.plugins.ListPlugins;
@@ -26,7 +28,8 @@
import java.io.IOException;
@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
-@CommandMetaData(name = "ls", description = "List the installed plugins")
+@CommandMetaData(name = "ls", description = "List the installed plugins",
+ runsAt = MASTER_OR_SLAVE)
final class PluginLsCommand extends BaseCommand {
@Inject
private ListPlugins impl;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginReloadCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginReloadCommand.java
index 3ed1011..8449160 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginReloadCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginReloadCommand.java
@@ -14,10 +14,12 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.gerrit.common.data.GlobalCapability;
+import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.server.plugins.InvalidPluginException;
import com.google.gerrit.server.plugins.PluginInstallException;
-import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.server.plugins.PluginLoader;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
@@ -28,7 +30,8 @@
import java.util.List;
@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
-@CommandMetaData(name = "reload", description = "Reload/Restart plugins")
+@CommandMetaData(name = "reload", description = "Reload/Restart plugins",
+ runsAt = MASTER_OR_SLAVE)
final class PluginReloadCommand extends SshCommand {
@Argument(index = 0, metaVar = "NAME", usage = "plugins to reload/restart")
private List<String> names;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginRemoveCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginRemoveCommand.java
index 0ae11af..757348f 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginRemoveCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginRemoveCommand.java
@@ -14,6 +14,8 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.common.collect.Sets;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
@@ -27,7 +29,8 @@
import java.util.List;
@RequiresCapability(GlobalCapability.ADMINISTRATE_SERVER)
-@CommandMetaData(name = "remove", description = "Disable plugins")
+@CommandMetaData(name = "remove", description = "Disable plugins",
+ runsAt = MASTER_OR_SLAVE)
final class PluginRemoveCommand extends SshCommand {
@Argument(index = 0, metaVar = "NAME", required = true, usage = "plugin to remove")
List<String> names;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Query.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Query.java
index af42e1b..2bda15d 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Query.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Query.java
@@ -14,6 +14,8 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.gerrit.server.query.change.QueryProcessor;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
@@ -24,7 +26,8 @@
import java.util.List;
-@CommandMetaData(name = "query", description = "Query the change database")
+@CommandMetaData(name = "query", description = "Query the change database",
+ runsAt = MASTER_OR_SLAVE)
class Query extends SshCommand {
@Inject
private QueryProcessor processor;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowCaches.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowCaches.java
index ff1de80..397120f 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowCaches.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowCaches.java
@@ -14,6 +14,8 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.common.cache.Cache;
import com.google.common.cache.CacheStats;
import com.google.common.collect.Maps;
@@ -54,7 +56,8 @@
/** Show the current cache states. */
@RequiresCapability(GlobalCapability.VIEW_CACHES)
-@CommandMetaData(name = "show-caches", description = "Display current cache statistics")
+@CommandMetaData(name = "show-caches", description = "Display current cache statistics",
+ runsAt = MASTER_OR_SLAVE)
final class ShowCaches extends CacheCommand {
private static volatile long serverStarted;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowConnections.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowConnections.java
index d97d750..17bea45 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowConnections.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowConnections.java
@@ -14,6 +14,8 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability;
import com.google.gerrit.server.CurrentUser;
@@ -46,7 +48,8 @@
/** Show the current SSH connections. */
@RequiresCapability(GlobalCapability.VIEW_CONNECTIONS)
-@CommandMetaData(name = "show-connections", description = "Display active client SSH connections")
+@CommandMetaData(name = "show-connections", description = "Display active client SSH connections",
+ runsAt = MASTER_OR_SLAVE)
final class ShowConnections extends SshCommand {
@Option(name = "--numeric", aliases = {"-n"}, usage = "don't resolve names")
private boolean numeric;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowQueue.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowQueue.java
index afb5787..40f7059 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowQueue.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowQueue.java
@@ -14,6 +14,8 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.git.TaskInfoFactory;
@@ -42,7 +44,8 @@
/** Display the current work queue. */
@AdminHighPriorityCommand
-@CommandMetaData(name = "show-queue", description = "Display the background work queues")
+@CommandMetaData(name = "show-queue", description = "Display the background work queues",
+ runsAt = MASTER_OR_SLAVE)
final class ShowQueue extends SshCommand {
@Option(name = "--wide", aliases = {"-w"}, usage = "display without line width truncation")
private boolean wide;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SlaveCommandModule.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SlaveCommandModule.java
deleted file mode 100644
index ac0eb0d..0000000
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SlaveCommandModule.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (C) 2009 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.sshd.commands;
-
-import com.google.gerrit.sshd.CommandModule;
-import com.google.gerrit.sshd.CommandName;
-import com.google.gerrit.sshd.Commands;
-
-
-/** Register the commands a Gerrit server in slave mode supports. */
-public class SlaveCommandModule extends CommandModule {
- @Override
- protected void configure() {
- final CommandName gerrit = Commands.named("gerrit");
-
- command(gerrit, "create-account").to(ErrorSlaveMode.class);
- command(gerrit, "create-group").to(ErrorSlaveMode.class);
- command(gerrit, "create-project").to(ErrorSlaveMode.class);
- command(gerrit, "gsql").to(ErrorSlaveMode.class);
- command(gerrit, "receive-pack").to(ErrorSlaveMode.class);
- command(gerrit, "rename-group").to(ErrorSlaveMode.class);
- command(gerrit, "review").to(ErrorSlaveMode.class);
- command(gerrit, "set-project-parent").to(ErrorSlaveMode.class);
- command(gerrit, "set-reviewers").to(ErrorSlaveMode.class);
- }
-}
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/StreamEvents.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/StreamEvents.java
index fd4a9ec..c55c7ed2 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/StreamEvents.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/StreamEvents.java
@@ -14,6 +14,8 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.common.ChangeListener;
import com.google.gerrit.common.data.GlobalCapability;
@@ -36,7 +38,8 @@
import java.util.concurrent.LinkedBlockingQueue;
@RequiresCapability(GlobalCapability.STREAM_EVENTS)
-@CommandMetaData(name = "stream-events", description = "Monitor events occurring in real time")
+@CommandMetaData(name = "stream-events", description = "Monitor events occurring in real time",
+ runsAt = MASTER_OR_SLAVE)
final class StreamEvents extends BaseCommand {
/** Maximum number of events that may be queued up for each connection. */
private static final int MAX_EVENTS = 128;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/VersionCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/VersionCommand.java
index 19888c8..50f880d 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/VersionCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/VersionCommand.java
@@ -14,11 +14,14 @@
package com.google.gerrit.sshd.commands;
+import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
+
import com.google.gerrit.common.Version;
import com.google.gerrit.sshd.CommandMetaData;
import com.google.gerrit.sshd.SshCommand;
-@CommandMetaData(name = "version", description = "Display gerrit version")
+@CommandMetaData(name = "version", description = "Display gerrit version",
+ runsAt = MASTER_OR_SLAVE)
final class VersionCommand extends SshCommand {
@Override
diff --git a/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java b/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java
index 32fac33..45cc4a2a 100644
--- a/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java
+++ b/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java
@@ -57,7 +57,7 @@
import com.google.gerrit.sshd.SshHostKeyModule;
import com.google.gerrit.sshd.SshKeyCacheImpl;
import com.google.gerrit.sshd.SshModule;
-import com.google.gerrit.sshd.commands.MasterCommandModule;
+import com.google.gerrit.sshd.commands.DefaultCommandModule;
import com.google.inject.AbstractModule;
import com.google.inject.CreationException;
import com.google.inject.Guice;
@@ -304,7 +304,7 @@
final List<Module> modules = new ArrayList<Module>();
modules.add(sysInjector.getInstance(SshModule.class));
modules.add(new SshHostKeyModule());
- modules.add(new MasterCommandModule());
+ modules.add(new DefaultCommandModule(false));
return sysInjector.createChildInjector(modules);
}
diff --git a/lib/maven.defs b/lib/maven.defs
index 09fd1a2..b874d8e 100644
--- a/lib/maven.defs
+++ b/lib/maven.defs
@@ -124,3 +124,37 @@
source_jar = genfile(srcjar) if srcjar else None,
visibility = visibility,
)
+
+def local_jar(
+ name,
+ jar,
+ src = None,
+ deps = [],
+ visibility = ['PUBLIC']):
+ binjar = name + '.jar'
+ srcjar = name + '-src.jar'
+ genrule(
+ name = name + '__local_bin',
+ cmd = 'ln -s %s $OUT' % jar,
+ out = binjar)
+ if src:
+ genrule(
+ name = name + '__local_src',
+ cmd = 'ln -s %s $OUT' % src,
+ out = srcjar)
+ prebuilt_jar(
+ name = name + '_src',
+ deps = [':' + name + '__local_src'],
+ binary_jar = genfile(srcjar),
+ visibility = visibility,
+ )
+ else:
+ srcjar = None
+
+ prebuilt_jar(
+ name = name,
+ deps = deps + [':' + name + '__local_bin'],
+ binary_jar = genfile(binjar),
+ source_jar = genfile(srcjar) if srcjar else None,
+ visibility = visibility,
+ )
diff --git a/tools/maven/mvn.py b/tools/maven/mvn.py
index a4aaa5a..250e89f 100644
--- a/tools/maven/mvn.py
+++ b/tools/maven/mvn.py
@@ -23,6 +23,9 @@
def mvn(action):
return ['mvn', '--file', path.join(self, 'fake_pom_%s.xml' % action)]
+def mvn(action):
+ return ['mvn', '--file', path.join(self, 'fake_pom_%s.xml' % action)]
+
opts = OptionParser()
opts.add_option('--repository', help='maven repository id')
opts.add_option('--url', help='maven repository url')