Merge "If file is unchanged, start scrolled to top"
diff --git a/.bazelrc b/.bazelrc
index 7230cf3..d6d4ce6 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -1,6 +1,11 @@
build --workspace_status_command=./tools/workspace-status.sh --strategy=Closure=worker
-build --disk_cache=~/.gerritcodereview/bazel-cache/cas
build --repository_cache=~/.gerritcodereview/bazel-cache/repository
build --experimental_strict_action_env
build --action_env=PATH
+build --disk_cache=~/.gerritcodereview/bazel-cache/cas
+build --java_toolchain //tools:error_prone_warnings_toolchain
+
test --build_tests_only
+test --test_output=errors
+
+import tools/remote-bazelrc
diff --git a/Documentation/access-control.txt b/Documentation/access-control.txt
index cdf6b30..d333347 100644
--- a/Documentation/access-control.txt
+++ b/Documentation/access-control.txt
@@ -727,13 +727,29 @@
A user must have this access granted in order to see a project, its
changes, or any of its data.
-This category has a special behavior, where the per-project ACL is
-evaluated before the global all projects ACL. If the per-project
-ACL has granted `Read` with 'DENY', and does not otherwise grant
-`Read` with 'ALLOW', then a `Read` in the all projects ACL
-is ignored. This behavior is useful to hide a handful of projects
+[[read_special_behaviors]]
+==== Special behaviors
+
+This category has multiple special behaviors:
+
+The per-project ACL is evaluated before the global all projects ACL.
+If the per-project ACL has granted `Read` with 'DENY', and does not
+otherwise grant `Read` with 'ALLOW', then a `Read` in the all projects
+ACL is ignored. This behavior is useful to hide a handful of projects
on an otherwise public server.
+You cannot grant `Read` on the `refs/tags/` namespace. Visibility to
+`refs/tags/` is derived from `Read` grants on refs namespaces other than
+`refs/tags/`, `refs/changes/`, and `refs/cache-automerge/` by finding
+tags reachable from those refs. For example, if a tag `refs/tags/test`
+points to a commit on the branch `refs/heads/master`, then allowing
+`Read` access to `refs/heads/master` would also allow access to
+`refs/tags/test`. If a tag is reachable from multiple refs, allowing
+access to any of those refs allows access to the tag.
+
+[[read_typical_usage]]
+==== Typical usage
+
For an open source, public Gerrit installation it is common to grant
`Read` to `Anonymous Users` in the `All-Projects` ACL, enabling
casual browsing of any project's changes, as well as fetching any
@@ -911,7 +927,7 @@
Suggested access rights to grant:
-* xref:category_read[`Read`] on 'refs/heads/\*' and 'refs/tags/*'
+* xref:category_read[`Read`] on 'refs/heads/\*'
* xref:category_push[`Push`] to 'refs/for/refs/heads/*'
* link:config-labels.html#label_Code-Review[`Code-Review`] with range '-1' to '+1' for 'refs/heads/*'
@@ -939,7 +955,7 @@
Suggested access rights to grant:
-* xref:category_read[`Read`] on 'refs/heads/\*' and 'refs/tags/*'
+* xref:category_read[`Read`] on 'refs/heads/\*'
* xref:category_push[`Push`] to 'refs/for/refs/heads/*'
* xref:category_push_merge[`Push merge commit`] to 'refs/for/refs/heads/*'
* xref:category_forge_author[`Forge Author Identity`] to 'refs/heads/*'
@@ -994,7 +1010,7 @@
Suggested access rights to grant, that won't block changes:
-* xref:category_read[`Read`] on 'refs/heads/\*' and 'refs/tags/*'
+* xref:category_read[`Read`] on 'refs/heads/\*'
* link:config-labels.html#label_Code-Review[`Label: Code-Review`] with range '-1' to '0' for 'refs/heads/*'
* link:config-labels.html#label_Verified[`Label: Verified`] with range '0' to '+1' for 'refs/heads/*'
diff --git a/Documentation/config-accounts.txt b/Documentation/config-accounts.txt
index 13e663e..e642425 100644
--- a/Documentation/config-accounts.txt
+++ b/Documentation/config-accounts.txt
@@ -275,7 +275,7 @@
To identify SSH keys in the REST API Gerrit uses
link:rest-api-accounts.html#ssh-key-id[sequence numbers per account].
This is why the order of the keys in the `authorized_keys` file is
-used to determines the sequence numbers of the keys (the sequence
+used to determine the sequence numbers of the keys (the sequence
numbers start at 1).
To keep the sequence numbers intact when a key is deleted, a
@@ -286,19 +286,21 @@
[[external-ids]]
== External IDs
-External IDs are used to link external identities, such as an LDAP
-account or an OAUTH identity, to an account in Gerrit.
+External IDs are used to link identities, such as the username and email
+addresses, and external identies such as an LDAP account or an OAUTH
+identity, to an account in Gerrit.
External IDs are stored as Git Notes in the `All-Users` repository. The
name of the notes branch is `refs/meta/external-ids`.
-As note key the SHA1 of the external ID key is used. This ensures that
-an external ID is used only once (e.g. an external ID can never be
-assigned to multiple accounts at a point in time).
+As note key the SHA1 of the external ID key is used, for example the key
+for the external ID `username:jdoe` is `e0b751ae90ef039f320e097d7d212f490e933706`.
+This ensures that an external ID is used only once (e.g. an external ID can
+never be assigned to multiple accounts at a point in time).
[IMPORTANT]
If the external ID key is changed manually you must adapt the note key
-to the new SHA1. Otherwise the external ID becomes inconsistent and is
+to the new SHA1, otherwise the external ID becomes inconsistent and is
ignored by Gerrit.
The note content is a Git config file:
@@ -310,14 +312,14 @@
password = bcrypt:4:LCbmSBDivK/hhGVQMfkDpA==:XcWn0pKYSVU/UJgOvhidkEtmqCp6oKB7
----
-The config file has one `externalId` section. The external ID key which
-consists of scheme and ID in the format '<scheme>:<id>' is used as
+The config file has one `externalId` section. The external ID key, which
+consists of scheme and ID in the format '<scheme>:<id>', is used as
subsection name.
-The `accountId` field is mandatory, the `email` and `password` fields
+The `accountId` field is mandatory. The `email` and `password` fields
are optional.
-The external IDs are maintained by Gerrit, this means users are not
+The external IDs are maintained by Gerrit. This means users are not
allowed to manually edit their external IDs. Only users with the
link:access-control.html#capability_accessDatabase[Access Database]
global capability can push updates to the `refs/meta/external-ids`
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 7e9f1e1..67cd0f9 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -1577,6 +1577,10 @@
[[core]]
=== Section core
+[NOTE]
+The link:#jgitConfig[etc/jgit.config] file supports configuration of all JGit
+options.
+
[[core.packedGitWindowSize]]core.packedGitWindowSize::
+
Number of bytes of a pack file to load into memory in a single
@@ -4924,6 +4928,19 @@
+
* link:config-themes.html[Themes]
+[[jgitConfig]]
+== File `etc/jgit.config`
+
+Gerrit uses the `$site_path/etc/jgit.config` file instead of the
+system-wide and user-global Git configuration for its runtime JGit
+configuration.
+
+Sample `etc/jgit.config` file:
+----
+[core]
+ trustFolderStat = false
+----
+
GERRIT
------
Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/config-mail.txt b/Documentation/config-mail.txt
index ef6a488..7d46e26 100644
--- a/Documentation/config-mail.txt
+++ b/Documentation/config-mail.txt
@@ -66,6 +66,12 @@
will be appended to emails related to a user submitting comments on changes.
See `ChangeSubject.soy`, Comment and ChangeFooter.
+=== DeleteKey.soy and DeleteKeyHtml.soy
+
+DeleteKey templates will determine the contents of the email related to SSH or GPG keys
+being deleted from a user account. This notification is not sent when the key is
+administratively deleted from another user account.
+
=== DeleteVote.soy and DeleteVoteHtml.soy
The DeleteVote templates will determine the contents of the email related to
@@ -83,6 +89,11 @@
The Footer templates will determine the contents of the footer text appended to
the end of all outgoing emails after the ChangeFooter and CommentFooter.
+=== HttpPasswordUpdate.soy and HttpPasswordUpdateHtml.soy
+
+HttpPasswordUpdate templates will determine the contents of the email related to adding,
+changing or deleting the HTTP password on a user account.
+
=== Merged.soy and MergedHtml.soy
The Merged templates will determine the contents of the email related to a
diff --git a/Documentation/config-robot-comments.txt b/Documentation/config-robot-comments.txt
index 0077697..f5185a4 100644
--- a/Documentation/config-robot-comments.txt
+++ b/Documentation/config-robot-comments.txt
@@ -36,7 +36,6 @@
== Limitations
-* Robot comments are not displayed in the web UI yet.
* There is no support for draft robot comments, but robot comments are
always published and visible to everyone who can see the change.
diff --git a/Documentation/dev-bazel.txt b/Documentation/dev-bazel.txt
index 2ab3d44..306fff9 100644
--- a/Documentation/dev-bazel.txt
+++ b/Documentation/dev-bazel.txt
@@ -8,14 +8,32 @@
* A Linux or macOS system (Windows is not supported at this time)
* A JDK for Java 8|9|10|11|...
* Python 2 or 3
-* Node.js
+* Node.js (including npm)
* link:https://www.bazel.io/versions/master/docs/install.html[Bazel]
* Maven
* zip, unzip
* gcc
-[[Java 10 and newer version support]]
-Java 10 (and newer is) supported through vanilla java toolchain
+[[java]]
+=== Java
+
+==== MacOS
+
+On MacOS, ensure that "Java for MacOS X 10.5 Update 4" (or higher) is installed
+and that `JAVA_HOME` is set to the
+link:install.html#Requirements[required Java version].
+
+Java installations can typically be found in
+"/System/Library/Frameworks/JavaVM.framework/Versions".
+
+To check the installed version of Java, open a terminal window and run:
+
+`java -version`
+
+[[java-10]]
+==== Java 10 support
+
+Java 10 (and newer) is supported through vanilla java toolchain
link:https://docs.bazel.build/versions/master/toolchains.html[Bazel option].
To build Gerrit with Java 10 and newer, specify vanilla java toolchain and
provide the path to JDK home:
@@ -66,7 +84,9 @@
javaOptions = --add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED
```
-[[Java 9 support]]
+[[java-9]]
+==== Java 9 support
+
Java 9 is supported through alternative java toolchain
link:https://docs.bazel.build/versions/master/toolchains.html[Bazel option].
The Java 9 support is backwards compatible. Java 8 is still the default.
@@ -87,6 +107,9 @@
javaOptions = --add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED
```
+=== Node.js and npm packages
+See link:https://gerrit.googlesource.com/gerrit/+/master/polygerrit-ui/README.md#installing-node_js-and-npm-packages[Installing Node.js and npm packages].
+
[[build]]
== Building on the Command Line
@@ -98,10 +121,6 @@
bazel build gerrit
----
-[NOTE]
-PolyGerrit UI may require additional tools (such as npm). Please read
-the polygerrit-ui/README.md for more info.
-
The output executable WAR will be placed in:
----
@@ -200,13 +219,6 @@
Note that when building an individual plugin, the `core.zip` package
is not regenerated.
-To build with all Error Prone warnings activated, run:
-
-----
- bazel build --java_toolchain //tools:error_prone_warnings_toolchain //...
-----
-
-
[[IDEs]]
== Using an IDE.
@@ -548,6 +560,43 @@
wrapper script. For an example, see the use of `crisper` in `tools/bzl/js.bzl`.
+
+[[RBE]]
+== Google Remote Build Support
+
+The Bazel build can be used with Google's Remote Build Execution.
+
+
+This needs the following setup steps:
+
+```
+gcloud auth application-default login
+gcloud services enable remotebuildexecution.googleapis.com --project=${PROJECT}
+```
+
+Create a worker pool. The instances should have at least 4 CPUs each
+for adequate performance.
+
+```
+gcloud alpha remote-build-execution worker-pools create default \
+ --project=${PROJECT} \
+ --instance=default_instance \
+ --worker-count=50 \
+ --machine-type=n1-highcpu-4 \
+ --disk-size=200
+```
+
+To use RBE, execute
+
+```
+bazel test --config=remote \
+ --remote_instance_name=projects/${PROJECT}/instances/default_instance \
+ javatests/...
+```
+
+
+
+
GERRIT
------
Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/dev-build-plugins.txt b/Documentation/dev-build-plugins.txt
index 072c22c..47ace5b 100644
--- a/Documentation/dev-build-plugins.txt
+++ b/Documentation/dev-build-plugins.txt
@@ -75,6 +75,12 @@
Some plugins describe their build process in `src/main/resources/Documentation/build.md`
file. It may worth checking.
+=== Error Prone checks
+
+Error Prone checks are enabled by default for core Gerrit and all core plugins. To
+enable the checks for custom plugins, add it in the `error_prone_packages` group
+in `tools/BUILD`.
+
=== Plugins with external dependencies ===
If the plugin has external dependencies, then they must be included from Gerrit's
diff --git a/Documentation/dev-cla.txt b/Documentation/dev-cla.txt
index 3311d49..267351f 100644
--- a/Documentation/dev-cla.txt
+++ b/Documentation/dev-cla.txt
@@ -13,10 +13,10 @@
tab on the settings page
. Click on 'New Contributor Agreement' and follow the instructions
-For reference, the actual agreements are linked below
+For reference, the actual agreements are linked below:
-* link:https://cla.developers.google.com/about/android-individual[Individual Agreement]
-* link:https://source.android.com/source/cla-corporate.pdf[Corporate Agreement]
+* link:https://cla.developers.google.com/about/google-individual[Individual Agreement]
+* link:https://cla.developers.google.com/about/google-corporate[Corporate Agreement]
GERRIT
------
diff --git a/Documentation/dev-community.txt b/Documentation/dev-community.txt
index b9036b8..0656090 100644
--- a/Documentation/dev-community.txt
+++ b/Documentation/dev-community.txt
@@ -15,7 +15,12 @@
* link:https://gerrit-review.googlesource.com/q/status:open+project:gerrit[Change Review]
* link:dev-design.html[System Design]
* Processes
-** link:dev-contributing.html[Contribution Process]
+** link:dev-processes.html#project-governance[Project Governance / Engineering Steering Committee]
+** link:dev-contributing.html#contribution-processes[Contribution Processes]
+*** link:dev-contributing.html#lightweight-contribution-process[Lightweight Contribution Process]
+*** link:dev-contributing.html#design-driven-contribution-process[Design-Driven Contribution Process]
+*** link:dev-contributing.html#mentorship[Mentorship]
+** link:dev-design-docs.html#review[Design doc reviews]
** link:dev-processes.html#dev-in-stable-branches[Development in stable branches]
** link:dev-processes.html#backporting[Backporting to stable branches]
** link:dev-processes.html#upgrading-libraries[Upgrading Libraries]
@@ -24,14 +29,21 @@
** link:dev-roles.html#supporter[Supporter]
** link:dev-roles.html#contributor[Contributor]
** link:dev-roles.html#maintainer[Maintainer]
+** link:dev-roles.html#mentor[Mentor]
+** link:dev-roles.html#steering-committee-member[Engineering Steering Committee Member]
+** link:dev-roles.html#community-manager[Community Manager]
** link:dev-roles.html#release-manager[Release Manager]
[[how-to-contribute]]
== How to contribute?
* link:dev-cla.html[Contributor License Agreement]
-* link:dev-contributing.html[Contributing to Gerrit]
+* link:dev-contributing.html#contribution-processes[Contribution Processes]
+** link:dev-contributing.html#lightweight-contribution-process[Lightweight Contribution Process]
+** link:dev-contributing.html#design-driven-contribution-process[Design-Driven Contribution Process]
+** link:dev-contributing.html#mentorship[Mentorship]
+* link:dev-design-docs.html[Design Docs]
* link:dev-readme.html[Developer Setup]
-* link:dev-frontend-readme.html[Polymer Frontend Developer Setup]
+* link:https://gerrit.googlesource.com/gerrit/+/master/polygerrit-ui[Polymer Frontend Developer Setup]
* link:dev-crafting-changes.html[Crafting Changes]
* link:dev-starter-projects.html[Starter Projects]
@@ -48,7 +60,7 @@
== Maintainer
* link:dev-release.html[Making a Gerrit Release]
* link:dev-release-subproject.html[Making a Release of a Gerrit Subproject]
-* link:dev-release-jgit.html[Making a Release of JGit]
+* link:https://www.gerritcodereview.com/publishing.html[Publish Gerrit Homepage]
GERRIT
------
diff --git a/Documentation/dev-contributing.txt b/Documentation/dev-contributing.txt
index 5d6941d..0bac643 100644
--- a/Documentation/dev-contributing.txt
+++ b/Documentation/dev-contributing.txt
@@ -6,13 +6,84 @@
In order to contribute to Gerrit a link:dev-cla.html[Contributor
License Agreement] must be completed before contributions are accepted.
-[[contribution-process]]
-== Contribution Process
+[[contribution-processes]]
+== Contribution Processes
+
+The Gerrit project offers two contribution processes:
+
+* link:#lightweight-contribution-process[Lightweight Contribution
+ Process]
+* link:#design-driven-contribution-process[Design-Driven Contribution
+ Process]
+
+The lightweight contribution process has little overhead and is best
+suited for small contributions (documentation updates, bug fixes, small
+features). Contributions are pushed as changes and
+link:dev-roles.html#maintainer[maintainers] review them adhoc.
+
+For large/complex features, it is required to follow the
+link:#design-driven-contribution-process[design-driven contribution
+process] and specify the feature in a link:dev-design-docs.html[design
+doc] before starting with the implementation.
+
+If link:dev-roles.html#contributor[contributors] choose the
+lightweight contribution process and during the review it turns out
+that the feature is too large or complex,
+link:dev-roles.html#maintainer[maintainers] can require to follow the
+design-driven contribution process instead.
+
+If you are in doubt which process is right for you, consult the
+link:https://groups.google.com/d/forum/repo-discuss[repo-discuss]
+mailing list.
+
+These contribution processes apply to everyone who contributes code to
+the Gerrit project, including link:dev-roles.html#maintainer[
+maintainers]. When reading this document, keep in mind that maintainers
+are also contributors when they contribute code.
+
+If a new feature is large or complex, it is often difficult to find a
+maintainer who can take the time that is needed for a thorough review,
+and who can help with getting the changes submitted. To avoid that this
+results in unpredictable long waiting times during code review,
+contributors can ask for link:#mentorship[mentor support]. A mentor
+helps with timely code reviews and technical guidance. Doing the
+implementation is still the responsibility of the contributor.
+
+[[comparison]]
+=== Quick Comparison
+
+[options="header"]
+|======================
+| |Lightweight Contribution Process|Design-Driven Contribution Process
+|Overhead|low (write good commit message, address review comments)|
+high (write link:dev-design-docs.html[design doc] and get it approved)
+|Technical Guidance|by reviewer|during the design review and by
+reviewer/mentor
+|Review |adhoc (when reviewer is available)|by a dedicated mentor (if
+a link:#mentorship[mentor] was assigned)
+|Caveats |features may get vetoed after the implementation was already
+done, maintainers may make the design-driven contribution process
+required if a change gets too complex/large|design doc must stay open
+for a minimum of 10 calendar days, a mentor may not be available
+immediately
+|Applicable to|documentation updates, bug fixes, small features|
+large/complex features
+|======================
+
+[[lightweight-contribution-process]]
+=== Lightweight Contribution Process
+
+The lightweight contribution process has little overhead and is best
+suited for small contributions (documentation updates, bug fixes, small
+features). For large/complex features the
+link:#design-driven-contribution-process[design-driven contribution
+process] is required.
As Gerrit is a code review tool, naturally contributions will
be reviewed before they will get submitted to the code base. To
start your contribution, please make a git commit and upload it
-for review to the main Gerrit review server. To help speed up the
+for review to the link:https://gerrit-review.googlesource.com/[
+gerrit-review.googlesource.com] Gerrit server. To help speed up the
review of your change, review these link:dev-crafting-changes.html[
guidelines] before submitting your change. You can view the pending
Gerrit contributions and their statuses
@@ -20,24 +91,158 @@
Depending on the size of that list it might take a while for
your change to get reviewed. Naturally there are fewer
-approvers than contributors; so anything that you can do to
-ensure that your contribution will undergo fewer revisions
-will speed up the contribution process. This includes helping
-out reviewing other people's changes to relieve the load from
-the approvers. Even if you are not familiar with Gerrit's
-internals, it would be of great help if you can download, try
-out, and comment on new features. If it works as advertised,
-say so, and if you have the privileges to do so, go ahead
-and give it a +1 Verified. If you would find the feature
-useful, say so and give it a +1 code review.
+link:dev-roles.html#maintainer[maintainers], that can approve changes,
+than link:dev-roles.html#contributor[contributors]; so anything that
+you can do to ensure that your contribution will undergo fewer
+revisions will speed up the contribution process. This includes
+helping out reviewing other people's changes to relieve the load from
+the maintainers. Even if you are not familiar with Gerrit's internals,
+it would be of great help if you can download, try out, and comment on
+new features. If it works as advertised, say so, and if you have the
+privileges to do so, go ahead and give it a `+1 Verified`. If you
+would find the feature useful, say so and give it a `+1 Code Review`.
-And finally, the quicker you respond to the comments of your
-reviewers, the quicker your change might get merged! Try to
-reply to every comment after submitting your new patch,
-particularly if you decided against making the suggested change.
-Reviewers don't want to seem like nags and pester you if you
-haven't replied or made a fix, so it helps them know if you
-missed it or decided against it.
+And finally, the quicker you respond to the comments of your reviewers,
+the quicker your change might get merged! Try to reply to every
+comment after submitting your new patch, particularly if you decided
+against making the suggested change. Reviewers don't want to seem like
+nags and pester you if you haven't replied or made a fix, so it helps
+them know if you missed it or decided against it.
+
+[[design-driven-contribution-process]]
+=== Design-driven Contribution Process
+
+The design-driven contribution process applies to large/complex
+features.
+
+For large/complex features it is important to:
+
+* agree on the functionality and scope before spending too much time
+ on the implementation
+* ensure that they are in line with Gerrit's project scope and vision
+* ensure that they are well aligned with other features
+* think about possibilities how the feature could be evolved over time
+
+This is why for large/complex features it is required to describe the
+feature in a link:dev-design-docs.html[design doc] and get it approved
+by the link:dev-processes.html#steering-committee[steering committee],
+before starting the implementation.
+
+The design-driven contribution process has the following steps:
+
+* A link:dev-roles.html#contributor[contributor]
+ link:dev-design-docs.html#propose[proposes] a new feature by
+ uploading a change with a link:dev-design-docs.html[design doc].
+* The design doc is link:dev-design-docs.html#review[reviewed] by
+ interested parties from the community. The design review is public
+ and everyone can comment and raise concerns.
+* Design docs should stay open for a minimum of 10 calendar days so
+ that everyone has a fair chance to join the review.
+* Within 14 calendar days the contributor should hear back from the
+ link:dev-processes.html#steering-committee[steering committee]
+ whether the proposed feature is in scope of the project and if it can
+ be accepted.
+* To be submitted, the design doc needs to be approved by the
+ link:dev-processes.html#steering-committee[steering committee].
+* After the design was approved, the implementation is done by pushing
+ changes for review, see link:#lightweight-contribution-process[
+ lightweight contribution process]. Changes that are associated with
+ a design should all share a common hashtag. The contributor is the
+ main driver of the implementation and responsible that it is done.
+ Others from the Gerrit community are usually much welcome to help
+ with the implementation.
+
+In order to be accepted/submitted, it is not necessary that the design
+doc fully specifies all the details, but the idea of the feature and
+how it fits into Gerrit should be sufficiently clear (judged by the
+steering committee). Contributors are expected to keep the design doc
+updated and fill in gaps while they go forward with the implementation.
+We expect that implementing the feature and updating the design doc
+will be an iterative process.
+
+While the design doc is still in review, contributors may already start
+with the implementation (e.g. do some prototyping to demonstrate parts
+of the proposed design), but those changes should not be submitted
+while the design wasn't approved yet.
+
+By approving a design, the steering committee commits to:
+
+* Accepting the feature when it is implemented.
+* Supporting the feature by assigning a link:dev-roles.html#mentor[
+ mentor] (if requested, see link:#mentorship[mentorship]).
+
+If the implementation of a feature gets stuck and it's unclear whether
+the feature gets fully done, it should be discussed with the steering
+committee how to proceed. If the contributor cannot commit to finish
+the implementation and no other contributor can take over, changes that
+have already been submitted for the feature might get reverted so that
+there is no unused or half-finished code in the code base.
+
+For contributors, the design-driven contribution process has the
+following advantages:
+
+* By writing a design doc, the feature gets more attention. During the
+ design review, feedback from various sides can be collected, which
+ likely leads to improvements of the feature.
+* Once a design was approved by the
+ link:dev-processes.html#steering-committee[steering committee], the
+ contributor can be almost certain that the feature will be accepted.
+ Hence, there is only a low risk to invest into implementing a feature
+ and see it being rejected later during the code review, as it can
+ happen with the lightweight contribution process.
+* The contributor can link:#mentorship[get a dedicated mentor assigned]
+ who provides timely reviews and serves as a contact person for
+ technical questions and discussing details of the design.
+
+[[mentorship]]
+== Mentorship
+
+For features for which a link:dev-design-docs.html[design] has been
+approved (see link:#design-driven-contribution-process[design-driven
+contribution process]), contributors can gain the support of a mentor
+if they are committed to implement the feature.
+
+A link:dev-roles.html#mentor[mentor] helps with:
+
+* doing timely reviews
+* providing technical guidance during code reviews
+* discussing details of the design
+* ensuring that the quality standards are met (well documented,
+ sufficient test coverage, backwards compatible etc.)
+
+A feature can have more than one mentor. To be able to deliver the
+promised support, at least one of the mentors must be a
+link:dev-roles.html#maintainer[maintainer].
+
+Mentors are assigned by the link:dev-processes.html#steering-committee[
+steering committee]. To gain a mentor, ask for a mentor in the
+link:dev-design-doc-template.html#implementation-plan[Implementation
+Plan] section of the design doc or ask the steering committee after the
+design has been approved.
+
+Mentors may not be available immediately. In this case, the steering
+committee should include the approved feature into the roadmap or
+prioritize it in the backlog. This way, it is transparent for the
+contributor when they can expect to be able to work on the feature with
+mentor support.
+
+Once the implementation phase starts, the contributor is expected to do
+the implementation in a timely manner.
+
+For every mentorship, the end must be clearly defined. The design doc
+must specify:
+
+* a maximum time frame for the mentorship, after which the mentorship
+ automatically ends, even if the feature is not done yet
+* done criteria that define when the feature is done and the mentorship
+ ends
+
+If a feature is not finished in time, it should be discussed with the
+steering committee how to proceed. If the contributor cannot commit to
+finish the implementation in time and no other contributor can take
+over, changes that have already been submitted for the feature might
+get reverted so that there is no unused or half-finished code in the
+code base.
GERRIT
------
diff --git a/Documentation/dev-crafting-changes.txt b/Documentation/dev-crafting-changes.txt
index ef96e6b..0f93be7 100644
--- a/Documentation/dev-crafting-changes.txt
+++ b/Documentation/dev-crafting-changes.txt
@@ -110,7 +110,7 @@
link:https://github.com/google/google-java-format[`google-java-format`]
tool (version 1.7), and to format Bazel BUILD, WORKSPACE and .bzl files the
link:https://github.com/bazelbuild/buildtools/tree/master/buildifier[`buildifier`]
-tool (version 0.20.0).
+tool (version 0.22.0).
These tools automatically apply format according to the style guides; this
streamlines code review by reducing the need for time-consuming, tedious,
and contentious discussions about trivial issues like whitespace.
diff --git a/Documentation/dev-design-doc-template.txt b/Documentation/dev-design-doc-template.txt
new file mode 100644
index 0000000..9480d97
--- /dev/null
+++ b/Documentation/dev-design-doc-template.txt
@@ -0,0 +1,79 @@
+= Gerrit Code Review - ${title}
+
+[[objective]]
+== Objective
+
+In a few sentences, describe the key system objectives. Define the
+goals and non-goals.
+
+[[background]]
+== Background
+
+Stuff one needs to know to understand this doc (e.g. motivating
+examples, previous versions and problems, links to related
+changes/design docs, etc.
+
+Note: this is background; do not write about your design or ideas to
+solve problems here.
+
+[[overview]]
+== Overview
+
+High-level overview; put details in the next section and background in
+the previous section. Should be understandable by engineers that are
+not working on Gerrit.
+
+[[detailed-design]]
+== Detailed Design
+
+How does the overall design work? Details about the algorithms,
+storage format, APIs, etc., should be included here.
+
+It is ok for this to lack in detail at first for initial review.
+
+[[alternatives-considered]]
+== Alternatives Considered
+
+You may need to describe what you did not do or why simpler approaches
+don't work. Mention other things to watch out for (if any).
+
+[[implemenation-plan]]
+== Implementation Plan
+
+If known, say who is driving the implementation, for when the
+implementation is planned and which priority it has for you.
+
+It is possible to contribute designs without having resources to do the
+implementation. In this case, say so here.
+
+If mentor support is desired, say so here. Also briefly describe any
+circumstances that can help with finding a suitable mentor.
+
+[[time-estimation]]
+=== Time Estimation
+
+A rough itemized estimation of how much time it takes to implement this
+feature. Break down the feature into work items and estimate each item
+separately.
+
+If a mentor is assigned, this section must define a maximum time frame
+after which the mentorship automatically ends even if the feature isn't
+fully done yet.
+
+[[done-criteria]]
+== Done Criteria
+
+Describe the conditions that must be satisfied to consider this feature
+as done.
+
+If a mentor is assigned, the mentorship ends when this state is reached.
+Please note that a mentorship can also end earlier if the maximum time
+frame for the mentorship has exceeded (see section 'Time Estimation'
+above).
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
+
+SEARCHBOX
+---------
diff --git a/Documentation/dev-design-docs.txt b/Documentation/dev-design-docs.txt
new file mode 100644
index 0000000..621fd70
--- /dev/null
+++ b/Documentation/dev-design-docs.txt
@@ -0,0 +1,62 @@
+= Gerrit Code Review - Design Docs
+
+For the link:dev-contributing.html#design-driven-contribution-process[
+design-driven contribution process] it is required to specify features
+upfront in a design doc.
+
+[[propose]]
+== How to propose a new design?
+
+To propose a new design, add a `design-${title}.txt` file to this
+folder and push it as change for review. The design doc should follow
+the structure of the link:dev-design-doc-template.html[design doc
+template] and the change should be marked with the hashtag
+`design-doc`.
+
+Pushing a design doc for review requires to be a
+link:dev-roles.html#contributor[contributor].
+
+When contributing design docs, contributors should make clear whether
+they are committed to do the implementation. It is possible to
+contribute designs without having resources to do the implementation,
+but in this case the implementation is only done if someone volunteers
+to do it (which is not guaranteed to happen).
+
+[[review]]
+== Design doc review
+
+Everyone in the link:dev-roles.html[Gerrit community] is welcome to
+take part in the design review and comment on the design.
+
+Changes with new design docs should stay open for a minimum of 10
+calendar days so that everyone has a fair chance to see them. It is
+important that concerns regarding a feature are raised during this time
+frame since once a design is approved and submitted the implementation
+may start immediately.
+
+Within the 10 calendar days time frame, the contributor should hear back
+from the link:dev-processes.html#steering-committee[engineering steering committee]
+whether the proposed feature is in scope of the project and if it can
+be accepted.
+
+In order to be accepted/submitted, it is not necessary that the design
+doc fully specifies all the details, but the idea of the feature and
+how it fits into Gerrit should be sufficiently clear (judged by the
+engineering steering committee). Contributors are expected to keep the design doc
+updated and fill in gaps while they go forward with the implementation.
+
+[[watch-designs]]
+== How to get notified for new design docs?
+
+. Go to the
+ link:https://gerrit-review.googlesource.com/settings/#Notifications[
+ notification settings]
+. Add a project watch for the `gerrit` repository with the following
+ query: `hashtag:design-doc`
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
+
+SEARCHBOX
+---------
diff --git a/Documentation/dev-processes.txt b/Documentation/dev-processes.txt
index 12ffb45..b3c147f 100644
--- a/Documentation/dev-processes.txt
+++ b/Documentation/dev-processes.txt
@@ -1,10 +1,85 @@
= Gerrit Code Review - Development Processes
+[[project-governance]]
+[[steering-committee]]
+== Project Governance / Engineering Steering Committee
+
+The Gerrit project has an engineering steering committee (ESC) that is
+in charge of:
+
+* Gerrit core (the `gerrit` project) and the core plugins
+* defining the project vision and the project scope
+* maintaining a roadmap, a release plan and a prioritized backlog
+* ensuring timely design reviews
+* ensuring that new features are compatible with the project vision and
+ are well aligned with other features (give feedback on new
+ link:dev-design-docs.html[design docs] within 14 calendar days)
+* approving/rejecting link:dev-design-docs.html[designs], vetoing new
+ features
+* assigning link:dev-roles.html#mentor[mentors] for approved features
+* accepting new plugins as core plugins
+* making changes to the project governance process and the
+ link:dev-contributing.html#contribution-processes[contribution
+ processes]
+
+The steering committee has 5 members:
+
+* 3 Googlers that are appointed by Google
+* 2 non-Google maintainers, elected by non-Google maintainers for the
+ period of 1 year (see link:#steering-committee-election[below])
+
+Refer to the project homepage for the link:https://www.gerritcodereview.com/esc.html[
+list of current committee members].
+
+The steering committee should act in the interest of the Gerrit project
+and the whole Gerrit community.
+
+For decisions, consensus between steering committee members and all
+other maintainers is desired. If consensus cannot be reached, decisions
+can also be made by simple majority in the steering committee (should
+be applied only in exceptional situations).
+
+The steering committee is empowered to overrule positive/negative votes
+from individual maintainers, but should do so only in exceptional
+situations after attempts to reach consensus have failed.
+
+As an integral part of the Gerrit community, the steering committee is
+committed to transparency and to answering incoming requests in a
+timely manner.
+
+[[steering-committee-election]]
+=== Election of non-Google steering committee members
+
+The election of the non-Google steering committee members happens once
+a year in May. Non-Google link:dev-roles.html#maintainer[maintainers]
+can nominate themselves by posting an informal application on the
+non-public maintainers mailing list by end of April (deadline for 2019
+is Mon 13th of May). By applying to be steering committee member, the
+candidate confirms to be able to dedicate the time that is needed to
+fulfill this role (also see
+link:dev-roles.html#steering-committee-member[steering committee
+member]).
+
+Each non-Google maintainer can vote for 2 candidates. The voting
+happens by posting on the maintainer mailing list. The voting period is
+14 calendar days from the nomination deadline (except for 2019, where
+the initial steering committee should be confirmed during the Munich
+hackathon, the voting period goes from 14th May to 16th May).
+
+Google maintainers do not take part in this vote, because Google
+already has dedicated seats in the steering committee (see section
+link:steering-committee[steering committee]).
+
[[contribution-process]]
== Contribution Process
See link:dev-contributing.html[here].
+[[design-doc-review]]
+== Design Doc Review
+
+See link:dev-design-docs.html#review[here].
+
[[dev-in-stable-branches]]
== Development in stable branches
@@ -18,14 +93,14 @@
branch before the first release candidate is created.
* To stabilize the code before doing a major release several release candidates are created. Once
the first release candidate was done no more features should be accepted on the stable branch.
- If more features are found to be required they should be discussed with the Gerrit maintainers
+ If more features are found to be required they should be discussed with the steering committee
and should only be allowed if the risk of breaking things is considered to be low.
* Once a major release is done only bug-fixes and documentation updates should be done on the
stable branch. These updates will be included in the next minor release.
* For minor releases new features are only acceptable if they are important to the Gerrit
community, if they are backwards compatible and the risk of breaking things is low and if there
- are no objections from the Gerrit community.
- * In cases of doubt it's the responsibility of the release maintainer to evaluate the risk of new
+ are no objections from the steering committee.
+ * In cases of doubt it's the responsibility of the steering committee to evaluate the risk of new
features and make a decision based on these rules and opinions from the Gerrit community.
* The older a stable branch is the more stable it should be. This means old stable branches
should only receive bug-fixes that are either important or low risk. Security fixes, including
diff --git a/Documentation/dev-readme.txt b/Documentation/dev-readme.txt
index f9b09da..02b1891 100644
--- a/Documentation/dev-readme.txt
+++ b/Documentation/dev-readme.txt
@@ -3,7 +3,9 @@
To build a developer instance, you'll need link:https://bazel.build/[Bazel] to
compile the code.
-== Getting the Source
+== Git Setup
+
+=== Getting the Source
Create a new client workspace:
@@ -15,38 +17,54 @@
The `--recurse-submodules` option is needed on `git clone` to ensure that the
core plugins, which are included as git submodules, are also cloned.
+=== Switching between branches
+
+When using `git checkout` without `--recurse-submodules` to switch between
+branches, submodule revisions are not altered, which can result in:
+
+* Incorrect or unneeded plugin revisions.
+* Missing plugins.
+
+After you switch branches, ensure that you have the correct versions of
+the submodules.
+
+CAUTION: If you store Eclipse or IntelliJ project files in the Gerrit source
+directories, do *_not_* run `git clean -fdx`. Doing so may remove untracked files and damage your project. For more information, see
+link:https://git-scm.com/docs/git-clean[git-clean].
+
+Run the following:
+
+----
+ git submodule update
+ git clean -ffd
+----
+
[[compile_project]]
== Compiling
For details, see <<dev-bazel#,Building with Bazel>>.
-== Configuring Eclipse
-To use the Eclipse IDE for development, see
-link:dev-eclipse.html[Eclipse Setup].
+== Testing
-To configure the Eclipse workspace with Bazel, see
-link:dev-bazel.html#eclipse[Eclipse integration with Bazel].
+[[tests]]
+=== Running the acceptance tests
-== Configuring IntelliJ IDEA
+Gerrit contains acceptance tests that validate the Gerrit daemon via REST, SSH,
+and the Git protocol.
-See <<dev-intellij#,IntelliJ Setup>> for details.
+A new review site is created for each test and the Gerrit daemon is
+then started on that site. When the test is completed, the Gerrit daemon is
+shut down.
-== MacOS
+For instructions on running the acceptance tests with Bazel,
+see <<dev-bazel#tests,Running Unit Tests with Bazel>>.
-On MacOS, ensure that "Java for MacOS X 10.5 Update 4" (or higher) is installed
-and that `JAVA_HOME` is set to the
-link:install.html#Requirements[required Java version].
-Java installations can typically be found in
-"/System/Library/Frameworks/JavaVM.framework/Versions".
-
-To check the installed version of Java, open a terminal window and run:
-
-`java -version`
+== Local server
[[init]]
-== Site Initialization
+=== Site Initialization
After you compile the project <<compile_project,(above)>>, run the Gerrit
`init`
@@ -90,7 +108,7 @@
[[localdev]]
-== Working with the Local Server
+=== Working with the Local Server
To create more accounts on your development instance:
@@ -107,27 +125,27 @@
git clone ssh://username@localhost:29418/projectname
----
+To use the `HTTP` protocol, run:
+
+----
+git clone http://username@localhost:8080/projectname
+----
+
+The default password for user `admin` is `secret`. You can regenerate a
+password in the UI under User Settings -- HTTP credentials. The password can be
+stored locally to avoid retyping it:
+
+----
+git config --global credential.helper store
+git pull
+----
+
To create changes as users of Gerrit would, run:
----
git push origin HEAD:refs/for/master
----
-== Testing
-
-[[tests]]
-=== Running the acceptance tests
-
-Gerrit contains acceptance tests that validate the Gerrit daemon via REST, SSH,
-and the Git protocol.
-
-A new review site is created for each test and the Gerrit daemon is
-then started on that site. When the test is completed, the Gerrit daemon is
-shut down.
-
-For instructions on running the acceptance tests with Bazel,
-see <<dev-bazel#tests,Running Unit Tests with Bazel>>.
-
[[run_daemon]]
=== Running the Daemon
@@ -192,27 +210,24 @@
CAUTION: When using the Inspector, be careful not to modify the internal state
of the system.
-== Switching between branches
-When using `git checkout` without `--recurse-submodules` to switch between
-branches, submodule revisions are not altered, which can result in:
+== Setup for backend developers
-* Incorrect or unneeded plugin revisions.
-* Missing plugins.
+=== Configuring Eclipse
-After you switch branches, ensure that you have the correct versions of
-the submodules.
+To use the Eclipse IDE for development, see
+link:dev-eclipse.html[Eclipse Setup].
-CAUTION: If you store Eclipse or IntelliJ project files in the Gerrit source
-directories, do *_not_* run `git clean -fdx`. Doing so may remove untracked files and damage your project. For more information, see
-link:https://git-scm.com/docs/git-clean[git-clean].
+To configure the Eclipse workspace with Bazel, see
+link:dev-bazel.html#eclipse[Eclipse integration with Bazel].
-Run the following:
+=== Configuring IntelliJ IDEA
-----
- git submodule update
- git clean -ffd
-----
+See <<dev-intellij#,IntelliJ Setup>> for details.
+
+== Setup for frontend developers
+See link:https://gerrit.googlesource.com/gerrit/+/master/polygerrit-ui/README.md[Frontend Developer Setup].
+
GERRIT
------
diff --git a/Documentation/dev-roles.txt b/Documentation/dev-roles.txt
index 1cc1897..7d5ca5d 100644
--- a/Documentation/dev-roles.txt
+++ b/Documentation/dev-roles.txt
@@ -1,7 +1,7 @@
= Gerrit Code Review - Supporting Roles
-As an open source project Gerrit has a large community of people that
-are driving the project forward and there are many ways to engage with
+As an open source project Gerrit has a large community of people
+driving the project forward. There are many ways to engage with
the project and get involved.
[[supporter]]
@@ -54,6 +54,11 @@
see below)
* file issues in the link:https://bugs.chromium.org/p/gerrit/issues/list[
issue tracker] and comment on existing issues
+* support the
+ link:dev-processes.html#design-driven-contribution-process[
+ design-driven contribution process] by reviewing incoming
+ link:dev-design-docs.html[design docs] and raising concerns during
+ the design review
Supporters who want to engage further can get additional privileges
on request (ask for it on the
@@ -91,6 +96,9 @@
* code cleanups
* documentation updates
* release notes updates
+* propose link:#dev-design-docs[design docs] as part of the
+ link:dev-contributing.html#design-driven-contribution-process[
+ design-driven contribution process]
* scripts which are of interest to the community
Contributors have all the permissions that link:#supporter[supporters]
@@ -107,8 +115,11 @@
Being member of the `gerrit-verifiers` group includes further
permissions (see link:#supporter[supporter] section above).
-It's highly appreciated if contributors engage in code reviews and
-mailing list discussions.
+It's highly appreciated if contributors engage in code reviews,
+link:dev-design-docs.html#review[design reviews] and mailing list
+discussions. If wanted, contributors can also serve as link#mentor[
+mentors] to support other contributors with getting their features
+done.
Contributors may also be invited to join the Gerrit hackathons which
happen regularly (e.g. twice a year). Hackathons are announced on the
@@ -125,12 +136,16 @@
== Maintainer
Maintainers are the gatekeepers of the project and are in charge of
-approving and submitting changes.
+approving and submitting changes. Refer to the project homepage for
+the link:https://www.gerritcodereview.com/maintainers.html[
+list of current maintainers].
Maintainers should only approve changes that:
* they fully understand
-* seem to be in scope for what Gerrit should do
+* are in line with the project vision and project scope that are
+ defined by the link:dev-processes.html#steering-committee[engineering steering
+ committee], and should consult them, when in doubt
* meet the quality expectations of the project (well-tested, properly
documented, scalable, backwards-compatible)
* implement usable features or bug fixes (no incomplete/unusable
@@ -149,6 +164,12 @@
* reviewing changes
* mailing list discussions and support
* bug fixing and bug triaging
+* supporting the
+ link:dev-processes.html#design-driven-contribution-process[
+ design-driven contribution process] by reviewing incoming
+ link:dev-design-docs.html[design docs] and raising concerns during
+ the design review
+* serving as link:#mentor[mentor]
* doing releases (see link#release-manager[release manager])
Maintainers can:
@@ -158,8 +179,10 @@
ignored if there is a good reason, in this case the reason should be
clearly communicated on the change
* submit changes
-* veto changes if they disagree with a feature or with how it is being
- implemented (vote `-2` on the `Code-Review` label)
+* block submission of changes if they disagree with how a feature is
+ being implemented (vote `-2` on the `Code-Review` label), but their
+ vote can be overruled by the steering committee, see
+ link:dev-processes.html#project-governance[Project Governance]
* nominate new maintainers and vote on nominations (see below)
* administrate the link:https://groups.google.com/d/forum/repo-discuss[
mailing list], the
@@ -199,6 +222,90 @@
* high quality code reviews
* activity on the mailing list
+[[steering-committee-member]]
+== Engineering Steering Committee Member
+
+The Gerrit project has an Engineering Steering Committee (ESC) that
+governs the project, see link:dev-processes.html#project-governance[Project Governance].
+
+Members of the steering committee are expected to act in the interest
+of the Gerrit project and the whole Gerrit community. Refer to the project
+homepage for the link:https://www.gerritcodereview.com/esc.html[
+list of current committee members].
+
+For those that are familiar with scrum, the steering committee member
+role is similar to the role of an agile product owner.
+
+Steering committee members must be able to dedicate sufficient time to
+their role so that the steering committee can satisfy its
+responsibilities and live up to the promise of answering incoming
+requests in a timely manner.
+
+link:#maintainer[Maintainers] can become steering committee member by
+election, or by being appointed by Google (only for the seats that
+belong to Google).
+
+[[mentor]]
+== Mentor
+
+A mentor is a link:#maintainer[maintainer] or link:#contributor[
+contributor] who is assigned to support the development of a feature
+that was specified in a link:dev-design-docs.html[design doc] and was
+approved by the link:dev-processes.html#steering-committee[steering
+committee].
+
+The goal of the mentor is to make the feature successful by:
+
+* doing timely reviews
+* providing technical guidance during code reviews
+* discussing details of the design
+* ensuring that the quality standards are met (well documented,
+ sufficient test coverage, backwards compatible etc.)
+
+The implementation is fully done by the contributor, but optionally
+mentors can help out with contributing some changes.
+
+link:#maintainer[Maintainers] and link:#contributor[contributors] can
+volunteer to generally serve as mentors, or to mentor specific features
+(e.g. if they see an upcoming feature on the roadmap that they are
+interested in). To volunteer as mentor, contact the
+link:dev-processes.html#steering-committee[steering committee] or
+comment on a change that adds a link:dev-design-docs.html#propose[
+design doc].
+
+[[community-manager]]
+== Community Manager
+
+Community managers should act as stakeholders for the Gerrit community
+and focus on the health of the community.
+
+Tasks:
+
+* act as stakeholder for the Gerrit community towards the
+ link:dev-processes.html#steering-committee[steering committee]
+* ensure that the link:dev-contributing.html#mentorship[mentorship
+ process] works
+* deescalate conflicts in the Gerrit community
+* constantly improve community processes (e.g. contribution process)
+* watch out for community issues and address them proactively
+* serve as contact person for community issues
+
+The community managers should be a pair or trio that shares the work:
+
+* One Googler that is appointed by Google.
+* One or two non-Googlers, elected by the community if there are more
+ than two candidates. If there is no candidate, we only have the one
+ community manager from Google.
+
+Community managers must not be link:#steering-committee-member[
+steering committee members] at the same time so that they can represent
+the community without conflict of interest.
+
+Nomination process, election process and election period for the
+non-Google community manager are the same as for
+link:dev-processes.html#steering-committee-election[steering committee
+members].
+
[[release-manager]]
== Release Manager
diff --git a/Documentation/licenses.txt b/Documentation/licenses.txt
index 6e61e29..17c1184 100644
--- a/Documentation/licenses.txt
+++ b/Documentation/licenses.txt
@@ -52,6 +52,7 @@
* commons:pool
* commons:validator
* dropwizard:dropwizard-core
+* errorprone:annotations
* flogger:api
* fonts:robotofonts
* guice:guice
diff --git a/Documentation/note-db.txt b/Documentation/note-db.txt
index fd2bef37..c7e21f1 100644
--- a/Documentation/note-db.txt
+++ b/Documentation/note-db.txt
@@ -1,8 +1,8 @@
= Gerrit Code Review - NoteDb Backend
NoteDb is the next generation of Gerrit storage backend, which replaces the
-traditional SQL backend for change and account metadata with storing data in the
-same repository as code changes.
+traditional SQL backend for change, account and group metadata with storing
+data in the same repository as code changes.
.Advantages
- *Simplicity*: All data is stored in one location in the site directory, rather
@@ -32,12 +32,15 @@
2.15 release. Account data is migrated automatically during the upgrade
process by running `gerrit.war init`.
- Storing link:config-groups.html[group metadata] is fully implemented
- for the 2.16 release. Group data is migrated automatically during
+ in the 2.16 release. Group data is migrated automatically during
the upgrade process by running `gerrit.war init`
- Account, group and change metadata on the servers behind `googlesource.com` is fully
migrated to NoteDb. In other words, if you use
link:https://gerrit-review.googlesource.com/[gerrit-review], you're already
using NoteDb.
+- NoteDb is the only database format supported by Gerrit 3.0. The offline
+ change data migration tool is included in Gerrit 3.0, but online
+ migration is only available in the 2.x line.
For an example NoteDb change, poke around at this one:
----
@@ -45,12 +48,6 @@
&& git log -p FETCH_HEAD
----
-== Future Work ("Gerrit 3.0")
-
-- NoteDb will be the only database format supported by Gerrit 3.0. The offline
- change data migration tool will be included in Gerrit 3.0, but online
- migration will only be available in the 2.x line.
-
[[migration]]
== Migration
@@ -64,6 +61,9 @@
[[online-migration]]
=== Online
+Note that online migration is only available in 2.x. To do the online migration
+from 2.14.x or 2.15.x to 3.0, it is necessary to first upgrade to 2.16.x.
+
To start the online migration, set the `noteDb.changes.autoMigrate` option in
`gerrit.config` and restart Gerrit:
----
@@ -87,7 +87,7 @@
*Disadvantages*
-* Only available in 2.x; will not be available in Gerrit 3.0.
+* Only available in 2.x; not available in Gerrit 3.0.
* Much slower than offline; uses only a single thread, to leave resources
available for serving traffic.
* Performance may be degraded, particularly of updates; data needs to be written
diff --git a/Documentation/rest-api-accounts.txt b/Documentation/rest-api-accounts.txt
index c326b66..5d22659 100644
--- a/Documentation/rest-api-accounts.txt
+++ b/Documentation/rest-api-accounts.txt
@@ -479,6 +479,8 @@
in the request body inside a link:#http-password-input[
HttpPasswordInput] entity.
+The account must have a username.
+
.Request
----
PUT /accounts/self/password.http HTTP/1.0
diff --git a/Documentation/user-search.txt b/Documentation/user-search.txt
index cafd5ca..cc3ac42 100644
--- a/Documentation/user-search.txt
+++ b/Documentation/user-search.txt
@@ -325,7 +325,7 @@
regular expression. The link:http://www.brics.dk/automaton/[dk.brics.automaton
library] is used for evaluation of such patterns.
-[[footer]]
+[[footer-operator]]
footer:'FOOTER'::
+
Matches any change that has 'FOOTER' as footer in the commit message of the
diff --git a/WORKSPACE b/WORKSPACE
index b783e08..0d3f9ce 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -7,31 +7,51 @@
load("//tools:nongoogle.bzl", "declare_nongoogle_deps")
http_archive(
+ name = "bazel_toolchains",
+ sha256 = "88e818f9f03628eef609c8429c210ecf265ffe46c2af095f36c7ef8b1855fef5",
+ strip_prefix = "bazel-toolchains-92dd8a7a518a2fb7ba992d47c8b38299fe0be825",
+ urls = [
+ "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/92dd8a7a518a2fb7ba992d47c8b38299fe0be825.tar.gz",
+ "https://github.com/bazelbuild/bazel-toolchains/archive/92dd8a7a518a2fb7ba992d47c8b38299fe0be825.tar.gz",
+ ],
+)
+
+load("@bazel_toolchains//rules:rbe_repo.bzl", "rbe_autoconfig")
+
+# Creates a default toolchain config for RBE.
+# Use this as is if you are using the rbe_ubuntu16_04 container,
+# otherwise refer to RBE docs.
+rbe_autoconfig(name = "rbe_default")
+
+http_archive(
+ name = "bazel_toolchains",
+ sha256 = "88e818f9f03628eef609c8429c210ecf265ffe46c2af095f36c7ef8b1855fef5",
+ strip_prefix = "bazel-toolchains-92dd8a7a518a2fb7ba992d47c8b38299fe0be825",
+ urls = [
+ "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/92dd8a7a518a2fb7ba992d47c8b38299fe0be825.tar.gz",
+ "https://github.com/bazelbuild/bazel-toolchains/archive/92dd8a7a518a2fb7ba992d47c8b38299fe0be825.tar.gz",
+ ],
+)
+
+load("@bazel_toolchains//rules:rbe_repo.bzl", "rbe_autoconfig")
+
+# Creates a default toolchain config for RBE.
+# Use this as is if you are using the rbe_ubuntu16_04 container,
+# otherwise refer to RBE docs.
+rbe_autoconfig(name = "rbe_default")
+
+http_archive(
name = "bazel_skylib",
- sha256 = "bbccf674aa441c266df9894182d80de104cabd19be98be002f6d478aaa31574d",
- strip_prefix = "bazel-skylib-2169ae1c374aab4a09aa90e65efe1a3aad4e279b",
- urls = ["https://github.com/bazelbuild/bazel-skylib/archive/2169ae1c374aab4a09aa90e65efe1a3aad4e279b.tar.gz"],
+ sha256 = "2ea8a5ed2b448baf4a6855d3ce049c4c452a6470b1efd1504fdb7c1c134d220a",
+ strip_prefix = "bazel-skylib-0.8.0",
+ urls = ["https://github.com/bazelbuild/bazel-skylib/archive/0.8.0.tar.gz"],
)
http_archive(
name = "io_bazel_rules_closure",
- sha256 = "1c05fea22c9630cf1047f25d008780756373a60ddd4d2a6993cf9858279c5da6",
- strip_prefix = "rules_closure-50d3dc9e6d27a5577a0f95708466718825d579f4",
- urls = ["https://github.com/bazelbuild/rules_closure/archive/50d3dc9e6d27a5577a0f95708466718825d579f4.tar.gz"],
-)
-
-# Transitive dependency of rules_closure and protobuf
-http_archive(
- name = "net_zlib",
- build_file = "//:lib/zlib/BUILD",
- sha256 = "c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1",
- strip_prefix = "zlib-1.2.11",
- urls = ["https://zlib.net/zlib-1.2.11.tar.gz"],
-)
-
-bind(
- name = "zlib",
- actual = "@net_zlib//:zlib",
+ sha256 = "bdb00831682cd0923df36e19b01619b8230896d582f16304a937d8dc8270b1b6",
+ strip_prefix = "rules_closure-ad75d7cc1cff0e845cd83683881915d995bd75b2",
+ urls = ["https://github.com/bazelbuild/rules_closure/archive/ad75d7cc1cff0e845cd83683881915d995bd75b2.tar.gz"],
)
# File is specific to Polymer and copied from the Closure Github -- should be
@@ -46,7 +66,7 @@
load("@bazel_skylib//lib:versions.bzl", "versions")
-versions.check(minimum_bazel_version = "0.22.0")
+versions.check(minimum_bazel_version = "0.25.0")
load("@io_bazel_rules_closure//closure:defs.bzl", "closure_repositories")
@@ -56,6 +76,7 @@
# https://github.com/google/closure-templates/pull/155
closure_repositories(
omit_aopalliance = True,
+ omit_bazel_skylib = True,
omit_javax_inject = True,
)
@@ -165,6 +186,12 @@
sha1 = "94ad16d728b374d65bd897625f3fbb3da223a2b6",
)
+maven_jar(
+ name = "error-prone-annotations",
+ artifact = "com.google.errorprone:error_prone_annotations:2.3.3",
+ sha1 = "42aa5155a54a87d70af32d4b0d06bf43779de0e2",
+)
+
FLOGGER_VERS = "0.4"
maven_jar(
@@ -858,30 +885,30 @@
sha1 = "42a25dc3219429f0e5d060061f71acb49bf010a0",
)
-TRUTH_VERS = "0.44"
+TRUTH_VERS = "0.45"
maven_jar(
name = "truth",
artifact = "com.google.truth:truth:" + TRUTH_VERS,
- sha1 = "11eff954c0c14da7d43276d7b3bcf71463105368",
+ sha1 = "e16683346f6a6887b1f140a2984e60c73c66c40a",
)
maven_jar(
name = "truth-java8-extension",
artifact = "com.google.truth.extensions:truth-java8-extension:" + TRUTH_VERS,
- sha1 = "2081a0721d3101e1cf559f013e59c6129b4b10b0",
+ sha1 = "f43262ad81c8df9a7f148659ff34de28b952754f",
)
maven_jar(
name = "truth-liteproto-extension",
artifact = "com.google.truth.extensions:truth-liteproto-extension:" + TRUTH_VERS,
- sha1 = "64f47e4e3f79b0a582573098b9c3c6b73599f7c6",
+ sha1 = "67017d3aaec607c4a181ac95e9be0dc14e6c3fb2",
)
maven_jar(
name = "truth-proto-extension",
artifact = "com.google.truth.extensions:truth-proto-extension:" + TRUTH_VERS,
- sha1 = "c03fbc16087d8cb3bf0f3265a04566d4beb88a6d",
+ sha1 = "f69edef92d9aceb82c6353e425328712ce1a25e7",
)
maven_jar(
@@ -903,12 +930,6 @@
sha1 = "92bf48723d277d6efd1150b2f7e9e1e92cb56caf",
)
-maven_jar(
- name = "objenesis",
- artifact = "org.objenesis:objenesis:1.3",
- sha1 = "dc13ae4faca6df981fc7aeb5a522d9db446d5d50",
-)
-
POWERM_VERS = "1.6.1"
maven_jar(
@@ -953,13 +974,6 @@
sha1 = "3e83394258ae2089be7219b971ec21a8288528ad",
)
-maven_jar(
- name = "derby",
- artifact = "org.apache.derby:derby:10.12.1.1",
- attach_source = False,
- sha1 = "75070c744a8e52a7d17b8b476468580309d5cd09",
-)
-
JETTY_VERS = "9.4.14.v20181114"
maven_jar(
@@ -1057,30 +1071,28 @@
# and httpasyncclient as necessary.
maven_jar(
name = "elasticsearch-rest-client",
- artifact = "org.elasticsearch.client:elasticsearch-rest-client:7.0.0",
- sha1 = "121d12f1c71f318be1a654e8a956e38d5b68e98a",
+ artifact = "org.elasticsearch.client:elasticsearch-rest-client:7.1.0",
+ sha1 = "93e8e8b96121069d1d6a6f94d29e7aebd3327301",
)
-JACKSON_VERSION = "2.9.8"
-
maven_jar(
name = "jackson-core",
- artifact = "com.fasterxml.jackson.core:jackson-core:" + JACKSON_VERSION,
+ artifact = "com.fasterxml.jackson.core:jackson-core:2.9.8",
sha1 = "0f5a654e4675769c716e5b387830d19b501ca191",
)
-TESTCONTAINERS_VERSION = "1.11.2"
+TESTCONTAINERS_VERSION = "1.11.3"
maven_jar(
name = "testcontainers",
artifact = "org.testcontainers:testcontainers:" + TESTCONTAINERS_VERSION,
- sha1 = "eae47ed24bb07270d4b60b5e2c3444c5bf3c8ea9",
+ sha1 = "154b69dd976416734b2fc809fb86e173ad9aa25b",
)
maven_jar(
name = "testcontainers-elasticsearch",
artifact = "org.testcontainers:elasticsearch:" + TESTCONTAINERS_VERSION,
- sha1 = "a327bd8cb68eb7146b36d754aee98a8018132d8f",
+ sha1 = "90713b61f5748d8894c31a20f955bd7f81ac2ece",
)
maven_jar(
@@ -1283,8 +1295,8 @@
bower_archive(
name = "polymer-resin",
package = "polymer/polymer-resin",
- sha1 = "5cb65081d461e710252a1ba1e671fe4c290356ef",
- version = "1.2.8",
+ sha1 = "94c29926c20ea3a9b636f26b3e0d689ead8137e5",
+ version = "2.0.1",
)
bower_archive(
diff --git a/contrib/hooks/post-receive-move-tmp-refs b/contrib/hooks/post-receive-move-tmp-refs
new file mode 100755
index 0000000..c4a53db
--- /dev/null
+++ b/contrib/hooks/post-receive-move-tmp-refs
@@ -0,0 +1,79 @@
+#!/bin/sh
+#
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# --------------------------------------------------------
+# Install this hook script as post-receive hook in replicated repositories
+# hosted by a gerrit slave which are updated by push replication from the
+# corresponding gerrit master.
+#
+# In the gerrit master configure the replication plugin to push changes from
+# refs/changes/ to refs/tmp/changes/
+# remote.NAME.push = +refs/changes/*:refs/tmp/changes/*
+# remote.NAME.push = +refs/heads/*:refs/heads/*
+# remote.NAME.push = +refs/tags/*:refs/tags/*
+#
+# In the replicated repository in the gerrit slave configure
+# receive.hideRefs = refs/changes/
+# in order to not advertise the big number of refs in this namespace when
+# the gerrit master's replication plugin is pushing a change
+#
+# Whenever a ref under refs/tmp/changes/ is arriving this hook will move it
+# to refs/changes/. This helps to avoid the large overhead of advertising all
+# refs/changes/ refs to the gerrit master when it replicates changes to the
+# slave..
+#
+# Make this script executable then link to it in the repository you would like
+# to use it in.
+# cd /path/to/your/repository.git
+# ln -sf <shared hooks directory>/post-receive-move-tmp-refs hooks/post-receive
+#
+# If you want to use this by default for repositories on the Gerrit slave you
+# can set up a git template directory $TEMPLATE_DIR/hooks/post-receive and
+# configure init.templateDir in the ~/.gitconfig of the user that receives the
+# replication on the mirror host. That way when a new repository is created on
+# the master and hence on the mirror (if configured that way) it will
+# automatically have the "tmp-refs" commit hook installed.
+# See https://git-scm.com/docs/git-init#_template_directory for details.
+
+readonly NULL_SHA1=0000000000000000000000000000000000000000
+
+# move new changes arriving under refs/tmp/changes/ to refs/changes/
+mv_tmp_refs()
+{
+ oldrev=$1
+ newrev=$2
+ refname=$3
+ case "$refname","$oldrev" in
+ refs/tmp/changes/*,$NULL_SHA1)
+ short_refname=${refname##refs/tmp/changes/}
+ $(git update-ref refs/changes/$short_refname $newrev $NULL_SHA1 2>/dev/null)
+ $(git update-ref -d $refname $newrev 2>/dev/null)
+ echo "moved \"$refname\" to \"refs/changes/$short_refname\""
+ ;;
+ esac
+ return 0
+}
+
+GIT_DIR=$(git rev-parse --git-dir 2>/dev/null)
+if [ -z "$GIT_DIR" ]; then
+ echo >&2 "fatal: post-receive: GIT_DIR not set"
+ exit 1
+fi
+
+# read ref updates passed to post-receive hook
+while read oldrev newrev refname
+do
+ mv_tmp_refs $oldrev $newrev $refname || continue
+done
diff --git a/java/com/google/gerrit/acceptance/AbstractDaemonTest.java b/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
index 56db9a9..87da183 100644
--- a/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
+++ b/java/com/google/gerrit/acceptance/AbstractDaemonTest.java
@@ -18,15 +18,13 @@
import static com.google.common.truth.OptionalSubject.optionals;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
-import static com.google.common.truth.Truth.assert_;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.common.truth.TruthJUnit.assume;
import static com.google.gerrit.extensions.api.changes.SubmittedTogetherOption.NON_VISIBLE_CHANGES;
import static com.google.gerrit.reviewdb.client.Patch.COMMIT_MSG;
import static com.google.gerrit.reviewdb.client.Patch.MERGE_LIST;
-import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
-import static com.google.gerrit.server.project.testing.Util.category;
-import static com.google.gerrit.server.project.testing.Util.value;
+import static com.google.gerrit.server.project.testing.TestLabels.label;
+import static com.google.gerrit.server.project.testing.TestLabels.value;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toList;
@@ -42,7 +40,6 @@
import com.google.common.primitives.Chars;
import com.google.gerrit.acceptance.AcceptanceTestRequestScope.Context;
import com.google.gerrit.acceptance.testsuite.account.TestSshKeys;
-import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.AccessSection;
@@ -52,7 +49,6 @@
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelValue;
import com.google.gerrit.common.data.Permission;
-import com.google.gerrit.common.data.PermissionRange;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.common.data.PermissionRule.Action;
import com.google.gerrit.extensions.api.GerritApi;
@@ -124,7 +120,6 @@
import com.google.gerrit.server.plugins.TestServerPlugin;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectConfig;
-import com.google.gerrit.server.project.testing.Util;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.restapi.change.Revisions;
@@ -160,8 +155,6 @@
import java.util.Optional;
import java.util.regex.Pattern;
import org.eclipse.jgit.api.Git;
-import org.eclipse.jgit.errors.ConfigInvalidException;
-import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
@@ -184,7 +177,6 @@
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
-import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
@@ -201,8 +193,6 @@
@ConfigSuite.Parameter public Config baseConfig;
@ConfigSuite.Name private String configName;
- @Rule public ExpectedException exception = ExpectedException.none();
-
@Rule
public TestRule testRunner =
new TestRule() {
@@ -289,7 +279,6 @@
@Inject private PluginGuiceEnvironment pluginGuiceEnvironment;
@Inject private PluginUser.Factory pluginUserFactory;
@Inject private ProjectIndexCollection projectIndexes;
- @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Inject private SitePaths sitePaths;
@@ -883,59 +872,6 @@
return gApi.changes().id(r.getChangeId()).current();
}
- protected void allow(String ref, String permission, AccountGroup.UUID id) throws Exception {
- allow(project, ref, permission, id);
- }
-
- protected void allow(Project.NameKey p, String ref, String permission, AccountGroup.UUID id)
- throws Exception {
- try (ProjectConfigUpdate u = updateProject(p)) {
- Util.allow(u.getConfig(), permission, id, ref);
- u.save();
- }
- }
-
- protected void allowGlobalCapabilities(
- AccountGroup.UUID id, int min, int max, String... capabilityNames) throws Exception {
- try (ProjectConfigUpdate u = updateProject(allProjects)) {
- for (String capabilityName : capabilityNames) {
- Util.allow(
- u.getConfig(), capabilityName, id, new PermissionRange(capabilityName, min, max));
- }
- u.save();
- }
- }
-
- protected void allowGlobalCapabilities(AccountGroup.UUID id, String... capabilityNames)
- throws Exception {
- allowGlobalCapabilities(id, Arrays.asList(capabilityNames));
- }
-
- protected void allowGlobalCapabilities(AccountGroup.UUID id, Iterable<String> capabilityNames)
- throws Exception {
- try (ProjectConfigUpdate u = updateProject(allProjects)) {
- for (String capabilityName : capabilityNames) {
- Util.allow(u.getConfig(), capabilityName, id);
- }
- u.save();
- }
- }
-
- protected void removeGlobalCapabilities(AccountGroup.UUID id, String... capabilityNames)
- throws Exception {
- removeGlobalCapabilities(id, Arrays.asList(capabilityNames));
- }
-
- protected void removeGlobalCapabilities(AccountGroup.UUID id, Iterable<String> capabilityNames)
- throws Exception {
- try (ProjectConfigUpdate u = updateProject(allProjects)) {
- for (String capabilityName : capabilityNames) {
- Util.remove(u.getConfig(), capabilityName, id);
- }
- u.save();
- }
- }
-
protected void setUseSignedOffBy(InheritableBoolean value) throws Exception {
try (MetaDataUpdate md = metaDataUpdateFactory.create(project)) {
ProjectConfig config = projectConfigFactory.read(md);
@@ -954,116 +890,6 @@
}
}
- protected void deny(String ref, String permission, AccountGroup.UUID id) throws Exception {
- deny(project, ref, permission, id);
- }
-
- protected void deny(Project.NameKey p, String ref, String permission, AccountGroup.UUID id)
- throws Exception {
- try (ProjectConfigUpdate u = updateProject(p)) {
- Util.deny(u.getConfig(), permission, id, ref);
- u.save();
- }
- }
-
- protected PermissionRule block(String ref, String permission, AccountGroup.UUID id)
- throws Exception {
- return block(project, ref, permission, id);
- }
-
- protected PermissionRule block(
- Project.NameKey project, String ref, String permission, AccountGroup.UUID id)
- throws Exception {
- try (ProjectConfigUpdate u = updateProject(project)) {
- PermissionRule rule = Util.block(u.getConfig(), permission, id, ref);
- u.save();
- return rule;
- }
- }
-
- protected void blockLabel(
- String label, int min, int max, AccountGroup.UUID id, String ref, Project.NameKey project)
- throws Exception {
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.block(u.getConfig(), Permission.LABEL + label, min, max, id, ref);
- u.save();
- }
- }
-
- protected void grant(Project.NameKey project, String ref, String permission)
- throws RepositoryNotFoundException, IOException, ConfigInvalidException {
- grant(project, ref, permission, false);
- }
-
- protected void grant(Project.NameKey project, String ref, String permission, boolean force)
- throws RepositoryNotFoundException, IOException, ConfigInvalidException {
- grant(project, ref, permission, force, adminGroupUuid());
- }
-
- protected void grant(
- Project.NameKey project,
- String ref,
- String permission,
- boolean force,
- AccountGroup.UUID groupUUID)
- throws RepositoryNotFoundException, IOException, ConfigInvalidException {
- try (MetaDataUpdate md = metaDataUpdateFactory.create(project)) {
- md.setMessage(String.format("Grant %s on %s", permission, ref));
- ProjectConfig config = projectConfigFactory.read(md);
- AccessSection s = config.getAccessSection(ref, true);
- Permission p = s.getPermission(permission, true);
- PermissionRule rule = Util.newRule(config, groupUUID);
- rule.setForce(force);
- p.add(rule);
- config.commit(md);
- projectCache.evict(config.getProject());
- }
- }
-
- protected void grantLabel(
- String label,
- int min,
- int max,
- Project.NameKey project,
- String ref,
- boolean force,
- AccountGroup.UUID groupUUID,
- boolean exclusive)
- throws RepositoryNotFoundException, IOException, ConfigInvalidException {
- String permission = Permission.LABEL + label;
- try (MetaDataUpdate md = metaDataUpdateFactory.create(project)) {
- md.setMessage(String.format("Grant %s on %s", permission, ref));
- ProjectConfig config = projectConfigFactory.read(md);
- AccessSection s = config.getAccessSection(ref, true);
- Permission p = s.getPermission(permission, true);
- p.setExclusiveGroup(exclusive);
- PermissionRule rule = Util.newRule(config, groupUUID);
- rule.setForce(force);
- rule.setMin(min);
- rule.setMax(max);
- p.add(rule);
- config.commit(md);
- projectCache.evict(config.getProject());
- }
- }
-
- protected void removePermission(Project.NameKey project, String ref, String permission)
- throws IOException, ConfigInvalidException {
- try (MetaDataUpdate md = metaDataUpdateFactory.create(project)) {
- md.setMessage(String.format("Remove %s on %s", permission, ref));
- ProjectConfig config = projectConfigFactory.read(md);
- AccessSection s = config.getAccessSection(ref, true);
- Permission p = s.getPermission(permission, true);
- p.clearRules();
- config.commit(md);
- projectCache.evict(config.getProject());
- }
- }
-
- protected void blockRead(String ref) throws Exception {
- block(ref, Permission.READ, REGISTERED_USERS);
- }
-
protected PushOneCommit.Result pushTo(String ref) throws Exception {
PushOneCommit push = pushFactory.create(admin.newIdent(), testRepo);
return push.to(ref);
@@ -1128,15 +954,6 @@
}
}
- // TODO(hanwen): push this down.
- protected RevCommit getRemoteHead(Project.NameKey project, String branch) throws Exception {
- return projectOperations.project(project).getHead(branch);
- }
-
- protected RevCommit getRemoteHead() throws Exception {
- return getRemoteHead(project, "master");
- }
-
protected void assertMailReplyTo(Message message, String email) throws Exception {
assertThat(message.headers()).containsKey("Reply-To");
EmailHeader.String replyTo = (EmailHeader.String) message.headers().get("Reply-To");
@@ -1508,7 +1325,7 @@
LabelValue... value)
throws Exception {
try (ProjectConfigUpdate u = updateProject(project)) {
- LabelType labelType = category(label, value);
+ LabelType labelType = label(label, value);
labelType.setFunction(func);
labelType.setRefPatterns(refPatterns);
u.getConfig().getLabelSections().put(labelType.getName(), labelType);
@@ -1516,10 +1333,6 @@
}
}
- protected void fail(@Nullable String format, Object... args) {
- assert_().fail(format, args);
- }
-
protected void enableCreateNewChangeForAllNotInTarget() throws Exception {
try (ProjectConfigUpdate u = updateProject(project)) {
u.getConfig()
diff --git a/java/com/google/gerrit/acceptance/AbstractNotificationTest.java b/java/com/google/gerrit/acceptance/AbstractNotificationTest.java
index af2f17e..c6f9d32 100644
--- a/java/com/google/gerrit/acceptance/AbstractNotificationTest.java
+++ b/java/com/google/gerrit/acceptance/AbstractNotificationTest.java
@@ -73,7 +73,11 @@
}
protected static FakeEmailSenderSubject assertThat(FakeEmailSender sender) {
- return assertAbout(FakeEmailSenderSubject::new).that(sender);
+ return assertAbout(fakeEmailSenders()).that(sender);
+ }
+
+ protected static Subject.Factory<FakeEmailSenderSubject, FakeEmailSender> fakeEmailSenders() {
+ return FakeEmailSenderSubject::new;
}
protected void setEmailStrategy(TestAccount account, EmailStrategy strategy) throws Exception {
@@ -93,6 +97,7 @@
protected static class FakeEmailSenderSubject
extends Subject<FakeEmailSenderSubject, FakeEmailSender> {
+ private final FakeEmailSender fakeEmailSender;
private Message message;
private StagedUsers users;
private Map<RecipientType, List<String>> recipients = new HashMap<>();
@@ -100,10 +105,11 @@
FakeEmailSenderSubject(FailureMetadata failureMetadata, FakeEmailSender target) {
super(failureMetadata, target);
+ fakeEmailSender = target;
}
public FakeEmailSenderSubject didNotSend() {
- Message message = actual().peekMessage();
+ Message message = fakeEmailSender.peekMessage();
if (message != null) {
failWithoutActual(fact("expected no message", message));
}
@@ -111,7 +117,7 @@
}
public FakeEmailSenderSubject sent(String messageType, StagedUsers users) {
- message = actual().nextMessage();
+ message = fakeEmailSender.nextMessage();
if (message == null) {
failWithoutActual(fact("expected message", "not sent"));
}
@@ -140,9 +146,7 @@
: header));
}
- // Return a named subject that displays a human-readable table of
- // recipients.
- return named(recipientMapToString(recipients, users::emailToName));
+ return this;
}
private static String recipientMapToString(
@@ -203,8 +207,9 @@
if (recipients.get(type).contains(email) != expected) {
failWithoutActual(
fact(
- expected ? "should notify" : "shouldn't notify",
- type + ": " + users.emailToName(email)));
+ expected ? "expected to notify" : "expected not to notify",
+ type + ": " + users.emailToName(email)),
+ fact("but notified", recipientMapToString(recipients, users::emailToName)));
}
if (expected) {
accountedFor.add(email);
diff --git a/java/com/google/gerrit/acceptance/BUILD b/java/com/google/gerrit/acceptance/BUILD
index 0714d22..ef9f4e6 100644
--- a/java/com/google/gerrit/acceptance/BUILD
+++ b/java/com/google/gerrit/acceptance/BUILD
@@ -1,6 +1,11 @@
load("//tools/bzl:java.bzl", "java_library2")
load("//tools/bzl:javadoc.bzl", "java_doc")
+FUNCTION_SRCS = [
+ "testsuite/ThrowingConsumer.java",
+ "testsuite/ThrowingFunction.java",
+]
+
java_library(
name = "lib",
testonly = True,
@@ -35,6 +40,7 @@
"//java/com/google/gerrit/server/restapi",
"//java/com/google/gerrit/sshd",
"//java/com/google/gerrit/testing:gerrit-test-util",
+ "//java/com/google/gerrit/truth",
"//lib:args4j",
"//lib:gson",
"//lib:guava-retrying",
@@ -51,7 +57,6 @@
"//lib/guice:guice-servlet",
"//lib/jgit/org.eclipse.jgit:jgit",
"//lib/mina:sshd",
- "//lib/mockito",
"//prolog:gerrit-prolog-common",
],
)
@@ -67,8 +72,13 @@
java_library2(
name = "framework-lib",
testonly = True,
- srcs = glob(["**/*.java"]),
+ srcs = glob(
+ ["**/*.java"],
+ exclude = FUNCTION_SRCS,
+ ),
exported_deps = [
+ ":function",
+ "//java/com/google/gerrit/acceptance/testsuite/project",
"//java/com/google/gerrit/exceptions",
"//java/com/google/gerrit/gpg",
"//java/com/google/gerrit/httpd/auth/openid",
@@ -92,6 +102,7 @@
"//lib/jgit/org.eclipse.jgit.junit:junit",
"//lib/log:impl-log4j",
"//lib/log:log4j",
+ "//lib/mockito",
"//lib/truth",
"//lib/truth:truth-java8-extension",
"//prolog:gerrit-prolog-common",
@@ -133,6 +144,12 @@
],
)
+java_library(
+ name = "function",
+ srcs = FUNCTION_SRCS,
+ visibility = ["//visibility:public"],
+)
+
java_doc(
name = "framework-javadoc",
testonly = True,
diff --git a/java/com/google/gerrit/acceptance/GerritServer.java b/java/com/google/gerrit/acceptance/GerritServer.java
index 3a49f46..a48a278 100644
--- a/java/com/google/gerrit/acceptance/GerritServer.java
+++ b/java/com/google/gerrit/acceptance/GerritServer.java
@@ -524,7 +524,7 @@
}
private static Injector createTestInjector(Daemon daemon) throws Exception {
- Injector sysInjector = get(daemon, "sysInjector");
+ Injector sysInjector = getInjector(daemon, "sysInjector");
Module module =
new FactoryModule() {
@Override
@@ -557,13 +557,14 @@
return sysInjector.createChildInjector(module);
}
- @SuppressWarnings("unchecked")
- private static <T> T get(Object obj, String field)
+ private static Injector getInjector(Object obj, String field)
throws SecurityException, NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Field f = obj.getClass().getDeclaredField(field);
f.setAccessible(true);
- return (T) f.get(obj);
+ Object v = f.get(obj);
+ checkArgument(v instanceof Injector, "not an Injector: %s", v);
+ return (Injector) f.get(obj);
}
private static InetAddress getLocalHost() {
diff --git a/java/com/google/gerrit/acceptance/GitUtil.java b/java/com/google/gerrit/acceptance/GitUtil.java
index a00497b..bb1c123 100644
--- a/java/com/google/gerrit/acceptance/GitUtil.java
+++ b/java/com/google/gerrit/acceptance/GitUtil.java
@@ -110,19 +110,14 @@
throws Exception {
DfsRepositoryDescription desc = new DfsRepositoryDescription("clone of " + project.get());
- FS fs = FS.detect();
-
- // Avoid leaking user state into our tests.
- fs.setUserHome(null);
-
- InMemoryRepository dest =
- new InMemoryRepository.Builder()
- .setRepositoryDescription(desc)
- // SshTransport depends on a real FS to read ~/.ssh/config, but
- // InMemoryRepository by default uses a null FS.
- // TODO(dborowitz): Remove when we no longer depend on SSH.
- .setFS(fs)
- .build();
+ InMemoryRepository.Builder b = new InMemoryRepository.Builder().setRepositoryDescription(desc);
+ if (uri.startsWith("ssh://")) {
+ // SshTransport depends on a real FS to read ~/.ssh/config, but InMemoryRepository by default
+ // uses a null FS.
+ // Avoid leaking user state into our tests.
+ b.setFS(FS.detect().setUserHome(null));
+ }
+ InMemoryRepository dest = b.build();
Config cfg = dest.getConfig();
cfg.setString("remote", "origin", "url", uri);
cfg.setString("remote", "origin", "fetch", "+refs/heads/*:refs/remotes/origin/*");
@@ -135,11 +130,6 @@
return testRepo;
}
- public static TestRepository<InMemoryRepository> cloneProject(
- Project.NameKey project, SshSession sshSession) throws Exception {
- return cloneProject(project, sshSession.getUrl() + "/" + project.get());
- }
-
public static Ref createAnnotatedTag(TestRepository<?> testRepo, String name, PersonIdent tagger)
throws GitAPIException {
TagCommand cmd =
diff --git a/java/com/google/gerrit/acceptance/InMemoryTestingDatabaseModule.java b/java/com/google/gerrit/acceptance/InMemoryTestingDatabaseModule.java
index a704d2f..a3207e2 100644
--- a/java/com/google/gerrit/acceptance/InMemoryTestingDatabaseModule.java
+++ b/java/com/google/gerrit/acceptance/InMemoryTestingDatabaseModule.java
@@ -55,8 +55,6 @@
@Override
protected void configure() {
bind(Config.class).annotatedWith(GerritServerConfig.class).toInstance(cfg);
-
- // TODO(dborowitz): Use jimfs.
bind(Path.class).annotatedWith(SitePath.class).toInstance(sitePath);
if (repoManager != null) {
diff --git a/java/com/google/gerrit/acceptance/InProcessProtocol.java b/java/com/google/gerrit/acceptance/InProcessProtocol.java
index 7a79ce4..4a203be6 100644
--- a/java/com/google/gerrit/acceptance/InProcessProtocol.java
+++ b/java/com/google/gerrit/acceptance/InProcessProtocol.java
@@ -83,8 +83,6 @@
@Provides
@RemotePeer
SocketAddress getSocketAddress() {
- // TODO(dborowitz): Could potentially fake this with thread ID or
- // something.
throw new OutOfScopeException("No remote peer in acceptance tests");
}
};
diff --git a/java/com/google/gerrit/acceptance/testsuite/project/BUILD b/java/com/google/gerrit/acceptance/testsuite/project/BUILD
new file mode 100644
index 0000000..3215a9c
--- /dev/null
+++ b/java/com/google/gerrit/acceptance/testsuite/project/BUILD
@@ -0,0 +1,21 @@
+package(default_testonly = 1)
+
+java_library(
+ name = "project",
+ srcs = glob(["*.java"]),
+ visibility = ["//visibility:public"],
+ deps = [
+ "//java/com/google/gerrit/acceptance:function",
+ "//java/com/google/gerrit/common:server",
+ "//java/com/google/gerrit/extensions:api",
+ "//java/com/google/gerrit/reviewdb:server",
+ "//java/com/google/gerrit/server",
+ "//java/com/google/gerrit/server/project/testing:project-test-util",
+ "//lib:guava",
+ "//lib/auto:auto-value",
+ "//lib/auto:auto-value-annotations",
+ "//lib/commons:lang",
+ "//lib/guice",
+ "//lib/jgit/org.eclipse.jgit:jgit",
+ ],
+)
diff --git a/java/com/google/gerrit/acceptance/testsuite/project/ProjectOperations.java b/java/com/google/gerrit/acceptance/testsuite/project/ProjectOperations.java
index 029d161..b310393 100644
--- a/java/com/google/gerrit/acceptance/testsuite/project/ProjectOperations.java
+++ b/java/com/google/gerrit/acceptance/testsuite/project/ProjectOperations.java
@@ -15,6 +15,8 @@
package com.google.gerrit.acceptance.testsuite.project;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.project.ProjectConfig;
+import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.revwalk.RevCommit;
/**
@@ -28,6 +30,9 @@
PerProjectOperations project(Project.NameKey key);
+ /** Starts a fluent chain for updating All-Projects. */
+ TestProjectUpdate.Builder allProjectsForUpdate();
+
interface PerProjectOperations {
/**
* Returns the commit for this project. branchName can either be shortened ("HEAD", "master") or
@@ -40,5 +45,33 @@
* fully qualified refname ("refs/heads/master").
*/
boolean hasHead(String branchName);
+
+ /** Returns a fresh {@link ProjectConfig} read from the tip of {@code refs/meta/config}. */
+ ProjectConfig getProjectConfig();
+
+ /**
+ * Returns a fresh JGit {@link Config} instance read from {@code project.config} at the tip of
+ * {@code refs/meta/config}. Does not have a base config, i.e. does not respect {@code
+ * $site_path/etc/project.config}.
+ */
+ Config getConfig();
+
+ /**
+ * Starts the fluent chain to update a project. The returned builder can be used to specify how
+ * the attributes of the project should be modified. To update the project for real, the {@link
+ * TestProjectUpdate.Builder#update()} must be called.
+ *
+ * <p>Example:
+ *
+ * <pre>
+ * projectOperations
+ * .forUpdate()
+ * .add(allow(ABANDON).ref("refs/*").group(REGISTERED_USERS))
+ * .update();
+ * </pre>
+ *
+ * @return a builder to update the check.
+ */
+ TestProjectUpdate.Builder forUpdate();
}
}
diff --git a/java/com/google/gerrit/acceptance/testsuite/project/ProjectOperationsImpl.java b/java/com/google/gerrit/acceptance/testsuite/project/ProjectOperationsImpl.java
index 09066e7..34e57b4 100644
--- a/java/com/google/gerrit/acceptance/testsuite/project/ProjectOperationsImpl.java
+++ b/java/com/google/gerrit/acceptance/testsuite/project/ProjectOperationsImpl.java
@@ -14,30 +14,68 @@
package com.google.gerrit.acceptance.testsuite.project;
-import com.google.common.base.Preconditions;
+import static com.google.gerrit.reviewdb.client.RefNames.REFS_CONFIG;
+import static com.google.gerrit.server.project.ProjectConfig.PROJECT_CONFIG;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.gerrit.acceptance.testsuite.project.TestProjectCreation.Builder;
+import com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.TestCapability;
+import com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.TestLabelPermission;
+import com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.TestPermission;
+import com.google.gerrit.common.data.AccessSection;
+import com.google.gerrit.common.data.GroupReference;
+import com.google.gerrit.common.data.Permission;
+import com.google.gerrit.common.data.PermissionRule;
+import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
+import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.project.CreateProjectArgs;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.project.ProjectConfig;
import com.google.gerrit.server.project.ProjectCreator;
import com.google.inject.Inject;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import org.apache.commons.lang.RandomStringUtils;
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.TreeWalk;
public class ProjectOperationsImpl implements ProjectOperations {
- private final ProjectCreator projectCreator;
+ private final AllProjectsName allProjectsName;
private final GitRepositoryManager repoManager;
+ private final MetaDataUpdate.Server metaDataUpdateFactory;
+ private final ProjectCache projectCache;
+ private final ProjectConfig.Factory projectConfigFactory;
+ private final ProjectCreator projectCreator;
@Inject
- ProjectOperationsImpl(GitRepositoryManager repoManager, ProjectCreator projectCreator) {
+ ProjectOperationsImpl(
+ AllProjectsName allProjectsName,
+ GitRepositoryManager repoManager,
+ MetaDataUpdate.Server metaDataUpdateFactory,
+ ProjectCache projectCache,
+ ProjectConfig.Factory projectConfigFactory,
+ ProjectCreator projectCreator) {
+ this.allProjectsName = allProjectsName;
this.repoManager = repoManager;
+ this.metaDataUpdateFactory = metaDataUpdateFactory;
+ this.projectCache = projectCache;
+ this.projectConfigFactory = projectConfigFactory;
this.projectCreator = projectCreator;
}
@@ -66,8 +104,12 @@
return new PerProjectOperations(key);
}
- private class PerProjectOperations implements ProjectOperations.PerProjectOperations {
+ @Override
+ public TestProjectUpdate.Builder allProjectsForUpdate() {
+ return project(allProjectsName).forUpdate();
+ }
+ private class PerProjectOperations implements ProjectOperations.PerProjectOperations {
Project.NameKey nameKey;
PerProjectOperations(Project.NameKey nameKey) {
@@ -76,7 +118,7 @@
@Override
public RevCommit getHead(String branch) {
- return Preconditions.checkNotNull(headOrNull(branch));
+ return requireNonNull(headOrNull(branch));
}
@Override
@@ -84,6 +126,88 @@
return headOrNull(branch) != null;
}
+ @Override
+ public TestProjectUpdate.Builder forUpdate() {
+ return TestProjectUpdate.builder(nameKey, allProjectsName, this::updateProject);
+ }
+
+ private void updateProject(TestProjectUpdate projectUpdate)
+ throws IOException, ConfigInvalidException {
+ try (MetaDataUpdate metaDataUpdate = metaDataUpdateFactory.create(nameKey)) {
+ ProjectConfig projectConfig = projectConfigFactory.read(metaDataUpdate);
+ removePermissions(projectConfig, projectUpdate.removedPermissions());
+ addCapabilities(projectConfig, projectUpdate.addedCapabilities());
+ addPermissions(projectConfig, projectUpdate.addedPermissions());
+ addLabelPermissions(projectConfig, projectUpdate.addedLabelPermissions());
+ setExclusiveGroupPermissions(projectConfig, projectUpdate.exclusiveGroupPermissions());
+ projectConfig.commit(metaDataUpdate);
+ }
+ projectCache.evict(nameKey);
+ }
+
+ private void removePermissions(
+ ProjectConfig projectConfig,
+ ImmutableList<TestProjectUpdate.TestPermissionKey> removedPermissions) {
+ for (TestProjectUpdate.TestPermissionKey p : removedPermissions) {
+ Permission permission =
+ projectConfig.getAccessSection(p.section(), true).getPermission(p.name(), true);
+ if (p.group().isPresent()) {
+ GroupReference group = new GroupReference(p.group().get(), p.group().get().get());
+ group = projectConfig.resolve(group);
+ permission.removeRule(group);
+ } else {
+ permission.clearRules();
+ }
+ }
+ }
+
+ private void addCapabilities(
+ ProjectConfig projectConfig, ImmutableList<TestCapability> addedCapabilities) {
+ for (TestCapability c : addedCapabilities) {
+ PermissionRule rule = newRule(projectConfig, c.group());
+ rule.setRange(c.min(), c.max());
+ projectConfig
+ .getAccessSection(AccessSection.GLOBAL_CAPABILITIES, true)
+ .getPermission(c.name(), true)
+ .add(rule);
+ }
+ }
+
+ private void addPermissions(
+ ProjectConfig projectConfig, ImmutableList<TestPermission> addedPermissions) {
+ for (TestPermission p : addedPermissions) {
+ PermissionRule rule = newRule(projectConfig, p.group());
+ rule.setAction(p.action());
+ rule.setForce(p.force());
+ projectConfig.getAccessSection(p.ref(), true).getPermission(p.name(), true).add(rule);
+ }
+ }
+
+ private void addLabelPermissions(
+ ProjectConfig projectConfig, ImmutableList<TestLabelPermission> addedLabelPermissions) {
+ for (TestLabelPermission p : addedLabelPermissions) {
+ PermissionRule rule = newRule(projectConfig, p.group());
+ rule.setAction(p.action());
+ rule.setRange(p.min(), p.max());
+ String permissionName =
+ p.impersonation() ? Permission.forLabelAs(p.name()) : Permission.forLabel(p.name());
+ Permission permission =
+ projectConfig.getAccessSection(p.ref(), true).getPermission(permissionName, true);
+ permission.add(rule);
+ }
+ }
+
+ private void setExclusiveGroupPermissions(
+ ProjectConfig projectConfig,
+ ImmutableMap<TestProjectUpdate.TestPermissionKey, Boolean> exclusiveGroupPermissions) {
+ exclusiveGroupPermissions.forEach(
+ (key, exclusive) ->
+ projectConfig
+ .getAccessSection(key.section(), true)
+ .getPermission(key.name(), true)
+ .setExclusiveGroup(exclusive));
+ }
+
private RevCommit headOrNull(String branch) {
if (!branch.startsWith(Constants.R_REFS)) {
branch = RefNames.REFS_HEADS + branch;
@@ -97,5 +221,45 @@
throw new IllegalStateException(e);
}
}
+
+ @Override
+ public ProjectConfig getProjectConfig() {
+ try (Repository repo = repoManager.openRepository(nameKey)) {
+ ProjectConfig projectConfig = projectConfigFactory.create(nameKey);
+ projectConfig.load(nameKey, repo);
+ return projectConfig;
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Override
+ public Config getConfig() {
+ try (Repository repo = repoManager.openRepository(nameKey);
+ RevWalk rw = new RevWalk(repo)) {
+ Ref ref = repo.exactRef(REFS_CONFIG);
+ if (ref == null) {
+ return new Config();
+ }
+ RevTree tree = rw.parseTree(ref.getObjectId());
+ TreeWalk tw = TreeWalk.forPath(rw.getObjectReader(), PROJECT_CONFIG, tree);
+ if (tw == null) {
+ return new Config();
+ }
+ ObjectLoader loader = rw.getObjectReader().open(tw.getObjectId(0));
+ String text = new String(loader.getCachedBytes(), UTF_8);
+ Config config = new Config();
+ config.fromText(text);
+ return config;
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+
+ private static PermissionRule newRule(ProjectConfig project, AccountGroup.UUID groupUUID) {
+ GroupReference group = new GroupReference(groupUUID, groupUUID.get());
+ group = project.resolve(group);
+ return new PermissionRule(group);
}
}
diff --git a/java/com/google/gerrit/acceptance/testsuite/project/TestProjectUpdate.java b/java/com/google/gerrit/acceptance/testsuite/project/TestProjectUpdate.java
new file mode 100644
index 0000000..6cbf40d
--- /dev/null
+++ b/java/com/google/gerrit/acceptance/testsuite/project/TestProjectUpdate.java
@@ -0,0 +1,436 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.acceptance.testsuite.project;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.gerrit.common.data.AccessSection.GLOBAL_CAPABILITIES;
+import static java.util.Objects.requireNonNull;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.gerrit.acceptance.testsuite.ThrowingConsumer;
+import com.google.gerrit.common.data.GlobalCapability;
+import com.google.gerrit.common.data.LabelType;
+import com.google.gerrit.common.data.Permission;
+import com.google.gerrit.common.data.PermissionRange;
+import com.google.gerrit.common.data.PermissionRule;
+import com.google.gerrit.reviewdb.client.AccountGroup;
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.config.AllProjectsName;
+import java.util.Optional;
+import org.eclipse.jgit.lib.Constants;
+
+@AutoValue
+public abstract class TestProjectUpdate {
+ /** Starts a builder for allowing a capability. */
+ public static TestCapability.Builder allowCapability(String name) {
+ return TestCapability.builder().name(name);
+ }
+
+ /** Records a global capability to be updated. */
+ @AutoValue
+ public abstract static class TestCapability {
+ private static Builder builder() {
+ return new AutoValue_TestProjectUpdate_TestCapability.Builder();
+ }
+
+ abstract String name();
+
+ abstract AccountGroup.UUID group();
+
+ abstract int min();
+
+ abstract int max();
+
+ /** Builder for {@link TestCapability}. */
+ @AutoValue.Builder
+ public abstract static class Builder {
+ /** Sets the name of the capability. */
+ public abstract Builder name(String name);
+
+ abstract String name();
+
+ /** Sets the group to which the capability applies. */
+ public abstract Builder group(AccountGroup.UUID group);
+
+ abstract Builder min(int min);
+
+ abstract Optional<Integer> min();
+
+ abstract Builder max(int max);
+
+ abstract Optional<Integer> max();
+
+ /** Sets the minimum and maximum values for the capability. */
+ public Builder range(int min, int max) {
+ checkNonInvertedRange(min, max);
+ return min(min).max(max);
+ }
+
+ /** Builds the {@link TestCapability}. */
+ abstract TestCapability autoBuild();
+
+ public TestCapability build() {
+ PermissionRange.WithDefaults withDefaults = GlobalCapability.getRange(name());
+ if (withDefaults != null) {
+ int min = min().orElse(withDefaults.getDefaultMin());
+ int max = max().orElse(withDefaults.getDefaultMax());
+ range(min, max);
+ // Don't enforce range is nonempty; this is allowed for e.g. batchChangesLimit.
+ } else {
+ checkArgument(
+ !min().isPresent() && !max().isPresent(),
+ "capability %s does not support ranges",
+ name());
+ range(0, 0);
+ }
+
+ return autoBuild();
+ }
+ }
+ }
+
+ /** Starts a builder for allowing a permission. */
+ public static TestPermission.Builder allow(String name) {
+ return TestPermission.builder().name(name).action(PermissionRule.Action.ALLOW);
+ }
+
+ /** Starts a builder for denying a permission. */
+ public static TestPermission.Builder deny(String name) {
+ return TestPermission.builder().name(name).action(PermissionRule.Action.DENY);
+ }
+
+ /** Starts a builder for blocking a permission. */
+ public static TestPermission.Builder block(String name) {
+ return TestPermission.builder().name(name).action(PermissionRule.Action.BLOCK);
+ }
+
+ /**
+ * Records a permission to be updated.
+ *
+ * <p>Not used for permissions that have ranges (label permissions) or global capabilities.
+ */
+ @AutoValue
+ public abstract static class TestPermission {
+ private static Builder builder() {
+ return new AutoValue_TestProjectUpdate_TestPermission.Builder().force(false);
+ }
+
+ abstract String name();
+
+ abstract String ref();
+
+ abstract AccountGroup.UUID group();
+
+ abstract PermissionRule.Action action();
+
+ abstract boolean force();
+
+ /** Builder for {@link TestPermission}. */
+ @AutoValue.Builder
+ public abstract static class Builder {
+ abstract Builder name(String name);
+
+ /** Sets the ref pattern used on the permission. */
+ public abstract Builder ref(String ref);
+
+ /** Sets the group to which the permission applies. */
+ public abstract Builder group(AccountGroup.UUID groupUuid);
+
+ abstract Builder action(PermissionRule.Action action);
+
+ /** Sets whether the permission is a force permission. */
+ public abstract Builder force(boolean force);
+
+ /** Builds the {@link TestPermission}. */
+ public abstract TestPermission build();
+ }
+ }
+
+ /** Starts a builder for allowing a label permission. */
+ public static TestLabelPermission.Builder allowLabel(String name) {
+ return TestLabelPermission.builder().name(name).action(PermissionRule.Action.ALLOW);
+ }
+
+ /** Starts a builder for denying a label permission. */
+ public static TestLabelPermission.Builder blockLabel(String name) {
+ return TestLabelPermission.builder().name(name).action(PermissionRule.Action.BLOCK);
+ }
+
+ /** Records a label permission to be updated. */
+ @AutoValue
+ public abstract static class TestLabelPermission {
+ private static Builder builder() {
+ return new AutoValue_TestProjectUpdate_TestLabelPermission.Builder().impersonation(false);
+ }
+
+ abstract String name();
+
+ abstract String ref();
+
+ abstract AccountGroup.UUID group();
+
+ abstract PermissionRule.Action action();
+
+ abstract int min();
+
+ abstract int max();
+
+ abstract boolean impersonation();
+
+ /** Builder for {@link TestLabelPermission}. */
+ @AutoValue.Builder
+ public abstract static class Builder {
+ abstract Builder name(String name);
+
+ /** Sets the ref pattern used on the permission. */
+ public abstract Builder ref(String ref);
+
+ /** Sets the group to which the permission applies. */
+ public abstract Builder group(AccountGroup.UUID group);
+
+ abstract Builder action(PermissionRule.Action action);
+
+ abstract Builder min(int min);
+
+ abstract Builder max(int max);
+
+ /** Sets the minimum and maximum values for the permission. */
+ public Builder range(int min, int max) {
+ checkArgument(min != 0 || max != 0, "empty range");
+ checkNonInvertedRange(min, max);
+ return min(min).max(max);
+ }
+
+ /** Sets whether this permission should be for impersonating another user's votes. */
+ public abstract Builder impersonation(boolean impersonation);
+
+ abstract TestLabelPermission autoBuild();
+
+ /** Builds the {@link TestPermission}. */
+ public TestLabelPermission build() {
+ TestLabelPermission result = autoBuild();
+ checkLabelName(result.name());
+ return result;
+ }
+ }
+ }
+
+ /**
+ * Starts a builder for describing a permission key for deletion. Not for label permissions or
+ * global capabilities.
+ */
+ public static TestPermissionKey.Builder permissionKey(String name) {
+ return TestPermissionKey.builder().name(name);
+ }
+
+ /** Starts a builder for describing a label permission key for deletion. */
+ public static TestPermissionKey.Builder labelPermissionKey(String name) {
+ checkLabelName(name);
+ return TestPermissionKey.builder().name(Permission.forLabel(name));
+ }
+
+ /** Starts a builder for describing a capability key for deletion. */
+ public static TestPermissionKey.Builder capabilityKey(String name) {
+ return TestPermissionKey.builder().name(name).section(GLOBAL_CAPABILITIES);
+ }
+
+ /** Records the key of a permission (of any type) for deletion. */
+ @AutoValue
+ public abstract static class TestPermissionKey {
+ private static Builder builder() {
+ return new AutoValue_TestProjectUpdate_TestPermissionKey.Builder();
+ }
+
+ abstract String section();
+
+ abstract String name();
+
+ abstract Optional<AccountGroup.UUID> group();
+
+ @AutoValue.Builder
+ public abstract static class Builder {
+ abstract Builder section(String section);
+
+ abstract Optional<String> section();
+
+ /** Sets the ref pattern used on the permission. Not for global capabilities. */
+ public Builder ref(String ref) {
+ requireNonNull(ref);
+ checkArgument(ref.startsWith(Constants.R_REFS), "must be a ref: %s", ref);
+ checkArgument(
+ !section().isPresent() || !section().get().equals(GLOBAL_CAPABILITIES),
+ "can't set ref on global capability");
+ return section(ref);
+ }
+
+ abstract Builder name(String name);
+
+ /** Sets the group to which the permission applies. */
+ public abstract Builder group(AccountGroup.UUID group);
+
+ /** Builds the {@link TestPermissionKey}. */
+ public abstract TestPermissionKey build();
+ }
+ }
+
+ static Builder builder(
+ Project.NameKey nameKey,
+ AllProjectsName allProjectsName,
+ ThrowingConsumer<TestProjectUpdate> projectUpdater) {
+ return new AutoValue_TestProjectUpdate.Builder()
+ .nameKey(nameKey)
+ .allProjectsName(allProjectsName)
+ .projectUpdater(projectUpdater);
+ }
+
+ /** Builder for {@link TestProjectUpdate}. */
+ @AutoValue.Builder
+ public abstract static class Builder {
+ abstract Builder nameKey(Project.NameKey project);
+
+ abstract Builder allProjectsName(AllProjectsName allProjects);
+
+ abstract ImmutableList.Builder<TestPermission> addedPermissionsBuilder();
+
+ abstract ImmutableList.Builder<TestLabelPermission> addedLabelPermissionsBuilder();
+
+ abstract ImmutableList.Builder<TestCapability> addedCapabilitiesBuilder();
+
+ abstract ImmutableList.Builder<TestPermissionKey> removedPermissionsBuilder();
+
+ abstract ImmutableMap.Builder<TestPermissionKey, Boolean> exclusiveGroupPermissionsBuilder();
+
+ /** Adds a permission to be included in this update. */
+ public Builder add(TestPermission testPermission) {
+ addedPermissionsBuilder().add(testPermission);
+ return this;
+ }
+
+ /** Adds a permission to be included in this update. */
+ public Builder add(TestPermission.Builder testPermissionBuilder) {
+ return add(testPermissionBuilder.build());
+ }
+
+ /** Adds a label permission to be included in this update. */
+ public Builder add(TestLabelPermission testLabelPermission) {
+ addedLabelPermissionsBuilder().add(testLabelPermission);
+ return this;
+ }
+
+ /** Adds a label permission to be included in this update. */
+ public Builder add(TestLabelPermission.Builder testLabelPermissionBuilder) {
+ return add(testLabelPermissionBuilder.build());
+ }
+
+ /** Adds a capability to be included in this update. */
+ public Builder add(TestCapability testCapability) {
+ addedCapabilitiesBuilder().add(testCapability);
+ return this;
+ }
+
+ /** Adds a capability to be included in this update. */
+ public Builder add(TestCapability.Builder testCapabilityBuilder) {
+ return add(testCapabilityBuilder.build());
+ }
+
+ /** Removes a permission, label permission, or capability as part of this update. */
+ public Builder remove(TestPermissionKey testPermissionKey) {
+ removedPermissionsBuilder().add(testPermissionKey);
+ return this;
+ }
+
+ /** Removes a permission, label permission, or capability as part of this update. */
+ public Builder remove(TestPermissionKey.Builder testPermissionKeyBuilder) {
+ return remove(testPermissionKeyBuilder.build());
+ }
+
+ /** Sets the exclusive bit bit for the given permission key. */
+ public Builder setExclusiveGroup(
+ TestPermissionKey.Builder testPermissionKeyBuilder, boolean exclusive) {
+ return setExclusiveGroup(testPermissionKeyBuilder.build(), exclusive);
+ }
+
+ /** Sets the exclusive bit bit for the given permission key. */
+ public Builder setExclusiveGroup(TestPermissionKey testPermissionKey, boolean exclusive) {
+ checkArgument(
+ !testPermissionKey.group().isPresent(),
+ "do not specify group for setExclusiveGroup: %s",
+ testPermissionKey);
+ checkArgument(
+ !testPermissionKey.section().equals(GLOBAL_CAPABILITIES),
+ "setExclusiveGroup not valid for global capabilities: %s",
+ testPermissionKey);
+ exclusiveGroupPermissionsBuilder().put(testPermissionKey, exclusive);
+ return this;
+ }
+
+ abstract Builder projectUpdater(ThrowingConsumer<TestProjectUpdate> projectUpdater);
+
+ abstract TestProjectUpdate autoBuild();
+
+ TestProjectUpdate build() {
+ TestProjectUpdate projectUpdate = autoBuild();
+ if (projectUpdate.hasCapabilityUpdates()) {
+ checkArgument(
+ projectUpdate.nameKey().equals(projectUpdate.allProjectsName()),
+ "cannot update global capabilities on %s, only %s: %s",
+ projectUpdate.nameKey(),
+ projectUpdate.allProjectsName(),
+ projectUpdate);
+ }
+ return projectUpdate;
+ }
+
+ /** Executes the update, updating the underlying project. */
+ public void update() {
+ TestProjectUpdate projectUpdate = build();
+ projectUpdate.projectUpdater().acceptAndThrowSilently(projectUpdate);
+ }
+ }
+
+ abstract Project.NameKey nameKey();
+
+ abstract AllProjectsName allProjectsName();
+
+ abstract ImmutableList<TestPermission> addedPermissions();
+
+ abstract ImmutableList<TestLabelPermission> addedLabelPermissions();
+
+ abstract ImmutableList<TestCapability> addedCapabilities();
+
+ abstract ImmutableList<TestPermissionKey> removedPermissions();
+
+ abstract ImmutableMap<TestPermissionKey, Boolean> exclusiveGroupPermissions();
+
+ abstract ThrowingConsumer<TestProjectUpdate> projectUpdater();
+
+ boolean hasCapabilityUpdates() {
+ return !addedCapabilities().isEmpty()
+ || removedPermissions().stream().anyMatch(k -> k.section().equals(GLOBAL_CAPABILITIES));
+ }
+
+ private static void checkLabelName(String name) {
+ // "label-Code-Review" is technically a valid label name, and we don't prevent users from
+ // using it in production, but specifying it in a test is programmer error.
+ checkArgument(!Permission.isLabel(name), "expected label name, got permission name: %s", name);
+ LabelType.checkName(name);
+ }
+
+ private static void checkNonInvertedRange(int min, int max) {
+ checkArgument(min <= max, "inverted range: %s > %s", min, max);
+ }
+}
diff --git a/java/com/google/gerrit/common/FileUtil.java b/java/com/google/gerrit/common/FileUtil.java
index 04288bc..5b0925e 100644
--- a/java/com/google/gerrit/common/FileUtil.java
+++ b/java/com/google/gerrit/common/FileUtil.java
@@ -44,7 +44,6 @@
}
public static void chmod(int mode, Path path) {
- // TODO(dborowitz): Is there a portable way to do this with NIO?
chmod(mode, path.toFile());
}
diff --git a/java/com/google/gerrit/common/UsedAt.java b/java/com/google/gerrit/common/UsedAt.java
index 1be6353..1816d50 100644
--- a/java/com/google/gerrit/common/UsedAt.java
+++ b/java/com/google/gerrit/common/UsedAt.java
@@ -14,6 +14,7 @@
package com.google.gerrit.common;
+import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@@ -22,13 +23,13 @@
import java.lang.annotation.Target;
/**
- * A marker for a method that is public solely because it is called from inside a project or an
- * organisation using Gerrit.
+ * A marker to say a method/type/field is added or is increased to public solely because it is
+ * called from inside a project or an organisation using Gerrit.
*/
-@Target({METHOD, TYPE})
+@Target({METHOD, TYPE, FIELD})
@Retention(RUNTIME)
public @interface UsedAt {
- /** Enumeration of projects that call a method that would otherwise be private. */
+ /** Enumeration of projects that call a method/type/field. */
enum Project {
GOOGLE,
PLUGIN_CHECKS,
diff --git a/java/com/google/gerrit/common/data/LabelFunction.java b/java/com/google/gerrit/common/data/LabelFunction.java
index 7d13c70..3c00cf5 100644
--- a/java/com/google/gerrit/common/data/LabelFunction.java
+++ b/java/com/google/gerrit/common/data/LabelFunction.java
@@ -98,18 +98,18 @@
}
for (PatchSetApproval a : approvals) {
- if (a.getValue() == 0) {
+ if (a.value() == 0) {
continue;
}
if (isBlock && labelType.isMaxNegative(a)) {
- submitRecordLabel.appliedBy = a.getAccountId();
+ submitRecordLabel.appliedBy = a.accountId();
submitRecordLabel.status = SubmitRecord.Label.Status.REJECT;
return submitRecordLabel;
}
if (labelType.isMaxPositive(a) || !requiresMaxValue) {
- submitRecordLabel.appliedBy = a.getAccountId();
+ submitRecordLabel.appliedBy = a.accountId();
submitRecordLabel.status = SubmitRecord.Label.Status.MAY;
if (isRequired) {
diff --git a/java/com/google/gerrit/common/data/LabelType.java b/java/com/google/gerrit/common/data/LabelType.java
index 0696df0..25b8d19 100644
--- a/java/com/google/gerrit/common/data/LabelType.java
+++ b/java/com/google/gerrit/common/data/LabelType.java
@@ -155,7 +155,7 @@
}
public boolean matches(PatchSetApproval psa) {
- return psa.getLabelId().get().equalsIgnoreCase(name);
+ return psa.labelId().get().equalsIgnoreCase(name);
}
public LabelFunction getFunction() {
@@ -279,11 +279,11 @@
}
public boolean isMaxNegative(PatchSetApproval ca) {
- return maxNegative == ca.getValue();
+ return maxNegative == ca.value();
}
public boolean isMaxPositive(PatchSetApproval ca) {
- return maxPositive == ca.getValue();
+ return maxPositive == ca.value();
}
public LabelValue getValue(short value) {
@@ -291,7 +291,7 @@
}
public LabelValue getValue(PatchSetApproval ca) {
- return byValue.get(ca.getValue());
+ return byValue.get(ca.value());
}
public LabelId getLabelId() {
diff --git a/java/com/google/gerrit/common/data/testing/GroupReferenceSubject.java b/java/com/google/gerrit/common/data/testing/GroupReferenceSubject.java
index cd96cf4..61263fc 100644
--- a/java/com/google/gerrit/common/data/testing/GroupReferenceSubject.java
+++ b/java/com/google/gerrit/common/data/testing/GroupReferenceSubject.java
@@ -33,19 +33,20 @@
return GroupReferenceSubject::new;
}
+ private final GroupReference group;
+
private GroupReferenceSubject(FailureMetadata metadata, GroupReference group) {
super(metadata, group);
+ this.group = group;
}
public ComparableSubject<?, AccountGroup.UUID> groupUuid() {
isNotNull();
- GroupReference group = actual();
return check("getUUID()").that(group.getUUID());
}
public StringSubject name() {
isNotNull();
- GroupReference group = actual();
return check("getName()").that(group.getName());
}
}
diff --git a/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java b/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
index 86f1083..e215759 100644
--- a/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
+++ b/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
@@ -185,7 +185,7 @@
@Override
public void deleteAll() {
// Delete the index, if it exists.
- String endpoint = indexName + client.adapter().indicesExistParam();
+ String endpoint = indexName + client.adapter().indicesExistParams();
Response response = performRequest("HEAD", endpoint);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
@@ -224,10 +224,15 @@
}
protected String getMappingsFor(String type, MappingProperties properties) {
- JsonObject mappingType = new JsonObject();
- mappingType.add(type, gson.toJsonTree(properties));
JsonObject mappings = new JsonObject();
- mappings.add(MAPPINGS, gson.toJsonTree(mappingType));
+
+ if (client.adapter().omitType()) {
+ mappings.add(MAPPINGS, gson.toJsonTree(properties));
+ } else {
+ JsonObject mappingType = new JsonObject();
+ mappingType.add(type, gson.toJsonTree(properties));
+ mappings.add(MAPPINGS, gson.toJsonTree(mappingType));
+ }
return gson.toJson(mappings);
}
@@ -300,7 +305,6 @@
protected JsonArray getSortArray(String idFieldName) {
JsonObject properties = new JsonObject();
properties.addProperty(ORDER, "asc");
- client.adapter().setIgnoreUnmapped(properties);
JsonArray sortArray = new JsonArray();
addNamedElement(idFieldName, properties, sortArray);
@@ -310,11 +314,12 @@
protected String getURI(String type, String request) {
try {
String encodedIndexName = URLEncoder.encode(indexName, UTF_8.toString());
- if (SEARCH.equals(request) && client.adapter().omitTypeFromSearch()) {
+ if (SEARCH.equals(request) && client.adapter().omitType()) {
return encodedIndexName + "/" + request;
}
- String encodedType = URLEncoder.encode(type, UTF_8.toString());
- return encodedIndexName + "/" + encodedType + "/" + request;
+ String encodedTypeIfAny =
+ client.adapter().omitType() ? "" : "/" + URLEncoder.encode(type, UTF_8.toString());
+ return encodedIndexName + encodedTypeIfAny + "/" + request;
} catch (UnsupportedEncodingException e) {
throw new StorageException(e);
}
diff --git a/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java b/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
index 38f8578..f595fdc 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticChangeIndex.java
@@ -122,7 +122,7 @@
BulkRequest bulk =
new IndexRequest(getId(cd), indexName, adapter.getType(insertIndex), adapter)
.add(new UpdateRequest<>(schema, cd));
- if (!adapter.usePostV5Type()) {
+ if (adapter.deleteToReplace()) {
bulk.add(new DeleteRequest(cd.getId().toString(), indexName, deleteIndex, adapter));
}
@@ -141,17 +141,19 @@
throws QueryParseException {
Set<Change.Status> statuses = ChangeIndexRewriter.getPossibleStatus(p);
List<String> indexes = Lists.newArrayListWithCapacity(2);
- if (client.adapter().usePostV5Type()) {
- if (!Sets.intersection(statuses, OPEN_STATUSES).isEmpty()
- || !Sets.intersection(statuses, CLOSED_STATUSES).isEmpty()) {
- indexes.add(ElasticQueryAdapter.POST_V5_TYPE);
- }
- } else {
- if (!Sets.intersection(statuses, OPEN_STATUSES).isEmpty()) {
- indexes.add(OPEN_CHANGES);
- }
- if (!Sets.intersection(statuses, CLOSED_STATUSES).isEmpty()) {
- indexes.add(CLOSED_CHANGES);
+ if (!client.adapter().omitType()) {
+ if (client.adapter().useV6Type()) {
+ if (!Sets.intersection(statuses, OPEN_STATUSES).isEmpty()
+ || !Sets.intersection(statuses, CLOSED_STATUSES).isEmpty()) {
+ indexes.add(ElasticQueryAdapter.V6_TYPE);
+ }
+ } else {
+ if (!Sets.intersection(statuses, OPEN_STATUSES).isEmpty()) {
+ indexes.add(OPEN_CHANGES);
+ }
+ if (!Sets.intersection(statuses, CLOSED_STATUSES).isEmpty()) {
+ indexes.add(CLOSED_CHANGES);
+ }
}
}
@@ -162,7 +164,6 @@
private JsonArray getSortArray() {
JsonObject properties = new JsonObject();
properties.addProperty(ORDER, "desc");
- client.adapter().setIgnoreUnmapped(properties);
JsonArray sortArray = new JsonArray();
addNamedElement(ChangeField.UPDATED.getName(), properties, sortArray);
@@ -176,16 +177,16 @@
@Override
protected String getDeleteActions(Change.Id c) {
- if (client.adapter().usePostV5Type()) {
- return delete(ElasticQueryAdapter.POST_V5_TYPE, c);
+ if (!client.adapter().useV5Type()) {
+ return delete(client.adapter().getType(), c);
}
return delete(OPEN_CHANGES, c) + delete(CLOSED_CHANGES, c);
}
@Override
protected String getMappings() {
- if (client.adapter().usePostV5Type()) {
- return getMappingsFor(ElasticQueryAdapter.POST_V5_TYPE, mapping.changes);
+ if (!client.adapter().useV5Type()) {
+ return getMappingsFor(client.adapter().getType(), mapping.changes);
}
return gson.toJson(ImmutableMap.of(MAPPINGS, mapping));
}
diff --git a/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java b/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java
index 23b6ffd..b015678 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticQueryAdapter.java
@@ -14,17 +14,22 @@
package com.google.gerrit.elasticsearch;
+import static com.google.gerrit.elasticsearch.ElasticVersion.V6_7;
+
import com.google.gson.JsonObject;
public class ElasticQueryAdapter {
- static final String POST_V5_TYPE = "_doc";
+ static final String V6_TYPE = "_doc";
- private final boolean ignoreUnmapped;
- private final boolean usePostV5Type;
- private final boolean omitTypeFromSearch;
+ private static final String INCLUDE_TYPE = "include_type_name=true";
+ private static final String INDICES = "?allow_no_indices=false";
+
+ private final boolean useV5Type;
+ private final boolean useV6Type;
+ private final boolean omitType;
private final String searchFilteringName;
- private final String indicesExistParam;
+ private final String indicesExistParams;
private final String exactFieldType;
private final String stringFieldType;
private final String indexProperty;
@@ -33,27 +38,22 @@
private final String includeTypeNameParam;
ElasticQueryAdapter(ElasticVersion version) {
- this.ignoreUnmapped = false;
- this.usePostV5Type = version.isV6OrLater();
- this.omitTypeFromSearch = version.isV7OrLater();
+ this.useV5Type = !version.isV6OrLater();
+ this.useV6Type = version.isV6();
+ this.omitType = version.isV7OrLater();
this.versionDiscoveryUrl = version.isV6OrLater() ? "/%s*" : "/%s*/_aliases";
this.searchFilteringName = "_source";
- this.indicesExistParam = "?allow_no_indices=false";
+ this.indicesExistParams =
+ version.isAtLeastMinorVersion(V6_7) ? INDICES + "&" + INCLUDE_TYPE : INDICES;
this.exactFieldType = "keyword";
this.stringFieldType = "text";
this.indexProperty = "true";
this.rawFieldsKey = "_source";
- this.includeTypeNameParam = version.isV7OrLater() ? "?include_type_name=true" : "";
- }
-
- void setIgnoreUnmapped(JsonObject properties) {
- if (ignoreUnmapped) {
- properties.addProperty("ignore_unmapped", true);
- }
+ this.includeTypeNameParam = version.isAtLeastMinorVersion(V6_7) ? "?" + INCLUDE_TYPE : "";
}
public void setType(JsonObject properties, String type) {
- if (!usePostV5Type) {
+ if (useV5Type) {
properties.addProperty("_type", type);
}
}
@@ -62,8 +62,8 @@
return searchFilteringName;
}
- String indicesExistParam() {
- return indicesExistParam;
+ String indicesExistParams() {
+ return indicesExistParams;
}
String exactFieldType() {
@@ -82,16 +82,31 @@
return rawFieldsKey;
}
- boolean usePostV5Type() {
- return usePostV5Type;
+ boolean deleteToReplace() {
+ return useV5Type;
}
- boolean omitTypeFromSearch() {
- return omitTypeFromSearch;
+ boolean useV5Type() {
+ return useV5Type;
+ }
+
+ boolean useV6Type() {
+ return useV6Type;
+ }
+
+ boolean omitType() {
+ return omitType;
+ }
+
+ String getType() {
+ return getType("");
}
String getType(String type) {
- return usePostV5Type() ? POST_V5_TYPE : type;
+ if (useV6Type()) {
+ return V6_TYPE;
+ }
+ return useV5Type() ? type : "";
}
String getVersionDiscoveryUrl(String name) {
diff --git a/java/com/google/gerrit/elasticsearch/ElasticVersion.java b/java/com/google/gerrit/elasticsearch/ElasticVersion.java
index 6de4d97..6be41c8 100644
--- a/java/com/google/gerrit/elasticsearch/ElasticVersion.java
+++ b/java/com/google/gerrit/elasticsearch/ElasticVersion.java
@@ -25,7 +25,8 @@
V6_5("6.5.*"),
V6_6("6.6.*"),
V6_7("6.7.*"),
- V7_0("7.0.*");
+ V7_0("7.0.*"),
+ V7_1("7.1.*");
private final String version;
private final Pattern pattern;
@@ -58,6 +59,10 @@
return Joiner.on(", ").join(ElasticVersion.values());
}
+ public boolean isV6() {
+ return getMajor() == 6;
+ }
+
public boolean isV6OrLater() {
return isAtLeastVersion(6);
}
@@ -66,8 +71,20 @@
return isAtLeastVersion(7);
}
- private boolean isAtLeastVersion(int v) {
- return Integer.valueOf(version.split("\\.")[0]) >= v;
+ private boolean isAtLeastVersion(int major) {
+ return getMajor() >= major;
+ }
+
+ public boolean isAtLeastMinorVersion(ElasticVersion version) {
+ return getMajor().equals(version.getMajor()) && getMinor() >= version.getMinor();
+ }
+
+ private Integer getMajor() {
+ return Integer.valueOf(version.split("\\.")[0]);
+ }
+
+ private Integer getMinor() {
+ return Integer.valueOf(version.split("\\.")[1]);
}
@Override
diff --git a/java/com/google/gerrit/extensions/common/GroupAuditEventInfo.java b/java/com/google/gerrit/extensions/common/GroupAuditEventInfo.java
index 3e6f762..711337a 100644
--- a/java/com/google/gerrit/extensions/common/GroupAuditEventInfo.java
+++ b/java/com/google/gerrit/extensions/common/GroupAuditEventInfo.java
@@ -15,6 +15,7 @@
package com.google.gerrit.extensions.common;
import java.sql.Timestamp;
+import java.util.Optional;
public abstract class GroupAuditEventInfo {
public enum Type {
@@ -30,35 +31,35 @@
public static UserMemberAuditEventInfo createAddUserEvent(
AccountInfo user, Timestamp date, AccountInfo member) {
- return new UserMemberAuditEventInfo(Type.ADD_USER, user, date, member);
+ return new UserMemberAuditEventInfo(Type.ADD_USER, user, Optional.of(date), member);
}
public static UserMemberAuditEventInfo createRemoveUserEvent(
- AccountInfo user, Timestamp date, AccountInfo member) {
+ AccountInfo user, Optional<Timestamp> date, AccountInfo member) {
return new UserMemberAuditEventInfo(Type.REMOVE_USER, user, date, member);
}
public static GroupMemberAuditEventInfo createAddGroupEvent(
AccountInfo user, Timestamp date, GroupInfo member) {
- return new GroupMemberAuditEventInfo(Type.ADD_GROUP, user, date, member);
+ return new GroupMemberAuditEventInfo(Type.ADD_GROUP, user, Optional.of(date), member);
}
public static GroupMemberAuditEventInfo createRemoveGroupEvent(
- AccountInfo user, Timestamp date, GroupInfo member) {
+ AccountInfo user, Optional<Timestamp> date, GroupInfo member) {
return new GroupMemberAuditEventInfo(Type.REMOVE_GROUP, user, date, member);
}
- protected GroupAuditEventInfo(Type type, AccountInfo user, Timestamp date) {
+ protected GroupAuditEventInfo(Type type, AccountInfo user, Optional<Timestamp> date) {
this.type = type;
this.user = user;
- this.date = date;
+ this.date = date.orElse(null);
}
public static class UserMemberAuditEventInfo extends GroupAuditEventInfo {
public AccountInfo member;
- public UserMemberAuditEventInfo(
- Type type, AccountInfo user, Timestamp date, AccountInfo member) {
+ private UserMemberAuditEventInfo(
+ Type type, AccountInfo user, Optional<Timestamp> date, AccountInfo member) {
super(type, user, date);
this.member = member;
}
@@ -67,8 +68,8 @@
public static class GroupMemberAuditEventInfo extends GroupAuditEventInfo {
public GroupInfo member;
- public GroupMemberAuditEventInfo(
- Type type, AccountInfo user, Timestamp date, GroupInfo member) {
+ private GroupMemberAuditEventInfo(
+ Type type, AccountInfo user, Optional<Timestamp> date, GroupInfo member) {
super(type, user, date);
this.member = member;
}
diff --git a/java/com/google/gerrit/extensions/common/testing/CommitInfoSubject.java b/java/com/google/gerrit/extensions/common/testing/CommitInfoSubject.java
index 5da0f7b..d827108 100644
--- a/java/com/google/gerrit/extensions/common/testing/CommitInfoSubject.java
+++ b/java/com/google/gerrit/extensions/common/testing/CommitInfoSubject.java
@@ -34,37 +34,35 @@
return CommitInfoSubject::new;
}
+ private final CommitInfo commitInfo;
+
private CommitInfoSubject(FailureMetadata failureMetadata, CommitInfo commitInfo) {
super(failureMetadata, commitInfo);
+ this.commitInfo = commitInfo;
}
public StringSubject commit() {
isNotNull();
- CommitInfo commitInfo = actual();
return check("commit").that(commitInfo.commit);
}
public ListSubject<CommitInfoSubject, CommitInfo> parents() {
isNotNull();
- CommitInfo commitInfo = actual();
return check("parents").about(elements()).thatCustom(commitInfo.parents, commits());
}
public GitPersonSubject committer() {
isNotNull();
- CommitInfo commitInfo = actual();
return check("committer").about(gitPersons()).that(commitInfo.committer);
}
public GitPersonSubject author() {
isNotNull();
- CommitInfo commitInfo = actual();
return check("author").about(gitPersons()).that(commitInfo.author);
}
public StringSubject message() {
isNotNull();
- CommitInfo commitInfo = actual();
return check("message").that(commitInfo.message);
}
}
diff --git a/java/com/google/gerrit/extensions/common/testing/ContentEntrySubject.java b/java/com/google/gerrit/extensions/common/testing/ContentEntrySubject.java
index 25750c1..e7aa01d 100644
--- a/java/com/google/gerrit/extensions/common/testing/ContentEntrySubject.java
+++ b/java/com/google/gerrit/extensions/common/testing/ContentEntrySubject.java
@@ -37,13 +37,15 @@
return ContentEntrySubject::new;
}
+ private final ContentEntry contentEntry;
+
private ContentEntrySubject(FailureMetadata failureMetadata, ContentEntry contentEntry) {
super(failureMetadata, contentEntry);
+ this.contentEntry = contentEntry;
}
public void isDueToRebase() {
isNotNull();
- ContentEntry contentEntry = actual();
if (contentEntry.dueToRebase == null || !contentEntry.dueToRebase) {
failWithActual(simpleFact("expected entry to be marked 'dueToRebase'"));
}
@@ -51,7 +53,6 @@
public void isNotDueToRebase() {
isNotNull();
- ContentEntry contentEntry = actual();
if (contentEntry.dueToRebase != null && contentEntry.dueToRebase) {
failWithActual(simpleFact("expected entry not to be marked 'dueToRebase'"));
}
@@ -59,7 +60,6 @@
public ListSubject<StringSubject, String> commonLines() {
isNotNull();
- ContentEntry contentEntry = actual();
return check("commonLines()")
.about(elements())
.that(contentEntry.ab, StandardSubjectBuilder::that);
@@ -67,31 +67,26 @@
public ListSubject<StringSubject, String> linesOfA() {
isNotNull();
- ContentEntry contentEntry = actual();
return check("linesOfA()").about(elements()).that(contentEntry.a, StandardSubjectBuilder::that);
}
public ListSubject<StringSubject, String> linesOfB() {
isNotNull();
- ContentEntry contentEntry = actual();
return check("linesOfB()").about(elements()).that(contentEntry.b, StandardSubjectBuilder::that);
}
public IterableSubject intralineEditsOfA() {
isNotNull();
- ContentEntry contentEntry = actual();
return check("intralineEditsOfA()").that(contentEntry.editA);
}
public IterableSubject intralineEditsOfB() {
isNotNull();
- ContentEntry contentEntry = actual();
return check("intralineEditsOfB()").that(contentEntry.editB);
}
public IntegerSubject numberOfSkippedLines() {
isNotNull();
- ContentEntry contentEntry = actual();
return check("numberOfSkippedLines()").that(contentEntry.skip);
}
}
diff --git a/java/com/google/gerrit/extensions/common/testing/DiffInfoSubject.java b/java/com/google/gerrit/extensions/common/testing/DiffInfoSubject.java
index 039991b..1322793 100644
--- a/java/com/google/gerrit/extensions/common/testing/DiffInfoSubject.java
+++ b/java/com/google/gerrit/extensions/common/testing/DiffInfoSubject.java
@@ -32,13 +32,15 @@
return assertAbout(DiffInfoSubject::new).that(diffInfo);
}
+ private final DiffInfo diffInfo;
+
private DiffInfoSubject(FailureMetadata failureMetadata, DiffInfo diffInfo) {
super(failureMetadata, diffInfo);
+ this.diffInfo = diffInfo;
}
public ListSubject<ContentEntrySubject, ContentEntry> content() {
isNotNull();
- DiffInfo diffInfo = actual();
return check("content")
.about(elements())
.thatCustom(diffInfo.content, ContentEntrySubject.contentEntries());
@@ -46,19 +48,16 @@
public ComparableSubject<?, ChangeType> changeType() {
isNotNull();
- DiffInfo diffInfo = actual();
return check("changeType").that(diffInfo.changeType);
}
public FileMetaSubject metaA() {
isNotNull();
- DiffInfo diffInfo = actual();
return check("metaA").about(fileMetas()).that(diffInfo.metaA);
}
public FileMetaSubject metaB() {
isNotNull();
- DiffInfo diffInfo = actual();
return check("metaB").about(fileMetas()).that(diffInfo.metaB);
}
}
diff --git a/java/com/google/gerrit/extensions/common/testing/EditInfoSubject.java b/java/com/google/gerrit/extensions/common/testing/EditInfoSubject.java
index 8e357c7..25db1fe 100644
--- a/java/com/google/gerrit/extensions/common/testing/EditInfoSubject.java
+++ b/java/com/google/gerrit/extensions/common/testing/EditInfoSubject.java
@@ -39,19 +39,20 @@
return OptionalSubject.assertThat(editInfoOptional, edits());
}
+ private final EditInfo editInfo;
+
private EditInfoSubject(FailureMetadata failureMetadata, EditInfo editInfo) {
super(failureMetadata, editInfo);
+ this.editInfo = editInfo;
}
public CommitInfoSubject commit() {
isNotNull();
- EditInfo editInfo = actual();
return check("commit").about(commits()).that(editInfo.commit);
}
public StringSubject baseRevision() {
isNotNull();
- EditInfo editInfo = actual();
return check("baseRevision").that(editInfo.baseRevision);
}
}
diff --git a/java/com/google/gerrit/extensions/common/testing/FileInfoSubject.java b/java/com/google/gerrit/extensions/common/testing/FileInfoSubject.java
index 82f53de..27d3f0e 100644
--- a/java/com/google/gerrit/extensions/common/testing/FileInfoSubject.java
+++ b/java/com/google/gerrit/extensions/common/testing/FileInfoSubject.java
@@ -28,25 +28,25 @@
return assertAbout(FileInfoSubject::new).that(fileInfo);
}
+ private final FileInfo fileInfo;
+
private FileInfoSubject(FailureMetadata failureMetadata, FileInfo fileInfo) {
super(failureMetadata, fileInfo);
+ this.fileInfo = fileInfo;
}
public IntegerSubject linesInserted() {
isNotNull();
- FileInfo fileInfo = actual();
return check("linesInserted").that(fileInfo.linesInserted);
}
public IntegerSubject linesDeleted() {
isNotNull();
- FileInfo fileInfo = actual();
return check("linesDeleted").that(fileInfo.linesDeleted);
}
public ComparableSubject<?, Character> status() {
isNotNull();
- FileInfo fileInfo = actual();
return check("status").that(fileInfo.status);
}
}
diff --git a/java/com/google/gerrit/extensions/common/testing/FileMetaSubject.java b/java/com/google/gerrit/extensions/common/testing/FileMetaSubject.java
index d1b2031..6cac80dd 100644
--- a/java/com/google/gerrit/extensions/common/testing/FileMetaSubject.java
+++ b/java/com/google/gerrit/extensions/common/testing/FileMetaSubject.java
@@ -31,13 +31,15 @@
return FileMetaSubject::new;
}
+ private final FileMeta fileMeta;
+
private FileMetaSubject(FailureMetadata failureMetadata, FileMeta fileMeta) {
super(failureMetadata, fileMeta);
+ this.fileMeta = fileMeta;
}
public IntegerSubject totalLineCount() {
isNotNull();
- FileMeta fileMeta = actual();
return check("totalLineCount()").that(fileMeta.lines);
}
}
diff --git a/java/com/google/gerrit/extensions/common/testing/FixReplacementInfoSubject.java b/java/com/google/gerrit/extensions/common/testing/FixReplacementInfoSubject.java
index b720d8a..1ecc604 100644
--- a/java/com/google/gerrit/extensions/common/testing/FixReplacementInfoSubject.java
+++ b/java/com/google/gerrit/extensions/common/testing/FixReplacementInfoSubject.java
@@ -33,23 +33,26 @@
return FixReplacementInfoSubject::new;
}
+ private final FixReplacementInfo fixReplacementInfo;
+
private FixReplacementInfoSubject(
FailureMetadata failureMetadata, FixReplacementInfo fixReplacementInfo) {
super(failureMetadata, fixReplacementInfo);
+ this.fixReplacementInfo = fixReplacementInfo;
}
public StringSubject path() {
isNotNull();
- return check("path").that(actual().path);
+ return check("path").that(fixReplacementInfo.path);
}
public RangeSubject range() {
isNotNull();
- return check("range").about(ranges()).that(actual().range);
+ return check("range").about(ranges()).that(fixReplacementInfo.range);
}
public StringSubject replacement() {
isNotNull();
- return check("replacement").that(actual().replacement);
+ return check("replacement").that(fixReplacementInfo.replacement);
}
}
diff --git a/java/com/google/gerrit/extensions/common/testing/FixSuggestionInfoSubject.java b/java/com/google/gerrit/extensions/common/testing/FixSuggestionInfoSubject.java
index a5db833..1e95907 100644
--- a/java/com/google/gerrit/extensions/common/testing/FixSuggestionInfoSubject.java
+++ b/java/com/google/gerrit/extensions/common/testing/FixSuggestionInfoSubject.java
@@ -35,20 +35,23 @@
return FixSuggestionInfoSubject::new;
}
+ private final FixSuggestionInfo fixSuggestionInfo;
+
private FixSuggestionInfoSubject(
FailureMetadata failureMetadata, FixSuggestionInfo fixSuggestionInfo) {
super(failureMetadata, fixSuggestionInfo);
+ this.fixSuggestionInfo = fixSuggestionInfo;
}
public StringSubject fixId() {
- return check("fixId").that(actual().fixId);
+ return check("fixId").that(fixSuggestionInfo.fixId);
}
public ListSubject<FixReplacementInfoSubject, FixReplacementInfo> replacements() {
isNotNull();
return check("replacements")
.about(elements())
- .thatCustom(actual().replacements, fixReplacements());
+ .thatCustom(fixSuggestionInfo.replacements, fixReplacements());
}
public FixReplacementInfoSubject onlyReplacement() {
@@ -57,6 +60,6 @@
public StringSubject description() {
isNotNull();
- return check("description").that(actual().description);
+ return check("description").that(fixSuggestionInfo.description);
}
}
diff --git a/java/com/google/gerrit/extensions/common/testing/GitPersonSubject.java b/java/com/google/gerrit/extensions/common/testing/GitPersonSubject.java
index eb2fdff..c9f5a79 100644
--- a/java/com/google/gerrit/extensions/common/testing/GitPersonSubject.java
+++ b/java/com/google/gerrit/extensions/common/testing/GitPersonSubject.java
@@ -14,8 +14,8 @@
package com.google.gerrit.extensions.common.testing;
-import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.truth.Truth.assertAbout;
+import static java.util.Objects.requireNonNull;
import com.google.common.truth.ComparableSubject;
import com.google.common.truth.FailureMetadata;
@@ -37,36 +37,35 @@
return GitPersonSubject::new;
}
+ private final GitPerson gitPerson;
+
private GitPersonSubject(FailureMetadata failureMetadata, GitPerson gitPerson) {
super(failureMetadata, gitPerson);
+ this.gitPerson = gitPerson;
}
public StringSubject name() {
isNotNull();
- GitPerson gitPerson = actual();
return check("name").that(gitPerson.name);
}
public StringSubject email() {
isNotNull();
- GitPerson gitPerson = actual();
return check("email").that(gitPerson.email);
}
public ComparableSubject<?, Timestamp> date() {
isNotNull();
- GitPerson gitPerson = actual();
return check("date").that(gitPerson.date);
}
public IntegerSubject tz() {
isNotNull();
- GitPerson gitPerson = actual();
return check("tz").that(gitPerson.tz);
}
public void hasSameDateAs(GitPerson other) {
- checkNotNull(other, "'other' GitPerson must not be null");
+ requireNonNull(other, "'other' GitPerson must not be null");
isNotNull();
date().isEqualTo(other.date);
tz().isEqualTo(other.tz);
@@ -76,7 +75,7 @@
isNotNull();
name().isEqualTo(ident.getName());
email().isEqualTo(ident.getEmailAddress());
- check("roundedDate()").that(new Date(actual().date.getTime())).isEqualTo(ident.getWhen());
+ check("roundedDate()").that(new Date(gitPerson.date.getTime())).isEqualTo(ident.getWhen());
tz().isEqualTo(ident.getTimeZoneOffset());
}
}
diff --git a/java/com/google/gerrit/extensions/common/testing/RangeSubject.java b/java/com/google/gerrit/extensions/common/testing/RangeSubject.java
index 2b9cec3..0d049e0 100644
--- a/java/com/google/gerrit/extensions/common/testing/RangeSubject.java
+++ b/java/com/google/gerrit/extensions/common/testing/RangeSubject.java
@@ -32,36 +32,39 @@
return RangeSubject::new;
}
+ private final Comment.Range range;
+
private RangeSubject(FailureMetadata failureMetadata, Comment.Range range) {
super(failureMetadata, range);
+ this.range = range;
}
public IntegerSubject startLine() {
- return check("startLine").that(actual().startLine);
+ return check("startLine").that(range.startLine);
}
public IntegerSubject startCharacter() {
- return check("startCharacter").that(actual().startCharacter);
+ return check("startCharacter").that(range.startCharacter);
}
public IntegerSubject endLine() {
- return check("endLine").that(actual().endLine);
+ return check("endLine").that(range.endLine);
}
public IntegerSubject endCharacter() {
- return check("endCharacter").that(actual().endCharacter);
+ return check("endCharacter").that(range.endCharacter);
}
public void isValid() {
isNotNull();
- if (!actual().isValid()) {
+ if (!range.isValid()) {
failWithActual(simpleFact("expected to be valid"));
}
}
public void isInvalid() {
isNotNull();
- if (actual().isValid()) {
+ if (range.isValid()) {
failWithActual(simpleFact("expected to be invalid"));
}
}
diff --git a/java/com/google/gerrit/extensions/common/testing/RobotCommentInfoSubject.java b/java/com/google/gerrit/extensions/common/testing/RobotCommentInfoSubject.java
index ed9f97f..0a53154 100644
--- a/java/com/google/gerrit/extensions/common/testing/RobotCommentInfoSubject.java
+++ b/java/com/google/gerrit/extensions/common/testing/RobotCommentInfoSubject.java
@@ -39,15 +39,18 @@
return RobotCommentInfoSubject::new;
}
+ private final RobotCommentInfo robotCommentInfo;
+
private RobotCommentInfoSubject(
FailureMetadata failureMetadata, RobotCommentInfo robotCommentInfo) {
super(failureMetadata, robotCommentInfo);
+ this.robotCommentInfo = robotCommentInfo;
}
public ListSubject<FixSuggestionInfoSubject, FixSuggestionInfo> fixSuggestions() {
return check("fixSuggestions")
.about(elements())
- .thatCustom(actual().fixSuggestions, FixSuggestionInfoSubject.fixSuggestions());
+ .thatCustom(robotCommentInfo.fixSuggestions, FixSuggestionInfoSubject.fixSuggestions());
}
public FixSuggestionInfoSubject onlyFixSuggestion() {
diff --git a/java/com/google/gerrit/extensions/restapi/ResourceNotFoundException.java b/java/com/google/gerrit/extensions/restapi/ResourceNotFoundException.java
index e676828..75cf713 100644
--- a/java/com/google/gerrit/extensions/restapi/ResourceNotFoundException.java
+++ b/java/com/google/gerrit/extensions/restapi/ResourceNotFoundException.java
@@ -34,9 +34,8 @@
super("Not found: " + id.get());
}
- @SuppressWarnings("unchecked")
- @Override
public ResourceNotFoundException caching(CacheControl c) {
- return super.caching(c);
+ setCaching(c);
+ return this;
}
}
diff --git a/java/com/google/gerrit/extensions/restapi/RestApiException.java b/java/com/google/gerrit/extensions/restapi/RestApiException.java
index b09723e..f3d7dec 100644
--- a/java/com/google/gerrit/extensions/restapi/RestApiException.java
+++ b/java/com/google/gerrit/extensions/restapi/RestApiException.java
@@ -14,6 +14,8 @@
package com.google.gerrit.extensions.restapi;
+import static java.util.Objects.requireNonNull;
+
/** Root exception type for REST API failures. */
public class RestApiException extends Exception {
private static final long serialVersionUID = 1L;
@@ -33,9 +35,7 @@
return caching;
}
- @SuppressWarnings("unchecked")
- public <T extends RestApiException> T caching(CacheControl c) {
- caching = c;
- return (T) this;
+ protected void setCaching(CacheControl caching) {
+ this.caching = requireNonNull(caching);
}
}
diff --git a/java/com/google/gerrit/extensions/restapi/testing/BinaryResultSubject.java b/java/com/google/gerrit/extensions/restapi/testing/BinaryResultSubject.java
index 5109205..d492aa2 100644
--- a/java/com/google/gerrit/extensions/restapi/testing/BinaryResultSubject.java
+++ b/java/com/google/gerrit/extensions/restapi/testing/BinaryResultSubject.java
@@ -41,8 +41,11 @@
return OptionalSubject.assertThat(binaryResultOptional, binaryResults());
}
+ private final BinaryResult binaryResult;
+
private BinaryResultSubject(FailureMetadata failureMetadata, BinaryResult binaryResult) {
super(failureMetadata, binaryResult);
+ this.binaryResult = binaryResult;
}
public StringSubject asString() throws IOException {
@@ -50,7 +53,6 @@
// We shouldn't close the BinaryResult within this method as it might still
// be used afterwards. Besides, closing it doesn't have an effect for most
// implementations of a BinaryResult.
- BinaryResult binaryResult = actual();
return check("asString()").that(binaryResult.asString());
}
@@ -59,7 +61,6 @@
// We shouldn't close the BinaryResult within this method as it might still
// be used afterwards. Besides, closing it doesn't have an effect for most
// implementations of a BinaryResult.
- BinaryResult binaryResult = actual();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
binaryResult.writeTo(byteArrayOutputStream);
byte[] bytes = byteArrayOutputStream.toByteArray();
diff --git a/java/com/google/gerrit/git/testing/CommitSubject.java b/java/com/google/gerrit/git/testing/CommitSubject.java
index e9ba862..4d02313 100644
--- a/java/com/google/gerrit/git/testing/CommitSubject.java
+++ b/java/com/google/gerrit/git/testing/CommitSubject.java
@@ -56,8 +56,11 @@
commitSubject.hasSha1(expectedSha1);
}
- private CommitSubject(FailureMetadata metadata, RevCommit actual) {
- super(metadata, actual);
+ private final RevCommit commit;
+
+ private CommitSubject(FailureMetadata metadata, RevCommit commit) {
+ super(metadata, commit);
+ this.commit = commit;
}
/**
@@ -67,7 +70,6 @@
*/
public void hasCommitMessage(String expectedCommitMessage) {
isNotNull();
- RevCommit commit = actual();
check("getFullMessage()").that(commit.getFullMessage()).isEqualTo(expectedCommitMessage);
}
@@ -78,7 +80,6 @@
*/
public void hasCommitTimestamp(Timestamp expectedCommitTimestamp) {
isNotNull();
- RevCommit commit = actual();
long timestampDiffMs =
Math.abs(commit.getCommitTime() * 1000L - expectedCommitTimestamp.getTime());
check("commitTimestampDiff()").that(timestampDiffMs).isAtMost(SECONDS.toMillis(1));
@@ -91,7 +92,6 @@
*/
public void hasSha1(ObjectId expectedSha1) {
isNotNull();
- RevCommit commit = actual();
check("sha1()").that(commit).isEqualTo(expectedSha1);
}
}
diff --git a/java/com/google/gerrit/git/testing/ObjectIdSubject.java b/java/com/google/gerrit/git/testing/ObjectIdSubject.java
index fb2ee75..5a99229 100644
--- a/java/com/google/gerrit/git/testing/ObjectIdSubject.java
+++ b/java/com/google/gerrit/git/testing/ObjectIdSubject.java
@@ -29,13 +29,15 @@
return ObjectIdSubject::new;
}
- private ObjectIdSubject(FailureMetadata metadata, ObjectId actual) {
- super(metadata, actual);
+ private final ObjectId objectId;
+
+ private ObjectIdSubject(FailureMetadata metadata, ObjectId objectId) {
+ super(metadata, objectId);
+ this.objectId = objectId;
}
public void hasName(String expectedName) {
isNotNull();
- ObjectId objectId = actual();
check("getName()").that(objectId.getName()).isEqualTo(expectedName);
}
}
diff --git a/java/com/google/gerrit/git/testing/PushResultSubject.java b/java/com/google/gerrit/git/testing/PushResultSubject.java
index 48a0ac9..9ff4c3b 100644
--- a/java/com/google/gerrit/git/testing/PushResultSubject.java
+++ b/java/com/google/gerrit/git/testing/PushResultSubject.java
@@ -37,8 +37,11 @@
return assertAbout(PushResultSubject::new).that(actual);
}
- private PushResultSubject(FailureMetadata metadata, PushResult actual) {
- super(metadata, actual);
+ private final PushResult pushResult;
+
+ private PushResultSubject(FailureMetadata metadata, PushResult pushResult) {
+ super(metadata, pushResult);
+ this.pushResult = pushResult;
}
public void hasNoMessages() {
@@ -62,7 +65,7 @@
}
private String getTrimmedMessages() {
- return trimMessages(actual().getMessages());
+ return trimMessages(pushResult.getMessages());
}
@VisibleForTesting
@@ -81,7 +84,7 @@
public void hasProcessed(ImmutableMap<String, Integer> expected) {
isNotNull();
ImmutableMap<String, Integer> actual;
- String messages = actual().getMessages();
+ String messages = pushResult.getMessages();
try {
actual = parseProcessed(messages);
} catch (RuntimeException e) {
@@ -124,22 +127,25 @@
isNotNull();
return check("getRemoteUpdate(%s)", refName)
.about(refs())
- .that(actual().getRemoteUpdate(refName));
+ .that(pushResult.getRemoteUpdate(refName));
}
public RemoteRefUpdateSubject onlyRef(String refName) {
isNotNull();
check("setOfRefs()")
.about(StreamSubject.streams())
- .that(actual().getRemoteUpdates().stream().map(RemoteRefUpdate::getRemoteName))
+ .that(pushResult.getRemoteUpdates().stream().map(RemoteRefUpdate::getRemoteName))
.containsExactly(refName);
return ref(refName);
}
public static class RemoteRefUpdateSubject
extends Subject<RemoteRefUpdateSubject, RemoteRefUpdate> {
- private RemoteRefUpdateSubject(FailureMetadata metadata, RemoteRefUpdate actual) {
- super(metadata, actual);
+ private final RemoteRefUpdate remoteRefUpdate;
+
+ private RemoteRefUpdateSubject(FailureMetadata metadata, RemoteRefUpdate remoteRefUpdate) {
+ super(metadata, remoteRefUpdate);
+ this.remoteRefUpdate = remoteRefUpdate;
}
static Factory<RemoteRefUpdateSubject, RemoteRefUpdate> refs() {
@@ -148,7 +154,7 @@
public void hasStatus(RemoteRefUpdate.Status status) {
isNotNull();
- RemoteRefUpdate u = actual();
+ RemoteRefUpdate u = remoteRefUpdate;
check("getStatus()")
.withMessage(
"status message: %s", u.getMessage() != null ? ": " + u.getMessage() : "<emtpy>")
@@ -158,12 +164,12 @@
public void hasNoMessage() {
isNotNull();
- check("getMessage()").that(actual().getMessage()).isNull();
+ check("getMessage()").that(remoteRefUpdate.getMessage()).isNull();
}
public void hasMessage(String expected) {
isNotNull();
- check("getMessage()").that(actual().getMessage()).isEqualTo(expected);
+ check("getMessage()").that(remoteRefUpdate.getMessage()).isEqualTo(expected);
}
public void isOk() {
diff --git a/java/com/google/gerrit/gpg/PublicKeyStore.java b/java/com/google/gerrit/gpg/PublicKeyStore.java
index cc380da..519c400 100644
--- a/java/com/google/gerrit/gpg/PublicKeyStore.java
+++ b/java/com/google/gerrit/gpg/PublicKeyStore.java
@@ -16,6 +16,7 @@
import static com.google.common.base.Preconditions.checkState;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.eclipse.jgit.lib.Constants.EMPTY_TREE_ID;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
import com.google.common.base.Preconditions;
@@ -75,10 +76,6 @@
* after checking with a {@link PublicKeyChecker}.
*/
public class PublicKeyStore implements AutoCloseable {
-
- private static final ObjectId EMPTY_TREE =
- ObjectId.fromString("4b825dc642cb6eb9a060e54bf8d69288fbee4904");
-
/** Ref where GPG public keys are stored. */
public static final String REFS_GPG_KEYS = "refs/meta/gpg-keys";
@@ -361,7 +358,7 @@
deleteFromNotes(ins, fp);
}
cb.setTreeId(notes.writeTree(ins));
- if (cb.getTreeId().equals(tip != null ? tip.getTree() : EMPTY_TREE)) {
+ if (cb.getTreeId().equals(tip != null ? tip.getTree() : EMPTY_TREE_ID)) {
return RefUpdate.Result.NO_CHANGE;
}
diff --git a/java/com/google/gerrit/gpg/server/DeleteGpgKey.java b/java/com/google/gerrit/gpg/server/DeleteGpgKey.java
index 69e106c..a1217b3 100644
--- a/java/com/google/gerrit/gpg/server/DeleteGpgKey.java
+++ b/java/com/google/gerrit/gpg/server/DeleteGpgKey.java
@@ -17,7 +17,10 @@
import static com.google.gerrit.gpg.PublicKeyStore.keyIdToString;
import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_GPGKEY;
+import com.google.common.collect.ImmutableList;
+import com.google.common.flogger.FluentLogger;
import com.google.common.io.BaseEncoding;
+import com.google.gerrit.exceptions.EmailException;
import com.google.gerrit.extensions.common.Input;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
@@ -30,6 +33,7 @@
import com.google.gerrit.server.account.AccountsUpdate;
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIds;
+import com.google.gerrit.server.mail.send.DeleteKeySender;
import com.google.inject.Inject;
import com.google.inject.Provider;
import java.io.IOException;
@@ -42,22 +46,26 @@
import org.eclipse.jgit.lib.RefUpdate;
public class DeleteGpgKey implements RestModifyView<GpgKey, Input> {
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private final Provider<PersonIdent> serverIdent;
private final Provider<PublicKeyStore> storeProvider;
private final Provider<AccountsUpdate> accountsUpdateProvider;
private final ExternalIds externalIds;
+ private final DeleteKeySender.Factory deleteKeySenderFactory;
@Inject
DeleteGpgKey(
@GerritPersonIdent Provider<PersonIdent> serverIdent,
Provider<PublicKeyStore> storeProvider,
@UserInitiated Provider<AccountsUpdate> accountsUpdateProvider,
- ExternalIds externalIds) {
+ ExternalIds externalIds,
+ DeleteKeySender.Factory deleteKeySenderFactory) {
this.serverIdent = serverIdent;
this.storeProvider = storeProvider;
this.accountsUpdateProvider = accountsUpdateProvider;
this.externalIds = externalIds;
+ this.deleteKeySenderFactory = deleteKeySenderFactory;
}
@Override
@@ -90,6 +98,15 @@
switch (saveResult) {
case NO_CHANGE:
case FAST_FORWARD:
+ try {
+ deleteKeySenderFactory
+ .create(rsrc.getUser(), ImmutableList.of(PublicKeyStore.keyToString(key)))
+ .send();
+ } catch (EmailException e) {
+ logger.atSevere().withCause(e).log(
+ "Cannot send GPG key deletion message to %s",
+ rsrc.getUser().getAccount().getPreferredEmail());
+ }
break;
case FORCED:
case IO_FAILURE:
diff --git a/java/com/google/gerrit/gpg/server/PostGpgKeys.java b/java/com/google/gerrit/gpg/server/PostGpgKeys.java
index f641902..986d5ff 100644
--- a/java/com/google/gerrit/gpg/server/PostGpgKeys.java
+++ b/java/com/google/gerrit/gpg/server/PostGpgKeys.java
@@ -18,8 +18,11 @@
import static com.google.gerrit.gpg.PublicKeyStore.keyToString;
import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_GPGKEY;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.toList;
import com.google.common.base.Joiner;
+import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
@@ -27,12 +30,15 @@
import com.google.common.flogger.FluentLogger;
import com.google.common.io.BaseEncoding;
import com.google.gerrit.exceptions.EmailException;
+import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.extensions.api.accounts.GpgKeysInput;
import com.google.gerrit.extensions.common.GpgKeyInfo;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
+import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestModifyView;
+import com.google.gerrit.git.LockFailureException;
import com.google.gerrit.gpg.CheckResult;
import com.google.gerrit.gpg.Fingerprint;
import com.google.gerrit.gpg.GerritPublicKeyChecker;
@@ -49,7 +55,10 @@
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIds;
import com.google.gerrit.server.mail.send.AddKeySender;
+import com.google.gerrit.server.mail.send.DeleteKeySender;
import com.google.gerrit.server.query.account.InternalAccountQuery;
+import com.google.gerrit.server.update.RetryHelper;
+import com.google.gerrit.server.update.RetryHelper.ActionType;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
@@ -79,10 +88,12 @@
private final Provider<CurrentUser> self;
private final Provider<PublicKeyStore> storeProvider;
private final GerritPublicKeyChecker.Factory checkerFactory;
- private final AddKeySender.Factory addKeyFactory;
+ private final AddKeySender.Factory addKeySenderFactory;
+ private final DeleteKeySender.Factory deleteKeySenderFactory;
private final Provider<InternalAccountQuery> accountQueryProvider;
private final ExternalIds externalIds;
private final Provider<AccountsUpdate> accountsUpdateProvider;
+ private final RetryHelper retryHelper;
@Inject
PostGpgKeys(
@@ -90,24 +101,27 @@
Provider<CurrentUser> self,
Provider<PublicKeyStore> storeProvider,
GerritPublicKeyChecker.Factory checkerFactory,
- AddKeySender.Factory addKeyFactory,
+ AddKeySender.Factory addKeySenderFactory,
+ DeleteKeySender.Factory deleteKeySenderFactory,
Provider<InternalAccountQuery> accountQueryProvider,
ExternalIds externalIds,
- @UserInitiated Provider<AccountsUpdate> accountsUpdateProvider) {
+ @UserInitiated Provider<AccountsUpdate> accountsUpdateProvider,
+ RetryHelper retryHelper) {
this.serverIdent = serverIdent;
this.self = self;
this.storeProvider = storeProvider;
this.checkerFactory = checkerFactory;
- this.addKeyFactory = addKeyFactory;
+ this.addKeySenderFactory = addKeySenderFactory;
+ this.deleteKeySenderFactory = deleteKeySenderFactory;
this.accountQueryProvider = accountQueryProvider;
this.externalIds = externalIds;
this.accountsUpdateProvider = accountsUpdateProvider;
+ this.retryHelper = retryHelper;
}
@Override
public Map<String, GpgKeyInfo> apply(AccountResource rsrc, GpgKeysInput input)
- throws ResourceNotFoundException, BadRequestException, ResourceConflictException,
- PGPException, IOException, ConfigInvalidException {
+ throws RestApiException, PGPException, IOException, ConfigInvalidException {
GpgKeys.checkVisible(self, rsrc);
Collection<ExternalId> existingExtIds =
@@ -190,7 +204,24 @@
private void storeKeys(
AccountResource rsrc, List<PGPPublicKeyRing> keyRings, Collection<Fingerprint> toRemove)
- throws BadRequestException, ResourceConflictException, PGPException, IOException {
+ throws RestApiException, PGPException, IOException {
+ try {
+ retryHelper.execute(
+ ActionType.ACCOUNT_UPDATE,
+ () -> tryStoreKeys(rsrc, keyRings, toRemove),
+ LockFailureException.class::isInstance);
+ } catch (Exception e) {
+ Throwables.throwIfUnchecked(e);
+ Throwables.throwIfInstanceOf(e, RestApiException.class);
+ Throwables.throwIfInstanceOf(e, IOException.class);
+ Throwables.throwIfInstanceOf(e, PGPException.class);
+ throw new StorageException(e);
+ }
+ }
+
+ private Void tryStoreKeys(
+ AccountResource rsrc, List<PGPPublicKeyRing> keyRings, Collection<Fingerprint> toRemove)
+ throws RestApiException, PGPException, IOException {
try (PublicKeyStore store = storeProvider.get()) {
List<String> addedKeys = new ArrayList<>();
IdentifiedUser user = rsrc.getUser();
@@ -222,13 +253,24 @@
case FORCED:
if (!addedKeys.isEmpty()) {
try {
- addKeyFactory.create(user, addedKeys).send();
+ addKeySenderFactory.create(user, addedKeys).send();
} catch (EmailException e) {
logger.atSevere().withCause(e).log(
"Cannot send GPG key added message to %s",
rsrc.getUser().getAccount().getPreferredEmail());
}
}
+ if (!toRemove.isEmpty()) {
+ try {
+ deleteKeySenderFactory
+ .create(user, toRemove.stream().map(Fingerprint::toString).collect(toList()))
+ .send();
+ } catch (EmailException e) {
+ logger.atSevere().withCause(e).log(
+ "Cannot send GPG key deleted message to %s",
+ user.getAccount().getPreferredEmail());
+ }
+ }
break;
case NO_CHANGE:
break;
@@ -241,10 +283,10 @@
case REJECTED_MISSING_OBJECT:
case REJECTED_OTHER_REASON:
default:
- // TODO(dborowitz): Backoff and retry on LOCK_FAILURE.
throw new ResourceConflictException("Failed to save public keys: " + saveResult);
}
}
+ return null;
}
private ExternalId.Key toExtIdKey(byte[] fp) {
@@ -259,12 +301,12 @@
}
if (accountStates.size() > 1) {
- StringBuilder msg = new StringBuilder();
- msg.append("GPG key ")
- .append(extIdKey.get())
- .append(" associated with multiple accounts: ")
- .append(Lists.transform(accountStates, AccountState.ACCOUNT_ID_FUNCTION));
- throw new IllegalStateException(msg.toString());
+ String msg = "GPG key " + extIdKey.get() + " associated with multiple accounts: [";
+ msg =
+ accountStates.stream()
+ .map(a -> a.getAccount().getId().toString())
+ .collect(joining(", ", msg, "]"));
+ throw new IllegalStateException(msg);
}
return accountStates.get(0).getAccount();
diff --git a/java/com/google/gerrit/httpd/HttpServletResponseRecorder.java b/java/com/google/gerrit/httpd/HttpServletResponseRecorder.java
index 397d093..4ae7e5e 100644
--- a/java/com/google/gerrit/httpd/HttpServletResponseRecorder.java
+++ b/java/com/google/gerrit/httpd/HttpServletResponseRecorder.java
@@ -67,7 +67,7 @@
headers.put(name, value);
}
- @SuppressWarnings("all")
+ @SuppressWarnings({"all", "MissingOverride"})
// @Override is omitted for backwards compatibility with servlet-api 2.5
// TODO: Remove @SuppressWarnings and add @Override when Google upgrades
// to servlet-api 3.1
diff --git a/java/com/google/gerrit/httpd/gitweb/GitwebServlet.java b/java/com/google/gerrit/httpd/gitweb/GitwebServlet.java
index 3bacd1c..b5d9f29 100644
--- a/java/com/google/gerrit/httpd/gitweb/GitwebServlet.java
+++ b/java/com/google/gerrit/httpd/gitweb/GitwebServlet.java
@@ -174,10 +174,8 @@
}
Path myconf = Files.createTempFile(site.tmp_dir, "gitweb_config", ".perl");
- // To make our configuration file only readable or writable by us;
- // this reduces the chances of someone tampering with the file.
- //
- // TODO(dborowitz): Is there a portable way to do this with NIO?
+ // To make our configuration file only readable or writable by us; this reduces the chances of
+ // someone tampering with the file.
File myconfFile = myconf.toFile();
myconfFile.setWritable(false, false /* all */);
myconfFile.setReadable(false, false /* all */);
diff --git a/java/com/google/gerrit/httpd/init/WebAppInitializer.java b/java/com/google/gerrit/httpd/init/WebAppInitializer.java
index 1fd28cc..b0b843f 100644
--- a/java/com/google/gerrit/httpd/init/WebAppInitializer.java
+++ b/java/com/google/gerrit/httpd/init/WebAppInitializer.java
@@ -37,6 +37,7 @@
import com.google.gerrit.httpd.plugins.HttpPluginModule;
import com.google.gerrit.httpd.raw.StaticModule;
import com.google.gerrit.lifecycle.LifecycleManager;
+import com.google.gerrit.lifecycle.LifecycleModule;
import com.google.gerrit.lucene.LuceneIndexModule;
import com.google.gerrit.metrics.dropwizard.DropWizardMetricMaker;
import com.google.gerrit.pgm.util.LogFileCompressor;
@@ -70,6 +71,7 @@
import com.google.gerrit.server.git.GarbageCollectionModule;
import com.google.gerrit.server.git.GitRepositoryManagerModule;
import com.google.gerrit.server.git.SearchingChangeCacheImpl;
+import com.google.gerrit.server.git.SystemReaderInstaller;
import com.google.gerrit.server.git.WorkQueue;
import com.google.gerrit.server.index.IndexModule;
import com.google.gerrit.server.index.IndexModule.IndexType;
@@ -179,7 +181,7 @@
}
try {
- dbInjector = createDbInjector();
+ cfgInjector = createCfgInjector();
} catch (CreationException ce) {
final Message first = ce.getErrorMessages().iterator().next();
final StringBuilder buf = new StringBuilder();
@@ -199,7 +201,7 @@
throw new CreationException(Collections.singleton(first));
}
- cfgInjector = createCfgInjector();
+ dbInjector = createDbInjector();
initIndexType();
config = cfgInjector.getInstance(Key.get(Config.class, GerritServerConfig.class));
sysInjector = createSysInjector();
@@ -244,36 +246,40 @@
return new SshAddressesModule().getListenAddresses(config).isEmpty();
}
- private Injector createDbInjector() {
+ private Injector createCfgInjector() {
final List<Module> modules = new ArrayList<>();
AbstractModule secureStore = createSecureStoreModule();
modules.add(secureStore);
- if (sitePath != null) {
- Module sitePathModule =
- new AbstractModule() {
- @Override
- protected void configure() {
- bind(Path.class).annotatedWith(SitePath.class).toInstance(sitePath);
- }
- };
- modules.add(sitePathModule);
+ Module sitePathModule =
+ new AbstractModule() {
+ @Override
+ protected void configure() {
+ bind(Path.class).annotatedWith(SitePath.class).toInstance(sitePath);
+ }
+ };
+ modules.add(sitePathModule);
- Module configModule = new GerritServerConfigModule();
- modules.add(configModule);
- } else {
- modules.add(new GerritServerConfigModule());
- }
+ Module configModule = new GerritServerConfigModule();
+ modules.add(configModule);
+ modules.add(
+ new LifecycleModule() {
+ @Override
+ protected void configure() {
+ listener().to(SystemReaderInstaller.class);
+ }
+ });
modules.add(new DropWizardMetricMaker.ApiModule());
- return Guice.createInjector(
- PRODUCTION, LibModuleLoader.loadModules(cfgInjector, LibModuleType.DB_MODULE));
+ return Guice.createInjector(PRODUCTION, modules);
}
- private Injector createCfgInjector() {
+ private Injector createDbInjector() {
final List<Module> modules = new ArrayList<>();
modules.add(new SchemaModule());
modules.add(NoteDbSchemaVersionCheck.module());
modules.add(new AuthConfigModule());
- return dbInjector.createChildInjector(modules);
+ return cfgInjector.createChildInjector(
+ ModuleOverloader.override(
+ modules, LibModuleLoader.loadModules(cfgInjector, LibModuleType.DB_MODULE)));
}
private Injector createSysInjector() {
@@ -337,19 +343,18 @@
modules.add(new ChangeCleanupRunner.Module());
modules.add(new AccountDeactivator.Module());
modules.add(new DefaultProjectNameLockManager.Module());
- return cfgInjector.createChildInjector(
+ return dbInjector.createChildInjector(
ModuleOverloader.override(
modules, LibModuleLoader.loadModules(cfgInjector, LibModuleType.SYS_MODULE)));
}
private Module createIndexModule() {
- switch (indexType) {
- case LUCENE:
- return LuceneIndexModule.latestVersion(false);
- case ELASTICSEARCH:
- return ElasticIndexModule.latestVersion(false);
- default:
- throw new IllegalStateException("unsupported index.type = " + indexType);
+ if (indexType.isLucene()) {
+ return LuceneIndexModule.latestVersion(false);
+ } else if (indexType.isElasticsearch()) {
+ return ElasticIndexModule.latestVersion(false);
+ } else {
+ throw new IllegalStateException("unsupported index.type = " + indexType);
}
}
diff --git a/java/com/google/gerrit/httpd/raw/CatServlet.java b/java/com/google/gerrit/httpd/raw/CatServlet.java
index 0accdb8..a4538cf 100644
--- a/java/com/google/gerrit/httpd/raw/CatServlet.java
+++ b/java/com/google/gerrit/httpd/raw/CatServlet.java
@@ -139,7 +139,7 @@
rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
- revision = patchSet.getCommitId().name();
+ revision = patchSet.commitId().name();
}
} catch (ResourceConflictException | NoSuchChangeException | AuthException e) {
rsp.sendError(HttpServletResponse.SC_NOT_FOUND);
diff --git a/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java
new file mode 100644
index 0000000..905c013
--- /dev/null
+++ b/java/com/google/gerrit/httpd/raw/IndexHtmlUtil.java
@@ -0,0 +1,135 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.httpd.raw;
+
+import static com.google.template.soy.data.ordainers.GsonOrdainer.serializeObject;
+
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.flogger.FluentLogger;
+import com.google.gerrit.common.Nullable;
+import com.google.gerrit.common.UsedAt;
+import com.google.gerrit.common.UsedAt.Project;
+import com.google.gerrit.extensions.api.GerritApi;
+import com.google.gerrit.extensions.api.accounts.AccountApi;
+import com.google.gerrit.extensions.api.config.Server;
+import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.extensions.restapi.RestApiException;
+import com.google.gerrit.json.OutputFormat;
+import com.google.gson.Gson;
+import com.google.template.soy.data.SanitizedContent;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Function;
+
+/** Helper for generating parts of {@code index.html}. */
+public class IndexHtmlUtil {
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+
+ /**
+ * Returns both static and dynamic parameters of {@code index.html}. The result is to be used when
+ * rendering the soy template.
+ */
+ public static ImmutableMap<String, Object> templateData(
+ GerritApi gerritApi,
+ String canonicalURL,
+ String cdnPath,
+ String faviconPath,
+ Function<String, SanitizedContent> urlInScriptTagOrdainer)
+ throws URISyntaxException, RestApiException {
+ return ImmutableMap.<String, Object>builder()
+ .putAll(staticTemplateData(canonicalURL, cdnPath, faviconPath, urlInScriptTagOrdainer))
+ .putAll(dynamicTemplateData(gerritApi))
+ .build();
+ }
+
+ /** Returns dynamic parameters of {@code index.html}. */
+ @UsedAt(Project.GOOGLE)
+ public static Map<String, Map<String, SanitizedContent>> dynamicTemplateData(GerritApi gerritApi)
+ throws RestApiException {
+ Gson gson = OutputFormat.JSON_COMPACT.newGson();
+ Map<String, SanitizedContent> initialData = new HashMap<>();
+ Server serverApi = gerritApi.config().server();
+ initialData.put("\"/config/server/info\"", serializeObject(gson, serverApi.getInfo()));
+ initialData.put("\"/config/server/version\"", serializeObject(gson, serverApi.getVersion()));
+ initialData.put("\"/config/server/top-menus\"", serializeObject(gson, serverApi.topMenus()));
+
+ try {
+ AccountApi accountApi = gerritApi.accounts().self();
+ initialData.put("\"/accounts/self/detail\"", serializeObject(gson, accountApi.get()));
+ initialData.put(
+ "\"/accounts/self/preferences\"", serializeObject(gson, accountApi.getPreferences()));
+ initialData.put(
+ "\"/accounts/self/preferences.diff\"",
+ serializeObject(gson, accountApi.getDiffPreferences()));
+ initialData.put(
+ "\"/accounts/self/preferences.edit\"",
+ serializeObject(gson, accountApi.getEditPreferences()));
+ } catch (AuthException e) {
+ logger.atFine().withCause(e).log(
+ "Can't inline account-related data because user is unauthenticated");
+ // Don't render data
+ // TODO(hiesel): Tell the client that the user is not authenticated so that it doesn't have to
+ // fetch anyway. This requires more client side modifications.
+ }
+ return ImmutableMap.of("gerritInitialData", initialData);
+ }
+
+ /** Returns all static parameters of {@code index.html}. */
+ static Map<String, Object> staticTemplateData(
+ String canonicalURL,
+ String cdnPath,
+ String faviconPath,
+ Function<String, SanitizedContent> urlInScriptTagOrdainer)
+ throws URISyntaxException {
+ String canonicalPath = computeCanonicalPath(canonicalURL);
+
+ String staticPath = "";
+ if (cdnPath != null) {
+ staticPath = cdnPath;
+ } else if (canonicalPath != null) {
+ staticPath = canonicalPath;
+ }
+
+ SanitizedContent sanitizedStaticPath = urlInScriptTagOrdainer.apply(staticPath);
+ ImmutableMap.Builder<String, Object> data = ImmutableMap.builder();
+ if (canonicalPath != null) {
+ data.put("canonicalPath", canonicalPath);
+ }
+ if (sanitizedStaticPath != null) {
+ data.put("staticResourcePath", sanitizedStaticPath);
+ }
+ if (faviconPath != null) {
+ data.put("faviconPath", faviconPath);
+ }
+ return data.build();
+ }
+
+ private static String computeCanonicalPath(@Nullable String canonicalURL)
+ throws URISyntaxException {
+ if (Strings.isNullOrEmpty(canonicalURL)) {
+ return "";
+ }
+
+ // If we serving from a sub-directory rather than root, determine the path
+ // from the cannonical web URL.
+ URI uri = new URI(canonicalURL);
+ return uri.getPath().replaceAll("/$", "");
+ }
+
+ private IndexHtmlUtil() {}
+}
diff --git a/java/com/google/gerrit/httpd/raw/IndexServlet.java b/java/com/google/gerrit/httpd/raw/IndexServlet.java
index a414e84..8299bfc 100644
--- a/java/com/google/gerrit/httpd/raw/IndexServlet.java
+++ b/java/com/google/gerrit/httpd/raw/IndexServlet.java
@@ -17,83 +17,73 @@
import static java.nio.charset.StandardCharsets.UTF_8;
import static javax.servlet.http.HttpServletResponse.SC_OK;
-import com.google.common.base.Strings;
import com.google.common.io.Resources;
import com.google.gerrit.common.Nullable;
+import com.google.gerrit.extensions.api.GerritApi;
+import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.template.soy.SoyFileSet;
import com.google.template.soy.data.SanitizedContent;
-import com.google.template.soy.data.SoyMapData;
import com.google.template.soy.data.UnsafeSanitizedContentOrdainer;
import com.google.template.soy.tofu.SoyTofu;
import java.io.IOException;
import java.io.OutputStream;
-import java.net.URI;
import java.net.URISyntaxException;
+import java.util.function.Function;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class IndexServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
- protected final byte[] indexSource;
+
+ @Nullable private final String canonicalUrl;
+ @Nullable private final String cdnPath;
+ @Nullable private final String faviconPath;
+ private final GerritApi gerritApi;
+ private final SoyTofu soyTofu;
+ private final Function<String, SanitizedContent> urlOrdainer;
IndexServlet(
- @Nullable String canonicalURL, @Nullable String cdnPath, @Nullable String faviconPath)
- throws URISyntaxException {
- String resourcePath = "com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy";
- SoyFileSet.Builder builder = SoyFileSet.builder();
- builder.add(Resources.getResource(resourcePath));
- SoyTofu.Renderer renderer =
- builder
+ @Nullable String canonicalUrl,
+ @Nullable String cdnPath,
+ @Nullable String faviconPath,
+ GerritApi gerritApi) {
+ this.canonicalUrl = canonicalUrl;
+ this.cdnPath = cdnPath;
+ this.faviconPath = faviconPath;
+ this.gerritApi = gerritApi;
+ this.soyTofu =
+ SoyFileSet.builder()
+ .add(Resources.getResource("com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy"))
.build()
- .compileToTofu()
- .newRenderer("com.google.gerrit.httpd.raw.Index")
- .setContentKind(SanitizedContent.ContentKind.HTML)
- .setData(getTemplateData(canonicalURL, cdnPath, faviconPath));
- indexSource = renderer.render().getBytes(UTF_8);
+ .compileToTofu();
+ this.urlOrdainer =
+ (s) ->
+ UnsafeSanitizedContentOrdainer.ordainAsSafe(
+ s, SanitizedContent.ContentKind.TRUSTED_RESOURCE_URI);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
+ SoyTofu.Renderer renderer;
+ try {
+ // TODO(hiesel): Remove URL ordainer as parameter once Soy is consistent
+ renderer =
+ soyTofu
+ .newRenderer("com.google.gerrit.httpd.raw.Index")
+ .setContentKind(SanitizedContent.ContentKind.HTML)
+ .setData(
+ IndexHtmlUtil.templateData(
+ gerritApi, canonicalUrl, cdnPath, faviconPath, urlOrdainer));
+ } catch (URISyntaxException | RestApiException e) {
+ throw new IOException(e);
+ }
+
rsp.setCharacterEncoding(UTF_8.name());
rsp.setContentType("text/html");
rsp.setStatus(SC_OK);
try (OutputStream w = rsp.getOutputStream()) {
- w.write(indexSource);
+ w.write(renderer.render().getBytes(UTF_8));
}
}
-
- static String computeCanonicalPath(@Nullable String canonicalURL) throws URISyntaxException {
- if (Strings.isNullOrEmpty(canonicalURL)) {
- return "";
- }
-
- // If we serving from a sub-directory rather than root, determine the path
- // from the cannonical web URL.
- URI uri = new URI(canonicalURL);
- return uri.getPath().replaceAll("/$", "");
- }
-
- static SoyMapData getTemplateData(String canonicalURL, String cdnPath, String faviconPath)
- throws URISyntaxException {
- String canonicalPath = computeCanonicalPath(canonicalURL);
-
- String staticPath = "";
- if (cdnPath != null) {
- staticPath = cdnPath;
- } else if (canonicalPath != null) {
- staticPath = canonicalPath;
- }
-
- // The resource path must be typed as safe for use in a script src.
- // TODO(wyatta): Upgrade this to use an appropriate safe URL type.
- SanitizedContent sanitizedStaticPath =
- UnsafeSanitizedContentOrdainer.ordainAsSafe(
- staticPath, SanitizedContent.ContentKind.TRUSTED_RESOURCE_URI);
-
- return new SoyMapData(
- "canonicalPath", canonicalPath,
- "staticResourcePath", sanitizedStaticPath,
- "faviconPath", faviconPath);
- }
}
diff --git a/java/com/google/gerrit/httpd/raw/StaticModule.java b/java/com/google/gerrit/httpd/raw/StaticModule.java
index e513620..2b11015 100644
--- a/java/com/google/gerrit/httpd/raw/StaticModule.java
+++ b/java/com/google/gerrit/httpd/raw/StaticModule.java
@@ -22,6 +22,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
+import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.httpd.XsrfCookieFilter;
import com.google.gerrit.httpd.raw.ResourceServlet.Resource;
import com.google.gerrit.launcher.GerritLauncher;
@@ -41,7 +42,6 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
-import java.net.URISyntaxException;
import java.nio.file.FileSystem;
import java.nio.file.Path;
import javax.servlet.Filter;
@@ -60,7 +60,6 @@
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
public static final String CACHE = "static_content";
- public static final String GERRIT_UI_COOKIE = "GERRIT_UI";
/**
* Paths at which we should serve the main PolyGerrit application {@code index.html}.
@@ -78,11 +77,6 @@
"/dashboard/*",
"/settings/*",
"/Documentation/q/*");
- // TODO(dborowitz): These fragments conflict with the REST API
- // namespace, so they will need to use a different path.
- // "/groups/*",
- // "/projects/*");
- //
/**
* Paths that should be treated as static assets when serving PolyGerrit.
@@ -224,11 +218,12 @@
@Singleton
@Named(POLYGERRIT_INDEX_SERVLET)
HttpServlet getPolyGerritUiIndexServlet(
- @CanonicalWebUrl @Nullable String canonicalUrl, @GerritServerConfig Config cfg)
- throws URISyntaxException {
+ @CanonicalWebUrl @Nullable String canonicalUrl,
+ @GerritServerConfig Config cfg,
+ GerritApi gerritApi) {
String cdnPath = cfg.getString("gerrit", null, "cdnPath");
String faviconPath = cfg.getString("gerrit", null, "faviconPath");
- return new IndexServlet(canonicalUrl, cdnPath, faviconPath);
+ return new IndexServlet(canonicalUrl, cdnPath, faviconPath, gerritApi);
}
@Provides
diff --git a/java/com/google/gerrit/httpd/restapi/RestApiServlet.java b/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
index d6dca48..33daf46 100644
--- a/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
+++ b/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
@@ -601,11 +601,13 @@
e.caching(),
e);
} catch (NotImplementedException e) {
+ logger.atSevere().withCause(e).log("Error in %s %s", req.getMethod(), uriForLogging(req));
responseBytes =
replyError(req, res, status = SC_NOT_IMPLEMENTED, messageOr(e, "Not Implemented"), e);
} catch (UpdateException e) {
Throwable t = e.getCause();
if (t instanceof LockFailureException) {
+ logger.atSevere().withCause(t).log("Error in %s %s", req.getMethod(), uriForLogging(req));
responseBytes =
replyError(
req, res, status = SC_SERVICE_UNAVAILABLE, messageOr(t, "Lock failure"), e);
@@ -1431,11 +1433,7 @@
private static long handleException(
Throwable err, HttpServletRequest req, HttpServletResponse res) throws IOException {
- String uri = req.getRequestURI();
- if (!Strings.isNullOrEmpty(req.getQueryString())) {
- uri += "?" + LogRedactUtil.redactQueryString(req.getQueryString());
- }
- logger.atSevere().withCause(err).log("Error in %s %s", req.getMethod(), uri);
+ logger.atSevere().withCause(err).log("Error in %s %s", req.getMethod(), uriForLogging(req));
if (!res.isCommitted()) {
res.reset();
return replyError(req, res, SC_INTERNAL_SERVER_ERROR, "Internal server error", err);
@@ -1443,6 +1441,14 @@
return 0;
}
+ private static String uriForLogging(HttpServletRequest req) {
+ String uri = req.getRequestURI();
+ if (!Strings.isNullOrEmpty(req.getQueryString())) {
+ uri += "?" + LogRedactUtil.redactQueryString(req.getQueryString());
+ }
+ return uri;
+ }
+
public static long replyError(
HttpServletRequest req,
HttpServletResponse res,
diff --git a/java/com/google/gerrit/index/Schema.java b/java/com/google/gerrit/index/Schema.java
index e633bfa..ed7ae30 100644
--- a/java/com/google/gerrit/index/Schema.java
+++ b/java/com/google/gerrit/index/Schema.java
@@ -17,7 +17,6 @@
import static com.google.common.base.Preconditions.checkState;
import com.google.common.base.MoreObjects;
-import com.google.common.base.Predicates;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -26,6 +25,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.Optional;
/** Specific version of a secondary index schema. */
@@ -191,7 +191,7 @@
return new Values<>(f, Collections.singleton(v));
}
})
- .filter(Predicates.notNull());
+ .filter(Objects::nonNull);
}
@Override
diff --git a/java/com/google/gerrit/index/query/AndSource.java b/java/com/google/gerrit/index/query/AndSource.java
index 7d817d2..538e11b 100644
--- a/java/com/google/gerrit/index/query/AndSource.java
+++ b/java/com/google/gerrit/index/query/AndSource.java
@@ -78,48 +78,55 @@
if (source == null) {
throw new StorageException("No DataSource: " + this);
}
- List<T> r = new ArrayList<>();
- T last = null;
- int nextStart = 0;
- boolean skipped = false;
- for (T data : buffer(source.read())) {
- if (!isMatchable() || match(data)) {
- r.add(data);
- } else {
- skipped = true;
- }
- last = data;
- nextStart++;
- }
- if (skipped && last != null && source instanceof Paginated) {
- // If our source is a paginated source and we skipped at
- // least one of its results, we may not have filled the full
- // limit the caller wants. Restart the source and continue.
- //
- @SuppressWarnings("unchecked")
- Paginated<T> p = (Paginated<T>) source;
- while (skipped && r.size() < p.getOptions().limit() + start) {
- skipped = false;
- ResultSet<T> next = p.restart(nextStart);
-
- for (T data : buffer(next)) {
- if (match(data)) {
- r.add(data);
- } else {
- skipped = true;
+ // ResultSets are lazy. Calling #read here first and then dealing with ResultSets only when
+ // requested allows the index to run asynchronous queries.
+ ResultSet<T> resultSet = source.read();
+ return new LazyResultSet<>(
+ () -> {
+ List<T> r = new ArrayList<>();
+ T last = null;
+ int nextStart = 0;
+ boolean skipped = false;
+ for (T data : buffer(resultSet)) {
+ if (!isMatchable() || match(data)) {
+ r.add(data);
+ } else {
+ skipped = true;
+ }
+ last = data;
+ nextStart++;
}
- nextStart++;
- }
- }
- }
- if (start >= r.size()) {
- r = ImmutableList.of();
- } else if (start > 0) {
- r = ImmutableList.copyOf(r.subList(start, r.size()));
- }
- return new ListResultSet<>(r);
+ if (skipped && last != null && source instanceof Paginated) {
+ // If our source is a paginated source and we skipped at
+ // least one of its results, we may not have filled the full
+ // limit the caller wants. Restart the source and continue.
+ //
+ @SuppressWarnings("unchecked")
+ Paginated<T> p = (Paginated<T>) source;
+ while (skipped && r.size() < p.getOptions().limit() + start) {
+ skipped = false;
+ ResultSet<T> next = p.restart(nextStart);
+
+ for (T data : buffer(next)) {
+ if (match(data)) {
+ r.add(data);
+ } else {
+ skipped = true;
+ }
+ nextStart++;
+ }
+ }
+ }
+
+ if (start >= r.size()) {
+ return ImmutableList.of();
+ } else if (start > 0) {
+ return ImmutableList.copyOf(r.subList(start, r.size()));
+ }
+ return ImmutableList.copyOf(r);
+ });
}
@Override
diff --git a/java/com/google/gerrit/index/query/LazyResultSet.java b/java/com/google/gerrit/index/query/LazyResultSet.java
new file mode 100644
index 0000000..f3fab5f
--- /dev/null
+++ b/java/com/google/gerrit/index/query/LazyResultSet.java
@@ -0,0 +1,56 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.index.query;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ImmutableList;
+import java.util.Iterator;
+import java.util.function.Supplier;
+
+/**
+ * Result set that allows for asynchronous execution of the actual query. Callers should dispatch
+ * the query and call the constructor of this class with a supplier that fetches the result and
+ * blocks on it if necessary.
+ *
+ * <p>If the execution is synchronous or the results are known a priori, consider using {@link
+ * ListResultSet}.
+ */
+public class LazyResultSet<T> implements ResultSet<T> {
+ private final Supplier<ImmutableList<T>> resultsCallback;
+
+ private boolean resultsReturned = false;
+
+ public LazyResultSet(Supplier<ImmutableList<T>> r) {
+ resultsCallback = requireNonNull(r, "results can't be null");
+ }
+
+ @Override
+ public Iterator<T> iterator() {
+ return toList().iterator();
+ }
+
+ @Override
+ public ImmutableList<T> toList() {
+ if (resultsReturned) {
+ throw new IllegalStateException("Results already obtained");
+ }
+ resultsReturned = true;
+ return resultsCallback.get();
+ }
+
+ @Override
+ public void close() {}
+}
diff --git a/java/com/google/gerrit/index/query/ListResultSet.java b/java/com/google/gerrit/index/query/ListResultSet.java
index 4cf48c8..9d7eadf 100644
--- a/java/com/google/gerrit/index/query/ListResultSet.java
+++ b/java/com/google/gerrit/index/query/ListResultSet.java
@@ -14,15 +14,25 @@
package com.google.gerrit.index.query;
+import static java.util.Objects.requireNonNull;
+
import com.google.common.collect.ImmutableList;
import java.util.Iterator;
import java.util.List;
+/**
+ * Result set for queries that run synchronously or for cases where the result is already known and
+ * we just need to pipe it back through our interfaces.
+ *
+ * <p>If your implementation benefits from asynchronous execution (i.e. dispatching a query and
+ * awaiting results only when {@link ResultSet#toList()} is called, consider using {@link
+ * LazyResultSet}.
+ */
public class ListResultSet<T> implements ResultSet<T> {
- private ImmutableList<T> items;
+ private ImmutableList<T> results;
public ListResultSet(List<T> r) {
- items = ImmutableList.copyOf(r);
+ results = ImmutableList.copyOf(requireNonNull(r, "results can't be null"));
}
@Override
@@ -32,16 +42,16 @@
@Override
public ImmutableList<T> toList() {
- if (items == null) {
+ if (results == null) {
throw new IllegalStateException("Results already obtained");
}
- ImmutableList<T> r = items;
- items = null;
+ ImmutableList<T> r = results;
+ results = null;
return r;
}
@Override
public void close() {
- items = null;
+ results = null;
}
}
diff --git a/java/com/google/gerrit/index/query/testing/TreeSubject.java b/java/com/google/gerrit/index/query/testing/TreeSubject.java
index c60b363..46c3895 100644
--- a/java/com/google/gerrit/index/query/testing/TreeSubject.java
+++ b/java/com/google/gerrit/index/query/testing/TreeSubject.java
@@ -28,38 +28,41 @@
return assertAbout(TreeSubject::new).that(actual);
}
+ private final Tree tree;
+
private TreeSubject(FailureMetadata failureMetadata, Tree tree) {
super(failureMetadata, tree);
+ this.tree = tree;
}
public void hasType(int expectedType) {
isNotNull();
- check("getType()").that(typeName(actual().getType())).isEqualTo(typeName(expectedType));
+ check("getType()").that(typeName(tree.getType())).isEqualTo(typeName(expectedType));
}
public void hasText(String expectedText) {
requireNonNull(expectedText);
isNotNull();
- check("getText()").that(actual().getText()).isEqualTo(expectedText);
+ check("getText()").that(tree.getText()).isEqualTo(expectedText);
}
public void hasNoChildren() {
isNotNull();
- check("getChildCount()").that(actual().getChildCount()).isEqualTo(0);
+ check("getChildCount()").that(tree.getChildCount()).isEqualTo(0);
}
public void hasChildCount(int expectedChildCount) {
checkArgument(
expectedChildCount > 0, "expected child count must be positive: %s", expectedChildCount);
isNotNull();
- check("getChildCount()").that(actual().getChildCount()).isEqualTo(expectedChildCount);
+ check("getChildCount()").that(tree.getChildCount()).isEqualTo(expectedChildCount);
}
public TreeSubject child(int childIndex) {
isNotNull();
return check("getChild(%s)", childIndex)
.about(TreeSubject::new)
- .that(actual().getChild(childIndex));
+ .that(tree.getChild(childIndex));
}
private static String typeName(int type) {
diff --git a/java/com/google/gerrit/launcher/BUILD b/java/com/google/gerrit/launcher/BUILD
index 918a83f..bac0c53 100644
--- a/java/com/google/gerrit/launcher/BUILD
+++ b/java/com/google/gerrit/launcher/BUILD
@@ -3,17 +3,5 @@
java_library(
name = "launcher",
srcs = ["GerritLauncher.java"],
- resources = [":workspace-root.txt"],
- visibility = ["//visibility:public"],
-)
-
-# The root of the workspace is non-hermetic, but we need it for
-# on-the-flyPolyGerrit updates.
-genrule(
- name = "gen_root",
- outs = ["workspace-root.txt"],
- cmd = ("cat bazel-out/stable-status.txt | " +
- "grep STABLE_WORKSPACE_ROOT | cut -d ' ' -f 2 > $@"),
- stamp = 1,
visibility = ["//visibility:public"],
)
diff --git a/java/com/google/gerrit/launcher/GerritLauncher.java b/java/com/google/gerrit/launcher/GerritLauncher.java
index dec077a..077c763a 100644
--- a/java/com/google/gerrit/launcher/GerritLauncher.java
+++ b/java/com/google/gerrit/launcher/GerritLauncher.java
@@ -46,7 +46,6 @@
import java.util.List;
import java.util.Map;
import java.util.Properties;
-import java.util.Scanner;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.jar.Attributes;
@@ -663,7 +662,6 @@
}
static final String SOURCE_ROOT_RESOURCE = "/com/google/gerrit/launcher/workspace-root.txt";
-
/**
* Locate a path in the source tree.
*
@@ -675,48 +673,40 @@
// Find ourselves in the classpath, as a loose class file or jar.
Class<GerritLauncher> self = GerritLauncher.class;
- // If the build system provides us with a source root, use that.
- try (InputStream stream = self.getResourceAsStream(SOURCE_ROOT_RESOURCE)) {
- if (stream != null) {
- try (Scanner scan = new Scanner(stream, UTF_8.name()).useDelimiter("\n")) {
- if (scan.hasNext()) {
- Path p = Paths.get(scan.next());
- if (!Files.exists(p)) {
- throw new FileNotFoundException("source root not found: " + p);
- }
- return p;
- }
+ Path dir;
+ String sourceRoot = System.getProperty("sourceRoot");
+ if (sourceRoot != null) {
+ dir = Paths.get(sourceRoot);
+ if (!Files.exists(dir)) {
+ throw new FileNotFoundException("source root not found: " + dir);
+ }
+ } else {
+ URL u = self.getResource(self.getSimpleName() + ".class");
+ if (u == null) {
+ throw new FileNotFoundException("Cannot find class " + self.getName());
+ } else if ("jar".equals(u.getProtocol())) {
+ String p = u.getPath();
+ try {
+ u = new URL(p.substring(0, p.indexOf('!')));
+ } catch (MalformedURLException e) {
+ FileNotFoundException fnfe = new FileNotFoundException("Not a valid jar file: " + u);
+ fnfe.initCause(e);
+ throw fnfe;
}
}
- } catch (IOException e) {
- // not Bazel, then.
- }
-
- URL u = self.getResource(self.getSimpleName() + ".class");
- if (u == null) {
- throw new FileNotFoundException("Cannot find class " + self.getName());
- } else if ("jar".equals(u.getProtocol())) {
- String p = u.getPath();
- try {
- u = new URL(p.substring(0, p.indexOf('!')));
- } catch (MalformedURLException e) {
- FileNotFoundException fnfe = new FileNotFoundException("Not a valid jar file: " + u);
- fnfe.initCause(e);
- throw fnfe;
+ if (!"file".equals(u.getProtocol())) {
+ throw new FileNotFoundException("Cannot extract path from " + u);
}
- }
- if (!"file".equals(u.getProtocol())) {
- throw new FileNotFoundException("Cannot extract path from " + u);
- }
- // Pop up to the top-level source folder by looking for .buckconfig.
- Path dir = Paths.get(u.getPath());
- while (!Files.isRegularFile(dir.resolve("WORKSPACE"))) {
- Path parent = dir.getParent();
- if (parent == null) {
- throw new FileNotFoundException("Cannot find source root from " + u);
+ // Pop up to the top-level source folder by looking for WORKSPACE.
+ dir = Paths.get(u.getPath());
+ while (!Files.isRegularFile(dir.resolve("WORKSPACE"))) {
+ Path parent = dir.getParent();
+ if (parent == null) {
+ throw new FileNotFoundException("Cannot find source root from " + u);
+ }
+ dir = parent;
}
- dir = parent;
}
Path ret = dir.resolve(name);
diff --git a/java/com/google/gerrit/lucene/LuceneChangeIndex.java b/java/com/google/gerrit/lucene/LuceneChangeIndex.java
index ef64d36..5ad5dfd 100644
--- a/java/com/google/gerrit/lucene/LuceneChangeIndex.java
+++ b/java/com/google/gerrit/lucene/LuceneChangeIndex.java
@@ -24,7 +24,6 @@
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toList;
-import com.google.common.base.Function;
import com.google.common.base.Throwables;
import com.google.common.collect.Collections2;
import com.google.common.collect.FluentIterable;
@@ -77,6 +76,7 @@
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.function.Consumer;
+import java.util.function.Function;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexableField;
@@ -259,10 +259,6 @@
new SortField(ID_SORT_FIELD, SortField.Type.LONG, true));
}
- public ChangeSubIndex getClosedChangesIndex() {
- return closedIndex;
- }
-
private class QuerySource implements ChangeDataSource {
private final List<ChangeSubIndex> indexes;
private final Predicate<ChangeData> predicate;
diff --git a/java/com/google/gerrit/lucene/WrappableSearcherManager.java b/java/com/google/gerrit/lucene/WrappableSearcherManager.java
index ba8d7da..4044b90 100644
--- a/java/com/google/gerrit/lucene/WrappableSearcherManager.java
+++ b/java/com/google/gerrit/lucene/WrappableSearcherManager.java
@@ -177,7 +177,7 @@
* Expert: creates a searcher from the provided {@link IndexReader} using the provided {@link
* SearcherFactory}. NOTE: this decRefs incoming reader on throwing an exception.
*/
- @SuppressWarnings("resource")
+ @SuppressWarnings({"resource", "ReferenceEquality"})
public static IndexSearcher getSearcher(SearcherFactory searcherFactory, IndexReader reader)
throws IOException {
boolean success = false;
diff --git a/java/com/google/gerrit/metrics/Field.java b/java/com/google/gerrit/metrics/Field.java
index 95eb9cf..b2acce7 100644
--- a/java/com/google/gerrit/metrics/Field.java
+++ b/java/com/google/gerrit/metrics/Field.java
@@ -16,8 +16,7 @@
import static com.google.common.base.Preconditions.checkArgument;
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
+import java.util.function.Function;
/**
* Describes a bucketing field used by a metric.
@@ -156,12 +155,11 @@
return formatter;
}
- @SuppressWarnings("unchecked")
private static <T> Function<T, String> initFormatter(Class<T> keyType) {
if (keyType == String.class) {
- return (Function<T, String>) Functions.<String>identity();
+ return s -> (String) s;
} else if (keyType == Integer.class || keyType == Boolean.class) {
- return (Function<T, String>) Functions.toStringFunction();
+ return Object::toString;
} else if (Enum.class.isAssignableFrom(keyType)) {
return in -> ((Enum<?>) in).name();
}
diff --git a/java/com/google/gerrit/metrics/dropwizard/CallbackMetricImpl1.java b/java/com/google/gerrit/metrics/dropwizard/CallbackMetricImpl1.java
index 6d1daf4..d718035 100644
--- a/java/com/google/gerrit/metrics/dropwizard/CallbackMetricImpl1.java
+++ b/java/com/google/gerrit/metrics/dropwizard/CallbackMetricImpl1.java
@@ -15,10 +15,10 @@
package com.google.gerrit.metrics.dropwizard;
import com.codahale.metrics.MetricRegistry;
-import com.google.common.base.Function;
import com.google.gerrit.metrics.CallbackMetric1;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Field;
+import java.util.function.Function;
/** Optimized version of {@link BucketedCallback} for single dimension. */
class CallbackMetricImpl1<F1, V> extends BucketedCallback<V> {
diff --git a/java/com/google/gerrit/metrics/dropwizard/CounterImpl1.java b/java/com/google/gerrit/metrics/dropwizard/CounterImpl1.java
index 46434ce..0e554a8 100644
--- a/java/com/google/gerrit/metrics/dropwizard/CounterImpl1.java
+++ b/java/com/google/gerrit/metrics/dropwizard/CounterImpl1.java
@@ -14,10 +14,10 @@
package com.google.gerrit.metrics.dropwizard;
-import com.google.common.base.Function;
import com.google.gerrit.metrics.Counter1;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Field;
+import java.util.function.Function;
/** Optimized version of {@link BucketedCounter} for single dimension. */
class CounterImpl1<F1> extends BucketedCounter {
diff --git a/java/com/google/gerrit/metrics/dropwizard/CounterImplN.java b/java/com/google/gerrit/metrics/dropwizard/CounterImplN.java
index 38c31a1..07afc2a 100644
--- a/java/com/google/gerrit/metrics/dropwizard/CounterImplN.java
+++ b/java/com/google/gerrit/metrics/dropwizard/CounterImplN.java
@@ -14,13 +14,13 @@
package com.google.gerrit.metrics.dropwizard;
-import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.metrics.Counter2;
import com.google.gerrit.metrics.Counter3;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Field;
+import java.util.function.Function;
/** Generalized implementation of N-dimensional counter metrics. */
class CounterImplN extends BucketedCounter implements BucketedMetric {
diff --git a/java/com/google/gerrit/metrics/dropwizard/HistogramImpl1.java b/java/com/google/gerrit/metrics/dropwizard/HistogramImpl1.java
index 3eb12fa..4578db1 100644
--- a/java/com/google/gerrit/metrics/dropwizard/HistogramImpl1.java
+++ b/java/com/google/gerrit/metrics/dropwizard/HistogramImpl1.java
@@ -14,10 +14,10 @@
package com.google.gerrit.metrics.dropwizard;
-import com.google.common.base.Function;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.Histogram1;
+import java.util.function.Function;
/** Optimized version of {@link BucketedHistogram} for single dimension. */
class HistogramImpl1<F1> extends BucketedHistogram implements BucketedMetric {
diff --git a/java/com/google/gerrit/metrics/dropwizard/HistogramImplN.java b/java/com/google/gerrit/metrics/dropwizard/HistogramImplN.java
index 3561c55a..446590c 100644
--- a/java/com/google/gerrit/metrics/dropwizard/HistogramImplN.java
+++ b/java/com/google/gerrit/metrics/dropwizard/HistogramImplN.java
@@ -14,13 +14,13 @@
package com.google.gerrit.metrics.dropwizard;
-import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.Histogram2;
import com.google.gerrit.metrics.Histogram3;
+import java.util.function.Function;
/** Generalized implementation of N-dimensional Histogram metrics. */
class HistogramImplN extends BucketedHistogram implements BucketedMetric {
diff --git a/java/com/google/gerrit/metrics/dropwizard/MetricJson.java b/java/com/google/gerrit/metrics/dropwizard/MetricJson.java
index 20f4fa3..c66e48d 100644
--- a/java/com/google/gerrit/metrics/dropwizard/MetricJson.java
+++ b/java/com/google/gerrit/metrics/dropwizard/MetricJson.java
@@ -21,7 +21,6 @@
import com.codahale.metrics.Metric;
import com.codahale.metrics.Snapshot;
import com.codahale.metrics.Timer;
-import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.metrics.Description;
@@ -30,6 +29,7 @@
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
+import java.util.function.Function;
class MetricJson {
String description;
diff --git a/java/com/google/gerrit/metrics/dropwizard/TimerImpl1.java b/java/com/google/gerrit/metrics/dropwizard/TimerImpl1.java
index d97e73a..cdf67bc 100644
--- a/java/com/google/gerrit/metrics/dropwizard/TimerImpl1.java
+++ b/java/com/google/gerrit/metrics/dropwizard/TimerImpl1.java
@@ -14,11 +14,11 @@
package com.google.gerrit.metrics.dropwizard;
-import com.google.common.base.Function;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.Timer1;
import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
/** Optimized version of {@link BucketedTimer} for single dimension. */
class TimerImpl1<F1> extends BucketedTimer implements BucketedMetric {
diff --git a/java/com/google/gerrit/metrics/dropwizard/TimerImplN.java b/java/com/google/gerrit/metrics/dropwizard/TimerImplN.java
index be66009..685e3e1 100644
--- a/java/com/google/gerrit/metrics/dropwizard/TimerImplN.java
+++ b/java/com/google/gerrit/metrics/dropwizard/TimerImplN.java
@@ -14,7 +14,6 @@
package com.google.gerrit.metrics.dropwizard;
-import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.metrics.Description;
@@ -22,6 +21,7 @@
import com.google.gerrit.metrics.Timer2;
import com.google.gerrit.metrics.Timer3;
import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
/** Generalized implementation of N-dimensional timer metrics. */
class TimerImplN extends BucketedTimer implements BucketedMetric {
diff --git a/java/com/google/gerrit/pgm/Daemon.java b/java/com/google/gerrit/pgm/Daemon.java
index 50005f2..ab570a2 100644
--- a/java/com/google/gerrit/pgm/Daemon.java
+++ b/java/com/google/gerrit/pgm/Daemon.java
@@ -485,24 +485,19 @@
if (luceneModule != null) {
return luceneModule;
}
- switch (indexType) {
- case LUCENE:
- return LuceneIndexModule.latestVersion(slave);
- case ELASTICSEARCH:
- return ElasticIndexModule.latestVersion(slave);
- default:
- throw new IllegalStateException("unsupported index.type = " + indexType);
+ if (indexType.isLucene()) {
+ return LuceneIndexModule.latestVersion(slave);
}
+ if (indexType.isElasticsearch()) {
+ return ElasticIndexModule.latestVersion(slave);
+ }
+ throw new IllegalStateException("unsupported index.type = " + indexType);
}
private void initIndexType() {
indexType = IndexModule.getIndexType(cfgInjector);
- switch (indexType) {
- case LUCENE:
- case ELASTICSEARCH:
- break;
- default:
- throw new IllegalStateException("unsupported index.type = " + indexType);
+ if (!indexType.isLucene() && !indexType.isElasticsearch()) {
+ throw new IllegalStateException("unsupported index.type = " + indexType);
}
}
diff --git a/java/com/google/gerrit/pgm/Reindex.java b/java/com/google/gerrit/pgm/Reindex.java
index 0e5f659..6d9fe59 100644
--- a/java/com/google/gerrit/pgm/Reindex.java
+++ b/java/com/google/gerrit/pgm/Reindex.java
@@ -147,16 +147,13 @@
boolean slave = globalConfig.getBoolean("container", "slave", false);
List<Module> modules = new ArrayList<>();
Module indexModule;
- switch (IndexModule.getIndexType(dbInjector)) {
- case LUCENE:
- indexModule = LuceneIndexModule.singleVersionWithExplicitVersions(versions, threads, slave);
- break;
- case ELASTICSEARCH:
- indexModule =
- ElasticIndexModule.singleVersionWithExplicitVersions(versions, threads, slave);
- break;
- default:
- throw new IllegalStateException("unsupported index.type");
+ IndexType indexType = IndexModule.getIndexType(dbInjector);
+ if (indexType.isLucene()) {
+ indexModule = LuceneIndexModule.singleVersionWithExplicitVersions(versions, threads, slave);
+ } else if (indexType.isElasticsearch()) {
+ indexModule = ElasticIndexModule.singleVersionWithExplicitVersions(versions, threads, slave);
+ } else {
+ throw new IllegalStateException("unsupported index.type = " + indexType);
}
modules.add(indexModule);
modules.add(new BatchProgramModule());
@@ -173,7 +170,7 @@
private void overrideConfig() {
// Disable auto-commit for speed; committing will happen at the end of the process.
- if (IndexModule.getIndexType(dbInjector) == IndexType.LUCENE) {
+ if (IndexModule.getIndexType(dbInjector).isLucene()) {
globalConfig.setLong("index", "changes_open", "commitWithin", -1);
globalConfig.setLong("index", "changes_closed", "commitWithin", -1);
}
diff --git a/java/com/google/gerrit/pgm/init/BaseInit.java b/java/com/google/gerrit/pgm/init/BaseInit.java
index 9c158b7..df6a375 100644
--- a/java/com/google/gerrit/pgm/init/BaseInit.java
+++ b/java/com/google/gerrit/pgm/init/BaseInit.java
@@ -38,6 +38,7 @@
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.index.IndexModule;
+import com.google.gerrit.server.index.IndexModule.IndexType;
import com.google.gerrit.server.plugins.JarScanner;
import com.google.gerrit.server.schema.NoteDbSchemaUpdater;
import com.google.gerrit.server.schema.UpdateUI;
@@ -404,15 +405,13 @@
}
});
Injector dbInjector = createDbInjector();
- switch (IndexModule.getIndexType(dbInjector)) {
- case LUCENE:
- modules.add(new LuceneIndexModuleOnInit());
- break;
- case ELASTICSEARCH:
- modules.add(new ElasticIndexModuleOnInit());
- break;
- default:
- throw new IllegalStateException("unsupported index.type");
+ IndexType indexType = IndexModule.getIndexType(dbInjector);
+ if (indexType.isLucene()) {
+ modules.add(new LuceneIndexModuleOnInit());
+ } else if (indexType.isElasticsearch()) {
+ modules.add(new ElasticIndexModuleOnInit());
+ } else {
+ throw new IllegalStateException("unsupported index.type = " + indexType);
}
sysInjector = dbInjector.createChildInjector(modules);
}
diff --git a/java/com/google/gerrit/pgm/init/InitIndex.java b/java/com/google/gerrit/pgm/init/InitIndex.java
index 0de08f2..5ede863 100644
--- a/java/com/google/gerrit/pgm/init/InitIndex.java
+++ b/java/com/google/gerrit/pgm/init/InitIndex.java
@@ -53,27 +53,23 @@
@Override
public void run() throws IOException {
- IndexType type = IndexType.LUCENE;
- if (IndexType.values().length > 1) {
- ui.header("Index");
- type = index.select("Type", "type", type);
- }
+ ui.header("Index");
+ IndexType type =
+ new IndexType(
+ index.select("Type", "type", IndexType.getDefault(), IndexType.getKnownTypes()));
- if (type == IndexType.ELASTICSEARCH) {
+ if (type.isElasticsearch()) {
Section elasticsearch = sections.get("elasticsearch", null);
elasticsearch.string("Index Prefix", "prefix", "gerrit_");
elasticsearch.string("Server", "server", "http://localhost:9200");
index.string("Result window size", "maxLimit", "10000");
}
- if ((site.isNew || isEmptySite()) && type == IndexType.LUCENE) {
+ if ((site.isNew || isEmptySite()) && type.isLucene()) {
for (SchemaDefinitions<?> def : IndexModule.ALL_SCHEMA_DEFS) {
IndexUtils.setReady(site, def.getName(), def.getLatest().getVersion(), true);
}
} else {
- if (IndexType.values().length <= 1) {
- ui.header("Index");
- }
String message =
String.format(
"\nThe index must be %sbuilt before starting Gerrit:\n"
diff --git a/java/com/google/gerrit/pgm/init/SitePathInitializer.java b/java/com/google/gerrit/pgm/init/SitePathInitializer.java
index 9d09461..846bb82 100644
--- a/java/com/google/gerrit/pgm/init/SitePathInitializer.java
+++ b/java/com/google/gerrit/pgm/init/SitePathInitializer.java
@@ -115,6 +115,8 @@
extractMailExample("CommentHtml.soy");
extractMailExample("CommentFooter.soy");
extractMailExample("CommentFooterHtml.soy");
+ extractMailExample("DeleteKey.soy");
+ extractMailExample("DeleteKeyHtml.soy");
extractMailExample("DeleteReviewer.soy");
extractMailExample("DeleteReviewerHtml.soy");
extractMailExample("DeleteVote.soy");
@@ -122,6 +124,8 @@
extractMailExample("Footer.soy");
extractMailExample("FooterHtml.soy");
extractMailExample("HeaderHtml.soy");
+ extractMailExample("HttpPasswordUpdate.soy");
+ extractMailExample("HttpPasswordUpdateHtml.soy");
extractMailExample("InboundEmailRejection.soy");
extractMailExample("InboundEmailRejectionHtml.soy");
extractMailExample("Merged.soy");
diff --git a/java/com/google/gerrit/pgm/init/api/Section.java b/java/com/google/gerrit/pgm/init/api/Section.java
index baf37b6..cbf32a1 100644
--- a/java/com/google/gerrit/pgm/init/api/Section.java
+++ b/java/com/google/gerrit/pgm/init/api/Section.java
@@ -127,8 +127,10 @@
public <T extends Enum<?>, E extends EnumSet<? extends T>> T select(
String title, String name, T defValue, boolean nullIfDefault) {
+ @SuppressWarnings("rawtypes")
+ Class<? extends Enum> declaringClass = defValue.getDeclaringClass();
@SuppressWarnings("unchecked")
- E allowedValues = (E) EnumSet.allOf(defValue.getClass());
+ E allowedValues = (E) EnumSet.allOf(declaringClass);
return select(title, name, defValue, allowedValues, nullIfDefault);
}
diff --git a/java/com/google/gerrit/pgm/util/SiteProgram.java b/java/com/google/gerrit/pgm/util/SiteProgram.java
index eed307f..98558fb 100644
--- a/java/com/google/gerrit/pgm/util/SiteProgram.java
+++ b/java/com/google/gerrit/pgm/util/SiteProgram.java
@@ -18,6 +18,7 @@
import static com.google.inject.Stage.PRODUCTION;
import com.google.gerrit.common.Die;
+import com.google.gerrit.lifecycle.LifecycleModule;
import com.google.gerrit.metrics.DisabledMetricMaker;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.metrics.dropwizard.DropWizardMetricMaker;
@@ -28,6 +29,7 @@
import com.google.gerrit.server.config.GerritServerConfigModule;
import com.google.gerrit.server.config.SitePath;
import com.google.gerrit.server.git.GitRepositoryManagerModule;
+import com.google.gerrit.server.git.SystemReaderInstaller;
import com.google.gerrit.server.schema.SchemaModule;
import com.google.gerrit.server.securestore.SecureStoreClassName;
import com.google.inject.AbstractModule;
@@ -106,6 +108,13 @@
});
}
+ modules.add(
+ new LifecycleModule() {
+ @Override
+ protected void configure() {
+ listener().to(SystemReaderInstaller.class);
+ }
+ });
Module configModule = new GerritServerConfigModule();
modules.add(configModule);
modules.add(
diff --git a/java/com/google/gerrit/proto/testing/SerializedClassSubject.java b/java/com/google/gerrit/proto/testing/SerializedClassSubject.java
index 09079fd..b078217 100644
--- a/java/com/google/gerrit/proto/testing/SerializedClassSubject.java
+++ b/java/com/google/gerrit/proto/testing/SerializedClassSubject.java
@@ -60,20 +60,23 @@
return assertAbout(factory).that(actual);
}
- private SerializedClassSubject(FailureMetadata metadata, Class<?> actual) {
- super(metadata, actual);
+ private final Class<?> clazz;
+
+ private SerializedClassSubject(FailureMetadata metadata, Class<?> clazz) {
+ super(metadata, clazz);
+ this.clazz = clazz;
}
public void isAbstract() {
isNotNull();
- if (!Modifier.isAbstract(actual().getModifiers())) {
+ if (!Modifier.isAbstract(clazz.getModifiers())) {
failWithActual(simpleFact("expected class to be abstract"));
}
}
public void isConcrete() {
isNotNull();
- if (Modifier.isAbstract(actual().getModifiers())) {
+ if (Modifier.isAbstract(clazz.getModifiers())) {
failWithActual(simpleFact("expected class to be concrete"));
}
}
@@ -82,7 +85,7 @@
isConcrete();
check("fields()")
.that(
- FieldUtils.getAllFieldsList(actual()).stream()
+ FieldUtils.getAllFieldsList(clazz).stream()
.filter(f -> !Modifier.isStatic(f.getModifiers()))
.collect(toImmutableMap(Field::getName, Field::getGenericType)))
.containsExactlyEntriesIn(expectedFields);
@@ -93,7 +96,7 @@
isAbstract();
check("noArgumentAbstractMethods()")
.that(
- Arrays.stream(actual().getDeclaredMethods())
+ Arrays.stream(clazz.getDeclaredMethods())
.filter(m -> !Modifier.isStatic(m.getModifiers()))
.filter(m -> Modifier.isAbstract(m.getModifiers()))
.filter(m -> m.getParameters().length == 0)
@@ -103,6 +106,6 @@
public void extendsClass(Type superclassType) {
isNotNull();
- check("getGenericSuperclass()").that(actual().getGenericSuperclass()).isEqualTo(superclassType);
+ check("getGenericSuperclass()").that(clazz.getGenericSuperclass()).isEqualTo(superclassType);
}
}
diff --git a/java/com/google/gerrit/reviewdb/BUILD b/java/com/google/gerrit/reviewdb/BUILD
index d241140..8c286ce 100644
--- a/java/com/google/gerrit/reviewdb/BUILD
+++ b/java/com/google/gerrit/reviewdb/BUILD
@@ -13,6 +13,7 @@
"//lib:protobuf",
"//lib/auto:auto-value",
"//lib/auto:auto-value-annotations",
+ "//lib/errorprone:annotations",
"//lib/jgit/org.eclipse.jgit:jgit",
"//proto:entities_java_proto",
],
diff --git a/java/com/google/gerrit/reviewdb/client/Account.java b/java/com/google/gerrit/reviewdb/client/Account.java
index 2642654..6366ce2 100644
--- a/java/com/google/gerrit/reviewdb/client/Account.java
+++ b/java/com/google/gerrit/reviewdb/client/Account.java
@@ -37,8 +37,6 @@
* <li>ExternalId: OpenID identities and email addresses known to be registered to this user.
* Multiple records can exist when the user has more than one public identity, such as a work
* and a personal email address.
- * <li>{@link AccountGroupMember}: membership of the user in a specific human managed {@link
- * AccountGroup}. Multiple records can exist when the user is a member of more than one group.
* <li>AccountSshKey: user's public SSH keys, for authentication through the internal SSH daemon.
* One record per SSH key uploaded by the user, keys are checked in random order until a match
* is found.
diff --git a/java/com/google/gerrit/reviewdb/client/AccountGroupById.java b/java/com/google/gerrit/reviewdb/client/AccountGroupById.java
deleted file mode 100644
index e073bc4..0000000
--- a/java/com/google/gerrit/reviewdb/client/AccountGroupById.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (C) 2011 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.reviewdb.client;
-
-import com.google.auto.value.AutoValue;
-import java.util.Objects;
-
-/** Membership of an {@link AccountGroup} in an {@link AccountGroup}. */
-public final class AccountGroupById {
- public static Key key(AccountGroup.Id groupId, AccountGroup.UUID includeUuid) {
- return new AutoValue_AccountGroupById_Key(groupId, includeUuid);
- }
-
- @AutoValue
- public abstract static class Key {
- public abstract AccountGroup.Id groupId();
-
- public abstract AccountGroup.UUID includeUuid();
- }
-
- protected Key key;
-
- protected AccountGroupById() {}
-
- public AccountGroupById(AccountGroupById.Key k) {
- key = k;
- }
-
- public AccountGroupById.Key getKey() {
- return key;
- }
-
- public AccountGroup.Id getGroupId() {
- return key.groupId();
- }
-
- public AccountGroup.UUID getIncludeUuid() {
- return key.includeUuid();
- }
-
- @Override
- public boolean equals(Object o) {
- return (o instanceof AccountGroupById) && Objects.equals(key, ((AccountGroupById) o).key);
- }
-
- @Override
- public int hashCode() {
- return key.hashCode();
- }
-
- @Override
- public String toString() {
- return getClass().getSimpleName() + "{key=" + key + "}";
- }
-}
diff --git a/java/com/google/gerrit/reviewdb/client/AccountGroupByIdAud.java b/java/com/google/gerrit/reviewdb/client/AccountGroupByIdAud.java
deleted file mode 100644
index 8eb62ae..0000000
--- a/java/com/google/gerrit/reviewdb/client/AccountGroupByIdAud.java
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (C) 2011 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.reviewdb.client;
-
-import com.google.auto.value.AutoValue;
-import com.google.gerrit.common.Nullable;
-import java.sql.Timestamp;
-import java.util.Objects;
-
-/** Inclusion of an {@link AccountGroup} in another {@link AccountGroup}. */
-public final class AccountGroupByIdAud {
- public static Key key(AccountGroup.Id groupId, AccountGroup.UUID includeUuid, Timestamp addedOn) {
- return new AutoValue_AccountGroupByIdAud_Key(groupId, includeUuid, addedOn);
- }
-
- @AutoValue
- public abstract static class Key {
- public abstract AccountGroup.Id groupId();
-
- public abstract AccountGroup.UUID includeUuid();
-
- public abstract Timestamp addedOn();
- }
-
- protected Key key;
-
- protected Account.Id addedBy;
-
- @Nullable protected Account.Id removedBy;
-
- @Nullable protected Timestamp removedOn;
-
- protected AccountGroupByIdAud() {}
-
- public AccountGroupByIdAud(final AccountGroupById m, Account.Id adder, Timestamp when) {
- final AccountGroup.Id group = m.getGroupId();
- final AccountGroup.UUID include = m.getIncludeUuid();
- key = key(group, include, when);
- addedBy = adder;
- }
-
- public AccountGroupByIdAud(AccountGroupByIdAud.Key key, Account.Id adder) {
- this.key = key;
- addedBy = adder;
- }
-
- public AccountGroupByIdAud.Key getKey() {
- return key;
- }
-
- public AccountGroup.Id getGroupId() {
- return key.groupId();
- }
-
- public AccountGroup.UUID getIncludeUUID() {
- return key.includeUuid();
- }
-
- public boolean isActive() {
- return removedOn == null;
- }
-
- public void removed(Account.Id deleter, Timestamp when) {
- removedBy = deleter;
- removedOn = when;
- }
-
- public Account.Id getAddedBy() {
- return addedBy;
- }
-
- public Timestamp getAddedOn() {
- return key.addedOn();
- }
-
- public Account.Id getRemovedBy() {
- return removedBy;
- }
-
- public Timestamp getRemovedOn() {
- return removedOn;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof AccountGroupByIdAud)) {
- return false;
- }
- AccountGroupByIdAud a = (AccountGroupByIdAud) o;
- return Objects.equals(key, a.key)
- && Objects.equals(addedBy, a.addedBy)
- && Objects.equals(removedBy, a.removedBy)
- && Objects.equals(removedOn, a.removedOn);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(key, addedBy, removedBy, removedOn);
- }
-
- @Override
- public String toString() {
- return getClass().getSimpleName()
- + "{"
- + "key="
- + key
- + ", addedBy="
- + addedBy
- + ", removedBy="
- + removedBy
- + ", removedOn="
- + removedOn
- + "}";
- }
-}
diff --git a/java/com/google/gerrit/reviewdb/client/AccountGroupByIdAudit.java b/java/com/google/gerrit/reviewdb/client/AccountGroupByIdAudit.java
new file mode 100644
index 0000000..e421d63
--- /dev/null
+++ b/java/com/google/gerrit/reviewdb/client/AccountGroupByIdAudit.java
@@ -0,0 +1,66 @@
+// Copyright (C) 2011 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.reviewdb.client;
+
+import com.google.auto.value.AutoValue;
+import java.sql.Timestamp;
+import java.util.Optional;
+
+/** Inclusion of an {@link AccountGroup} in another {@link AccountGroup}. */
+@AutoValue
+public abstract class AccountGroupByIdAudit {
+ public static Builder builder() {
+ return new AutoValue_AccountGroupByIdAudit.Builder();
+ }
+
+ @AutoValue.Builder
+ public abstract static class Builder {
+ public abstract Builder groupId(AccountGroup.Id groupId);
+
+ public abstract Builder includeUuid(AccountGroup.UUID includeUuid);
+
+ public abstract Builder addedBy(Account.Id addedBy);
+
+ public abstract Builder addedOn(Timestamp addedOn);
+
+ abstract Builder removedBy(Account.Id removedBy);
+
+ abstract Builder removedOn(Timestamp removedOn);
+
+ public Builder removed(Account.Id removedBy, Timestamp removedOn) {
+ return removedBy(removedBy).removedOn(removedOn);
+ }
+
+ public abstract AccountGroupByIdAudit build();
+ }
+
+ public abstract AccountGroup.Id groupId();
+
+ public abstract AccountGroup.UUID includeUuid();
+
+ public abstract Account.Id addedBy();
+
+ public abstract Timestamp addedOn();
+
+ public abstract Optional<Account.Id> removedBy();
+
+ public abstract Optional<Timestamp> removedOn();
+
+ public abstract Builder toBuilder();
+
+ public boolean isActive() {
+ return !removedOn().isPresent();
+ }
+}
diff --git a/java/com/google/gerrit/reviewdb/client/AccountGroupMember.java b/java/com/google/gerrit/reviewdb/client/AccountGroupMember.java
deleted file mode 100644
index 51da8a4..0000000
--- a/java/com/google/gerrit/reviewdb/client/AccountGroupMember.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (C) 2008 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.reviewdb.client;
-
-import com.google.auto.value.AutoValue;
-import java.util.Objects;
-
-/** Membership of an {@link Account} in an {@link AccountGroup}. */
-public final class AccountGroupMember {
- public static Key key(Account.Id accountId, AccountGroup.Id groupId) {
- return new AutoValue_AccountGroupMember_Key(accountId, groupId);
- }
-
- @AutoValue
- public abstract static class Key {
- public abstract Account.Id accountId();
-
- public abstract AccountGroup.Id groupId();
- }
-
- protected Key key;
-
- protected AccountGroupMember() {}
-
- public AccountGroupMember(AccountGroupMember.Key k) {
- key = k;
- }
-
- public AccountGroupMember.Key getKey() {
- return key;
- }
-
- public Account.Id getAccountId() {
- return key.accountId();
- }
-
- public AccountGroup.Id getAccountGroupId() {
- return key.groupId();
- }
-
- @Override
- public boolean equals(Object o) {
- return (o instanceof AccountGroupMember) && Objects.equals(key, ((AccountGroupMember) o).key);
- }
-
- @Override
- public int hashCode() {
- return key.hashCode();
- }
-
- @Override
- public String toString() {
- return getClass().getSimpleName() + "{key=" + key + "}";
- }
-}
diff --git a/java/com/google/gerrit/reviewdb/client/AccountGroupMemberAudit.java b/java/com/google/gerrit/reviewdb/client/AccountGroupMemberAudit.java
index 35ceeee..37b57ee 100644
--- a/java/com/google/gerrit/reviewdb/client/AccountGroupMemberAudit.java
+++ b/java/com/google/gerrit/reviewdb/client/AccountGroupMemberAudit.java
@@ -15,118 +15,60 @@
package com.google.gerrit.reviewdb.client;
import com.google.auto.value.AutoValue;
-import com.google.gerrit.common.Nullable;
import java.sql.Timestamp;
-import java.util.Objects;
+import java.util.Optional;
/** Membership of an {@link Account} in an {@link AccountGroup}. */
-public final class AccountGroupMemberAudit {
- public static Key key(Account.Id accountId, AccountGroup.Id groupId, Timestamp addedOn) {
- return new AutoValue_AccountGroupMemberAudit_Key(accountId, groupId, addedOn);
+@AutoValue
+public abstract class AccountGroupMemberAudit {
+ public static Builder builder() {
+ return new AutoValue_AccountGroupMemberAudit.Builder();
}
- @AutoValue
- public abstract static class Key {
- public abstract Account.Id accountId();
+ @AutoValue.Builder
+ public abstract static class Builder {
+ public abstract Builder groupId(AccountGroup.Id groupId);
- public abstract AccountGroup.Id groupId();
+ public abstract Builder memberId(Account.Id accountId);
- public abstract Timestamp addedOn();
+ public abstract Builder addedBy(Account.Id addedBy);
+
+ abstract Account.Id addedBy();
+
+ public abstract Builder addedOn(Timestamp addedOn);
+
+ abstract Timestamp addedOn();
+
+ abstract Builder removedBy(Account.Id removedBy);
+
+ abstract Builder removedOn(Timestamp removedOn);
+
+ public Builder removed(Account.Id removedBy, Timestamp removedOn) {
+ return removedBy(removedBy).removedOn(removedOn);
+ }
+
+ public Builder removedLegacy() {
+ return removed(addedBy(), addedOn());
+ }
+
+ public abstract AccountGroupMemberAudit build();
}
- protected Key key;
+ public abstract AccountGroup.Id groupId();
- protected Account.Id addedBy;
+ public abstract Account.Id memberId();
- @Nullable protected Account.Id removedBy;
+ public abstract Account.Id addedBy();
- @Nullable protected Timestamp removedOn;
+ public abstract Timestamp addedOn();
- protected AccountGroupMemberAudit() {}
+ public abstract Optional<Account.Id> removedBy();
- public AccountGroupMemberAudit(final AccountGroupMember m, Account.Id adder, Timestamp addedOn) {
- final Account.Id who = m.getAccountId();
- final AccountGroup.Id group = m.getAccountGroupId();
- key = key(who, group, addedOn);
- addedBy = adder;
- }
+ public abstract Optional<Timestamp> removedOn();
- public AccountGroupMemberAudit(AccountGroupMemberAudit.Key key, Account.Id adder) {
- this.key = key;
- addedBy = adder;
- }
-
- public AccountGroupMemberAudit.Key getKey() {
- return key;
- }
-
- public AccountGroup.Id getGroupId() {
- return key.groupId();
- }
-
- public Account.Id getMemberId() {
- return key.accountId();
- }
+ public abstract Builder toBuilder();
public boolean isActive() {
- return removedOn == null;
- }
-
- public void removed(Account.Id deleter, Timestamp when) {
- removedBy = deleter;
- removedOn = when;
- }
-
- public void removedLegacy() {
- removedBy = addedBy;
- removedOn = key.addedOn();
- }
-
- public Account.Id getAddedBy() {
- return addedBy;
- }
-
- public Timestamp getAddedOn() {
- return key.addedOn();
- }
-
- public Account.Id getRemovedBy() {
- return removedBy;
- }
-
- public Timestamp getRemovedOn() {
- return removedOn;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof AccountGroupMemberAudit)) {
- return false;
- }
- AccountGroupMemberAudit a = (AccountGroupMemberAudit) o;
- return Objects.equals(key, a.key)
- && Objects.equals(addedBy, a.addedBy)
- && Objects.equals(removedBy, a.removedBy)
- && Objects.equals(removedOn, a.removedOn);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(key, addedBy, removedBy, removedOn);
- }
-
- @Override
- public String toString() {
- return getClass().getSimpleName()
- + "{"
- + "key="
- + key
- + ", addedBy="
- + addedBy
- + ", removedBy="
- + removedBy
- + ", removedOn="
- + removedOn
- + "}";
+ return !removedOn().isPresent();
}
}
diff --git a/java/com/google/gerrit/reviewdb/client/PatchSet.java b/java/com/google/gerrit/reviewdb/client/PatchSet.java
index 9192acc..7c0af0f 100644
--- a/java/com/google/gerrit/reviewdb/client/PatchSet.java
+++ b/java/com/google/gerrit/reviewdb/client/PatchSet.java
@@ -15,21 +15,22 @@
package com.google.gerrit.reviewdb.client;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.ImmutableList.toImmutableList;
import static java.util.Objects.requireNonNull;
import com.google.auto.value.AutoValue;
import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Streams;
import com.google.common.primitives.Ints;
-import com.google.gerrit.common.Nullable;
import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
-import java.util.Objects;
+import java.util.Optional;
import org.eclipse.jgit.lib.ObjectId;
/** A single revision of a {@link Change}. */
-public final class PatchSet {
+@AutoValue
+public abstract class PatchSet {
/** Is the reference name a change reference? */
public static boolean isChangeRef(String name) {
return Id.fromRef(name) != null;
@@ -46,38 +47,15 @@
}
public static String joinGroups(List<String> groups) {
- if (groups == null) {
- throw new IllegalArgumentException("groups may not be null");
+ requireNonNull(groups);
+ for (String group : groups) {
+ checkArgument(!group.contains(","), "group may not contain ',': %s", group);
}
- StringBuilder sb = new StringBuilder();
- boolean first = true;
- for (String g : groups) {
- if (!first) {
- sb.append(',');
- } else {
- first = false;
- }
- sb.append(g);
- }
- return sb.toString();
+ return String.join(",", groups);
}
- public static List<String> splitGroups(String joinedGroups) {
- if (joinedGroups == null) {
- throw new IllegalArgumentException("groups may not be null");
- }
- List<String> groups = new ArrayList<>();
- int i = 0;
- while (true) {
- int idx = joinedGroups.indexOf(',', i);
- if (idx < 0) {
- groups.add(joinedGroups.substring(i));
- break;
- }
- groups.add(joinedGroups.substring(i, idx));
- i = idx + 1;
- }
- return groups;
+ public static ImmutableList<String> splitGroups(String joinedGroups) {
+ return Streams.stream(Splitter.on(',').split(joinedGroups)).collect(toImmutableList());
}
public static Id id(Change.Id changeId, int id) {
@@ -101,7 +79,7 @@
checkArgument(test, "invalid patch set ID: %s", input);
}
- /** Parse a PatchSet.Id from a {@link PatchSet#getRefName()} result. */
+ /** Parse a PatchSet.Id from a {@link #refName()} result. */
public static Id fromRef(String ref) {
int cs = Change.Id.startIndex(ref);
if (cs < 0) {
@@ -156,14 +134,70 @@
}
}
- protected Id id;
+ public static Builder builder() {
+ return new AutoValue_PatchSet.Builder().groups(ImmutableList.of());
+ }
- protected ObjectId commitId;
+ @AutoValue.Builder
+ public abstract static class Builder {
+ public abstract Builder id(Id id);
- protected Account.Id uploader;
+ public abstract Id id();
- /** When this patch set was first introduced onto the change. */
- protected Timestamp createdOn;
+ public abstract Builder commitId(ObjectId commitId);
+
+ public abstract Optional<ObjectId> commitId();
+
+ public abstract Builder uploader(Account.Id uploader);
+
+ public abstract Builder createdOn(Timestamp createdOn);
+
+ public abstract Builder groups(Iterable<String> groups);
+
+ public abstract ImmutableList<String> groups();
+
+ public abstract Builder pushCertificate(Optional<String> pushCertificate);
+
+ public abstract Builder pushCertificate(String pushCertificate);
+
+ public abstract Builder description(Optional<String> description);
+
+ public abstract Builder description(String description);
+
+ public abstract Optional<String> description();
+
+ public abstract PatchSet build();
+ }
+
+ /** ID of the patch set. */
+ public abstract Id id();
+
+ /**
+ * Commit ID of the patch set, also known as the revision.
+ *
+ * <p>If this is a deserialized instance that was originally serialized by an older version of
+ * Gerrit, and the old data erroneously did not include a {@code commitId}, then this method will
+ * return {@link ObjectId#zeroId()}.
+ */
+ public abstract ObjectId commitId();
+
+ /**
+ * Account that uploaded the patch set.
+ *
+ * <p>If this is a deserialized instance that was originally serialized by an older version of
+ * Gerrit, and the old data erroneously did not include an {@code uploader}, then this method will
+ * return an account ID of 0.
+ */
+ public abstract Account.Id uploader();
+
+ /**
+ * When this patch set was first introduced onto the change.
+ *
+ * <p>If this is a deserialized instance that was originally serialized by an older version of
+ * Gerrit, and the old data erroneously did not include a {@code createdOn}, then this method will
+ * return a timestamp of 0.
+ */
+ public abstract Timestamp createdOn();
/**
* Opaque group identifier, usually assigned during creation.
@@ -174,127 +208,26 @@
* <p>Changes on the same branch having patch sets with intersecting groups are considered
* related, as in the "Related Changes" tab.
*/
- @Nullable protected String groups;
-
- // DELETED id = 7 (pushCertficate)
+ public abstract ImmutableList<String> groups();
/** Certificate sent with a push that created this patch set. */
- @Nullable protected String pushCertificate;
+ public abstract Optional<String> pushCertificate();
/**
* Optional user-supplied description for this patch set.
*
- * <p>When this field is null, the description was never set on the patch set. When this field is
- * an empty string, the description was set and later cleared.
+ * <p>When this field is an empty {@code Optional}, the description was never set on the patch
+ * set. When this field is present but an empty string, the description was set and later cleared.
*/
- @Nullable protected String description;
+ public abstract Optional<String> description();
- public PatchSet(PatchSet.Id id, ObjectId commitId) {
- this.id = requireNonNull(id);
- this.commitId = commitId.copy();
+ /** Patch set number. */
+ public int number() {
+ return id().get();
}
- public PatchSet(PatchSet src) {
- this.id = src.id;
- this.commitId = src.commitId;
- this.uploader = src.uploader;
- this.createdOn = src.createdOn;
- this.groups = src.groups;
- this.pushCertificate = src.pushCertificate;
- this.description = src.description;
- }
-
- public PatchSet.Id getId() {
- return id;
- }
-
- public int getPatchSetId() {
- return id.get();
- }
-
- /**
- * Get the ID of the commit associated with this patch set.
- *
- * <p>The commit associated with a patch set is also known as the <strong>revision</strong>.
- *
- * @return the commit ID, never null.
- */
- public ObjectId getCommitId() {
- return commitId;
- }
-
- public Account.Id getUploader() {
- return uploader;
- }
-
- public void setUploader(Account.Id who) {
- uploader = who;
- }
-
- public Timestamp getCreatedOn() {
- return createdOn;
- }
-
- public void setCreatedOn(Timestamp ts) {
- createdOn = ts;
- }
-
- public List<String> getGroups() {
- if (groups == null) {
- return Collections.emptyList();
- }
- return splitGroups(groups);
- }
-
- public void setGroups(List<String> groups) {
- if (groups == null) {
- groups = Collections.emptyList();
- }
- this.groups = joinGroups(groups);
- }
-
- public String getRefName() {
- return id.toRefName();
- }
-
- public String getPushCertificate() {
- return pushCertificate;
- }
-
- public void setPushCertificate(String cert) {
- pushCertificate = cert;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof PatchSet)) {
- return false;
- }
- PatchSet p = (PatchSet) o;
- return Objects.equals(id, p.id)
- && Objects.equals(commitId, p.commitId)
- && Objects.equals(uploader, p.uploader)
- && Objects.equals(createdOn, p.createdOn)
- && Objects.equals(groups, p.groups)
- && Objects.equals(pushCertificate, p.pushCertificate)
- && Objects.equals(description, p.description);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(id, commitId, uploader, createdOn, groups, pushCertificate, description);
- }
-
- @Override
- public String toString() {
- return "[PatchSet " + getId().toString() + "]";
+ /** Name of the corresponding patch set ref. */
+ public String refName() {
+ return id().toRefName();
}
}
diff --git a/java/com/google/gerrit/reviewdb/client/PatchSetApproval.java b/java/com/google/gerrit/reviewdb/client/PatchSetApproval.java
index cef2c04..c5c8166 100644
--- a/java/com/google/gerrit/reviewdb/client/PatchSetApproval.java
+++ b/java/com/google/gerrit/reviewdb/client/PatchSetApproval.java
@@ -15,13 +15,14 @@
package com.google.gerrit.reviewdb.client;
import com.google.auto.value.AutoValue;
-import com.google.gerrit.common.Nullable;
+import com.google.common.primitives.Shorts;
import java.sql.Timestamp;
import java.util.Date;
-import java.util.Objects;
+import java.util.Optional;
/** An approval (or negative approval) on a patch set. */
-public final class PatchSetApproval {
+@AutoValue
+public abstract class PatchSetApproval {
public static Key key(PatchSet.Id patchSetId, Account.Id accountId, LabelId labelId) {
return new AutoValue_PatchSetApproval_Key(patchSetId, accountId, labelId);
}
@@ -33,9 +34,55 @@
public abstract Account.Id accountId();
public abstract LabelId labelId();
+
+ public boolean isLegacySubmit() {
+ return LabelId.LEGACY_SUBMIT_NAME.equals(labelId().get());
+ }
}
- protected Key key;
+ public static Builder builder() {
+ return new AutoValue_PatchSetApproval.Builder().postSubmit(false);
+ }
+
+ @AutoValue.Builder
+ public abstract static class Builder {
+ public abstract Builder key(Key key);
+
+ public abstract Key key();
+
+ public abstract Builder value(short value);
+
+ public Builder value(int value) {
+ return value(Shorts.checkedCast(value));
+ }
+
+ public abstract Builder granted(Timestamp granted);
+
+ public Builder granted(Date granted) {
+ return granted(new Timestamp(granted.getTime()));
+ }
+
+ public abstract Builder tag(String tag);
+
+ public abstract Builder tag(Optional<String> tag);
+
+ public abstract Builder realAccountId(Account.Id realAccountId);
+
+ abstract Optional<Account.Id> realAccountId();
+
+ public abstract Builder postSubmit(boolean isPostSubmit);
+
+ abstract PatchSetApproval autoBuild();
+
+ public PatchSetApproval build() {
+ if (!realAccountId().isPresent()) {
+ realAccountId(key().accountId());
+ }
+ return autoBuild();
+ }
+ }
+
+ public abstract Key key();
/**
* Value assigned by the user.
@@ -53,143 +100,40 @@
* and in the negative and positive direction a magnitude can be assumed.The further from 0 the
* more assertive the approval.
*/
- protected short value;
+ public abstract short value();
- protected Timestamp granted;
+ public abstract Timestamp granted();
- @Nullable protected String tag;
+ public abstract Optional<String> tag();
/** Real user that made this approval on behalf of the user recorded in {@link Key#accountId}. */
- @Nullable protected Account.Id realAccountId;
+ public abstract Account.Id realAccountId();
- protected boolean postSubmit;
+ public abstract boolean postSubmit();
- // DELETED: id = 4 (changeOpen)
- // DELETED: id = 5 (changeSortKey)
+ public abstract Builder toBuilder();
- protected PatchSetApproval() {}
-
- public PatchSetApproval(PatchSetApproval.Key k, short v, Date ts) {
- key = k;
- setValue(v);
- setGranted(ts);
+ public PatchSetApproval copyWithPatchSet(PatchSet.Id psId) {
+ return toBuilder().key(key(psId, key().accountId(), key().labelId())).build();
}
- public PatchSetApproval(PatchSet.Id psId, PatchSetApproval src) {
- key = key(psId, src.getAccountId(), src.getLabelId());
- value = src.getValue();
- granted = src.granted;
- realAccountId = src.realAccountId;
- tag = src.tag;
- postSubmit = src.postSubmit;
+ public PatchSet.Id patchSetId() {
+ return key().patchSetId();
}
- public PatchSetApproval(PatchSetApproval src) {
- this(src.getPatchSetId(), src);
+ public Account.Id accountId() {
+ return key().accountId();
}
- public PatchSetApproval.Key getKey() {
- return key;
+ public LabelId labelId() {
+ return key().labelId();
}
- public PatchSet.Id getPatchSetId() {
- return key.patchSetId();
- }
-
- public Account.Id getAccountId() {
- return key.accountId();
- }
-
- public Account.Id getRealAccountId() {
- return realAccountId != null ? realAccountId : getAccountId();
- }
-
- public void setRealAccountId(Account.Id id) {
- // Use null for same real author, as before the column was added.
- realAccountId = Objects.equals(getAccountId(), id) ? null : id;
- }
-
- public LabelId getLabelId() {
- return key.labelId();
- }
-
- public short getValue() {
- return value;
- }
-
- public void setValue(short v) {
- value = v;
- }
-
- public Timestamp getGranted() {
- return granted;
- }
-
- public void setGranted(Date when) {
- if (when instanceof Timestamp) {
- granted = (Timestamp) when;
- } else {
- granted = new Timestamp(when.getTime());
- }
- }
-
- public void setTag(String t) {
- tag = t;
- }
-
- public String getLabel() {
- return getLabelId().get();
+ public String label() {
+ return labelId().get();
}
public boolean isLegacySubmit() {
- return LabelId.LEGACY_SUBMIT_NAME.equals(getLabel());
- }
-
- public String getTag() {
- return tag;
- }
-
- public void setPostSubmit(boolean postSubmit) {
- this.postSubmit = postSubmit;
- }
-
- public boolean isPostSubmit() {
- return postSubmit;
- }
-
- @Override
- public String toString() {
- StringBuilder sb =
- new StringBuilder("[")
- .append(key)
- .append(": ")
- .append(value)
- .append(",tag:")
- .append(tag)
- .append(",realAccountId:")
- .append(realAccountId);
- if (postSubmit) {
- sb.append(",postSubmit");
- }
- return sb.append(']').toString();
- }
-
- @Override
- public boolean equals(Object o) {
- if (o instanceof PatchSetApproval) {
- PatchSetApproval p = (PatchSetApproval) o;
- return Objects.equals(key, p.key)
- && Objects.equals(value, p.value)
- && Objects.equals(granted, p.granted)
- && Objects.equals(tag, p.tag)
- && Objects.equals(realAccountId, p.realAccountId)
- && postSubmit == p.postSubmit;
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(key, value, granted, tag, realAccountId, postSubmit);
+ return key().isLegacySubmit();
}
}
diff --git a/java/com/google/gerrit/reviewdb/converter/AccountIdProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/AccountIdProtoConverter.java
index 51e98c7..5c7b03b 100644
--- a/java/com/google/gerrit/reviewdb/converter/AccountIdProtoConverter.java
+++ b/java/com/google/gerrit/reviewdb/converter/AccountIdProtoConverter.java
@@ -14,10 +14,12 @@
package com.google.gerrit.reviewdb.converter;
+import com.google.errorprone.annotations.Immutable;
import com.google.gerrit.proto.Entities;
import com.google.gerrit.reviewdb.client.Account;
import com.google.protobuf.Parser;
+@Immutable
public enum AccountIdProtoConverter implements ProtoConverter<Entities.Account_Id, Account.Id> {
INSTANCE;
diff --git a/java/com/google/gerrit/reviewdb/converter/BranchNameKeyProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/BranchNameKeyProtoConverter.java
index f1018fc..6fa9353 100644
--- a/java/com/google/gerrit/reviewdb/converter/BranchNameKeyProtoConverter.java
+++ b/java/com/google/gerrit/reviewdb/converter/BranchNameKeyProtoConverter.java
@@ -14,11 +14,13 @@
package com.google.gerrit.reviewdb.converter;
+import com.google.errorprone.annotations.Immutable;
import com.google.gerrit.proto.Entities;
import com.google.gerrit.reviewdb.client.BranchNameKey;
import com.google.gerrit.reviewdb.client.Project;
import com.google.protobuf.Parser;
+@Immutable
public enum BranchNameKeyProtoConverter
implements ProtoConverter<Entities.Branch_NameKey, BranchNameKey> {
INSTANCE;
diff --git a/java/com/google/gerrit/reviewdb/converter/ChangeIdProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/ChangeIdProtoConverter.java
index a89434e..5e90c87 100644
--- a/java/com/google/gerrit/reviewdb/converter/ChangeIdProtoConverter.java
+++ b/java/com/google/gerrit/reviewdb/converter/ChangeIdProtoConverter.java
@@ -14,10 +14,12 @@
package com.google.gerrit.reviewdb.converter;
+import com.google.errorprone.annotations.Immutable;
import com.google.gerrit.proto.Entities;
import com.google.gerrit.reviewdb.client.Change;
import com.google.protobuf.Parser;
+@Immutable
public enum ChangeIdProtoConverter implements ProtoConverter<Entities.Change_Id, Change.Id> {
INSTANCE;
diff --git a/java/com/google/gerrit/reviewdb/converter/ChangeKeyProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/ChangeKeyProtoConverter.java
index b9a4f4d..4aa900b 100644
--- a/java/com/google/gerrit/reviewdb/converter/ChangeKeyProtoConverter.java
+++ b/java/com/google/gerrit/reviewdb/converter/ChangeKeyProtoConverter.java
@@ -14,10 +14,12 @@
package com.google.gerrit.reviewdb.converter;
+import com.google.errorprone.annotations.Immutable;
import com.google.gerrit.proto.Entities;
import com.google.gerrit.reviewdb.client.Change;
import com.google.protobuf.Parser;
+@Immutable
public enum ChangeKeyProtoConverter implements ProtoConverter<Entities.Change_Key, Change.Key> {
INSTANCE;
diff --git a/java/com/google/gerrit/reviewdb/converter/ChangeMessageKeyProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/ChangeMessageKeyProtoConverter.java
index 7d97e39..3d36293 100644
--- a/java/com/google/gerrit/reviewdb/converter/ChangeMessageKeyProtoConverter.java
+++ b/java/com/google/gerrit/reviewdb/converter/ChangeMessageKeyProtoConverter.java
@@ -14,11 +14,13 @@
package com.google.gerrit.reviewdb.converter;
+import com.google.errorprone.annotations.Immutable;
import com.google.gerrit.proto.Entities;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.ChangeMessage;
import com.google.protobuf.Parser;
+@Immutable
public enum ChangeMessageKeyProtoConverter
implements ProtoConverter<Entities.ChangeMessage_Key, ChangeMessage.Key> {
INSTANCE;
diff --git a/java/com/google/gerrit/reviewdb/converter/ChangeMessageProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/ChangeMessageProtoConverter.java
index 0895d8d..31b0e11 100644
--- a/java/com/google/gerrit/reviewdb/converter/ChangeMessageProtoConverter.java
+++ b/java/com/google/gerrit/reviewdb/converter/ChangeMessageProtoConverter.java
@@ -14,6 +14,7 @@
package com.google.gerrit.reviewdb.converter;
+import com.google.errorprone.annotations.Immutable;
import com.google.gerrit.proto.Entities;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.ChangeMessage;
@@ -22,6 +23,7 @@
import java.sql.Timestamp;
import java.util.Objects;
+@Immutable
public enum ChangeMessageProtoConverter
implements ProtoConverter<Entities.ChangeMessage, ChangeMessage> {
INSTANCE;
diff --git a/java/com/google/gerrit/reviewdb/converter/ChangeProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/ChangeProtoConverter.java
index 384dbca..2dfa516 100644
--- a/java/com/google/gerrit/reviewdb/converter/ChangeProtoConverter.java
+++ b/java/com/google/gerrit/reviewdb/converter/ChangeProtoConverter.java
@@ -14,6 +14,7 @@
package com.google.gerrit.reviewdb.converter;
+import com.google.errorprone.annotations.Immutable;
import com.google.gerrit.proto.Entities;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.BranchNameKey;
@@ -22,6 +23,7 @@
import com.google.protobuf.Parser;
import java.sql.Timestamp;
+@Immutable
public enum ChangeProtoConverter implements ProtoConverter<Entities.Change, Change> {
INSTANCE;
diff --git a/java/com/google/gerrit/reviewdb/converter/LabelIdProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/LabelIdProtoConverter.java
index 7bc2ab1..42049a4 100644
--- a/java/com/google/gerrit/reviewdb/converter/LabelIdProtoConverter.java
+++ b/java/com/google/gerrit/reviewdb/converter/LabelIdProtoConverter.java
@@ -14,10 +14,12 @@
package com.google.gerrit.reviewdb.converter;
+import com.google.errorprone.annotations.Immutable;
import com.google.gerrit.proto.Entities;
import com.google.gerrit.reviewdb.client.LabelId;
import com.google.protobuf.Parser;
+@Immutable
public enum LabelIdProtoConverter implements ProtoConverter<Entities.LabelId, LabelId> {
INSTANCE;
diff --git a/java/com/google/gerrit/reviewdb/converter/ObjectIdProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/ObjectIdProtoConverter.java
index 7413af9..246207d 100644
--- a/java/com/google/gerrit/reviewdb/converter/ObjectIdProtoConverter.java
+++ b/java/com/google/gerrit/reviewdb/converter/ObjectIdProtoConverter.java
@@ -14,6 +14,7 @@
package com.google.gerrit.reviewdb.converter;
+import com.google.errorprone.annotations.Immutable;
import com.google.gerrit.proto.Entities;
import com.google.protobuf.Parser;
import org.eclipse.jgit.lib.ObjectId;
@@ -30,6 +31,7 @@
* <li>This maintains backwards wire compatibility with a pre-NoteDb implementation.
* </ul>
*/
+@Immutable
public enum ObjectIdProtoConverter implements ProtoConverter<Entities.ObjectId, ObjectId> {
INSTANCE;
diff --git a/java/com/google/gerrit/reviewdb/converter/PatchSetApprovalKeyProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/PatchSetApprovalKeyProtoConverter.java
index 43f6295..d3136b1 100644
--- a/java/com/google/gerrit/reviewdb/converter/PatchSetApprovalKeyProtoConverter.java
+++ b/java/com/google/gerrit/reviewdb/converter/PatchSetApprovalKeyProtoConverter.java
@@ -14,6 +14,7 @@
package com.google.gerrit.reviewdb.converter;
+import com.google.errorprone.annotations.Immutable;
import com.google.gerrit.proto.Entities;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.LabelId;
@@ -21,6 +22,7 @@
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.protobuf.Parser;
+@Immutable
public enum PatchSetApprovalKeyProtoConverter
implements ProtoConverter<Entities.PatchSetApproval_Key, PatchSetApproval.Key> {
INSTANCE;
diff --git a/java/com/google/gerrit/reviewdb/converter/PatchSetApprovalProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/PatchSetApprovalProtoConverter.java
index 418076f..a08d745 100644
--- a/java/com/google/gerrit/reviewdb/converter/PatchSetApprovalProtoConverter.java
+++ b/java/com/google/gerrit/reviewdb/converter/PatchSetApprovalProtoConverter.java
@@ -14,6 +14,7 @@
package com.google.gerrit.reviewdb.converter;
+import com.google.errorprone.annotations.Immutable;
import com.google.gerrit.proto.Entities;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
@@ -21,6 +22,7 @@
import java.sql.Timestamp;
import java.util.Objects;
+@Immutable
public enum PatchSetApprovalProtoConverter
implements ProtoConverter<Entities.PatchSetApproval, PatchSetApproval> {
INSTANCE;
@@ -34,21 +36,18 @@
public Entities.PatchSetApproval toProto(PatchSetApproval patchSetApproval) {
Entities.PatchSetApproval.Builder builder =
Entities.PatchSetApproval.newBuilder()
- .setKey(patchSetApprovalKeyProtoConverter.toProto(patchSetApproval.getKey()))
- .setValue(patchSetApproval.getValue())
- .setGranted(patchSetApproval.getGranted().getTime())
- .setPostSubmit(patchSetApproval.isPostSubmit());
+ .setKey(patchSetApprovalKeyProtoConverter.toProto(patchSetApproval.key()))
+ .setValue(patchSetApproval.value())
+ .setGranted(patchSetApproval.granted().getTime())
+ .setPostSubmit(patchSetApproval.postSubmit());
- String tag = patchSetApproval.getTag();
- if (tag != null) {
- builder.setTag(tag);
- }
- Account.Id realAccountId = patchSetApproval.getRealAccountId();
+ patchSetApproval.tag().ifPresent(builder::setTag);
+ Account.Id realAccountId = patchSetApproval.realAccountId();
// PatchSetApproval#getRealAccountId automatically delegates to PatchSetApproval#getAccountId if
// the real author is not set. However, the previous protobuf representation kept
// 'realAccountId' empty if it wasn't set. To ensure binary compatibility, simulate the previous
// behavior.
- if (realAccountId != null && !Objects.equals(realAccountId, patchSetApproval.getAccountId())) {
+ if (realAccountId != null && !Objects.equals(realAccountId, patchSetApproval.accountId())) {
builder.setRealAccountId(accountIdConverter.toProto(realAccountId));
}
@@ -57,21 +56,19 @@
@Override
public PatchSetApproval fromProto(Entities.PatchSetApproval proto) {
- PatchSetApproval patchSetApproval =
- new PatchSetApproval(
- patchSetApprovalKeyProtoConverter.fromProto(proto.getKey()),
- (short) proto.getValue(),
- new Timestamp(proto.getGranted()));
+ PatchSetApproval.Builder builder =
+ PatchSetApproval.builder()
+ .key(patchSetApprovalKeyProtoConverter.fromProto(proto.getKey()))
+ .value(proto.getValue())
+ .granted(new Timestamp(proto.getGranted()))
+ .postSubmit(proto.getPostSubmit());
if (proto.hasTag()) {
- patchSetApproval.setTag(proto.getTag());
+ builder.tag(proto.getTag());
}
if (proto.hasRealAccountId()) {
- patchSetApproval.setRealAccountId(accountIdConverter.fromProto(proto.getRealAccountId()));
+ builder.realAccountId(accountIdConverter.fromProto(proto.getRealAccountId()));
}
- if (proto.hasPostSubmit()) {
- patchSetApproval.setPostSubmit(proto.getPostSubmit());
- }
- return patchSetApproval;
+ return builder.build();
}
@Override
diff --git a/java/com/google/gerrit/reviewdb/converter/PatchSetIdProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/PatchSetIdProtoConverter.java
index 4101a6b..154b0bf 100644
--- a/java/com/google/gerrit/reviewdb/converter/PatchSetIdProtoConverter.java
+++ b/java/com/google/gerrit/reviewdb/converter/PatchSetIdProtoConverter.java
@@ -14,11 +14,13 @@
package com.google.gerrit.reviewdb.converter;
+import com.google.errorprone.annotations.Immutable;
import com.google.gerrit.proto.Entities;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.protobuf.Parser;
+@Immutable
public enum PatchSetIdProtoConverter implements ProtoConverter<Entities.PatchSet_Id, PatchSet.Id> {
INSTANCE;
diff --git a/java/com/google/gerrit/reviewdb/converter/PatchSetProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/PatchSetProtoConverter.java
index da844c6..5006906 100644
--- a/java/com/google/gerrit/reviewdb/converter/PatchSetProtoConverter.java
+++ b/java/com/google/gerrit/reviewdb/converter/PatchSetProtoConverter.java
@@ -14,8 +14,8 @@
package com.google.gerrit.reviewdb.converter;
-import static com.google.common.base.Preconditions.checkArgument;
-
+import com.google.common.collect.ImmutableList;
+import com.google.errorprone.annotations.Immutable;
import com.google.gerrit.proto.Entities;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.PatchSet;
@@ -24,6 +24,7 @@
import java.util.List;
import org.eclipse.jgit.lib.ObjectId;
+@Immutable
public enum PatchSetProtoConverter implements ProtoConverter<Entities.PatchSet, PatchSet> {
INSTANCE;
@@ -37,54 +38,55 @@
@Override
public Entities.PatchSet toProto(PatchSet patchSet) {
Entities.PatchSet.Builder builder =
- Entities.PatchSet.newBuilder().setId(patchSetIdConverter.toProto(patchSet.getId()));
- builder.setCommitId(objectIdConverter.toProto(patchSet.getCommitId()));
- Account.Id uploader = patchSet.getUploader();
- if (uploader != null) {
- builder.setUploaderAccountId(accountIdConverter.toProto(uploader));
- }
- Timestamp createdOn = patchSet.getCreatedOn();
- if (createdOn != null) {
- builder.setCreatedOn(createdOn.getTime());
- }
- List<String> groups = patchSet.getGroups();
+ Entities.PatchSet.newBuilder()
+ .setId(patchSetIdConverter.toProto(patchSet.id()))
+ .setCommitId(objectIdConverter.toProto(patchSet.commitId()))
+ .setUploaderAccountId(accountIdConverter.toProto(patchSet.uploader()))
+ .setCreatedOn(patchSet.createdOn().getTime());
+ List<String> groups = patchSet.groups();
if (!groups.isEmpty()) {
builder.setGroups(PatchSet.joinGroups(groups));
}
- String pushCertificate = patchSet.getPushCertificate();
- if (pushCertificate != null) {
- builder.setPushCertificate(pushCertificate);
- }
- String description = patchSet.getDescription();
- if (description != null) {
- builder.setDescription(description);
- }
+ patchSet.pushCertificate().ifPresent(builder::setPushCertificate);
+ patchSet.description().ifPresent(builder::setDescription);
return builder.build();
}
@Override
public PatchSet fromProto(Entities.PatchSet proto) {
- checkArgument(proto.hasCommitId(), "missing commit_id: %s", proto);
- PatchSet patchSet =
- new PatchSet(
- patchSetIdConverter.fromProto(proto.getId()),
- objectIdConverter.fromProto(proto.getCommitId()));
- if (proto.hasUploaderAccountId()) {
- patchSet.setUploader(accountIdConverter.fromProto(proto.getUploaderAccountId()));
- }
- if (proto.hasCreatedOn()) {
- patchSet.setCreatedOn(new Timestamp(proto.getCreatedOn()));
- }
- if (proto.hasGroups()) {
- patchSet.setGroups(PatchSet.splitGroups(proto.getGroups()));
- }
+ PatchSet.Builder builder =
+ PatchSet.builder()
+ .id(patchSetIdConverter.fromProto(proto.getId()))
+ .groups(
+ proto.hasGroups() ? PatchSet.splitGroups(proto.getGroups()) : ImmutableList.of());
if (proto.hasPushCertificate()) {
- patchSet.setPushCertificate(proto.getPushCertificate());
+ builder.pushCertificate(proto.getPushCertificate());
}
if (proto.hasDescription()) {
- patchSet.setDescription(proto.getDescription());
+ builder.description(proto.getDescription());
}
- return patchSet;
+
+ // The following fields used to theoretically be nullable in PatchSet, but in practice no
+ // production codepath should have ever serialized an instance that was missing one of these
+ // fields.
+ //
+ // However, since some protos may theoretically be missing these fields, we need to support
+ // them. Populate specific sentinel values for each field as documented in the PatchSet javadoc.
+ // Callers that encounter one of these sentinels will likely fail, for example by failing to
+ // look up the zeroId. They would have also failed back when the fields were nullable, for
+ // example with NPE; the current behavior just fails slightly differently.
+ builder
+ .commitId(
+ proto.hasCommitId()
+ ? objectIdConverter.fromProto(proto.getCommitId())
+ : ObjectId.zeroId())
+ .uploader(
+ proto.hasUploaderAccountId()
+ ? accountIdConverter.fromProto(proto.getUploaderAccountId())
+ : Account.id(0))
+ .createdOn(proto.hasCreatedOn() ? new Timestamp(proto.getCreatedOn()) : new Timestamp(0));
+
+ return builder.build();
}
@Override
diff --git a/java/com/google/gerrit/reviewdb/converter/ProjectNameKeyProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/ProjectNameKeyProtoConverter.java
index 74849af..99048a0 100644
--- a/java/com/google/gerrit/reviewdb/converter/ProjectNameKeyProtoConverter.java
+++ b/java/com/google/gerrit/reviewdb/converter/ProjectNameKeyProtoConverter.java
@@ -14,10 +14,12 @@
package com.google.gerrit.reviewdb.converter;
+import com.google.errorprone.annotations.Immutable;
import com.google.gerrit.proto.Entities;
import com.google.gerrit.reviewdb.client.Project;
import com.google.protobuf.Parser;
+@Immutable
public enum ProjectNameKeyProtoConverter
implements ProtoConverter<Entities.Project_NameKey, Project.NameKey> {
INSTANCE;
diff --git a/java/com/google/gerrit/reviewdb/converter/ProtoConverter.java b/java/com/google/gerrit/reviewdb/converter/ProtoConverter.java
index 568759c..f4f1de06 100644
--- a/java/com/google/gerrit/reviewdb/converter/ProtoConverter.java
+++ b/java/com/google/gerrit/reviewdb/converter/ProtoConverter.java
@@ -14,9 +14,11 @@
package com.google.gerrit.reviewdb.converter;
+import com.google.errorprone.annotations.Immutable;
import com.google.protobuf.MessageLite;
import com.google.protobuf.Parser;
+@Immutable
public interface ProtoConverter<P extends MessageLite, C> {
P toProto(C valueClass);
diff --git a/java/com/google/gerrit/server/ApprovalCopier.java b/java/com/google/gerrit/server/ApprovalCopier.java
index 3ee6d94..979cc11 100644
--- a/java/com/google/gerrit/server/ApprovalCopier.java
+++ b/java/com/google/gerrit/server/ApprovalCopier.java
@@ -104,13 +104,13 @@
Table<String, Account.Id, PatchSetApproval> wontCopy = HashBasedTable.create();
for (PatchSetApproval psa : dontCopy) {
- wontCopy.put(psa.getLabel(), psa.getAccountId(), psa);
+ wontCopy.put(psa.label(), psa.accountId(), psa);
}
Table<String, Account.Id, PatchSetApproval> byUser = HashBasedTable.create();
- for (PatchSetApproval psa : all.get(ps.getId())) {
- if (!wontCopy.contains(psa.getLabel(), psa.getAccountId())) {
- byUser.put(psa.getLabel(), psa.getAccountId(), psa);
+ for (PatchSetApproval psa : all.get(ps.id())) {
+ if (!wontCopy.contains(psa.label(), psa.accountId())) {
+ byUser.put(psa.label(), psa.accountId(), psa);
}
}
@@ -118,29 +118,29 @@
// Walk patch sets strictly less than current in descending order.
Collection<PatchSet> allPrior =
- patchSets.descendingMap().tailMap(ps.getId().get(), false).values();
+ patchSets.descendingMap().tailMap(ps.id().get(), false).values();
for (PatchSet priorPs : allPrior) {
- List<PatchSetApproval> priorApprovals = all.get(priorPs.getId());
+ List<PatchSetApproval> priorApprovals = all.get(priorPs.id());
if (priorApprovals.isEmpty()) {
continue;
}
ChangeKind kind =
changeKindCache.getChangeKind(
- project.getNameKey(), rw, repoConfig, priorPs.getCommitId(), ps.getCommitId());
+ project.getNameKey(), rw, repoConfig, priorPs.commitId(), ps.commitId());
for (PatchSetApproval psa : priorApprovals) {
- if (wontCopy.contains(psa.getLabel(), psa.getAccountId())) {
+ if (wontCopy.contains(psa.label(), psa.accountId())) {
continue;
}
- if (byUser.contains(psa.getLabel(), psa.getAccountId())) {
+ if (byUser.contains(psa.label(), psa.accountId())) {
continue;
}
- if (!canCopy(project, psa, ps.getId(), kind)) {
- wontCopy.put(psa.getLabel(), psa.getAccountId(), psa);
+ if (!canCopy(project, psa, ps.id(), kind)) {
+ wontCopy.put(psa.label(), psa.accountId(), psa);
continue;
}
- byUser.put(psa.getLabel(), psa.getAccountId(), copy(psa, ps.getId()));
+ byUser.put(psa.label(), psa.accountId(), psa.copyWithPatchSet(ps.id()));
}
}
return labelNormalizer.normalize(notes, byUser.values()).getNormalized();
@@ -153,16 +153,16 @@
Collection<PatchSet> patchSets = cd.patchSets();
TreeMap<Integer, PatchSet> result = new TreeMap<>();
for (PatchSet ps : patchSets) {
- result.put(ps.getId().get(), ps);
+ result.put(ps.id().get(), ps);
}
return result;
}
private static boolean canCopy(
ProjectState project, PatchSetApproval psa, PatchSet.Id psId, ChangeKind kind) {
- int n = psa.getKey().patchSetId().get();
+ int n = psa.key().patchSetId().get();
checkArgument(n != psId.get());
- LabelType type = project.getLabelTypes().byLabel(psa.getLabelId());
+ LabelType type = project.getLabelTypes().byLabel(psa.labelId());
if (type == null) {
return false;
} else if ((type.isCopyMinScore() && type.isMaxNegative(psa))
@@ -186,11 +186,4 @@
return false;
}
}
-
- private static PatchSetApproval copy(PatchSetApproval src, PatchSet.Id psId) {
- if (src.getKey().patchSetId().equals(psId)) {
- return src;
- }
- return new PatchSetApproval(psId, src);
- }
}
diff --git a/java/com/google/gerrit/server/ApprovalsUtil.java b/java/com/google/gerrit/server/ApprovalsUtil.java
index 05c5123..9befb46 100644
--- a/java/com/google/gerrit/server/ApprovalsUtil.java
+++ b/java/com/google/gerrit/server/ApprovalsUtil.java
@@ -25,7 +25,6 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.common.flogger.FluentLogger;
-import com.google.common.primitives.Shorts;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelTypes;
@@ -76,20 +75,20 @@
public class ApprovalsUtil {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
- public static PatchSetApproval newApproval(
+ public static PatchSetApproval.Builder newApproval(
PatchSet.Id psId, CurrentUser user, LabelId labelId, int value, Date when) {
- PatchSetApproval psa =
- new PatchSetApproval(
- PatchSetApproval.key(psId, user.getAccountId(), labelId),
- Shorts.checkedCast(value),
- when);
- user.updateRealAccountId(psa::setRealAccountId);
- return psa;
+ PatchSetApproval.Builder b =
+ PatchSetApproval.builder()
+ .key(PatchSetApproval.key(psId, user.getAccountId(), labelId))
+ .value(value)
+ .granted(when);
+ user.updateRealAccountId(b::realAccountId);
+ return b;
}
private static Iterable<PatchSetApproval> filterApprovals(
Iterable<PatchSetApproval> psas, Account.Id accountId) {
- return Iterables.filter(psas, a -> Objects.equals(a.getAccountId(), accountId));
+ return Iterables.filter(psas, a -> Objects.equals(a.accountId(), accountId));
}
private final ApprovalCopier copier;
@@ -147,7 +146,7 @@
update,
labelTypes,
change,
- ps.getId(),
+ ps.id(),
info.getAuthor().getAccount(),
info.getCommitter().getAccount(),
wantReviewers,
@@ -207,8 +206,11 @@
LabelId labelId = Iterables.getLast(allTypes).getLabelId();
for (Account.Id account : need) {
cells.add(
- new PatchSetApproval(
- PatchSetApproval.key(psId, account, labelId), (short) 0, update.getWhen()));
+ PatchSetApproval.builder()
+ .key(PatchSetApproval.key(psId, account, labelId))
+ .value(0)
+ .granted(update.getWhen())
+ .build());
update.putReviewer(account, REVIEWER);
}
return Collections.unmodifiableList(cells);
@@ -274,10 +276,10 @@
throws RestApiException, PermissionBackendException {
Account.Id accountId = user.getAccountId();
checkArgument(
- accountId.equals(ps.getUploader()),
+ accountId.equals(ps.uploader()),
"expected user %s to match patch set uploader %s",
accountId,
- ps.getUploader());
+ ps.uploader());
if (approvals.isEmpty()) {
return ImmutableList.of();
}
@@ -286,10 +288,10 @@
Date ts = update.getWhen();
for (Map.Entry<String, Short> vote : approvals.entrySet()) {
LabelType lt = labelTypes.byLabel(vote.getKey());
- cells.add(newApproval(ps.getId(), user, lt.getLabelId(), vote.getValue(), ts));
+ cells.add(newApproval(ps.id(), user, lt.getLabelId(), vote.getValue(), ts).build());
}
for (PatchSetApproval psa : cells) {
- update.putApproval(psa.getLabel(), psa.getValue());
+ update.putApproval(psa.label(), psa.value());
}
return cells;
}
@@ -357,8 +359,8 @@
}
PatchSetApproval submitter = null;
for (PatchSetApproval a : approvals) {
- if (a.getPatchSetId().equals(c) && a.getValue() > 0 && a.isLegacySubmit()) {
- if (submitter == null || a.getGranted().compareTo(submitter.getGranted()) > 0) {
+ if (a.patchSetId().equals(c) && a.value() > 0 && a.isLegacySubmit()) {
+ if (submitter == null || a.granted().compareTo(submitter.granted()) > 0) {
submitter = a;
}
}
@@ -372,7 +374,7 @@
if (!n.isEmpty()) {
boolean first = true;
for (Map.Entry<String, Short> e : n.entrySet()) {
- if (c.containsKey(e.getKey()) && c.get(e.getKey()).getValue() == e.getValue()) {
+ if (c.containsKey(e.getKey()) && c.get(e.getKey()).value() == e.getValue()) {
continue;
}
if (first) {
diff --git a/java/com/google/gerrit/server/ChangeUtil.java b/java/com/google/gerrit/server/ChangeUtil.java
index 73013a6..8c207a8 100644
--- a/java/com/google/gerrit/server/ChangeUtil.java
+++ b/java/com/google/gerrit/server/ChangeUtil.java
@@ -40,7 +40,7 @@
private static final BaseEncoding UUID_ENCODING = BaseEncoding.base16().lowerCase();
public static final Ordering<PatchSet> PS_ID_ORDER =
- Ordering.from(comparingInt(PatchSet::getPatchSetId));
+ Ordering.from(comparingInt(PatchSet::number));
/** @return a new unique identifier for change message entities. */
public static String messageUuid() {
diff --git a/java/com/google/gerrit/server/CommentsUtil.java b/java/com/google/gerrit/server/CommentsUtil.java
index ea65bd1..449d61b 100644
--- a/java/com/google/gerrit/server/CommentsUtil.java
+++ b/java/com/google/gerrit/server/CommentsUtil.java
@@ -308,9 +308,9 @@
public static void setCommentCommitId(Comment c, PatchListCache cache, Change change, PatchSet ps)
throws PatchListNotAvailableException {
checkArgument(
- c.key.patchSetId == ps.getId().get(),
+ c.key.patchSetId == ps.id().get(),
"cannot set commit ID for patch set %s on comment %s",
- ps.getId(),
+ ps.id(),
c);
if (c.getCommitId() == null) {
if (Side.fromShort(c.side) == Side.PARENT) {
@@ -320,7 +320,7 @@
c.setCommitId(cache.getOldId(change, ps, null));
}
} else {
- c.setCommitId(ps.getCommitId());
+ c.setCommitId(ps.commitId());
}
}
}
diff --git a/java/com/google/gerrit/server/PatchSetUtil.java b/java/com/google/gerrit/server/PatchSetUtil.java
index 41fb79d..7e5b90c 100644
--- a/java/com/google/gerrit/server/PatchSetUtil.java
+++ b/java/com/google/gerrit/server/PatchSetUtil.java
@@ -20,6 +20,7 @@
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
+import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.LabelFunction;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
@@ -38,6 +39,7 @@
import java.io.IOException;
import java.sql.Timestamp;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
@@ -88,8 +90,8 @@
PatchSet.Id psId,
ObjectId commit,
List<String> groups,
- String pushCertificate,
- String description)
+ @Nullable String pushCertificate,
+ @Nullable String description)
throws IOException {
requireNonNull(groups, "groups may not be null");
ensurePatchSetMatches(psId, update);
@@ -98,17 +100,19 @@
update.setPsDescription(description);
update.setGroups(groups);
- PatchSet ps = new PatchSet(psId, commit);
- ps.setUploader(update.getAccountId());
- ps.setCreatedOn(new Timestamp(update.getWhen().getTime()));
- ps.setGroups(groups);
- ps.setPushCertificate(pushCertificate);
- ps.setDescription(description);
- return ps;
+ return PatchSet.builder()
+ .id(psId)
+ .commitId(commit)
+ .uploader(update.getAccountId())
+ .createdOn(new Timestamp(update.getWhen().getTime()))
+ .groups(groups)
+ .pushCertificate(Optional.ofNullable(pushCertificate))
+ .description(Optional.ofNullable(description))
+ .build();
}
private static void ensurePatchSetMatches(PatchSet.Id psId, ChangeUpdate update) {
- Change.Id changeId = update.getChange().getId();
+ Change.Id changeId = update.getId();
checkArgument(
psId.changeId().equals(changeId),
"cannot modify patch set %s on update for change %s",
@@ -125,11 +129,6 @@
}
}
- public void setGroups(ChangeUpdate update, PatchSet ps, List<String> groups) {
- ps.setGroups(groups);
- update.setGroups(groups);
- }
-
/** Check if the current patch set of the change is locked. */
public void checkPatchSetNotLocked(ChangeNotes notes)
throws IOException, ResourceConflictException {
@@ -153,10 +152,8 @@
ApprovalsUtil approvalsUtil = approvalsUtilProvider.get();
for (PatchSetApproval ap :
approvalsUtil.byPatchSet(notes, change.currentPatchSetId(), null, null)) {
- LabelType type = projectState.getLabelTypes(notes).byLabel(ap.getLabel());
- if (type != null
- && ap.getValue() == 1
- && type.getFunction() == LabelFunction.PATCH_SET_LOCK) {
+ LabelType type = projectState.getLabelTypes(notes).byLabel(ap.label());
+ if (type != null && ap.value() == 1 && type.getFunction() == LabelFunction.PATCH_SET_LOCK) {
return true;
}
}
@@ -167,7 +164,7 @@
public RevCommit getRevCommit(Project.NameKey project, PatchSet patchSet) throws IOException {
try (Repository repo = repoManager.openRepository(project);
RevWalk rw = new RevWalk(repo)) {
- RevCommit src = rw.parseCommit(patchSet.getCommitId());
+ RevCommit src = rw.parseCommit(patchSet.commitId());
rw.parseBody(src);
return src;
}
diff --git a/java/com/google/gerrit/server/ReviewerSet.java b/java/com/google/gerrit/server/ReviewerSet.java
index f9f9a9d..f0bc23e 100644
--- a/java/com/google/gerrit/server/ReviewerSet.java
+++ b/java/com/google/gerrit/server/ReviewerSet.java
@@ -44,14 +44,14 @@
first = psa;
} else {
checkArgument(
- first.getKey().patchSetId().changeId().equals(psa.getKey().patchSetId().changeId()),
+ first.key().patchSetId().changeId().equals(psa.key().patchSetId().changeId()),
"multiple change IDs: %s, %s",
- first.getKey(),
- psa.getKey());
+ first.key(),
+ psa.key());
}
- Account.Id id = psa.getAccountId();
- reviewers.put(REVIEWER, id, psa.getGranted());
- if (psa.getValue() != 0) {
+ Account.Id id = psa.accountId();
+ reviewers.put(REVIEWER, id, psa.granted());
+ if (psa.value() != 0) {
reviewers.remove(CC, id);
}
}
diff --git a/java/com/google/gerrit/server/WebLinks.java b/java/com/google/gerrit/server/WebLinks.java
index 589344c..94bf53c 100644
--- a/java/com/google/gerrit/server/WebLinks.java
+++ b/java/com/google/gerrit/server/WebLinks.java
@@ -14,10 +14,11 @@
package com.google.gerrit.server;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
+import static com.google.common.collect.ImmutableList.toImmutableList;
+
import com.google.common.base.Strings;
-import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Streams;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.extensions.common.DiffWebLinkInfo;
import com.google.gerrit.extensions.common.WebLinkInfo;
@@ -35,8 +36,8 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.inject.Inject;
import com.google.inject.Singleton;
-import java.util.Collections;
-import java.util.List;
+import java.util.function.Function;
+import java.util.function.Predicate;
@Singleton
public class WebLinks {
@@ -87,7 +88,7 @@
* @param commit SHA1 of commit.
* @return Links for patch sets.
*/
- public List<WebLinkInfo> getPatchSetLinks(Project.NameKey project, String commit) {
+ public ImmutableList<WebLinkInfo> getPatchSetLinks(Project.NameKey project, String commit) {
return filterLinks(patchSetLinks, webLink -> webLink.getPatchSetWebLink(project.get(), commit));
}
@@ -96,7 +97,7 @@
* @param revision SHA1 of the parent revision.
* @return Links for patch sets.
*/
- public List<WebLinkInfo> getParentLinks(Project.NameKey project, String revision) {
+ public ImmutableList<WebLinkInfo> getParentLinks(Project.NameKey project, String revision) {
return filterLinks(parentLinks, webLink -> webLink.getParentWebLink(project.get(), revision));
}
@@ -106,9 +107,9 @@
* @param file File name.
* @return Links for files.
*/
- public List<WebLinkInfo> getFileLinks(String project, String revision, String file) {
+ public ImmutableList<WebLinkInfo> getFileLinks(String project, String revision, String file) {
return Patch.isMagic(file)
- ? Collections.emptyList()
+ ? ImmutableList.of()
: filterLinks(fileLinks, webLink -> webLink.getFileWebLink(project, revision, file));
}
@@ -118,14 +119,15 @@
* @param file File name.
* @return Links for file history
*/
- public List<WebLinkInfo> getFileHistoryLinks(String project, String revision, String file) {
+ public ImmutableList<WebLinkInfo> getFileHistoryLinks(
+ String project, String revision, String file) {
if (Patch.isMagic(file)) {
- return Collections.emptyList();
+ return ImmutableList.of();
}
- return FluentIterable.from(fileHistoryLinks)
- .transform(webLink -> webLink.getFileHistoryWebLink(project, revision, file))
+ return Streams.stream(fileHistoryLinks)
+ .map(webLink -> webLink.getFileHistoryWebLink(project, revision, file))
.filter(INVALID_WEBLINK)
- .toList();
+ .collect(toImmutableList());
}
/**
@@ -138,20 +140,20 @@
* @param fileB File name of side B.
* @return Links for file diffs.
*/
- public List<DiffWebLinkInfo> getDiffLinks(
- final String project,
- final int changeId,
- final Integer patchSetIdA,
- final String revisionA,
- final String fileA,
- final int patchSetIdB,
- final String revisionB,
- final String fileB) {
+ public ImmutableList<DiffWebLinkInfo> getDiffLinks(
+ String project,
+ int changeId,
+ Integer patchSetIdA,
+ String revisionA,
+ String fileA,
+ int patchSetIdB,
+ String revisionB,
+ String fileB) {
if (Patch.isMagic(fileA) || Patch.isMagic(fileB)) {
- return Collections.emptyList();
+ return ImmutableList.of();
}
- return FluentIterable.from(diffLinks)
- .transform(
+ return Streams.stream(diffLinks)
+ .map(
webLink ->
webLink.getDiffLink(
project,
@@ -163,14 +165,14 @@
revisionB,
fileB))
.filter(INVALID_WEBLINK)
- .toList();
+ .collect(toImmutableList());
}
/**
* @param project Project name.
* @return Links for projects.
*/
- public List<WebLinkInfo> getProjectLinks(String project) {
+ public ImmutableList<WebLinkInfo> getProjectLinks(String project) {
return filterLinks(projectLinks, webLink -> webLink.getProjectWeblink(project));
}
@@ -179,7 +181,7 @@
* @param branch Branch name
* @return Links for branches.
*/
- public List<WebLinkInfo> getBranchLinks(String project, String branch) {
+ public ImmutableList<WebLinkInfo> getBranchLinks(String project, String branch) {
return filterLinks(branchLinks, webLink -> webLink.getBranchWebLink(project, branch));
}
@@ -188,12 +190,15 @@
* @param tag Tag name
* @return Links for tags.
*/
- public List<WebLinkInfo> getTagLinks(String project, String tag) {
+ public ImmutableList<WebLinkInfo> getTagLinks(String project, String tag) {
return filterLinks(tagLinks, webLink -> webLink.getTagWebLink(project, tag));
}
- private <T extends WebLink> List<WebLinkInfo> filterLinks(
+ private <T extends WebLink> ImmutableList<WebLinkInfo> filterLinks(
DynamicSet<T> links, Function<T, WebLinkInfo> transformer) {
- return FluentIterable.from(links).transform(transformer).filter(INVALID_WEBLINK).toList();
+ return Streams.stream(links)
+ .map(transformer)
+ .filter(INVALID_WEBLINK)
+ .collect(toImmutableList());
}
}
diff --git a/java/com/google/gerrit/server/account/AccountLoader.java b/java/com/google/gerrit/server/account/AccountLoader.java
index 4398d9e..09b9ac3 100644
--- a/java/com/google/gerrit/server/account/AccountLoader.java
+++ b/java/com/google/gerrit/server/account/AccountLoader.java
@@ -17,6 +17,7 @@
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.collect.Iterables;
+import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.server.account.AccountDirectory.FillOptions;
@@ -67,7 +68,8 @@
provided = new ArrayList<>();
}
- public synchronized AccountInfo get(Account.Id id) {
+ @Nullable
+ public synchronized AccountInfo get(@Nullable Account.Id id) {
if (id == null) {
return null;
}
@@ -95,7 +97,8 @@
fill();
}
- public AccountInfo fillOne(Account.Id id) throws PermissionBackendException {
+ @Nullable
+ public AccountInfo fillOne(@Nullable Account.Id id) throws PermissionBackendException {
AccountInfo info = get(id);
fill();
return info;
diff --git a/java/com/google/gerrit/server/account/AccountState.java b/java/com/google/gerrit/server/account/AccountState.java
index 1854dc1..46fde8c 100644
--- a/java/com/google/gerrit/server/account/AccountState.java
+++ b/java/com/google/gerrit/server/account/AccountState.java
@@ -17,7 +17,6 @@
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_USERNAME;
-import com.google.common.base.Function;
import com.google.common.base.MoreObjects;
import com.google.common.base.Strings;
import com.google.common.cache.Cache;
@@ -54,9 +53,6 @@
public class AccountState {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
- public static final Function<AccountState, Account.Id> ACCOUNT_ID_FUNCTION =
- a -> a.getAccount().getId();
-
/**
* Creates an AccountState from the given account config.
*
diff --git a/java/com/google/gerrit/server/account/externalids/ExternalIdNotes.java b/java/com/google/gerrit/server/account/externalids/ExternalIdNotes.java
index f4ff471..eef2156 100644
--- a/java/com/google/gerrit/server/account/externalids/ExternalIdNotes.java
+++ b/java/com/google/gerrit/server/account/externalids/ExternalIdNotes.java
@@ -806,7 +806,7 @@
}
checkState(
accountId.equals(extId.accountId()),
- "external id %s belongs to account %s, expected account %s",
+ "external id %s belongs to account %s, but expected account %s",
extId.key().get(),
extId.accountId().get(),
accountId.get());
@@ -864,7 +864,7 @@
ExternalId actualExtId = ExternalId.parse(noteId.name(), raw, noteDataId);
checkState(
extId.equals(actualExtId),
- "external id %s should be removed, but it's not matching the actual external id %s",
+ "external id %s should be removed, but it doesn't match the actual external id %s",
extId.toString(),
actualExtId.toString());
noteMap.remove(noteId);
diff --git a/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java b/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java
index 2df7ae6..27073db 100644
--- a/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java
+++ b/java/com/google/gerrit/server/api/changes/RevisionApiImpl.java
@@ -476,7 +476,7 @@
// Reread change to pick up new notes refs.
return changes
.id(revision.getChange().getId().get())
- .revision(revision.getPatchSet().getId().get())
+ .revision(revision.getPatchSet().id().get())
.draft(id);
} catch (Exception e) {
throw asRestApiException("Cannot create draft", e);
@@ -587,20 +587,20 @@
ListMultimapBuilder.treeKeys().arrayListValues().build();
try {
Iterable<PatchSetApproval> approvals =
- approvalsUtil.byPatchSet(revision.getNotes(), revision.getPatchSet().getId(), null, null);
+ approvalsUtil.byPatchSet(revision.getNotes(), revision.getPatchSet().id(), null, null);
AccountLoader accountLoader =
accountLoaderFactory.create(
EnumSet.of(
FillOptions.ID, FillOptions.NAME, FillOptions.EMAIL, FillOptions.USERNAME));
for (PatchSetApproval approval : approvals) {
- String label = approval.getLabel();
+ String label = approval.label();
ApprovalInfo info =
new ApprovalInfo(
- approval.getAccountId().get(),
- Integer.valueOf(approval.getValue()),
+ approval.accountId().get(),
+ Integer.valueOf(approval.value()),
null,
- approval.getTag(),
- approval.getGranted());
+ approval.tag().orElse(null),
+ approval.granted());
accountLoader.put(info);
result.get(label).add(info);
}
diff --git a/java/com/google/gerrit/server/change/AccountPatchReviewStore.java b/java/com/google/gerrit/server/change/AccountPatchReviewStore.java
index fc3e476..fff3274 100644
--- a/java/com/google/gerrit/server/change/AccountPatchReviewStore.java
+++ b/java/com/google/gerrit/server/change/AccountPatchReviewStore.java
@@ -17,6 +17,7 @@
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import java.util.Collection;
import java.util.Optional;
@@ -82,6 +83,13 @@
void clearReviewed(PatchSet.Id psId);
/**
+ * Clears the reviewed flags for all files in all patch sets in the given change for all users.
+ *
+ * @param changeId change ID
+ */
+ void clearReviewed(Change.Id changeId);
+
+ /**
* Find the latest patch set, that is smaller or equals to the given patch set, where at least,
* one file has been reviewed by the given user.
*
diff --git a/java/com/google/gerrit/server/change/AddReviewersOp.java b/java/com/google/gerrit/server/change/AddReviewersOp.java
index 610290d..a8ebcb2 100644
--- a/java/com/google/gerrit/server/change/AddReviewersOp.java
+++ b/java/com/google/gerrit/server/change/AddReviewersOp.java
@@ -240,7 +240,7 @@
addReviewersEmail.emailReviewers(
ctx.getUser().asIdentifiedUser(),
change,
- Lists.transform(addedReviewers, PatchSetApproval::getAccountId),
+ Lists.transform(addedReviewers, PatchSetApproval::accountId),
addedCCs,
addedReviewersByEmail,
addedCCsByEmail,
@@ -249,7 +249,7 @@
if (!addedReviewers.isEmpty()) {
List<AccountState> reviewers =
addedReviewers.stream()
- .map(r -> accountCache.get(r.getAccountId()))
+ .map(r -> accountCache.get(r.accountId()))
.flatMap(Streams::stream)
.collect(toList());
reviewerAdded.fire(change, patchSet, reviewers, ctx.getAccount(), ctx.getWhen());
diff --git a/java/com/google/gerrit/server/change/ArchiveFormat.java b/java/com/google/gerrit/server/change/ArchiveFormat.java
index 0316c5f..d895a66 100644
--- a/java/com/google/gerrit/server/change/ArchiveFormat.java
+++ b/java/com/google/gerrit/server/change/ArchiveFormat.java
@@ -35,7 +35,9 @@
TXZ("application/x-xz", new TxzFormat()),
ZIP("application/x-zip", new ZipFormat());
+ @SuppressWarnings("ImmutableEnumChecker") // ArchiveCommand.Format is effectively immutable.
private final ArchiveCommand.Format<?> format;
+
private final String mimeType;
ArchiveFormat(String mimeType, ArchiveCommand.Format<?> format) {
diff --git a/java/com/google/gerrit/server/change/ChangeInserter.java b/java/com/google/gerrit/server/change/ChangeInserter.java
index 34bad7b..6e8f04f 100644
--- a/java/com/google/gerrit/server/change/ChangeInserter.java
+++ b/java/com/google/gerrit/server/change/ChangeInserter.java
@@ -426,9 +426,9 @@
if (message != null) {
changeMessage =
ChangeMessagesUtil.newMessage(
- patchSet.getId(),
+ patchSet.id(),
ctx.getUser(),
- patchSet.getCreatedOn(),
+ patchSet.createdOn(),
message,
ChangeMessagesUtil.uploadedPatchSetTag(workInProgress));
cmUtil.addChangeMessage(update, changeMessage);
@@ -453,7 +453,7 @@
cm.setNotify(notify);
cm.addReviewers(
reviewerAdditions.flattenResults(AddReviewersOp.Result::addedReviewers).stream()
- .map(PatchSetApproval::getAccountId)
+ .map(PatchSetApproval::accountId)
.collect(toImmutableSet()));
cm.addReviewersByEmail(
reviewerAdditions.flattenResults(AddReviewersOp.Result::addedReviewersByEmail));
diff --git a/java/com/google/gerrit/server/change/ChangeJson.java b/java/com/google/gerrit/server/change/ChangeJson.java
index 8b43c9e..d4b347b 100644
--- a/java/com/google/gerrit/server/change/ChangeJson.java
+++ b/java/com/google/gerrit/server/change/ChangeJson.java
@@ -286,7 +286,7 @@
public ChangeInfo format(RevisionResource rsrc) {
ChangeData cd = changeDataFactory.create(rsrc.getNotes());
- return format(cd, Optional.of(rsrc.getPatchSet().getId()), true, ChangeInfo::new);
+ return format(cd, Optional.of(rsrc.getPatchSet().id()), true, ChangeInfo::new);
}
public List<List<ChangeInfo>> format(List<QueryResult<ChangeData>> in)
@@ -656,8 +656,8 @@
if (!s.isPresent()) {
return;
}
- out.submitted = s.get().getGranted();
- out.submitter = accountLoader.get(s.get().getAccountId());
+ out.submitted = s.get().granted();
+ out.submitter = accountLoader.get(s.get().accountId());
}
private Collection<ChangeMessageInfo> messages(ChangeData cd) {
@@ -784,7 +784,7 @@
}
Map<PatchSet.Id, PatchSet> map = Maps.newHashMapWithExpectedSize(src.size());
for (PatchSet patchSet : src) {
- map.put(patchSet.getId(), patchSet);
+ map.put(patchSet.id(), patchSet);
}
return map;
}
diff --git a/java/com/google/gerrit/server/change/ChangeKeyAdapter.java b/java/com/google/gerrit/server/change/ChangeKeyAdapter.java
index ef0c92c..f0fef20 100644
--- a/java/com/google/gerrit/server/change/ChangeKeyAdapter.java
+++ b/java/com/google/gerrit/server/change/ChangeKeyAdapter.java
@@ -15,7 +15,6 @@
package com.google.gerrit.server.change;
import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.reviewdb.client.Change.Key;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
@@ -26,8 +25,8 @@
import java.lang.reflect.Type;
/**
- * Adapter that serializes {@link Change.Key}'s {@code key} field as {@code id}, for backwards
- * compatibility in stream-events.
+ * Adapter that serializes {@link com.google.gerrit.reviewdb.client.Change.Key}'s {@code key} field
+ * as {@code id}, for backwards compatibility in stream-events.
*/
// TODO(dborowitz): auto-value-gson should support this directly using @SerializedName on the
// AutoValue method.
@@ -40,7 +39,7 @@
}
@Override
- public Key deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
+ public Change.Key deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
JsonElement keyJson = json.getAsJsonObject().get("id");
if (keyJson == null || !keyJson.isJsonPrimitive() || !keyJson.getAsJsonPrimitive().isString()) {
diff --git a/java/com/google/gerrit/server/change/ChangeKindCacheImpl.java b/java/com/google/gerrit/server/change/ChangeKindCacheImpl.java
index 50104fd..45fc8b1 100644
--- a/java/com/google/gerrit/server/change/ChangeKindCacheImpl.java
+++ b/java/com/google/gerrit/server/change/ChangeKindCacheImpl.java
@@ -367,13 +367,13 @@
ChangeKind kind = ChangeKind.REWORK;
// Trivial case: if we're on the first patch, we don't need to use
// the repository.
- if (patch.getId().get() > 1) {
+ if (patch.id().get() > 1) {
try {
Collection<PatchSet> patchSetCollection = change.patchSets();
PatchSet priorPs = patch;
for (PatchSet ps : patchSetCollection) {
- if (ps.getId().get() < patch.getId().get()
- && (ps.getId().get() > priorPs.getId().get() || priorPs == patch)) {
+ if (ps.id().get() < patch.id().get()
+ && (ps.id().get() > priorPs.id().get() || priorPs == patch)) {
// We only want the previous patch set, so walk until the last one
priorPs = ps;
}
@@ -386,13 +386,13 @@
if (priorPs != patch) {
kind =
cache.getChangeKind(
- change.project(), rw, repoConfig, priorPs.getCommitId(), patch.getCommitId());
+ change.project(), rw, repoConfig, priorPs.commitId(), patch.commitId());
}
} catch (StorageException e) {
// Do nothing; assume we have a complex change
logger.atWarning().withCause(e).log(
"Unable to get change kind for patchSet %s of change %s",
- patch.getPatchSetId(), change.getId());
+ patch.number(), change.getId());
}
}
return kind;
@@ -408,7 +408,7 @@
ChangeKind kind = ChangeKind.REWORK;
// Trivial case: if we're on the first patch, we don't need to open
// the repository.
- if (patch.getId().get() > 1) {
+ if (patch.id().get() > 1) {
try (Repository repo = repoManager.openRepository(change.getProject());
RevWalk rw = new RevWalk(repo)) {
kind =
@@ -418,7 +418,7 @@
// Do nothing; assume we have a complex change
logger.atWarning().withCause(e).log(
"Unable to get change kind for patchSet %s of change %s",
- patch.getPatchSetId(), change.getChangeId());
+ patch.number(), change.getChangeId());
}
}
return kind;
diff --git a/java/com/google/gerrit/server/change/ChangeResource.java b/java/com/google/gerrit/server/change/ChangeResource.java
index 98b728f..19a4e5c 100644
--- a/java/com/google/gerrit/server/change/ChangeResource.java
+++ b/java/com/google/gerrit/server/change/ChangeResource.java
@@ -149,7 +149,7 @@
accounts.add(getChange().getAssignee());
}
try {
- patchSetUtil.byChange(notes).stream().map(PatchSet::getUploader).forEach(accounts::add);
+ patchSetUtil.byChange(notes).stream().map(PatchSet::uploader).forEach(accounts::add);
// It's intentional to include the states for *all* reviewers into the ETag computation.
// We need the states of all current reviewers and CCs because they are part of ChangeInfo.
diff --git a/java/com/google/gerrit/server/change/ConsistencyChecker.java b/java/com/google/gerrit/server/change/ConsistencyChecker.java
index c00cb2b..0e555e9 100644
--- a/java/com/google/gerrit/server/change/ConsistencyChecker.java
+++ b/java/com/google/gerrit/server/change/ConsistencyChecker.java
@@ -265,7 +265,7 @@
try {
refs =
repo.getRefDatabase()
- .exactRef(all.stream().map(ps -> ps.getId().toRefName()).toArray(String[]::new));
+ .exactRef(all.stream().map(ps -> ps.id().toRefName()).toArray(String[]::new));
} catch (IOException e) {
error("error reading refs", e);
refs = Collections.emptyMap();
@@ -274,9 +274,9 @@
List<DeletePatchSetFromDbOp> deletePatchSetOps = new ArrayList<>();
for (PatchSet ps : all) {
// Check revision format.
- int psNum = ps.getId().get();
- String refName = ps.getId().toRefName();
- ObjectId objId = ps.getCommitId();
+ int psNum = ps.id().get();
+ String refName = ps.id().toRefName();
+ ObjectId objId = ps.commitId();
patchSetsBySha.put(objId, ps);
// Check ref existence.
@@ -296,13 +296,13 @@
RevCommit psCommit = parseCommit(objId, String.format("patch set %d", psNum));
if (psCommit == null) {
if (fix != null && fix.deletePatchSetIfCommitMissing) {
- deletePatchSetOps.add(new DeletePatchSetFromDbOp(lastProblem(), ps.getId()));
+ deletePatchSetOps.add(new DeletePatchSetFromDbOp(lastProblem(), ps.id()));
}
continue;
} else if (refProblem != null && fix != null) {
fixPatchSetRef(refProblem, ps);
}
- if (ps.getId().equals(change().currentPatchSetId())) {
+ if (ps.id().equals(change().currentPatchSetId())) {
currPsCommit = psCommit;
}
}
@@ -316,7 +316,7 @@
problem(
String.format(
"Multiple patch sets pointing to %s: %s",
- e.getKey().name(), Collections2.transform(e.getValue(), PatchSet::getPatchSetId)));
+ e.getKey().name(), Collections2.transform(e.getValue(), PatchSet::number)));
}
}
@@ -348,10 +348,10 @@
try {
merged = rw.isMergedInto(currPsCommit, tip);
} catch (IOException e) {
- problem("Error checking whether patch set " + currPs.getId().get() + " is merged");
+ problem("Error checking whether patch set " + currPs.id().get() + " is merged");
return;
}
- checkMergedBitMatchesStatus(currPs.getId(), currPsCommit, merged);
+ checkMergedBitMatchesStatus(currPs.id(), currPsCommit, merged);
}
}
@@ -376,7 +376,7 @@
formatProblemMessage(
"Patch set %d (%s) is not merged into"
+ " destination ref %s (%s), but change status is %s",
- currPs.getId().get(), commit.name(), refName, tip.name()));
+ currPs.id().get(), commit.name(), refName, tip.name()));
}
}
@@ -601,9 +601,9 @@
private void fixPatchSetRef(ProblemInfo p, PatchSet ps) {
try {
- RefUpdate ru = repo.updateRef(ps.getId().toRefName());
+ RefUpdate ru = repo.updateRef(ps.id().toRefName());
ru.setForceUpdate(true);
- ru.setNewObjectId(ps.getCommitId());
+ ru.setNewObjectId(ps.commitId());
ru.setRefLogIdent(newRefLogIdent());
ru.setRefLogMessage("Repair patch set ref", true);
RefUpdate.Result result = ru.update();
@@ -630,7 +630,7 @@
}
} catch (IOException e) {
String msg = "Error fixing patch set ref";
- logger.atWarning().withCause(e).log("%s %s", msg, ps.getId().toRefName());
+ logger.atWarning().withCause(e).log("%s %s", msg, ps.id().toRefName());
p.status = Status.FIX_FAILED;
p.outcome = msg;
}
@@ -714,8 +714,8 @@
// and whether they are seen by this op; we are already given the full set
// of patch sets that will eventually be deleted in this update.
for (PatchSet ps : psUtil.byChange(ctx.getNotes())) {
- if (!toDelete.contains(ps.getId())) {
- all.add(ps.getId());
+ if (!toDelete.contains(ps.id())) {
+ all.add(ps.id());
}
}
if (all.isEmpty()) {
diff --git a/java/com/google/gerrit/server/change/DeleteChangeOp.java b/java/com/google/gerrit/server/change/DeleteChangeOp.java
index 6319a08..2449df2 100644
--- a/java/com/google/gerrit/server/change/DeleteChangeOp.java
+++ b/java/com/google/gerrit/server/change/DeleteChangeOp.java
@@ -70,7 +70,7 @@
ensureDeletable(ctx, id, patchSets);
// Cleaning up is only possible as long as the change and its elements are
// still part of the database.
- cleanUpReferences(id, patchSets);
+ cleanUpReferences(id);
ctx.deleteChange();
changeDeleted.fire(ctx.getChange(), ctx.getAccount(), ctx.getWhen());
@@ -86,8 +86,7 @@
if (isPatchSetMerged(ctx, patchSet)) {
throw new ResourceConflictException(
String.format(
- "Cannot delete change %s: patch set %s is already merged",
- id, patchSet.getPatchSetId()));
+ "Cannot delete change %s: patch set %s is already merged", id, patchSet.number()));
}
}
}
@@ -100,13 +99,11 @@
RevWalk revWalk = ctx.getRevWalk();
return revWalk.isMergedInto(
- revWalk.parseCommit(patchSet.getCommitId()), revWalk.parseCommit(destId.get()));
+ revWalk.parseCommit(patchSet.commitId()), revWalk.parseCommit(destId.get()));
}
- private void cleanUpReferences(Change.Id id, Collection<PatchSet> patchSets) throws IOException {
- for (PatchSet ps : patchSets) {
- accountPatchReviewStore.run(s -> s.clearReviewed(ps.getId()));
- }
+ private void cleanUpReferences(Change.Id id) throws IOException {
+ accountPatchReviewStore.run(s -> s.clearReviewed(id));
// Non-atomic operation on All-Users refs; not much we can do to make it atomic.
starredChangesUtil.unstarAllForChangeDeletion(id);
diff --git a/java/com/google/gerrit/server/change/DeleteReviewerOp.java b/java/com/google/gerrit/server/change/DeleteReviewerOp.java
index 29458a8..de5c4bd 100644
--- a/java/com/google/gerrit/server/change/DeleteReviewerOp.java
+++ b/java/com/google/gerrit/server/change/DeleteReviewerOp.java
@@ -28,7 +28,7 @@
import com.google.gerrit.reviewdb.client.ChangeMessage;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
-import com.google.gerrit.reviewdb.client.Project.NameKey;
+import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.IdentifiedUser;
@@ -134,14 +134,14 @@
// Check if removing this vote is OK
removeReviewerControl.checkRemoveReviewer(ctx.getNotes(), ctx.getUser(), a);
del.add(a);
- if (a.getPatchSetId().equals(currPs.getId()) && a.getValue() != 0) {
- oldApprovals.put(a.getLabel(), a.getValue());
+ if (a.patchSetId().equals(currPs.id()) && a.value() != 0) {
+ oldApprovals.put(a.label(), a.value());
removedVotesMsg
.append("* ")
- .append(a.getLabel())
- .append(formatLabelValue(a.getValue()))
+ .append(a.label())
+ .append(formatLabelValue(a.value()))
.append(" by ")
- .append(userFactory.create(a.getAccountId()).getNameEmail())
+ .append(userFactory.create(a.accountId()).getNameEmail())
.append("\n");
votesRemoved = true;
}
@@ -152,7 +152,7 @@
} else {
msg.append(".");
}
- ChangeUpdate update = ctx.getUpdate(currPs.getId());
+ ChangeUpdate update = ctx.getUpdate(currPs.id());
update.removeReviewer(reviewerId);
changeMessage =
@@ -195,7 +195,7 @@
private Iterable<PatchSetApproval> approvals(ChangeContext ctx, Account.Id accountId) {
Iterable<PatchSetApproval> approvals;
approvals = approvalsUtil.byChange(ctx.getNotes()).values();
- return Iterables.filter(approvals, psa -> accountId.equals(psa.getAccountId()));
+ return Iterables.filter(approvals, psa -> accountId.equals(psa.accountId()));
}
private String formatLabelValue(short value) {
@@ -206,7 +206,10 @@
}
private void emailReviewers(
- NameKey projectName, Change change, ChangeMessage changeMessage, NotifyResolver.Result notify)
+ Project.NameKey projectName,
+ Change change,
+ ChangeMessage changeMessage,
+ NotifyResolver.Result notify)
throws EmailException {
Account.Id userId = user.get().getAccountId();
if (userId.equals(reviewer.getAccount().getId())) {
diff --git a/java/com/google/gerrit/server/change/EmailReviewComments.java b/java/com/google/gerrit/server/change/EmailReviewComments.java
index 8353501..c6bcd81 100644
--- a/java/com/google/gerrit/server/change/EmailReviewComments.java
+++ b/java/com/google/gerrit/server/change/EmailReviewComments.java
@@ -129,7 +129,7 @@
cm.setNotify(notify);
cm.send();
} catch (Exception e) {
- logger.atSevere().withCause(e).log("Cannot email comments for %s", patchSet.getId());
+ logger.atSevere().withCause(e).log("Cannot email comments for %s", patchSet.id());
} finally {
requestContext.setContext(old);
}
diff --git a/java/com/google/gerrit/server/change/FileInfoJson.java b/java/com/google/gerrit/server/change/FileInfoJson.java
index 1416358..8e7f8ea 100644
--- a/java/com/google/gerrit/server/change/FileInfoJson.java
+++ b/java/com/google/gerrit/server/change/FileInfoJson.java
@@ -43,13 +43,13 @@
public Map<String, FileInfo> toFileInfoMap(Change change, PatchSet patchSet)
throws PatchListNotAvailableException {
- return toFileInfoMap(change, patchSet.getCommitId(), null);
+ return toFileInfoMap(change, patchSet.commitId(), null);
}
public Map<String, FileInfo> toFileInfoMap(
Change change, ObjectId objectId, @Nullable PatchSet base)
throws PatchListNotAvailableException {
- ObjectId a = base != null ? base.getCommitId() : null;
+ ObjectId a = base != null ? base.commitId() : null;
return toFileInfoMap(change, PatchListKey.againstCommit(a, objectId, Whitespace.IGNORE_NONE));
}
diff --git a/java/com/google/gerrit/server/change/FileResource.java b/java/com/google/gerrit/server/change/FileResource.java
index 6843643..ba724ec 100644
--- a/java/com/google/gerrit/server/change/FileResource.java
+++ b/java/com/google/gerrit/server/change/FileResource.java
@@ -29,7 +29,7 @@
public FileResource(RevisionResource rev, String name) {
this.rev = rev;
- this.key = Patch.key(rev.getPatchSet().getId(), name);
+ this.key = Patch.key(rev.getPatchSet().id(), name);
}
public Patch.Key getPatchKey() {
diff --git a/java/com/google/gerrit/server/change/LabelNormalizer.java b/java/com/google/gerrit/server/change/LabelNormalizer.java
index 63c9165..2a48c3b 100644
--- a/java/com/google/gerrit/server/change/LabelNormalizer.java
+++ b/java/com/google/gerrit/server/change/LabelNormalizer.java
@@ -88,24 +88,23 @@
List<PatchSetApproval> deleted = Lists.newArrayListWithCapacity(approvals.size());
LabelTypes labelTypes = projectCache.checkedGet(notes.getProjectName()).getLabelTypes(notes);
for (PatchSetApproval psa : approvals) {
- Change.Id changeId = psa.getKey().patchSetId().changeId();
+ Change.Id changeId = psa.key().patchSetId().changeId();
checkArgument(
changeId.equals(notes.getChangeId()),
"Approval %s does not match change %s",
- psa.getKey(),
+ psa.key(),
notes.getChange().getKey());
if (psa.isLegacySubmit()) {
unchanged.add(psa);
continue;
}
- LabelType label = labelTypes.byLabel(psa.getLabelId());
+ LabelType label = labelTypes.byLabel(psa.labelId());
if (label == null) {
deleted.add(psa);
continue;
}
- PatchSetApproval copy = copy(psa);
- applyTypeFloor(label, copy);
- if (copy.getValue() != psa.getValue()) {
+ PatchSetApproval copy = applyTypeFloor(label, psa);
+ if (copy.value() != psa.value()) {
updated.add(copy);
} else {
unchanged.add(psa);
@@ -114,18 +113,16 @@
return Result.create(unchanged, updated, deleted);
}
- private PatchSetApproval copy(PatchSetApproval src) {
- return new PatchSetApproval(src.getPatchSetId(), src);
- }
-
- private void applyTypeFloor(LabelType lt, PatchSetApproval a) {
+ private PatchSetApproval applyTypeFloor(LabelType lt, PatchSetApproval a) {
+ PatchSetApproval.Builder b = a.toBuilder();
LabelValue atMin = lt.getMin();
- if (atMin != null && a.getValue() < atMin.getValue()) {
- a.setValue(atMin.getValue());
+ if (atMin != null && a.value() < atMin.getValue()) {
+ b.value(atMin.getValue());
}
LabelValue atMax = lt.getMax();
- if (atMax != null && a.getValue() > atMax.getValue()) {
- a.setValue(atMax.getValue());
+ if (atMax != null && a.value() > atMax.getValue()) {
+ b.value(atMax.getValue());
}
+ return b.build();
}
}
diff --git a/java/com/google/gerrit/server/change/LabelsJson.java b/java/com/google/gerrit/server/change/LabelsJson.java
index 6fde5a5..dd9e08b 100644
--- a/java/com/google/gerrit/server/change/LabelsJson.java
+++ b/java/com/google/gerrit/server/change/LabelsJson.java
@@ -206,8 +206,8 @@
if (standard) {
for (PatchSetApproval psa : cd.currentApprovals()) {
if (type.matches(psa)) {
- short val = psa.getValue();
- Account.Id accountId = psa.getAccountId();
+ short val = psa.value();
+ Account.Id accountId = psa.accountId();
setLabelScores(accountLoader, type, e.getValue(), val, accountId);
}
}
@@ -260,7 +260,7 @@
accountId,
null,
null)) {
- result.put(psa.getLabel(), psa.getValue());
+ result.put(psa.label(), psa.value());
}
return result;
}
@@ -279,7 +279,7 @@
// we aren't including 0 votes for all users below, so we can just look at
// the latest patch set (in the next loop).
for (PatchSetApproval psa : cd.approvals().values()) {
- allUsers.add(psa.getAccountId());
+ allUsers.add(psa.accountId());
}
}
@@ -287,13 +287,13 @@
SetMultimap<Account.Id, PatchSetApproval> current =
MultimapBuilder.hashKeys().hashSetValues().build();
for (PatchSetApproval a : cd.currentApprovals()) {
- allUsers.add(a.getAccountId());
- LabelType type = labelTypes.byLabel(a.getLabelId());
+ allUsers.add(a.accountId());
+ LabelType type = labelTypes.byLabel(a.labelId());
if (type != null) {
labelNames.add(type.getName());
// Not worth the effort to distinguish between votable/non-votable for 0
// values on closed changes, since they can't vote anyway.
- current.put(a.getAccountId(), a);
+ current.put(a.accountId(), a);
}
}
@@ -335,19 +335,19 @@
}
}
for (PatchSetApproval psa : current.get(accountId)) {
- LabelType type = labelTypes.byLabel(psa.getLabelId());
+ LabelType type = labelTypes.byLabel(psa.labelId());
if (type == null) {
continue;
}
- short val = psa.getValue();
+ short val = psa.value();
ApprovalInfo info = byLabel.get(type.getName());
if (info != null) {
info.value = Integer.valueOf(val);
info.permittedVotingRange = pvr.getOrDefault(type.getName(), null);
- info.date = psa.getGranted();
- info.tag = psa.getTag();
- if (psa.isPostSubmit()) {
+ info.date = psa.granted();
+ info.tag = psa.tag().orElse(null);
+ if (psa.postSubmit()) {
info.postSubmit = true;
}
}
@@ -441,13 +441,13 @@
Set<Account.Id> allUsers = new HashSet<>();
allUsers.addAll(cd.reviewers().byState(ReviewerStateInternal.REVIEWER));
for (PatchSetApproval psa : cd.approvals().values()) {
- allUsers.add(psa.getAccountId());
+ allUsers.add(psa.accountId());
}
Table<Account.Id, String, PatchSetApproval> current =
HashBasedTable.create(allUsers.size(), cd.getLabelTypes().getLabelTypes().size());
for (PatchSetApproval psa : cd.currentApprovals()) {
- current.put(psa.getAccountId(), psa.getLabel(), psa);
+ current.put(psa.accountId(), psa.label(), psa);
}
LabelTypes labelTypes = cd.getLabelTypes();
@@ -467,16 +467,16 @@
Timestamp date = null;
PatchSetApproval psa = current.get(accountId, lt.getName());
if (psa != null) {
- value = Integer.valueOf(psa.getValue());
+ value = Integer.valueOf(psa.value());
if (value == 0) {
// This may be a dummy approval that was inserted when the reviewer
// was added. Explicitly check whether the user can vote on this
// label.
value = perm.test(new LabelPermission(lt)) ? 0 : null;
}
- tag = psa.getTag();
- date = psa.getGranted();
- if (psa.isPostSubmit()) {
+ tag = psa.tag().orElse(null);
+ date = psa.granted();
+ if (psa.postSubmit()) {
logger.atWarning().log("unexpected post-submit approval on open change: %s", psa);
}
} else {
diff --git a/java/com/google/gerrit/server/change/PatchSetInserter.java b/java/com/google/gerrit/server/change/PatchSetInserter.java
index 11dc4e3..fecc099 100644
--- a/java/com/google/gerrit/server/change/PatchSetInserter.java
+++ b/java/com/google/gerrit/server/change/PatchSetInserter.java
@@ -208,7 +208,7 @@
if (newGroups.isEmpty()) {
PatchSet prevPs = psUtil.current(ctx.getNotes());
if (prevPs != null) {
- newGroups = prevPs.getGroups();
+ newGroups = prevPs.groups();
}
}
patchSet =
@@ -222,7 +222,7 @@
if (message != null) {
changeMessage =
ChangeMessagesUtil.newMessage(
- patchSet.getId(),
+ patchSet.id(),
ctx.getUser(),
ctx.getWhen(),
message,
diff --git a/java/com/google/gerrit/server/change/PureRevert.java b/java/com/google/gerrit/server/change/PureRevert.java
index 56ec648..63146fa 100644
--- a/java/com/google/gerrit/server/change/PureRevert.java
+++ b/java/com/google/gerrit/server/change/PureRevert.java
@@ -54,6 +54,6 @@
}
return pureRevertCache.isPureRevert(
- notes.getProjectName(), notes.getCurrentPatchSet().getCommitId(), claimedOriginalObjectId);
+ notes.getProjectName(), notes.getCurrentPatchSet().commitId(), claimedOriginalObjectId);
}
}
diff --git a/java/com/google/gerrit/server/change/RebaseChangeOp.java b/java/com/google/gerrit/server/change/RebaseChangeOp.java
index 7c51446..688d349 100644
--- a/java/com/google/gerrit/server/change/RebaseChangeOp.java
+++ b/java/com/google/gerrit/server/change/RebaseChangeOp.java
@@ -151,7 +151,7 @@
// Ok that originalPatchSet was not read in a transaction, since we just
// need its revision.
RevWalk rw = ctx.getRevWalk();
- RevCommit original = rw.parseCommit(originalPatchSet.getCommitId());
+ RevCommit original = rw.parseCommit(originalPatchSet.commitId());
rw.parseBody(original);
RevCommit baseCommit = rw.parseCommit(baseCommitId);
CurrentUser changeOwner = identifiedUserFactory.create(notes.getChange().getOwner());
@@ -161,7 +161,7 @@
rw.parseBody(baseCommit);
newCommitMessage =
newMergeUtil()
- .createCommitMessageOnSubmit(original, baseCommit, notes, originalPatchSet.getId());
+ .createCommitMessageOnSubmit(original, baseCommit, notes, originalPatchSet.id());
} else {
newCommitMessage = original.getFullMessage();
}
@@ -175,7 +175,7 @@
rebasedPatchSetId =
ChangeUtil.nextPatchSetIdFromChangeRefs(
- ctx.getRepoView().getRefs(originalPatchSet.getId().changeId().toRefPrefix()).keySet(),
+ ctx.getRepoView().getRefs(originalPatchSet.id().changeId().toRefPrefix()).keySet(),
notes.getChange().currentPatchSetId());
patchSetInserter =
patchSetInserterFactory
@@ -190,14 +190,14 @@
"Patch Set "
+ rebasedPatchSetId.get()
+ ": Patch Set "
- + originalPatchSet.getId().get()
+ + originalPatchSet.id().get()
+ " was rebased");
}
if (base != null && !base.notes().getChange().isMerged()) {
if (!base.notes().getChange().isMerged()) {
// Add to end of relation chain for open base change.
- patchSetInserter.setGroups(base.patchSet().getGroups());
+ patchSetInserter.setGroups(base.patchSet().groups());
} else {
// If the base is merged, start a new relation chain.
patchSetInserter.setGroups(GroupCollector.getDefaultGroups(rebasedCommit));
diff --git a/java/com/google/gerrit/server/change/RebaseUtil.java b/java/com/google/gerrit/server/change/RebaseUtil.java
index 8e01b15..731648c 100644
--- a/java/com/google/gerrit/server/change/RebaseUtil.java
+++ b/java/com/google/gerrit/server/change/RebaseUtil.java
@@ -64,7 +64,7 @@
return false;
} catch (StorageException | IOException e) {
logger.atWarning().withCause(e).log(
- "Error checking if patch set %s on %s can be rebased", patchSet.getId(), dest);
+ "Error checking if patch set %s on %s can be rebased", patchSet.id(), dest);
return false;
}
}
@@ -108,10 +108,10 @@
Base ret = null;
for (ChangeData cd : queryProvider.get().byProjectCommit(rsrc.getProject(), base)) {
for (PatchSet ps : cd.patchSets()) {
- if (!ObjectIds.matchesAbbreviation(ps.getCommitId(), base)) {
+ if (!ObjectIds.matchesAbbreviation(ps.commitId(), base)) {
continue;
}
- if (ret == null || ret.patchSet().getId().get() < ps.getId().get()) {
+ if (ret == null || ret.patchSet().id().get() < ps.id().get()) {
ret = Base.create(cd.notes(), ps);
}
}
@@ -144,7 +144,7 @@
PatchSet patchSet, BranchNameKey destBranch, Repository git, RevWalk rw)
throws RestApiException, IOException {
ObjectId baseId = null;
- RevCommit commit = rw.parseCommit(patchSet.getCommitId());
+ RevCommit commit = rw.parseCommit(patchSet.commitId());
if (commit.getParentCount() > 1) {
throw new UnprocessableEntityException("Cannot rebase a change with multiple parents.");
@@ -158,7 +158,7 @@
CHANGES:
for (ChangeData cd : queryProvider.get().byBranchCommit(destBranch, parentId.name())) {
for (PatchSet depPatchSet : cd.patchSets()) {
- if (!depPatchSet.getCommitId().equals(parentId)) {
+ if (!depPatchSet.commitId().equals(parentId)) {
continue;
}
Change depChange = cd.change();
@@ -168,11 +168,11 @@
}
if (depChange.isNew()) {
- if (depPatchSet.getId().equals(depChange.currentPatchSetId())) {
+ if (depPatchSet.id().equals(depChange.currentPatchSetId())) {
throw new ResourceConflictException(
"Change is already based on the latest patch set of the dependent change.");
}
- baseId = cd.currentPatchSet().getCommitId();
+ baseId = cd.currentPatchSet().commitId();
}
break CHANGES;
}
diff --git a/java/com/google/gerrit/server/change/ReviewerAdder.java b/java/com/google/gerrit/server/change/ReviewerAdder.java
index 6802c89..95cd5f1 100644
--- a/java/com/google/gerrit/server/change/ReviewerAdder.java
+++ b/java/com/google/gerrit/server/change/ReviewerAdder.java
@@ -469,8 +469,8 @@
// New reviewers have value 0, don't bother normalizing.
result.reviewers.add(
json.format(
- new ReviewerInfo(psa.getAccountId().get()),
- psa.getAccountId(),
+ new ReviewerInfo(psa.accountId().get()),
+ psa.accountId(),
cd,
ImmutableList.of(psa)));
}
diff --git a/java/com/google/gerrit/server/change/ReviewerJson.java b/java/com/google/gerrit/server/change/ReviewerJson.java
index 2742bb9..93582f9 100644
--- a/java/com/google/gerrit/server/change/ReviewerJson.java
+++ b/java/com/google/gerrit/server/change/ReviewerJson.java
@@ -111,9 +111,9 @@
out.approvals = new TreeMap<>(labelTypes.nameComparator());
for (PatchSetApproval ca : approvals) {
- LabelType at = labelTypes.byLabel(ca.getLabelId());
+ LabelType at = labelTypes.byLabel(ca.labelId());
if (at != null) {
- out.approvals.put(at.getName(), formatValue(ca.getValue()));
+ out.approvals.put(at.getName(), formatValue(ca.value()));
}
}
diff --git a/java/com/google/gerrit/server/change/RevisionJson.java b/java/com/google/gerrit/server/change/RevisionJson.java
index b9c9259..f30b321 100644
--- a/java/com/google/gerrit/server/change/RevisionJson.java
+++ b/java/com/google/gerrit/server/change/RevisionJson.java
@@ -28,6 +28,7 @@
import static com.google.gerrit.extensions.client.ListChangesOption.WEB_LINKS;
import static com.google.gerrit.server.CommonConverters.toGitPerson;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.flogger.FluentLogger;
@@ -71,7 +72,6 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.eclipse.jgit.lib.ObjectId;
@@ -182,7 +182,7 @@
info.message = commit.getFullMessage();
if (addLinks) {
- List<WebLinkInfo> links = webLinks.getPatchSetLinks(project, commit.name());
+ ImmutableList<WebLinkInfo> links = webLinks.getPatchSetLinks(project, commit.name());
info.webLinks = links.isEmpty() ? null : links;
}
@@ -192,7 +192,7 @@
i.commit = parent.name();
i.subject = parent.getShortMessage();
if (addLinks) {
- List<WebLinkInfo> parentLinks = webLinks.getParentLinks(project, parent.name());
+ ImmutableList<WebLinkInfo> parentLinks = webLinks.getParentLinks(project, parent.name());
i.webLinks = parentLinks.isEmpty() ? null : parentLinks;
}
info.parents.add(i);
@@ -216,7 +216,7 @@
try (Repository repo = openRepoIfNecessary(cd.project());
RevWalk rw = newRevWalk(repo)) {
for (PatchSet in : map.values()) {
- PatchSet.Id id = in.getId();
+ PatchSet.Id id = in.id();
boolean want;
if (has(ALL_REVISIONS)) {
want = true;
@@ -227,7 +227,7 @@
}
if (want) {
res.put(
- in.getCommitId().name(),
+ in.commitId().name(),
toRevisionInfo(accountLoader, cd, in, repo, rw, false, changeInfo));
}
}
@@ -251,7 +251,7 @@
String projectName = cd.project().get();
String url = scheme.getUrl(projectName);
- String refName = in.getRefName();
+ String refName = in.refName();
FetchInfo fetchInfo = new FetchInfo(url, refName);
r.put(schemeName, fetchInfo);
@@ -275,14 +275,14 @@
throws PatchListNotAvailableException, GpgException, IOException, PermissionBackendException {
Change c = cd.change();
RevisionInfo out = new RevisionInfo();
- out.isCurrent = in.getId().equals(c.currentPatchSetId());
- out._number = in.getId().get();
- out.ref = in.getRefName();
- out.created = in.getCreatedOn();
- out.uploader = accountLoader.get(in.getUploader());
+ out.isCurrent = in.id().equals(c.currentPatchSetId());
+ out._number = in.id().get();
+ out.ref = in.refName();
+ out.created = in.createdOn();
+ out.uploader = accountLoader.get(in.uploader());
out.fetch = makeFetchMap(cd, in);
out.kind = changeKindCache.getChangeKind(rw, repo != null ? repo.getConfig() : null, cd, in);
- out.description = in.getDescription();
+ out.description = in.description().orElse(null);
boolean setCommit = has(ALL_COMMITS) || (out.isCurrent && has(CURRENT_COMMIT));
boolean addFooters = out.isCurrent && has(COMMIT_FOOTERS);
@@ -290,7 +290,7 @@
checkState(rw != null);
checkState(repo != null);
Project.NameKey project = c.getProject();
- String rev = in.getCommitId().name();
+ String rev = in.commitId().name();
RevCommit commit = rw.parseCommit(ObjectId.fromString(rev));
rw.parseBody(commit);
if (setCommit) {
@@ -306,7 +306,7 @@
out.commitWithFooters =
mergeUtilFactory
.create(projectCache.get(project))
- .createCommitMessageOnSubmit(commit, mergeTip, cd.notes(), in.getId());
+ .createCommitMessageOnSubmit(commit, mergeTip, cd.notes(), in.id());
}
}
@@ -324,10 +324,10 @@
}
if (gpgApi.isEnabled() && has(PUSH_CERTIFICATES)) {
- if (in.getPushCertificate() != null) {
+ if (in.pushCertificate().isPresent()) {
out.pushCertificate =
gpgApi.checkPushCertificate(
- in.getPushCertificate(), userFactory.create(in.getUploader()));
+ in.pushCertificate().get(), userFactory.create(in.uploader()));
} else {
out.pushCertificate = new PushCertificateInfo();
}
diff --git a/java/com/google/gerrit/server/change/RevisionResource.java b/java/com/google/gerrit/server/change/RevisionResource.java
index caafe24..efd9d2d 100644
--- a/java/com/google/gerrit/server/change/RevisionResource.java
+++ b/java/com/google/gerrit/server/change/RevisionResource.java
@@ -114,7 +114,7 @@
@Override
public String toString() {
- String s = ps.getId().toString();
+ String s = ps.id().toString();
if (edit.isPresent()) {
s = "edit:" + s;
}
@@ -122,6 +122,6 @@
}
public boolean isCurrent() {
- return ps.getId().equals(getChange().currentPatchSetId());
+ return ps.id().equals(getChange().currentPatchSetId());
}
}
diff --git a/java/com/google/gerrit/server/change/WalkSorter.java b/java/com/google/gerrit/server/change/WalkSorter.java
index dc8e3b5..056312c 100644
--- a/java/com/google/gerrit/server/change/WalkSorter.java
+++ b/java/com/google/gerrit/server/change/WalkSorter.java
@@ -222,7 +222,7 @@
for (ChangeData cd : in) {
PatchSet maxPs = null;
for (PatchSet ps : cd.patchSets()) {
- if (shouldInclude(ps) && (maxPs == null || ps.getId().get() > maxPs.getId().get())) {
+ if (shouldInclude(ps) && (maxPs == null || ps.id().get() > maxPs.id().get())) {
maxPs = ps;
}
}
@@ -230,18 +230,18 @@
continue; // No patch sets matched.
}
try {
- RevCommit c = rw.parseCommit(maxPs.getCommitId());
+ RevCommit c = rw.parseCommit(maxPs.commitId());
byCommit.put(c, PatchSetData.create(cd, maxPs, c));
} catch (MissingObjectException | IncorrectObjectTypeException e) {
logger.atWarning().withCause(e).log(
- "missing commit %s for patch set %s", maxPs.getCommitId().name(), maxPs.getId());
+ "missing commit %s for patch set %s", maxPs.commitId().name(), maxPs.id());
}
}
return byCommit;
}
private boolean shouldInclude(PatchSet ps) {
- return includePatchSets.isEmpty() || includePatchSets.contains(ps.getId());
+ return includePatchSets.isEmpty() || includePatchSets.contains(ps.id());
}
private static void markStart(RevWalk rw, Iterable<RevCommit> commits) throws IOException {
diff --git a/java/com/google/gerrit/server/config/SitePaths.java b/java/com/google/gerrit/server/config/SitePaths.java
index 47b6336..ee95c6f 100644
--- a/java/com/google/gerrit/server/config/SitePaths.java
+++ b/java/com/google/gerrit/server/config/SitePaths.java
@@ -54,6 +54,8 @@
public final Path secure_config;
public final Path notedb_config;
+ public final Path jgit_config;
+
public final Path ssl_keystore;
public final Path ssh_key;
public final Path ssh_rsa;
@@ -99,6 +101,8 @@
secure_config = etc_dir.resolve("secure.config");
notedb_config = etc_dir.resolve("notedb.config");
+ jgit_config = etc_dir.resolve("jgit.config");
+
ssl_keystore = etc_dir.resolve("keystore");
ssh_key = etc_dir.resolve("ssh_host_key");
ssh_rsa = etc_dir.resolve("ssh_host_rsa_key");
diff --git a/java/com/google/gerrit/server/edit/ChangeEditJson.java b/java/com/google/gerrit/server/edit/ChangeEditJson.java
index f297e5e..25dcae0 100644
--- a/java/com/google/gerrit/server/edit/ChangeEditJson.java
+++ b/java/com/google/gerrit/server/edit/ChangeEditJson.java
@@ -51,8 +51,8 @@
public EditInfo toEditInfo(ChangeEdit edit, boolean downloadCommands) {
EditInfo out = new EditInfo();
out.commit = fillCommit(edit.getEditCommit());
- out.baseRevision = edit.getBasePatchSet().getCommitId().name();
- out.basePatchSetNumber = edit.getBasePatchSet().getPatchSetId();
+ out.baseRevision = edit.getBasePatchSet().commitId().name();
+ out.basePatchSetNumber = edit.getBasePatchSet().number();
out.ref = edit.getRefName();
if (downloadCommands) {
out.fetch = fillFetchMap(edit);
diff --git a/java/com/google/gerrit/server/edit/ChangeEditModifier.java b/java/com/google/gerrit/server/edit/ChangeEditModifier.java
index 2815674..fcd38c3 100644
--- a/java/com/google/gerrit/server/edit/ChangeEditModifier.java
+++ b/java/com/google/gerrit/server/edit/ChangeEditModifier.java
@@ -124,7 +124,7 @@
}
PatchSet currentPatchSet = lookupCurrentPatchSet(notes);
- ObjectId patchSetCommitId = currentPatchSet.getCommitId();
+ ObjectId patchSetCommitId = currentPatchSet.commitId();
createEdit(repository, notes, currentPatchSet, patchSetCommitId, TimeUtil.nowTs());
}
@@ -157,7 +157,7 @@
throw new InvalidChangeOperationException(
String.format(
"Change edit for change %s is already based on latest patch set %s",
- notes.getChangeId(), currentPatchSet.getId()));
+ notes.getChangeId(), currentPatchSet.id()));
}
rebase(repository, changeEdit, currentPatchSet);
@@ -421,10 +421,10 @@
String.format(
"Only the patch set %s on which the existing change edit is based may be modified "
+ "(specified patch set: %s)",
- changeEdit.getBasePatchSet().getId(), patchSet.getId()));
+ changeEdit.getBasePatchSet().id(), patchSet.id()));
}
} else {
- PatchSet.Id patchSetId = patchSet.getId();
+ PatchSet.Id patchSetId = patchSet.id();
PatchSet.Id currentPatchSetId = notes.getChange().currentPatchSetId();
if (!patchSetId.equals(currentPatchSetId)) {
throw new InvalidChangeOperationException(
@@ -451,12 +451,12 @@
private static boolean isBasedOn(ChangeEdit changeEdit, PatchSet patchSet) {
PatchSet editBasePatchSet = changeEdit.getBasePatchSet();
- return editBasePatchSet.getId().equals(patchSet.getId());
+ return editBasePatchSet.id().equals(patchSet.id());
}
private static RevCommit lookupCommit(Repository repository, PatchSet patchSet)
throws IOException {
- ObjectId patchSetCommitId = patchSet.getCommitId();
+ ObjectId patchSetCommitId = patchSet.commitId();
return lookupCommit(repository, patchSetCommitId);
}
@@ -483,7 +483,7 @@
private static ObjectId merge(Repository repository, ChangeEdit changeEdit, ObjectId newTreeId)
throws IOException, MergeConflictException {
PatchSet basePatchSet = changeEdit.getBasePatchSet();
- ObjectId basePatchSetCommitId = basePatchSet.getCommitId();
+ ObjectId basePatchSetCommitId = basePatchSet.commitId();
ObjectId editCommitId = changeEdit.getEditCommit();
ThreeWayMerger threeWayMerger = MergeStrategy.RESOLVE.newMerger(repository, true);
@@ -540,7 +540,7 @@
private String getEditRefName(Change change, PatchSet basePatchSet) {
IdentifiedUser me = currentUser.get().asIdentifiedUser();
- return RefNames.refsEdit(me.getAccountId(), change.getId(), basePatchSet.getId());
+ return RefNames.refsEdit(me.getAccountId(), change.getId(), basePatchSet.id());
}
private ChangeEdit updateEdit(
diff --git a/java/com/google/gerrit/server/edit/ChangeEditUtil.java b/java/com/google/gerrit/server/edit/ChangeEditUtil.java
index e50779e..1af8148 100644
--- a/java/com/google/gerrit/server/edit/ChangeEditUtil.java
+++ b/java/com/google/gerrit/server/edit/ChangeEditUtil.java
@@ -162,7 +162,7 @@
ObjectReader reader = oi.newReader();
RevWalk rw = new RevWalk(reader)) {
PatchSet basePatchSet = edit.getBasePatchSet();
- if (!basePatchSet.getId().equals(change.currentPatchSetId())) {
+ if (!basePatchSet.id().equals(change.currentPatchSetId())) {
throw new ResourceConflictException("only edit for current patch set can be published");
}
@@ -174,17 +174,14 @@
new StringBuilder("Patch Set ").append(inserter.getPatchSetId().get()).append(": ");
// Previously checked that the base patch set is the current patch set.
- ObjectId prior = basePatchSet.getCommitId();
+ ObjectId prior = basePatchSet.commitId();
ChangeKind kind =
changeKindCache.getChangeKind(change.getProject(), rw, repo.getConfig(), prior, squashed);
if (kind == ChangeKind.NO_CODE_CHANGE) {
message.append("Commit message was updated.");
inserter.setDescription("Edit commit message");
} else {
- message
- .append("Published edit on patch set ")
- .append(basePatchSet.getPatchSetId())
- .append(".");
+ message.append("Published edit on patch set ").append(basePatchSet.number()).append(".");
}
try (BatchUpdate bu = updateFactory.create(change.getProject(), user, TimeUtil.nowTs())) {
@@ -232,7 +229,7 @@
private RevCommit squashEdit(
RevWalk rw, ObjectInserter inserter, RevCommit edit, PatchSet basePatchSet)
throws IOException, ResourceConflictException {
- RevCommit parent = rw.parseCommit(basePatchSet.getCommitId());
+ RevCommit parent = rw.parseCommit(basePatchSet.commitId());
if (parent.getTree().equals(edit.getTree())
&& edit.getFullMessage().equals(parent.getFullMessage())) {
throw new ResourceConflictException("identical tree and message");
diff --git a/java/com/google/gerrit/server/events/EventBroker.java b/java/com/google/gerrit/server/events/EventBroker.java
index f5af8ac..423f5af 100644
--- a/java/com/google/gerrit/server/events/EventBroker.java
+++ b/java/com/google/gerrit/server/events/EventBroker.java
@@ -21,7 +21,6 @@
import com.google.gerrit.reviewdb.client.BranchNameKey;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.reviewdb.client.PatchSet.Id;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.notedb.ChangeNotes;
@@ -198,7 +197,7 @@
RefEvent refEvent = (RefEvent) event;
String ref = refEvent.getRefName();
if (PatchSet.isChangeRef(ref)) {
- Change.Id cid = Id.fromRef(ref).changeId();
+ Change.Id cid = PatchSet.Id.fromRef(ref).changeId();
try {
Change change = notesFactory.createChecked(refEvent.getProjectNameKey(), cid).getChange();
return isVisibleTo(change, user);
diff --git a/java/com/google/gerrit/server/events/EventFactory.java b/java/com/google/gerrit/server/events/EventFactory.java
index 1385db5..b57dacb 100644
--- a/java/com/google/gerrit/server/events/EventFactory.java
+++ b/java/com/google/gerrit/server/events/EventFactory.java
@@ -285,7 +285,7 @@
private void addDependsOn(RevWalk rw, ChangeAttribute ca, Change change, PatchSet currentPs)
throws IOException {
- RevCommit commit = rw.parseCommit(currentPs.getCommitId());
+ RevCommit commit = rw.parseCommit(currentPs.commitId());
final List<String> parentNames = new ArrayList<>(commit.getParentCount());
for (RevCommit p : commit.getParents()) {
parentNames.add(p.name());
@@ -296,7 +296,7 @@
for (ChangeData cd : queryProvider.get().byProjectCommits(change.getProject(), parentNames)) {
for (PatchSet ps : cd.patchSets()) {
for (String p : parentNames) {
- if (!ps.getCommitId().name().equals(p)) {
+ if (!ps.commitId().name().equals(p)) {
continue;
}
ca.dependsOn.add(newDependsOn(requireNonNull(cd.change()), ps));
@@ -318,18 +318,18 @@
private void addNeededBy(RevWalk rw, ChangeAttribute ca, Change change, PatchSet currentPs)
throws IOException {
- if (currentPs.getGroups().isEmpty()) {
+ if (currentPs.groups().isEmpty()) {
return;
}
- String rev = currentPs.getCommitId().name();
+ String rev = currentPs.commitId().name();
// Find changes in the same related group as this patch set, having a patch
// set whose parent matches this patch set's revision.
for (ChangeData cd :
InternalChangeQuery.byProjectGroups(
- queryProvider, indexConfig, change.getProject(), currentPs.getGroups())) {
+ queryProvider, indexConfig, change.getProject(), currentPs.groups())) {
PATCH_SETS:
for (PatchSet ps : cd.patchSets()) {
- RevCommit commit = rw.parseCommit(ps.getCommitId());
+ RevCommit commit = rw.parseCommit(ps.commitId());
for (RevCommit p : commit.getParents()) {
if (!p.name().equals(rev)) {
continue;
@@ -343,7 +343,7 @@
private DependencyAttribute newDependsOn(Change c, PatchSet ps) {
DependencyAttribute d = newDependencyAttribute(c, ps);
- d.isCurrentPatchSet = ps.getId().equals(c.currentPatchSetId());
+ d.isCurrentPatchSet = ps.id().equals(c.currentPatchSetId());
return d;
}
@@ -355,8 +355,8 @@
DependencyAttribute d = new DependencyAttribute();
d.number = c.getId().get();
d.id = c.getKey().toString();
- d.revision = ps.getCommitId().name();
- d.ref = ps.getRefName();
+ d.revision = ps.commitId().name();
+ d.ref = ps.refName();
return d;
}
@@ -400,7 +400,7 @@
for (PatchSet p : ps) {
PatchSetAttribute psa = asPatchSetAttribute(revWalk, change, p);
if (approvals != null) {
- addApprovals(psa, p.getId(), approvals, labelTypes);
+ addApprovals(psa, p.id(), approvals, labelTypes);
}
ca.patchSets.add(psa);
if (includeFiles) {
@@ -463,12 +463,12 @@
*/
public PatchSetAttribute asPatchSetAttribute(RevWalk revWalk, Change change, PatchSet patchSet) {
PatchSetAttribute p = new PatchSetAttribute();
- p.revision = patchSet.getCommitId().name();
- p.number = patchSet.getPatchSetId();
- p.ref = patchSet.getRefName();
- p.uploader = asAccountAttribute(patchSet.getUploader());
- p.createdOn = patchSet.getCreatedOn().getTime() / 1000L;
- PatchSet.Id pId = patchSet.getId();
+ p.revision = patchSet.commitId().name();
+ p.number = patchSet.number();
+ p.ref = patchSet.refName();
+ p.uploader = asAccountAttribute(patchSet.uploader());
+ p.createdOn = patchSet.createdOn().getTime() / 1000L;
+ PatchSet.Id pId = patchSet.id();
try {
p.parents = new ArrayList<>();
RevCommit c = revWalk.parseCommit(ObjectId.fromString(p.revision));
@@ -495,7 +495,7 @@
}
p.kind = changeKindCache.getChangeKind(change, patchSet);
} catch (IOException | StorageException e) {
- logger.atSevere().withCause(e).log("Cannot load patch set data for %s", patchSet.getId());
+ logger.atSevere().withCause(e).log("Cannot load patch set data for %s", patchSet.id());
} catch (PatchListObjectTooLargeException e) {
logger.atWarning().log("Cannot get size information for %s: %s", pId, e.getMessage());
} catch (PatchListNotAvailableException e) {
@@ -540,7 +540,7 @@
if (!list.isEmpty()) {
p.approvals = new ArrayList<>(list.size());
for (PatchSetApproval a : list) {
- if (a.getValue() != 0) {
+ if (a.value() != 0) {
p.approvals.add(asApprovalAttribute(a, labelTypes));
}
}
@@ -599,13 +599,13 @@
*/
public ApprovalAttribute asApprovalAttribute(PatchSetApproval approval, LabelTypes labelTypes) {
ApprovalAttribute a = new ApprovalAttribute();
- a.type = approval.getLabelId().get();
- a.value = Short.toString(approval.getValue());
- a.by = asAccountAttribute(approval.getAccountId());
- a.grantedOn = approval.getGranted().getTime() / 1000L;
+ a.type = approval.labelId().get();
+ a.value = Short.toString(approval.value());
+ a.by = asAccountAttribute(approval.accountId());
+ a.grantedOn = approval.granted().getTime() / 1000L;
a.oldValue = null;
- LabelType lt = labelTypes.byLabel(approval.getLabelId());
+ LabelType lt = labelTypes.byLabel(approval.labelId());
if (lt != null) {
a.description = lt.getName();
}
diff --git a/java/com/google/gerrit/server/extensions/events/EventUtil.java b/java/com/google/gerrit/server/extensions/events/EventUtil.java
index 2e09c7b..7122a4c 100644
--- a/java/com/google/gerrit/server/extensions/events/EventUtil.java
+++ b/java/com/google/gerrit/server/extensions/events/EventUtil.java
@@ -84,7 +84,7 @@
public RevisionInfo revisionInfo(Project.NameKey project, PatchSet ps)
throws PatchListNotAvailableException, GpgException, IOException, PermissionBackendException {
- ChangeData cd = changeDataFactory.create(project, ps.getId().changeId());
+ ChangeData cd = changeDataFactory.create(project, ps.id().changeId());
return revisionJsonFactory.create(CHANGE_OPTIONS).getRevisionInfo(cd, ps);
}
diff --git a/java/com/google/gerrit/server/extensions/webui/UiActions.java b/java/com/google/gerrit/server/extensions/webui/UiActions.java
index 3ca2bdb..be64d54 100644
--- a/java/com/google/gerrit/server/extensions/webui/UiActions.java
+++ b/java/com/google/gerrit/server/extensions/webui/UiActions.java
@@ -19,7 +19,6 @@
import static java.util.stream.Collectors.toList;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Predicate;
import com.google.common.collect.Streams;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
@@ -50,6 +49,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.function.Predicate;
@Singleton
public class UiActions {
diff --git a/java/com/google/gerrit/server/git/GroupCollector.java b/java/com/google/gerrit/server/git/GroupCollector.java
index 3f45fba..c7dcc73 100644
--- a/java/com/google/gerrit/server/git/GroupCollector.java
+++ b/java/com/google/gerrit/server/git/GroupCollector.java
@@ -82,9 +82,9 @@
if (rsrc.getEdit().isPresent()) {
// Groups for an edit are just the base revision's groups, since they have
// the same parent.
- return rsrc.getEdit().get().getBasePatchSet().getGroups();
+ return rsrc.getEdit().get().getBasePatchSet().groups();
}
- return rsrc.getPatchSet().getGroups();
+ return rsrc.getPatchSet().groups();
}
private interface Lookup {
@@ -109,7 +109,7 @@
// TODO(dborowitz): Reuse open repository from caller.
ChangeNotes notes = notesFactory.createChecked(project, psId.changeId());
PatchSet ps = psUtil.get(notes, psId);
- return ps != null ? ps.getGroups() : null;
+ return ps != null ? ps.groups() : null;
});
}
diff --git a/java/com/google/gerrit/server/git/MergeUtil.java b/java/com/google/gerrit/server/git/MergeUtil.java
index 084df6c..4088c81 100644
--- a/java/com/google/gerrit/server/git/MergeUtil.java
+++ b/java/com/google/gerrit/server/git/MergeUtil.java
@@ -522,7 +522,7 @@
PatchSetApproval submitAudit = null;
for (PatchSetApproval a : safeGetApprovals(notes, psId)) {
- if (a.getValue() <= 0) {
+ if (a.value() <= 0) {
// Negative votes aren't counted.
continue;
}
@@ -530,13 +530,13 @@
if (a.isLegacySubmit()) {
// Submit is treated specially, below (becomes committer)
//
- if (submitAudit == null || a.getGranted().compareTo(submitAudit.getGranted()) > 0) {
+ if (submitAudit == null || a.granted().compareTo(submitAudit.granted()) > 0) {
submitAudit = a;
}
continue;
}
- final Account acc = identifiedUserFactory.create(a.getAccountId()).getAccount();
+ final Account acc = identifiedUserFactory.create(a.accountId()).getAccount();
final StringBuilder identbuf = new StringBuilder();
if (acc.getFullName() != null && acc.getFullName().length() > 0) {
if (identbuf.length() > 0) {
@@ -561,12 +561,12 @@
}
final String tag;
- if (isCodeReview(a.getLabelId())) {
+ if (isCodeReview(a.labelId())) {
tag = "Reviewed-by";
- } else if (isVerified(a.getLabelId())) {
+ } else if (isVerified(a.labelId())) {
tag = "Tested-by";
} else {
- final LabelType lt = project.getLabelTypes().byLabel(a.getLabelId());
+ final LabelType lt = project.getLabelTypes().byLabel(a.labelId());
if (lt == null) {
continue;
}
diff --git a/java/com/google/gerrit/server/git/MergedByPushOp.java b/java/com/google/gerrit/server/git/MergedByPushOp.java
index 1f896e2..a217e64 100644
--- a/java/com/google/gerrit/server/git/MergedByPushOp.java
+++ b/java/com/google/gerrit/server/git/MergedByPushOp.java
@@ -21,9 +21,7 @@
import com.google.gerrit.reviewdb.client.ChangeMessage;
import com.google.gerrit.reviewdb.client.LabelId;
import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
-import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.config.SendEmailExecutor;
@@ -148,12 +146,7 @@
ChangeMessagesUtil.newMessage(
psId, ctx.getUser(), ctx.getWhen(), msgBuf.toString(), ChangeMessagesUtil.TAG_MERGED);
cmUtil.addChangeMessage(update, msg);
-
- PatchSetApproval submitter =
- ApprovalsUtil.newApproval(
- change.currentPatchSetId(), ctx.getUser(), LabelId.legacySubmit(), 1, ctx.getWhen());
- update.putApproval(submitter.getLabel(), submitter.getValue());
-
+ update.putApproval(LabelId.legacySubmit().get(), (short) 1);
return true;
}
@@ -188,12 +181,12 @@
}));
changeMerged.fire(
- change, patchSet, ctx.getAccount(), patchSet.getCommitId().name(), ctx.getWhen());
+ change, patchSet, ctx.getAccount(), patchSet.commitId().name(), ctx.getWhen());
}
private PatchSetInfo getPatchSetInfo(ChangeContext ctx) throws IOException {
RevWalk rw = ctx.getRevWalk();
- RevCommit commit = rw.parseCommit(requireNonNull(patchSet).getCommitId());
+ RevCommit commit = rw.parseCommit(requireNonNull(patchSet).commitId());
return patchSetInfoFactory.get(rw, commit, psId);
}
}
diff --git a/java/com/google/gerrit/server/git/PureRevertCache.java b/java/com/google/gerrit/server/git/PureRevertCache.java
index c3e9423..2faa0bb 100644
--- a/java/com/google/gerrit/server/git/PureRevertCache.java
+++ b/java/com/google/gerrit/server/git/PureRevertCache.java
@@ -97,8 +97,8 @@
claimedRevert.getProjectName(), claimedRevert.getChange().getRevertOf());
return isPureRevert(
claimedRevert.getProjectName(),
- claimedRevert.getCurrentPatchSet().getCommitId(),
- claimedOriginal.getCurrentPatchSet().getCommitId());
+ claimedRevert.getCurrentPatchSet().commitId(),
+ claimedOriginal.getCurrentPatchSet().commitId());
}
/**
diff --git a/java/com/google/gerrit/server/git/SystemReaderInstaller.java b/java/com/google/gerrit/server/git/SystemReaderInstaller.java
new file mode 100644
index 0000000..1043210
--- /dev/null
+++ b/java/com/google/gerrit/server/git/SystemReaderInstaller.java
@@ -0,0 +1,87 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.git;
+
+import com.google.common.flogger.FluentLogger;
+import com.google.gerrit.extensions.events.LifecycleListener;
+import com.google.gerrit.server.config.SitePaths;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.SystemReader;
+
+@Singleton
+public class SystemReaderInstaller implements LifecycleListener {
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+
+ private final SitePaths site;
+
+ @Inject
+ SystemReaderInstaller(SitePaths site) {
+ this.site = site;
+ }
+
+ @Override
+ public void start() {
+ SystemReader.setInstance(customReader());
+ logger.atInfo().log("Set JGit's SystemReader to read system config from %s", site.jgit_config);
+ }
+
+ @Override
+ public void stop() {}
+
+ private SystemReader customReader() {
+ SystemReader current = SystemReader.getInstance();
+
+ return new SystemReader() {
+ @Override
+ public String getHostname() {
+ return current.getHostname();
+ }
+
+ @Override
+ public String getenv(String variable) {
+ return current.getenv(variable);
+ }
+
+ @Override
+ public String getProperty(String key) {
+ return current.getProperty(key);
+ }
+
+ @Override
+ public FileBasedConfig openUserConfig(Config parent, FS fs) {
+ return current.openUserConfig(parent, fs);
+ }
+
+ @Override
+ public FileBasedConfig openSystemConfig(Config parent, FS fs) {
+ return new FileBasedConfig(parent, site.jgit_config.toFile(), FS.DETECTED);
+ }
+
+ @Override
+ public long getCurrentTime() {
+ return current.getCurrentTime();
+ }
+
+ @Override
+ public int getTimezone(long when) {
+ return current.getTimezone(when);
+ }
+ };
+ }
+}
diff --git a/java/com/google/gerrit/server/git/receive/BranchCommitValidator.java b/java/com/google/gerrit/server/git/receive/BranchCommitValidator.java
index fe7ff86..d04c894 100644
--- a/java/com/google/gerrit/server/git/receive/BranchCommitValidator.java
+++ b/java/com/google/gerrit/server/git/receive/BranchCommitValidator.java
@@ -17,6 +17,8 @@
import static com.google.gerrit.git.ObjectIds.abbreviateName;
import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_OTHER_REASON;
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.BranchNameKey;
@@ -27,14 +29,12 @@
import com.google.gerrit.server.git.validators.CommitValidationException;
import com.google.gerrit.server.git.validators.CommitValidationMessage;
import com.google.gerrit.server.git.validators.CommitValidators;
-import com.google.gerrit.server.git.validators.ValidationMessage;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.ssh.SshInfo;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
-import java.util.List;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.notes.NoteMap;
import org.eclipse.jgit.revwalk.RevCommit;
@@ -56,6 +56,23 @@
ProjectState projectState, BranchNameKey branch, IdentifiedUser user);
}
+ /** A boolean validation status and a list of additional messages. */
+ @AutoValue
+ abstract static class Result {
+ static Result create(boolean isValid, ImmutableList<CommitValidationMessage> messages) {
+ return new AutoValue_BranchCommitValidator_Result(isValid, messages);
+ }
+
+ /** Whether the commit is valid. */
+ abstract boolean isValid();
+
+ /**
+ * A list of messages related to the validation. Messages may be present regardless of the
+ * {@link #isValid()} status.
+ */
+ abstract ImmutableList<CommitValidationMessage> messages();
+ }
+
@Inject
BranchCommitValidator(
CommitValidators.Factory commitValidatorsFactory,
@@ -80,16 +97,17 @@
* @param commit the commit being validated.
* @param isMerged whether this is a merge commit created by magicBranch --merge option
* @param change the change for which this is a new patchset.
+ * @return The validation {@link Result}.
*/
- public boolean validCommit(
+ Result validateCommit(
ObjectReader objectReader,
ReceiveCommand cmd,
RevCommit commit,
boolean isMerged,
- List<ValidationMessage> messages,
NoteMap rejectCommits,
@Nullable Change change)
throws IOException {
+ ImmutableList.Builder<CommitValidationMessage> messages = new ImmutableList.Builder<>();
try (CommitReceivedEvent receiveEvent =
new CommitReceivedEvent(cmd, project, branch.branch(), objectReader, commit, user)) {
CommitValidators validators;
@@ -123,9 +141,9 @@
messageForCommit(commit, m.getMessage(), objectReader), m.getType()));
}
cmd.setResult(REJECTED_OTHER_REASON, messageForCommit(commit, e.getMessage(), objectReader));
- return false;
+ return Result.create(false, messages.build());
}
- return true;
+ return Result.create(true, messages.build());
}
private String messageForCommit(RevCommit c, String msg, ObjectReader objectReader)
diff --git a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
index cc568f0..73e0b1c 100644
--- a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
+++ b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
@@ -41,7 +41,6 @@
import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_MISSING_OBJECT;
import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_OTHER_REASON;
-import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
@@ -63,6 +62,7 @@
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.FooterConstants;
import com.google.gerrit.common.Nullable;
+import com.google.gerrit.common.UsedAt;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.exceptions.StorageException;
@@ -275,16 +275,14 @@
}
}
- private static final Function<Exception, RestApiException> INSERT_EXCEPTION =
- input -> {
- if (input instanceof RestApiException) {
- return (RestApiException) input;
- } else if ((input instanceof ExecutionException)
- && (input.getCause() instanceof RestApiException)) {
- return (RestApiException) input.getCause();
- }
- return new RestApiException("Error inserting change/patchset", input);
- };
+ private static RestApiException asRestApiException(Exception e) {
+ if (e instanceof RestApiException) {
+ return (RestApiException) e;
+ } else if ((e instanceof ExecutionException) && (e.getCause() instanceof RestApiException)) {
+ return (RestApiException) e.getCause();
+ }
+ return new RestApiException("Error inserting change/patchset", e);
+ }
// ReceiveCommits has a lot of fields, sorry. Here and in the constructor they are split up
// somewhat, and kept sorted lexicographically within sections, except where later assignments
@@ -855,7 +853,7 @@
try {
bu.execute();
} catch (UpdateException e) {
- throw INSERT_EXCEPTION.apply(e);
+ throw asRestApiException(e);
}
replaceByChange.values().stream()
@@ -1520,6 +1518,10 @@
// TODO(dpursehouse): validate hashtags
}
+ @UsedAt(UsedAt.Project.GOOGLE)
+ @Option(name = "--create-cod-token", usage = "create a token for consistency-on-demand")
+ private boolean createCodToken;
+
MagicBranchInput(IdentifiedUser user, ReceiveCommand cmd, LabelTypes labelTypes) {
this.deprecatedTopicSeen = false;
this.cmd = cmd;
@@ -1952,14 +1954,16 @@
BranchCommitValidator validator =
commitValidatorFactory.create(projectState, changeEnt.getDest(), user);
try {
- if (validator.validCommit(
- receivePack.getRevWalk().getObjectReader(),
- cmd,
- newCommit,
- false,
- messages,
- rejectCommits,
- changeEnt)) {
+ BranchCommitValidator.Result validationResult =
+ validator.validateCommit(
+ receivePack.getRevWalk().getObjectReader(),
+ cmd,
+ newCommit,
+ false,
+ rejectCommits,
+ changeEnt);
+ messages.addAll(validationResult.messages());
+ if (validationResult.isValid()) {
logger.atFine().log("Replacing change %s", changeEnt.getId());
requestReplace(cmd, true, changeEnt, newCommit);
}
@@ -2117,14 +2121,16 @@
logger.atFine().log("Creating new change for %s even though it is already tracked", name);
}
- if (!validator.validCommit(
- receivePack.getRevWalk().getObjectReader(),
- magicBranch.cmd,
- c,
- magicBranch.merged,
- messages,
- rejectCommits,
- null)) {
+ BranchCommitValidator.Result validationResult =
+ validator.validateCommit(
+ receivePack.getRevWalk().getObjectReader(),
+ magicBranch.cmd,
+ c,
+ magicBranch.merged,
+ rejectCommits,
+ null);
+ messages.addAll(validationResult.messages());
+ if (!validationResult.isValid()) {
// Not a change the user can propose? Abort as early as possible.
logger.atFine().log("Aborting early due to invalid commit");
return Collections.emptyList();
@@ -2187,7 +2193,7 @@
// Schedule as a replacement to this one matching change.
//
- ObjectId currentPs = changes.get(0).currentPatchSet().getCommitId();
+ ObjectId currentPs = changes.get(0).currentPatchSet().commitId();
// If Commit is already current PatchSet of target Change.
if (p.commit.equals(currentPs)) {
if (pending.size() == 1) {
@@ -2522,7 +2528,7 @@
});
bu.addOp(changeId, new ChangeProgressOp(progress));
} catch (Exception e) {
- throw INSERT_EXCEPTION.apply(e);
+ throw asRestApiException(e);
}
}
}
@@ -2817,7 +2823,7 @@
}
if (edit.isPresent()) {
- if (edit.get().getBasePatchSet().getId().equals(psId)) {
+ if (edit.get().getBasePatchSet().id().equals(psId)) {
// replace edit
cmd =
new ReceiveCommand(edit.get().getEditCommit(), newCommitId, edit.get().getRefName());
@@ -2911,7 +2917,7 @@
@Override
public boolean updateChange(ChangeContext ctx) {
PatchSet ps = psUtil.get(ctx.getNotes(), psId);
- List<String> oldGroups = ps.getGroups();
+ List<String> oldGroups = ps.groups();
if (oldGroups == null) {
if (groups == null) {
return false;
@@ -2919,7 +2925,7 @@
} else if (sameGroups(oldGroups, groups)) {
return false;
}
- psUtil.setGroups(ctx.getUpdate(psId), ps, groups);
+ ctx.getUpdate(psId).setGroups(groups);
return true;
}
});
@@ -3052,7 +3058,7 @@
try {
messages.addAll(refValidators.validateForRefOperation());
} catch (RefOperationValidationException e) {
- messages.addAll(Lists.newArrayList(e.getMessages()));
+ messages.addAll(e.getMessages());
reject(cmd, e.getMessage());
return false;
}
@@ -3116,8 +3122,10 @@
continue;
}
- if (!validator.validCommit(
- walk.getObjectReader(), cmd, c, false, messages, rejectCommits, null)) {
+ BranchCommitValidator.Result validationResult =
+ validator.validateCommit(walk.getObjectReader(), cmd, c, false, rejectCommits, null);
+ messages.addAll(validationResult.messages());
+ if (!validationResult.isValid()) {
break;
}
}
diff --git a/java/com/google/gerrit/server/git/receive/ReceiveCommitsAdvertiseRefsHook.java b/java/com/google/gerrit/server/git/receive/ReceiveCommitsAdvertiseRefsHook.java
index 5e72ba4..f7e0078 100644
--- a/java/com/google/gerrit/server/git/receive/ReceiveCommitsAdvertiseRefsHook.java
+++ b/java/com/google/gerrit/server/git/receive/ReceiveCommitsAdvertiseRefsHook.java
@@ -111,8 +111,8 @@
// Ensure we actually observed a patch set ref pointing to this
// object, in case the database is out of sync with the repo and the
// object doesn't actually exist.
- if (allPatchSets.contains(ps.getCommitId())) {
- r.add(ps.getCommitId());
+ if (allPatchSets.contains(ps.commitId())) {
+ r.add(ps.commitId());
}
}
}
diff --git a/java/com/google/gerrit/server/git/receive/ReplaceOp.java b/java/com/google/gerrit/server/git/receive/ReplaceOp.java
index 396a350..e839400 100644
--- a/java/com/google/gerrit/server/git/receive/ReplaceOp.java
+++ b/java/com/google/gerrit/server/git/receive/ReplaceOp.java
@@ -250,7 +250,7 @@
}
if (groups.isEmpty()) {
PatchSet prevPs = psUtil.current(notes);
- groups = prevPs != null ? prevPs.getGroups() : ImmutableList.of();
+ groups = prevPs != null ? prevPs.groups() : ImmutableList.of();
}
ChangeData cd = changeDataFactory.create(ctx.getNotes());
@@ -290,7 +290,7 @@
}
if (shouldPublishComments()) {
boolean workInProgress = change.isWorkInProgress();
- if (magicBranch != null && magicBranch.workInProgress) {
+ if (magicBranch.workInProgress) {
workInProgress = true;
}
comments = publishComments(ctx, workInProgress);
@@ -454,7 +454,7 @@
continue;
}
- LabelType lt = projectState.getLabelTypes().byLabel(a.getLabelId());
+ LabelType lt = projectState.getLabelTypes().byLabel(a.labelId());
if (lt != null) {
current.put(lt.getName(), a);
}
@@ -551,7 +551,7 @@
Streams.concat(
oldRecipients.getReviewers().stream(),
reviewerAdditions.flattenResults(AddReviewersOp.Result::addedReviewers).stream()
- .map(PatchSetApproval::getAccountId))
+ .map(PatchSetApproval::accountId))
.collect(toImmutableSet()));
cm.addExtraCC(
Streams.concat(
@@ -562,7 +562,7 @@
cm.send();
} catch (Exception e) {
logger.atSevere().withCause(e).log(
- "Cannot send email for new patch set %s", newPatchSet.getId());
+ "Cannot send email for new patch set %s", newPatchSet.id());
}
}
diff --git a/java/com/google/gerrit/server/git/validators/RefOperationValidationException.java b/java/com/google/gerrit/server/git/validators/RefOperationValidationException.java
index 9eaf2d2..d27cc38 100644
--- a/java/com/google/gerrit/server/git/validators/RefOperationValidationException.java
+++ b/java/com/google/gerrit/server/git/validators/RefOperationValidationException.java
@@ -14,27 +14,28 @@
package com.google.gerrit.server.git.validators;
+import static java.util.stream.Collectors.joining;
+
+import com.google.common.collect.ImmutableList;
import com.google.gerrit.server.validators.ValidationException;
public class RefOperationValidationException extends ValidationException {
private static final long serialVersionUID = 1L;
- private final Iterable<ValidationMessage> messages;
+ private final ImmutableList<ValidationMessage> messages;
- public RefOperationValidationException(String reason, Iterable<ValidationMessage> messages) {
+ public RefOperationValidationException(String reason, ImmutableList<ValidationMessage> messages) {
super(reason);
this.messages = messages;
}
- public Iterable<ValidationMessage> getMessages() {
+ public ImmutableList<ValidationMessage> getMessages() {
return messages;
}
@Override
public String getMessage() {
- StringBuilder msg = new StringBuilder(super.getMessage());
- for (ValidationMessage error : messages) {
- msg.append("\n").append(error.getMessage());
- }
- return msg.toString();
+ return messages.stream()
+ .map(ValidationMessage::getMessage)
+ .collect(joining("\n", super.getMessage() + "\n", ""));
}
}
diff --git a/java/com/google/gerrit/server/git/validators/RefOperationValidators.java b/java/com/google/gerrit/server/git/validators/RefOperationValidators.java
index dd5d508..919bd5a 100644
--- a/java/com/google/gerrit/server/git/validators/RefOperationValidators.java
+++ b/java/com/google/gerrit/server/git/validators/RefOperationValidators.java
@@ -13,9 +13,9 @@
// limitations under the License.
package com.google.gerrit.server.git.validators;
-import com.google.common.base.Predicate;
+import static com.google.common.collect.ImmutableList.toImmutableList;
+
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.reviewdb.client.Account;
@@ -39,8 +39,6 @@
public class RefOperationValidators {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
- private static final GetErrorMessages GET_ERRORS = new GetErrorMessages();
-
public interface Factory {
RefOperationValidators create(Project project, IdentifiedUser user, ReceiveCommand cmd);
}
@@ -93,22 +91,15 @@
return messages;
}
- private void throwException(Iterable<ValidationMessage> messages, RefReceivedEvent event)
+ private void throwException(List<ValidationMessage> messages, RefReceivedEvent event)
throws RefOperationValidationException {
- Iterable<ValidationMessage> errors = Iterables.filter(messages, GET_ERRORS);
String header =
String.format(
"Ref \"%s\" %S in project %s validation failed",
event.command.getRefName(), event.command.getType(), event.project.getName());
logger.atSevere().log(header);
- throw new RefOperationValidationException(header, errors);
- }
-
- private static class GetErrorMessages implements Predicate<ValidationMessage> {
- @Override
- public boolean apply(ValidationMessage input) {
- return input.isError();
- }
+ throw new RefOperationValidationException(
+ header, messages.stream().filter(ValidationMessage::isError).collect(toImmutableList()));
}
private static class DisallowCreationAndDeletionOfGerritMaintainedBranches
diff --git a/java/com/google/gerrit/server/group/db/AuditLogReader.java b/java/com/google/gerrit/server/group/db/AuditLogReader.java
index 8ef9e7f..fb58577 100644
--- a/java/com/google/gerrit/server/group/db/AuditLogReader.java
+++ b/java/com/google/gerrit/server/group/db/AuditLogReader.java
@@ -14,6 +14,8 @@
package com.google.gerrit.server.group.db;
+import static com.google.common.collect.ImmutableList.toImmutableList;
+
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ListMultimap;
@@ -21,7 +23,7 @@
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.client.AccountGroupByIdAud;
+import com.google.gerrit.reviewdb.client.AccountGroupByIdAudit;
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.config.AllUsersName;
@@ -69,66 +71,75 @@
private ImmutableList<AccountGroupMemberAudit> getMembersAudit(
AccountGroup.Id groupId, List<ParsedCommit> commits) {
- ListMultimap<MemberKey, AccountGroupMemberAudit> audits =
+ ListMultimap<MemberKey, AccountGroupMemberAudit.Builder> audits =
MultimapBuilder.hashKeys().linkedListValues().build();
- ImmutableList.Builder<AccountGroupMemberAudit> result = ImmutableList.builder();
+ List<AccountGroupMemberAudit.Builder> result = new ArrayList<>();
for (ParsedCommit pc : commits) {
for (Account.Id id : pc.addedMembers()) {
MemberKey key = MemberKey.create(groupId, id);
- AccountGroupMemberAudit audit =
- new AccountGroupMemberAudit(
- AccountGroupMemberAudit.key(id, groupId, pc.when()), pc.authorId());
+ AccountGroupMemberAudit.Builder audit =
+ AccountGroupMemberAudit.builder()
+ .memberId(id)
+ .groupId(groupId)
+ .addedOn(pc.when())
+ .addedBy(pc.authorId());
audits.put(key, audit);
result.add(audit);
}
for (Account.Id id : pc.removedMembers()) {
- List<AccountGroupMemberAudit> adds = audits.get(MemberKey.create(groupId, id));
+ List<AccountGroupMemberAudit.Builder> adds = audits.get(MemberKey.create(groupId, id));
if (!adds.isEmpty()) {
- AccountGroupMemberAudit audit = adds.remove(0);
+ AccountGroupMemberAudit.Builder audit = adds.remove(0);
audit.removed(pc.authorId(), pc.when());
} else {
// Match old behavior of DbGroupAuditListener and add a "legacy" add/remove pair.
- AccountGroupMemberAudit audit =
- new AccountGroupMemberAudit(
- AccountGroupMemberAudit.key(id, groupId, pc.when()), pc.authorId());
- audit.removedLegacy();
+ AccountGroupMemberAudit.Builder audit =
+ AccountGroupMemberAudit.builder()
+ .groupId(groupId)
+ .memberId(id)
+ .addedOn(pc.when())
+ .addedBy(pc.authorId())
+ .removedLegacy();
result.add(audit);
}
}
}
- return result.build();
+ return result.stream().map(AccountGroupMemberAudit.Builder::build).collect(toImmutableList());
}
- public ImmutableList<AccountGroupByIdAud> getSubgroupsAudit(
+ public ImmutableList<AccountGroupByIdAudit> getSubgroupsAudit(
Repository repo, AccountGroup.UUID uuid) throws IOException, ConfigInvalidException {
return getSubgroupsAudit(getGroupId(repo, uuid), parseCommits(repo, uuid));
}
- private ImmutableList<AccountGroupByIdAud> getSubgroupsAudit(
+ private ImmutableList<AccountGroupByIdAudit> getSubgroupsAudit(
AccountGroup.Id groupId, List<ParsedCommit> commits) {
- ListMultimap<SubgroupKey, AccountGroupByIdAud> audits =
+ ListMultimap<SubgroupKey, AccountGroupByIdAudit.Builder> audits =
MultimapBuilder.hashKeys().linkedListValues().build();
- ImmutableList.Builder<AccountGroupByIdAud> result = ImmutableList.builder();
+ List<AccountGroupByIdAudit.Builder> result = new ArrayList<>();
for (ParsedCommit pc : commits) {
for (AccountGroup.UUID uuid : pc.addedSubgroups()) {
SubgroupKey key = SubgroupKey.create(groupId, uuid);
- AccountGroupByIdAud audit =
- new AccountGroupByIdAud(
- AccountGroupByIdAud.key(groupId, uuid, pc.when()), pc.authorId());
+ AccountGroupByIdAudit.Builder audit =
+ AccountGroupByIdAudit.builder()
+ .groupId(groupId)
+ .includeUuid(uuid)
+ .addedOn(pc.when())
+ .addedBy(pc.authorId());
audits.put(key, audit);
result.add(audit);
}
for (AccountGroup.UUID uuid : pc.removedSubgroups()) {
- List<AccountGroupByIdAud> adds = audits.get(SubgroupKey.create(groupId, uuid));
+ List<AccountGroupByIdAudit.Builder> adds = audits.get(SubgroupKey.create(groupId, uuid));
if (!adds.isEmpty()) {
- AccountGroupByIdAud audit = adds.remove(0);
+ AccountGroupByIdAudit.Builder audit = adds.remove(0);
audit.removed(pc.authorId(), pc.when());
} else {
// Unlike members, DbGroupAuditListener didn't insert an add/remove pair here.
}
}
}
- return result.build();
+ return result.stream().map(AccountGroupByIdAudit.Builder::build).collect(toImmutableList());
}
private Optional<ParsedCommit> parse(AccountGroup.UUID uuid, RevCommit c) {
diff --git a/java/com/google/gerrit/server/group/db/Groups.java b/java/com/google/gerrit/server/group/db/Groups.java
index 37de011..1c8d897 100644
--- a/java/com/google/gerrit/server/group/db/Groups.java
+++ b/java/com/google/gerrit/server/group/db/Groups.java
@@ -18,7 +18,7 @@
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.common.data.GroupReference;
import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.client.AccountGroupByIdAud;
+import com.google.gerrit.reviewdb.client.AccountGroupByIdAudit;
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.git.GitRepositoryManager;
@@ -152,7 +152,7 @@
* @throws IOException if an error occurs while reading from NoteDb
* @throws ConfigInvalidException if the group couldn't be retrieved from NoteDb
*/
- public List<AccountGroupByIdAud> getSubgroupsAudit(Repository repo, AccountGroup.UUID groupUuid)
+ public List<AccountGroupByIdAudit> getSubgroupsAudit(Repository repo, AccountGroup.UUID groupUuid)
throws IOException, ConfigInvalidException {
return auditLogReader.getSubgroupsAudit(repo, groupUuid);
}
diff --git a/java/com/google/gerrit/server/group/db/testing/GroupTestUtil.java b/java/com/google/gerrit/server/group/db/testing/GroupTestUtil.java
index 5a0d28c..fa06281 100644
--- a/java/com/google/gerrit/server/group/db/testing/GroupTestUtil.java
+++ b/java/com/google/gerrit/server/group/db/testing/GroupTestUtil.java
@@ -45,8 +45,8 @@
String fileName,
String contents)
throws Exception {
- try (RevWalk rw = new RevWalk(allUsersRepo)) {
- TestRepository<Repository> testRepository = new TestRepository<>(allUsersRepo, rw);
+ try (RevWalk rw = new RevWalk(allUsersRepo);
+ TestRepository<Repository> testRepository = new TestRepository<>(allUsersRepo, rw)) {
TestRepository<Repository>.CommitBuilder builder =
testRepository
.branch(refName)
diff --git a/java/com/google/gerrit/server/group/testing/InternalGroupSubject.java b/java/com/google/gerrit/server/group/testing/InternalGroupSubject.java
index d372ad5..0b24f8c 100644
--- a/java/com/google/gerrit/server/group/testing/InternalGroupSubject.java
+++ b/java/com/google/gerrit/server/group/testing/InternalGroupSubject.java
@@ -18,7 +18,6 @@
import com.google.common.truth.BooleanSubject;
import com.google.common.truth.ComparableSubject;
-import com.google.common.truth.DefaultSubject;
import com.google.common.truth.FailureMetadata;
import com.google.common.truth.IterableSubject;
import com.google.common.truth.StringSubject;
@@ -38,73 +37,65 @@
return InternalGroupSubject::new;
}
- private InternalGroupSubject(FailureMetadata metadata, InternalGroup actual) {
- super(metadata, actual);
+ private final InternalGroup group;
+
+ private InternalGroupSubject(FailureMetadata metadata, InternalGroup group) {
+ super(metadata, group);
+ this.group = group;
}
public ComparableSubject<?, AccountGroup.UUID> groupUuid() {
isNotNull();
- InternalGroup group = actual();
return check("getGroupUUID()").that(group.getGroupUUID());
}
public ComparableSubject<?, AccountGroup.NameKey> nameKey() {
isNotNull();
- InternalGroup group = actual();
return check("getNameKey()").that(group.getNameKey());
}
public StringSubject name() {
isNotNull();
- InternalGroup group = actual();
return check("getName()").that(group.getName());
}
- public Subject<DefaultSubject, Object> id() {
+ public Subject<?, ?> id() {
isNotNull();
- InternalGroup group = actual();
return check("getId()").that(group.getId());
}
public StringSubject description() {
isNotNull();
- InternalGroup group = actual();
return check("getDescription()").that(group.getDescription());
}
public ComparableSubject<?, AccountGroup.UUID> ownerGroupUuid() {
isNotNull();
- InternalGroup group = actual();
return check("getOwnerGroupUUID()").that(group.getOwnerGroupUUID());
}
public BooleanSubject visibleToAll() {
isNotNull();
- InternalGroup group = actual();
return check("isVisibleToAll()").that(group.isVisibleToAll());
}
public ComparableSubject<?, Timestamp> createdOn() {
isNotNull();
- InternalGroup group = actual();
return check("getCreatedOn()").that(group.getCreatedOn());
}
public IterableSubject members() {
isNotNull();
- InternalGroup group = actual();
return check("getMembers()").that(group.getMembers());
}
public IterableSubject subgroups() {
isNotNull();
- InternalGroup group = actual();
return check("getSubgroups()").that(group.getSubgroups());
}
public ComparableSubject<?, ObjectId> refState() {
isNotNull();
- InternalGroup group = actual();
return check("getRefState()").that(group.getRefState());
}
}
diff --git a/java/com/google/gerrit/server/index/AbstractIndexModule.java b/java/com/google/gerrit/server/index/AbstractIndexModule.java
index 352ea4b..995b4b6 100644
--- a/java/com/google/gerrit/server/index/AbstractIndexModule.java
+++ b/java/com/google/gerrit/server/index/AbstractIndexModule.java
@@ -15,7 +15,6 @@
package com.google.gerrit.server.index;
import com.google.gerrit.index.IndexConfig;
-import com.google.gerrit.index.Schema;
import com.google.gerrit.index.project.ProjectIndex;
import com.google.gerrit.lifecycle.LifecycleModule;
import com.google.gerrit.server.config.GerritServerConfig;
@@ -44,9 +43,21 @@
@Override
protected void configure() {
if (slave) {
- bind(AccountIndex.Factory.class).toInstance(AbstractIndexModule::createDummyIndexFactory);
- bind(ChangeIndex.Factory.class).toInstance(AbstractIndexModule::createDummyIndexFactory);
- bind(ProjectIndex.Factory.class).toInstance(AbstractIndexModule::createDummyIndexFactory);
+ bind(AccountIndex.Factory.class)
+ .toInstance(
+ s -> {
+ throw new UnsupportedOperationException();
+ });
+ bind(ChangeIndex.Factory.class)
+ .toInstance(
+ s -> {
+ throw new UnsupportedOperationException();
+ });
+ bind(ProjectIndex.Factory.class)
+ .toInstance(
+ s -> {
+ throw new UnsupportedOperationException();
+ });
} else {
install(
new FactoryModuleBuilder()
@@ -74,11 +85,6 @@
}
}
- @SuppressWarnings("unused")
- private static <T> T createDummyIndexFactory(Schema<?> schema) {
- throw new UnsupportedOperationException();
- }
-
protected abstract Class<? extends AccountIndex> getAccountIndex();
protected abstract Class<? extends ChangeIndex> getChangeIndex();
diff --git a/java/com/google/gerrit/server/index/IndexModule.java b/java/com/google/gerrit/server/index/IndexModule.java
index 3d5c1a7..899e061 100644
--- a/java/com/google/gerrit/server/index/IndexModule.java
+++ b/java/com/google/gerrit/server/index/IndexModule.java
@@ -17,11 +17,14 @@
import static com.google.gerrit.server.git.QueueProvider.QueueType.BATCH;
import static com.google.gerrit.server.git.QueueProvider.QueueType.INTERACTIVE;
+import com.google.common.base.MoreObjects;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
+import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.index.IndexDefinition;
@@ -70,9 +73,36 @@
* (e.g. Lucene).
*/
public class IndexModule extends LifecycleModule {
- public enum IndexType {
- LUCENE,
- ELASTICSEARCH
+ public static class IndexType {
+ private static final String LUCENE = "lucene";
+ private static final String ELASTICSEARCH = "elasticsearch";
+
+ private final String type;
+
+ public IndexType(@Nullable String type) {
+ this.type = type == null ? getDefault() : type.toLowerCase();
+ }
+
+ public static String getDefault() {
+ return LUCENE;
+ }
+
+ public static ImmutableSet<String> getKnownTypes() {
+ return ImmutableSet.of(LUCENE, ELASTICSEARCH);
+ }
+
+ public boolean isLucene() {
+ return type.equals(LUCENE);
+ }
+
+ public boolean isElasticsearch() {
+ return type.equals(ELASTICSEARCH);
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this).add("type", type).toString();
+ }
}
public static final ImmutableCollection<SchemaDefinitions<?>> ALL_SCHEMA_DEFS =
@@ -84,8 +114,13 @@
/** Type of secondary index. */
public static IndexType getIndexType(Injector injector) {
- Config cfg = injector.getInstance(Key.get(Config.class, GerritServerConfig.class));
- return cfg.getEnum("index", null, "type", IndexType.LUCENE);
+ return getIndexType(injector.getInstance(Key.get(Config.class, GerritServerConfig.class)));
+ }
+
+ /** Type of secondary index. */
+ public static IndexType getIndexType(@Nullable Config cfg) {
+ String configValue = cfg != null ? cfg.getString("index", null, "type") : null;
+ return new IndexType(configValue);
}
private final int threads;
diff --git a/java/com/google/gerrit/server/index/account/AccountField.java b/java/com/google/gerrit/server/index/account/AccountField.java
index f67a41d..ab3a96d 100644
--- a/java/com/google/gerrit/server/index/account/AccountField.java
+++ b/java/com/google/gerrit/server/index/account/AccountField.java
@@ -21,7 +21,6 @@
import static com.google.gerrit.index.FieldDef.timestamp;
import static java.util.stream.Collectors.toSet;
-import com.google.common.base.Predicates;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
@@ -36,6 +35,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.Locale;
+import java.util.Objects;
import java.util.Set;
import org.eclipse.jgit.lib.ObjectId;
@@ -96,7 +96,7 @@
FluentIterable.from(a.getExternalIds())
.transform(ExternalId::email)
.append(Collections.singleton(a.getAccount().getPreferredEmail()))
- .filter(Predicates.notNull())
+ .filter(Objects::nonNull)
.transform(String::toLowerCase)
.toSet());
diff --git a/java/com/google/gerrit/server/index/change/AllChangesIndexer.java b/java/com/google/gerrit/server/index/change/AllChangesIndexer.java
index 577c255..3015187 100644
--- a/java/com/google/gerrit/server/index/change/AllChangesIndexer.java
+++ b/java/com/google/gerrit/server/index/change/AllChangesIndexer.java
@@ -23,6 +23,7 @@
import com.google.common.base.Stopwatch;
import com.google.common.collect.ComparisonChain;
import com.google.common.flogger.FluentLogger;
+import com.google.common.primitives.Ints;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.gerrit.index.SiteIndexer;
@@ -108,7 +109,7 @@
int projectsFailed = 0;
for (Project.NameKey name : projectCache.all()) {
try (Repository repo = repoManager.openRepository(name)) {
- long size = estimateSize(repo);
+ int size = estimateSize(repo);
changeCount += size;
projects.add(new ProjectHolder(name, size));
} catch (IOException e) {
@@ -126,15 +127,17 @@
return indexAll(index, projects);
}
- private long estimateSize(Repository repo) throws IOException {
+ private int estimateSize(Repository repo) throws IOException {
// Estimate size based on IDs that show up in ref names. This is not perfect, since patch set
// refs may exist for changes whose metadata was never successfully stored. But that's ok, as
// the estimate is just used as a heuristic for sorting projects.
- return repo.getRefDatabase().getRefsByPrefix(RefNames.REFS_CHANGES).stream()
- .map(r -> Change.Id.fromRef(r.getName()))
- .filter(Objects::nonNull)
- .distinct()
- .count();
+ long size =
+ repo.getRefDatabase().getRefsByPrefix(RefNames.REFS_CHANGES).stream()
+ .map(r -> Change.Id.fromRef(r.getName()))
+ .filter(Objects::nonNull)
+ .distinct()
+ .count();
+ return Ints.saturatedCast(size);
}
private SiteIndexer.Result indexAll(ChangeIndex index, SortedSet<ProjectHolder> projects) {
diff --git a/java/com/google/gerrit/server/index/change/ChangeField.java b/java/com/google/gerrit/server/index/change/ChangeField.java
index f47f8bc..599c604 100644
--- a/java/com/google/gerrit/server/index/change/ChangeField.java
+++ b/java/com/google/gerrit/server/index/change/ChangeField.java
@@ -451,7 +451,7 @@
exact(ChangeQueryBuilder.FIELD_EXACTCOMMIT).buildRepeatable(ChangeField::getRevisions);
private static ImmutableSet<String> getRevisions(ChangeData cd) {
- return cd.patchSets().stream().map(ps -> ps.getCommitId().name()).collect(toImmutableSet());
+ return cd.patchSets().stream().map(ps -> ps.commitId().name()).collect(toImmutableSet());
}
/** Tracking id extracted from a footer. */
@@ -467,13 +467,12 @@
Set<String> allApprovals = new HashSet<>();
Set<String> distinctApprovals = new HashSet<>();
for (PatchSetApproval a : cd.currentApprovals()) {
- if (a.getValue() != 0 && !a.isLegacySubmit()) {
- allApprovals.add(formatLabel(a.getLabel(), a.getValue(), a.getAccountId()));
- if (owners && cd.change().getOwner().equals(a.getAccountId())) {
- allApprovals.add(
- formatLabel(a.getLabel(), a.getValue(), ChangeQueryBuilder.OWNER_ACCOUNT_ID));
+ if (a.value() != 0 && !a.isLegacySubmit()) {
+ allApprovals.add(formatLabel(a.label(), a.value(), a.accountId()));
+ if (owners && cd.change().getOwner().equals(a.accountId())) {
+ allApprovals.add(formatLabel(a.label(), a.value(), ChangeQueryBuilder.OWNER_ACCOUNT_ID));
}
- distinctApprovals.add(formatLabel(a.getLabel(), a.getValue()));
+ distinctApprovals.add(formatLabel(a.label(), a.value()));
}
}
allApprovals.addAll(distinctApprovals);
@@ -663,8 +662,7 @@
public static final FieldDef<ChangeData, Iterable<String>> GROUP =
exact(ChangeQueryBuilder.FIELD_GROUP)
.buildRepeatable(
- cd ->
- cd.patchSets().stream().flatMap(ps -> ps.getGroups().stream()).collect(toSet()));
+ cd -> cd.patchSets().stream().flatMap(ps -> ps.groups().stream()).collect(toSet()));
/** Serialized patch set object, used for pre-populating results. */
public static final FieldDef<ChangeData, Iterable<byte[]>> PATCH_SET =
diff --git a/java/com/google/gerrit/server/index/change/ChangeIndexRewriter.java b/java/com/google/gerrit/server/index/change/ChangeIndexRewriter.java
index 976813f..e92a0f6 100644
--- a/java/com/google/gerrit/server/index/change/ChangeIndexRewriter.java
+++ b/java/com/google/gerrit/server/index/change/ChangeIndexRewriter.java
@@ -155,7 +155,7 @@
MutableInteger leafTerms = new MutableInteger();
Predicate<ChangeData> out = rewriteImpl(in, index, opts, leafTerms);
- if (in == out || out instanceof IndexPredicate) {
+ if (isSameInstance(in, out) || out instanceof IndexPredicate) {
return new IndexedChangeQuery(index, out, opts);
} else if (out == null /* cannot rewrite */) {
return in;
@@ -207,7 +207,7 @@
for (int i = 0; i < n; i++) {
Predicate<ChangeData> c = in.getChild(i);
Predicate<ChangeData> nc = rewriteImpl(c, index, opts, leafTerms);
- if (nc == c) {
+ if (isSameInstance(nc, c)) {
isIndexed.set(i);
newChildren.add(c);
} else if (nc == null /* cannot rewrite c */) {
@@ -291,4 +291,9 @@
return p.getChildCount() > 0
&& (p instanceof AndPredicate || p instanceof OrPredicate || p instanceof NotPredicate);
}
+
+ @SuppressWarnings("ReferenceEquality")
+ private static <T> boolean isSameInstance(T a, T b) {
+ return a == b;
+ }
}
diff --git a/java/com/google/gerrit/server/mail/EmailModule.java b/java/com/google/gerrit/server/mail/EmailModule.java
index 862293e..cc3db75 100644
--- a/java/com/google/gerrit/server/mail/EmailModule.java
+++ b/java/com/google/gerrit/server/mail/EmailModule.java
@@ -20,8 +20,10 @@
import com.google.gerrit.server.mail.send.AddReviewerSender;
import com.google.gerrit.server.mail.send.CommentSender;
import com.google.gerrit.server.mail.send.CreateChangeSender;
+import com.google.gerrit.server.mail.send.DeleteKeySender;
import com.google.gerrit.server.mail.send.DeleteReviewerSender;
import com.google.gerrit.server.mail.send.DeleteVoteSender;
+import com.google.gerrit.server.mail.send.HttpPasswordUpdateSender;
import com.google.gerrit.server.mail.send.MergedSender;
import com.google.gerrit.server.mail.send.RegisterNewEmailSender;
import com.google.gerrit.server.mail.send.ReplacePatchSetSender;
@@ -37,8 +39,10 @@
factory(AddReviewerSender.Factory.class);
factory(CommentSender.Factory.class);
factory(CreateChangeSender.Factory.class);
+ factory(DeleteKeySender.Factory.class);
factory(DeleteReviewerSender.Factory.class);
factory(DeleteVoteSender.Factory.class);
+ factory(HttpPasswordUpdateSender.Factory.class);
factory(MergedSender.Factory.class);
factory(RegisterNewEmailSender.Factory.class);
factory(ReplacePatchSetSender.Factory.class);
diff --git a/java/com/google/gerrit/server/mail/receive/MailProcessor.java b/java/com/google/gerrit/server/mail/receive/MailProcessor.java
index 5a72b59..3655369 100644
--- a/java/com/google/gerrit/server/mail/receive/MailProcessor.java
+++ b/java/com/google/gerrit/server/mail/receive/MailProcessor.java
@@ -330,7 +330,7 @@
approvalsUtil
.byPatchSetUser(
notes, psId, ctx.getAccountId(), ctx.getRevWalk(), ctx.getRepoView().getConfig())
- .forEach(a -> approvals.put(a.getLabel(), a.getValue()));
+ .forEach(a -> approvals.put(a.label(), a.value()));
// Fire Gerrit event. Note that approvals can't be granted via email, so old and new approvals
// are always the same here.
commentAdded.fire(
@@ -386,7 +386,7 @@
commentsUtil.newComment(
ctx,
fileName,
- patchSetForComment.getId(),
+ patchSetForComment.id(),
(short) side.ordinal(),
mailComment.getMessage(),
false,
diff --git a/java/com/google/gerrit/server/mail/send/ChangeEmail.java b/java/com/google/gerrit/server/mail/send/ChangeEmail.java
index 170215e..f28afbd 100644
--- a/java/com/google/gerrit/server/mail/send/ChangeEmail.java
+++ b/java/com/google/gerrit/server/mail/send/ChangeEmail.java
@@ -156,10 +156,10 @@
}
if (patchSet != null) {
- setHeader(MailHeader.PATCH_SET.fieldName(), patchSet.getPatchSetId() + "");
+ setHeader(MailHeader.PATCH_SET.fieldName(), patchSet.number() + "");
if (patchSetInfo == null) {
try {
- patchSetInfo = args.patchSetInfoFactory.get(changeData.notes(), patchSet.getId());
+ patchSetInfo = args.patchSetInfoFactory.get(changeData.notes(), patchSet.id());
} catch (PatchSetInfoNotAvailableException | StorageException err) {
patchSetInfo = null;
}
@@ -205,7 +205,7 @@
private void setCommitIdHeader() {
if (patchSet != null) {
- setHeader(MailHeader.COMMIT.fieldName(), patchSet.getCommitId().name());
+ setHeader(MailHeader.COMMIT.fieldName(), patchSet.commitId().name());
}
}
@@ -286,7 +286,7 @@
/** Get the patch list corresponding to patch set patchSetId of this change. */
protected PatchList getPatchList(int patchSetId) throws PatchListNotAvailableException {
PatchSet ps;
- if (patchSetId == patchSet.getPatchSetId()) {
+ if (patchSetId == patchSet.number()) {
ps = patchSet;
} else {
try {
@@ -411,7 +411,7 @@
case ALL:
default:
if (patchSet != null) {
- authors.add(patchSet.getUploader());
+ authors.add(patchSet.uploader());
}
if (patchSetInfo != null) {
if (patchSetInfo.getAuthor().getAccount() != null) {
@@ -461,8 +461,8 @@
soyContext.put("change", changeData);
Map<String, Object> patchSetData = new HashMap<>();
- patchSetData.put("patchSetId", patchSet.getPatchSetId());
- patchSetData.put("refName", patchSet.getRefName());
+ patchSetData.put("patchSetId", patchSet.number());
+ patchSetData.put("refName", patchSet.refName());
soyContext.put("patchSet", patchSetData);
Map<String, Object> patchSetInfoData = new HashMap<>();
@@ -472,7 +472,7 @@
footers.add(MailHeader.CHANGE_ID.withDelimiter() + change.getKey().get());
footers.add(MailHeader.CHANGE_NUMBER.withDelimiter() + Integer.toString(change.getChangeId()));
- footers.add(MailHeader.PATCH_SET.withDelimiter() + patchSet.getPatchSetId());
+ footers.add(MailHeader.PATCH_SET.withDelimiter() + patchSet.number());
footers.add(MailHeader.OWNER.withDelimiter() + getNameEmailFor(change.getOwner()));
if (change.getAssignee() != null) {
footers.add(MailHeader.ASSIGNEE.withDelimiter() + getNameEmailFor(change.getAssignee()));
diff --git a/java/com/google/gerrit/server/mail/send/DeleteKeySender.java b/java/com/google/gerrit/server/mail/send/DeleteKeySender.java
new file mode 100644
index 0000000..b95b596
--- /dev/null
+++ b/java/com/google/gerrit/server/mail/send/DeleteKeySender.java
@@ -0,0 +1,150 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.mail.send;
+
+import com.google.common.base.Joiner;
+import com.google.gerrit.exceptions.EmailException;
+import com.google.gerrit.extensions.api.changes.RecipientType;
+import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.mail.Address;
+import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.account.AccountSshKey;
+import com.google.gerrit.server.permissions.GlobalPermission;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+import java.util.Collections;
+import java.util.List;
+
+public class DeleteKeySender extends OutgoingEmail {
+ public interface Factory {
+ DeleteKeySender create(IdentifiedUser user, AccountSshKey sshKey);
+
+ DeleteKeySender create(IdentifiedUser user, List<String> gpgKeyFingerprints);
+ }
+
+ private final PermissionBackend permissionBackend;
+ private final IdentifiedUser callingUser;
+ private final IdentifiedUser user;
+ private final AccountSshKey sshKey;
+ private final List<String> gpgKeyFingerprints;
+
+ @AssistedInject
+ public DeleteKeySender(
+ EmailArguments ea,
+ PermissionBackend permissionBackend,
+ IdentifiedUser callingUser,
+ @Assisted IdentifiedUser user,
+ @Assisted AccountSshKey sshKey) {
+ super(ea, "deletekey");
+ this.permissionBackend = permissionBackend;
+ this.callingUser = callingUser;
+ this.user = user;
+ this.gpgKeyFingerprints = Collections.emptyList();
+ this.sshKey = sshKey;
+ }
+
+ @AssistedInject
+ public DeleteKeySender(
+ EmailArguments ea,
+ PermissionBackend permissionBackend,
+ IdentifiedUser callingUser,
+ @Assisted IdentifiedUser user,
+ @Assisted List<String> gpgKeyFingerprints) {
+ super(ea, "deletekey");
+ this.permissionBackend = permissionBackend;
+ this.callingUser = callingUser;
+ this.user = user;
+ this.gpgKeyFingerprints = gpgKeyFingerprints;
+ this.sshKey = null;
+ }
+
+ @Override
+ protected void init() throws EmailException {
+ super.init();
+ setHeader("Subject", String.format("[Gerrit Code Review] %s Keys Deleted", getKeyType()));
+ add(RecipientType.TO, new Address(getEmail()));
+ }
+
+ @Override
+ protected boolean shouldSendMessage() {
+ if (user.equals(callingUser)) {
+ // Send email if the user self-removed a key; this notification is necessary to alert
+ // the user if their account was compromised and a key was unexpectedly deleted.
+ return true;
+ }
+
+ try {
+ // Don't email if an administrator removed a key on behalf of the user.
+ permissionBackend.user(callingUser).check(GlobalPermission.ADMINISTRATE_SERVER);
+ return false;
+ } catch (AuthException | PermissionBackendException e) {
+ // Send email if a non-administrator modified the keys, e.g. by MODIFY_ACCOUNT.
+ return true;
+ }
+ }
+
+ @Override
+ protected void format() throws EmailException {
+ appendText(textTemplate("DeleteKey"));
+ if (useHtml()) {
+ appendHtml(soyHtmlTemplate("DeleteKeyHtml"));
+ }
+ }
+
+ public String getEmail() {
+ return user.getAccount().getPreferredEmail();
+ }
+
+ public String getUserNameEmail() {
+ return getUserNameEmailFor(user.getAccountId());
+ }
+
+ public String getKeyType() {
+ if (sshKey != null) {
+ return "SSH";
+ } else if (gpgKeyFingerprints != null) {
+ return "GPG";
+ }
+ throw new IllegalStateException("key type is not SSH or GPG");
+ }
+
+ public String getSshKey() {
+ return (sshKey != null) ? sshKey.sshPublicKey() + "\n" : null;
+ }
+
+ public String getGpgKeyFingerprints() {
+ if (!gpgKeyFingerprints.isEmpty()) {
+ return Joiner.on("\n").join(gpgKeyFingerprints);
+ }
+ return null;
+ }
+
+ @Override
+ protected void setupSoyContext() {
+ super.setupSoyContext();
+ soyContextEmailData.put("email", getEmail());
+ soyContextEmailData.put("gpgKeyFingerprints", getGpgKeyFingerprints());
+ soyContextEmailData.put("keyType", getKeyType());
+ soyContextEmailData.put("sshKey", getSshKey());
+ soyContextEmailData.put("userNameEmail", getUserNameEmail());
+ }
+
+ @Override
+ protected boolean supportsHtml() {
+ return true;
+ }
+}
diff --git a/java/com/google/gerrit/server/mail/send/HttpPasswordUpdateSender.java b/java/com/google/gerrit/server/mail/send/HttpPasswordUpdateSender.java
new file mode 100644
index 0000000..ca332ff
--- /dev/null
+++ b/java/com/google/gerrit/server/mail/send/HttpPasswordUpdateSender.java
@@ -0,0 +1,81 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.mail.send;
+
+import com.google.gerrit.exceptions.EmailException;
+import com.google.gerrit.extensions.api.changes.RecipientType;
+import com.google.gerrit.mail.Address;
+import com.google.gerrit.server.IdentifiedUser;
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+
+public class HttpPasswordUpdateSender extends OutgoingEmail {
+ public interface Factory {
+ HttpPasswordUpdateSender create(IdentifiedUser user, String operation);
+ }
+
+ private final IdentifiedUser user;
+ private final String operation;
+
+ @AssistedInject
+ public HttpPasswordUpdateSender(
+ EmailArguments ea, @Assisted IdentifiedUser user, @Assisted String operation) {
+ super(ea, "HttpPasswordUpdate");
+ this.user = user;
+ this.operation = operation;
+ }
+
+ @Override
+ protected void init() throws EmailException {
+ super.init();
+ setHeader("Subject", "[Gerrit Code Review] HTTP password was " + operation);
+ add(RecipientType.TO, new Address(getEmail()));
+ }
+
+ @Override
+ protected boolean shouldSendMessage() {
+ // Always send an email if the HTTP password is updated.
+ return true;
+ }
+
+ @Override
+ protected void format() throws EmailException {
+ appendText(textTemplate("HttpPasswordUpdate"));
+ if (useHtml()) {
+ appendHtml(soyHtmlTemplate("HttpPasswordUpdateHtml"));
+ }
+ }
+
+ public String getEmail() {
+ return user.getAccount().getPreferredEmail();
+ }
+
+ public String getUserNameEmail() {
+ return getUserNameEmailFor(user.getAccountId());
+ }
+
+ @Override
+ protected void setupSoyContext() {
+ super.setupSoyContext();
+ soyContextEmailData.put("email", getEmail());
+ soyContextEmailData.put("userNameEmail", getUserNameEmail());
+ soyContextEmailData.put("operation", operation);
+ }
+
+ @Override
+ protected boolean supportsHtml() {
+ return true;
+ }
+}
diff --git a/java/com/google/gerrit/server/mail/send/MailSoyTofuProvider.java b/java/com/google/gerrit/server/mail/send/MailSoyTofuProvider.java
index 8d7df41..3bb44c7 100644
--- a/java/com/google/gerrit/server/mail/send/MailSoyTofuProvider.java
+++ b/java/com/google/gerrit/server/mail/send/MailSoyTofuProvider.java
@@ -47,6 +47,8 @@
"CommentHtml.soy",
"CommentFooter.soy",
"CommentFooterHtml.soy",
+ "DeleteKey.soy",
+ "DeleteKeyHtml.soy",
"DeleteReviewer.soy",
"DeleteReviewerHtml.soy",
"DeleteVote.soy",
@@ -56,6 +58,8 @@
"Footer.soy",
"FooterHtml.soy",
"HeaderHtml.soy",
+ "HttpPasswordUpdate.soy",
+ "HttpPasswordUpdateHtml.soy",
"Merged.soy",
"MergedHtml.soy",
"NewChange.soy",
diff --git a/java/com/google/gerrit/server/mail/send/MergedSender.java b/java/com/google/gerrit/server/mail/send/MergedSender.java
index cbc4117..4a4a732 100644
--- a/java/com/google/gerrit/server/mail/send/MergedSender.java
+++ b/java/com/google/gerrit/server/mail/send/MergedSender.java
@@ -69,15 +69,15 @@
Table<Account.Id, String, PatchSetApproval> pos = HashBasedTable.create();
Table<Account.Id, String, PatchSetApproval> neg = HashBasedTable.create();
for (PatchSetApproval ca :
- args.approvalsUtil.byPatchSet(changeData.notes(), patchSet.getId(), null, null)) {
- LabelType lt = labelTypes.byLabel(ca.getLabelId());
+ args.approvalsUtil.byPatchSet(changeData.notes(), patchSet.id(), null, null)) {
+ LabelType lt = labelTypes.byLabel(ca.labelId());
if (lt == null) {
continue;
}
- if (ca.getValue() > 0) {
- pos.put(ca.getAccountId(), lt.getName(), ca);
- } else if (ca.getValue() < 0) {
- neg.put(ca.getAccountId(), lt.getName(), ca);
+ if (ca.value() > 0) {
+ pos.put(ca.accountId(), lt.getName(), ca);
+ } else if (ca.value() < 0) {
+ neg.put(ca.accountId(), lt.getName(), ca);
}
}
@@ -117,7 +117,7 @@
} else {
txt.append(lt.getName());
txt.append('=');
- txt.append(LabelValue.formatValue(ca.getValue()));
+ txt.append(LabelValue.formatValue(ca.value()));
}
}
txt.append('\n');
diff --git a/java/com/google/gerrit/server/mail/send/NotificationEmail.java b/java/com/google/gerrit/server/mail/send/NotificationEmail.java
index 10d6ba5..f738367 100644
--- a/java/com/google/gerrit/server/mail/send/NotificationEmail.java
+++ b/java/com/google/gerrit/server/mail/send/NotificationEmail.java
@@ -131,6 +131,9 @@
if (lastIndexSlash == 0) {
return projectName.substring(1); // Remove the first slash
}
+ if (lastIndexSlash == -1) { // No slash in the project name
+ return projectName;
+ }
return "..." + projectName.substring(lastIndexSlash + 1);
}
diff --git a/java/com/google/gerrit/server/notedb/AllUsersAsyncUpdate.java b/java/com/google/gerrit/server/notedb/AllUsersAsyncUpdate.java
new file mode 100644
index 0000000..5d909d0
--- /dev/null
+++ b/java/com/google/gerrit/server/notedb/AllUsersAsyncUpdate.java
@@ -0,0 +1,116 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.notedb;
+
+import static com.google.common.base.MoreObjects.firstNonNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.MultimapBuilder;
+import com.google.common.flogger.FluentLogger;
+import com.google.gerrit.git.RefUpdateUtil;
+import com.google.gerrit.server.FanOutExecutor;
+import com.google.gerrit.server.config.AllUsersName;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import javax.inject.Inject;
+import org.eclipse.jgit.lib.BatchRefUpdate;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.transport.PushCertificate;
+
+/**
+ * Performs an update on {@code All-Users} asynchronously if required. No-op in case no updates were
+ * scheduled for asynchronous execution.
+ */
+public class AllUsersAsyncUpdate {
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+
+ private final ExecutorService executor;
+ private final AllUsersName allUsersName;
+ private final GitRepositoryManager repoManager;
+ private final ListMultimap<String, ChangeDraftUpdate> draftUpdates;
+
+ private PersonIdent serverIdent;
+
+ @Inject
+ AllUsersAsyncUpdate(
+ @FanOutExecutor ExecutorService executor,
+ AllUsersName allUsersName,
+ GitRepositoryManager repoManager) {
+ this.executor = executor;
+ this.allUsersName = allUsersName;
+ this.repoManager = repoManager;
+ this.draftUpdates = MultimapBuilder.hashKeys().arrayListValues().build();
+ }
+
+ void setDraftUpdates(ListMultimap<String, ChangeDraftUpdate> draftUpdates) {
+ checkState(isEmpty(), "attempted to set draft comment updates for async execution twice");
+ boolean allPublishOnly =
+ draftUpdates.values().stream().allMatch(ChangeDraftUpdate::canRunAsync);
+ checkState(allPublishOnly, "not all updates can be run asynchronously");
+ // Add deep copies to avoid any threading issues.
+ for (Map.Entry<String, ChangeDraftUpdate> entry : draftUpdates.entries()) {
+ this.draftUpdates.put(entry.getKey(), entry.getValue().copy());
+ }
+ if (draftUpdates.size() > 0) {
+ // Save the PersonIdent for later so that we get consistent time stamps in the commit and ref
+ // log.
+ serverIdent = Iterables.get(draftUpdates.entries(), 0).getValue().serverIdent;
+ }
+ }
+
+ /** Returns true if no operations should be performed on the repo. */
+ boolean isEmpty() {
+ return draftUpdates.isEmpty();
+ }
+
+ /** Executes repository update asynchronously. No-op in case no updates were scheduled. */
+ void execute(PersonIdent refLogIdent, String refLogMessage, PushCertificate pushCert) {
+ if (isEmpty()) {
+ return;
+ }
+
+ @SuppressWarnings("unused")
+ Future<?> possiblyIgnoredError =
+ executor.submit(
+ () -> {
+ try (OpenRepo allUsersRepo = OpenRepo.open(repoManager, allUsersName)) {
+ allUsersRepo.addUpdates(draftUpdates);
+ allUsersRepo.flush();
+ BatchRefUpdate bru = allUsersRepo.repo.getRefDatabase().newBatchUpdate();
+ bru.setPushCertificate(pushCert);
+ if (refLogMessage != null) {
+ bru.setRefLogMessage(refLogMessage, false);
+ } else {
+ bru.setRefLogMessage(
+ firstNonNull(NoteDbUtil.guessRestApiHandler(), "Update NoteDb refs async"),
+ false);
+ }
+ bru.setRefLogIdent(refLogIdent != null ? refLogIdent : serverIdent);
+ bru.setAtomic(true);
+ allUsersRepo.cmds.addTo(bru);
+ bru.setAllowNonFastForwards(true);
+ RefUpdateUtil.executeChecked(bru, allUsersRepo.rw);
+ } catch (IOException e) {
+ logger.atSevere().withCause(e).log(
+ "Failed to delete draft comments asynchronously after publishing them");
+ }
+ });
+ }
+}
diff --git a/java/com/google/gerrit/server/notedb/ChangeDraftUpdate.java b/java/com/google/gerrit/server/notedb/ChangeDraftUpdate.java
index 3bd0e34..bf27019 100644
--- a/java/com/google/gerrit/server/notedb/ChangeDraftUpdate.java
+++ b/java/com/google/gerrit/server/notedb/ChangeDraftUpdate.java
@@ -15,6 +15,7 @@
package com.google.gerrit.server.notedb;
import static com.google.common.base.MoreObjects.firstNonNull;
+import static com.google.common.base.Preconditions.checkState;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
import com.google.auto.value.AutoValue;
@@ -34,7 +35,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
-import java.util.HashSet;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -78,6 +79,12 @@
abstract Comment.Key key();
}
+ enum DeleteReason {
+ DELETED,
+ PUBLISHED,
+ FIXED
+ }
+
private static Key key(Comment c) {
return new AutoValue_ChangeDraftUpdate_Key(c.getCommitId(), c.key);
}
@@ -85,7 +92,7 @@
private final AllUsersName draftsProject;
private List<Comment> put = new ArrayList<>();
- private Set<Key> delete = new HashSet<>();
+ private Map<Key, DeleteReason> delete = new HashMap<>();
@AssistedInject
private ChangeDraftUpdate(
@@ -116,17 +123,69 @@
}
public void putComment(Comment c) {
+ checkState(!put.contains(c), "comment already added");
verifyComment(c);
put.add(c);
}
- public void deleteComment(Comment c) {
+ /**
+ * Marks a comment for deletion. Called when the comment is deleted because the user published it.
+ */
+ public void markCommentPublished(Comment c) {
+ checkState(!delete.containsKey(key(c)), "comment already marked for deletion");
verifyComment(c);
- delete.add(key(c));
+ delete.put(key(c), DeleteReason.PUBLISHED);
}
+ /**
+ * Marks a comment for deletion. Called when the comment is deleted because the user removed it.
+ */
+ public void deleteComment(Comment c) {
+ checkState(!delete.containsKey(key(c)), "comment already marked for deletion");
+ verifyComment(c);
+ delete.put(key(c), DeleteReason.DELETED);
+ }
+
+ /**
+ * Marks a comment for deletion. Called when the comment should have been deleted previously, but
+ * wasn't, so we're fixing it up.
+ */
public void deleteComment(ObjectId commitId, Comment.Key key) {
- delete.add(new AutoValue_ChangeDraftUpdate_Key(commitId, key));
+ Key commentKey = new AutoValue_ChangeDraftUpdate_Key(commitId, key);
+ checkState(!delete.containsKey(commentKey), "comment already marked for deletion");
+ delete.put(commentKey, DeleteReason.FIXED);
+ }
+
+ /**
+ * Returns true if all we do in this operations is deletes caused by publishing or fixing up
+ * comments.
+ */
+ public boolean canRunAsync() {
+ return put.isEmpty()
+ && delete.values().stream()
+ .allMatch(r -> r == DeleteReason.PUBLISHED || r == DeleteReason.FIXED);
+ }
+
+ /**
+ * Returns a copy of the current {@link ChangeDraftUpdate} that contains references to all
+ * deletions. Copying of {@link ChangeDraftUpdate} is only allowed if it contains no new comments.
+ */
+ ChangeDraftUpdate copy() {
+ checkState(
+ put.isEmpty(),
+ "copying ChangeDraftUpdate is allowed only if it doesn't contain new comments");
+ ChangeDraftUpdate clonedUpdate =
+ new ChangeDraftUpdate(
+ authorIdent,
+ draftsProject,
+ noteUtil,
+ new Change(getChange()),
+ accountId,
+ realAccountId,
+ authorIdent,
+ when);
+ clonedUpdate.delete.putAll(delete);
+ return clonedUpdate;
}
private CommitBuilder storeCommentsInNotes(
@@ -137,11 +196,11 @@
RevisionNoteBuilder.Cache cache = new RevisionNoteBuilder.Cache(rnm);
for (Comment c : put) {
- if (!delete.contains(key(c))) {
+ if (!delete.keySet().contains(key(c))) {
cache.get(c.getCommitId()).putComment(c);
}
}
- for (Key k : delete) {
+ for (Key k : delete.keySet()) {
cache.get(k.commitId()).deleteComment(k.key());
}
diff --git a/java/com/google/gerrit/server/notedb/ChangeNotes.java b/java/com/google/gerrit/server/notedb/ChangeNotes.java
index 280e5c5..e1217c2 100644
--- a/java/com/google/gerrit/server/notedb/ChangeNotes.java
+++ b/java/com/google/gerrit/server/notedb/ChangeNotes.java
@@ -62,7 +62,6 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
@@ -77,7 +76,7 @@
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
static final Ordering<PatchSetApproval> PSA_BY_TIME =
- Ordering.from(comparing(PatchSetApproval::getGranted));
+ Ordering.from(comparing(PatchSetApproval::granted));
public static final Ordering<ChangeMessage> MESSAGE_BY_TIME =
Ordering.from(comparing(ChangeMessage::getWrittenOn));
@@ -330,9 +329,7 @@
if (patchSets == null) {
ImmutableSortedMap.Builder<PatchSet.Id, PatchSet> b =
ImmutableSortedMap.orderedBy(comparing(PatchSet.Id::get));
- for (Map.Entry<PatchSet.Id, PatchSet> e : state.patchSets()) {
- b.put(e.getKey(), new PatchSet(e.getValue()));
- }
+ b.putAll(state.patchSets());
patchSets = b.build();
}
return patchSets;
@@ -340,12 +337,7 @@
public ImmutableListMultimap<PatchSet.Id, PatchSetApproval> getApprovals() {
if (approvals == null) {
- ImmutableListMultimap.Builder<PatchSet.Id, PatchSetApproval> b =
- ImmutableListMultimap.builder();
- for (Map.Entry<PatchSet.Id, PatchSetApproval> e : state.approvals()) {
- b.put(e.getKey(), new PatchSetApproval(e.getValue()));
- }
- approvals = b.build();
+ approvals = ImmutableListMultimap.copyOf(state.approvals());
}
return approvals;
}
diff --git a/java/com/google/gerrit/server/notedb/ChangeNotesParser.java b/java/com/google/gerrit/server/notedb/ChangeNotesParser.java
index 4588be6..185f651 100644
--- a/java/com/google/gerrit/server/notedb/ChangeNotesParser.java
+++ b/java/com/google/gerrit/server/notedb/ChangeNotesParser.java
@@ -40,7 +40,6 @@
import static java.util.Comparator.comparing;
import static java.util.stream.Collectors.joining;
-import com.google.auto.value.AutoValue;
import com.google.common.base.Enums;
import com.google.common.base.Splitter;
import com.google.common.collect.HashBasedTable;
@@ -48,6 +47,7 @@
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import com.google.common.collect.MultimapBuilder;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;
@@ -100,31 +100,6 @@
class ChangeNotesParser {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
- @AutoValue
- abstract static class ApprovalKey {
- abstract PatchSet.Id psId();
-
- abstract Account.Id accountId();
-
- abstract String label();
-
- private static ApprovalKey create(PatchSet.Id psId, Account.Id accountId, String label) {
- return new AutoValue_ChangeNotesParser_ApprovalKey(psId, accountId, label);
- }
- }
-
- /**
- * Subset of field on patch sets that are mutable after patch set creation, and therefore may be
- * parsed before the rest of the patch set is available.
- *
- * <p>In the future, if {@code PatchSet} becomes an immutable type with a builder, this class can
- * be replaced with the builder. For now, keep it as simple as possible.
- */
- static class PendingPatchSetFields {
- List<String> groups = Collections.emptyList();
- String description;
- }
-
// Private final members initialized in the constructor.
private final ChangeNoteJson changeNoteJson;
private final LegacyChangeNoteRead legacyChangeNoteRead;
@@ -142,13 +117,12 @@
private final List<ReviewerStatusUpdate> reviewerUpdates;
private final List<SubmitRecord> submitRecords;
private final ListMultimap<ObjectId, Comment> comments;
- private final Map<PatchSet.Id, PatchSet> patchSets;
- private final Map<PatchSet.Id, PendingPatchSetFields> pendingPatchSets;
+ private final Map<PatchSet.Id, PatchSet.Builder> patchSets;
private final Set<PatchSet.Id> deletedPatchSets;
private final Map<PatchSet.Id, PatchSetState> patchSetStates;
private final List<PatchSet.Id> currentPatchSets;
- private final Map<ApprovalKey, PatchSetApproval> approvals;
- private final List<PatchSetApproval> bufferedApprovals;
+ private final Map<PatchSetApproval.Key, PatchSetApproval.Builder> approvals;
+ private final List<PatchSetApproval.Builder> bufferedApprovals;
private final List<ChangeMessage> allChangeMessages;
// Non-final private members filled in during the parsing process.
@@ -201,7 +175,6 @@
allChangeMessages = new ArrayList<>();
comments = MultimapBuilder.hashKeys().arrayListValues().build();
patchSets = new HashMap<>();
- pendingPatchSets = new HashMap<>();
deletedPatchSets = new HashSet<>();
patchSetStates = new HashMap<>();
currentPatchSets = new ArrayList<>();
@@ -242,7 +215,7 @@
return revisionNoteMap;
}
- private ChangeNotesState buildState() {
+ private ChangeNotesState buildState() throws ConfigInvalidException {
return ChangeNotesState.create(
tip.copy(),
id,
@@ -260,7 +233,7 @@
status,
Sets.newLinkedHashSet(Lists.reverse(pastAssignees)),
firstNonNull(hashtags, ImmutableSet.of()),
- patchSets,
+ buildPatchSets(),
buildApprovals(),
ReviewerSet.fromTable(Tables.transpose(reviewers)),
ReviewerByEmailSet.fromTable(Tables.transpose(reviewersByEmail)),
@@ -278,11 +251,26 @@
updateCount);
}
+ private Map<PatchSet.Id, PatchSet> buildPatchSets() throws ConfigInvalidException {
+ Map<PatchSet.Id, PatchSet> result = Maps.newHashMapWithExpectedSize(patchSets.size());
+ for (Map.Entry<PatchSet.Id, PatchSet.Builder> e : patchSets.entrySet()) {
+ try {
+ PatchSet ps = e.getValue().build();
+ result.put(ps.id(), ps);
+ } catch (Exception ex) {
+ ConfigInvalidException cie = parseException("Error building patch set %s", e.getKey());
+ cie.initCause(ex);
+ throw cie;
+ }
+ }
+ return result;
+ }
+
private PatchSet.Id buildCurrentPatchSetId() {
// currentPatchSets are in parse order, i.e. newest first. Pick the first
// patch set that was marked as current, excluding deleted patch sets.
for (PatchSet.Id psId : currentPatchSets) {
- if (patchSets.containsKey(psId)) {
+ if (patchSetCommitParsed(psId)) {
return psId;
}
}
@@ -292,14 +280,14 @@
private ListMultimap<PatchSet.Id, PatchSetApproval> buildApprovals() {
ListMultimap<PatchSet.Id, PatchSetApproval> result =
MultimapBuilder.hashKeys().arrayListValues().build();
- for (PatchSetApproval a : approvals.values()) {
- if (!patchSets.containsKey(a.getPatchSetId())) {
+ for (PatchSetApproval.Builder a : approvals.values()) {
+ if (!patchSetCommitParsed(a.key().patchSetId())) {
continue; // Patch set deleted or missing.
- } else if (allPastReviewers.contains(a.getAccountId())
- && !reviewers.containsRow(a.getAccountId())) {
+ } else if (allPastReviewers.contains(a.key().accountId())
+ && !reviewers.containsRow(a.key().accountId())) {
continue; // Reviewer was explicitly removed.
}
- result.put(a.getPatchSetId(), a);
+ result.put(a.key().patchSetId(), a.build());
}
result.keySet().forEach(k -> result.get(k).sort(ChangeNotes.PSA_BY_TIME));
return result;
@@ -496,25 +484,27 @@
if (accountId == null) {
throw parseException("patch set %s requires an identified user as uploader", psId.get());
}
- if (patchSets.containsKey(psId)) {
+ if (patchSetCommitParsed(psId)) {
if (deletedPatchSets.contains(psId)) {
// Do not update PS details as PS was deleted and this meta data is of no relevance.
return;
}
+ ObjectId commitId = patchSets.get(psId).commitId().orElseThrow(IllegalStateException::new);
throw new ConfigInvalidException(
String.format(
"Multiple revisions parsed for patch set %s: %s and %s",
- psId.get(), patchSets.get(psId).getCommitId().name(), rev.name()));
+ psId.get(), commitId.name(), rev.name()));
}
- PatchSet ps = new PatchSet(psId, rev);
- patchSets.put(psId, ps);
- ps.setUploader(accountId);
- ps.setCreatedOn(ts);
- PendingPatchSetFields pending = pendingPatchSets.remove(psId);
- if (pending != null) {
- ps.setGroups(pending.groups);
- ps.setDescription(pending.description);
- }
+ patchSets
+ .computeIfAbsent(psId, id -> PatchSet.builder())
+ .id(psId)
+ .commitId(rev)
+ .uploader(accountId)
+ .createdOn(ts);
+ // Fields not set here:
+ // * Groups, parsed earlier in parseGroups.
+ // * Description, parsed earlier in parseDescription.
+ // * Push certificate, parsed later in parseNotes.
}
private void parseGroups(PatchSet.Id psId, ChangeNotesCommit commit)
@@ -523,13 +513,10 @@
if (groupsStr == null) {
return;
}
- if (patchSets.containsKey(psId)) {
- throw patchSetFieldBeforeDefinition(psId, FOOTER_GROUPS);
- }
- PendingPatchSetFields pending =
- pendingPatchSets.computeIfAbsent(psId, p -> new PendingPatchSetFields());
- if (pending.groups.isEmpty()) {
- pending.groups = PatchSet.splitGroups(groupsStr);
+ checkPatchSetCommitNotParsed(psId, FOOTER_GROUPS);
+ PatchSet.Builder pending = patchSets.computeIfAbsent(psId, id -> PatchSet.builder());
+ if (pending.groups().isEmpty()) {
+ pending.groups(PatchSet.splitGroups(groupsStr));
}
}
@@ -625,9 +612,9 @@
// exception is the legacy SUBM approval, which is never considered post-submit, but might end
// up sorted after the submit during rebuilding.
if (status == Change.Status.MERGED) {
- for (PatchSetApproval psa : bufferedApprovals) {
- if (!psa.isLegacySubmit()) {
- psa.setPostSubmit(true);
+ for (PatchSetApproval.Builder psa : bufferedApprovals) {
+ if (!psa.key().isLegacySubmit()) {
+ psa.postSubmit(true);
}
}
}
@@ -673,15 +660,12 @@
return;
}
- if (patchSets.containsKey(psId)) {
- throw patchSetFieldBeforeDefinition(psId, FOOTER_PATCH_SET_DESCRIPTION);
- }
+ checkPatchSetCommitNotParsed(psId, FOOTER_PATCH_SET_DESCRIPTION);
if (descLines.size() == 1) {
String desc = descLines.get(0).trim();
- PendingPatchSetFields pending =
- pendingPatchSets.computeIfAbsent(psId, p -> new PendingPatchSetFields());
- if (pending.description == null) {
- pending.description = desc;
+ PatchSet.Builder pending = patchSets.computeIfAbsent(psId, p -> PatchSet.builder());
+ if (!pending.description().isPresent()) {
+ pending.description(Optional.of(desc));
}
} else {
throw expectedOneFooter(FOOTER_PATCH_SET_DESCRIPTION, descLines);
@@ -740,10 +724,15 @@
}
}
- for (PatchSet ps : patchSets.values()) {
- ChangeRevisionNote rn = rns.get(ps.getCommitId());
+ for (PatchSet.Builder b : patchSets.values()) {
+ ObjectId commitId =
+ b.commitId()
+ .orElseThrow(
+ () ->
+ new IllegalStateException("never parsed commit ID for patch set " + b.id()));
+ ChangeRevisionNote rn = rns.get(commitId);
if (rn != null && rn.getPushCert() != null) {
- ps.setPushCertificate(rn.getPushCert());
+ b.pushCertificate(Optional.of(rn.getPushCert()));
}
}
}
@@ -754,7 +743,7 @@
if (accountId == null) {
throw parseException("patch set %s requires an identified user as uploader", psId.get());
}
- PatchSetApproval psa;
+ PatchSetApproval.Builder psa;
if (line.startsWith("-")) {
psa = parseRemoveApproval(psId, accountId, realAccountId, ts, line);
} else {
@@ -763,7 +752,7 @@
bufferedApprovals.add(psa);
}
- private PatchSetApproval parseAddApproval(
+ private PatchSetApproval.Builder parseAddApproval(
PatchSet.Id psId, Account.Id committerId, Account.Id realAccountId, Timestamp ts, String line)
throws ConfigInvalidException {
// There are potentially 3 accounts involved here:
@@ -800,23 +789,20 @@
throw pe;
}
- PatchSetApproval psa =
- new PatchSetApproval(
- PatchSetApproval.key(psId, effectiveAccountId, LabelId.create(l.label())),
- l.value(),
- ts);
- psa.setTag(tag);
+ PatchSetApproval.Builder psa =
+ PatchSetApproval.builder()
+ .key(PatchSetApproval.key(psId, effectiveAccountId, LabelId.create(l.label())))
+ .value(l.value())
+ .granted(ts)
+ .tag(Optional.ofNullable(tag));
if (!Objects.equals(realAccountId, committerId)) {
- psa.setRealAccountId(realAccountId);
+ psa.realAccountId(realAccountId);
}
- ApprovalKey k = ApprovalKey.create(psId, effectiveAccountId, l.label());
- if (!approvals.containsKey(k)) {
- approvals.put(k, psa);
- }
+ approvals.putIfAbsent(psa.key(), psa);
return psa;
}
- private PatchSetApproval parseRemoveApproval(
+ private PatchSetApproval.Builder parseRemoveApproval(
PatchSet.Id psId, Account.Id committerId, Account.Id realAccountId, Timestamp ts, String line)
throws ConfigInvalidException {
// See comments in parseAddApproval about the various users involved.
@@ -843,16 +829,15 @@
// Store an actual 0-vote approval in the map for a removed approval, because ApprovalCopier
// needs an actual approval in order to block copying an earlier approval over a later delete.
- PatchSetApproval remove =
- new PatchSetApproval(
- PatchSetApproval.key(psId, effectiveAccountId, LabelId.create(label)), (short) 0, ts);
+ PatchSetApproval.Builder remove =
+ PatchSetApproval.builder()
+ .key(PatchSetApproval.key(psId, effectiveAccountId, LabelId.create(label)))
+ .value(0)
+ .granted(ts);
if (!Objects.equals(realAccountId, committerId)) {
- remove.setRealAccountId(realAccountId);
+ remove.realAccountId(realAccountId);
}
- ApprovalKey k = ApprovalKey.create(psId, effectiveAccountId, label);
- if (!approvals.containsKey(k)) {
- approvals.put(k, remove);
- }
+ approvals.putIfAbsent(remove.key(), remove);
return remove;
}
@@ -1014,7 +999,7 @@
private void updatePatchSetStates() {
Set<PatchSet.Id> missing = new TreeSet<>(comparing(PatchSet.Id::get));
- missing.addAll(pendingPatchSets.keySet());
+ missing.addAll(patchSets.keySet());
for (Map.Entry<PatchSet.Id, PatchSetState> e : patchSetStates.entrySet()) {
switch (e.getValue()) {
case PUBLISHED:
@@ -1038,7 +1023,7 @@
comments.values(), c -> PatchSet.id(id, c.key.patchSetId), missing);
pruned +=
pruneEntitiesForMissingPatchSets(
- approvals.values(), PatchSetApproval::getPatchSetId, missing);
+ approvals.values(), psa -> psa.key().patchSetId(), missing);
if (!missing.isEmpty()) {
logger.atWarning().log(
@@ -1051,7 +1036,7 @@
int pruned = 0;
for (Iterator<T> it = ents.iterator(); it.hasNext(); ) {
PatchSet.Id psId = psIdFunc.apply(it.next());
- if (!patchSets.containsKey(psId)) {
+ if (!patchSetCommitParsed(psId)) {
pruned++;
missing.add(psId);
it.remove();
@@ -1094,11 +1079,18 @@
}
}
- private ConfigInvalidException patchSetFieldBeforeDefinition(
- PatchSet.Id psId, FooterKey footerPatchSetDescription) {
- return parseException(
- "%s field found for patch set %s before it was defined",
- footerPatchSetDescription.getName(), psId.get());
+ private void checkPatchSetCommitNotParsed(PatchSet.Id psId, FooterKey footer)
+ throws ConfigInvalidException {
+ if (patchSetCommitParsed(psId)) {
+ throw parseException(
+ "%s field found for patch set %s before patch set was originally defined",
+ footer.getName(), psId.get());
+ }
+ }
+
+ private boolean patchSetCommitParsed(PatchSet.Id psId) {
+ PatchSet.Builder pending = patchSets.get(psId);
+ return pending != null && pending.commitId().isPresent();
}
private ConfigInvalidException parseException(String fmt, Object... args) {
diff --git a/java/com/google/gerrit/server/notedb/ChangeNotesState.java b/java/com/google/gerrit/server/notedb/ChangeNotesState.java
index 74f32ab..2728516 100644
--- a/java/com/google/gerrit/server/notedb/ChangeNotesState.java
+++ b/java/com/google/gerrit/server/notedb/ChangeNotesState.java
@@ -555,12 +555,12 @@
.patchSets(
proto.getPatchSetList().stream()
.map(bytes -> parseProtoFrom(PatchSetProtoConverter.INSTANCE, bytes))
- .map(ps -> Maps.immutableEntry(ps.getId(), ps))
+ .map(ps -> Maps.immutableEntry(ps.id(), ps))
.collect(toImmutableList()))
.approvals(
proto.getApprovalList().stream()
.map(bytes -> parseProtoFrom(PatchSetApprovalProtoConverter.INSTANCE, bytes))
- .map(a -> Maps.immutableEntry(a.getPatchSetId(), a))
+ .map(a -> Maps.immutableEntry(a.patchSetId(), a))
.collect(toImmutableList()))
.reviewers(toReviewerSet(proto.getReviewerList()))
.reviewersByEmail(toReviewerByEmailSet(proto.getReviewerByEmailList()))
diff --git a/java/com/google/gerrit/server/notedb/ChangeUpdate.java b/java/com/google/gerrit/server/notedb/ChangeUpdate.java
index ab78931..8e751de 100644
--- a/java/com/google/gerrit/server/notedb/ChangeUpdate.java
+++ b/java/com/google/gerrit/server/notedb/ChangeUpdate.java
@@ -280,11 +280,7 @@
draftUpdate.putComment(c);
} else {
comments.add(c);
- // Always delete the corresponding comment from drafts. Published comments
- // are immutable, meaning in normal operation we only hit this path when
- // publishing a comment. It's exactly in that case that we have to delete
- // the draft.
- draftUpdate.deleteComment(c);
+ draftUpdate.markCommentPublished(c);
}
}
@@ -414,7 +410,7 @@
}
public void setRevertOf(int revertOf) {
- int ownId = getChange().getId().get();
+ int ownId = getId().get();
checkArgument(ownId != revertOf, "A change cannot revert itself");
this.revertOf = revertOf;
rootOnly = true;
diff --git a/java/com/google/gerrit/server/notedb/DeleteChangeMessageRewriter.java b/java/com/google/gerrit/server/notedb/DeleteChangeMessageRewriter.java
index 8fb28e1..6d0530a 100644
--- a/java/com/google/gerrit/server/notedb/DeleteChangeMessageRewriter.java
+++ b/java/com/google/gerrit/server/notedb/DeleteChangeMessageRewriter.java
@@ -15,9 +15,9 @@
package com.google.gerrit.server.notedb;
import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.parseCommitMessageRange;
+import static java.util.Objects.requireNonNull;
import static org.eclipse.jgit.util.RawParseUtils.decode;
import com.google.gerrit.reviewdb.client.Change;
@@ -46,7 +46,7 @@
DeleteChangeMessageRewriter(Change.Id changeId, String targetMessageId, String newChangeMessage) {
this.changeId = changeId;
- this.targetMessageId = checkNotNull(targetMessageId);
+ this.targetMessageId = requireNonNull(targetMessageId);
this.newChangeMessage = newChangeMessage;
}
diff --git a/java/com/google/gerrit/server/notedb/NoteDbUpdateManager.java b/java/com/google/gerrit/server/notedb/NoteDbUpdateManager.java
index 460cfae..e3a9a92 100644
--- a/java/com/google/gerrit/server/notedb/NoteDbUpdateManager.java
+++ b/java/com/google/gerrit/server/notedb/NoteDbUpdateManager.java
@@ -18,16 +18,11 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.gerrit.server.notedb.NoteDbTable.CHANGES;
-import static java.util.Objects.requireNonNull;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.MultimapBuilder;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.exceptions.StorageException;
-import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.git.RefUpdateUtil;
import com.google.gerrit.metrics.Timer1;
import com.google.gerrit.reviewdb.client.Change;
@@ -37,10 +32,7 @@
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.git.GitRepositoryManager;
-import com.google.gerrit.server.git.InMemoryInserter;
-import com.google.gerrit.server.git.InsertedObject;
import com.google.gerrit.server.update.ChainedReceiveCommands;
-import com.google.gerrit.server.update.RetryingRestModifyView;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted;
@@ -48,7 +40,6 @@
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
-import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import org.eclipse.jgit.errors.ConfigInvalidException;
@@ -56,7 +47,6 @@
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
-import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
@@ -74,98 +64,10 @@
* {@link #stage()}.
*/
public class NoteDbUpdateManager implements AutoCloseable {
- private static final ImmutableList<String> PACKAGE_PREFIXES =
- ImmutableList.of("com.google.gerrit.server.", "com.google.gerrit.");
- private static final ImmutableSet<String> SERVLET_NAMES =
- ImmutableSet.of(
- "com.google.gerrit.httpd.restapi.RestApiServlet", RetryingRestModifyView.class.getName());
-
public interface Factory {
NoteDbUpdateManager create(Project.NameKey projectName);
}
- public static class TooManyUpdatesException extends StorageException {
- @VisibleForTesting
- public static String message(Change.Id id, int maxUpdates) {
- return "Change "
- + id
- + " may not exceed "
- + maxUpdates
- + " updates. It may still be abandoned or submitted. To continue working on this "
- + "change, recreate it with a new Change-Id, then abandon this one.";
- }
-
- private static final long serialVersionUID = 1L;
-
- private TooManyUpdatesException(Change.Id id, int maxUpdates) {
- super(message(id, maxUpdates));
- }
- }
-
- public static class OpenRepo implements AutoCloseable {
- public final Repository repo;
- public final RevWalk rw;
- public final ChainedReceiveCommands cmds;
-
- private final InMemoryInserter inMemIns;
- private final ObjectInserter tempIns;
- @Nullable private final ObjectInserter finalIns;
-
- private final boolean close;
-
- private OpenRepo(
- Repository repo,
- RevWalk rw,
- @Nullable ObjectInserter ins,
- ChainedReceiveCommands cmds,
- boolean close) {
- ObjectReader reader = rw.getObjectReader();
- checkArgument(
- ins == null || reader.getCreatedFromInserter() == ins,
- "expected reader to be created from %s, but was %s",
- ins,
- reader.getCreatedFromInserter());
- this.repo = requireNonNull(repo);
-
- this.inMemIns = new InMemoryInserter(rw.getObjectReader());
- this.tempIns = inMemIns;
-
- this.rw = new RevWalk(tempIns.newReader());
- this.finalIns = ins;
- this.cmds = requireNonNull(cmds);
- this.close = close;
- }
-
- public Optional<ObjectId> getObjectId(String refName) throws IOException {
- return cmds.get(refName);
- }
-
- void flush() throws IOException {
- flushToFinalInserter();
- finalIns.flush();
- }
-
- void flushToFinalInserter() throws IOException {
- checkState(finalIns != null);
- for (InsertedObject obj : inMemIns.getInsertedObjects()) {
- finalIns.insert(obj.type(), obj.data().toByteArray());
- }
- inMemIns.clear();
- }
-
- @Override
- public void close() {
- rw.getObjectReader().close();
- rw.close();
- if (close) {
- if (finalIns != null) {
- finalIns.close();
- }
- repo.close();
- }
- }
- }
-
private final Provider<PersonIdent> serverIdent;
private final GitRepositoryManager repoManager;
private final AllUsersName allUsersName;
@@ -180,6 +82,7 @@
private OpenRepo changeRepo;
private OpenRepo allUsersRepo;
+ private AllUsersAsyncUpdate updateAllUsersAsync;
private boolean executed;
private String refLogMessage;
private PersonIdent refLogIdent;
@@ -192,11 +95,13 @@
GitRepositoryManager repoManager,
AllUsersName allUsersName,
NoteDbMetrics metrics,
+ AllUsersAsyncUpdate updateAllUsersAsync,
@Assisted Project.NameKey projectName) {
this.serverIdent = serverIdent;
this.repoManager = repoManager;
this.allUsersName = allUsersName;
this.metrics = metrics;
+ this.updateAllUsersAsync = updateAllUsersAsync;
this.projectName = projectName;
maxUpdates = cfg.getInt("change", null, "maxUpdates", 1000);
changeUpdates = MultimapBuilder.hashKeys().arrayListValues().build();
@@ -261,28 +166,13 @@
private void initChangeRepo() throws IOException {
if (changeRepo == null) {
- changeRepo = openRepo(projectName);
+ changeRepo = OpenRepo.open(repoManager, projectName);
}
}
private void initAllUsersRepo() throws IOException {
if (allUsersRepo == null) {
- allUsersRepo = openRepo(allUsersName);
- }
- }
-
- private OpenRepo openRepo(Project.NameKey p) throws IOException {
- Repository repo = repoManager.openRepository(p); // Closed by OpenRepo#close.
- ObjectInserter ins = repo.newObjectInserter(); // Closed by OpenRepo#close.
- ObjectReader reader = ins.newReader(); // Not closed by OpenRepo#close.
- try (RevWalk rw = new RevWalk(reader)) { // Doesn't escape OpenRepo constructor.
- return new OpenRepo(repo, rw, ins, new ChainedReceiveCommands(repo), true) {
- @Override
- public void close() {
- reader.close();
- super.close();
- }
- };
+ allUsersRepo = OpenRepo.open(repoManager, allUsersName);
}
}
@@ -293,7 +183,8 @@
&& rewriters.isEmpty()
&& toDelete.isEmpty()
&& !hasCommands(changeRepo)
- && !hasCommands(allUsersRepo);
+ && !hasCommands(allUsersRepo)
+ && updateAllUsersAsync.isEmpty();
}
private static boolean hasCommands(@Nullable OpenRepo or) {
@@ -423,6 +314,13 @@
// comments can only go from DRAFT to PUBLISHED, not vice versa.
BatchRefUpdate result = execute(changeRepo, dryrun, pushCert);
execute(allUsersRepo, dryrun, null);
+ if (!dryrun) {
+ // Only execute the asynchronous operation if we are not in dry-run mode: The dry run would
+ // have to run synchronous to be of any value at all. For the removal of draft comments from
+ // All-Users we don't care much of the operation succeeds, so we are skipping the dry run
+ // altogether.
+ updateAllUsersAsync.execute(refLogIdent, refLogMessage, pushCert);
+ }
executed = true;
return result;
} finally {
@@ -448,7 +346,8 @@
if (refLogMessage != null) {
bru.setRefLogMessage(refLogMessage, false);
} else {
- bru.setRefLogMessage(firstNonNull(guessRestApiHandler(), "Update NoteDb refs"), false);
+ bru.setRefLogMessage(
+ firstNonNull(NoteDbUtil.guessRestApiHandler(), "Update NoteDb refs"), false);
}
bru.setRefLogIdent(refLogIdent != null ? refLogIdent : serverIdent.get());
bru.setAtomic(true);
@@ -461,59 +360,18 @@
return bru;
}
- private static String guessRestApiHandler() {
- StackTraceElement[] trace = Thread.currentThread().getStackTrace();
- int i = findRestApiServlet(trace);
- if (i < 0) {
- return null;
- }
- try {
- for (i--; i >= 0; i--) {
- String cn = trace[i].getClassName();
- Class<?> cls = Class.forName(cn);
- if (RestModifyView.class.isAssignableFrom(cls) && cls != RetryingRestModifyView.class) {
- return viewName(cn);
- }
- }
- return null;
- } catch (ClassNotFoundException e) {
- return null;
- }
- }
-
- private static String viewName(String cn) {
- String impl = cn.replace('$', '.');
- for (String p : PACKAGE_PREFIXES) {
- if (impl.startsWith(p)) {
- return impl.substring(p.length());
- }
- }
- return impl;
- }
-
- private static int findRestApiServlet(StackTraceElement[] trace) {
- for (int i = 0; i < trace.length; i++) {
- if (SERVLET_NAMES.contains(trace[i].getClassName())) {
- return i;
- }
- }
- return -1;
- }
-
private void addCommands() throws IOException {
- if (isEmpty()) {
- return;
- }
- checkState(changeRepo != null, "must set change repo");
+ changeRepo.addUpdates(changeUpdates, Optional.of(maxUpdates));
if (!draftUpdates.isEmpty()) {
- checkState(allUsersRepo != null, "must set all users repo");
- }
- addUpdates(changeUpdates, changeRepo, Optional.of(maxUpdates));
- if (!draftUpdates.isEmpty()) {
- addUpdates(draftUpdates, allUsersRepo, Optional.empty());
+ boolean publishOnly = draftUpdates.values().stream().allMatch(ChangeDraftUpdate::canRunAsync);
+ if (publishOnly) {
+ updateAllUsersAsync.setDraftUpdates(draftUpdates);
+ } else {
+ allUsersRepo.addUpdates(draftUpdates);
+ }
}
if (!robotCommentUpdates.isEmpty()) {
- addUpdates(robotCommentUpdates, changeRepo, Optional.empty());
+ changeRepo.addUpdates(robotCommentUpdates);
}
if (!rewriters.isEmpty()) {
addRewrites(rewriters, changeRepo);
@@ -545,51 +403,6 @@
checkState(!executed, "update has already been executed");
}
- private static <U extends AbstractChangeUpdate> void addUpdates(
- ListMultimap<String, U> all, OpenRepo or, Optional<Integer> maxUpdates) throws IOException {
- for (Map.Entry<String, Collection<U>> e : all.asMap().entrySet()) {
- String refName = e.getKey();
- Collection<U> updates = e.getValue();
- ObjectId old = or.cmds.get(refName).orElse(ObjectId.zeroId());
- // Only actually write to the ref if one of the updates explicitly allows
- // us to do so, i.e. it is known to represent a new change. This avoids
- // writing partial change meta if the change hasn't been backfilled yet.
- if (!allowWrite(updates, old)) {
- continue;
- }
-
- int updateCount;
- U first = updates.iterator().next();
- if (maxUpdates.isPresent()) {
- checkState(first.getNotes() != null, "expected ChangeNotes on %s", first);
- updateCount = first.getNotes().getUpdateCount();
- } else {
- updateCount = 0;
- }
-
- ObjectId curr = old;
- for (U u : updates) {
- if (u.isRootOnly() && !old.equals(ObjectId.zeroId())) {
- throw new StorageException("Given ChangeUpdate is only allowed on initial commit");
- }
- ObjectId next = u.apply(or.rw, or.tempIns, curr);
- if (next == null) {
- continue;
- }
- if (maxUpdates.isPresent()
- && !Objects.equals(next, curr)
- && ++updateCount > maxUpdates.get()
- && !u.bypassMaxUpdates()) {
- throw new TooManyUpdatesException(u.getId(), maxUpdates.get());
- }
- curr = next;
- }
- if (!old.equals(curr)) {
- or.cmds.add(new ReceiveCommand(old, curr, refName));
- }
- }
- }
-
private static void addRewrites(ListMultimap<String, NoteDbRewriter> rewriters, OpenRepo openRepo)
throws IOException {
for (Map.Entry<String, Collection<NoteDbRewriter>> entry : rewriters.asMap().entrySet()) {
@@ -618,12 +431,4 @@
}
}
}
-
- private static <U extends AbstractChangeUpdate> boolean allowWrite(
- Collection<U> updates, ObjectId old) {
- if (!old.equals(ObjectId.zeroId())) {
- return true;
- }
- return updates.iterator().next().allowWriteToNewRef();
- }
}
diff --git a/java/com/google/gerrit/server/notedb/NoteDbUtil.java b/java/com/google/gerrit/server/notedb/NoteDbUtil.java
index 6b8eb4b..c53f4b9 100644
--- a/java/com/google/gerrit/server/notedb/NoteDbUtil.java
+++ b/java/com/google/gerrit/server/notedb/NoteDbUtil.java
@@ -15,8 +15,12 @@
package com.google.gerrit.server.notedb;
import com.google.common.base.CharMatcher;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints;
+import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.server.update.RetryingRestModifyView;
import java.sql.Timestamp;
import java.util.Optional;
import org.eclipse.jgit.lib.PersonIdent;
@@ -25,6 +29,14 @@
public class NoteDbUtil {
+ private static final CharMatcher INVALID_FOOTER_CHARS = CharMatcher.anyOf("\r\n\0");
+
+ private static final ImmutableList<String> PACKAGE_PREFIXES =
+ ImmutableList.of("com.google.gerrit.server.", "com.google.gerrit.");
+ private static final ImmutableSet<String> SERVLET_NAMES =
+ ImmutableSet.of(
+ "com.google.gerrit.httpd.restapi.RestApiServlet", RetryingRestModifyView.class.getName());
+
/**
* Returns an AccountId for the given email address. Returns empty if the address isn't on this
* server.
@@ -44,8 +56,6 @@
return Optional.empty();
}
- private NoteDbUtil() {}
-
public static String formatTime(PersonIdent ident, Timestamp t) {
GitDateFormatter dateFormatter = new GitDateFormatter(Format.DEFAULT);
// TODO(dborowitz): Use a ThreadLocal or use Joda.
@@ -53,7 +63,29 @@
return dateFormatter.formatDate(newIdent);
}
- private static final CharMatcher INVALID_FOOTER_CHARS = CharMatcher.anyOf("\r\n\0");
+ /**
+ * Returns the name of the REST API handler that is in the stack trace of the caller of this
+ * method.
+ */
+ static String guessRestApiHandler() {
+ StackTraceElement[] trace = Thread.currentThread().getStackTrace();
+ int i = findRestApiServlet(trace);
+ if (i < 0) {
+ return null;
+ }
+ try {
+ for (i--; i >= 0; i--) {
+ String cn = trace[i].getClassName();
+ Class<?> cls = Class.forName(cn);
+ if (RestModifyView.class.isAssignableFrom(cls) && cls != RetryingRestModifyView.class) {
+ return viewName(cn);
+ }
+ }
+ return null;
+ } catch (ClassNotFoundException e) {
+ return null;
+ }
+ }
static String sanitizeFooter(String value) {
// Remove characters that would confuse JGit's footer parser if they were
@@ -65,4 +97,25 @@
// empty paragraph for the purposes of footer parsing.
return INVALID_FOOTER_CHARS.trimAndCollapseFrom(value, ' ');
}
+
+ private static int findRestApiServlet(StackTraceElement[] trace) {
+ for (int i = 0; i < trace.length; i++) {
+ if (SERVLET_NAMES.contains(trace[i].getClassName())) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ private static String viewName(String cn) {
+ String impl = cn.replace('$', '.');
+ for (String p : PACKAGE_PREFIXES) {
+ if (impl.startsWith(p)) {
+ return impl.substring(p.length());
+ }
+ }
+ return impl;
+ }
+
+ private NoteDbUtil() {}
}
diff --git a/java/com/google/gerrit/server/notedb/OpenRepo.java b/java/com/google/gerrit/server/notedb/OpenRepo.java
new file mode 100644
index 0000000..4595607
--- /dev/null
+++ b/java/com/google/gerrit/server/notedb/OpenRepo.java
@@ -0,0 +1,176 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.notedb;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ListMultimap;
+import com.google.gerrit.common.Nullable;
+import com.google.gerrit.exceptions.StorageException;
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.git.InMemoryInserter;
+import com.google.gerrit.server.git.InsertedObject;
+import com.google.gerrit.server.update.ChainedReceiveCommands;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.transport.ReceiveCommand;
+
+/**
+ * Wrapper around {@link Repository} that keeps track of related {@link ObjectInserter}s and other
+ * objects that are jointly closed when invoking {@link #close}.
+ */
+class OpenRepo implements AutoCloseable {
+ /** Returns a {@link OpenRepo} wrapping around an open {@link Repository}. */
+ static OpenRepo open(GitRepositoryManager repoManager, Project.NameKey project)
+ throws IOException {
+ Repository repo = repoManager.openRepository(project); // Closed by OpenRepo#close.
+ ObjectInserter ins = repo.newObjectInserter(); // Closed by OpenRepo#close.
+ ObjectReader reader = ins.newReader(); // Not closed by OpenRepo#close.
+ try (RevWalk rw = new RevWalk(reader)) { // Doesn't escape OpenRepo constructor.
+ return new OpenRepo(repo, rw, ins, new ChainedReceiveCommands(repo), true) {
+ @Override
+ public void close() {
+ reader.close();
+ super.close();
+ }
+ };
+ }
+ }
+
+ final Repository repo;
+ final RevWalk rw;
+ final ChainedReceiveCommands cmds;
+ final ObjectInserter tempIns;
+
+ private final InMemoryInserter inMemIns;
+ @Nullable private final ObjectInserter finalIns;
+ private final boolean close;
+
+ OpenRepo(
+ Repository repo,
+ RevWalk rw,
+ @Nullable ObjectInserter ins,
+ ChainedReceiveCommands cmds,
+ boolean close) {
+ ObjectReader reader = rw.getObjectReader();
+ checkArgument(
+ ins == null || reader.getCreatedFromInserter() == ins,
+ "expected reader to be created from %s, but was %s",
+ ins,
+ reader.getCreatedFromInserter());
+ this.repo = requireNonNull(repo);
+
+ this.inMemIns = new InMemoryInserter(rw.getObjectReader());
+ this.tempIns = inMemIns;
+
+ this.rw = new RevWalk(tempIns.newReader());
+ this.finalIns = ins;
+ this.cmds = requireNonNull(cmds);
+ this.close = close;
+ }
+
+ @Override
+ public void close() {
+ rw.getObjectReader().close();
+ rw.close();
+ if (close) {
+ if (finalIns != null) {
+ finalIns.close();
+ }
+ repo.close();
+ }
+ }
+
+ void flush() throws IOException {
+ flushToFinalInserter();
+ finalIns.flush();
+ }
+
+ void flushToFinalInserter() throws IOException {
+ checkState(finalIns != null);
+ for (InsertedObject obj : inMemIns.getInsertedObjects()) {
+ finalIns.insert(obj.type(), obj.data().toByteArray());
+ }
+ inMemIns.clear();
+ }
+
+ private static <U extends AbstractChangeUpdate> boolean allowWrite(
+ Collection<U> updates, ObjectId old) {
+ if (!old.equals(ObjectId.zeroId())) {
+ return true;
+ }
+ return updates.iterator().next().allowWriteToNewRef();
+ }
+
+ <U extends AbstractChangeUpdate> void addUpdates(ListMultimap<String, U> all) throws IOException {
+ addUpdates(all, Optional.empty());
+ }
+
+ <U extends AbstractChangeUpdate> void addUpdates(
+ ListMultimap<String, U> all, Optional<Integer> maxUpdates) throws IOException {
+ for (Map.Entry<String, Collection<U>> e : all.asMap().entrySet()) {
+ String refName = e.getKey();
+ Collection<U> updates = e.getValue();
+ ObjectId old = cmds.get(refName).orElse(ObjectId.zeroId());
+ // Only actually write to the ref if one of the updates explicitly allows
+ // us to do so, i.e. it is known to represent a new change. This avoids
+ // writing partial change meta if the change hasn't been backfilled yet.
+ if (!allowWrite(updates, old)) {
+ continue;
+ }
+
+ int updateCount;
+ U first = updates.iterator().next();
+ if (maxUpdates.isPresent()) {
+ checkState(first.getNotes() != null, "expected ChangeNotes on %s", first);
+ updateCount = first.getNotes().getUpdateCount();
+ } else {
+ updateCount = 0;
+ }
+
+ ObjectId curr = old;
+ for (U u : updates) {
+ if (u.isRootOnly() && !old.equals(ObjectId.zeroId())) {
+ throw new StorageException("Given ChangeUpdate is only allowed on initial commit");
+ }
+ ObjectId next = u.apply(rw, tempIns, curr);
+ if (next == null) {
+ continue;
+ }
+ if (maxUpdates.isPresent()
+ && !Objects.equals(next, curr)
+ && ++updateCount > maxUpdates.get()
+ && !u.bypassMaxUpdates()) {
+ throw new TooManyUpdatesException(u.getId(), maxUpdates.get());
+ }
+ curr = next;
+ }
+ if (!old.equals(curr)) {
+ cmds.add(new ReceiveCommand(old, curr, refName));
+ }
+ }
+ }
+}
diff --git a/java/com/google/gerrit/server/notedb/ReviewerStateInternal.java b/java/com/google/gerrit/server/notedb/ReviewerStateInternal.java
index fad9832..d5a7259 100644
--- a/java/com/google/gerrit/server/notedb/ReviewerStateInternal.java
+++ b/java/com/google/gerrit/server/notedb/ReviewerStateInternal.java
@@ -21,13 +21,13 @@
/** State of a reviewer on a change. */
public enum ReviewerStateInternal {
/** The user has contributed at least one nonzero vote on the change. */
- REVIEWER(new FooterKey("Reviewer"), ReviewerState.REVIEWER),
+ REVIEWER("Reviewer", ReviewerState.REVIEWER),
/** The reviewer was added to the change, but has not voted. */
- CC(new FooterKey("CC"), ReviewerState.CC),
+ CC("CC", ReviewerState.CC),
/** The user was previously a reviewer on the change, but was removed. */
- REMOVED(new FooterKey("Removed"), ReviewerState.REMOVED);
+ REMOVED("Removed", ReviewerState.REMOVED);
public static ReviewerStateInternal fromReviewerState(ReviewerState state) {
return ReviewerStateInternal.values()[state.ordinal()];
@@ -50,20 +50,20 @@
}
}
- private final FooterKey footerKey;
+ private final String footer;
private final ReviewerState state;
- ReviewerStateInternal(FooterKey footerKey, ReviewerState state) {
- this.footerKey = footerKey;
+ ReviewerStateInternal(String footer, ReviewerState state) {
+ this.footer = footer;
this.state = state;
}
FooterKey getFooterKey() {
- return footerKey;
+ return new FooterKey(footer);
}
FooterKey getByEmailFooterKey() {
- return new FooterKey(footerKey.getName() + "-email");
+ return new FooterKey(footer + "-email");
}
public ReviewerState asReviewerState() {
diff --git a/java/com/google/gerrit/server/notedb/TooManyUpdatesException.java b/java/com/google/gerrit/server/notedb/TooManyUpdatesException.java
new file mode 100644
index 0000000..421e8c4
--- /dev/null
+++ b/java/com/google/gerrit/server/notedb/TooManyUpdatesException.java
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.notedb;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.gerrit.exceptions.StorageException;
+import com.google.gerrit.reviewdb.client.Change;
+
+/**
+ * Exception indicating that the change has received too many updates. Further actions apart from
+ * {@code abandon} or {@code submit} are blocked.
+ */
+public class TooManyUpdatesException extends StorageException {
+ @VisibleForTesting
+ public static String message(Change.Id id, int maxUpdates) {
+ return "Change "
+ + id
+ + " may not exceed "
+ + maxUpdates
+ + " updates. It may still be abandoned or submitted. To continue working on this "
+ + "change, recreate it with a new Change-Id, then abandon this one.";
+ }
+
+ private static final long serialVersionUID = 1L;
+
+ TooManyUpdatesException(Change.Id id, int maxUpdates) {
+ super(message(id, maxUpdates));
+ }
+}
diff --git a/java/com/google/gerrit/server/patch/PatchFile.java b/java/com/google/gerrit/server/patch/PatchFile.java
index 1593b11..ec02485 100644
--- a/java/com/google/gerrit/server/patch/PatchFile.java
+++ b/java/com/google/gerrit/server/patch/PatchFile.java
@@ -39,6 +39,15 @@
private final RevTree aTree;
private final RevTree bTree;
+ // Full text of both sides of the file. For standard files, these are not directly reconstructable
+ // from the PatchListEntry, which comes from the PatchListCache and only contains the diff between
+ // the two blobs. This is intentional, to avoid storing entire large blobs in the cache. For
+ // regular files, the full text is initialized from the repo lazily only when necessary, e.g. in
+ // getLine. Although it's a safe assumption that any caller constructing a PatchSet will want to
+ // read some content, we don't know in advance which side they are interested in.
+ //
+ // For special files like COMMIT_MSG, the full text is loaded eagerly during the constructor.
+ // TODO(dborowitz): I see why the logic is different, but I don't see why it needs to be eager.
private Text a;
private Text b;
diff --git a/java/com/google/gerrit/server/patch/PatchListCacheImpl.java b/java/com/google/gerrit/server/patch/PatchListCacheImpl.java
index 0919e41..8201947 100644
--- a/java/com/google/gerrit/server/patch/PatchListCacheImpl.java
+++ b/java/com/google/gerrit/server/patch/PatchListCacheImpl.java
@@ -134,7 +134,7 @@
private PatchList get(Change change, PatchSet patchSet, Integer parentNum)
throws PatchListNotAvailableException {
Project.NameKey project = change.getProject();
- ObjectId b = patchSet.getCommitId();
+ ObjectId b = patchSet.commitId();
Whitespace ws = Whitespace.IGNORE_NONE;
if (parentNum != null) {
return get(PatchListKey.againstParentNum(parentNum, b, ws), project);
diff --git a/java/com/google/gerrit/server/patch/PatchScriptBuilder.java b/java/com/google/gerrit/server/patch/PatchScriptBuilder.java
index 61f0180..acf88e1 100644
--- a/java/com/google/gerrit/server/patch/PatchScriptBuilder.java
+++ b/java/com/google/gerrit/server/patch/PatchScriptBuilder.java
@@ -37,6 +37,7 @@
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
+import java.util.Objects;
import java.util.Optional;
import org.eclipse.jgit.diff.Edit;
import org.eclipse.jgit.errors.CorruptObjectException;
@@ -500,8 +501,7 @@
try {
final boolean reuse;
if (Patch.COMMIT_MSG.equals(path)) {
- if (comparisonType.isAgainstParentOrAutoMerge()
- && (aId == within || within.equals(aId))) {
+ if (comparisonType.isAgainstParentOrAutoMerge() && Objects.equals(aId, within)) {
id = ObjectId.zeroId();
src = Text.EMPTY;
srcContent = Text.NO_BYTES;
@@ -520,8 +520,7 @@
}
reuse = false;
} else if (Patch.MERGE_LIST.equals(path)) {
- if (comparisonType.isAgainstParentOrAutoMerge()
- && (aId == within || within.equals(aId))) {
+ if (comparisonType.isAgainstParentOrAutoMerge() && Objects.equals(aId, within)) {
id = ObjectId.zeroId();
src = Text.EMPTY;
srcContent = Text.NO_BYTES;
diff --git a/java/com/google/gerrit/server/patch/PatchScriptFactory.java b/java/com/google/gerrit/server/patch/PatchScriptFactory.java
index 61de8ee..ec05200 100644
--- a/java/com/google/gerrit/server/patch/PatchScriptFactory.java
+++ b/java/com/google/gerrit/server/patch/PatchScriptFactory.java
@@ -268,7 +268,7 @@
if (ps == null) {
throw new NoSuchChangeException(psId.changeId());
}
- return ps.getCommitId();
+ return ps.commitId();
}
private ObjectId getEditRev() throws AuthException, IOException {
@@ -303,7 +303,7 @@
switch (changeType) {
case COPIED:
case RENAMED:
- if (ps.getId().equals(psa)) {
+ if (ps.id().equals(psa)) {
name = oldName;
}
break;
@@ -316,7 +316,7 @@
}
}
- Patch p = new Patch(Patch.key(ps.getId(), name));
+ Patch p = new Patch(Patch.key(ps.id(), name));
history.add(p);
byKey.put(p.getKey(), p);
}
diff --git a/java/com/google/gerrit/server/patch/PatchSetInfoFactory.java b/java/com/google/gerrit/server/patch/PatchSetInfoFactory.java
index acc789b..c684da5 100644
--- a/java/com/google/gerrit/server/patch/PatchSetInfoFactory.java
+++ b/java/com/google/gerrit/server/patch/PatchSetInfoFactory.java
@@ -76,8 +76,8 @@
throws PatchSetInfoNotAvailableException {
try (Repository repo = repoManager.openRepository(project);
RevWalk rw = new RevWalk(repo)) {
- RevCommit src = rw.parseCommit(patchSet.getCommitId());
- PatchSetInfo info = get(rw, src, patchSet.getId());
+ RevCommit src = rw.parseCommit(patchSet.commitId());
+ PatchSetInfo info = get(rw, src, patchSet.id());
info.setParents(toParentInfos(src.getParents(), rw));
return info;
} catch (IOException | StorageException e) {
diff --git a/java/com/google/gerrit/server/permissions/DefaultRefFilter.java b/java/com/google/gerrit/server/permissions/DefaultRefFilter.java
index 2a8619f..6f9f75a 100644
--- a/java/com/google/gerrit/server/permissions/DefaultRefFilter.java
+++ b/java/com/google/gerrit/server/permissions/DefaultRefFilter.java
@@ -14,7 +14,6 @@
package com.google.gerrit.server.permissions;
-import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.gerrit.reviewdb.client.RefNames.REFS_CACHE_AUTOMERGE;
@@ -498,7 +497,7 @@
// even if the change is not part of the set of most recent changes that
// SearchingChangeCacheImpl returns.
Change.Id cId = Change.Id.fromRef(refName);
- checkNotNull(cId, "invalid change id for ref %s", refName);
+ requireNonNull(cId, () -> String.format("invalid change id for ref %s", refName));
ChangeNotes notes;
try {
notes = changeNotesFactory.create(projectState.getNameKey(), cId);
diff --git a/java/com/google/gerrit/server/project/ProjectCache.java b/java/com/google/gerrit/server/project/ProjectCache.java
index c7858dd..509caa4 100644
--- a/java/com/google/gerrit/server/project/ProjectCache.java
+++ b/java/com/google/gerrit/server/project/ProjectCache.java
@@ -57,7 +57,7 @@
* errors.
* @return the cached data or null when strict = false
*/
- public ProjectState checkedGet(Project.NameKey projectName, boolean strict) throws Exception;
+ ProjectState checkedGet(Project.NameKey projectName, boolean strict) throws Exception;
/**
* Invalidate the cached information about the given project, and triggers reindexing for it
diff --git a/java/com/google/gerrit/server/project/ProjectConfig.java b/java/com/google/gerrit/server/project/ProjectConfig.java
index e29a48a..d01954c 100644
--- a/java/com/google/gerrit/server/project/ProjectConfig.java
+++ b/java/com/google/gerrit/server/project/ProjectConfig.java
@@ -26,6 +26,7 @@
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.primitives.Shorts;
import com.google.gerrit.common.Nullable;
@@ -329,6 +330,10 @@
return as;
}
+ public ImmutableSet<String> getAccessSectionNames() {
+ return ImmutableSet.copyOf(accessSections.keySet());
+ }
+
public Collection<AccessSection> getAccessSections() {
return sort(accessSections.values());
}
diff --git a/java/com/google/gerrit/server/project/ProjectJson.java b/java/com/google/gerrit/server/project/ProjectJson.java
index f2a93d3..ca6c9f4 100644
--- a/java/com/google/gerrit/server/project/ProjectJson.java
+++ b/java/com/google/gerrit/server/project/ProjectJson.java
@@ -17,6 +17,7 @@
import static java.util.stream.Collectors.toMap;
import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelValue;
import com.google.gerrit.extensions.common.LabelTypeInfo;
@@ -29,7 +30,6 @@
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.util.HashMap;
-import java.util.List;
@Singleton
public class ProjectJson {
@@ -65,7 +65,7 @@
info.description = Strings.emptyToNull(p.getDescription());
info.state = p.getState();
info.id = Url.encode(info.name);
- List<WebLinkInfo> links = webLinks.getProjectLinks(p.getName());
+ ImmutableList<WebLinkInfo> links = webLinks.getProjectLinks(p.getName());
info.webLinks = links.isEmpty() ? null : links;
return info;
}
diff --git a/java/com/google/gerrit/server/project/ProjectState.java b/java/com/google/gerrit/server/project/ProjectState.java
index acfbf40..22f4227 100644
--- a/java/com/google/gerrit/server/project/ProjectState.java
+++ b/java/com/google/gerrit/server/project/ProjectState.java
@@ -67,7 +67,10 @@
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
-/** Cached information on a project. */
+/**
+ * Cached information on a project. Must not contain any data derived from parents other than it's
+ * immediate parent's {@link com.google.gerrit.reviewdb.client.Project.NameKey}.
+ */
public class ProjectState {
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -100,9 +103,6 @@
/** If this is all projects, the capabilities used by the server. */
private final CapabilityCollection capabilities;
- /** All label types applicable to changes in this project. */
- private LabelTypes labelTypes;
-
@Inject
public ProjectState(
ProjectCache projectCache,
@@ -451,10 +451,23 @@
/** All available label types. */
public LabelTypes getLabelTypes() {
- if (labelTypes == null) {
- labelTypes = loadLabelTypes();
+ Map<String, LabelType> types = new LinkedHashMap<>();
+ for (ProjectState s : treeInOrder()) {
+ for (LabelType type : s.getConfig().getLabelSections().values()) {
+ String lower = type.getName().toLowerCase();
+ LabelType old = types.get(lower);
+ if (old == null || old.canOverride()) {
+ types.put(lower, type);
+ }
+ }
}
- return labelTypes;
+ List<LabelType> all = Lists.newArrayListWithCapacity(types.size());
+ for (LabelType type : types.values()) {
+ if (!type.getValues().isEmpty()) {
+ all.add(type);
+ }
+ }
+ return new LabelTypes(Collections.unmodifiableList(all));
}
/** All available label types for this change. */
@@ -571,26 +584,6 @@
return project;
}
- private LabelTypes loadLabelTypes() {
- Map<String, LabelType> types = new LinkedHashMap<>();
- for (ProjectState s : treeInOrder()) {
- for (LabelType type : s.getConfig().getLabelSections().values()) {
- String lower = type.getName().toLowerCase();
- LabelType old = types.get(lower);
- if (old == null || old.canOverride()) {
- types.put(lower, type);
- }
- }
- }
- List<LabelType> all = Lists.newArrayListWithCapacity(types.size());
- for (LabelType type : types.values()) {
- if (!type.getValues().isEmpty()) {
- all.add(type);
- }
- }
- return new LabelTypes(Collections.unmodifiableList(all));
- }
-
private boolean match(BranchNameKey destination, String refPattern) {
return RefPatternMatcher.getMatcher(refPattern).match(destination.branch(), null);
}
diff --git a/java/com/google/gerrit/server/project/ProjectsConsistencyChecker.java b/java/com/google/gerrit/server/project/ProjectsConsistencyChecker.java
index 51bdc0b..83393bc 100644
--- a/java/com/google/gerrit/server/project/ProjectsConsistencyChecker.java
+++ b/java/com/google/gerrit/server/project/ProjectsConsistencyChecker.java
@@ -297,7 +297,7 @@
// Auto-close by commit
for (ObjectId patchSetSha1 :
autoCloseableChange.patchSets().stream()
- .map(PatchSet::getCommitId)
+ .map(PatchSet::commitId)
.collect(toSet())) {
if (mergedSha1s.contains(patchSetSha1)) {
autoCloseableChangesByBranch.add(
diff --git a/java/com/google/gerrit/server/project/RefFilter.java b/java/com/google/gerrit/server/project/RefFilter.java
index 76bafc0..cdabcbe 100644
--- a/java/com/google/gerrit/server/project/RefFilter.java
+++ b/java/com/google/gerrit/server/project/RefFilter.java
@@ -14,15 +14,17 @@
package com.google.gerrit.server.project;
-import com.google.common.base.Predicate;
+import static com.google.common.collect.ImmutableList.toImmutableList;
+
import com.google.common.base.Strings;
-import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
import com.google.gerrit.extensions.api.projects.RefInfo;
import com.google.gerrit.extensions.restapi.BadRequestException;
import dk.brics.automaton.RegExp;
import dk.brics.automaton.RunAutomaton;
import java.util.List;
import java.util.Locale;
+import java.util.stream.Stream;
public class RefFilter<T extends RefInfo> {
private final String prefix;
@@ -55,15 +57,17 @@
return this;
}
- public List<T> filter(List<T> refs) throws BadRequestException {
+ public ImmutableList<T> filter(List<T> refs) throws BadRequestException {
if (!Strings.isNullOrEmpty(matchSubstring) && !Strings.isNullOrEmpty(matchRegex)) {
throw new BadRequestException("specify exactly one of m/r");
}
- FluentIterable<T> results = FluentIterable.from(refs);
+ Stream<T> results = refs.stream();
if (!Strings.isNullOrEmpty(matchSubstring)) {
- results = results.filter(new SubstringPredicate(matchSubstring));
+ String lowercaseSubstring = matchSubstring.toLowerCase(Locale.US);
+ results = results.filter(refInfo -> matchesSubstring(prefix, lowercaseSubstring, refInfo));
} else if (!Strings.isNullOrEmpty(matchRegex)) {
- results = results.filter(new RegexPredicate(matchRegex));
+ RunAutomaton a = parseRegex(matchRegex);
+ results = results.filter(refInfo -> matchesRegex(prefix, a, refInfo));
}
if (start > 0) {
results = results.skip(start);
@@ -71,51 +75,39 @@
if (limit > 0) {
results = results.limit(limit);
}
- return results.toList();
+ return results.collect(toImmutableList());
}
- private class SubstringPredicate implements Predicate<T> {
- private final String substring;
-
- private SubstringPredicate(String substring) {
- this.substring = substring.toLowerCase(Locale.US);
+ private static <T extends RefInfo> boolean matchesSubstring(
+ String prefix, String lowercaseSubstring, T refInfo) {
+ String ref = refInfo.ref;
+ if (ref.startsWith(prefix)) {
+ ref = ref.substring(prefix.length());
}
+ ref = ref.toLowerCase(Locale.US);
+ return ref.contains(lowercaseSubstring);
+ }
- @Override
- public boolean apply(T in) {
- String ref = in.ref;
- if (ref.startsWith(prefix)) {
- ref = ref.substring(prefix.length());
+ private static RunAutomaton parseRegex(String regex) throws BadRequestException {
+ if (regex.startsWith("^")) {
+ regex = regex.substring(1);
+ if (regex.endsWith("$") && !regex.endsWith("\\$")) {
+ regex = regex.substring(0, regex.length() - 1);
}
- ref = ref.toLowerCase(Locale.US);
- return ref.contains(substring);
+ }
+ try {
+ return new RunAutomaton(new RegExp(regex).toAutomaton());
+ } catch (IllegalArgumentException e) {
+ throw new BadRequestException(e.getMessage());
}
}
- private class RegexPredicate implements Predicate<T> {
- private final RunAutomaton a;
-
- private RegexPredicate(String regex) throws BadRequestException {
- if (regex.startsWith("^")) {
- regex = regex.substring(1);
- if (regex.endsWith("$") && !regex.endsWith("\\$")) {
- regex = regex.substring(0, regex.length() - 1);
- }
- }
- try {
- a = new RunAutomaton(new RegExp(regex).toAutomaton());
- } catch (IllegalArgumentException e) {
- throw new BadRequestException(e.getMessage());
- }
+ private static <T extends RefInfo> boolean matchesRegex(
+ String prefix, RunAutomaton a, T refInfo) {
+ String ref = refInfo.ref;
+ if (ref.startsWith(prefix)) {
+ ref = ref.substring(prefix.length());
}
-
- @Override
- public boolean apply(T in) {
- String ref = in.ref;
- if (ref.startsWith(prefix)) {
- ref = ref.substring(prefix.length());
- }
- return a.run(ref);
- }
+ return a.run(ref);
}
}
diff --git a/java/com/google/gerrit/server/project/RemoveReviewerControl.java b/java/com/google/gerrit/server/project/RemoveReviewerControl.java
index d7c0333..efd99dd 100644
--- a/java/com/google/gerrit/server/project/RemoveReviewerControl.java
+++ b/java/com/google/gerrit/server/project/RemoveReviewerControl.java
@@ -47,7 +47,7 @@
public void checkRemoveReviewer(
ChangeNotes notes, CurrentUser currentUser, PatchSetApproval approval)
throws PermissionBackendException, AuthException {
- checkRemoveReviewer(notes, currentUser, approval.getAccountId(), approval.getValue());
+ checkRemoveReviewer(notes, currentUser, approval.accountId(), approval.value());
}
/**
diff --git a/java/com/google/gerrit/server/project/testing/TestLabels.java b/java/com/google/gerrit/server/project/testing/TestLabels.java
new file mode 100644
index 0000000..6c2ddde
--- /dev/null
+++ b/java/com/google/gerrit/server/project/testing/TestLabels.java
@@ -0,0 +1,53 @@
+// 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.project.testing;
+
+import com.google.gerrit.common.data.LabelFunction;
+import com.google.gerrit.common.data.LabelType;
+import com.google.gerrit.common.data.LabelValue;
+import java.util.Arrays;
+
+public class TestLabels {
+ public static LabelType codeReview() {
+ return label(
+ "Code-Review",
+ value(2, "Looks good to me, approved"),
+ value(1, "Looks good to me, but someone else must approve"),
+ value(0, "No score"),
+ value(-1, "I would prefer this is not merged as is"),
+ value(-2, "This shall not be merged"));
+ }
+
+ public static LabelType verified() {
+ return label("Verified", value(1, "Verified"), value(0, "No score"), value(-1, "Fails"));
+ }
+
+ public static LabelType patchSetLock() {
+ LabelType label =
+ label("Patch-Set-Lock", value(1, "Patch Set Locked"), value(0, "Patch Set Unlocked"));
+ label.setFunction(LabelFunction.PATCH_SET_LOCK);
+ return label;
+ }
+
+ public static LabelValue value(int value, String text) {
+ return new LabelValue((short) value, text);
+ }
+
+ public static LabelType label(String name, LabelValue... values) {
+ return new LabelType(name, Arrays.asList(values));
+ }
+
+ private TestLabels() {}
+}
diff --git a/java/com/google/gerrit/server/project/testing/Util.java b/java/com/google/gerrit/server/project/testing/Util.java
deleted file mode 100644
index 2bd71c3..0000000
--- a/java/com/google/gerrit/server/project/testing/Util.java
+++ /dev/null
@@ -1,239 +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.project.testing;
-
-import com.google.gerrit.common.data.AccessSection;
-import com.google.gerrit.common.data.GlobalCapability;
-import com.google.gerrit.common.data.GroupReference;
-import com.google.gerrit.common.data.LabelFunction;
-import com.google.gerrit.common.data.LabelType;
-import com.google.gerrit.common.data.LabelValue;
-import com.google.gerrit.common.data.Permission;
-import com.google.gerrit.common.data.PermissionRange;
-import com.google.gerrit.common.data.PermissionRule;
-import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.server.project.ProjectConfig;
-import java.util.Arrays;
-
-public class Util {
- public static final AccountGroup.UUID ADMIN = AccountGroup.uuid("test.admin");
- public static final AccountGroup.UUID DEVS = AccountGroup.uuid("test.devs");
-
- public static final LabelType codeReview() {
- return category(
- "Code-Review",
- value(2, "Looks good to me, approved"),
- value(1, "Looks good to me, but someone else must approve"),
- value(0, "No score"),
- value(-1, "I would prefer this is not merged as is"),
- value(-2, "This shall not be merged"));
- }
-
- public static final LabelType verified() {
- return category("Verified", value(1, "Verified"), value(0, "No score"), value(-1, "Fails"));
- }
-
- public static final LabelType patchSetLock() {
- LabelType label =
- category("Patch-Set-Lock", value(1, "Patch Set Locked"), value(0, "Patch Set Unlocked"));
- label.setFunction(LabelFunction.PATCH_SET_LOCK);
- return label;
- }
-
- public static LabelValue value(int value, String text) {
- return new LabelValue((short) value, text);
- }
-
- public static LabelType category(String name, LabelValue... values) {
- return new LabelType(name, Arrays.asList(values));
- }
-
- public static PermissionRule newRule(ProjectConfig project, AccountGroup.UUID groupUUID) {
- GroupReference group = new GroupReference(groupUUID, groupUUID.get());
- group = project.resolve(group);
-
- return new PermissionRule(group);
- }
-
- public static PermissionRule allow(
- ProjectConfig project,
- String permissionName,
- int min,
- int max,
- AccountGroup.UUID group,
- String ref) {
- PermissionRule rule = newRule(project, group);
- rule.setMin(min);
- rule.setMax(max);
- return grant(project, permissionName, rule, ref);
- }
-
- public static PermissionRule allowExclusive(
- ProjectConfig project,
- String permissionName,
- int min,
- int max,
- AccountGroup.UUID group,
- String ref) {
- PermissionRule rule = newRule(project, group);
- rule.setMin(min);
- rule.setMax(max);
- return grant(project, permissionName, rule, ref, true);
- }
-
- public static PermissionRule block(
- ProjectConfig project,
- String permissionName,
- int min,
- int max,
- AccountGroup.UUID group,
- String ref) {
- PermissionRule rule = newRule(project, group);
- rule.setMin(min);
- rule.setMax(max);
- PermissionRule r = grant(project, permissionName, rule, ref);
- r.setBlock();
- return r;
- }
-
- public static PermissionRule allow(
- ProjectConfig project, String permissionName, AccountGroup.UUID group, String ref) {
- return grant(project, permissionName, newRule(project, group), ref);
- }
-
- public static PermissionRule allow(
- ProjectConfig project,
- String permissionName,
- AccountGroup.UUID group,
- String ref,
- boolean exclusive) {
- return grant(project, permissionName, newRule(project, group), ref, exclusive);
- }
-
- public static PermissionRule allow(
- ProjectConfig project, String capabilityName, AccountGroup.UUID group) {
- return allow(project, capabilityName, group, (PermissionRange) null);
- }
-
- public static PermissionRule allow(
- ProjectConfig project,
- String capabilityName,
- AccountGroup.UUID group,
- PermissionRange customRange) {
- PermissionRule rule = newRule(project, group);
- project
- .getAccessSection(AccessSection.GLOBAL_CAPABILITIES, true)
- .getPermission(capabilityName, true)
- .add(rule);
- if (GlobalCapability.hasRange(capabilityName)) {
- if (customRange == null) {
- PermissionRange.WithDefaults range = GlobalCapability.getRange(capabilityName);
- if (range != null) {
- rule.setRange(range.getDefaultMin(), range.getDefaultMax());
- }
- return rule;
- }
- rule.setRange(customRange.getMin(), customRange.getMax());
- }
- return rule;
- }
-
- public static PermissionRule remove(
- ProjectConfig project, String capabilityName, AccountGroup.UUID group) {
- PermissionRule rule = newRule(project, group);
- project
- .getAccessSection(AccessSection.GLOBAL_CAPABILITIES, true)
- .getPermission(capabilityName, true)
- .remove(rule);
- return rule;
- }
-
- public static PermissionRule remove(
- ProjectConfig project, String permissionName, AccountGroup.UUID group, String ref) {
- PermissionRule rule = newRule(project, group);
- project.getAccessSection(ref, true).getPermission(permissionName, true).remove(rule);
- return rule;
- }
-
- public static PermissionRule block(
- ProjectConfig project, String capabilityName, AccountGroup.UUID group) {
- PermissionRule rule = newRule(project, group);
- project
- .getAccessSection(AccessSection.GLOBAL_CAPABILITIES, true)
- .getPermission(capabilityName, true)
- .add(rule);
- return rule;
- }
-
- public static PermissionRule block(
- ProjectConfig project, String permissionName, AccountGroup.UUID group, String ref) {
- PermissionRule r = grant(project, permissionName, newRule(project, group), ref);
- r.setBlock();
- return r;
- }
-
- public static PermissionRule blockLabel(
- ProjectConfig project, String labelName, AccountGroup.UUID group, String ref) {
- return blockLabel(project, labelName, -1, 1, group, ref);
- }
-
- public static PermissionRule blockLabel(
- ProjectConfig project,
- String labelName,
- int min,
- int max,
- AccountGroup.UUID group,
- String ref) {
- PermissionRule r = grant(project, Permission.LABEL + labelName, newRule(project, group), ref);
- r.setBlock();
- r.setRange(min, max);
- return r;
- }
-
- public static PermissionRule deny(
- ProjectConfig project, String permissionName, AccountGroup.UUID group, String ref) {
- PermissionRule r = grant(project, permissionName, newRule(project, group), ref);
- r.setDeny();
- return r;
- }
-
- public static void doNotInherit(ProjectConfig project, String permissionName, String ref) {
- project
- .getAccessSection(ref, true) //
- .getPermission(permissionName, true) //
- .setExclusiveGroup(true);
- }
-
- private static PermissionRule grant(
- ProjectConfig project, String permissionName, PermissionRule rule, String ref) {
- return grant(project, permissionName, rule, ref, false);
- }
-
- private static PermissionRule grant(
- ProjectConfig project,
- String permissionName,
- PermissionRule rule,
- String ref,
- boolean exclusive) {
- Permission permission = project.getAccessSection(ref, true).getPermission(permissionName, true);
- if (exclusive) {
- permission.setExclusiveGroup(exclusive);
- }
- permission.add(rule);
- return rule;
- }
-
- private Util() {}
-}
diff --git a/java/com/google/gerrit/server/query/change/ChangeData.java b/java/com/google/gerrit/server/query/change/ChangeData.java
index c251c53..d3b57d7 100644
--- a/java/com/google/gerrit/server/query/change/ChangeData.java
+++ b/java/com/google/gerrit/server/query/change/ChangeData.java
@@ -74,6 +74,7 @@
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.project.SubmitRuleEvaluator;
import com.google.gerrit.server.project.SubmitRuleOptions;
+import com.google.gerrit.server.util.time.TimeUtil;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.io.IOException;
@@ -227,7 +228,13 @@
new ChangeData(
null, null, null, null, null, null, null, null, null, null, null, null, null, null,
null, project, id, null, null);
- cd.currentPatchSet = new PatchSet(PatchSet.id(id, currentPatchSetId), commitId);
+ cd.currentPatchSet =
+ PatchSet.builder()
+ .id(PatchSet.id(id, currentPatchSetId))
+ .commitId(commitId)
+ .uploader(Account.id(1000))
+ .createdOn(TimeUtil.nowTs())
+ .build();
return cd;
}
@@ -387,7 +394,7 @@
return Optional.empty();
}
- ObjectId id = ps.getCommitId();
+ ObjectId id = ps.commitId();
Whitespace ws = Whitespace.IGNORE_NONE;
PatchListKey pk =
parentCount > 1
@@ -497,7 +504,7 @@
return null;
}
for (PatchSet p : patchSets()) {
- if (p.getId().equals(c.currentPatchSetId())) {
+ if (p.id().equals(c.currentPatchSetId())) {
currentPatchSet = p;
return p;
}
@@ -582,7 +589,7 @@
}
try (Repository repo = repoManager.openRepository(project());
RevWalk walk = new RevWalk(repo)) {
- RevCommit c = walk.parseCommit(ps.getCommitId());
+ RevCommit c = walk.parseCommit(ps.commitId());
commitMessage = c.getFullMessage();
commitFooters = c.getFooterLines();
author = c.getAuthorIdent();
@@ -609,11 +616,11 @@
/** @return patch with the given ID, or null if it does not exist. */
public PatchSet patchSet(PatchSet.Id psId) {
- if (currentPatchSet != null && currentPatchSet.getId().equals(psId)) {
+ if (currentPatchSet != null && currentPatchSet.id().equals(psId)) {
return currentPatchSet;
}
for (PatchSet ps : patchSets()) {
- if (ps.getId().equals(psId)) {
+ if (ps.id().equals(psId)) {
return ps;
}
}
@@ -896,8 +903,7 @@
String mergeStrategy =
mergeUtilFactory.create(projectCache.get(project())).mergeStrategyName();
mergeable =
- mergeabilityCache.get(
- ps.getCommitId(), ref, str.type, mergeStrategy, c.getDest(), repo);
+ mergeabilityCache.get(ps.commitId(), ref, str.type, mergeStrategy, c.getDest(), repo);
} catch (IOException e) {
throw new StorageException(e);
}
@@ -975,11 +981,11 @@
PatchSet ps = currentPatchSet();
if (ps != null) {
- if (stars.contains(StarredChangesUtil.REVIEWED_LABEL + "/" + ps.getPatchSetId())) {
+ if (stars.contains(StarredChangesUtil.REVIEWED_LABEL + "/" + ps.number())) {
return true;
}
- if (stars.contains(StarredChangesUtil.UNREVIEWED_LABEL + "/" + ps.getPatchSetId())) {
+ if (stars.contains(StarredChangesUtil.UNREVIEWED_LABEL + "/" + ps.number())) {
return false;
}
}
diff --git a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index c2e09b0..3c43cb8 100644
--- a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -64,7 +64,9 @@
import com.google.gerrit.server.change.ChangeTriplet;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.config.AllUsersName;
+import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.index.IndexModule;
import com.google.gerrit.server.index.change.ChangeField;
import com.google.gerrit.server.index.change.ChangeIndex;
import com.google.gerrit.server.index.change.ChangeIndexCollection;
@@ -94,6 +96,7 @@
import java.util.regex.Pattern;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
+import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.lib.Repository;
/** Parses a query string meant to be applied to change objects. */
@@ -405,6 +408,8 @@
private final Arguments args;
+ private @Inject @GerritServerConfig Config cfg;
+
@Inject
ChangeQueryBuilder(Arguments args) {
this(mydef, args);
@@ -736,6 +741,9 @@
@Operator
public Predicate<ChangeData> extension(String ext) throws QueryParseException {
if (args.getSchema().hasField(ChangeField.EXTENSION)) {
+ if (ext.isEmpty() && IndexModule.getIndexType(cfg).isElasticsearch()) {
+ return new FileWithNoExtensionInElasticPredicate();
+ }
return new FileExtensionPredicate(ext);
}
throw new QueryParseException("'extension' operator is not supported by change index version");
@@ -775,6 +783,10 @@
return new RegexDirectoryPredicate(directory);
}
+ if (IndexModule.getIndexType(cfg).isElasticsearch()
+ && (directory.isEmpty() || directory.equals("/"))) {
+ return Predicate.any();
+ }
return new DirectoryPredicate(directory);
}
throw new QueryParseException("'directory' operator is not supported by change index version");
diff --git a/java/com/google/gerrit/server/query/change/CommitPredicate.java b/java/com/google/gerrit/server/query/change/CommitPredicate.java
index f1ff229..25d3ec3 100644
--- a/java/com/google/gerrit/server/query/change/CommitPredicate.java
+++ b/java/com/google/gerrit/server/query/change/CommitPredicate.java
@@ -47,9 +47,9 @@
protected boolean equals(PatchSet p, String id) {
if (getField() == EXACT_COMMIT) {
- return p.getCommitId().name().equals(id);
+ return p.commitId().name().equals(id);
}
- return matchesAbbreviation(p.getCommitId(), id);
+ return matchesAbbreviation(p.commitId(), id);
}
@Override
diff --git a/java/com/google/gerrit/server/query/change/ConflictsPredicate.java b/java/com/google/gerrit/server/query/change/ConflictsPredicate.java
index e08a6fd..f18a5a7 100644
--- a/java/com/google/gerrit/server/query/change/ConflictsPredicate.java
+++ b/java/com/google/gerrit/server/query/change/ConflictsPredicate.java
@@ -131,7 +131,7 @@
return false;
}
- other = object.currentPatchSet().getCommitId();
+ other = object.currentPatchSet().commitId();
ConflictKey conflictsKey =
ConflictKey.create(
changeDataCache.getTestAgainst(),
@@ -207,7 +207,7 @@
ObjectId getTestAgainst() {
if (testAgainst == null) {
- testAgainst = cd.currentPatchSet().getCommitId();
+ testAgainst = cd.currentPatchSet().commitId();
}
return testAgainst;
}
diff --git a/java/com/google/gerrit/server/query/change/EqualsLabelPredicate.java b/java/com/google/gerrit/server/query/change/EqualsLabelPredicate.java
index 3bcdd66..0e07a18 100644
--- a/java/com/google/gerrit/server/query/change/EqualsLabelPredicate.java
+++ b/java/com/google/gerrit/server/query/change/EqualsLabelPredicate.java
@@ -76,7 +76,7 @@
for (PatchSetApproval p : object.currentApprovals()) {
if (labelType.matches(p)) {
hasVote = true;
- if (match(object, p.getValue(), p.getAccountId())) {
+ if (match(object, p.value(), p.accountId())) {
return true;
}
}
diff --git a/java/com/google/gerrit/server/query/change/FileWithNoExtensionInElasticPredicate.java b/java/com/google/gerrit/server/query/change/FileWithNoExtensionInElasticPredicate.java
new file mode 100644
index 0000000..d886baf
--- /dev/null
+++ b/java/com/google/gerrit/server/query/change/FileWithNoExtensionInElasticPredicate.java
@@ -0,0 +1,37 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.query.change;
+
+import com.google.gerrit.index.query.PostFilterPredicate;
+import com.google.gerrit.server.index.change.ChangeField;
+
+public class FileWithNoExtensionInElasticPredicate extends PostFilterPredicate<ChangeData> {
+
+ private static final String NO_EXT = "";
+
+ public FileWithNoExtensionInElasticPredicate() {
+ super(ChangeField.EXTENSION.getName(), NO_EXT);
+ }
+
+ @Override
+ public boolean match(ChangeData cd) {
+ return ChangeField.getExtensions(cd).contains(NO_EXT);
+ }
+
+ @Override
+ public int getCost() {
+ return 1;
+ }
+}
diff --git a/java/com/google/gerrit/server/query/change/GroupPredicate.java b/java/com/google/gerrit/server/query/change/GroupPredicate.java
index 7f7bcff..0e6f45d 100644
--- a/java/com/google/gerrit/server/query/change/GroupPredicate.java
+++ b/java/com/google/gerrit/server/query/change/GroupPredicate.java
@@ -26,7 +26,7 @@
@Override
public boolean match(ChangeData cd) {
for (PatchSet ps : cd.patchSets()) {
- List<String> groups = ps.getGroups();
+ List<String> groups = ps.groups();
if (groups != null && groups.contains(getValue())) {
return true;
}
diff --git a/java/com/google/gerrit/server/query/change/OrSource.java b/java/com/google/gerrit/server/query/change/OrSource.java
index ba06b89..66255f1 100644
--- a/java/com/google/gerrit/server/query/change/OrSource.java
+++ b/java/com/google/gerrit/server/query/change/OrSource.java
@@ -14,9 +14,12 @@
package com.google.gerrit.server.query.change;
+import static com.google.common.collect.ImmutableList.toImmutableList;
+
+import com.google.common.collect.ImmutableList;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.index.query.FieldBundle;
-import com.google.gerrit.index.query.ListResultSet;
+import com.google.gerrit.index.query.LazyResultSet;
import com.google.gerrit.index.query.OrPredicate;
import com.google.gerrit.index.query.Predicate;
import com.google.gerrit.index.query.ResultSet;
@@ -25,6 +28,7 @@
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
public class OrSource extends OrPredicate<ChangeData> implements ChangeDataSource {
@@ -36,22 +40,29 @@
@Override
public ResultSet<ChangeData> read() {
- // TODO(spearce) This probably should be more lazy.
- //
- List<ChangeData> r = new ArrayList<>();
- Set<Change.Id> have = new HashSet<>();
- for (Predicate<ChangeData> p : getChildren()) {
- if (p instanceof ChangeDataSource) {
- for (ChangeData cd : ((ChangeDataSource) p).read()) {
- if (have.add(cd.getId())) {
- r.add(cd);
- }
- }
- } else {
- throw new StorageException("No ChangeDataSource: " + p);
- }
+ Optional<Predicate<ChangeData>> nonChangeDataSource =
+ getChildren().stream().filter(p -> !(p instanceof ChangeDataSource)).findAny();
+ if (nonChangeDataSource.isPresent()) {
+ throw new StorageException("No ChangeDataSource: " + nonChangeDataSource.get());
}
- return new ListResultSet<>(r);
+
+ // ResultSets are lazy. Calling #read here first and then dealing with ResultSets only when
+ // requested allows the index to run asynchronous queries.
+ List<ResultSet<ChangeData>> results =
+ getChildren().stream().map(p -> ((ChangeDataSource) p).read()).collect(toImmutableList());
+ return new LazyResultSet<>(
+ () -> {
+ List<ChangeData> r = new ArrayList<>();
+ Set<Change.Id> have = new HashSet<>();
+ for (ResultSet<ChangeData> resultSet : results) {
+ for (ChangeData result : resultSet) {
+ if (have.add(result.getId())) {
+ r.add(result);
+ }
+ }
+ }
+ return ImmutableList.copyOf(r);
+ });
}
@Override
diff --git a/java/com/google/gerrit/server/restapi/account/DeleteSshKey.java b/java/com/google/gerrit/server/restapi/account/DeleteSshKey.java
index 787e083..054f4bc 100644
--- a/java/com/google/gerrit/server/restapi/account/DeleteSshKey.java
+++ b/java/com/google/gerrit/server/restapi/account/DeleteSshKey.java
@@ -14,13 +14,17 @@
package com.google.gerrit.server.restapi.account;
+import com.google.common.flogger.FluentLogger;
+import com.google.gerrit.exceptions.EmailException;
import com.google.gerrit.extensions.common.Input;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.Response;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountResource;
import com.google.gerrit.server.account.VersionedAuthorizedKeys;
+import com.google.gerrit.server.mail.send.DeleteKeySender;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
@@ -34,22 +38,26 @@
@Singleton
public class DeleteSshKey implements RestModifyView<AccountResource.SshKey, Input> {
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
private final Provider<CurrentUser> self;
private final PermissionBackend permissionBackend;
private final VersionedAuthorizedKeys.Accessor authorizedKeys;
private final SshKeyCache sshKeyCache;
+ private final DeleteKeySender.Factory deleteKeySenderFactory;
@Inject
DeleteSshKey(
Provider<CurrentUser> self,
PermissionBackend permissionBackend,
VersionedAuthorizedKeys.Accessor authorizedKeys,
- SshKeyCache sshKeyCache) {
+ SshKeyCache sshKeyCache,
+ DeleteKeySender.Factory deleteKeySenderFactory) {
this.self = self;
this.permissionBackend = permissionBackend;
this.authorizedKeys = authorizedKeys;
this.sshKeyCache = sshKeyCache;
+ this.deleteKeySenderFactory = deleteKeySenderFactory;
}
@Override
@@ -60,8 +68,15 @@
permissionBackend.currentUser().check(GlobalPermission.ADMINISTRATE_SERVER);
}
- authorizedKeys.deleteKey(rsrc.getUser().getAccountId(), rsrc.getSshKey().seq());
- rsrc.getUser().getUserName().ifPresent(sshKeyCache::evict);
+ IdentifiedUser user = rsrc.getUser();
+ authorizedKeys.deleteKey(user.getAccountId(), rsrc.getSshKey().seq());
+ try {
+ deleteKeySenderFactory.create(user, rsrc.getSshKey()).send();
+ } catch (EmailException e) {
+ logger.atSevere().withCause(e).log(
+ "Cannot send SSH key deletion message to %s", user.getAccount().getPreferredEmail());
+ }
+ user.getUserName().ifPresent(sshKeyCache::evict);
return Response.none();
}
diff --git a/java/com/google/gerrit/server/restapi/account/PutHttpPassword.java b/java/com/google/gerrit/server/restapi/account/PutHttpPassword.java
index 4b223ed..62bb0cd 100644
--- a/java/com/google/gerrit/server/restapi/account/PutHttpPassword.java
+++ b/java/com/google/gerrit/server/restapi/account/PutHttpPassword.java
@@ -17,7 +17,9 @@
import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_USERNAME;
import com.google.common.base.Strings;
+import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.UsedAt;
+import com.google.gerrit.exceptions.EmailException;
import com.google.gerrit.extensions.common.HttpPasswordInput;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
@@ -31,6 +33,7 @@
import com.google.gerrit.server.account.AccountsUpdate;
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIds;
+import com.google.gerrit.server.mail.send.HttpPasswordUpdateSender;
import com.google.gerrit.server.permissions.GlobalPermission;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackendException;
@@ -44,6 +47,8 @@
import org.eclipse.jgit.errors.ConfigInvalidException;
public class PutHttpPassword implements RestModifyView<AccountResource, HttpPasswordInput> {
+ private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+
private static final int LEN = 31;
private static final SecureRandom rng;
@@ -59,17 +64,20 @@
private final PermissionBackend permissionBackend;
private final ExternalIds externalIds;
private final Provider<AccountsUpdate> accountsUpdateProvider;
+ private final HttpPasswordUpdateSender.Factory httpPasswordUpdateSenderFactory;
@Inject
PutHttpPassword(
Provider<CurrentUser> self,
PermissionBackend permissionBackend,
ExternalIds externalIds,
- @UserInitiated Provider<AccountsUpdate> accountsUpdateProvider) {
+ @UserInitiated Provider<AccountsUpdate> accountsUpdateProvider,
+ HttpPasswordUpdateSender.Factory httpPasswordUpdateSenderFactory) {
this.self = self;
this.permissionBackend = permissionBackend;
this.externalIds = externalIds;
this.accountsUpdateProvider = accountsUpdateProvider;
+ this.httpPasswordUpdateSenderFactory = httpPasswordUpdateSenderFactory;
}
@Override
@@ -98,6 +106,7 @@
return apply(rsrc.getUser(), newPassword);
}
+ @UsedAt(UsedAt.Project.PLUGIN_SERVICEUSER)
public Response<String> apply(IdentifiedUser user, String newPassword)
throws ResourceNotFoundException, ResourceConflictException, IOException,
ConfigInvalidException {
@@ -116,6 +125,15 @@
ExternalId.createWithPassword(
extId.key(), extId.accountId(), extId.email(), newPassword)));
+ try {
+ httpPasswordUpdateSenderFactory
+ .create(user, newPassword == null ? "deleted" : "added or updated")
+ .send();
+ } catch (EmailException e) {
+ logger.atSevere().withCause(e).log(
+ "Cannot send HttpPassword update message to %s", user.getAccount().getPreferredEmail());
+ }
+
return Strings.isNullOrEmpty(newPassword) ? Response.none() : Response.ok(newPassword);
}
diff --git a/java/com/google/gerrit/server/restapi/change/ApplyFix.java b/java/com/google/gerrit/server/restapi/change/ApplyFix.java
index c25a52d..dc5c2b1 100644
--- a/java/com/google/gerrit/server/restapi/change/ApplyFix.java
+++ b/java/com/google/gerrit/server/restapi/change/ApplyFix.java
@@ -75,7 +75,7 @@
try (Repository repository = gitRepositoryManager.openRepository(project)) {
List<TreeModification> treeModifications =
fixReplacementInterpreter.toTreeModifications(
- repository, projectState, patchSet.getCommitId(), fixResource.getFixReplacements());
+ repository, projectState, patchSet.commitId(), fixResource.getFixReplacements());
ChangeEdit changeEdit =
changeEditModifier.combineWithModifiedPatchSetTree(
repository, revisionResource.getNotes(), patchSet, treeModifications);
diff --git a/java/com/google/gerrit/server/restapi/change/ChangeEdits.java b/java/com/google/gerrit/server/restapi/change/ChangeEdits.java
index 64789f9..f90b8e5 100644
--- a/java/com/google/gerrit/server/restapi/change/ChangeEdits.java
+++ b/java/com/google/gerrit/server/restapi/change/ChangeEdits.java
@@ -15,6 +15,7 @@
package com.google.gerrit.server.restapi.change;
import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
import com.google.gerrit.extensions.common.DiffWebLinkInfo;
import com.google.gerrit.extensions.common.EditInfo;
import com.google.gerrit.extensions.common.Input;
@@ -357,7 +358,7 @@
return Response.ok(
fileContentUtil.getContent(
projectCache.checkedGet(rsrc.getChangeResource().getProject()),
- base ? edit.getBasePatchSet().getCommitId() : edit.getEditCommit(),
+ base ? edit.getBasePatchSet().commitId() : edit.getEditCommit(),
rsrc.getPath(),
null));
} catch (ResourceNotFoundException | BadRequestException e) {
@@ -380,12 +381,12 @@
FileInfo r = new FileInfo();
ChangeEdit edit = rsrc.getChangeEdit();
Change change = edit.getChange();
- List<DiffWebLinkInfo> links =
+ ImmutableList<DiffWebLinkInfo> links =
webLinks.getDiffLinks(
change.getProject().get(),
change.getChangeId(),
- edit.getBasePatchSet().getPatchSetId(),
- edit.getBasePatchSet().getRefName(),
+ edit.getBasePatchSet().number(),
+ edit.getBasePatchSet().refName(),
rsrc.getPath(),
0,
edit.getRefName(),
@@ -458,7 +459,7 @@
if (base) {
try (Repository repo = repoManager.openRepository(rsrc.getProject());
RevWalk rw = new RevWalk(repo)) {
- RevCommit commit = rw.parseCommit(edit.get().getBasePatchSet().getCommitId());
+ RevCommit commit = rw.parseCommit(edit.get().getBasePatchSet().commitId());
msg = commit.getFullMessage();
}
} else {
diff --git a/java/com/google/gerrit/server/restapi/change/ChangeIncludedIn.java b/java/com/google/gerrit/server/restapi/change/ChangeIncludedIn.java
index d1ebb79..3ac3eed 100644
--- a/java/com/google/gerrit/server/restapi/change/ChangeIncludedIn.java
+++ b/java/com/google/gerrit/server/restapi/change/ChangeIncludedIn.java
@@ -39,6 +39,6 @@
@Override
public IncludedInInfo apply(ChangeResource rsrc) throws RestApiException, IOException {
PatchSet ps = psUtil.current(rsrc.getNotes());
- return includedIn.apply(rsrc.getProject(), ps.getCommitId().name());
+ return includedIn.apply(rsrc.getProject(), ps.commitId().name());
}
}
diff --git a/java/com/google/gerrit/server/restapi/change/CherryPickChange.java b/java/com/google/gerrit/server/restapi/change/CherryPickChange.java
index 4c2e790..afd9d8e9 100644
--- a/java/com/google/gerrit/server/restapi/change/CherryPickChange.java
+++ b/java/com/google/gerrit/server/restapi/change/CherryPickChange.java
@@ -143,7 +143,7 @@
throws IOException, InvalidChangeOperationException, IntegrationException, UpdateException,
RestApiException, ConfigInvalidException, NoSuchProjectException {
return cherryPick(
- batchUpdateFactory, change, change.getProject(), patch.getCommitId(), input, dest);
+ batchUpdateFactory, change, change.getProject(), patch.commitId(), input, dest);
}
public Result cherryPick(
diff --git a/java/com/google/gerrit/server/restapi/change/Comments.java b/java/com/google/gerrit/server/restapi/change/Comments.java
index d9a0d57..84771b1 100644
--- a/java/com/google/gerrit/server/restapi/change/Comments.java
+++ b/java/com/google/gerrit/server/restapi/change/Comments.java
@@ -58,7 +58,7 @@
String uuid = id.get();
ChangeNotes notes = rev.getNotes();
- for (Comment c : commentsUtil.publishedByPatchSet(notes, rev.getPatchSet().getId())) {
+ for (Comment c : commentsUtil.publishedByPatchSet(notes, rev.getPatchSet().id())) {
if (uuid.equals(c.key.uuid)) {
return new CommentResource(rev, c);
}
diff --git a/java/com/google/gerrit/server/restapi/change/CreateChange.java b/java/com/google/gerrit/server/restapi/change/CreateChange.java
index 9545888..9c952f7 100644
--- a/java/com/google/gerrit/server/restapi/change/CreateChange.java
+++ b/java/com/google/gerrit/server/restapi/change/CreateChange.java
@@ -277,7 +277,7 @@
if (input.baseChange != null) {
ChangeNotes baseChange = getBaseChange(input.baseChange);
basePatchSet = psUtil.current(baseChange);
- groups = basePatchSet.getGroups();
+ groups = basePatchSet.groups();
}
ObjectId parentCommit =
getParentCommit(git, rw, input.branch, input.newBranch, basePatchSet, input.baseCommit);
@@ -345,7 +345,7 @@
throws BadRequestException, IOException, UnprocessableEntityException,
ResourceConflictException {
if (basePatchSet != null) {
- return basePatchSet.getCommitId();
+ return basePatchSet.commitId();
}
Ref destRef = repo.getRefDatabase().exactRef(inputBranch);
diff --git a/java/com/google/gerrit/server/restapi/change/CreateDraftComment.java b/java/com/google/gerrit/server/restapi/change/CreateDraftComment.java
index 71d00ec..4ee9ba5 100644
--- a/java/com/google/gerrit/server/restapi/change/CreateDraftComment.java
+++ b/java/com/google/gerrit/server/restapi/change/CreateDraftComment.java
@@ -84,7 +84,7 @@
try (BatchUpdate bu =
updateFactory.create(rsrc.getProject(), rsrc.getUser(), TimeUtil.nowTs())) {
- Op op = new Op(rsrc.getPatchSet().getId(), in);
+ Op op = new Op(rsrc.getPatchSet().id(), in);
bu.addOp(rsrc.getChange().getId(), op);
bu.execute();
return Response.created(
@@ -115,7 +115,7 @@
comment =
commentsUtil.newComment(
- ctx, in.path, ps.getId(), in.side(), in.message.trim(), in.unresolved, parentUuid);
+ ctx, in.path, ps.id(), in.side(), in.message.trim(), in.unresolved, parentUuid);
comment.setLineNbrAndRange(in.line, in.range);
comment.tag = in.tag;
diff --git a/java/com/google/gerrit/server/restapi/change/CreateMergePatchSet.java b/java/com/google/gerrit/server/restapi/change/CreateMergePatchSet.java
index 2b91f95..76fbab2 100644
--- a/java/com/google/gerrit/server/restapi/change/CreateMergePatchSet.java
+++ b/java/com/google/gerrit/server/restapi/change/CreateMergePatchSet.java
@@ -154,10 +154,10 @@
List<String> groups = null;
if (!in.inheritParent && !in.baseChange.isEmpty()) {
PatchSet basePS = findBasePatchSet(in.baseChange);
- currentPsCommit = rw.parseCommit(basePS.getCommitId());
- groups = basePS.getGroups();
+ currentPsCommit = rw.parseCommit(basePS.commitId());
+ groups = basePS.groups();
} else {
- currentPsCommit = rw.parseCommit(ps.getCommitId());
+ currentPsCommit = rw.parseCommit(ps.commitId());
}
Timestamp now = TimeUtil.nowTs();
@@ -176,7 +176,7 @@
author,
ObjectId.fromString(change.getKey().get().substring(1)));
- PatchSet.Id nextPsId = ChangeUtil.nextPatchSetId(ps.getId());
+ PatchSet.Id nextPsId = ChangeUtil.nextPatchSetId(ps.id());
PatchSetInserter psInserter =
patchSetInserterFactory.create(rsrc.getNotes(), nextPsId, newCommit);
try (BatchUpdate bu = updateFactory.create(project, me, now)) {
diff --git a/java/com/google/gerrit/server/restapi/change/DeleteVote.java b/java/com/google/gerrit/server/restapi/change/DeleteVote.java
index 77894fb..0c8240a 100644
--- a/java/com/google/gerrit/server/restapi/change/DeleteVote.java
+++ b/java/com/google/gerrit/server/restapi/change/DeleteVote.java
@@ -175,11 +175,11 @@
for (PatchSetApproval a :
approvalsUtil.byPatchSetUser(
ctx.getNotes(), psId, accountId, ctx.getRevWalk(), ctx.getRepoView().getConfig())) {
- if (labelTypes.byLabel(a.getLabelId()) == null) {
+ if (labelTypes.byLabel(a.labelId()) == null) {
continue; // Ignore undefined labels.
- } else if (!a.getLabel().equals(label)) {
+ } else if (!a.label().equals(label)) {
// Populate map for non-matching labels, needed by VoteDeleted.
- newApprovals.put(a.getLabel(), a.getValue());
+ newApprovals.put(a.label(), a.value());
continue;
} else {
try {
@@ -189,11 +189,11 @@
}
}
// Set the approval to 0 if vote is being removed.
- newApprovals.put(a.getLabel(), (short) 0);
+ newApprovals.put(a.label(), (short) 0);
found = true;
// Set old value, as required by VoteDeleted.
- oldApprovals.put(a.getLabel(), a.getValue());
+ oldApprovals.put(a.label(), a.value());
break;
}
if (!found) {
diff --git a/java/com/google/gerrit/server/restapi/change/DownloadContent.java b/java/com/google/gerrit/server/restapi/change/DownloadContent.java
index 9107666..60741e7 100644
--- a/java/com/google/gerrit/server/restapi/change/DownloadContent.java
+++ b/java/com/google/gerrit/server/restapi/change/DownloadContent.java
@@ -45,6 +45,6 @@
String path = rsrc.getPatchKey().fileName();
RevisionResource rev = rsrc.getRevision();
return fileContentUtil.downloadContent(
- projectCache.checkedGet(rev.getProject()), rev.getPatchSet().getCommitId(), path, parent);
+ projectCache.checkedGet(rev.getProject()), rev.getPatchSet().commitId(), path, parent);
}
}
diff --git a/java/com/google/gerrit/server/restapi/change/DraftComments.java b/java/com/google/gerrit/server/restapi/change/DraftComments.java
index dd61ca0..6a1e0f1 100644
--- a/java/com/google/gerrit/server/restapi/change/DraftComments.java
+++ b/java/com/google/gerrit/server/restapi/change/DraftComments.java
@@ -66,7 +66,7 @@
String uuid = id.get();
for (Comment c :
commentsUtil.draftByPatchSetAuthor(
- rev.getPatchSet().getId(), rev.getAccountId(), rev.getNotes())) {
+ rev.getPatchSet().id(), rev.getAccountId(), rev.getNotes())) {
if (uuid.equals(c.key.uuid)) {
return new DraftCommentResource(rev, c);
}
diff --git a/java/com/google/gerrit/server/restapi/change/Files.java b/java/com/google/gerrit/server/restapi/change/Files.java
index 5c9a41d..aa3b68c 100644
--- a/java/com/google/gerrit/server/restapi/change/Files.java
+++ b/java/com/google/gerrit/server/restapi/change/Files.java
@@ -162,13 +162,13 @@
Response.ok(
fileInfoJson.toFileInfoMap(
resource.getChange(),
- resource.getPatchSet().getCommitId(),
+ resource.getPatchSet().commitId(),
baseResource.getPatchSet()));
} else if (parentNum > 0) {
r =
Response.ok(
fileInfoJson.toFileInfoMap(
- resource.getChange(), resource.getPatchSet().getCommitId(), parentNum - 1));
+ resource.getChange(), resource.getPatchSet().commitId(), parentNum - 1));
} else {
r = Response.ok(fileInfoJson.toFileInfoMap(resource.getChange(), resource.getPatchSet()));
}
@@ -205,7 +205,7 @@
ObjectReader or = git.newObjectReader();
RevWalk rw = new RevWalk(or);
TreeWalk tw = new TreeWalk(or)) {
- RevCommit c = rw.parseCommit(resource.getPatchSet().getCommitId());
+ RevCommit c = rw.parseCommit(resource.getPatchSet().commitId());
tw.addTree(c.getTree());
tw.setRecursive(true);
@@ -229,11 +229,11 @@
Account.Id userId = user.getAccountId();
PatchSet patchSetId = resource.getPatchSet();
Optional<PatchSetWithReviewedFiles> o;
- o = accountPatchReviewStore.call(s -> s.findReviewed(patchSetId.getId(), userId));
+ o = accountPatchReviewStore.call(s -> s.findReviewed(patchSetId.id(), userId));
if (o.isPresent()) {
PatchSetWithReviewedFiles res = o.get();
- if (res.patchSetId().equals(patchSetId.getId())) {
+ if (res.patchSetId().equals(patchSetId.id())) {
return res.files();
}
@@ -312,7 +312,7 @@
}
accountPatchReviewStore.run(
- s -> s.markReviewed(resource.getPatchSet().getId(), userId, pathList));
+ s -> s.markReviewed(resource.getPatchSet().id(), userId, pathList));
return pathList;
}
}
diff --git a/java/com/google/gerrit/server/restapi/change/Fixes.java b/java/com/google/gerrit/server/restapi/change/Fixes.java
index 855d1f4..9255ee3 100644
--- a/java/com/google/gerrit/server/restapi/change/Fixes.java
+++ b/java/com/google/gerrit/server/restapi/change/Fixes.java
@@ -54,7 +54,7 @@
ChangeNotes changeNotes = revisionResource.getNotes();
List<RobotComment> robotComments =
- commentsUtil.robotCommentsByPatchSet(changeNotes, revisionResource.getPatchSet().getId());
+ commentsUtil.robotCommentsByPatchSet(changeNotes, revisionResource.getPatchSet().id());
for (RobotComment robotComment : robotComments) {
for (FixSuggestion fixSuggestion : robotComment.fixSuggestions) {
if (Objects.equals(fixId, fixSuggestion.fixId)) {
diff --git a/java/com/google/gerrit/server/restapi/change/GetArchive.java b/java/com/google/gerrit/server/restapi/change/GetArchive.java
index 5315ce1..2bf47e3 100644
--- a/java/com/google/gerrit/server/restapi/change/GetArchive.java
+++ b/java/com/google/gerrit/server/restapi/change/GetArchive.java
@@ -66,7 +66,7 @@
final RevCommit commit;
String name;
try (RevWalk rw = new RevWalk(repo)) {
- commit = rw.parseCommit(rsrc.getPatchSet().getCommitId());
+ commit = rw.parseCommit(rsrc.getPatchSet().commitId());
name = name(f, rw, commit);
}
diff --git a/java/com/google/gerrit/server/restapi/change/GetBlame.java b/java/com/google/gerrit/server/restapi/change/GetBlame.java
index d66deb3..cade702 100644
--- a/java/com/google/gerrit/server/restapi/change/GetBlame.java
+++ b/java/com/google/gerrit/server/restapi/change/GetBlame.java
@@ -87,7 +87,7 @@
String refName =
resource.getRevision().getEdit().isPresent()
? resource.getRevision().getEdit().get().getRefName()
- : resource.getRevision().getPatchSet().getRefName();
+ : resource.getRevision().getPatchSet().refName();
Ref ref = repository.findRef(refName);
if (ref == null) {
diff --git a/java/com/google/gerrit/server/restapi/change/GetCommit.java b/java/com/google/gerrit/server/restapi/change/GetCommit.java
index a6a44ad1..aeaafc4 100644
--- a/java/com/google/gerrit/server/restapi/change/GetCommit.java
+++ b/java/com/google/gerrit/server/restapi/change/GetCommit.java
@@ -54,7 +54,7 @@
Project.NameKey p = rsrc.getChange().getProject();
try (Repository repo = repoManager.openRepository(p);
RevWalk rw = new RevWalk(repo)) {
- RevCommit commit = rw.parseCommit(rsrc.getPatchSet().getCommitId());
+ RevCommit commit = rw.parseCommit(rsrc.getPatchSet().commitId());
rw.parseBody(commit);
CommitInfo info =
json.create(ImmutableSet.of())
diff --git a/java/com/google/gerrit/server/restapi/change/GetContent.java b/java/com/google/gerrit/server/restapi/change/GetContent.java
index fbc52f3..62889a3 100644
--- a/java/com/google/gerrit/server/restapi/change/GetContent.java
+++ b/java/com/google/gerrit/server/restapi/change/GetContent.java
@@ -76,7 +76,7 @@
}
return fileContentUtil.getContent(
projectCache.checkedGet(rsrc.getRevision().getProject()),
- rsrc.getRevision().getPatchSet().getCommitId(),
+ rsrc.getRevision().getPatchSet().commitId(),
path,
parent);
}
@@ -90,7 +90,7 @@
try (Repository git = gitManager.openRepository(notes.getProjectName());
RevWalk revWalk = new RevWalk(git)) {
- RevCommit commit = revWalk.parseCommit(ps.getCommitId());
+ RevCommit commit = revWalk.parseCommit(ps.commitId());
return commit.getFullMessage();
} catch (RepositoryNotFoundException e) {
throw new NoSuchChangeException(changeId, e);
@@ -107,7 +107,7 @@
try (Repository git = gitManager.openRepository(notes.getProjectName());
RevWalk revWalk = new RevWalk(git)) {
return Text.forMergeList(
- ComparisonType.againstAutoMerge(), revWalk.getObjectReader(), ps.getCommitId())
+ ComparisonType.againstAutoMerge(), revWalk.getObjectReader(), ps.commitId())
.getContent();
} catch (RepositoryNotFoundException e) {
throw new NoSuchChangeException(changeId, e);
diff --git a/java/com/google/gerrit/server/restapi/change/GetDescription.java b/java/com/google/gerrit/server/restapi/change/GetDescription.java
index 1a7ec63..c30bd0d 100644
--- a/java/com/google/gerrit/server/restapi/change/GetDescription.java
+++ b/java/com/google/gerrit/server/restapi/change/GetDescription.java
@@ -14,7 +14,6 @@
package com.google.gerrit.server.restapi.change;
-import com.google.common.base.Strings;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.server.change.RevisionResource;
import com.google.inject.Singleton;
@@ -23,6 +22,6 @@
public class GetDescription implements RestReadView<RevisionResource> {
@Override
public String apply(RevisionResource rsrc) {
- return Strings.nullToEmpty(rsrc.getPatchSet().getDescription());
+ return rsrc.getPatchSet().description().orElse("");
}
}
diff --git a/java/com/google/gerrit/server/restapi/change/GetDiff.java b/java/com/google/gerrit/server/restapi/change/GetDiff.java
index 8b5cdaf..e47865c 100644
--- a/java/com/google/gerrit/server/restapi/change/GetDiff.java
+++ b/java/com/google/gerrit/server/restapi/change/GetDiff.java
@@ -147,7 +147,7 @@
RevisionResource baseResource =
revisions.parse(resource.getRevision().getChangeResource(), IdString.fromDecoded(base));
basePatchSet = baseResource.getPatchSet();
- psf = patchScriptFactoryFactory.create(notes, fileName, basePatchSet.getId(), pId, prefs);
+ psf = patchScriptFactoryFactory.create(notes, fileName, basePatchSet.id(), pId, prefs);
} else if (parentNum > 0) {
psf = patchScriptFactoryFactory.create(notes, fileName, parentNum - 1, pId, prefs);
} else {
@@ -195,17 +195,17 @@
ProjectState state = projectCache.get(resource.getRevision().getChange().getProject());
DiffInfo result = new DiffInfo();
- String revA = basePatchSet != null ? basePatchSet.getRefName() : content.commitIdA;
+ String revA = basePatchSet != null ? basePatchSet.refName() : content.commitIdA;
String revB =
resource.getRevision().getEdit().isPresent()
? resource.getRevision().getEdit().get().getRefName()
- : resource.getRevision().getPatchSet().getRefName();
+ : resource.getRevision().getPatchSet().refName();
- List<DiffWebLinkInfo> links =
+ ImmutableList<DiffWebLinkInfo> links =
webLinks.getDiffLinks(
state.getName(),
resource.getPatchKey().patchSetId().changeId().get(),
- basePatchSet != null ? basePatchSet.getId().get() : null,
+ basePatchSet != null ? basePatchSet.id().get() : null,
revA,
MoreObjects.firstNonNull(ps.getOldName(), ps.getNewName()),
resource.getPatchKey().patchSetId().get(),
@@ -273,7 +273,7 @@
}
private List<WebLinkInfo> getFileWebLinks(Project project, String rev, String file) {
- List<WebLinkInfo> links = webLinks.getFileLinks(project.getName(), rev, file);
+ ImmutableList<WebLinkInfo> links = webLinks.getFileLinks(project.getName(), rev, file);
return links.isEmpty() ? null : links;
}
diff --git a/java/com/google/gerrit/server/restapi/change/GetMergeList.java b/java/com/google/gerrit/server/restapi/change/GetMergeList.java
index bece3e0..48d6dcb 100644
--- a/java/com/google/gerrit/server/restapi/change/GetMergeList.java
+++ b/java/com/google/gerrit/server/restapi/change/GetMergeList.java
@@ -66,7 +66,7 @@
Project.NameKey p = rsrc.getChange().getProject();
try (Repository repo = repoManager.openRepository(p);
RevWalk rw = new RevWalk(repo)) {
- RevCommit commit = rw.parseCommit(rsrc.getPatchSet().getCommitId());
+ RevCommit commit = rw.parseCommit(rsrc.getPatchSet().commitId());
rw.parseBody(commit);
if (uninterestingParent < 1 || uninterestingParent > commit.getParentCount()) {
diff --git a/java/com/google/gerrit/server/restapi/change/GetPatch.java b/java/com/google/gerrit/server/restapi/change/GetPatch.java
index edfa2a8..186752e 100644
--- a/java/com/google/gerrit/server/restapi/change/GetPatch.java
+++ b/java/com/google/gerrit/server/restapi/change/GetPatch.java
@@ -66,7 +66,7 @@
try {
final RevWalk rw = new RevWalk(repo);
try {
- final RevCommit commit = rw.parseCommit(rsrc.getPatchSet().getCommitId());
+ final RevCommit commit = rw.parseCommit(rsrc.getPatchSet().commitId());
RevCommit[] parents = commit.getParents();
if (parents.length > 1) {
throw new ResourceConflictException("Revision has more than 1 parent.");
diff --git a/java/com/google/gerrit/server/restapi/change/GetRelated.java b/java/com/google/gerrit/server/restapi/change/GetRelated.java
index ad2c7d4..fab081b 100644
--- a/java/com/google/gerrit/server/restapi/change/GetRelated.java
+++ b/java/com/google/gerrit/server/restapi/change/GetRelated.java
@@ -102,7 +102,7 @@
for (RelatedChangesSorter.PatchSetData d : sorter.sort(cds, basePs)) {
PatchSet ps = d.patchSet();
RevCommit commit;
- if (isEdit && ps.getId().equals(basePs.getId())) {
+ if (isEdit && ps.id().equals(basePs.id())) {
// Replace base of an edit with the edit itself.
ps = rsrc.getPatchSet();
commit = rsrc.getEdit().get().getEditCommit();
@@ -114,7 +114,7 @@
if (result.size() == 1) {
RelatedChangeAndCommitInfo r = result.get(0);
- if (r.commit != null && r.commit.commit.equals(rsrc.getPatchSet().getCommitId().name())) {
+ if (r.commit != null && r.commit.commit.equals(rsrc.getPatchSet().commitId().name())) {
return Collections.emptyList();
}
}
@@ -123,13 +123,13 @@
@VisibleForTesting
public static Set<String> getAllGroups(ChangeNotes notes, PatchSetUtil psUtil) {
- return psUtil.byChange(notes).stream().flatMap(ps -> ps.getGroups().stream()).collect(toSet());
+ return psUtil.byChange(notes).stream().flatMap(ps -> ps.groups().stream()).collect(toSet());
}
private void reloadChangeIfStale(List<ChangeData> cds, PatchSet wantedPs) {
for (ChangeData cd : cds) {
- if (cd.getId().equals(wantedPs.getId().changeId())) {
- if (cd.patchSet(wantedPs.getId()) == null) {
+ if (cd.getId().equals(wantedPs.id().changeId())) {
+ if (cd.patchSet(wantedPs.id()) == null) {
cd.reloadChange();
}
}
@@ -144,7 +144,7 @@
if (change != null) {
info.changeId = change.getKey().get();
info._changeNumber = change.getChangeId();
- info._revisionNumber = ps != null ? ps.getPatchSetId() : null;
+ info._revisionNumber = ps != null ? ps.number() : null;
PatchSet.Id curr = change.currentPatchSetId();
info._currentRevisionNumber = curr != null ? curr.get() : null;
info.status = ChangeUtil.status(change).toUpperCase(Locale.US);
diff --git a/java/com/google/gerrit/server/restapi/change/ListRevisionComments.java b/java/com/google/gerrit/server/restapi/change/ListRevisionComments.java
index b39ba63..f2e5a37 100644
--- a/java/com/google/gerrit/server/restapi/change/ListRevisionComments.java
+++ b/java/com/google/gerrit/server/restapi/change/ListRevisionComments.java
@@ -37,6 +37,6 @@
@Override
protected Iterable<Comment> listComments(RevisionResource rsrc) {
ChangeNotes notes = rsrc.getNotes();
- return commentsUtil.publishedByPatchSet(notes, rsrc.getPatchSet().getId());
+ return commentsUtil.publishedByPatchSet(notes, rsrc.getPatchSet().id());
}
}
diff --git a/java/com/google/gerrit/server/restapi/change/ListRevisionDrafts.java b/java/com/google/gerrit/server/restapi/change/ListRevisionDrafts.java
index a46bd6c..73b92f5 100644
--- a/java/com/google/gerrit/server/restapi/change/ListRevisionDrafts.java
+++ b/java/com/google/gerrit/server/restapi/change/ListRevisionDrafts.java
@@ -40,7 +40,7 @@
protected Iterable<Comment> listComments(RevisionResource rsrc) {
return commentsUtil.draftByPatchSetAuthor(
- rsrc.getPatchSet().getId(), rsrc.getAccountId(), rsrc.getNotes());
+ rsrc.getPatchSet().id(), rsrc.getAccountId(), rsrc.getNotes());
}
protected boolean includeAuthorInfo() {
diff --git a/java/com/google/gerrit/server/restapi/change/ListRobotComments.java b/java/com/google/gerrit/server/restapi/change/ListRobotComments.java
index bbf46a3..d617a10 100644
--- a/java/com/google/gerrit/server/restapi/change/ListRobotComments.java
+++ b/java/com/google/gerrit/server/restapi/change/ListRobotComments.java
@@ -58,6 +58,6 @@
}
private Iterable<RobotComment> listComments(RevisionResource rsrc) {
- return commentsUtil.robotCommentsByPatchSet(rsrc.getNotes(), rsrc.getPatchSet().getId());
+ return commentsUtil.robotCommentsByPatchSet(rsrc.getNotes(), rsrc.getPatchSet().id());
}
}
diff --git a/java/com/google/gerrit/server/restapi/change/Mergeable.java b/java/com/google/gerrit/server/restapi/change/Mergeable.java
index 800ebfa7..f20e03d 100644
--- a/java/com/google/gerrit/server/restapi/change/Mergeable.java
+++ b/java/com/google/gerrit/server/restapi/change/Mergeable.java
@@ -94,7 +94,7 @@
if (!change.isNew()) {
throw new ResourceConflictException("change is " + ChangeUtil.status(change));
- } else if (!ps.getId().equals(change.currentPatchSetId())) {
+ } else if (!ps.id().equals(change.currentPatchSetId())) {
// Only the current revision is mergeable. Others always fail.
return result;
}
@@ -103,7 +103,7 @@
result.submitType = getSubmitType(cd);
try (Repository git = gitManager.openRepository(change.getProject())) {
- ObjectId commit = ps.getCommitId();
+ ObjectId commit = ps.commitId();
Ref ref = git.getRefDatabase().exactRef(change.getDest().branch());
ProjectState projectState = projectCache.get(change.getProject());
String strategy = mergeUtilFactory.create(projectState).mergeStrategyName();
diff --git a/java/com/google/gerrit/server/restapi/change/Move.java b/java/com/google/gerrit/server/restapi/change/Move.java
index 1b0bc98..b5c774c 100644
--- a/java/com/google/gerrit/server/restapi/change/Move.java
+++ b/java/com/google/gerrit/server/restapi/change/Move.java
@@ -193,7 +193,7 @@
try (Repository repo = repoManager.openRepository(projectKey);
RevWalk revWalk = new RevWalk(repo)) {
RevCommit currPatchsetRevCommit =
- revWalk.parseCommit(psUtil.current(ctx.getNotes()).getCommitId());
+ revWalk.parseCommit(psUtil.current(ctx.getNotes()).commitId());
if (currPatchsetRevCommit.getParentCount() > 1) {
throw new ResourceConflictException("Merge commit cannot be moved");
}
@@ -261,7 +261,7 @@
approvalsUtil.byPatchSet(
ctx.getNotes(), psId, ctx.getRevWalk(), ctx.getRepoView().getConfig())) {
ProjectState projectState = projectCache.checkedGet(project);
- LabelType type = projectState.getLabelTypes(ctx.getNotes()).byLabel(psa.getLabelId());
+ LabelType type = projectState.getLabelTypes(ctx.getNotes()).byLabel(psa.labelId());
// Only keep veto votes, defined as votes where:
// 1- the label function allows minimum values to block submission.
// 2- the vote holds the minimum value.
@@ -270,12 +270,13 @@
}
// Remove votes from NoteDb.
- update.removeApprovalFor(psa.getAccountId(), psa.getLabel());
+ update.removeApprovalFor(psa.accountId(), psa.label());
approvals.add(
- new PatchSetApproval(
- PatchSetApproval.key(psId, psa.getAccountId(), LabelId.create(psa.getLabel())),
- (short) 0,
- ctx.getWhen()));
+ PatchSetApproval.builder()
+ .key(PatchSetApproval.key(psId, psa.accountId(), LabelId.create(psa.label())))
+ .value(0)
+ .granted(ctx.getWhen())
+ .build());
}
}
}
diff --git a/java/com/google/gerrit/server/restapi/change/PostReview.java b/java/com/google/gerrit/server/restapi/change/PostReview.java
index ab8f270..18d668a 100644
--- a/java/com/google/gerrit/server/restapi/change/PostReview.java
+++ b/java/com/google/gerrit/server/restapi/change/PostReview.java
@@ -133,6 +133,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.OptionalInt;
import java.util.Set;
import org.eclipse.jgit.errors.ConfigInvalidException;
@@ -356,8 +357,7 @@
// Add the review op.
bu.addOp(
- revision.getChange().getId(),
- new Op(projectState, revision.getPatchSet().getId(), input));
+ revision.getChange().getId(), new Op(projectState, revision.getPatchSet().id(), input));
// Notify based on ReviewInput, ignoring the notify settings from any AddReviewerInputs.
NotifyResolver.Result notify =
@@ -570,7 +570,7 @@
Set<String> revisionFilePaths = getAffectedFilePaths(revision);
for (Map.Entry<String, List<T>> entry : commentsPerPath.entrySet()) {
String path = entry.getKey();
- PatchSet.Id patchSetId = revision.getPatchSet().getId();
+ PatchSet.Id patchSetId = revision.getPatchSet().id();
ensurePathRefersToAvailableOrMagicFile(path, revisionFilePaths, patchSetId);
List<T> comments = entry.getValue();
@@ -584,7 +584,7 @@
private Set<String> getAffectedFilePaths(RevisionResource revision)
throws PatchListNotAvailableException {
- ObjectId newId = revision.getPatchSet().getCommitId();
+ ObjectId newId = revision.getPatchSet().commitId();
DiffSummaryKey key =
DiffSummaryKey.fromPatchListKey(
PatchListKey.againstDefaultBase(newId, Whitespace.IGNORE_NONE));
@@ -1062,7 +1062,7 @@
private Map<String, Short> approvalsByKey(Collection<PatchSetApproval> patchsetApprovals) {
Map<String, Short> labels = new HashMap<>();
for (PatchSetApproval psa : patchsetApprovals) {
- labels.put(psa.getLabel(), psa.getValue());
+ labels.put(psa.label(), psa.value());
}
return labels;
}
@@ -1142,35 +1142,40 @@
// User requested delete of this label.
oldApprovals.put(normName, null);
if (c != null) {
- if (c.getValue() != 0) {
+ if (c.value() != 0) {
addLabelDelta(normName, (short) 0);
oldApprovals.put(normName, previous.get(normName));
}
del.add(c);
update.putApproval(normName, (short) 0);
}
- } else if (c != null && c.getValue() != ent.getValue()) {
- c.setValue(ent.getValue());
- c.setGranted(ctx.getWhen());
- c.setTag(in.tag);
- ctx.getUser().updateRealAccountId(c::setRealAccountId);
+ } else if (c != null && c.value() != ent.getValue()) {
+ PatchSetApproval.Builder b =
+ c.toBuilder()
+ .value(ent.getValue())
+ .granted(ctx.getWhen())
+ .tag(Optional.ofNullable(in.tag));
+ ctx.getUser().updateRealAccountId(b::realAccountId);
+ c = b.build();
ups.add(c);
- addLabelDelta(normName, c.getValue());
+ addLabelDelta(normName, c.value());
oldApprovals.put(normName, previous.get(normName));
- approvals.put(normName, c.getValue());
+ approvals.put(normName, c.value());
update.putApproval(normName, ent.getValue());
- } else if (c != null && c.getValue() == ent.getValue()) {
+ } else if (c != null && c.value() == ent.getValue()) {
current.put(normName, c);
oldApprovals.put(normName, null);
- approvals.put(normName, c.getValue());
+ approvals.put(normName, c.value());
} else if (c == null) {
- c = ApprovalsUtil.newApproval(psId, user, lt.getLabelId(), ent.getValue(), ctx.getWhen());
- c.setTag(in.tag);
- c.setGranted(ctx.getWhen());
+ c =
+ ApprovalsUtil.newApproval(psId, user, lt.getLabelId(), ent.getValue(), ctx.getWhen())
+ .tag(Optional.ofNullable(in.tag))
+ .granted(ctx.getWhen())
+ .build();
ups.add(c);
- addLabelDelta(normName, c.getValue());
+ addLabelDelta(normName, c.value());
oldApprovals.put(normName, previous.get(normName));
- approvals.put(normName, c.getValue());
+ approvals.put(normName, c.value());
update.putReviewer(user.getAccountId(), REVIEWER);
update.putApproval(normName, ent.getValue());
}
@@ -1212,7 +1217,7 @@
List<String> disallowed = new ArrayList<>(labelTypes.getLabelTypes().size());
for (PatchSetApproval psa : del) {
- LabelType lt = requireNonNull(labelTypes.byLabel(psa.getLabel()));
+ LabelType lt = requireNonNull(labelTypes.byLabel(psa.label()));
String normName = lt.getName();
if (!lt.allowPostSubmit()) {
disallowed.add(normName);
@@ -1224,7 +1229,7 @@
}
for (PatchSetApproval psa : ups) {
- LabelType lt = requireNonNull(labelTypes.byLabel(psa.getLabel()));
+ LabelType lt = requireNonNull(labelTypes.byLabel(psa.label()));
String normName = lt.getName();
if (!lt.allowPostSubmit()) {
disallowed.add(normName);
@@ -1233,8 +1238,8 @@
if (prev == null) {
continue;
}
- checkState(prev != psa.getValue()); // Should be filtered out above.
- if (prev > psa.getValue()) {
+ checkState(prev != psa.value()); // Should be filtered out above.
+ if (prev > psa.value()) {
reduced.add(psa);
}
// No need to set postSubmit bit, which is set automatically when parsing from NoteDb.
@@ -1249,7 +1254,7 @@
throw new ResourceConflictException(
"Cannot reduce vote on labels for closed change: "
+ reduced.stream()
- .map(PatchSetApproval::getLabel)
+ .map(PatchSetApproval::label)
.distinct()
.sorted()
.collect(joining(", ")));
@@ -1276,18 +1281,16 @@
}
LabelId labelId = labelTypes.get(0).getLabelId();
- PatchSetApproval c = ApprovalsUtil.newApproval(psId, user, labelId, 0, ctx.getWhen());
- c.setTag(in.tag);
- c.setGranted(ctx.getWhen());
- ups.add(c);
+ ups.add(
+ ApprovalsUtil.newApproval(psId, user, labelId, 0, ctx.getWhen())
+ .tag(Optional.ofNullable(in.tag))
+ .granted(ctx.getWhen())
+ .build());
} else {
// Pick a random label that is about to be deleted and keep it.
Iterator<PatchSetApproval> i = del.iterator();
- PatchSetApproval c = i.next();
- c.setValue((short) 0);
- c.setGranted(ctx.getWhen());
+ ups.add(i.next().toBuilder().value(0).granted(ctx.getWhen()).build());
i.remove();
- ups.add(c);
}
}
ctx.getUpdate(ctx.getChange().currentPatchSetId()).putReviewer(user.getAccountId(), REVIEWER);
@@ -1310,7 +1313,7 @@
continue;
}
- LabelType lt = labelTypes.byLabel(a.getLabelId());
+ LabelType lt = labelTypes.byLabel(a.labelId());
if (lt != null) {
current.put(lt.getName(), a);
} else {
diff --git a/java/com/google/gerrit/server/restapi/change/PutDescription.java b/java/com/google/gerrit/server/restapi/change/PutDescription.java
index 0ec38e1..a2bff76 100644
--- a/java/com/google/gerrit/server/restapi/change/PutDescription.java
+++ b/java/com/google/gerrit/server/restapi/change/PutDescription.java
@@ -57,7 +57,7 @@
throws UpdateException, RestApiException, PermissionBackendException {
rsrc.permissions().check(ChangePermission.EDIT_DESCRIPTION);
- Op op = new Op(input != null ? input : new DescriptionInput(), rsrc.getPatchSet().getId());
+ Op op = new Op(input != null ? input : new DescriptionInput(), rsrc.getPatchSet().id());
try (BatchUpdate u =
updateFactory.create(rsrc.getChange().getProject(), rsrc.getUser(), TimeUtil.nowTs())) {
u.addOp(rsrc.getChange().getId(), op);
@@ -84,7 +84,7 @@
public boolean updateChange(ChangeContext ctx) {
ChangeUpdate update = ctx.getUpdate(psId);
newDescription = Strings.nullToEmpty(input.description);
- oldDescription = Strings.nullToEmpty(psUtil.get(ctx.getNotes(), psId).getDescription());
+ oldDescription = psUtil.get(ctx.getNotes(), psId).description().orElse("");
if (oldDescription.equals(newDescription)) {
return false;
}
diff --git a/java/com/google/gerrit/server/restapi/change/PutMessage.java b/java/com/google/gerrit/server/restapi/change/PutMessage.java
index 1f0c282..db02418 100644
--- a/java/com/google/gerrit/server/restapi/change/PutMessage.java
+++ b/java/com/google/gerrit/server/restapi/change/PutMessage.java
@@ -119,7 +119,7 @@
try (Repository repository = repositoryManager.openRepository(resource.getProject());
RevWalk revWalk = new RevWalk(repository);
ObjectInserter objectInserter = repository.newObjectInserter()) {
- RevCommit patchSetCommit = revWalk.parseCommit(ps.getCommitId());
+ RevCommit patchSetCommit = revWalk.parseCommit(ps.commitId());
String currentCommitMessage = patchSetCommit.getFullMessage();
if (input.message.equals(currentCommitMessage)) {
@@ -132,7 +132,7 @@
// Ensure that BatchUpdate will update the same repo
bu.setRepository(repository, new RevWalk(objectInserter.newReader()), objectInserter);
- PatchSet.Id psId = ChangeUtil.nextPatchSetId(repository, ps.getId());
+ PatchSet.Id psId = ChangeUtil.nextPatchSetId(repository, ps.id());
ObjectId newCommit =
createCommit(objectInserter, patchSetCommit, sanitizedCommitMessage, ts);
PatchSetInserter inserter = psInserterFactory.create(resource.getNotes(), psId, newCommit);
diff --git a/java/com/google/gerrit/server/restapi/change/Rebase.java b/java/com/google/gerrit/server/restapi/change/Rebase.java
index de88d9a..dbe9eff 100644
--- a/java/com/google/gerrit/server/restapi/change/Rebase.java
+++ b/java/com/google/gerrit/server/restapi/change/Rebase.java
@@ -159,7 +159,7 @@
throw new ResourceConflictException(
"base revision is missing from the destination branch: " + str);
}
- PatchSet.Id baseId = base.patchSet().getId();
+ PatchSet.Id baseId = base.patchSet().id();
if (change.getId().equals(baseId.changeId())) {
throw new ResourceConflictException("cannot rebase change onto itself");
}
@@ -181,18 +181,18 @@
+ baseChange.getKey()
+ " is a descendant of the current change - recursion not allowed");
}
- return base.patchSet().getCommitId();
+ return base.patchSet().commitId();
}
private boolean isMergedInto(RevWalk rw, PatchSet base, PatchSet tip) throws IOException {
- ObjectId baseId = base.getCommitId();
- ObjectId tipId = tip.getCommitId();
+ ObjectId baseId = base.commitId();
+ ObjectId tipId = tip.commitId();
return rw.isMergedInto(rw.parseCommit(baseId), rw.parseCommit(tipId));
}
private boolean hasOneParent(RevWalk rw, PatchSet ps) throws IOException {
// Prevent rebase of exotic changes (merge commit, no ancestor).
- RevCommit c = rw.parseCommit(ps.getCommitId());
+ RevCommit c = rw.parseCommit(ps.commitId());
return c.getParentCount() == 1;
}
diff --git a/java/com/google/gerrit/server/restapi/change/RelatedChangesSorter.java b/java/com/google/gerrit/server/restapi/change/RelatedChangesSorter.java
index abc6428..987da56 100644
--- a/java/com/google/gerrit/server/restapi/change/RelatedChangesSorter.java
+++ b/java/com/google/gerrit/server/restapi/change/RelatedChangesSorter.java
@@ -75,7 +75,7 @@
checkArgument(!in.isEmpty(), "Input may not be empty");
// Map of all patch sets, keyed by commit SHA-1.
Map<ObjectId, PatchSetData> byId = collectById(in);
- PatchSetData start = byId.get(startPs.getCommitId());
+ PatchSetData start = byId.get(startPs.commitId());
checkArgument(start != null, "%s not found in %s", startPs, in);
// Map of patch set -> immediate parent.
@@ -89,8 +89,8 @@
for (ChangeData cd : in) {
for (PatchSet ps : cd.patchSets()) {
- PatchSetData thisPsd = requireNonNull(byId.get(ps.getCommitId()));
- if (cd.getId().equals(start.id()) && !ps.getId().equals(start.psId())) {
+ PatchSetData thisPsd = requireNonNull(byId.get(ps.commitId()));
+ if (cd.getId().equals(start.id()) && !ps.id().equals(start.psId())) {
otherPatchSetsOfStart.add(thisPsd);
}
for (RevCommit p : thisPsd.commit().getParents()) {
@@ -126,9 +126,9 @@
project,
cd.change().getProject());
for (PatchSet ps : cd.patchSets()) {
- RevCommit c = rw.parseCommit(ps.getCommitId());
+ RevCommit c = rw.parseCommit(ps.commitId());
PatchSetData psd = PatchSetData.create(cd, ps, c);
- result.put(ps.getCommitId(), psd);
+ result.put(ps.commitId(), psd);
}
}
}
@@ -251,7 +251,7 @@
abstract RevCommit commit();
PatchSet.Id psId() {
- return patchSet().getId();
+ return patchSet().id();
}
Change.Id id() {
@@ -260,7 +260,7 @@
@Override
public int hashCode() {
- return Objects.hash(patchSet().getId(), commit());
+ return Objects.hash(patchSet().id(), commit());
}
@Override
@@ -269,7 +269,7 @@
return false;
}
PatchSetData o = (PatchSetData) obj;
- return Objects.equals(patchSet().getId(), o.patchSet().getId())
+ return Objects.equals(patchSet().id(), o.patchSet().id())
&& Objects.equals(commit(), o.commit());
}
}
diff --git a/java/com/google/gerrit/server/restapi/change/Revert.java b/java/com/google/gerrit/server/restapi/change/Revert.java
index d854d9f..dc6a073a 100644
--- a/java/com/google/gerrit/server/restapi/change/Revert.java
+++ b/java/com/google/gerrit/server/restapi/change/Revert.java
@@ -172,7 +172,7 @@
ObjectInserter oi = git.newObjectInserter();
ObjectReader reader = oi.newReader();
RevWalk revWalk = new RevWalk(reader)) {
- RevCommit commitToRevert = revWalk.parseCommit(patch.getCommitId());
+ RevCommit commitToRevert = revWalk.parseCommit(patch.commitId());
if (commitToRevert.getParentCount() == 0) {
throw new ResourceConflictException("Cannot revert initial commit");
}
@@ -197,7 +197,7 @@
MessageFormat.format(
ChangeMessages.get().revertChangeDefaultMessage,
changeToRevert.getSubject(),
- patch.getCommitId().name());
+ patch.commitId().name());
}
ObjectId computedChangeId =
diff --git a/java/com/google/gerrit/server/restapi/change/ReviewerRecommender.java b/java/com/google/gerrit/server/restapi/change/ReviewerRecommender.java
index ed487f7..ea7182f 100644
--- a/java/com/google/gerrit/server/restapi/change/ReviewerRecommender.java
+++ b/java/com/google/gerrit/server/restapi/change/ReviewerRecommender.java
@@ -209,7 +209,7 @@
Map<Account.Id, MutableDouble> suggestions = new HashMap<>();
for (ChangeData cd : result) {
for (PatchSetApproval approval : cd.currentApprovals()) {
- Account.Id id = approval.getAccountId();
+ Account.Id id = approval.accountId();
if (suggestions.containsKey(id)) {
suggestions.get(id).add(baseWeight);
} else {
diff --git a/java/com/google/gerrit/server/restapi/change/ReviewersUtil.java b/java/com/google/gerrit/server/restapi/change/ReviewersUtil.java
index 1704153..248dc6e 100644
--- a/java/com/google/gerrit/server/restapi/change/ReviewersUtil.java
+++ b/java/com/google/gerrit/server/restapi/change/ReviewersUtil.java
@@ -115,9 +115,9 @@
}
}
- // Generate a candidate list at 2x the size of what the user wants to see to
+ // Generate a candidate list at 3x the size of what the user wants to see to
// give the ranking algorithm a good set of candidates it can work with
- private static final int CANDIDATE_LIST_MULTIPLIER = 2;
+ private static final int CANDIDATE_LIST_MULTIPLIER = 3;
private final AccountLoader.Factory accountLoaderFactory;
private final AccountQueryBuilder accountQueryBuilder;
diff --git a/java/com/google/gerrit/server/restapi/change/Revisions.java b/java/com/google/gerrit/server/restapi/change/Revisions.java
index dca8b62..dfba895 100644
--- a/java/com/google/gerrit/server/restapi/change/Revisions.java
+++ b/java/com/google/gerrit/server/restapi/change/Revisions.java
@@ -37,11 +37,13 @@
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.IOException;
+import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.revwalk.RevCommit;
@Singleton
public class Revisions implements ChildCollection<ChangeResource, RevisionResource> {
@@ -129,7 +131,7 @@
} else {
List<RevisionResource> out = new ArrayList<>();
for (PatchSet ps : psUtil.byChange(change.getNotes())) {
- if (ObjectIds.matchesAbbreviation(ps.getCommitId(), id)) {
+ if (ObjectIds.matchesAbbreviation(ps.commitId(), id)) {
out.add(new RevisionResource(change, ps));
}
}
@@ -153,9 +155,15 @@
throws AuthException, IOException {
Optional<ChangeEdit> edit = editUtil.byChange(change.getNotes(), change.getUser());
if (edit.isPresent()) {
- ObjectId editCommitId = edit.get().getEditCommit();
- PatchSet ps = new PatchSet(PatchSet.id(change.getId(), 0), editCommitId);
- if (commitId == null || editCommitId.equals(commitId)) {
+ RevCommit editCommit = edit.get().getEditCommit();
+ PatchSet ps =
+ PatchSet.builder()
+ .id(PatchSet.id(change.getId(), 0))
+ .commitId(editCommit)
+ .uploader(change.getUser().getAccountId())
+ .createdOn(new Timestamp(editCommit.getCommitterIdent().getWhen().getTime()))
+ .build();
+ if (commitId == null || editCommit.equals(commitId)) {
return Collections.singletonList(new RevisionResource(change, ps, edit));
}
}
diff --git a/java/com/google/gerrit/server/restapi/change/RobotComments.java b/java/com/google/gerrit/server/restapi/change/RobotComments.java
index 1aa8c2a..4ff8ca9 100644
--- a/java/com/google/gerrit/server/restapi/change/RobotComments.java
+++ b/java/com/google/gerrit/server/restapi/change/RobotComments.java
@@ -59,7 +59,7 @@
String uuid = id.get();
ChangeNotes notes = rev.getNotes();
- for (RobotComment c : commentsUtil.robotCommentsByPatchSet(notes, rev.getPatchSet().getId())) {
+ for (RobotComment c : commentsUtil.robotCommentsByPatchSet(notes, rev.getPatchSet().id())) {
if (uuid.equals(c.key.uuid)) {
return new RobotCommentResource(rev, c);
}
diff --git a/java/com/google/gerrit/server/restapi/change/Submit.java b/java/com/google/gerrit/server/restapi/change/Submit.java
index db2645c..8aadadd 100644
--- a/java/com/google/gerrit/server/restapi/change/Submit.java
+++ b/java/com/google/gerrit/server/restapi/change/Submit.java
@@ -198,11 +198,11 @@
} else if (!ProjectUtil.branchExists(repoManager, change.getDest())) {
throw new ResourceConflictException(
String.format("destination branch \"%s\" not found.", change.getDest().branch()));
- } else if (!rsrc.getPatchSet().getId().equals(change.currentPatchSetId())) {
+ } else if (!rsrc.getPatchSet().id().equals(change.currentPatchSetId())) {
// TODO Allow submitting non-current revision by changing the current.
throw new ResourceConflictException(
String.format(
- "revision %s is not current revision", rsrc.getPatchSet().getCommitId().name()));
+ "revision %s is not current revision", rsrc.getPatchSet().commitId().name()));
}
try (MergeOp op = mergeOpProvider.get()) {
@@ -366,9 +366,9 @@
}
Map<String, String> params =
ImmutableMap.of(
- "patchSet", String.valueOf(resource.getPatchSet().getPatchSetId()),
+ "patchSet", String.valueOf(resource.getPatchSet().number()),
"branch", change.getDest().shortName(),
- "commit", abbreviateName(resource.getPatchSet().getCommitId()),
+ "commit", abbreviateName(resource.getPatchSet().commitId()),
"submitSize", String.valueOf(cs.size()));
ParameterizedString tp = cs.size() > 1 ? titlePatternWithAncestors : titlePattern;
return new UiAction.Description()
@@ -432,7 +432,7 @@
try (Repository repo = repoManager.openRepository(project);
RevWalk walk = new RevWalk(repo)) {
for (ChangeData change : changes) {
- RevCommit commit = walk.parseCommit(psUtil.current(change.notes()).getCommitId());
+ RevCommit commit = walk.parseCommit(psUtil.current(change.notes()).commitId());
commits.put(change.getId(), commit);
}
}
diff --git a/java/com/google/gerrit/server/restapi/change/Votes.java b/java/com/google/gerrit/server/restapi/change/Votes.java
index 31efe54..8f48aa5 100644
--- a/java/com/google/gerrit/server/restapi/change/Votes.java
+++ b/java/com/google/gerrit/server/restapi/change/Votes.java
@@ -85,7 +85,7 @@
null,
null);
for (PatchSetApproval psa : byPatchSetUser) {
- votes.put(psa.getLabel(), psa.getValue());
+ votes.put(psa.label(), psa.value());
}
return votes;
}
diff --git a/java/com/google/gerrit/server/restapi/group/GetAuditLog.java b/java/com/google/gerrit/server/restapi/group/GetAuditLog.java
index 218293d..195ac4a 100644
--- a/java/com/google/gerrit/server/restapi/group/GetAuditLog.java
+++ b/java/com/google/gerrit/server/restapi/group/GetAuditLog.java
@@ -24,7 +24,7 @@
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.client.AccountGroupByIdAud;
+import com.google.gerrit.reviewdb.client.AccountGroupByIdAudit;
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
import com.google.gerrit.server.account.AccountLoader;
import com.google.gerrit.server.account.GroupBackend;
@@ -90,22 +90,24 @@
try (Repository allUsersRepo = repoManager.openRepository(allUsers)) {
for (AccountGroupMemberAudit auditEvent :
groups.getMembersAudit(allUsersRepo, group.getGroupUUID())) {
- AccountInfo member = accountLoader.get(auditEvent.getMemberId());
+ AccountInfo member = accountLoader.get(auditEvent.memberId());
auditEvents.add(
GroupAuditEventInfo.createAddUserEvent(
- accountLoader.get(auditEvent.getAddedBy()), auditEvent.getAddedOn(), member));
+ accountLoader.get(auditEvent.addedBy()), auditEvent.addedOn(), member));
if (!auditEvent.isActive()) {
auditEvents.add(
GroupAuditEventInfo.createRemoveUserEvent(
- accountLoader.get(auditEvent.getRemovedBy()), auditEvent.getRemovedOn(), member));
+ accountLoader.get(auditEvent.removedBy().orElse(null)),
+ auditEvent.removedOn(),
+ member));
}
}
- for (AccountGroupByIdAud auditEvent :
+ for (AccountGroupByIdAudit auditEvent :
groups.getSubgroupsAudit(allUsersRepo, group.getGroupUUID())) {
- AccountGroup.UUID includedGroupUUID = auditEvent.getIncludeUUID();
+ AccountGroup.UUID includedGroupUUID = auditEvent.includeUuid();
Optional<InternalGroup> includedGroup = groupCache.get(includedGroupUUID);
GroupInfo member;
if (includedGroup.isPresent()) {
@@ -121,12 +123,14 @@
auditEvents.add(
GroupAuditEventInfo.createAddGroupEvent(
- accountLoader.get(auditEvent.getAddedBy()), auditEvent.getKey().addedOn(), member));
+ accountLoader.get(auditEvent.addedBy()), auditEvent.addedOn(), member));
if (!auditEvent.isActive()) {
auditEvents.add(
GroupAuditEventInfo.createRemoveGroupEvent(
- accountLoader.get(auditEvent.getRemovedBy()), auditEvent.getRemovedOn(), member));
+ accountLoader.get(auditEvent.removedBy().orElse(null)),
+ auditEvent.removedOn(),
+ member));
}
}
}
diff --git a/java/com/google/gerrit/server/restapi/project/ListBranches.java b/java/com/google/gerrit/server/restapi/project/ListBranches.java
index a0d2528..e26317d 100644
--- a/java/com/google/gerrit/server/restapi/project/ListBranches.java
+++ b/java/com/google/gerrit/server/restapi/project/ListBranches.java
@@ -127,7 +127,7 @@
}
@Override
- public List<BranchInfo> apply(ProjectResource rsrc)
+ public ImmutableList<BranchInfo> apply(ProjectResource rsrc)
throws RestApiException, IOException, PermissionBackendException {
rsrc.getProjectState().checkStatePermitsRead();
return new RefFilter<BranchInfo>(Constants.R_HEADS)
@@ -278,7 +278,8 @@
info.actions.put(d.getId(), new ActionInfo(d));
}
- List<WebLinkInfo> links = webLinks.getBranchLinks(projectState.getName(), ref.getName());
+ ImmutableList<WebLinkInfo> links =
+ webLinks.getBranchLinks(projectState.getName(), ref.getName());
info.webLinks = links.isEmpty() ? null : links;
return info;
}
diff --git a/java/com/google/gerrit/server/restapi/project/ListProjects.java b/java/com/google/gerrit/server/restapi/project/ListProjects.java
index 4f3dbb7..f12e4d8 100644
--- a/java/com/google/gerrit/server/restapi/project/ListProjects.java
+++ b/java/com/google/gerrit/server/restapi/project/ListProjects.java
@@ -505,7 +505,7 @@
continue;
}
- List<WebLinkInfo> links = webLinks.getProjectLinks(projectName.get());
+ ImmutableList<WebLinkInfo> links = webLinks.getProjectLinks(projectName.get());
info.webLinks = links.isEmpty() ? null : links;
if (stdout == null || format.isJson()) {
diff --git a/java/com/google/gerrit/server/restapi/project/ListTags.java b/java/com/google/gerrit/server/restapi/project/ListTags.java
index 98c8c61..6b38a2e 100644
--- a/java/com/google/gerrit/server/restapi/project/ListTags.java
+++ b/java/com/google/gerrit/server/restapi/project/ListTags.java
@@ -116,7 +116,7 @@
}
@Override
- public List<TagInfo> apply(ProjectResource resource)
+ public ImmutableList<TagInfo> apply(ProjectResource resource)
throws IOException, ResourceNotFoundException, RestApiException, PermissionBackendException {
resource.getProjectState().checkStatePermitsRead();
@@ -182,7 +182,7 @@
perm.testOrFalse(RefPermission.DELETE) && projectState.statePermitsWrite() ? true : null;
}
- List<WebLinkInfo> webLinks = links.getTagLinks(projectState.getName(), ref.getName());
+ ImmutableList<WebLinkInfo> webLinks = links.getTagLinks(projectState.getName(), ref.getName());
if (object instanceof RevTag) {
// Annotated or signed tag
RevTag tag = (RevTag) object;
diff --git a/java/com/google/gerrit/server/rules/DefaultSubmitRule.java b/java/com/google/gerrit/server/rules/DefaultSubmitRule.java
index 2be6c19..8401c1d 100644
--- a/java/com/google/gerrit/server/rules/DefaultSubmitRule.java
+++ b/java/com/google/gerrit/server/rules/DefaultSubmitRule.java
@@ -125,7 +125,7 @@
private static List<PatchSetApproval> getApprovalsForLabel(
List<PatchSetApproval> approvals, LabelType t) {
return approvals.stream()
- .filter(input -> input.getLabel().equals(t.getLabelId().get()))
+ .filter(input -> input.label().equals(t.getLabelId().get()))
.collect(toImmutableList());
}
}
diff --git a/java/com/google/gerrit/server/rules/IgnoreSelfApprovalRule.java b/java/com/google/gerrit/server/rules/IgnoreSelfApprovalRule.java
index 592c269c..4695800 100644
--- a/java/com/google/gerrit/server/rules/IgnoreSelfApprovalRule.java
+++ b/java/com/google/gerrit/server/rules/IgnoreSelfApprovalRule.java
@@ -79,7 +79,7 @@
Account.Id uploader;
try {
- uploader = cd.currentPatchSet().getUploader();
+ uploader = cd.currentPatchSet().uploader();
} catch (StorageException e) {
logger.atWarning().withCause(e).log(E_UNABLE_TO_FETCH_UPLOADER);
return singletonRuleError(E_UNABLE_TO_FETCH_UPLOADER);
@@ -155,7 +155,7 @@
static Collection<PatchSetApproval> filterOutPositiveApprovalsOfUser(
Collection<PatchSetApproval> approvals, Account.Id user) {
return approvals.stream()
- .filter(input -> input.getValue() < 0 || !input.getAccountId().equals(user))
+ .filter(input -> input.value() < 0 || !input.accountId().equals(user))
.collect(toImmutableList());
}
@@ -163,7 +163,7 @@
static Collection<PatchSetApproval> filterApprovalsByLabel(
Collection<PatchSetApproval> approvals, LabelType t) {
return approvals.stream()
- .filter(input -> input.getLabelId().get().equals(t.getLabelId().get()))
+ .filter(input -> input.labelId().get().equals(t.getLabelId().get()))
.collect(toImmutableList());
}
}
diff --git a/java/com/google/gerrit/server/rules/StoredValues.java b/java/com/google/gerrit/server/rules/StoredValues.java
index 2eb6d86..40f0ff5 100644
--- a/java/com/google/gerrit/server/rules/StoredValues.java
+++ b/java/com/google/gerrit/server/rules/StoredValues.java
@@ -96,7 +96,7 @@
Change change = getChange(engine);
Project.NameKey project = change.getProject();
Whitespace ws = Whitespace.IGNORE_NONE;
- PatchListKey plKey = PatchListKey.againstDefaultBase(ps.getCommitId(), ws);
+ PatchListKey plKey = PatchListKey.againstDefaultBase(ps.commitId(), ws);
PatchList patchList;
try {
patchList = plCache.get(plKey, project);
diff --git a/java/com/google/gerrit/server/schema/JdbcAccountPatchReviewStore.java b/java/com/google/gerrit/server/schema/JdbcAccountPatchReviewStore.java
index 4877eed..d7dbf58 100644
--- a/java/com/google/gerrit/server/schema/JdbcAccountPatchReviewStore.java
+++ b/java/com/google/gerrit/server/schema/JdbcAccountPatchReviewStore.java
@@ -27,6 +27,7 @@
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.lifecycle.LifecycleModule;
import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.change.AccountPatchReviewStore;
import com.google.gerrit.server.config.ConfigUtil;
@@ -295,6 +296,18 @@
}
@Override
+ public void clearReviewed(Change.Id changeId) {
+ try (Connection con = ds.getConnection();
+ PreparedStatement stmt =
+ con.prepareStatement("DELETE FROM account_patch_reviews WHERE change_id = ?")) {
+ stmt.setInt(1, changeId.get());
+ stmt.executeUpdate();
+ } catch (SQLException e) {
+ throw convertError("delete", e);
+ }
+ }
+
+ @Override
public Optional<PatchSetWithReviewedFiles> findReviewed(PatchSet.Id psId, Account.Id accountId) {
try (Connection con = ds.getConnection();
PreparedStatement stmt =
diff --git a/java/com/google/gerrit/server/submit/CherryPick.java b/java/com/google/gerrit/server/submit/CherryPick.java
index 8ff3cc5..4d57591 100644
--- a/java/com/google/gerrit/server/submit/CherryPick.java
+++ b/java/com/google/gerrit/server/submit/CherryPick.java
@@ -162,7 +162,7 @@
ctx.getUpdate(psId),
psId,
newCommit,
- prevPs != null ? prevPs.getGroups() : ImmutableList.of(),
+ prevPs != null ? prevPs.groups() : ImmutableList.of(),
null,
null);
ctx.getChange().setCurrentPatchSet(patchSetInfo);
diff --git a/java/com/google/gerrit/server/submit/CommitMergeStatus.java b/java/com/google/gerrit/server/submit/CommitMergeStatus.java
index 6f21138e..2ca0ec5 100644
--- a/java/com/google/gerrit/server/submit/CommitMergeStatus.java
+++ b/java/com/google/gerrit/server/submit/CommitMergeStatus.java
@@ -103,24 +103,22 @@
commit, otherCommit, caller != null ? caller.getLoggableName() : "<user-not-available>");
} else if (changes.size() == 1) {
ChangeData cd = changes.get(0);
- if (cd.currentPatchSet().getCommitId().name().equals(otherCommit)) {
+ if (cd.currentPatchSet().commitId().name().equals(otherCommit)) {
return String.format(
"Commit %s depends on commit %s of change %d which cannot be merged.",
commit, otherCommit, cd.getId().get());
}
Optional<PatchSet> patchSet =
- cd.patchSets().stream()
- .filter(ps -> ps.getCommitId().name().equals(otherCommit))
- .findAny();
+ cd.patchSets().stream().filter(ps -> ps.commitId().name().equals(otherCommit)).findAny();
if (patchSet.isPresent()) {
return String.format(
"Commit %s depends on commit %s, which is outdated patch set %d of change %d."
+ " The latest patch set is %d.",
commit,
otherCommit,
- patchSet.get().getId().get(),
+ patchSet.get().id().get(),
cd.getId().get(),
- cd.currentPatchSet().getId().get());
+ cd.currentPatchSet().id().get());
}
// should not happen, fall-back to default message
return String.format(
diff --git a/java/com/google/gerrit/server/submit/LocalMergeSuperSetComputation.java b/java/com/google/gerrit/server/submit/LocalMergeSuperSetComputation.java
index 580db67..bb6a2e5 100644
--- a/java/com/google/gerrit/server/submit/LocalMergeSuperSetComputation.java
+++ b/java/com/google/gerrit/server/submit/LocalMergeSuperSetComputation.java
@@ -134,7 +134,7 @@
}
// Get the underlying git commit object
- RevCommit commit = or.rw.parseCommit(cd.currentPatchSet().getCommitId());
+ RevCommit commit = or.rw.parseCommit(cd.currentPatchSet().commitId());
// Always include the input, even if merged. This allows
// SubmitStrategyOp to correct the situation later, assuming it gets
diff --git a/java/com/google/gerrit/server/submit/MergeOp.java b/java/com/google/gerrit/server/submit/MergeOp.java
index b21dd5f..06c52c7 100644
--- a/java/com/google/gerrit/server/submit/MergeOp.java
+++ b/java/com/google/gerrit/server/submit/MergeOp.java
@@ -296,7 +296,7 @@
throw new IllegalStateException(
String.format(
"SubmitRuleEvaluator.evaluate for change %s returned empty list for %s in %s",
- cd.getId(), patchSet.getId(), cd.change().getProject().get()));
+ cd.getId(), patchSet.id(), cd.change().getProject().get()));
}
for (SubmitRecord record : results) {
@@ -318,7 +318,7 @@
throw new IllegalStateException(
String.format(
"Unexpected SubmitRecord status %s for %s in %s",
- record.status, patchSet.getId().getId(), cd.change().getProject().get()));
+ record.status, patchSet.id().getId(), cd.change().getProject().get()));
}
}
throw new IllegalStateException();
@@ -781,9 +781,9 @@
continue;
}
- ObjectId id = ps.getCommitId();
- if (!revisions.containsEntry(id, ps.getId())) {
- if (revisions.containsValue(ps.getId())) {
+ ObjectId id = ps.commitId();
+ if (!revisions.containsEntry(id, ps.id())) {
+ if (revisions.containsValue(ps.id())) {
// TODO This is actually an error, the patch set ref exists but points to a revision that
// is different from the revision that we have stored for the patch set in the change
// meta data.
@@ -792,9 +792,9 @@
"Revision "
+ id.name()
+ " of patch set "
- + ps.getPatchSetId()
+ + ps.number()
+ " does not match the revision of the patch set ref "
- + ps.getId().toRefName());
+ + ps.id().toRefName());
continue;
}
@@ -805,9 +805,9 @@
commitStatus.logProblem(
changeId,
"Patch set ref "
- + ps.getId().toRefName()
+ + ps.id().toRefName()
+ " not found. Expected patch set ref of "
- + ps.getPatchSetId()
+ + ps.number()
+ " to point to revision "
+ id.name());
continue;
@@ -822,13 +822,12 @@
}
commit.setNotes(notes);
- commit.setPatchsetId(ps.getId());
+ commit.setPatchsetId(ps.id());
commitStatus.put(commit);
MergeValidators mergeValidators = mergeValidatorsFactory.create();
try {
- mergeValidators.validatePreMerge(
- or.repo, commit, or.project, destBranch, ps.getId(), caller);
+ mergeValidators.validatePreMerge(or.repo, commit, or.project, destBranch, ps.id(), caller);
} catch (MergeValidationException mve) {
commitStatus.problem(changeId, mve.getMessage());
continue;
diff --git a/java/com/google/gerrit/server/submit/RebaseSubmitStrategy.java b/java/com/google/gerrit/server/submit/RebaseSubmitStrategy.java
index 342ae69..b8fb067 100644
--- a/java/com/google/gerrit/server/submit/RebaseSubmitStrategy.java
+++ b/java/com/google/gerrit/server/submit/RebaseSubmitStrategy.java
@@ -234,7 +234,7 @@
ctx.getUpdate(newPatchSetId),
newPatchSetId,
newCommit,
- prevPs != null ? prevPs.getGroups() : ImmutableList.of(),
+ prevPs != null ? prevPs.groups() : ImmutableList.of(),
null,
null);
}
diff --git a/java/com/google/gerrit/server/submit/SubmitStrategyOp.java b/java/com/google/gerrit/server/submit/SubmitStrategyOp.java
index 02dfd09..b1c7dd9 100644
--- a/java/com/google/gerrit/server/submit/SubmitStrategyOp.java
+++ b/java/com/google/gerrit/server/submit/SubmitStrategyOp.java
@@ -20,7 +20,6 @@
import static java.util.Comparator.comparing;
import static java.util.Objects.requireNonNull;
-import com.google.common.base.Function;
import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.data.SubmitRecord;
import com.google.gerrit.exceptions.StorageException;
@@ -252,7 +251,7 @@
args.psUtil.get(ctx.getNotes(), oldPsId),
() -> String.format("missing old patch set %s", oldPsId));
} else {
- PatchSet.Id n = newPatchSet.getId();
+ PatchSet.Id n = newPatchSet.id();
checkState(
!n.equals(oldPsId) && n.equals(newPsId),
"current patch was %s and is now %s, but updateChangeImpl returned"
@@ -312,7 +311,7 @@
// a patch set ref. Fix up the database. Note that this uses the current
// user as the uploader, which is as good a guess as any.
List<String> groups =
- prevPs != null ? prevPs.getGroups() : GroupCollector.getDefaultGroups(alreadyMergedCommit);
+ prevPs != null ? prevPs.groups() : GroupCollector.getDefaultGroups(alreadyMergedCommit);
return args.psUtil.insert(
ctx.getRevWalk(), ctx.getUpdate(psId), psId, alreadyMergedCommit, groups, null, null);
}
@@ -334,7 +333,7 @@
// approvals as well.
if (!newPsId.equals(oldPsId)) {
saveApprovals(normalized, newPsUpdate, true);
- submitter = convertPatchSet(newPsId).apply(submitter);
+ submitter = submitter.copyWithPatchSet(newPsId);
}
}
@@ -345,12 +344,13 @@
for (PatchSetApproval psa :
args.approvalsUtil.byPatchSet(
ctx.getNotes(), psId, ctx.getRevWalk(), ctx.getRepoView().getConfig())) {
- byKey.put(psa.getKey(), psa);
+ byKey.put(psa.key(), psa);
}
submitter =
- ApprovalsUtil.newApproval(psId, ctx.getUser(), LabelId.legacySubmit(), 1, ctx.getWhen());
- byKey.put(submitter.getKey(), submitter);
+ ApprovalsUtil.newApproval(psId, ctx.getUser(), LabelId.legacySubmit(), 1, ctx.getWhen())
+ .build();
+ byKey.put(submitter.key(), submitter);
// Flatten out existing approvals for this patch set based upon the current
// permissions. Once the change is closed the approvals are not updated at
@@ -359,7 +359,7 @@
// permissions get modified in the future, historical records stay accurate.
LabelNormalizer.Result normalized =
args.labelNormalizer.normalize(ctx.getNotes(), byKey.values());
- update.putApproval(submitter.getLabel(), submitter.getValue());
+ update.putApproval(submitter.label(), submitter.value());
saveApprovals(normalized, update, false);
return normalized;
}
@@ -367,10 +367,10 @@
private void saveApprovals(
LabelNormalizer.Result normalized, ChangeUpdate update, boolean includeUnchanged) {
for (PatchSetApproval psa : normalized.updated()) {
- update.putApprovalFor(psa.getAccountId(), psa.getLabel(), psa.getValue());
+ update.putApprovalFor(psa.accountId(), psa.label(), psa.value());
}
for (PatchSetApproval psa : normalized.deleted()) {
- update.removeApprovalFor(psa.getAccountId(), psa.getLabel());
+ update.removeApprovalFor(psa.accountId(), psa.label());
}
// TODO(dborowitz): Don't use a label in NoteDb; just check when status
@@ -378,25 +378,15 @@
for (PatchSetApproval psa : normalized.unchanged()) {
if (includeUnchanged || psa.isLegacySubmit()) {
logger.atFine().log("Adding submit label %s", psa);
- update.putApprovalFor(psa.getAccountId(), psa.getLabel(), psa.getValue());
+ update.putApprovalFor(psa.accountId(), psa.label(), psa.value());
}
}
}
- private static Function<PatchSetApproval, PatchSetApproval> convertPatchSet(
- final PatchSet.Id psId) {
- return psa -> {
- if (psa.getPatchSetId().equals(psId)) {
- return psa;
- }
- return new PatchSetApproval(psId, psa);
- };
- }
-
private String getByAccountName() {
requireNonNull(submitter, "getByAccountName called before submitter populated");
Optional<Account> account =
- args.accountCache.get(submitter.getAccountId()).map(AccountState::getAccount);
+ args.accountCache.get(submitter.accountId()).map(AccountState::getAccount);
if (account.isPresent() && account.get().getFullName() != null) {
return " by " + account.get().getFullName();
}
@@ -499,7 +489,7 @@
// have failed fast in one of the other steps.
try {
args.mergedSenderFactory
- .create(ctx.getProject(), getId(), submitter.getAccountId(), ctx.getNotify(getId()))
+ .create(ctx.getProject(), getId(), submitter.accountId(), ctx.getNotify(getId()))
.sendAsync();
} catch (Exception e) {
logger.atSevere().withCause(e).log("Cannot email merged notification for %s", getId());
@@ -508,7 +498,7 @@
args.changeMerged.fire(
updatedChange,
mergedPatchSet,
- args.accountCache.get(submitter.getAccountId()).orElse(null),
+ args.accountCache.get(submitter.accountId()).orElse(null),
args.mergeTip.getCurrentTip().name(),
ctx.getWhen());
}
diff --git a/java/com/google/gerrit/server/submit/SubmoduleOp.java b/java/com/google/gerrit/server/submit/SubmoduleOp.java
index 7fc47dc..8ad063a 100644
--- a/java/com/google/gerrit/server/submit/SubmoduleOp.java
+++ b/java/com/google/gerrit/server/submit/SubmoduleOp.java
@@ -646,7 +646,7 @@
int newSize = msgbuf.length() + bullet.length() + message.length();
if (++numMessages > maxCommitMessages
|| newSize > maxCombinedCommitMessageSize
- || iter.hasNext() && (newSize + ellipsis.length()) > maxCombinedCommitMessageSize) {
+ || (iter.hasNext() && (newSize + ellipsis.length()) > maxCombinedCommitMessageSize)) {
msgbuf.append(ellipsis);
break;
}
diff --git a/java/com/google/gerrit/server/update/BatchUpdate.java b/java/com/google/gerrit/server/update/BatchUpdate.java
index 1fc75c4..2a958af 100644
--- a/java/com/google/gerrit/server/update/BatchUpdate.java
+++ b/java/com/google/gerrit/server/update/BatchUpdate.java
@@ -52,7 +52,7 @@
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.notedb.NoteDbUpdateManager;
-import com.google.gerrit.server.notedb.NoteDbUpdateManager.TooManyUpdatesException;
+import com.google.gerrit.server.notedb.TooManyUpdatesException;
import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.project.NoSuchProjectException;
diff --git a/java/com/google/gerrit/server/update/RetryHelper.java b/java/com/google/gerrit/server/update/RetryHelper.java
index 4c7acfc..3c14d25 100644
--- a/java/com/google/gerrit/server/update/RetryHelper.java
+++ b/java/com/google/gerrit/server/update/RetryHelper.java
@@ -28,7 +28,6 @@
import com.github.rholder.retry.WaitStrategy;
import com.google.auto.value.AutoValue;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Predicate;
import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
import com.google.common.flogger.FluentLogger;
@@ -47,6 +46,7 @@
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
+import java.util.function.Predicate;
import org.eclipse.jgit.lib.Config;
@Singleton
@@ -294,7 +294,7 @@
private <O> RetryerBuilder<O> createRetryerBuilder(
ActionType actionType, Options opts, Predicate<Throwable> exceptionPredicate) {
RetryerBuilder<O> retryerBuilder =
- RetryerBuilder.<O>newBuilder().retryIfException(exceptionPredicate);
+ RetryerBuilder.<O>newBuilder().retryIfException(exceptionPredicate::test);
if (opts.listener() != null) {
retryerBuilder.withRetryListener(opts.listener());
}
diff --git a/java/com/google/gerrit/server/util/IdGenerator.java b/java/com/google/gerrit/server/util/IdGenerator.java
index 276df06..d4c2dc4 100644
--- a/java/com/google/gerrit/server/util/IdGenerator.java
+++ b/java/com/google/gerrit/server/util/IdGenerator.java
@@ -45,8 +45,8 @@
public static int mix(int salt, int in) {
short v0 = hi16(in);
short v1 = lo16(in);
- v0 += ((v1 << 2) + 0 ^ v1) + (salt ^ (v1 >>> 3)) + 1;
- v1 += ((v0 << 2) + 2 ^ v0) + (salt ^ (v0 >>> 3)) + 3;
+ v0 += (short) (((v1 << 2) + 0 ^ v1) + (salt ^ (v1 >>> 3)) + 1);
+ v1 += (short) (((v0 << 2) + 2 ^ v0) + (salt ^ (v0 >>> 3)) + 3);
return result(v0, v1);
}
@@ -54,8 +54,8 @@
static int unmix(int in) {
short v0 = hi16(in);
short v1 = lo16(in);
- v1 -= ((v0 << 2) + 2 ^ v0) + (salt ^ (v0 >>> 3)) + 3;
- v0 -= ((v1 << 2) + 0 ^ v1) + (salt ^ (v1 >>> 3)) + 1;
+ v1 -= (short) (((v0 << 2) + 2 ^ v0) + (salt ^ (v0 >>> 3)) + 3);
+ v0 -= (short) (((v1 << 2) + 0 ^ v1) + (salt ^ (v1 >>> 3)) + 1);
return result(v0, v1);
}
diff --git a/java/com/google/gerrit/sshd/commands/PatchSetParser.java b/java/com/google/gerrit/sshd/commands/PatchSetParser.java
index e8ff697..377e1ac 100644
--- a/java/com/google/gerrit/sshd/commands/PatchSetParser.java
+++ b/java/com/google/gerrit/sshd/commands/PatchSetParser.java
@@ -76,7 +76,7 @@
continue;
}
for (PatchSet ps : cd.patchSets()) {
- if (ObjectIds.matchesAbbreviation(ps.getCommitId(), token)) {
+ if (ObjectIds.matchesAbbreviation(ps.commitId(), token)) {
matches.add(ps);
}
}
diff --git a/java/com/google/gerrit/sshd/commands/ReviewCommand.java b/java/com/google/gerrit/sshd/commands/ReviewCommand.java
index e16ff49..2c54e4a 100644
--- a/java/com/google/gerrit/sshd/commands/ReviewCommand.java
+++ b/java/com/google/gerrit/sshd/commands/ReviewCommand.java
@@ -227,11 +227,11 @@
writeError("error", e.getMessage() + "\n");
} catch (NoSuchChangeException e) {
ok = false;
- writeError("error", "no such change " + patchSet.getId().changeId().get());
+ writeError("error", "no such change " + patchSet.id().changeId().get());
} catch (Exception e) {
ok = false;
- writeError("fatal", "internal server error while reviewing " + patchSet.getId() + "\n");
- logger.atSevere().withCause(e).log("internal error while reviewing %s", patchSet.getId());
+ writeError("fatal", "internal server error while reviewing " + patchSet.id() + "\n");
+ logger.atSevere().withCause(e).log("internal error while reviewing %s", patchSet.id());
}
}
@@ -242,8 +242,8 @@
private void applyReview(PatchSet patchSet, ReviewInput review) throws RestApiException {
gApi.changes()
- .id(patchSet.getId().changeId().get())
- .revision(patchSet.getCommitId().name())
+ .id(patchSet.id().changeId().get())
+ .revision(patchSet.commitId().name())
.review(review);
}
@@ -310,11 +310,11 @@
}
private ChangeApi changeApi(PatchSet patchSet) throws RestApiException {
- return gApi.changes().id(patchSet.getId().changeId().get());
+ return gApi.changes().id(patchSet.id().changeId().get());
}
private RevisionApi revisionApi(PatchSet patchSet) throws RestApiException {
- return changeApi(patchSet).revision(patchSet.getCommitId().name());
+ return changeApi(patchSet).revision(patchSet.commitId().name());
}
@Override
diff --git a/java/com/google/gerrit/sshd/commands/ShowConnections.java b/java/com/google/gerrit/sshd/commands/ShowConnections.java
index d579ef6..231bcf6 100644
--- a/java/com/google/gerrit/sshd/commands/ShowConnections.java
+++ b/java/com/google/gerrit/sshd/commands/ShowConnections.java
@@ -148,7 +148,7 @@
}
stdout.print("--\n");
- stdout.print("SSHD Backend: " + getBackend() + "\n");
+ stdout.print(String.format(" %d connections; SSHD Backend: %s\n", list.size(), getBackend()));
}
private String getBackend() {
diff --git a/java/com/google/gerrit/sshd/commands/StreamEvents.java b/java/com/google/gerrit/sshd/commands/StreamEvents.java
index 447f7ec..c680d30 100644
--- a/java/com/google/gerrit/sshd/commands/StreamEvents.java
+++ b/java/com/google/gerrit/sshd/commands/StreamEvents.java
@@ -87,29 +87,6 @@
EventTypes.register(DroppedOutputEvent.TYPE, DroppedOutputEvent.class);
}
- private final CancelableRunnable writer =
- new CancelableRunnable() {
- @Override
- public void run() {
- writeEvents();
- }
-
- @Override
- public void cancel() {
- onExit(0);
- }
-
- @Override
- public String toString() {
- StringBuilder b = new StringBuilder();
- b.append("Stream Events");
- if (currentUser.getUserName().isPresent()) {
- b.append(" (").append(currentUser.getUserName().get()).append(")");
- }
- return b.toString();
- }
- };
-
/** True if {@link DroppedOutputEvent} needs to be sent. */
private volatile boolean dropped;
@@ -127,8 +104,6 @@
*/
private Future<?> task;
- private PrintWriter stdout;
-
@Override
public void start(Environment env) throws IOException {
try {
@@ -144,7 +119,30 @@
return;
}
- stdout = toPrintWriter(out);
+ PrintWriter stdout = toPrintWriter(out);
+ CancelableRunnable writer =
+ new CancelableRunnable() {
+ @Override
+ public void run() {
+ writeEvents(this, stdout);
+ }
+
+ @Override
+ public void cancel() {
+ onExit(0);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder b = new StringBuilder();
+ b.append("Stream Events");
+ if (currentUser.getUserName().isPresent()) {
+ b.append(" (").append(currentUser.getUserName().get()).append(")");
+ }
+ return b.toString();
+ }
+ };
+
eventListenerRegistration =
eventListeners.add(
"gerrit",
@@ -152,7 +150,7 @@
@Override
public void onEvent(Event event) {
if (subscribedToEvents.isEmpty() || subscribedToEvents.contains(event.getType())) {
- offer(event);
+ offer(writer, event);
}
}
@@ -199,7 +197,7 @@
}
}
- private void offer(Event event) {
+ private void offer(CancelableRunnable writer, Event event) {
synchronized (taskLock) {
if (!queue.offer(event)) {
dropped = true;
@@ -221,7 +219,7 @@
}
}
- private void writeEvents() {
+ private void writeEvents(CancelableRunnable writer, PrintWriter stdout) {
int processed = 0;
while (processed < BATCH_SIZE) {
@@ -231,13 +229,13 @@
// accepting output. Either way terminate this instance.
//
removeEventListenerRegistration();
- flush();
+ flush(stdout);
onExit(0);
return;
}
if (dropped) {
- write(new DroppedOutputEvent());
+ write(stdout, new DroppedOutputEvent());
dropped = false;
}
@@ -246,11 +244,11 @@
break;
}
- write(event);
+ write(stdout, event);
processed++;
}
- flush();
+ flush(stdout);
if (BATCH_SIZE <= processed) {
// We processed the limit, but more might remain in the queue.
@@ -263,7 +261,7 @@
}
}
- private void write(Object message) {
+ private void write(PrintWriter stdout, Object message) {
String msg = null;
try {
msg = gson.toJson(message) + "\n";
@@ -277,7 +275,7 @@
}
}
- private void flush() {
+ private void flush(PrintWriter stdout) {
synchronized (stdout) {
stdout.flush();
}
diff --git a/java/com/google/gerrit/sshd/commands/UploadArchive.java b/java/com/google/gerrit/sshd/commands/UploadArchive.java
index 24f82a7..a58e472 100644
--- a/java/com/google/gerrit/sshd/commands/UploadArchive.java
+++ b/java/com/google/gerrit/sshd/commands/UploadArchive.java
@@ -139,7 +139,7 @@
PacketLineIn packetIn = new PacketLineIn(in);
for (; ; ) {
String s = packetIn.readString();
- if (s == PacketLineIn.END) {
+ if (isPacketLineEnd(s)) {
break;
}
if (!s.startsWith(argCmd)) {
@@ -163,6 +163,12 @@
}
}
+ // JGit API depends on reference equality with sentinel.
+ @SuppressWarnings({"ReferenceEquality", "StringEquality"})
+ private static boolean isPacketLineEnd(String s) {
+ return s == PacketLineIn.END;
+ }
+
@Override
protected void runImpl() throws IOException, PermissionBackendException, Failure {
PacketLineOut packetOut = new PacketLineOut(out);
diff --git a/java/com/google/gerrit/testing/AssertableExecutorService.java b/java/com/google/gerrit/testing/AssertableExecutorService.java
new file mode 100644
index 0000000..18ac2e9
--- /dev/null
+++ b/java/com/google/gerrit/testing/AssertableExecutorService.java
@@ -0,0 +1,65 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.testing;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import com.google.common.util.concurrent.ForwardingExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Forwards all calls to a direct executor making it so that the submitted {@link Runnable}s run
+ * synchronously. Holds a count of the number of tasks that were executed.
+ */
+public class AssertableExecutorService extends ForwardingExecutorService {
+
+ private final ExecutorService delegate = MoreExecutors.newDirectExecutorService();
+ private final AtomicInteger numInteractions = new AtomicInteger();
+
+ @Override
+ protected ExecutorService delegate() {
+ return delegate;
+ }
+
+ @Override
+ public <T> Future<T> submit(Callable<T> task) {
+ numInteractions.incrementAndGet();
+ return super.submit(task);
+ }
+
+ @Override
+ public Future<?> submit(Runnable task) {
+ numInteractions.incrementAndGet();
+ return super.submit(task);
+ }
+
+ @Override
+ public <T> Future<T> submit(Runnable task, T result) {
+ numInteractions.incrementAndGet();
+ return super.submit(task, result);
+ }
+
+ /** Asserts and resets the number of executions this executor observed. */
+ public void assertInteractions(int expectedNumInteractions) {
+ assertWithMessage("expectedRunnablesSubmittedOnExecutor")
+ .that(numInteractions.get())
+ .isEqualTo(expectedNumInteractions);
+ numInteractions.set(0);
+ }
+}
diff --git a/java/com/google/gerrit/testing/BUILD b/java/com/google/gerrit/testing/BUILD
index ec5076e..27065aa 100644
--- a/java/com/google/gerrit/testing/BUILD
+++ b/java/com/google/gerrit/testing/BUILD
@@ -1,7 +1,10 @@
java_library(
name = "gerrit-test-util",
testonly = True,
- srcs = glob(["**/*.java"]),
+ srcs = glob(
+ ["**/*.java"],
+ exclude = ["AssertableExecutorService.java"],
+ ),
visibility = ["//visibility:public"],
exports = [
"//lib/easymock",
@@ -12,6 +15,7 @@
"//lib/powermock:powermock-module-junit4-common",
],
deps = [
+ "//java/com/google/gerrit/acceptance/testsuite/project",
"//java/com/google/gerrit/common:annotations",
"//java/com/google/gerrit/common:server",
"//java/com/google/gerrit/exceptions",
@@ -47,3 +51,15 @@
"//lib/truth",
],
)
+
+java_library(
+ # This can't be part of gerrit-test-util because of https://github.com/google/guava/issues/2837
+ name = "assertable-executor",
+ testonly = True,
+ srcs = ["AssertableExecutorService.java"],
+ visibility = ["//visibility:public"],
+ deps = [
+ "//lib:guava",
+ "//lib/truth",
+ ],
+)
diff --git a/java/com/google/gerrit/testing/GerritJUnit.java b/java/com/google/gerrit/testing/GerritJUnit.java
new file mode 100644
index 0000000..0771c39
--- /dev/null
+++ b/java/com/google/gerrit/testing/GerritJUnit.java
@@ -0,0 +1,67 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.testing;
+
+/** Static JUnit utility methods. */
+public class GerritJUnit {
+ /**
+ * Assert that an exception is thrown by a block of code.
+ *
+ * <p>This method is source-compatible with <a
+ * href="https://junit.org/junit4/javadoc/latest/org/junit/Assert.html#assertThrows(java.lang.Class,%20org.junit.function.ThrowingRunnable)">JUnit
+ * 4.13 beta</a>.
+ *
+ * <p>This construction is recommended by the Truth team for use in conjunction with asserting
+ * over a {@code ThrowableSubject} on the return type:
+ *
+ * <pre>
+ * MyException e = assertThrows(MyException.class, () -> doSomething(foo));
+ * assertThat(e).isInstanceOf(MySubException.class);
+ * assertThat(e).hasMessageThat().contains("sub-exception occurred");
+ * </pre>
+ *
+ * @param throwableClass expected exception type.
+ * @param runnable runnable containing arbitrary code.
+ * @return exception that was thrown.
+ */
+ public static <T extends Throwable> T assertThrows(
+ Class<T> throwableClass, ThrowingRunnable runnable) {
+ try {
+ runnable.run();
+ } catch (Throwable t) {
+ if (!throwableClass.isInstance(t)) {
+ throw new AssertionError(
+ "expected "
+ + throwableClass.getName()
+ + " but "
+ + t.getClass().getName()
+ + " was thrown",
+ t);
+ }
+ @SuppressWarnings("unchecked")
+ T toReturn = (T) t;
+ return toReturn;
+ }
+ throw new AssertionError(
+ "expected " + throwableClass.getName() + " but no exception was thrown");
+ }
+
+ @FunctionalInterface
+ public interface ThrowingRunnable {
+ void run() throws Throwable;
+ }
+
+ private GerritJUnit() {}
+}
diff --git a/java/com/google/gerrit/testing/GerritServerTests.java b/java/com/google/gerrit/testing/GerritServerTests.java
index 9a922d6..ad985b6 100644
--- a/java/com/google/gerrit/testing/GerritServerTests.java
+++ b/java/com/google/gerrit/testing/GerritServerTests.java
@@ -21,7 +21,7 @@
import org.junit.runners.model.Statement;
@RunWith(ConfigSuite.class)
-public class GerritServerTests extends GerritBaseTests {
+public class GerritServerTests {
@ConfigSuite.Parameter public Config config;
@ConfigSuite.Name private String configName;
diff --git a/java/com/google/gerrit/testing/GerritBaseTests.java b/java/com/google/gerrit/testing/GerritTestName.java
similarity index 65%
rename from java/com/google/gerrit/testing/GerritBaseTests.java
rename to java/com/google/gerrit/testing/GerritTestName.java
index d6a2261..d003289 100644
--- a/java/com/google/gerrit/testing/GerritBaseTests.java
+++ b/java/com/google/gerrit/testing/GerritTestName.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2015 The Android Open Source Project
+// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,18 +15,16 @@
package com.google.gerrit.testing;
import com.google.common.base.CharMatcher;
-import org.junit.Ignore;
-import org.junit.Rule;
-import org.junit.rules.ExpectedException;
import org.junit.rules.TestName;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
-@Ignore
-public abstract class GerritBaseTests {
- @Rule public ExpectedException exception = ExpectedException.none();
- @Rule public final TestName testName = new TestName();
+public class GerritTestName implements TestRule {
+ private final TestName delegate = new TestName();
- protected String getSanitizedMethodName() {
- String name = testName.getMethodName().toLowerCase();
+ public String getSanitizedMethodName() {
+ String name = delegate.getMethodName().toLowerCase();
name =
CharMatcher.inRange('a', 'z')
.or(CharMatcher.inRange('A', 'Z'))
@@ -36,4 +34,9 @@
name = CharMatcher.is('_').trimTrailingFrom(name);
return name;
}
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ return delegate.apply(base, description);
+ }
}
diff --git a/java/com/google/gerrit/testing/InMemoryModule.java b/java/com/google/gerrit/testing/InMemoryModule.java
index c8cea6f..5f1826b 100644
--- a/java/com/google/gerrit/testing/InMemoryModule.java
+++ b/java/com/google/gerrit/testing/InMemoryModule.java
@@ -20,6 +20,8 @@
import com.google.common.base.Strings;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperationsImpl;
import com.google.gerrit.extensions.client.AuthType;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.gerrit.extensions.systemstatus.ServerInformation;
@@ -174,8 +176,8 @@
bindScope(RequestScoped.class, PerThreadRequestScope.REQUEST);
- // TODO(dborowitz): Use Jimfs. The biggest blocker is that JGit does not support Path-based
- // Configs, only FileBasedConfig.
+ // It would be nice to use Jimfs for the SitePath, but the biggest blocker is that JGit does not
+ // support Path-based Configs, only FileBasedConfig.
bind(Path.class).annotatedWith(SitePath.class).toInstance(Paths.get("."));
bind(Config.class).annotatedWith(GerritServerConfig.class).toInstance(cfg);
bind(GerritOptions.class).toInstance(new GerritOptions(false, false, false));
@@ -223,28 +225,19 @@
bind(AllChangesIndexer.class).toProvider(Providers.of(null));
bind(AllGroupsIndexer.class).toProvider(Providers.of(null));
- IndexType indexType = null;
- try {
- indexType = cfg.getEnum("index", null, "type", IndexType.LUCENE);
- } catch (IllegalArgumentException e) {
- // Custom index type, caller must provide their own module.
- }
- if (indexType != null) {
- switch (indexType) {
- case LUCENE:
- install(luceneIndexModule());
- break;
- case ELASTICSEARCH:
- install(elasticIndexModule());
- break;
- default:
- throw new ProvisionException("index type unsupported in tests: " + indexType);
- }
+ IndexType indexType = new IndexType(cfg.getString("index", null, "type"));
+ // For custom index types, callers must provide their own module.
+ if (indexType.isLucene()) {
+ install(luceneIndexModule());
+ } else if (indexType.isElasticsearch()) {
+ install(elasticIndexModule());
}
bind(ServerInformationImpl.class);
bind(ServerInformation.class).to(ServerInformationImpl.class);
install(new RestApiModule());
install(new DefaultProjectNameLockManager.Module());
+
+ bind(ProjectOperations.class).to(ProjectOperationsImpl.class);
}
/** Copy of SchemaModule with a slightly different server ID provider. */
diff --git a/java/com/google/gerrit/testing/TestChanges.java b/java/com/google/gerrit/testing/TestChanges.java
index d41877d..3c2d1f7 100644
--- a/java/com/google/gerrit/testing/TestChanges.java
+++ b/java/com/google/gerrit/testing/TestChanges.java
@@ -68,10 +68,12 @@
}
public static PatchSet newPatchSet(PatchSet.Id id, String revision, Account.Id userId) {
- PatchSet ps = new PatchSet(id, ObjectId.fromString(revision));
- ps.setUploader(userId);
- ps.setCreatedOn(TimeUtil.nowTs());
- return ps;
+ return PatchSet.builder()
+ .id(id)
+ .commitId(ObjectId.fromString(revision))
+ .uploader(userId)
+ .createdOn(TimeUtil.nowTs())
+ .build();
}
public static ChangeUpdate newUpdate(
@@ -104,8 +106,8 @@
// Change doesn't exist yet. NoteDb requires that there be a commit for the
// first patch set, so create one.
GitRepositoryManager repoManager = injector.getInstance(GitRepositoryManager.class);
- try (Repository repo = repoManager.openRepository(c.getProject())) {
- TestRepository<Repository> tr = new TestRepository<>(repo);
+ try (Repository repo = repoManager.openRepository(c.getProject());
+ TestRepository<Repository> tr = new TestRepository<>(repo)) {
PersonIdent ident =
user.asIdentifiedUser().newCommitterIdent(update.getWhen(), TimeZone.getDefault());
TestRepository<Repository>.CommitBuilder cb =
diff --git a/java/com/google/gerrit/truth/BUILD b/java/com/google/gerrit/truth/BUILD
index 6f958b1..4727da1 100644
--- a/java/com/google/gerrit/truth/BUILD
+++ b/java/com/google/gerrit/truth/BUILD
@@ -6,6 +6,7 @@
deps = [
"//java/com/google/gerrit/common:annotations",
"//lib:guava",
+ "//lib/jgit/org.eclipse.jgit:jgit",
"//lib/truth",
],
)
diff --git a/java/com/google/gerrit/truth/CacheStatsSubject.java b/java/com/google/gerrit/truth/CacheStatsSubject.java
index f1a9393..22c33c2 100644
--- a/java/com/google/gerrit/truth/CacheStatsSubject.java
+++ b/java/com/google/gerrit/truth/CacheStatsSubject.java
@@ -39,10 +39,12 @@
other.evictionCount());
}
+ private final CacheStats stats;
private CacheStats start = new CacheStats(0, 0, 0, 0, 0, 0);
private CacheStatsSubject(FailureMetadata failureMetadata, CacheStats stats) {
super(failureMetadata, stats);
+ this.stats = stats;
}
public CacheStatsSubject since(CacheStats start) {
@@ -52,11 +54,11 @@
public void hasHitCount(int expectedHitCount) {
isNotNull();
- check("hitCount()").that(actual().minus(start).hitCount()).isEqualTo(expectedHitCount);
+ check("hitCount()").that(stats.minus(start).hitCount()).isEqualTo(expectedHitCount);
}
public void hasMissCount(int expectedMissCount) {
isNotNull();
- check("missCount()").that(actual().minus(start).missCount()).isEqualTo(expectedMissCount);
+ check("missCount()").that(stats.minus(start).missCount()).isEqualTo(expectedMissCount);
}
}
diff --git a/java/com/google/gerrit/truth/ConfigSubject.java b/java/com/google/gerrit/truth/ConfigSubject.java
new file mode 100644
index 0000000..615719a
--- /dev/null
+++ b/java/com/google/gerrit/truth/ConfigSubject.java
@@ -0,0 +1,129 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.truth;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ImmutableListMultimap;
+import com.google.common.truth.BooleanSubject;
+import com.google.common.truth.FailureMetadata;
+import com.google.common.truth.IntegerSubject;
+import com.google.common.truth.IterableSubject;
+import com.google.common.truth.LongSubject;
+import com.google.common.truth.MultimapSubject;
+import com.google.common.truth.StringSubject;
+import com.google.common.truth.Subject;
+import com.google.gerrit.common.Nullable;
+import java.util.Arrays;
+import org.eclipse.jgit.lib.Config;
+
+public class ConfigSubject extends Subject<ConfigSubject, Config> {
+ public static ConfigSubject assertThat(Config config) {
+ return assertAbout(ConfigSubject::new).that(config);
+ }
+
+ private final Config config;
+
+ private ConfigSubject(FailureMetadata metadata, Config actual) {
+ super(metadata, actual);
+ this.config = actual;
+ }
+
+ public IterableSubject sections() {
+ isNotNull();
+ return check("getSections()").that(config.getSections());
+ }
+
+ public IterableSubject subsections(String section) {
+ requireNonNull(section);
+ isNotNull();
+ return check("getSubsections(%s)", section).that(config.getSubsections(section));
+ }
+
+ public MultimapSubject sectionValues(String section) {
+ requireNonNull(section);
+ return sectionValuesImpl(section, null);
+ }
+
+ public MultimapSubject subsectionValues(String section, String subsection) {
+ requireNonNull(section);
+ requireNonNull(subsection);
+ return sectionValuesImpl(section, subsection);
+ }
+
+ private MultimapSubject sectionValuesImpl(String section, @Nullable String subsection) {
+ isNotNull();
+ ImmutableListMultimap.Builder<String, String> b = ImmutableListMultimap.builder();
+ config
+ .getNames(section, subsection, true)
+ .forEach(
+ n ->
+ Arrays.stream(config.getStringList(section, subsection, n))
+ .forEach(v -> b.put(n, v)));
+ return check("getSection(%s, %s)", section, subsection).that(b.build());
+ }
+
+ public void isEmpty() {
+ sections().isEmpty();
+ }
+
+ public StringSubject text() {
+ isNotNull();
+ return check("toText()").that(config.toText());
+ }
+
+ public IterableSubject stringValues(String section, @Nullable String subsection, String name) {
+ requireNonNull(section);
+ requireNonNull(name);
+ isNotNull();
+ return check("getStringList(%s, %s, %s)", section, subsection, name)
+ .that(Arrays.asList(config.getStringList(section, subsection, name)));
+ }
+
+ public StringSubject stringValue(String section, @Nullable String subsection, String name) {
+ requireNonNull(section);
+ requireNonNull(name);
+ isNotNull();
+ return check("getString(%s, %s, %s)", section, subsection, name)
+ .that(config.getString(section, subsection, name));
+ }
+
+ public IntegerSubject intValue(
+ String section, @Nullable String subsection, String name, int defaultValue) {
+ requireNonNull(section);
+ requireNonNull(name);
+ isNotNull();
+ return check("getInt(%s, %s, %s, %s)", section, subsection, name, defaultValue)
+ .that(config.getInt(section, subsection, name, defaultValue));
+ }
+
+ public LongSubject longValue(String section, String subsection, String name, long defaultValue) {
+ requireNonNull(section);
+ requireNonNull(name);
+ isNotNull();
+ return check("getLong(%s, %s, %s, %s)", section, subsection, name, defaultValue)
+ .that(config.getLong(section, subsection, name, defaultValue));
+ }
+
+ public BooleanSubject booleanValue(
+ String section, String subsection, String name, boolean defaultValue) {
+ requireNonNull(section);
+ requireNonNull(name);
+ isNotNull();
+ return check("getBoolean(%s, %s, %s, %s)", section, subsection, name, defaultValue)
+ .that(config.getBoolean(section, subsection, name, defaultValue));
+ }
+}
diff --git a/java/com/google/gerrit/truth/ListSubject.java b/java/com/google/gerrit/truth/ListSubject.java
index d17e500..0da16f8 100644
--- a/java/com/google/gerrit/truth/ListSubject.java
+++ b/java/com/google/gerrit/truth/ListSubject.java
@@ -29,6 +29,7 @@
public class ListSubject<S extends Subject<S, E>, E> extends IterableSubject {
+ private final List<E> list;
private final BiFunction<StandardSubjectBuilder, E, S> elementSubjectCreator;
public static <S extends Subject<S, E>, E> ListSubject<S, E> assertThat(
@@ -45,13 +46,13 @@
List<E> list,
BiFunction<StandardSubjectBuilder, E, S> elementSubjectCreator) {
super(failureMetadata, list);
+ this.list = list;
this.elementSubjectCreator = elementSubjectCreator;
}
public S element(int index) {
checkArgument(index >= 0, "index(%s) must be >= 0", index);
isNotNull();
- List<E> list = getActualList();
if (index >= list.size()) {
failWithoutActual(fact("expected to have element at index", index));
}
@@ -61,23 +62,15 @@
public S onlyElement() {
isNotNull();
hasSize(1);
- List<E> list = getActualList();
return elementSubjectCreator.apply(check("onlyElement()"), Iterables.getOnlyElement(list));
}
public S lastElement() {
isNotNull();
isNotEmpty();
- List<E> list = getActualList();
return elementSubjectCreator.apply(check("lastElement()"), Iterables.getLast(list));
}
- @SuppressWarnings("unchecked")
- private List<E> getActualList() {
- // The constructor only accepts lists. -> Casting is appropriate.
- return (List<E>) actual();
- }
-
public static class ListSubjectBuilder extends CustomSubjectBuilder {
ListSubjectBuilder(FailureMetadata failureMetadata) {
diff --git a/java/com/google/gerrit/truth/OptionalSubject.java b/java/com/google/gerrit/truth/OptionalSubject.java
index b5fc5d0..dd1e419 100644
--- a/java/com/google/gerrit/truth/OptionalSubject.java
+++ b/java/com/google/gerrit/truth/OptionalSubject.java
@@ -29,6 +29,7 @@
public class OptionalSubject<S extends Subject<S, ? super T>, T>
extends Subject<OptionalSubject<S, T>, Optional<T>> {
+ private final Optional<T> optional;
private final BiFunction<StandardSubjectBuilder, ? super T, ? extends S> valueSubjectCreator;
// TODO(aliceks): Remove when all relevant usages are adapted to new check()/factory approach.
@@ -62,12 +63,12 @@
Optional<T> optional,
BiFunction<StandardSubjectBuilder, ? super T, ? extends S> valueSubjectCreator) {
super(failureMetadata, optional);
+ this.optional = optional;
this.valueSubjectCreator = valueSubjectCreator;
}
public void isPresent() {
isNotNull();
- Optional<T> optional = actual();
if (!optional.isPresent()) {
failWithoutActual(fact("expected to have", "value"));
}
@@ -75,7 +76,6 @@
public void isAbsent() {
isNotNull();
- Optional<T> optional = actual();
if (optional.isPresent()) {
failWithoutActual(fact("expected not to have", "value"));
}
@@ -88,7 +88,6 @@
public S value() {
isNotNull();
isPresent();
- Optional<T> optional = actual();
return valueSubjectCreator.apply(check("value()"), optional.get());
}
diff --git a/java/gerrit/PRED__load_commit_labels_1.java b/java/gerrit/PRED__load_commit_labels_1.java
index 693c89e..d491c0e 100644
--- a/java/gerrit/PRED__load_commit_labels_1.java
+++ b/java/gerrit/PRED__load_commit_labels_1.java
@@ -38,16 +38,15 @@
LabelTypes types = cd.getLabelTypes();
for (PatchSetApproval a : cd.currentApprovals()) {
- LabelType t = types.byLabel(a.getLabelId());
+ LabelType t = types.byLabel(a.labelId());
if (t == null) {
continue;
}
StructureTerm labelTerm =
- new StructureTerm(
- sym_label, SymbolTerm.intern(t.getName()), new IntegerTerm(a.getValue()));
+ new StructureTerm(sym_label, SymbolTerm.intern(t.getName()), new IntegerTerm(a.value()));
- StructureTerm userTerm = new StructureTerm(sym_user, new IntegerTerm(a.getAccountId().get()));
+ StructureTerm userTerm = new StructureTerm(sym_user, new IntegerTerm(a.accountId().get()));
listHead = new ListTerm(new StructureTerm(sym_commit_label, labelTerm, userTerm), listHead);
}
diff --git a/java/gerrit/PRED_uploader_1.java b/java/gerrit/PRED_uploader_1.java
index 029b84a..feb8302 100644
--- a/java/gerrit/PRED_uploader_1.java
+++ b/java/gerrit/PRED_uploader_1.java
@@ -50,7 +50,7 @@
return engine.fail();
}
- Account.Id uploaderId = patchSet.getUploader();
+ Account.Id uploaderId = patchSet.uploader();
if (!a1.unify(new StructureTerm(user, new IntegerTerm(uploaderId.get())), engine.trail)) {
return engine.fail();
diff --git a/javatests/com/google/gerrit/acceptance/BUILD b/javatests/com/google/gerrit/acceptance/BUILD
index 54b3626..405610b 100644
--- a/javatests/com/google/gerrit/acceptance/BUILD
+++ b/javatests/com/google/gerrit/acceptance/BUILD
@@ -7,6 +7,7 @@
"//java/com/google/gerrit/acceptance:lib",
"//java/com/google/gerrit/server/util/time",
"//java/com/google/gerrit/testing:gerrit-test-util",
+ "//java/com/google/gerrit/truth",
"//lib:guava",
"//lib/jgit/org.eclipse.jgit:jgit",
"//lib/truth",
diff --git a/javatests/com/google/gerrit/acceptance/MergeableFileBasedConfigTest.java b/javatests/com/google/gerrit/acceptance/MergeableFileBasedConfigTest.java
index 69fdc7e..3d17de0 100644
--- a/javatests/com/google/gerrit/acceptance/MergeableFileBasedConfigTest.java
+++ b/javatests/com/google/gerrit/acceptance/MergeableFileBasedConfigTest.java
@@ -15,17 +15,17 @@
package com.google.gerrit.acceptance;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.truth.ConfigSubject.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.collect.ImmutableList;
-import com.google.gerrit.testing.GerritBaseTests;
import java.io.File;
import java.nio.file.Files;
import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.util.FS;
import org.junit.Test;
-public class MergeableFileBasedConfigTest extends GerritBaseTests {
+public class MergeableFileBasedConfigTest {
@Test
public void mergeNull() throws Exception {
MergeableFileBasedConfig cfg = newConfig();
@@ -112,7 +112,7 @@
}
private void assertConfig(MergeableFileBasedConfig cfg, String expected) throws Exception {
- assertThat(cfg.toText()).isEqualTo(expected);
+ assertThat(cfg).text().isEqualTo(expected);
cfg.save();
assertThat(new String(Files.readAllBytes(cfg.getFile().toPath()), UTF_8)).isEqualTo(expected);
}
diff --git a/javatests/com/google/gerrit/acceptance/ProjectResetterTest.java b/javatests/com/google/gerrit/acceptance/ProjectResetterTest.java
index 813c989..2b30fe9 100644
--- a/javatests/com/google/gerrit/acceptance/ProjectResetterTest.java
+++ b/javatests/com/google/gerrit/acceptance/ProjectResetterTest.java
@@ -31,7 +31,6 @@
import com.google.gerrit.server.index.group.GroupIndexer;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.InMemoryRepositoryManager;
import com.google.gerrit.testing.TestTimeUtil;
import java.io.IOException;
@@ -50,7 +49,7 @@
import org.junit.Before;
import org.junit.Test;
-public class ProjectResetterTest extends GerritBaseTests {
+public class ProjectResetterTest {
private InMemoryRepositoryManager repoManager;
private Project.NameKey project;
private Repository repo;
diff --git a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
index b50cbf2..f653ef1 100644
--- a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
@@ -17,10 +17,15 @@
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
-import static com.google.common.truth.Truth.assert_;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.gerrit.acceptance.GitUtil.deleteRef;
import static com.google.gerrit.acceptance.GitUtil.fetch;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.deny;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.permissionKey;
import static com.google.gerrit.gpg.PublicKeyStore.REFS_GPG_KEYS;
import static com.google.gerrit.gpg.PublicKeyStore.keyToString;
import static com.google.gerrit.gpg.testing.TestKeys.allValidKeys;
@@ -32,6 +37,8 @@
import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_GPGKEY;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+import static com.google.gerrit.truth.ConfigSubject.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.TimeUnit.SECONDS;
@@ -354,9 +361,11 @@
AccountInput input = new AccountInput();
input.username = admin.username();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("username '" + admin.username() + "' already exists");
- gApi.accounts().create(input);
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> gApi.accounts().create(input));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("username '" + admin.username() + "' already exists");
}
@Test
@@ -365,9 +374,9 @@
input.username = "foo";
input.email = admin.email();
- exception.expect(UnprocessableEntityException.class);
- exception.expectMessage("email '" + admin.email() + "' already exists");
- gApi.accounts().create(input);
+ UnprocessableEntityException thrown =
+ assertThrows(UnprocessableEntityException.class, () -> gApi.accounts().create(input));
+ assertThat(thrown).hasMessageThat().contains("email '" + admin.email() + "' already exists");
}
@Test
@@ -413,8 +422,10 @@
List<EmailInfo> emails = gApi.accounts().id(accountId.get()).getEmails();
assertThat(emails.stream().map(e -> e.email).collect(toSet())).containsExactly(extId.email());
- RevCommit commitUserBranch = getRemoteHead(allUsers, RefNames.refsUsers(accountId));
- RevCommit commitRefsMetaExternalIds = getRemoteHead(allUsers, RefNames.REFS_EXTERNAL_IDS);
+ RevCommit commitUserBranch =
+ projectOperations.project(allUsers).getHead(RefNames.refsUsers(accountId));
+ RevCommit commitRefsMetaExternalIds =
+ projectOperations.project(allUsers).getHead(RefNames.REFS_EXTERNAL_IDS);
assertThat(commitUserBranch.getCommitTime())
.isEqualTo(commitRefsMetaExternalIds.getCommitTime());
} finally {
@@ -474,10 +485,11 @@
assertThat(tw).isNotNull();
Config cfg = new Config();
cfg.fromText(new String(or.open(tw.getObjectId(0), OBJ_BLOB).getBytes(), UTF_8));
- assertThat(
- cfg.getString(AccountProperties.ACCOUNT, null, AccountProperties.KEY_FULL_NAME))
+ assertThat(cfg)
+ .stringValue(AccountProperties.ACCOUNT, null, AccountProperties.KEY_FULL_NAME)
.isEqualTo(name);
- assertThat(cfg.getString(AccountProperties.ACCOUNT, null, AccountProperties.KEY_STATUS))
+ assertThat(cfg)
+ .stringValue(AccountProperties.ACCOUNT, null, AccountProperties.KEY_STATUS)
.isEqualTo(status);
} else {
// No account properties were set, hence an 'account.config' file was not created.
@@ -522,18 +534,15 @@
accountIndexedCounter.assertReindexOf(user);
// Inactive users may only be resolved by ID.
- try {
- gApi.accounts().id("user");
- assert_().fail("expected ResourceNotFoundException");
- } catch (ResourceNotFoundException e) {
- assertThat(e)
- .hasMessageThat()
- .isEqualTo(
- "Account 'user' only matches inactive accounts. To use an inactive account, retry"
- + " with one of the following exact account IDs:\n"
- + id
- + ": User <user@example.com>");
- }
+ ResourceNotFoundException thrown =
+ assertThrows(ResourceNotFoundException.class, () -> gApi.accounts().id("user"));
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo(
+ "Account 'user' only matches inactive accounts. To use an inactive account, retry"
+ + " with one of the following exact account IDs:\n"
+ + id
+ + ": User <user@example.com>");
assertThat(gApi.accounts().id(id).getActive()).isFalse();
gApi.accounts().id(id).setActive(true);
@@ -570,12 +579,11 @@
try {
/* Test account that can be activated, but not deactivated */
// Deactivate account that is already inactive
- try {
- gApi.accounts().id(activatableAccountId.get()).setActive(false);
- fail("Expected exception");
- } catch (ResourceConflictException e) {
- assertThat(e.getMessage()).isEqualTo("account not active");
- }
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.accounts().id(activatableAccountId.get()).setActive(false));
+ assertThat(thrown).hasMessageThat().isEqualTo("account not active");
assertThat(accountOperations.account(activatableAccountId).get().active()).isFalse();
// Activate account that can be activated
@@ -587,12 +595,11 @@
assertThat(accountOperations.account(activatableAccountId).get().active()).isTrue();
// Try deactivating account that cannot be deactivated
- try {
- gApi.accounts().id(activatableAccountId.get()).setActive(false);
- fail("Expected exception");
- } catch (ResourceConflictException e) {
- assertThat(e.getMessage()).isEqualTo("not allowed to deactive account");
- }
+ thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.accounts().id(activatableAccountId.get()).setActive(false));
+ assertThat(thrown).hasMessageThat().isEqualTo("not allowed to deactive account");
assertThat(accountOperations.account(activatableAccountId).get().active()).isTrue();
/* Test account that can be deactivated, but not activated */
@@ -605,21 +612,19 @@
assertThat(accountOperations.account(deactivatableAccountId).get().active()).isFalse();
// Deactivate account that is already inactive
- try {
- gApi.accounts().id(deactivatableAccountId.get()).setActive(false);
- fail("Expected exception");
- } catch (ResourceConflictException e) {
- assertThat(e.getMessage()).isEqualTo("account not active");
- }
+ thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.accounts().id(deactivatableAccountId.get()).setActive(false));
+ assertThat(thrown).hasMessageThat().isEqualTo("account not active");
assertThat(accountOperations.account(deactivatableAccountId).get().active()).isFalse();
// Try activating account that cannot be activated
- try {
- gApi.accounts().id(deactivatableAccountId.get()).setActive(true);
- fail("Expected exception");
- } catch (ResourceConflictException e) {
- assertThat(e.getMessage()).isEqualTo("not allowed to active account");
- }
+ thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.accounts().id(deactivatableAccountId.get()).setActive(true));
+ assertThat(thrown).hasMessageThat().isEqualTo("not allowed to active account");
assertThat(accountOperations.account(deactivatableAccountId).get().active()).isFalse();
} finally {
registrationHandle.remove();
@@ -628,9 +633,10 @@
@Test
public void deactivateSelf() throws Exception {
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("cannot deactivate own account");
- gApi.accounts().self().setActive(false);
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class, () -> gApi.accounts().self().setActive(false));
+ assertThat(thrown).hasMessageThat().contains("cannot deactivate own account");
}
@Test
@@ -639,12 +645,10 @@
assertThat(gApi.accounts().id("user").getActive()).isTrue();
gApi.accounts().id("user").setActive(false);
assertThat(gApi.accounts().id(id).getActive()).isFalse();
- try {
- gApi.accounts().id(id).setActive(false);
- fail("Expected exception");
- } catch (ResourceConflictException e) {
- assertThat(e.getMessage()).isEqualTo("account not active");
- }
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class, () -> gApi.accounts().id(id).setActive(false));
+ assertThat(thrown).hasMessageThat().isEqualTo("account not active");
gApi.accounts().id(id).setActive(true);
}
@@ -723,23 +727,31 @@
accountIndexedCounter.assertNoReindex();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("not allowed to get stars of another account");
- gApi.accounts().id(Integer.toString((admin.id().get()))).getStars(triplet);
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () -> gApi.accounts().id(Integer.toString((admin.id().get()))).getStars(triplet));
+ assertThat(thrown).hasMessageThat().contains("not allowed to get stars of another account");
}
@Test
public void starWithInvalidLabels() throws Exception {
PushOneCommit.Result r = createChange();
String triplet = project.get() + "~master~" + r.getChangeId();
- exception.expect(BadRequestException.class);
- exception.expectMessage("invalid labels: another invalid label, invalid label");
- gApi.accounts()
- .self()
- .setStars(
- triplet,
- new StarsInput(
- ImmutableSet.of(DEFAULT_LABEL, "invalid label", "blue", "another invalid label")));
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () ->
+ gApi.accounts()
+ .self()
+ .setStars(
+ triplet,
+ new StarsInput(
+ ImmutableSet.of(
+ DEFAULT_LABEL, "invalid label", "blue", "another invalid label"))));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("invalid labels: another invalid label, invalid label");
}
@Test
@@ -757,17 +769,24 @@
public void starWithDefaultAndIgnoreLabel() throws Exception {
PushOneCommit.Result r = createChange();
String triplet = project.get() + "~master~" + r.getChangeId();
- exception.expect(BadRequestException.class);
- exception.expectMessage(
- "The labels "
- + DEFAULT_LABEL
- + " and "
- + IGNORE_LABEL
- + " are mutually exclusive."
- + " Only one of them can be set.");
- gApi.accounts()
- .self()
- .setStars(triplet, new StarsInput(ImmutableSet.of(DEFAULT_LABEL, "blue", IGNORE_LABEL)));
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () ->
+ gApi.accounts()
+ .self()
+ .setStars(
+ triplet,
+ new StarsInput(ImmutableSet.of(DEFAULT_LABEL, "blue", IGNORE_LABEL))));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ "The labels "
+ + DEFAULT_LABEL
+ + " and "
+ + IGNORE_LABEL
+ + " are mutually exclusive."
+ + " Only one of them can be set.");
}
@Test
@@ -908,9 +927,9 @@
TestAccount foo = accountCreator.create(name("foo"), email, "Foo");
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("modify account not permitted");
- gApi.accounts().id(foo.id().get()).getEmails();
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.accounts().id(foo.id().get()).getEmails());
+ assertThat(thrown).hasMessageThat().contains("modify account not permitted");
}
@Test
@@ -960,12 +979,9 @@
"new.email@example.africa");
for (String email : emails) {
EmailInput input = newEmailInput(email);
- try {
- gApi.accounts().self().addEmail(input);
- fail("Expected BadRequestException for invalid email address: " + email);
- } catch (BadRequestException e) {
- assertThat(e).hasMessageThat().isEqualTo("invalid email address");
- }
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> gApi.accounts().self().addEmail(input));
+ assertWithMessage(email).that(thrown).hasMessageThat().isEqualTo("invalid email address");
}
accountIndexedCounter.assertNoReindex();
}
@@ -975,8 +991,7 @@
TestAccount account = accountCreator.create(name("user"));
EmailInput input = newEmailInput("test@test.com");
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- gApi.accounts().id(account.username()).addEmail(input);
+ assertThrows(AuthException.class, () -> gApi.accounts().id(account.username()).addEmail(input));
}
@Test
@@ -984,9 +999,13 @@
String email = "new.email@example.com";
EmailInput input = newEmailInput(email);
gApi.accounts().self().addEmail(input);
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Identity 'mailto:" + email + "' in use by another account");
- gApi.accounts().id(user.username()).addEmail(input);
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.accounts().id(user.username()).addEmail(input));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Identity 'mailto:" + email + "' in use by another account");
}
@Test
@@ -1022,9 +1041,14 @@
TestAccount user = accountCreator.create();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("modify account not permitted");
- gApi.accounts().id(admin.id().get()).addEmail(newEmailInput("foo@example.com", false));
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () ->
+ gApi.accounts()
+ .id(admin.id().get())
+ .addEmail(newEmailInput("foo@example.com", false)));
+ assertThat(thrown).hasMessageThat().contains("modify account not permitted");
}
@Test
@@ -1109,9 +1133,11 @@
assertThat(getEmails()).doesNotContain(email);
// user cannot delete email of admin
- exception.expect(AuthException.class);
- exception.expectMessage("modify account not permitted");
- gApi.accounts().id(admin.id().get()).deleteEmail(admin.email());
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () -> gApi.accounts().id(admin.id().get()).deleteEmail(admin.email()));
+ assertThat(thrown).hasMessageThat().contains("modify account not permitted");
}
@Test
@@ -1205,14 +1231,18 @@
@Test
public void userCannotSetNameOfOtherUser() throws Exception {
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- gApi.accounts().id(admin.username()).setName("Admin McAdminface");
+ assertThrows(
+ AuthException.class,
+ () -> gApi.accounts().id(admin.username()).setName("Admin McAdminface"));
}
@Test
@Sandboxed
public void userCanSetNameOfOtherUserWithModifyAccountPermission() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.MODIFY_ACCOUNT);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.MODIFY_ACCOUNT).group(REGISTERED_USERS))
+ .update();
gApi.accounts().id(admin.username()).setName("Admin McAdminface");
assertThat(gApi.accounts().id(admin.username()).get().name).isEqualTo("Admin McAdminface");
}
@@ -1233,23 +1263,24 @@
}
// deny READ permission that is inherited from All-Projects
- deny(allUsers, RefNames.REFS + "*", Permission.READ, ANONYMOUS_USERS);
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(deny(Permission.READ).ref(RefNames.REFS + "*").group(ANONYMOUS_USERS))
+ .update();
// fetching user branch without READ permission fails
- try {
- fetch(allUsersRepo, userRefName + ":userRef");
- fail("user branch is visible although no READ permission is granted");
- } catch (TransportException e) {
- // expected because no READ granted on user branch
- }
+ assertThrows(TransportException.class, () -> fetch(allUsersRepo, userRefName + ":userRef"));
// allow each user to read its own user branch
- grant(
- allUsers,
- RefNames.REFS_USERS + "${" + RefPattern.USERID_SHARDED + "}",
- Permission.READ,
- false,
- REGISTERED_USERS);
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(
+ allow(Permission.READ)
+ .ref(RefNames.REFS_USERS + "${" + RefPattern.USERID_SHARDED + "}")
+ .group(REGISTERED_USERS))
+ .update();
// fetch user branch using refs/users/YY/XXXXXXX
fetch(allUsersRepo, userRefName + ":userRef");
@@ -1266,9 +1297,13 @@
// fetching user branch of another user fails
String otherUserRefName = RefNames.refsUsers(admin.id());
- exception.expect(TransportException.class);
- exception.expectMessage("Remote does not have " + otherUserRefName + " available for fetch.");
- fetch(allUsersRepo, otherUserRefName + ":otherUserRef");
+ TransportException thrown =
+ assertThrows(
+ TransportException.class,
+ () -> fetch(allUsersRepo, otherUserRefName + ":otherUserRef"));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Remote does not have " + otherUserRefName + " available for fetch.");
}
@Test
@@ -1404,17 +1439,21 @@
assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRef);
gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
- exception.expect(ResourceConflictException.class);
- exception.expectMessage(
- String.format(
- "invalid account configuration: commit '%s' has an invalid '%s' file for account '%s':"
- + " Invalid config file %s in commit %s",
- r.getCommit().name(),
- AccountProperties.ACCOUNT_CONFIG,
- admin.id(),
- AccountProperties.ACCOUNT_CONFIG,
- r.getCommit().name()));
- gApi.changes().id(r.getChangeId()).current().submit();
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(r.getChangeId()).current().submit());
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ String.format(
+ "invalid account configuration: commit '%s' has an invalid '%s' file for account"
+ + " '%s': Invalid config file %s in commit %s",
+ r.getCommit().name(),
+ AccountProperties.ACCOUNT_CONFIG,
+ admin.id(),
+ AccountProperties.ACCOUNT_CONFIG,
+ r.getCommit().name()));
}
@Test
@@ -1443,12 +1482,16 @@
assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRef);
gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
- exception.expect(ResourceConflictException.class);
- exception.expectMessage(
- String.format(
- "invalid account configuration: invalid preferred email '%s' for account '%s'",
- noEmail, admin.id()));
- gApi.changes().id(r.getChangeId()).current().submit();
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(r.getChangeId()).current().submit());
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ String.format(
+ "invalid account configuration: invalid preferred email '%s' for account '%s'",
+ noEmail, admin.id()));
}
@Test
@@ -1476,23 +1519,34 @@
assertThat(r.getChange().change().getDest().branch()).isEqualTo(userRef);
gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("invalid account configuration: cannot deactivate own account");
- gApi.changes().id(r.getChangeId()).current().submit();
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(r.getChangeId()).current().submit());
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("invalid account configuration: cannot deactivate own account");
}
@Test
public void pushAccountConfigToUserBranchForReviewDeactivateOtherAccount() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
TestAccount foo = accountCreator.create(name("foo"));
assertThat(gApi.accounts().id(foo.id().get()).getActive()).isTrue();
String userRef = RefNames.refsUsers(foo.id());
accountIndexedCounter.clear();
- grant(allUsers, userRef, Permission.PUSH, false, adminGroupUuid());
- grantLabel("Code-Review", -2, 2, allUsers, userRef, false, adminGroupUuid(), false);
- grant(allUsers, userRef, Permission.SUBMIT, false, adminGroupUuid());
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref(userRef).group(adminGroupUuid()))
+ .add(allowLabel("Code-Review").ref(userRef).group(adminGroupUuid()).range(-2, 2))
+ .add(allow(Permission.SUBMIT).ref(userRef).group(adminGroupUuid()))
+ .update();
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
fetch(allUsersRepo, userRef + ":userRef");
@@ -1657,7 +1711,11 @@
.update("Set Preferred Email", foo.id(), u -> u.setPreferredEmail(noEmail));
accountIndexedCounter.clear();
- grant(allUsers, userRef, Permission.PUSH, false, REGISTERED_USERS);
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref(userRef).group(REGISTERED_USERS))
+ .update();
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers, foo);
fetch(allUsersRepo, userRef + ":userRef");
allUsersRepo.reset("userRef");
@@ -1689,7 +1747,11 @@
String userRef = RefNames.refsUsers(foo.id());
accountIndexedCounter.clear();
- grant(allUsers, userRef, Permission.PUSH, false, adminGroupUuid());
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref(userRef).group(adminGroupUuid()))
+ .update();
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers, foo);
fetch(allUsersRepo, userRef + ":userRef");
@@ -1740,14 +1802,21 @@
@Test
public void pushAccountConfigToUserBranchDeactivateOtherAccount() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
TestAccount foo = accountCreator.create(name("foo"));
assertThat(gApi.accounts().id(foo.id().get()).getActive()).isTrue();
String userRef = RefNames.refsUsers(foo.id());
accountIndexedCounter.clear();
- grant(allUsers, userRef, Permission.PUSH, false, adminGroupUuid());
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref(userRef).group(adminGroupUuid()))
+ .update();
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
fetch(allUsersRepo, userRef + ":userRef");
@@ -1772,8 +1841,12 @@
@Test
public void cannotCreateUserBranch() throws Exception {
- grant(allUsers, RefNames.REFS_USERS + "*", Permission.CREATE);
- grant(allUsers, RefNames.REFS_USERS + "*", Permission.PUSH);
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
+ .add(allow(Permission.PUSH).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
+ .update();
String userRef = RefNames.refsUsers(Account.id(seq.nextAccountId()));
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
@@ -1788,9 +1861,16 @@
@Test
public void createUserBranchWithAccessDatabaseCapability() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
- grant(allUsers, RefNames.REFS_USERS + "*", Permission.CREATE);
- grant(allUsers, RefNames.REFS_USERS + "*", Permission.PUSH);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
+ .add(allow(Permission.PUSH).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
+ .update();
String userRef = RefNames.refsUsers(Account.id(seq.nextAccountId()));
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
@@ -1804,9 +1884,16 @@
@Test
public void cannotCreateNonUserBranchUnderRefsUsersWithAccessDatabaseCapability()
throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
- grant(allUsers, RefNames.REFS_USERS + "*", Permission.CREATE);
- grant(allUsers, RefNames.REFS_USERS + "*", Permission.PUSH);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
+ .add(allow(Permission.PUSH).ref(RefNames.REFS_USERS + "*").group(adminGroupUuid()))
+ .update();
String userRef = RefNames.REFS_USERS + "foo";
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
@@ -1825,8 +1912,12 @@
assertThat(repo.exactRef(RefNames.REFS_USERS_DEFAULT)).isNull();
}
- grant(allUsers, RefNames.REFS_USERS_DEFAULT, Permission.CREATE);
- grant(allUsers, RefNames.REFS_USERS_DEFAULT, Permission.PUSH);
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref(RefNames.REFS_USERS_DEFAULT).group(adminGroupUuid()))
+ .add(allow(Permission.PUSH).ref(RefNames.REFS_USERS_DEFAULT).group(adminGroupUuid()))
+ .update();
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
pushFactory
@@ -1841,12 +1932,15 @@
@Test
public void cannotDeleteUserBranch() throws Exception {
- grant(
- allUsers,
- RefNames.REFS_USERS + "${" + RefPattern.USERID_SHARDED + "}",
- Permission.DELETE,
- true,
- REGISTERED_USERS);
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(
+ allow(Permission.DELETE)
+ .ref(RefNames.REFS_USERS + "${" + RefPattern.USERID_SHARDED + "}")
+ .group(REGISTERED_USERS)
+ .force(true))
+ .update();
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
String userRef = RefNames.refsUsers(admin.id());
@@ -1862,13 +1956,19 @@
@Test
public void deleteUserBranchWithAccessDatabaseCapability() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
- grant(
- allUsers,
- RefNames.REFS_USERS + "${" + RefPattern.USERID_SHARDED + "}",
- Permission.DELETE,
- true,
- REGISTERED_USERS);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(
+ allow(Permission.DELETE)
+ .ref(RefNames.REFS_USERS + "${" + RefPattern.USERID_SHARDED + "}")
+ .group(REGISTERED_USERS)
+ .force(true))
+ .update();
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
String userRef = RefNames.refsUsers(admin.id());
@@ -1897,9 +1997,10 @@
assertThat(sender.getMessages().get(0).body()).contains("new GPG keys have been added");
requestScopeOperations.setApiUser(user.id());
- exception.expect(ResourceNotFoundException.class);
- exception.expectMessage(id);
- gApi.accounts().self().gpgKey(id).get();
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class, () -> gApi.accounts().self().gpgKey(id).get());
+ assertThat(thrown).hasMessageThat().contains(id);
}
@Test
@@ -1942,9 +2043,9 @@
addGpgKey(key.getPublicKeyArmored());
requestScopeOperations.setApiUser(user.id());
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("GPG key already associated with another account");
- addGpgKey(key.getPublicKeyArmored());
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> addGpgKey(key.getPublicKeyArmored()));
+ assertThat(thrown).hasMessageThat().contains("GPG key already associated with another account");
}
@Test
@@ -1968,13 +2069,17 @@
addGpgKey(key.getPublicKeyArmored());
assertKeys(key);
+ sender.clear();
gApi.accounts().self().gpgKey(id).delete();
accountIndexedCounter.assertReindexOf(admin);
assertKeys();
+ assertThat(sender.getMessages()).hasSize(1);
+ assertThat(sender.getMessages().get(0).body()).contains("GPG keys have been deleted");
- exception.expect(ResourceNotFoundException.class);
- exception.expectMessage(id);
- gApi.accounts().self().gpgKey(id).get();
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class, () -> gApi.accounts().self().gpgKey(id).get());
+ assertThat(thrown).hasMessageThat().contains(id);
}
@Test
@@ -2008,20 +2113,25 @@
assertKeys(key2, key5);
accountIndexedCounter.assertReindexOf(admin);
- exception.expect(BadRequestException.class);
- exception.expectMessage("Cannot both add and delete key: " + keyToString(key2.getPublicKey()));
- gApi.accounts()
- .self()
- .putGpgKeys(
- ImmutableList.of(key2.getPublicKeyArmored()), ImmutableList.of(key2.getKeyIdString()));
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () ->
+ gApi.accounts()
+ .self()
+ .putGpgKeys(
+ ImmutableList.of(key2.getPublicKeyArmored()),
+ ImmutableList.of(key2.getKeyIdString())));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Cannot both add and delete key: " + keyToString(key2.getPublicKey()));
}
@Test
public void addMalformedGpgKey() throws Exception {
String key = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\ntest\n-----END PGP PUBLIC KEY BLOCK-----";
- exception.expect(BadRequestException.class);
- exception.expectMessage("Failed to parse GPG keys");
- addGpgKey(key);
+ BadRequestException thrown = assertThrows(BadRequestException.class, () -> addGpgKey(key));
+ assertThat(thrown).hasMessageThat().contains("Failed to parse GPG keys");
}
@Test
@@ -2071,6 +2181,7 @@
assertThat(sender.getMessages().get(0).body()).contains("new SSH keys have been added");
// Delete second key
+ sender.clear();
gApi.accounts().self().deleteSshKey(2);
info = gApi.accounts().self().listSshKeys();
assertThat(info).hasSize(2);
@@ -2078,6 +2189,9 @@
assertThat(info.get(1).seq).isEqualTo(3);
accountIndexedCounter.assertReindexOf(admin);
+ assertThat(sender.getMessages()).hasSize(1);
+ assertThat(sender.getMessages().get(0).body()).contains("SSH keys have been deleted");
+
// Mark first key as invalid
assertThat(info.get(0).valid).isTrue();
authorizedKeys.markKeyInvalid(admin.id(), 1);
@@ -2103,14 +2217,17 @@
accountIndexedCounter.assertReindexOf(user);
// user cannot reindex any account
- exception.expect(AuthException.class);
- exception.expectMessage("modify account not permitted");
- gApi.accounts().id(admin.username()).index();
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.accounts().id(admin.username()).index());
+ assertThat(thrown).hasMessageThat().contains("modify account not permitted");
}
@Test
public void checkConsistency() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
requestScopeOperations.resetCurrentApiUser();
// Create an account with a preferred email.
@@ -2234,12 +2351,9 @@
"@", "@foo", "-", "-foo", "_", "_foo", "!", "+", "{", "}", "*", "%", "#", "$", "&", "’",
"^", "=", "~");
for (String name : invalidNames) {
- try {
- gApi.accounts().create(name);
- fail(String.format("Expected BadRequestException for username [%s]", name));
- } catch (BadRequestException e) {
- assertThat(e).hasMessageThat().isEqualTo(String.format("Invalid username '%s'", name));
- }
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> gApi.accounts().create(name));
+ assertThat(thrown).hasMessageThat().isEqualTo(String.format("Invalid username '%s'", name));
}
}
@@ -2375,12 +2489,9 @@
assertThat(accountInfo.status).isNull();
assertThat(accountInfo.name).isNotEqualTo(fullName);
- try {
- update.update("Set Full Name", admin.id(), u -> u.setFullName(fullName));
- fail("expected LockFailureException");
- } catch (LockFailureException e) {
- // Ignore, expected
- }
+ assertThrows(
+ LockFailureException.class,
+ () -> update.update("Set Full Name", admin.id(), u -> u.setFullName(fullName)));
assertThat(bgCounter.get()).isEqualTo(status.size());
Account updatedAccount = accounts.get(admin.id()).get().getAccount();
@@ -2453,7 +2564,10 @@
@Test
public void atomicReadMofifyWriteExternalIds() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
Account.Id accountId = Account.id(seq.nextAccountId());
ExternalId extIdA1 = ExternalId.create("foo", "A-1", accountId);
@@ -2698,12 +2812,14 @@
requestScopeOperations.setApiUser(user.id());
createDraft(r, PushOneCommit.FILE_NAME, "draft");
requestScopeOperations.setApiUser(admin.id());
- try {
- gApi.accounts().id(user.id().get()).deleteDraftComments(new DeleteDraftCommentsInput());
- assert_().fail("expected AuthException");
- } catch (AuthException e) {
- assertThat(e).hasMessageThat().isEqualTo("Cannot delete drafts of other user");
- }
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () ->
+ gApi.accounts()
+ .id(user.id().get())
+ .deleteDraftComments(new DeleteDraftCommentsInput()));
+ assertThat(thrown).hasMessageThat().isEqualTo("Cannot delete drafts of other user");
} finally {
cleanUpDrafts();
}
@@ -2722,14 +2838,22 @@
assertThat(gApi.changes().id(r1.getChangeId()).current().draftsAsList()).hasSize(1);
assertThat(gApi.changes().id(r2.getChangeId()).current().draftsAsList()).hasSize(1);
- block(project, "refs/heads/secret", Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.READ).ref("refs/heads/secret").group(REGISTERED_USERS))
+ .update();
List<DeletedDraftCommentInfo> result =
gApi.accounts().self().deleteDraftComments(new DeleteDraftCommentsInput());
assertThat(result).hasSize(1);
assertThat(result.get(0).change.changeId).isEqualTo(r1.getChangeId());
assertThat(result.get(0).deleted.stream().map(c -> c.message)).containsExactly("draft a");
- removePermission(project, "refs/heads/secret", Permission.READ);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .remove(permissionKey(Permission.READ).ref("refs/heads/secret"))
+ .update();
assertThat(gApi.changes().id(r1.getChangeId()).current().draftsAsList()).isEmpty();
// Draft still exists since change wasn't visible when drafts where deleted.
assertThat(gApi.changes().id(r2.getChangeId()).current().draftsAsList()).hasSize(1);
@@ -2740,63 +2864,91 @@
@Test
public void userCanGenerateNewHttpPassword() throws Exception {
+ sender.clear();
String newPassword = gApi.accounts().self().generateHttpPassword();
assertThat(newPassword).isNotNull();
+ assertThat(sender.getMessages()).hasSize(1);
+ assertThat(sender.getMessages().get(0).body()).contains("HTTP password was added or updated");
}
@Test
public void adminCanGenerateNewHttpPasswordForUser() throws Exception {
requestScopeOperations.setApiUser(admin.id());
+ sender.clear();
String newPassword = gApi.accounts().id(user.username()).generateHttpPassword();
assertThat(newPassword).isNotNull();
+ assertThat(sender.getMessages()).hasSize(1);
+ assertThat(sender.getMessages().get(0).body()).contains("HTTP password was added or updated");
}
@Test
public void userCannotGenerateNewHttpPasswordForOtherUser() throws Exception {
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- gApi.accounts().id(admin.username()).generateHttpPassword();
+ assertThrows(
+ AuthException.class, () -> gApi.accounts().id(admin.username()).generateHttpPassword());
}
@Test
public void userCannotExplicitlySetHttpPassword() throws Exception {
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- gApi.accounts().self().setHttpPassword("my-new-password");
+ assertThrows(
+ AuthException.class, () -> gApi.accounts().self().setHttpPassword("my-new-password"));
}
@Test
public void userCannotExplicitlySetHttpPasswordForOtherUser() throws Exception {
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- gApi.accounts().id(admin.username()).setHttpPassword("my-new-password");
+ assertThrows(
+ AuthException.class,
+ () -> gApi.accounts().id(admin.username()).setHttpPassword("my-new-password"));
}
@Test
public void userCanRemoveHttpPassword() throws Exception {
requestScopeOperations.setApiUser(user.id());
+ sender.clear();
assertThat(gApi.accounts().self().setHttpPassword(null)).isNull();
+ assertThat(sender.getMessages()).hasSize(1);
+ assertThat(sender.getMessages().get(0).body()).contains("HTTP password was deleted");
}
@Test
public void userCannotRemoveHttpPasswordForOtherUser() throws Exception {
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- gApi.accounts().id(admin.username()).setHttpPassword(null);
+ assertThrows(
+ AuthException.class, () -> gApi.accounts().id(admin.username()).setHttpPassword(null));
}
@Test
public void adminCanExplicitlySetHttpPasswordForUser() throws Exception {
requestScopeOperations.setApiUser(admin.id());
String httpPassword = "new-password-for-user";
+ sender.clear();
assertThat(gApi.accounts().id(user.username()).setHttpPassword(httpPassword))
.isEqualTo(httpPassword);
+ assertThat(sender.getMessages()).hasSize(1);
+ assertThat(sender.getMessages().get(0).body()).contains("HTTP password was added or updated");
}
@Test
public void adminCanRemoveHttpPasswordForUser() throws Exception {
requestScopeOperations.setApiUser(admin.id());
+ sender.clear();
assertThat(gApi.accounts().id(user.username()).setHttpPassword(null)).isNull();
+ assertThat(sender.getMessages()).hasSize(1);
+ assertThat(sender.getMessages().get(0).body()).contains("HTTP password was deleted");
+ }
+
+ @Test
+ public void cannotGenerateHttpPasswordWhenUsernameIsNotSet() throws Exception {
+ requestScopeOperations.setApiUser(admin.id());
+ int userId = accountCreator.create().id().get();
+ assertThat(gApi.accounts().id(userId).get().username).isNull();
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.accounts().id(userId).generateHttpPassword());
+ assertThat(thrown).hasMessageThat().contains("username");
}
private void createDraft(PushOneCommit.Result r, String path, String message) throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/api/accounts/AccountManagerIT.java b/javatests/com/google/gerrit/acceptance/api/accounts/AccountManagerIT.java
index ff66789..8730486 100644
--- a/javatests/com/google/gerrit/acceptance/api/accounts/AccountManagerIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/accounts/AccountManagerIT.java
@@ -18,6 +18,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.Truth8.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GerritConfig;
@@ -236,9 +237,9 @@
}
AuthRequest who = AuthRequest.forUser(username);
- exception.expect(AccountException.class);
- exception.expectMessage("Authentication error, account not found");
- accountManager.authenticate(who);
+ AccountException thrown =
+ assertThrows(AccountException.class, () -> accountManager.authenticate(who));
+ assertThat(thrown).hasMessageThat().contains("Authentication error, account not found");
}
@Test
@@ -252,9 +253,9 @@
u -> u.setActive(false).addExternalId(ExternalId.create(gerritExtIdKey, accountId)));
AuthRequest who = AuthRequest.forUser(username);
- exception.expect(AccountException.class);
- exception.expectMessage("Authentication error, account inactive");
- accountManager.authenticate(who);
+ AccountException thrown =
+ assertThrows(AccountException.class, () -> accountManager.authenticate(who));
+ assertThat(thrown).hasMessageThat().contains("Authentication error, account inactive");
}
@Test
@@ -271,9 +272,9 @@
AuthRequest who = AuthRequest.forUser(username);
who.setActive(true);
who.setAuthProvidesAccountActiveStatus(true);
- exception.expect(AccountException.class);
- exception.expectMessage("Authentication error, account inactive");
- accountManager.authenticate(who);
+ AccountException thrown =
+ assertThrows(AccountException.class, () -> accountManager.authenticate(who));
+ assertThat(thrown).hasMessageThat().contains("Authentication error, account inactive");
}
@Test
@@ -334,12 +335,9 @@
AuthRequest who = AuthRequest.forUser(username);
who.setActive(false);
who.setAuthProvidesAccountActiveStatus(true);
- try {
- accountManager.authenticate(who);
- fail("Expected AccountException");
- } catch (AccountException e) {
- assertThat(e).hasMessageThat().isEqualTo("Authentication error, account inactive");
- }
+ AccountException thrown =
+ assertThrows(AccountException.class, () -> accountManager.authenticate(who));
+ assertThat(thrown).hasMessageThat().isEqualTo("Authentication error, account inactive");
Optional<AccountState> accountState = accounts.get(accountId);
assertThat(accountState).isPresent();
@@ -362,9 +360,11 @@
// Try to authenticate with this email to create a new account with a SCHEME_MAILTO external ID.
// Expect that this fails because the email is already assigned to the other account.
AuthRequest who = AuthRequest.forEmail(email);
- exception.expect(AccountException.class);
- exception.expectMessage("Email 'foo@example.com' in use by another account");
- accountManager.authenticate(who);
+ AccountException thrown =
+ assertThrows(AccountException.class, () -> accountManager.authenticate(who));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Email 'foo@example.com' in use by another account");
}
@Test
@@ -384,9 +384,11 @@
// Expect that this fails because the email is already assigned to the other account.
AuthRequest who = AuthRequest.forUser("bar");
who.setEmailAddress(email);
- exception.expect(AccountException.class);
- exception.expectMessage("Email 'foo@example.com' in use by another account");
- accountManager.authenticate(who);
+ AccountException thrown =
+ assertThrows(AccountException.class, () -> accountManager.authenticate(who));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Email 'foo@example.com' in use by another account");
}
@Test
@@ -417,12 +419,11 @@
// Expect that this fails because the new email is already assigned to the other account.
AuthRequest who = AuthRequest.forUser(username);
who.setEmailAddress(newEmail);
- try {
- accountManager.authenticate(who);
- fail("Expected AccountException");
- } catch (AccountException e) {
- assertThat(e).hasMessageThat().isEqualTo("Email 'bar@example.com' in use by another account");
- }
+ AccountException thrown =
+ assertThrows(AccountException.class, () -> accountManager.authenticate(who));
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo("Email 'bar@example.com' in use by another account");
// Verify that the email in the external ID was not updated.
Optional<ExternalId> gerritExtId = externalIds.get(gerritExtIdKey);
@@ -505,9 +506,11 @@
// Try to link external ID of the first account to the second account.
// Expect that this fails because the external ID is already assigned to the first account.
AuthRequest who = AuthRequest.forExternalUser(username1);
- exception.expect(AccountException.class);
- exception.expectMessage("Identity 'external:foo' in use by another account");
- accountManager.link(accountId2, who);
+ AccountException thrown =
+ assertThrows(AccountException.class, () -> accountManager.link(accountId2, who));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Identity 'external:foo' in use by another account");
}
@Test
@@ -535,9 +538,11 @@
// Try to link the email to the second account (via a new MAILTO external ID) and expect that
// this fails because the email is already assigned to the first account.
AuthRequest who = AuthRequest.forEmail(email);
- exception.expect(AccountException.class);
- exception.expectMessage("Email 'foo@example.com' in use by another account");
- accountManager.link(accountId, who);
+ AccountException thrown =
+ assertThrows(AccountException.class, () -> accountManager.link(accountId, who));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Email 'foo@example.com' in use by another account");
}
private void assertNoSuchExternalIds(ExternalId.Key... extIdKeys) throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/api/accounts/AgreementsIT.java b/javatests/com/google/gerrit/acceptance/api/accounts/AgreementsIT.java
index 67f4151..6dc8fc5 100644
--- a/javatests/com/google/gerrit/acceptance/api/accounts/AgreementsIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/accounts/AgreementsIT.java
@@ -16,6 +16,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.TruthJUnit.assume;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.concurrent.TimeUnit.SECONDS;
@@ -145,17 +146,21 @@
@Test
public void signNonExistingAgreement() throws Exception {
assume().that(isContributorAgreementsEnabled()).isTrue();
- exception.expect(UnprocessableEntityException.class);
- exception.expectMessage("contributor agreement not found");
- gApi.accounts().self().signAgreement("does-not-exist");
+ UnprocessableEntityException thrown =
+ assertThrows(
+ UnprocessableEntityException.class,
+ () -> gApi.accounts().self().signAgreement("does-not-exist"));
+ assertThat(thrown).hasMessageThat().contains("contributor agreement not found");
}
@Test
public void signAgreementNoAutoVerify() throws Exception {
assume().that(isContributorAgreementsEnabled()).isTrue();
- exception.expect(BadRequestException.class);
- exception.expectMessage("cannot enter a non-autoVerify agreement");
- gApi.accounts().self().signAgreement(caNoAutoVerify.getName());
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () -> gApi.accounts().self().signAgreement(caNoAutoVerify.getName()));
+ assertThat(thrown).hasMessageThat().contains("cannot enter a non-autoVerify agreement");
}
@Test
@@ -188,33 +193,40 @@
public void signAgreementAsOtherUser() throws Exception {
assume().that(isContributorAgreementsEnabled()).isTrue();
assertThat(gApi.accounts().self().get().name).isNotEqualTo("admin");
- exception.expect(AuthException.class);
- exception.expectMessage("not allowed to enter contributor agreement");
- gApi.accounts().id("admin").signAgreement(caAutoVerify.getName());
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () -> gApi.accounts().id("admin").signAgreement(caAutoVerify.getName()));
+ assertThat(thrown).hasMessageThat().contains("not allowed to enter contributor agreement");
}
@Test
public void signAgreementAnonymous() throws Exception {
requestScopeOperations.setApiUserAnonymous();
- exception.expect(AuthException.class);
- exception.expectMessage("Authentication required");
- gApi.accounts().self().signAgreement(caAutoVerify.getName());
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () -> gApi.accounts().self().signAgreement(caAutoVerify.getName()));
+ assertThat(thrown).hasMessageThat().contains("Authentication required");
}
@Test
public void agreementsDisabledSign() throws Exception {
assume().that(isContributorAgreementsEnabled()).isFalse();
- exception.expect(MethodNotAllowedException.class);
- exception.expectMessage("contributor agreements disabled");
- gApi.accounts().self().signAgreement(caAutoVerify.getName());
+ MethodNotAllowedException thrown =
+ assertThrows(
+ MethodNotAllowedException.class,
+ () -> gApi.accounts().self().signAgreement(caAutoVerify.getName()));
+ assertThat(thrown).hasMessageThat().contains("contributor agreements disabled");
}
@Test
public void agreementsDisabledList() throws Exception {
assume().that(isContributorAgreementsEnabled()).isFalse();
- exception.expect(MethodNotAllowedException.class);
- exception.expectMessage("contributor agreements disabled");
- gApi.accounts().self().listAgreements();
+ MethodNotAllowedException thrown =
+ assertThrows(
+ MethodNotAllowedException.class, () -> gApi.accounts().self().listAgreements());
+ assertThat(thrown).hasMessageThat().contains("contributor agreements disabled");
}
@Test
@@ -233,9 +245,9 @@
// Revert is not allowed when CLA is required but not signed
requestScopeOperations.setApiUser(user.id());
setUseContributorAgreements(InheritableBoolean.TRUE);
- exception.expect(AuthException.class);
- exception.expectMessage("Contributor Agreement");
- gApi.changes().id(change.changeId).revert();
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.changes().id(change.changeId).revert());
+ assertThat(thrown).hasMessageThat().contains("Contributor Agreement");
}
@Test
@@ -287,9 +299,10 @@
CherryPickInput in = new CherryPickInput();
in.destination = dest.ref;
in.message = change.subject;
- exception.expect(AuthException.class);
- exception.expectMessage("Contributor Agreement");
- gApi.changes().id(change.changeId).current().cherryPick(in);
+ AuthException thrown =
+ assertThrows(
+ AuthException.class, () -> gApi.changes().id(change.changeId).current().cherryPick(in));
+ assertThat(thrown).hasMessageThat().contains("Contributor Agreement");
}
@Test
@@ -302,12 +315,9 @@
// Create a change is not allowed when CLA is required but not signed
setUseContributorAgreements(InheritableBoolean.TRUE);
- try {
- gApi.changes().create(newChangeInput());
- fail("Expected AuthException");
- } catch (AuthException e) {
- assertThat(e.getMessage()).contains("Contributor Agreement");
- }
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.changes().create(newChangeInput()));
+ assertThat(thrown).hasMessageThat().contains("Contributor Agreement");
// Sign the agreement
gApi.accounts().self().signAgreement(caAutoVerify.getName());
diff --git a/javatests/com/google/gerrit/acceptance/api/accounts/GeneralPreferencesIT.java b/javatests/com/google/gerrit/acceptance/api/accounts/GeneralPreferencesIT.java
index 70e37ef..12266c9 100644
--- a/javatests/com/google/gerrit/acceptance/api/accounts/GeneralPreferencesIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/accounts/GeneralPreferencesIT.java
@@ -16,6 +16,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.AssertUtil.assertPrefs;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
@@ -160,9 +161,11 @@
i.my = new ArrayList<>();
i.my.add(new MenuItem(null, "url"));
- exception.expect(BadRequestException.class);
- exception.expectMessage("name for menu item is required");
- gApi.accounts().id(user42.id().toString()).setPreferences(i);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () -> gApi.accounts().id(user42.id().toString()).setPreferences(i));
+ assertThat(thrown).hasMessageThat().contains("name for menu item is required");
}
@Test
@@ -171,9 +174,11 @@
i.my = new ArrayList<>();
i.my.add(new MenuItem("name", null));
- exception.expect(BadRequestException.class);
- exception.expectMessage("URL for menu item is required");
- gApi.accounts().id(user42.id().toString()).setPreferences(i);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () -> gApi.accounts().id(user42.id().toString()).setPreferences(i));
+ assertThat(thrown).hasMessageThat().contains("URL for menu item is required");
}
@Test
@@ -191,9 +196,13 @@
GeneralPreferencesInfo i = GeneralPreferencesInfo.defaults();
i.downloadScheme = "foo";
- exception.expect(BadRequestException.class);
- exception.expectMessage("Unsupported download scheme: " + i.downloadScheme);
- gApi.accounts().id(user42.id().toString()).setPreferences(i);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () -> gApi.accounts().id(user42.id().toString()).setPreferences(i));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Unsupported download scheme: " + i.downloadScheme);
}
@Test
diff --git a/javatests/com/google/gerrit/acceptance/api/change/AbandonIT.java b/javatests/com/google/gerrit/acceptance/api/change/AbandonIT.java
index 27cb2e9..87f9a2d5 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/AbandonIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/AbandonIT.java
@@ -15,8 +15,10 @@
package com.google.gerrit.acceptance.api.change;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.extensions.client.ListChangesOption.MESSAGES;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.stream.Collectors.toList;
@@ -26,6 +28,7 @@
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GerritConfig;
import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.client.ChangeStatus;
@@ -46,8 +49,9 @@
public class AbandonIT extends AbstractDaemonTest {
@Inject private AbandonUtil abandonUtil;
- @Inject private RequestScopeOperations requestScopeOperations;
@Inject private ChangeCleanupConfig cleanupConfig;
+ @Inject private ProjectOperations projectOperations;
+ @Inject private RequestScopeOperations requestScopeOperations;
@Test
public void abandon() throws Exception {
@@ -59,9 +63,9 @@
assertThat(info.status).isEqualTo(ChangeStatus.ABANDONED);
assertThat(Iterables.getLast(info.messages).message.toLowerCase()).contains("abandoned");
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("change is abandoned");
- gApi.changes().id(changeId).abandon();
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> gApi.changes().id(changeId).abandon());
+ assertThat(thrown).hasMessageThat().contains("change is abandoned");
}
@Test
@@ -96,10 +100,16 @@
PushOneCommit.Result a = createChange(project1, "master", "x", "x", "x", "");
PushOneCommit.Result b = createChange(project2, "master", "x", "x", "x", "");
List<ChangeData> list = ImmutableList.of(a.getChange(), b.getChange());
- exception.expect(ResourceConflictException.class);
- exception.expectMessage(
- String.format("Project name \"%s\" doesn't match \"%s\"", project2Name, project1Name));
- batchAbandon.batchAbandon(batchUpdateFactory, Project.nameKey(project1Name), user, list);
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () ->
+ batchAbandon.batchAbandon(
+ batchUpdateFactory, Project.nameKey(project1Name), user, list));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ String.format("Project name \"%s\" doesn't match \"%s\"", project2Name, project1Name));
}
@Test
@@ -157,9 +167,9 @@
String changeId = r.getChangeId();
assertThat(info(changeId).status).isEqualTo(ChangeStatus.NEW);
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("abandon not permitted");
- gApi.changes().id(changeId).abandon();
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.changes().id(changeId).abandon());
+ assertThat(thrown).hasMessageThat().contains("abandon not permitted");
}
@Test
@@ -167,7 +177,11 @@
PushOneCommit.Result r = createChange();
String changeId = r.getChangeId();
assertThat(info(changeId).status).isEqualTo(ChangeStatus.NEW);
- grant(project, "refs/heads/master", Permission.ABANDON, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.ABANDON).ref("refs/heads/master").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
gApi.changes().id(changeId).abandon();
assertThat(info(changeId).status).isEqualTo(ChangeStatus.ABANDONED);
@@ -188,9 +202,9 @@
assertThat(info.status).isEqualTo(ChangeStatus.NEW);
assertThat(Iterables.getLast(info.messages).message.toLowerCase()).contains("restored");
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("change is new");
- gApi.changes().id(changeId).restore();
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> gApi.changes().id(changeId).restore());
+ assertThat(thrown).hasMessageThat().contains("change is new");
}
@Test
@@ -201,9 +215,9 @@
gApi.changes().id(changeId).abandon();
requestScopeOperations.setApiUser(user.id());
assertThat(info(changeId).status).isEqualTo(ChangeStatus.ABANDONED);
- exception.expect(AuthException.class);
- exception.expectMessage("restore not permitted");
- gApi.changes().id(changeId).restore();
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.changes().id(changeId).restore());
+ assertThat(thrown).hasMessageThat().contains("restore not permitted");
}
private List<Integer> toChangeNumbers(List<ChangeInfo> changes) {
diff --git a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
index 18a7eb2..e427277 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
@@ -22,6 +22,13 @@
import static com.google.gerrit.acceptance.PushOneCommit.FILE_CONTENT;
import static com.google.gerrit.acceptance.PushOneCommit.FILE_NAME;
import static com.google.gerrit.acceptance.PushOneCommit.SUBJECT;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.blockLabel;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.labelPermissionKey;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.permissionKey;
import static com.google.gerrit.extensions.client.ListChangesOption.ALL_REVISIONS;
import static com.google.gerrit.extensions.client.ListChangesOption.CHANGE_ACTIONS;
import static com.google.gerrit.extensions.client.ListChangesOption.CHECK;
@@ -45,8 +52,9 @@
import static com.google.gerrit.server.group.SystemGroupBackend.CHANGE_OWNER;
import static com.google.gerrit.server.group.SystemGroupBackend.PROJECT_OWNERS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
-import static com.google.gerrit.server.project.testing.Util.category;
-import static com.google.gerrit.server.project.testing.Util.value;
+import static com.google.gerrit.server.project.testing.TestLabels.label;
+import static com.google.gerrit.server.project.testing.TestLabels.value;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.stream.Collectors.joining;
@@ -97,7 +105,6 @@
import com.google.gerrit.extensions.api.projects.BranchApi;
import com.google.gerrit.extensions.api.projects.BranchInput;
import com.google.gerrit.extensions.api.projects.ConfigInput;
-import com.google.gerrit.extensions.api.projects.ProjectApi;
import com.google.gerrit.extensions.api.projects.ProjectInput;
import com.google.gerrit.extensions.client.ChangeKind;
import com.google.gerrit.extensions.client.ChangeStatus;
@@ -149,7 +156,7 @@
import com.google.gerrit.server.index.change.ChangeIndex;
import com.google.gerrit.server.index.change.ChangeIndexCollection;
import com.google.gerrit.server.index.change.IndexedChangeQuery;
-import com.google.gerrit.server.project.testing.Util;
+import com.google.gerrit.server.project.testing.TestLabels;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.ChangeQueryBuilder.ChangeOperatorFactory;
import com.google.gerrit.server.restapi.change.PostReview;
@@ -276,9 +283,9 @@
String changeId = rwip.getChangeId();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("toggle work in progress state not permitted");
- gApi.changes().id(changeId).setWorkInProgress();
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.changes().id(changeId).setWorkInProgress());
+ assertThat(thrown).hasMessageThat().contains("toggle work in progress state not permitted");
}
@Test
@@ -299,7 +306,11 @@
gApi.changes().create(new ChangeInput(project.get(), "master", "Test Change")).get().id;
com.google.gerrit.acceptance.TestAccount user2 = accountCreator.user2();
- grant(project, "refs/*", Permission.OWNER, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.OWNER).ref("refs/*").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user2.id());
gApi.changes().id(changeId).setWorkInProgress();
assertThat(gApi.changes().id(changeId).get().workInProgress).isTrue();
@@ -322,9 +333,9 @@
gApi.changes().id(changeId).setWorkInProgress();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("toggle work in progress state not permitted");
- gApi.changes().id(changeId).setReadyForReview();
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.changes().id(changeId).setReadyForReview());
+ assertThat(thrown).hasMessageThat().contains("toggle work in progress state not permitted");
}
@Test
@@ -347,7 +358,11 @@
gApi.changes().id(changeId).setWorkInProgress();
com.google.gerrit.acceptance.TestAccount user2 = accountCreator.user2();
- grant(project, "refs/*", Permission.OWNER, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.OWNER).ref("refs/*").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user2.id());
gApi.changes().id(changeId).setReadyForReview();
assertThat(gApi.changes().id(changeId).get().workInProgress).isNull();
@@ -506,12 +521,14 @@
String refactor = "Needs some refactoring";
String ptal = "PTAL";
- grant(
- project,
- "refs/heads/master",
- Permission.TOGGLE_WORK_IN_PROGRESS_STATE,
- false,
- REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(
+ allow(Permission.TOGGLE_WORK_IN_PROGRESS_STATE)
+ .ref("refs/heads/master")
+ .group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
gApi.changes().id(changeId).setWorkInProgress(refactor);
@@ -621,21 +638,24 @@
PushOneCommit.Result r = createChange();
ReviewInput in = ReviewInput.noScore().setWorkInProgress(true);
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("toggle work in progress state not permitted");
- gApi.changes().id(r.getChangeId()).current().review(in);
+ AuthException thrown =
+ assertThrows(
+ AuthException.class, () -> gApi.changes().id(r.getChangeId()).current().review(in));
+ assertThat(thrown).hasMessageThat().contains("toggle work in progress state not permitted");
}
@Test
public void reviewWithWorkInProgressByNonOwnerWithPermission() throws Exception {
PushOneCommit.Result r = createChange();
ReviewInput in = ReviewInput.noScore().setWorkInProgress(true);
- grant(
- project,
- "refs/heads/master",
- Permission.TOGGLE_WORK_IN_PROGRESS_STATE,
- false,
- REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(
+ allow(Permission.TOGGLE_WORK_IN_PROGRESS_STATE)
+ .ref("refs/heads/master")
+ .group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
gApi.changes().id(r.getChangeId()).current().review(in);
ChangeInfo info = gApi.changes().id(r.getChangeId()).get();
@@ -647,9 +667,10 @@
PushOneCommit.Result r = createChange();
ReviewInput in = ReviewInput.noScore().setReady(true);
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("toggle work in progress state not permitted");
- gApi.changes().id(r.getChangeId()).current().review(in);
+ AuthException thrown =
+ assertThrows(
+ AuthException.class, () -> gApi.changes().id(r.getChangeId()).current().review(in));
+ assertThat(thrown).hasMessageThat().contains("toggle work in progress state not permitted");
}
@Test
@@ -673,9 +694,9 @@
PushOneCommit.Result r2 = push2.to("refs/for/other");
assertThat(r2.getChangeId()).isEqualTo(changeId);
- exception.expect(ResourceNotFoundException.class);
- exception.expectMessage("Multiple changes found for " + changeId);
- gApi.changes().id(changeId).get();
+ ResourceNotFoundException thrown =
+ assertThrows(ResourceNotFoundException.class, () -> gApi.changes().id(changeId).get());
+ assertThat(thrown).hasMessageThat().contains("Multiple changes found for " + changeId);
}
@Test
@@ -769,9 +790,10 @@
gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).review(ReviewInput.approve());
gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).submit();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Cannot revert initial commit");
- gApi.changes().id(r.getChangeId()).revert();
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class, () -> gApi.changes().id(r.getChangeId()).revert());
+ assertThat(thrown).hasMessageThat().contains("Cannot revert initial commit");
}
@FunctionalInterface
@@ -826,9 +848,10 @@
assertThat(cr.all.get(0).value).isEqualTo(1);
// Rebasing the second change again should fail
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Change is already up to date");
- gApi.changes().id(changeId).current().rebase();
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class, () -> gApi.changes().id(changeId).current().rebase());
+ assertThat(thrown).hasMessageThat().contains("Change is already up to date");
}
@Test
@@ -931,9 +954,9 @@
// Rebase the second
String changeId = r2.getChangeId();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("rebase not permitted");
- gApi.changes().id(changeId).rebase();
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.changes().id(changeId).rebase());
+ assertThat(thrown).hasMessageThat().contains("rebase not permitted");
}
@Test
@@ -948,7 +971,11 @@
revision.review(ReviewInput.approve());
revision.submit();
- grant(project, "refs/heads/master", Permission.REBASE, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.REBASE).ref("refs/heads/master").group(REGISTERED_USERS))
+ .update();
// Rebase the second
String changeId = r2.getChangeId();
@@ -968,15 +995,19 @@
revision.review(ReviewInput.approve());
revision.submit();
- grant(project, "refs/heads/master", Permission.REBASE, false, REGISTERED_USERS);
- block("refs/for/*", Permission.PUSH, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.REBASE).ref("refs/heads/master").group(REGISTERED_USERS))
+ .add(block(Permission.PUSH).ref("refs/for/*").group(REGISTERED_USERS))
+ .update();
// Rebase the second
String changeId = r2.getChangeId();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("rebase not permitted");
- gApi.changes().id(changeId).rebase();
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.changes().id(changeId).rebase());
+ assertThat(thrown).hasMessageThat().contains("rebase not permitted");
}
@Test
@@ -991,13 +1022,17 @@
revision.review(ReviewInput.approve());
revision.submit();
- block("refs/for/*", Permission.PUSH, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.PUSH).ref("refs/for/*").group(REGISTERED_USERS))
+ .update();
// Rebase the second
String changeId = r2.getChangeId();
- exception.expect(AuthException.class);
- exception.expectMessage("rebase not permitted");
- gApi.changes().id(changeId).rebase();
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.changes().id(changeId).rebase());
+ assertThat(thrown).hasMessageThat().contains("rebase not permitted");
}
@Test
@@ -1013,14 +1048,18 @@
String changeId = changeResult.getChangeId();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("delete not permitted");
- gApi.changes().id(changeId).delete();
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.changes().id(changeId).delete());
+ assertThat(thrown).hasMessageThat().contains("delete not permitted");
}
@Test
public void deleteNewChangeAsUserWithDeleteChangesPermissionForGroup() throws Exception {
- allow("refs/*", Permission.DELETE_CHANGES, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.DELETE_CHANGES).ref("refs/*").group(REGISTERED_USERS))
+ .update();
deleteChangeAsUser(admin, user);
}
@@ -1029,32 +1068,40 @@
GroupApi groupApi = gApi.groups().create(name("delete-change"));
groupApi.addMembers("user");
+ Project.NameKey nameKey = Project.nameKey(name("delete-change"));
ProjectInput in = new ProjectInput();
- in.name = name("delete-change");
+ in.name = nameKey.get();
in.owners = Lists.newArrayListWithCapacity(1);
in.owners.add(groupApi.name());
in.createEmptyCommit = true;
- ProjectApi api = gApi.projects().create(in);
+ gApi.projects().create(in);
- Project.NameKey nameKey = Project.nameKey(api.get().name);
-
- try (ProjectConfigUpdate u = updateProject(nameKey)) {
- Util.allow(u.getConfig(), Permission.DELETE_CHANGES, PROJECT_OWNERS, "refs/*");
- u.save();
- }
+ projectOperations
+ .project(nameKey)
+ .forUpdate()
+ .add(allow(Permission.DELETE_CHANGES).ref("refs/*").group(PROJECT_OWNERS))
+ .update();
deleteChangeAsUser(nameKey, admin, user);
}
@Test
public void deleteChangeAsUserWithDeleteOwnChangesPermissionForGroup() throws Exception {
- allow("refs/*", Permission.DELETE_OWN_CHANGES, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.DELETE_OWN_CHANGES).ref("refs/*").group(REGISTERED_USERS))
+ .update();
deleteChangeAsUser(user, user);
}
@Test
public void deleteChangeAsUserWithDeleteOwnChangesPermissionForOwners() throws Exception {
- allow("refs/*", Permission.DELETE_OWN_CHANGES, CHANGE_OWNER);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.DELETE_OWN_CHANGES).ref("refs/*").group(CHANGE_OWNER))
+ .update();
deleteChangeAsUser(user, user);
}
@@ -1092,8 +1139,12 @@
eventRecorder.assertRefUpdatedEvents(projectName.get(), ref, null, commit, commit, null);
eventRecorder.assertChangeDeletedEvents(changeId, deleteAs.email());
} finally {
- removePermission(project, "refs/*", Permission.DELETE_OWN_CHANGES);
- removePermission(project, "refs/*", Permission.DELETE_CHANGES);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .remove(permissionKey(Permission.DELETE_OWN_CHANGES).ref("refs/*"))
+ .remove(permissionKey(Permission.DELETE_CHANGES).ref("refs/*"))
+ .update();
}
}
@@ -1104,18 +1155,26 @@
@Test
public void deleteNewChangeOfAnotherUserWithDeleteOwnChangesPermission() throws Exception {
- allow("refs/*", Permission.DELETE_OWN_CHANGES, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.DELETE_OWN_CHANGES).ref("refs/*").group(REGISTERED_USERS))
+ .update();
try {
PushOneCommit.Result changeResult = createChange();
String changeId = changeResult.getChangeId();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("delete not permitted");
- gApi.changes().id(changeId).delete();
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.changes().id(changeId).delete());
+ assertThat(thrown).hasMessageThat().contains("delete not permitted");
} finally {
- removePermission(project, "refs/*", Permission.DELETE_OWN_CHANGES);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .remove(permissionKey(Permission.DELETE_OWN_CHANGES).ref("refs/*"))
+ .update();
}
}
@@ -1140,9 +1199,9 @@
requestScopeOperations.setApiUser(user.id());
gApi.changes().id(changeId).abandon();
- exception.expect(AuthException.class);
- exception.expectMessage("delete not permitted");
- gApi.changes().id(changeId).delete();
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.changes().id(changeId).delete());
+ assertThat(thrown).hasMessageThat().contains("delete not permitted");
}
@Test
@@ -1166,15 +1225,19 @@
merge(changeResult);
- exception.expect(MethodNotAllowedException.class);
- exception.expectMessage("delete not permitted");
- gApi.changes().id(changeId).delete();
+ MethodNotAllowedException thrown =
+ assertThrows(MethodNotAllowedException.class, () -> gApi.changes().id(changeId).delete());
+ assertThat(thrown).hasMessageThat().contains("delete not permitted");
}
@Test
@TestProjectInput(cloneAs = "user")
public void deleteMergedChangeWithDeleteOwnChangesPermission() throws Exception {
- allow("refs/*", Permission.DELETE_OWN_CHANGES, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.DELETE_OWN_CHANGES).ref("refs/*").group(REGISTERED_USERS))
+ .update();
try {
PushOneCommit.Result changeResult =
@@ -1184,11 +1247,15 @@
merge(changeResult);
requestScopeOperations.setApiUser(user.id());
- exception.expect(MethodNotAllowedException.class);
- exception.expectMessage("delete not permitted");
- gApi.changes().id(changeId).delete();
+ MethodNotAllowedException thrown =
+ assertThrows(MethodNotAllowedException.class, () -> gApi.changes().id(changeId).delete());
+ assertThat(thrown).hasMessageThat().contains("delete not permitted");
} finally {
- removePermission(project, "refs/*", Permission.DELETE_OWN_CHANGES);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .remove(permissionKey(Permission.DELETE_OWN_CHANGES).ref("refs/*"))
+ .update();
}
}
@@ -1201,10 +1268,11 @@
merge(changeResult);
setChangeStatus(id, Change.Status.NEW);
- exception.expect(ResourceConflictException.class);
- exception.expectMessage(
- String.format("Cannot delete change %s: patch set 1 is already merged", id));
- gApi.changes().id(changeId).delete();
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> gApi.changes().id(changeId).delete());
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(String.format("Cannot delete change %s: patch set 1 is already merged", id));
}
@Test
@@ -1255,16 +1323,21 @@
@Test
public void rebaseUpToDateChange() throws Exception {
PushOneCommit.Result r = createChange();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Change is already up to date");
- gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).rebase();
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).rebase());
+ assertThat(thrown).hasMessageThat().contains("Change is already up to date");
}
@Test
public void rebaseConflict() throws Exception {
- PushOneCommit.Result r = createChange();
- gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).review(ReviewInput.approve());
- gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).submit();
+ PushOneCommit.Result r1 = createChange();
+ gApi.changes()
+ .id(r1.getChangeId())
+ .revision(r1.getCommit().name())
+ .review(ReviewInput.approve());
+ gApi.changes().id(r1.getChangeId()).revision(r1.getCommit().name()).submit();
PushOneCommit push =
pushFactory.create(
@@ -1274,11 +1347,11 @@
PushOneCommit.FILE_NAME,
"other content",
"If09d8782c1e59dd0b33de2b1ec3595d69cc10ad5");
- r = push.to("refs/for/master");
- r.assertOkStatus();
-
- exception.expect(ResourceConflictException.class);
- gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).rebase();
+ PushOneCommit.Result r2 = push.to("refs/for/master");
+ r2.assertOkStatus();
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(r2.getChangeId()).revision(r2.getCommit().name()).rebase());
}
@Test
@@ -1292,23 +1365,23 @@
ri.base = "";
gApi.changes().id(r3.getChangeId()).revision(r3.getCommit().name()).rebase(ri);
PatchSet ps3 = r3.getPatchSet();
- assertThat(ps3.getId().get()).isEqualTo(2);
+ assertThat(ps3.id().get()).isEqualTo(2);
// rebase r2 onto r3 (referenced by ref)
- ri.base = ps3.getId().toRefName();
+ ri.base = ps3.id().toRefName();
gApi.changes().id(r2.getChangeId()).revision(r2.getCommit().name()).rebase(ri);
PatchSet ps2 = r2.getPatchSet();
- assertThat(ps2.getId().get()).isEqualTo(2);
+ assertThat(ps2.id().get()).isEqualTo(2);
// rebase r1 onto r2 (referenced by commit)
- ri.base = ps2.getCommitId().name();
+ ri.base = ps2.commitId().name();
gApi.changes().id(r1.getChangeId()).revision(r1.getCommit().name()).rebase(ri);
PatchSet ps1 = r1.getPatchSet();
- assertThat(ps1.getId().get()).isEqualTo(2);
+ assertThat(ps1.id().get()).isEqualTo(2);
// rebase r1 onto r3 (referenced by change number)
ri.base = String.valueOf(r3.getChange().getId().get());
- gApi.changes().id(r1.getChangeId()).revision(ps1.getCommitId().name()).rebase(ri);
+ gApi.changes().id(r1.getChangeId()).revision(ps1.commitId().name()).rebase(ri);
assertThat(r1.getPatchSetId().get()).isEqualTo(3);
}
@@ -1323,9 +1396,11 @@
"base change "
+ r2.getChangeId()
+ " is a descendant of the current change - recursion not allowed";
- exception.expect(ResourceConflictException.class);
- exception.expectMessage(expectedMessage);
- gApi.changes().id(r1.getChangeId()).revision(r1.getCommit().name()).rebase(ri);
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(r1.getChangeId()).revision(r1.getCommit().name()).rebase(ri));
+ assertThat(thrown).hasMessageThat().contains(expectedMessage);
}
@Test
@@ -1337,9 +1412,11 @@
ChangeInfo info = info(changeId);
assertThat(info.status).isEqualTo(ChangeStatus.ABANDONED);
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("change is abandoned");
- gApi.changes().id(changeId).revision(r.getCommit().name()).rebase();
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(changeId).revision(r.getCommit().name()).rebase());
+ assertThat(thrown).hasMessageThat().contains("change is abandoned");
}
@Test
@@ -1359,9 +1436,11 @@
RebaseInput ri = new RebaseInput();
ri.base = r.getCommit().name();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("base change is abandoned: " + changeId);
- gApi.changes().id(r2.getChangeId()).revision(r2.getCommit().name()).rebase(ri);
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(r2.getChangeId()).revision(r2.getCommit().name()).rebase(ri));
+ assertThat(thrown).hasMessageThat().contains("base change is abandoned: " + changeId);
}
@Test
@@ -1371,9 +1450,11 @@
String commit = r.getCommit().name();
RebaseInput ri = new RebaseInput();
ri.base = commit;
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("cannot rebase change onto itself");
- gApi.changes().id(changeId).revision(commit).rebase(ri);
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(changeId).revision(commit).rebase(ri));
+ assertThat(thrown).hasMessageThat().contains("cannot rebase change onto itself");
}
@Test
@@ -1455,11 +1536,12 @@
public void pushCommitOfOtherUserThatCannotSeeChange() throws Exception {
// create hidden project that is only visible to administrators
Project.NameKey p = projectOperations.newProject().create();
- try (ProjectConfigUpdate u = updateProject(p)) {
- Util.allow(u.getConfig(), Permission.READ, adminGroupUuid(), "refs/*");
- Util.block(u.getConfig(), Permission.READ, REGISTERED_USERS, "refs/*");
- u.save();
- }
+ projectOperations
+ .project(p)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/*").group(adminGroupUuid()))
+ .add(block(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
// admin pushes commit of user
TestRepository<InMemoryRepository> repo = cloneProject(p, admin);
@@ -1475,12 +1557,8 @@
// check the user cannot see the change
requestScopeOperations.setApiUser(user.id());
- try {
- gApi.changes().id(result.getChangeId()).get();
- fail("Expected ResourceNotFoundException");
- } catch (ResourceNotFoundException e) {
- // Expected.
- }
+ assertThrows(
+ ResourceNotFoundException.class, () -> gApi.changes().id(result.getChangeId()).get());
// check that the author/committer was NOT added as reviewer (he can't see
// the change)
@@ -1528,11 +1606,12 @@
public void pushCommitWithFooterOfOtherUserThatCannotSeeChange() throws Exception {
// create hidden project that is only visible to administrators
Project.NameKey p = projectOperations.newProject().create();
- try (ProjectConfigUpdate u = updateProject(p)) {
- Util.allow(u.getConfig(), Permission.READ, adminGroupUuid(), "refs/*");
- Util.block(u.getConfig(), Permission.READ, REGISTERED_USERS, "refs/*");
- u.save();
- }
+ projectOperations
+ .project(p)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/*").group(adminGroupUuid()))
+ .add(block(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
// admin pushes commit that references 'user' in a footer
TestRepository<InMemoryRepository> repo = cloneProject(p, admin);
@@ -1552,12 +1631,8 @@
// check that 'user' cannot see the change
requestScopeOperations.setApiUser(user.id());
- try {
- gApi.changes().id(result.getChangeId()).get();
- fail("Expected ResourceNotFoundException");
- } catch (ResourceNotFoundException e) {
- // Expected.
- }
+ assertThrows(
+ ResourceNotFoundException.class, () -> gApi.changes().id(result.getChangeId()).get());
// check that 'user' was NOT added as cc ('user' can't see the change)
requestScopeOperations.setApiUser(admin.id());
@@ -1571,11 +1646,12 @@
public void addReviewerThatCannotSeeChange() throws Exception {
// create hidden project that is only visible to administrators
Project.NameKey p = projectOperations.newProject().create();
- try (ProjectConfigUpdate u = updateProject(p)) {
- Util.allow(u.getConfig(), Permission.READ, adminGroupUuid(), "refs/*");
- Util.block(u.getConfig(), Permission.READ, REGISTERED_USERS, "refs/*");
- u.save();
- }
+ projectOperations
+ .project(p)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/*").group(adminGroupUuid()))
+ .add(block(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
// create change
TestRepository<InMemoryRepository> repo = cloneProject(p, admin);
@@ -1585,12 +1661,8 @@
// check the user cannot see the change
requestScopeOperations.setApiUser(user.id());
- try {
- gApi.changes().id(result.getChangeId()).get();
- fail("Expected ResourceNotFoundException");
- } catch (ResourceNotFoundException e) {
- // Expected.
- }
+ assertThrows(
+ ResourceNotFoundException.class, () -> gApi.changes().id(result.getChangeId()).get());
// try to add user as reviewer
requestScopeOperations.setApiUser(admin.id());
@@ -2056,8 +2128,8 @@
comment.message = "comment 1";
review.comments = ImmutableMap.of(comment.path, Lists.newArrayList(comment));
- exception.expect(BadRequestException.class);
- gApi.changes().id(changeId).current().review(review);
+ assertThrows(
+ BadRequestException.class, () -> gApi.changes().id(changeId).current().review(review));
}
@Test
@@ -2082,21 +2154,21 @@
@Test
public void removeReviewerNoVotes() throws Exception {
+ LabelType verified =
+ label("Verified", value(1, "Passes"), value(0, "No score"), value(-1, "Failed"));
try (ProjectConfigUpdate u = updateProject(project)) {
- LabelType verified =
- category("Verified", value(1, "Passes"), value(0, "No score"), value(-1, "Failed"));
u.getConfig().getLabelSections().put(verified.getName(), verified);
- AccountGroup.UUID registeredUsers = systemGroupBackend.getGroup(REGISTERED_USERS).getUUID();
- String heads = RefNames.REFS_HEADS + "*";
- Util.allow(
- u.getConfig(),
- Permission.forLabel(Util.verified().getName()),
- -1,
- 1,
- registeredUsers,
- heads);
u.save();
}
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(
+ allowLabel(verified.getName())
+ .ref(RefNames.REFS_HEADS + "*")
+ .group(REGISTERED_USERS)
+ .range(-1, 1))
+ .update();
PushOneCommit.Result r = createChange();
String changeId = r.getChangeId();
@@ -2124,8 +2196,9 @@
// Remove again, and then try to remove once more to verify 404 is
// returned.
gApi.changes().id(changeId).reviewer(user.id().toString()).remove();
- exception.expect(ResourceNotFoundException.class);
- gApi.changes().id(changeId).reviewer(user.id().toString()).remove();
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.changes().id(changeId).reviewer(user.id().toString()).remove());
}
@Test
@@ -2186,9 +2259,11 @@
gApi.changes().id(changeId).revision(r.getCommit().name()).review(ReviewInput.approve());
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("remove reviewer not permitted");
- gApi.changes().id(r.getChangeId()).reviewer(admin.id().toString()).remove();
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () -> gApi.changes().id(r.getChangeId()).reviewer(admin.id().toString()).remove());
+ assertThat(thrown).hasMessageThat().contains("remove reviewer not permitted");
}
@Test
@@ -2204,9 +2279,11 @@
gApi.changes().id(changeId).revision(r.getCommit().name()).submit();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("remove reviewer not permitted");
- gApi.changes().id(r.getChangeId()).reviewer("self").remove();
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () -> gApi.changes().id(r.getChangeId()).reviewer("self").remove());
+ assertThat(thrown).hasMessageThat().contains("remove reviewer not permitted");
}
@Test
@@ -2238,9 +2315,11 @@
gApi.changes().id(changeId).abandon();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("remove reviewer not permitted");
- gApi.changes().id(r.getChangeId()).reviewer(admin.id().toString()).remove();
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () -> gApi.changes().id(r.getChangeId()).reviewer(admin.id().toString()).remove());
+ assertThat(thrown).hasMessageThat().contains("remove reviewer not permitted");
}
@Test
@@ -2348,24 +2427,32 @@
gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).review(ReviewInput.approve());
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("delete vote not permitted");
- gApi.changes().id(r.getChangeId()).reviewer(admin.id().toString()).deleteVote("Code-Review");
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () ->
+ gApi.changes()
+ .id(r.getChangeId())
+ .reviewer(admin.id().toString())
+ .deleteVote("Code-Review"));
+ assertThat(thrown).hasMessageThat().contains("delete vote not permitted");
}
@Test
public void nonVotingReviewerStaysAfterSubmit() throws Exception {
LabelType verified =
- category("Verified", value(1, "Passes"), value(0, "No score"), value(-1, "Failed"));
+ label("Verified", value(1, "Passes"), value(0, "No score"), value(-1, "Failed"));
+ String heads = "refs/heads/*";
try (ProjectConfigUpdate u = updateProject(project)) {
u.getConfig().getLabelSections().put(verified.getName(), verified);
- String heads = "refs/heads/*";
- AccountGroup.UUID owners = systemGroupBackend.getGroup(CHANGE_OWNER).getUUID();
- AccountGroup.UUID registered = systemGroupBackend.getGroup(REGISTERED_USERS).getUUID();
- Util.allow(u.getConfig(), Permission.forLabel(verified.getName()), -1, 1, owners, heads);
- Util.allow(u.getConfig(), Permission.forLabel("Code-Review"), -2, +2, registered, heads);
u.save();
}
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allowLabel(verified.getName()).ref(heads).group(CHANGE_OWNER).range(-1, 1))
+ .add(allowLabel("Code-Review").ref(heads).group(REGISTERED_USERS).range(-2, +2))
+ .update();
// Set Code-Review+2 and Verified+1 as admin (change owner)
PushOneCommit.Result r = createChange();
@@ -2461,8 +2548,13 @@
@Test
public void queryChangesNoLimit() throws Exception {
- allowGlobalCapabilities(
- SystemGroupBackend.REGISTERED_USERS, 0, 2, GlobalCapability.QUERY_LIMIT);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(
+ allowCapability(GlobalCapability.QUERY_LIMIT)
+ .group(SystemGroupBackend.REGISTERED_USERS)
+ .range(0, 2))
+ .update();
for (int i = 0; i < 3; i++) {
createChange();
}
@@ -2600,16 +2692,21 @@
PushOneCommit.Result r = createChange();
assertThat(gApi.changes().id(r.getChangeId()).topic()).isEqualTo("");
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("edit topic name not permitted");
- gApi.changes().id(r.getChangeId()).topic("mytopic");
+ AuthException thrown =
+ assertThrows(
+ AuthException.class, () -> gApi.changes().id(r.getChangeId()).topic("mytopic"));
+ assertThat(thrown).hasMessageThat().contains("edit topic name not permitted");
}
@Test
public void editTopicWithPermissionAllowed() throws Exception {
PushOneCommit.Result r = createChange();
assertThat(gApi.changes().id(r.getChangeId()).topic()).isEqualTo("");
- grant(project, "refs/heads/master", Permission.EDIT_TOPIC_NAME, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.EDIT_TOPIC_NAME).ref("refs/heads/master").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
gApi.changes().id(r.getChangeId()).topic("mytopic");
assertThat(gApi.changes().id(r.getChangeId()).topic()).isEqualTo("mytopic");
@@ -2655,16 +2752,22 @@
PushOneCommit.Result r = createChange();
gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).review(ReviewInput.approve());
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("submit not permitted");
- gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).submit();
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () -> gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).submit());
+ assertThat(thrown).hasMessageThat().contains("submit not permitted");
}
@Test
public void submitAllowedWithPermission() throws Exception {
PushOneCommit.Result r = createChange();
gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).review(ReviewInput.approve());
- grant(project, "refs/heads/master", Permission.SUBMIT, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.SUBMIT).ref("refs/heads/master").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).submit();
assertThat(gApi.changes().id(r.getChangeId()).info().status).isEqualTo(ChangeStatus.MERGED);
@@ -2680,22 +2783,24 @@
@Test
public void commitFooters() throws Exception {
LabelType verified =
- category("Verified", value(1, "Passes"), value(0, "No score"), value(-1, "Failed"));
+ label("Verified", value(1, "Passes"), value(0, "No score"), value(-1, "Failed"));
LabelType custom1 =
- category("Custom1", value(1, "Positive"), value(0, "No score"), value(-1, "Negative"));
+ label("Custom1", value(1, "Positive"), value(0, "No score"), value(-1, "Negative"));
LabelType custom2 =
- category("Custom2", value(1, "Positive"), value(0, "No score"), value(-1, "Negative"));
+ label("Custom2", value(1, "Positive"), value(0, "No score"), value(-1, "Negative"));
try (ProjectConfigUpdate u = updateProject(project)) {
u.getConfig().getLabelSections().put(verified.getName(), verified);
u.getConfig().getLabelSections().put(custom1.getName(), custom1);
u.getConfig().getLabelSections().put(custom2.getName(), custom2);
- String heads = "refs/heads/*";
- AccountGroup.UUID anon = systemGroupBackend.getGroup(ANONYMOUS_USERS).getUUID();
- Util.allow(u.getConfig(), Permission.forLabel("Verified"), -1, 1, anon, heads);
- Util.allow(u.getConfig(), Permission.forLabel("Custom1"), -1, 1, anon, heads);
- Util.allow(u.getConfig(), Permission.forLabel("Custom2"), -1, 1, anon, heads);
u.save();
}
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allowLabel(verified.getName()).ref("refs/heads/*").group(ANONYMOUS_USERS).range(-1, 1))
+ .add(allowLabel(custom1.getName()).ref("refs/heads/*").group(ANONYMOUS_USERS).range(-1, 1))
+ .add(allowLabel(custom2.getName()).ref("refs/heads/*").group(ANONYMOUS_USERS).range(-1, 1))
+ .update();
PushOneCommit.Result r1 = createChange();
r1.assertOkStatus();
@@ -2818,10 +2923,11 @@
assertThat(approval._accountId).isEqualTo(user.id().get());
assertThat(approval.value).isEqualTo(0);
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.blockLabel(u.getConfig(), "Code-Review", REGISTERED_USERS, "refs/heads/*");
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(blockLabel("Code-Review").ref("refs/heads/*").group(REGISTERED_USERS).range(-1, 1))
+ .update();
c = gApi.changes().id(triplet).get(DETAILED_LABELS);
codeReview = c.labels.get("Code-Review");
@@ -2867,9 +2973,9 @@
info = gApi.changes().id(info._number).get();
assertThat(info.changeId).isEqualTo(r.getChangeId());
-
- exception.expect(AuthException.class);
- gApi.changes().id(triplet).current().review(ReviewInput.approve());
+ assertThrows(
+ AuthException.class,
+ () -> gApi.changes().id(triplet).current().review(ReviewInput.approve()));
}
@Test
@@ -2926,8 +3032,7 @@
in.project = project.get();
in.newBranch = true;
- exception.expect(ResourceConflictException.class);
- gApi.changes().create(in).get();
+ assertThrows(ResourceConflictException.class, () -> gApi.changes().create(in).get());
}
@Test
@@ -2940,7 +3045,11 @@
TestRepository<InMemoryRepository> userTestRepo = cloneProject(p, user);
// Block default permission
- block(p, "refs/for/*", Permission.ADD_PATCH_SET, REGISTERED_USERS);
+ projectOperations
+ .project(p)
+ .forUpdate()
+ .add(block(Permission.ADD_PATCH_SET).ref("refs/for/*").group(REGISTERED_USERS))
+ .update();
// Create change as admin
PushOneCommit push = pushFactory.create(admin.newIdent(), adminTestRepo);
@@ -2948,7 +3057,7 @@
r1.assertOkStatus();
// Fetch change
- GitUtil.fetch(userTestRepo, r1.getPatchSet().getRefName() + ":ps");
+ GitUtil.fetch(userTestRepo, r1.getPatchSet().refName() + ":ps");
userTestRepo.reset("ps");
// Amend change as user
@@ -2968,7 +3077,7 @@
r1.assertOkStatus();
// Fetch change
- GitUtil.fetch(userTestRepo, r1.getPatchSet().getRefName() + ":ps");
+ GitUtil.fetch(userTestRepo, r1.getPatchSet().refName() + ":ps");
userTestRepo.reset("ps");
// Amend change as user
@@ -2984,7 +3093,11 @@
TestRepository<?> adminTestRepo = cloneProject(project, admin);
// Block default permission
- block(p, "refs/for/*", Permission.ADD_PATCH_SET, REGISTERED_USERS);
+ projectOperations
+ .project(p)
+ .forUpdate()
+ .add(block(Permission.ADD_PATCH_SET).ref("refs/for/*").group(REGISTERED_USERS))
+ .update();
// Create change as admin
PushOneCommit push = pushFactory.create(admin.newIdent(), adminTestRepo);
@@ -2992,7 +3105,7 @@
r1.assertOkStatus();
// Fetch change
- GitUtil.fetch(adminTestRepo, r1.getPatchSet().getRefName() + ":ps");
+ GitUtil.fetch(adminTestRepo, r1.getPatchSet().refName() + ":ps");
adminTestRepo.reset("ps");
// Amend change as admin
@@ -3078,7 +3191,7 @@
@Test
public void createMergePatchSetCannotBaseOnInvisibleChange() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
createBranch("foo");
createBranch("bar");
@@ -3095,14 +3208,19 @@
testRepo.reset(initialHead);
String changeId = createChange().getChangeId();
- exception.expect(UnprocessableEntityException.class);
- exception.expectMessage("Read not permitted for " + baseChange);
- gApi.changes().id(changeId).createMergePatchSet(createMergePatchSetInput(baseChange));
+ UnprocessableEntityException thrown =
+ assertThrows(
+ UnprocessableEntityException.class,
+ () ->
+ gApi.changes()
+ .id(changeId)
+ .createMergePatchSet(createMergePatchSetInput(baseChange)));
+ assertThat(thrown).hasMessageThat().contains("Read not permitted for " + baseChange);
}
@Test
public void createMergePatchSetBaseOnChange() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
createBranch("foo");
createBranch("bar");
@@ -3150,15 +3268,18 @@
// add new label and assert that it's returned for existing changes
AccountGroup.UUID registeredUsers = systemGroupBackend.getGroup(REGISTERED_USERS).getUUID();
- LabelType verified = Util.verified();
+ LabelType verified = TestLabels.verified();
String heads = RefNames.REFS_HEADS + "*";
try (ProjectConfigUpdate u = updateProject(project)) {
u.getConfig().getLabelSections().put(verified.getName(), verified);
- Util.allow(
- u.getConfig(), Permission.forLabel(verified.getName()), -1, 1, registeredUsers, heads);
u.save();
}
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allowLabel(verified.getName()).ref(heads).group(registeredUsers).range(-1, 1))
+ .update();
change = gApi.changes().id(r.getChangeId()).get();
assertThat(change.labels.keySet()).containsExactly("Code-Review", "Verified");
@@ -3176,9 +3297,16 @@
// remove label and assert that it's no longer returned for existing
// changes, even if there is an approval for it
u.getConfig().getLabelSections().remove(verified.getName());
- Util.remove(u.getConfig(), Permission.forLabel(verified.getName()), registeredUsers, heads);
u.save();
}
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .remove(
+ permissionKey(Permission.forLabel(verified.getName()))
+ .ref(heads)
+ .group(registeredUsers))
+ .update();
change = gApi.changes().id(r.getChangeId()).get();
assertThat(change.labels.keySet()).containsExactly("Code-Review");
@@ -3205,17 +3333,20 @@
assertThat(change.permittedLabels.keySet()).containsExactly("Code-Review");
assertPermitted(change, "Code-Review", 2);
- LabelType verified = Util.verified();
+ LabelType verified = TestLabels.verified();
AccountGroup.UUID registeredUsers = systemGroupBackend.getGroup(REGISTERED_USERS).getUUID();
String heads = RefNames.REFS_HEADS + "*";
// add new label and assert that it's returned for existing changes
try (ProjectConfigUpdate u = updateProject(project)) {
u.getConfig().getLabelSections().put(verified.getName(), verified);
- Util.allow(
- u.getConfig(), Permission.forLabel(verified.getName()), -1, 1, registeredUsers, heads);
u.save();
}
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allowLabel(verified.getName()).ref(heads).group(registeredUsers).range(-1, 1))
+ .update();
change = gApi.changes().id(r.getChangeId()).get();
assertThat(change.labels.keySet()).containsExactly("Code-Review", "Verified");
@@ -3257,9 +3388,13 @@
// changes, even if there is an approval for it
try (ProjectConfigUpdate u = updateProject(project)) {
u.getConfig().getLabelSections().remove(verified.getName());
- Util.remove(u.getConfig(), Permission.forLabel(verified.getName()), registeredUsers, heads);
u.save();
}
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .remove(permissionKey(verified.getName()).ref(heads).group(registeredUsers))
+ .update();
change = gApi.changes().id(r.getChangeId()).get();
assertThat(change.labels.keySet()).containsExactly("Code-Review");
@@ -3270,7 +3405,7 @@
@Test
public void checkLabelsForMergedChangeWithNonAuthorCodeReview() throws Exception {
// Configure Non-Author-Code-Review
- RevCommit oldHead = getRemoteHead();
+ RevCommit oldHead = projectOperations.project(project).getHead("master");
GitUtil.fetch(testRepo, RefNames.REFS_CONFIG + ":config");
testRepo.reset("config");
PushOneCommit push2 =
@@ -3295,20 +3430,18 @@
push2.to(RefNames.REFS_CONFIG);
testRepo.reset(oldHead);
- AccountGroup.UUID registeredUsers = systemGroupBackend.getGroup(REGISTERED_USERS).getUUID();
String heads = RefNames.REFS_HEADS + "*";
// Allow user to approve
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.allow(
- u.getConfig(),
- Permission.forLabel(Util.codeReview().getName()),
- -2,
- 2,
- registeredUsers,
- heads);
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(
+ allowLabel(TestLabels.codeReview().getName())
+ .ref(heads)
+ .group(REGISTERED_USERS)
+ .range(-2, 2))
+ .update();
PushOneCommit.Result r = createChange();
@@ -3360,16 +3493,15 @@
assertThat(approval.permittedVotingRange.min).isEqualTo(-1);
assertThat(approval.permittedVotingRange.max).isEqualTo(1);
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.allow(
- u.getConfig(),
- Permission.forLabel("Code-Review"),
- minPermittedValue,
- maxPermittedValue,
- REGISTERED_USERS,
- heads);
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(
+ allowLabel("Code-Review")
+ .ref(heads)
+ .group(REGISTERED_USERS)
+ .range(minPermittedValue, maxPermittedValue))
+ .update();
c = gApi.changes().id(triplet).get(DETAILED_LABELS);
codeReview = c.labels.get("Code-Review");
@@ -3383,10 +3515,11 @@
@Test
public void maxPermittedValueBlocked() throws Exception {
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.blockLabel(u.getConfig(), "Code-Review", REGISTERED_USERS, "refs/heads/*");
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(blockLabel("Code-Review").ref("refs/heads/*").group(REGISTERED_USERS).range(-1, 1))
+ .update();
PushOneCommit.Result r = createChange();
String triplet = project.get() + "~master~" + r.getChangeId();
@@ -3434,9 +3567,10 @@
String changeId = createChange().getChangeId();
ReviewInput in = new ReviewInput().label("Code-Style", 1);
- exception.expect(BadRequestException.class);
- exception.expectMessage("label \"Code-Style\" is not a configured label");
- gApi.changes().id(changeId).current().review(in);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class, () -> gApi.changes().id(changeId).current().review(in));
+ assertThat(thrown).hasMessageThat().contains("label \"Code-Style\" is not a configured label");
}
@Test
@@ -3445,9 +3579,10 @@
String changeId = createChange().getChangeId();
ReviewInput in = new ReviewInput().label("Code-Review", 3);
- exception.expect(BadRequestException.class);
- exception.expectMessage("label \"Code-Review\": 3 is not a valid value");
- gApi.changes().id(changeId).current().review(in);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class, () -> gApi.changes().id(changeId).current().review(in));
+ assertThat(thrown).hasMessageThat().contains("label \"Code-Review\": 3 is not a valid value");
}
@Test
@@ -3463,7 +3598,7 @@
+ "U > 0,"
+ "R = label('All-Comments-Resolved', need(_)). \n\n");
- String oldHead = getRemoteHead().name();
+ String oldHead = projectOperations.project(project).getHead("master").name();
PushOneCommit.Result result1 =
pushFactory.create(user.newIdent(), testRepo).to("refs/for/master");
testRepo.reset(oldHead);
@@ -3475,10 +3610,14 @@
gApi.changes().id(result1.getChangeId()).current().submit();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Failed to submit 1 change due to the following problems");
- exception.expectMessage("needs All-Comments-Resolved");
- gApi.changes().id(result2.getChangeId()).current().submit();
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(result2.getChangeId()).current().submit());
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Failed to submit 1 change due to the following problems");
+ assertThat(thrown).hasMessageThat().contains("needs All-Comments-Resolved");
}
@Test
@@ -3489,10 +3628,14 @@
PushOneCommit.Result r1 = pushFactory.create(user.newIdent(), testRepo).to("refs/for/master");
approve(r1.getChangeId());
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Failed to submit 1 change due to the following problems");
- exception.expectMessage("needs Is-Pure-Revert");
- gApi.changes().id(r1.getChangeId()).current().submit();
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(r1.getChangeId()).current().submit());
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Failed to submit 1 change due to the following problems");
+ assertThat(thrown).hasMessageThat().contains("needs Is-Pure-Revert");
}
@Test
@@ -3507,10 +3650,13 @@
amendChange(revertId);
approve(revertId);
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Failed to submit 1 change due to the following problems");
- exception.expectMessage("needs Is-Pure-Revert");
- gApi.changes().id(revertId).current().submit();
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class, () -> gApi.changes().id(revertId).current().submit());
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Failed to submit 1 change due to the following problems");
+ assertThat(thrown).hasMessageThat().contains("needs Is-Pure-Revert");
}
@Test
@@ -3588,9 +3734,11 @@
PushOneCommit.Result r = createChange();
assertThat(getCommitMessage(r.getChangeId()))
.isEqualTo("test commit\n\nChange-Id: " + r.getChangeId() + "\n");
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("missing Change-Id footer");
- gApi.changes().id(r.getChangeId()).setMessage("modified commit\n");
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(r.getChangeId()).setMessage("modified commit\n"));
+ assertThat(thrown).hasMessageThat().contains("missing Change-Id footer");
}
@Test
@@ -3598,11 +3746,14 @@
PushOneCommit.Result r = createChange();
assertThat(getCommitMessage(r.getChangeId()))
.isEqualTo("test commit\n\nChange-Id: " + r.getChangeId() + "\n");
- exception.expect(BadRequestException.class);
- exception.expectMessage("NUL character");
- gApi.changes()
- .id(r.getChangeId())
- .setMessage("test\0commit\n\nChange-Id: " + r.getChangeId() + "\n");
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () ->
+ gApi.changes()
+ .id(r.getChangeId())
+ .setMessage("test\0commit\n\nChange-Id: " + r.getChangeId() + "\n"));
+ assertThat(thrown).hasMessageThat().contains("NUL character");
}
@Test
@@ -3611,11 +3762,15 @@
PushOneCommit.Result r = createChange();
assertThat(getCommitMessage(r.getChangeId()))
.isEqualTo("test commit\n\nChange-Id: " + r.getChangeId() + "\n");
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("wrong Change-Id footer");
- gApi.changes()
- .id(r.getChangeId())
- .setMessage("modified commit\n\nChange-Id: " + otherChange.getChangeId() + "\n");
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () ->
+ gApi.changes()
+ .id(r.getChangeId())
+ .setMessage(
+ "modified commit\n\nChange-Id: " + otherChange.getChangeId() + "\n"));
+ assertThat(thrown).hasMessageThat().contains("wrong Change-Id footer");
}
@Test
@@ -3624,15 +3779,20 @@
Project.NameKey p = projectOperations.newProject().create();
TestRepository<InMemoryRepository> userTestRepo = cloneProject(p, user);
// Block default permission
- block(p, "refs/for/*", Permission.ADD_PATCH_SET, REGISTERED_USERS);
+ projectOperations
+ .project(p)
+ .forUpdate()
+ .add(block(Permission.ADD_PATCH_SET).ref("refs/for/*").group(REGISTERED_USERS))
+ .update();
// Create change as user
PushOneCommit push = pushFactory.create(user.newIdent(), userTestRepo);
PushOneCommit.Result r = push.to("refs/for/master");
r.assertOkStatus();
// Try to change the commit message
- exception.expect(AuthException.class);
- exception.expectMessage("modifying commit message not permitted");
- gApi.changes().id(r.getChangeId()).setMessage("foo");
+ AuthException thrown =
+ assertThrows(
+ AuthException.class, () -> gApi.changes().id(r.getChangeId()).setMessage("foo"));
+ assertThat(thrown).hasMessageThat().contains("modifying commit message not permitted");
}
@Test
@@ -3640,9 +3800,11 @@
PushOneCommit.Result r = createChange();
assertThat(getCommitMessage(r.getChangeId()))
.isEqualTo("test commit\n\nChange-Id: " + r.getChangeId() + "\n");
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("new and existing commit message are the same");
- gApi.changes().id(r.getChangeId()).setMessage(getCommitMessage(r.getChangeId()));
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(r.getChangeId()).setMessage(getCommitMessage(r.getChangeId())));
+ assertThat(thrown).hasMessageThat().contains("new and existing commit message are the same");
}
@Test
@@ -3692,7 +3854,8 @@
assertThat(
gApi.changes()
.id(revertId)
- .pureRevert(getRemoteHead().toObjectId().name())
+ .pureRevert(
+ projectOperations.project(project).getHead("master").toObjectId().name())
.isPureRevert)
.isTrue();
}
@@ -3715,7 +3878,7 @@
public void pureRevertParameterTakesPrecedence() throws Exception {
PushOneCommit.Result r1 = createChange("commit message", "a.txt", "content1");
merge(r1);
- String oldHead = getRemoteHead().toObjectId().name();
+ String oldHead = projectOperations.project(project).getHead("master").toObjectId().name();
PushOneCommit.Result r2 = createChange("commit message", "a.txt", "content2");
merge(r2);
@@ -3730,9 +3893,11 @@
PushOneCommit.Result r1 = createChange();
merge(r1);
- exception.expect(BadRequestException.class);
- exception.expectMessage("invalid object ID");
- gApi.changes().id(createChange().getChangeId()).pureRevert("invalid id");
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () -> gApi.changes().id(createChange().getChangeId()).pureRevert("invalid id"));
+ assertThat(thrown).hasMessageThat().contains("invalid object ID");
}
@Test
@@ -3756,7 +3921,8 @@
// Create an initial commit to serve as claimed original
PushOneCommit.Result r1 = createChange("commit message", "a.txt", "content1");
merge(r1);
- String claimedOriginal = getRemoteHead().toObjectId().name();
+ String claimedOriginal =
+ projectOperations.project(project).getHead("master").toObjectId().name();
// Change contents of the file to provoke a conflict
merge(createChange("commit message", "a.txt", "content2"));
@@ -3777,9 +3943,11 @@
@Test
public void pureRevertThrowsExceptionWhenChangeIsNotARevertAndNoIdProvided() throws Exception {
- exception.expect(BadRequestException.class);
- exception.expectMessage("revertOf not set");
- gApi.changes().id(createChange().getChangeId()).pureRevert();
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () -> gApi.changes().id(createChange().getChangeId()).pureRevert());
+ assertThat(thrown).hasMessageThat().contains("revertOf not set");
}
@Test
@@ -3787,9 +3955,9 @@
String changeId = createChange().getChangeId();
String topic = Stream.generate(() -> "t").limit(2049).collect(joining());
- exception.expect(BadRequestException.class);
- exception.expectMessage("topic length exceeds the limit");
- gApi.changes().id(changeId).topic(topic);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> gApi.changes().id(changeId).topic(topic));
+ assertThat(thrown).hasMessageThat().contains("topic length exceeds the limit");
}
@Test
@@ -3806,13 +3974,13 @@
public void submittableAfterLosingPermissions(String label) throws Exception {
String codeReviewLabel = "Code-Review";
- AccountGroup.UUID registered = SystemGroupBackend.REGISTERED_USERS;
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.allow(u.getConfig(), Permission.forLabel(label), -1, +1, registered, "refs/heads/*");
- Util.allow(
- u.getConfig(), Permission.forLabel(codeReviewLabel), -2, +2, registered, "refs/heads/*");
- u.save();
- }
+ AccountGroup.UUID registered = REGISTERED_USERS;
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allowLabel(label).ref("refs/heads/*").group(registered).range(-1, +1))
+ .add(allowLabel(codeReviewLabel).ref("refs/heads/*").group(registered).range(-2, +2))
+ .update();
requestScopeOperations.setApiUser(user.id());
PushOneCommit.Result r = createChange();
@@ -3835,15 +4003,13 @@
assertThat(gApi.changes().id(changeId).get().submittable).isTrue();
requestScopeOperations.setApiUser(admin.id());
- // Remove user's permission for 'Label'.
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.remove(u.getConfig(), Permission.forLabel(label), registered, "refs/heads/*");
- // Update user's permitted range for 'Code-Review' to be -1...+1.
- Util.remove(u.getConfig(), Permission.forLabel(codeReviewLabel), registered, "refs/heads/*");
- Util.allow(
- u.getConfig(), Permission.forLabel(codeReviewLabel), -1, +1, registered, "refs/heads/*");
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .remove(labelPermissionKey(label).ref("refs/heads/*").group(registered))
+ .remove(labelPermissionKey(codeReviewLabel).ref("refs/heads/*").group(registered))
+ .add(allowLabel(codeReviewLabel).ref("refs/heads/*").group(registered).range(-1, +1))
+ .update();
// Verify user's new permitted range.
requestScopeOperations.setApiUser(user.id());
@@ -3953,8 +4119,8 @@
}
private void modifySubmitRules(String newContent) throws Exception {
- try (Repository repo = repoManager.openRepository(project)) {
- TestRepository<?> testRepo = new TestRepository<>((InMemoryRepository) repo);
+ try (Repository repo = repoManager.openRepository(project);
+ TestRepository<Repository> testRepo = new TestRepository<>(repo)) {
testRepo
.branch(RefNames.REFS_CONFIG)
.commit()
@@ -4065,9 +4231,9 @@
public void cannotIgnoreOwnChange() throws Exception {
String changeId = createChange().getChangeId();
- exception.expect(BadRequestException.class);
- exception.expectMessage("cannot ignore own change");
- gApi.changes().id(changeId).ignore(true);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> gApi.changes().id(changeId).ignore(true));
+ assertThat(thrown).hasMessageThat().contains("cannot ignore own change");
}
@Test
@@ -4078,14 +4244,17 @@
gApi.accounts().self().starChange(changeId);
assertThat(gApi.changes().id(changeId).get().starred).isTrue();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage(
- "The labels "
- + StarredChangesUtil.DEFAULT_LABEL
- + " and "
- + StarredChangesUtil.IGNORE_LABEL
- + " are mutually exclusive. Only one of them can be set.");
- gApi.changes().id(changeId).ignore(true);
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class, () -> gApi.changes().id(changeId).ignore(true));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ "The labels "
+ + StarredChangesUtil.DEFAULT_LABEL
+ + " and "
+ + StarredChangesUtil.IGNORE_LABEL
+ + " are mutually exclusive. Only one of them can be set.");
}
@Test
@@ -4096,14 +4265,17 @@
gApi.changes().id(changeId).ignore(true);
assertThat(gApi.changes().id(changeId).ignored()).isTrue();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage(
- "The labels "
- + StarredChangesUtil.DEFAULT_LABEL
- + " and "
- + StarredChangesUtil.IGNORE_LABEL
- + " are mutually exclusive. Only one of them can be set.");
- gApi.accounts().self().starChange(changeId);
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class, () -> gApi.accounts().self().starChange(changeId));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ "The labels "
+ + StarredChangesUtil.DEFAULT_LABEL
+ + " and "
+ + StarredChangesUtil.IGNORE_LABEL
+ + " are mutually exclusive. Only one of them can be set.");
}
@Test
@@ -4141,21 +4313,28 @@
gApi.changes().id(changeId).markAsReviewed(true);
assertThat(gApi.changes().id(changeId).get().reviewed).isTrue();
- exception.expect(BadRequestException.class);
- exception.expectMessage(
- "The labels "
- + StarredChangesUtil.REVIEWED_LABEL
- + "/"
- + 1
- + " and "
- + StarredChangesUtil.UNREVIEWED_LABEL
- + "/"
- + 1
- + " are mutually exclusive. Only one of them can be set.");
- gApi.accounts()
- .self()
- .setStars(
- changeId, new StarsInput(ImmutableSet.of(StarredChangesUtil.UNREVIEWED_LABEL + "/1")));
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () ->
+ gApi.accounts()
+ .self()
+ .setStars(
+ changeId,
+ new StarsInput(
+ ImmutableSet.of(StarredChangesUtil.UNREVIEWED_LABEL + "/1"))));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ "The labels "
+ + StarredChangesUtil.REVIEWED_LABEL
+ + "/"
+ + 1
+ + " and "
+ + StarredChangesUtil.UNREVIEWED_LABEL
+ + "/"
+ + 1
+ + " are mutually exclusive. Only one of them can be set.");
}
@Test
@@ -4166,21 +4345,27 @@
gApi.changes().id(changeId).markAsReviewed(false);
assertThat(gApi.changes().id(changeId).get().reviewed).isNull();
- exception.expect(BadRequestException.class);
- exception.expectMessage(
- "The labels "
- + StarredChangesUtil.REVIEWED_LABEL
- + "/"
- + 1
- + " and "
- + StarredChangesUtil.UNREVIEWED_LABEL
- + "/"
- + 1
- + " are mutually exclusive. Only one of them can be set.");
- gApi.accounts()
- .self()
- .setStars(
- changeId, new StarsInput(ImmutableSet.of(StarredChangesUtil.REVIEWED_LABEL + "/1")));
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () ->
+ gApi.accounts()
+ .self()
+ .setStars(
+ changeId,
+ new StarsInput(ImmutableSet.of(StarredChangesUtil.REVIEWED_LABEL + "/1"))));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ "The labels "
+ + StarredChangesUtil.REVIEWED_LABEL
+ + "/"
+ + 1
+ + " and "
+ + StarredChangesUtil.UNREVIEWED_LABEL
+ + "/"
+ + 1
+ + " are mutually exclusive. Only one of them can be set.");
}
@Test
@@ -4209,9 +4394,14 @@
// label cannot contain whitespace
String invalidLabel = "invalid label";
- exception.expect(BadRequestException.class);
- exception.expectMessage("invalid labels: " + invalidLabel);
- gApi.accounts().self().setStars(changeId, new StarsInput(ImmutableSet.of(invalidLabel)));
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () ->
+ gApi.accounts()
+ .self()
+ .setStars(changeId, new StarsInput(ImmutableSet.of(invalidLabel))));
+ assertThat(thrown).hasMessageThat().contains("invalid labels: " + invalidLabel);
}
@Test
diff --git a/javatests/com/google/gerrit/acceptance/api/change/ChangeIdIT.java b/javatests/com/google/gerrit/acceptance/api/change/ChangeIdIT.java
index 7899ecd..789a7c7 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/ChangeIdIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/ChangeIdIT.java
@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance.api.change;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GerritConfig;
@@ -56,16 +57,22 @@
@Test
public void wrongProjectInProjectChangeNumberReturnsNotFound() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- exception.expectMessage("Not found: unknown~" + changeInfo._number);
- gApi.changes().id("unknown", changeInfo._number);
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.changes().id("unknown", changeInfo._number));
+ assertThat(thrown).hasMessageThat().contains("Not found: unknown~" + changeInfo._number);
}
@Test
public void wrongIdInProjectChangeNumberReturnsNotFound() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- exception.expectMessage("Not found: " + project.get() + "~" + Integer.MAX_VALUE);
- gApi.changes().id(project.get(), Integer.MAX_VALUE);
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.changes().id(project.get(), Integer.MAX_VALUE));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Not found: " + project.get() + "~" + Integer.MAX_VALUE);
}
@Test
@@ -76,8 +83,7 @@
@Test
public void wrongChangeNumberReturnsNotFound() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- gApi.changes().id(Integer.MAX_VALUE);
+ assertThrows(ResourceNotFoundException.class, () -> gApi.changes().id(Integer.MAX_VALUE));
}
@Test
@@ -88,25 +94,36 @@
@Test
public void wrongProjectInTripletChangeIdReturnsNotFound() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- exception.expectMessage("Not found: unknown~" + changeInfo.branch + "~" + changeInfo.changeId);
- gApi.changes().id("unknown", changeInfo.branch, changeInfo.changeId);
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.changes().id("unknown", changeInfo.branch, changeInfo.changeId));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Not found: unknown~" + changeInfo.branch + "~" + changeInfo.changeId);
}
@Test
public void wrongBranchInTripletChangeIdReturnsNotFound() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- exception.expectMessage("Not found: " + project.get() + "~unknown~" + changeInfo.changeId);
- gApi.changes().id(project.get(), "unknown", changeInfo.changeId);
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.changes().id(project.get(), "unknown", changeInfo.changeId));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Not found: " + project.get() + "~unknown~" + changeInfo.changeId);
}
@Test
public void wrongIdInTripletChangeIdReturnsNotFound() throws Exception {
String unknownId = "I1234567890";
- exception.expect(ResourceNotFoundException.class);
- exception.expectMessage(
- "Not found: " + project.get() + "~" + changeInfo.branch + "~" + unknownId);
- gApi.changes().id(project.get(), changeInfo.branch, unknownId);
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.changes().id(project.get(), changeInfo.branch, unknownId));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Not found: " + project.get() + "~" + changeInfo.branch + "~" + unknownId);
}
@Test
@@ -121,8 +138,7 @@
@Test
public void wrongChangeIdReturnsNotFound() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- gApi.changes().id("I1234567890");
+ assertThrows(ResourceNotFoundException.class, () -> gApi.changes().id("I1234567890"));
}
@Test
@@ -139,11 +155,13 @@
// IHash throws
ChangeInfo ci =
gApi.changes().create(new ChangeInput(project.get(), "master", "different message")).get();
- exception.expect(DeprecatedIdentifierException.class);
- exception.expectMessage(
- "The provided change identifier "
- + ci.changeId
- + " is deprecated. Use 'project~changeNumber' instead.");
- gApi.changes().id(ci.changeId);
+ DeprecatedIdentifierException thrown =
+ assertThrows(DeprecatedIdentifierException.class, () -> gApi.changes().id(ci.changeId));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ "The provided change identifier "
+ + ci.changeId
+ + " is deprecated. Use 'project~changeNumber' instead.");
}
}
diff --git a/javatests/com/google/gerrit/acceptance/api/change/DisablePrivateChangesIT.java b/javatests/com/google/gerrit/acceptance/api/change/DisablePrivateChangesIT.java
index ae88afd..57d7ece 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/DisablePrivateChangesIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/DisablePrivateChangesIT.java
@@ -15,25 +15,29 @@
package com.google.gerrit.acceptance.api.change;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GerritConfig;
import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.extensions.common.ChangeInput;
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
+import com.google.inject.Inject;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Test;
public class DisablePrivateChangesIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
@Test
@GerritConfig(name = "change.disablePrivateChanges", value = "true")
public void createPrivateChangeWithDisablePrivateChangesTrue() throws Exception {
ChangeInput input = new ChangeInput(project.get(), "master", "empty change");
input.isPrivate = true;
- exception.expect(MethodNotAllowedException.class);
- exception.expectMessage("private changes are disabled");
- gApi.changes().create(input);
+ MethodNotAllowedException thrown =
+ assertThrows(MethodNotAllowedException.class, () -> gApi.changes().create(input));
+ assertThat(thrown).hasMessageThat().contains("private changes are disabled");
}
@Test
@@ -62,7 +66,7 @@
@GerritConfig(name = "change.allowDrafts", value = "true")
@GerritConfig(name = "change.disablePrivateChanges", value = "true")
public void pushDraftsWithDisablePrivateChangesTrue() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result result =
pushFactory.create(admin.newIdent(), testRepo).to("refs/for/master%draft");
result.assertErrorStatus();
@@ -92,7 +96,7 @@
@Test
@GerritConfig(name = "change.allowDrafts", value = "true")
public void pushDraftsWithDisablePrivateChangesFalse() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result result =
pushFactory.create(admin.newIdent(), testRepo).to("refs/for/master%draft");
assertThat(result.getChange().change().isPrivate()).isTrue();
@@ -107,9 +111,11 @@
public void setPrivateWithDisablePrivateChangesTrue() throws Exception {
PushOneCommit.Result result = createChange();
- exception.expect(MethodNotAllowedException.class);
- exception.expectMessage("private changes are disabled");
- gApi.changes().id(result.getChangeId()).setPrivate(true, "set private");
+ MethodNotAllowedException thrown =
+ assertThrows(
+ MethodNotAllowedException.class,
+ () -> gApi.changes().id(result.getChangeId()).setPrivate(true, "set private"));
+ assertThat(thrown).hasMessageThat().contains("private changes are disabled");
}
@Test
diff --git a/javatests/com/google/gerrit/acceptance/api/change/MergeListIT.java b/javatests/com/google/gerrit/acceptance/api/change/MergeListIT.java
index 1b65e92..c5765da 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/MergeListIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/MergeListIT.java
@@ -17,6 +17,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.git.ObjectIds.abbreviateName;
import static com.google.gerrit.reviewdb.client.Patch.MERGE_LIST;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.eclipse.jgit.lib.Constants.HEAD;
@@ -153,18 +154,26 @@
public void editMergeList() throws Exception {
gApi.changes().id(changeId).edit().create();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Invalid path: " + MERGE_LIST);
- gApi.changes().id(changeId).edit().modifyFile(MERGE_LIST, RawInputUtil.create("new content"));
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () ->
+ gApi.changes()
+ .id(changeId)
+ .edit()
+ .modifyFile(MERGE_LIST, RawInputUtil.create("new content")));
+ assertThat(thrown).hasMessageThat().contains("Invalid path: " + MERGE_LIST);
}
@Test
public void deleteMergeList() throws Exception {
gApi.changes().id(changeId).edit().create();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("no changes were made");
- gApi.changes().id(changeId).edit().deleteFile(MERGE_LIST);
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(changeId).edit().deleteFile(MERGE_LIST));
+ assertThat(thrown).hasMessageThat().contains("no changes were made");
}
private String getMergeListContent(RevCommit... commits) {
diff --git a/javatests/com/google/gerrit/acceptance/api/change/PrivateChangeIT.java b/javatests/com/google/gerrit/acceptance/api/change/PrivateChangeIT.java
index a4d944b..59237cb 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/PrivateChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/PrivateChangeIT.java
@@ -15,11 +15,14 @@
package com.google.gerrit.acceptance.api.change;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.Iterables;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.client.ChangeStatus;
@@ -41,6 +44,7 @@
public class PrivateChangeIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Test
@@ -89,9 +93,9 @@
String changeId = result.getChangeId();
assertThat(gApi.changes().id(changeId).get().isPrivate).isNull();
- exception.expect(BadRequestException.class);
- exception.expectMessage("cannot set merged change to private");
- gApi.changes().id(changeId).setPrivate(true);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> gApi.changes().id(changeId).setPrivate(true));
+ assertThat(thrown).hasMessageThat().contains("cannot set merged change to private");
}
@Test
@@ -102,9 +106,9 @@
gApi.changes().id(changeId).abandon();
assertThat(gApi.changes().id(changeId).get().isPrivate).isNull();
- exception.expect(BadRequestException.class);
- exception.expectMessage("cannot set abandoned change to private");
- gApi.changes().id(changeId).setPrivate(true);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> gApi.changes().id(changeId).setPrivate(true));
+ assertThat(thrown).hasMessageThat().contains("cannot set abandoned change to private");
}
@Test
@@ -126,9 +130,11 @@
public void cannotSetOtherUsersChangePrivate() throws Exception {
PushOneCommit.Result result = createChange();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("not allowed to mark private");
- gApi.changes().id(result.getChangeId()).setPrivate(true, null);
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () -> gApi.changes().id(result.getChangeId()).setPrivate(true, null));
+ assertThat(thrown).hasMessageThat().contains("not allowed to mark private");
}
@Test
@@ -153,9 +159,10 @@
gApi.changes().id(result.getChangeId()).reviewer(admin.id().toString()).remove();
// This change should not be visible for admin anymore.
- exception.expect(ResourceNotFoundException.class);
- exception.expectMessage("Not found: " + result.getChangeId());
- gApi.changes().id(result.getChangeId());
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class, () -> gApi.changes().id(result.getChangeId()));
+ assertThat(thrown).hasMessageThat().contains("Not found: " + result.getChangeId());
}
@Test
@@ -163,7 +170,11 @@
PushOneCommit.Result result = createChange();
gApi.changes().id(result.getChangeId()).setPrivate(true, null);
- allow("refs/*", Permission.VIEW_PRIVATE_CHANGES, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.VIEW_PRIVATE_CHANGES).ref("refs/*").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
assertThat(gApi.changes().id(result.getChangeId()).get().isPrivate).isTrue();
}
@@ -191,9 +202,9 @@
merge(result);
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("not allowed to mark private");
- gApi.changes().id(changeId).setPrivate(true, null);
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.changes().id(changeId).setPrivate(true, null));
+ assertThat(thrown).hasMessageThat().contains("not allowed to mark private");
}
@Test
diff --git a/javatests/com/google/gerrit/acceptance/api/change/StickyApprovalsIT.java b/javatests/com/google/gerrit/acceptance/api/change/StickyApprovalsIT.java
index 5052b15..99935b5 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/StickyApprovalsIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/StickyApprovalsIT.java
@@ -16,6 +16,8 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.common.truth.Truth.assert_;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
import static com.google.gerrit.extensions.client.ChangeKind.MERGE_FIRST_PARENT_UPDATE;
import static com.google.gerrit.extensions.client.ChangeKind.NO_CHANGE;
import static com.google.gerrit.extensions.client.ChangeKind.NO_CODE_CHANGE;
@@ -25,8 +27,8 @@
import static com.google.gerrit.extensions.client.ListChangesOption.CURRENT_REVISION;
import static com.google.gerrit.extensions.client.ListChangesOption.DETAILED_LABELS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
-import static com.google.gerrit.server.project.testing.Util.category;
-import static com.google.gerrit.server.project.testing.Util.value;
+import static com.google.gerrit.server.project.testing.TestLabels.label;
+import static com.google.gerrit.server.project.testing.TestLabels.value;
import static org.eclipse.jgit.lib.Constants.HEAD;
import com.google.common.collect.ImmutableList;
@@ -35,9 +37,9 @@
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestAccount;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.LabelType;
-import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.changes.CherryPickInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.changes.RevisionApi;
@@ -45,9 +47,8 @@
import com.google.gerrit.extensions.common.ApprovalInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.CommitInfo;
-import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.RefNames;
-import com.google.gerrit.server.project.testing.Util;
+import com.google.gerrit.server.project.testing.TestLabels;
import com.google.inject.Inject;
import java.util.EnumSet;
import java.util.List;
@@ -61,6 +62,7 @@
@NoHttpd
public class StickyApprovalsIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Before
@@ -69,7 +71,7 @@
// Overwrite "Code-Review" label that is inherited from All-Projects.
// This way changes to the "Code Review" label don't affect other tests.
LabelType codeReview =
- category(
+ label(
"Code-Review",
value(2, "Looks good to me, approved"),
value(1, "Looks good to me, but someone else must approve"),
@@ -80,28 +82,26 @@
u.getConfig().getLabelSections().put(codeReview.getName(), codeReview);
LabelType verified =
- category("Verified", value(1, "Passes"), value(0, "No score"), value(-1, "Failed"));
+ label("Verified", value(1, "Passes"), value(0, "No score"), value(-1, "Failed"));
verified.setCopyAllScoresIfNoChange(false);
u.getConfig().getLabelSections().put(verified.getName(), verified);
- AccountGroup.UUID registeredUsers = systemGroupBackend.getGroup(REGISTERED_USERS).getUUID();
- String heads = RefNames.REFS_HEADS + "*";
- Util.allow(
- u.getConfig(),
- Permission.forLabel(Util.codeReview().getName()),
- -2,
- 2,
- registeredUsers,
- heads);
- Util.allow(
- u.getConfig(),
- Permission.forLabel(Util.verified().getName()),
- -1,
- 1,
- registeredUsers,
- heads);
u.save();
}
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(
+ allowLabel(TestLabels.codeReview().getName())
+ .ref(RefNames.REFS_HEADS + "*")
+ .group(REGISTERED_USERS)
+ .range(-2, 2))
+ .add(
+ allowLabel(TestLabels.verified().getName())
+ .ref(RefNames.REFS_HEADS + "*")
+ .group(REGISTERED_USERS)
+ .range(-1, 1))
+ .update();
}
@Test
@@ -119,7 +119,7 @@
for (ChangeKind changeKind :
EnumSet.of(REWORK, TRIVIAL_REBASE, NO_CODE_CHANGE, MERGE_FIRST_PARENT_UPDATE, NO_CHANGE)) {
- testRepo.reset(getRemoteHead());
+ testRepo.reset(projectOperations.project(project).getHead("master"));
String changeId = createChange(changeKind);
vote(admin, changeId, -1, 1);
@@ -141,7 +141,7 @@
for (ChangeKind changeKind :
EnumSet.of(REWORK, TRIVIAL_REBASE, NO_CODE_CHANGE, MERGE_FIRST_PARENT_UPDATE, NO_CHANGE)) {
- testRepo.reset(getRemoteHead());
+ testRepo.reset(projectOperations.project(project).getHead("master"));
String changeId = createChange(changeKind);
vote(admin, changeId, 2, 1);
@@ -178,7 +178,7 @@
assertNotSticky(EnumSet.of(REWORK, NO_CODE_CHANGE, MERGE_FIRST_PARENT_UPDATE));
// check that votes are sticky when trivial rebase is done by cherry-pick
- testRepo.reset(getRemoteHead());
+ testRepo.reset(projectOperations.project(project).getHead("master"));
changeId = createChange().getChangeId();
vote(admin, changeId, 2, 1);
vote(user, changeId, -2, -1);
@@ -189,7 +189,7 @@
assertVotes(c, user, -2, 0);
// check that votes are not sticky when rework is done by cherry-pick
- testRepo.reset(getRemoteHead());
+ testRepo.reset(projectOperations.project(project).getHead("master"));
changeId = createChange().getChangeId();
vote(admin, changeId, 2, 1);
vote(user, changeId, -2, -1);
@@ -261,7 +261,7 @@
for (ChangeKind changeKind :
EnumSet.of(REWORK, TRIVIAL_REBASE, NO_CODE_CHANGE, MERGE_FIRST_PARENT_UPDATE, NO_CHANGE)) {
- testRepo.reset(getRemoteHead());
+ testRepo.reset(projectOperations.project(project).getHead("master"));
String changeId = createChange(changeKind);
vote(admin, changeId, 2, 1);
@@ -369,7 +369,7 @@
private void assertNotSticky(Set<ChangeKind> changeKinds) throws Exception {
for (ChangeKind changeKind : changeKinds) {
- testRepo.reset(getRemoteHead());
+ testRepo.reset(projectOperations.project(project).getHead("master"));
String changeId = createChange(changeKind);
vote(admin, changeId, +2, 1);
@@ -414,7 +414,7 @@
noChange(changeId);
return;
default:
- fail("unexpected change kind: " + changeKind);
+ assert_().fail("unexpected change kind: " + changeKind);
}
}
@@ -460,7 +460,7 @@
private void trivialRebase(String changeId) throws Exception {
requestScopeOperations.setApiUser(admin.id());
- testRepo.reset(getRemoteHead());
+ testRepo.reset(projectOperations.project(project).getHead("master"));
PushOneCommit push =
pushFactory.create(
admin.newIdent(),
@@ -523,10 +523,10 @@
case NO_CHANGE:
case MERGE_FIRST_PARENT_UPDATE:
default:
- fail("unexpected change kind: " + changeKind);
+ assert_().fail("unexpected change kind: " + changeKind);
}
- testRepo.reset(getRemoteHead());
+ testRepo.reset(projectOperations.project(project).getHead("master"));
PushOneCommit.Result r =
pushFactory
.create(
diff --git a/javatests/com/google/gerrit/acceptance/api/change/SubmitTypeRuleIT.java b/javatests/com/google/gerrit/acceptance/api/change/SubmitTypeRuleIT.java
index 6c0e9ab..62600b2 100644
--- a/javatests/com/google/gerrit/acceptance/api/change/SubmitTypeRuleIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/change/SubmitTypeRuleIT.java
@@ -21,6 +21,7 @@
import static com.google.gerrit.extensions.client.SubmitType.MERGE_IF_NECESSARY;
import static com.google.gerrit.extensions.client.SubmitType.REBASE_ALWAYS;
import static com.google.gerrit.extensions.client.SubmitType.REBASE_IF_NECESSARY;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.acceptance.AbstractDaemonTest;
@@ -237,22 +238,21 @@
gApi.changes().id(r1.getChangeId()).current().review(ReviewInput.approve());
gApi.changes().id(r2.getChangeId()).current().review(ReviewInput.approve());
- try {
- gApi.changes().id(r2.getChangeId()).current().submit();
- fail("Expected ResourceConflictException");
- } catch (ResourceConflictException e) {
- assertThat(e)
- .hasMessageThat()
- .isEqualTo(
- "Failed to submit 2 changes due to the following problems:\n"
- + "Change "
- + r1.getChange().getId()
- + ": Change has submit type "
- + "CHERRY_PICK, but previously chose submit type MERGE_IF_NECESSARY "
- + "from change "
- + r2.getChange().getId()
- + " in the same batch");
- }
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(r2.getChangeId()).current().submit());
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo(
+ "Failed to submit 2 changes due to the following problems:\n"
+ + "Change "
+ + r1.getChange().getId()
+ + ": Change has submit type "
+ + "CHERRY_PICK, but previously chose submit type MERGE_IF_NECESSARY "
+ + "from change "
+ + r2.getChange().getId()
+ + " in the same batch");
}
@Test
diff --git a/javatests/com/google/gerrit/acceptance/api/group/GroupsConsistencyIT.java b/javatests/com/google/gerrit/acceptance/api/group/GroupsConsistencyIT.java
index cdcfc0c..ab1dbd3 100644
--- a/javatests/com/google/gerrit/acceptance/api/group/GroupsConsistencyIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/group/GroupsConsistencyIT.java
@@ -15,12 +15,15 @@
package com.google.gerrit.acceptance.api.group;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assert_;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.Sandboxed;
import com.google.gerrit.acceptance.testsuite.group.GroupOperations;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.api.config.ConsistencyCheckInfo;
import com.google.gerrit.extensions.api.config.ConsistencyCheckInfo.ConsistencyProblemInfo;
@@ -51,6 +54,7 @@
public class GroupsConsistencyIT extends AbstractDaemonTest {
@Inject protected GroupOperations groupOperations;
+ @Inject private ProjectOperations projectOperations;
private GroupInfo gAdmin;
private GroupInfo g1;
private GroupInfo g2;
@@ -59,7 +63,10 @@
@Before
public void basicSetup() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
String name1 = groupOperations.newGroup().name("g1").create().get();
String name2 = groupOperations.newGroup().name("g2").create().get();
@@ -245,7 +252,7 @@
}
}
- fail(String.format("could not find %s substring '%s' in %s", want, msg, problems));
+ assert_().fail(String.format("could not find %s substring '%s' in %s", want, msg, problems));
}
private void updateGroupFile(String refName, String fileName, String content) throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java b/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java
index 9c3dc8d..9eb1270 100644
--- a/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java
@@ -22,8 +22,12 @@
import static com.google.gerrit.acceptance.GitUtil.fetch;
import static com.google.gerrit.acceptance.api.group.GroupAssert.assertGroupInfo;
import static com.google.gerrit.acceptance.rest.account.AccountAssert.assertAccountInfos;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.util.stream.Collectors.toList;
@@ -43,6 +47,7 @@
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.testsuite.account.AccountOperations;
import com.google.gerrit.acceptance.testsuite.group.GroupOperations;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.GlobalCapability;
@@ -85,10 +90,9 @@
import com.google.gerrit.server.index.group.GroupIndexer;
import com.google.gerrit.server.index.group.StalenessChecker;
import com.google.gerrit.server.notedb.Sequences;
-import com.google.gerrit.server.project.ProjectConfig;
-import com.google.gerrit.server.project.testing.Util;
import com.google.gerrit.server.util.MagicBranch;
import com.google.gerrit.server.util.time.TimeUtil;
+import com.google.gerrit.testing.GerritJUnit.ThrowingRunnable;
import com.google.gerrit.testing.TestTimeUtil;
import com.google.inject.Inject;
import java.io.IOException;
@@ -131,6 +135,7 @@
@Inject private Groups groups;
@Inject private GroupsConsistencyChecker consistencyChecker;
@Inject private PeriodicGroupIndexer slaveGroupIndexer;
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Inject private Sequences seq;
@Inject private StalenessChecker stalenessChecker;
@@ -168,14 +173,16 @@
@Test
public void addToNonExistingGroup_NotFound() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- gApi.groups().id("non-existing").addMembers("admin");
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.groups().id("non-existing").addMembers("admin"));
}
@Test
public void removeFromNonExistingGroup_NotFound() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- gApi.groups().id("non-existing").removeMembers("admin");
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.groups().id("non-existing").removeMembers("admin"));
}
@Test
@@ -231,8 +238,9 @@
@Test
public void addNonExistingMember_UnprocessableEntity() throws Exception {
- exception.expect(UnprocessableEntityException.class);
- gApi.groups().id("Administrators").addMembers("non-existing");
+ assertThrows(
+ UnprocessableEntityException.class,
+ () -> gApi.groups().id("Administrators").addMembers("non-existing"));
}
@Test
@@ -351,9 +359,9 @@
public void createDuplicateInternalGroupCaseSensitiveName_Conflict() throws Exception {
String dupGroupName = name("dupGroup");
gApi.groups().create(dupGroupName);
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("group '" + dupGroupName + "' already exists");
- gApi.groups().create(dupGroupName);
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> gApi.groups().create(dupGroupName));
+ assertThat(thrown).hasMessageThat().contains("group '" + dupGroupName + "' already exists");
}
@Test
@@ -369,33 +377,34 @@
@Test
public void createDuplicateSystemGroupCaseSensitiveName_Conflict() throws Exception {
String newGroupName = "Registered Users";
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("group 'Registered Users' already exists");
- gApi.groups().create(newGroupName);
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> gApi.groups().create(newGroupName));
+ assertThat(thrown).hasMessageThat().contains("group 'Registered Users' already exists");
}
@Test
public void createDuplicateSystemGroupCaseInsensitiveName_Conflict() throws Exception {
String newGroupName = "registered users";
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("group 'Registered Users' already exists");
- gApi.groups().create(newGroupName);
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> gApi.groups().create(newGroupName));
+ assertThat(thrown).hasMessageThat().contains("group 'Registered Users' already exists");
}
@Test
@GerritConfig(name = "groups.global:Anonymous-Users.name", value = "All Users")
public void createGroupWithConfiguredNameOfSystemGroup_Conflict() throws Exception {
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("group 'All Users' already exists");
- gApi.groups().create("all users");
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> gApi.groups().create("all users"));
+ assertThat(thrown).hasMessageThat().contains("group 'All Users' already exists");
}
@Test
@GerritConfig(name = "groups.global:Anonymous-Users.name", value = "All Users")
public void createGroupWithDefaultNameOfSystemGroup_Conflict() throws Exception {
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("group name 'Anonymous Users' is reserved");
- gApi.groups().create("anonymous users");
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class, () -> gApi.groups().create("anonymous users"));
+ assertThat(thrown).hasMessageThat().contains("group name 'Anonymous Users' is reserved");
}
@Test
@@ -414,8 +423,7 @@
@Test
public void createGroupWithoutCapability_Forbidden() throws Exception {
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- gApi.groups().create(name("newGroup"));
+ assertThrows(AuthException.class, () -> gApi.groups().create(name("newGroup")));
}
@Test
@@ -481,8 +489,7 @@
@Test
@GerritConfig(name = "groups.global:Anonymous-Users.name", value = "All Users")
public void getSystemGroupByDefaultName_NotFound() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- gApi.groups().id("Anonymous-Users").get();
+ assertThrows(ResourceNotFoundException.class, () -> gApi.groups().id("Anonymous-Users").get());
}
@Test
@@ -498,8 +505,7 @@
String name = name("Users");
gApi.groups().create(name).get();
- exception.expect(ResourceConflictException.class);
- gApi.groups().create(name);
+ assertThrows(ResourceConflictException.class, () -> gApi.groups().create(name));
}
@Test
@@ -528,9 +534,7 @@
String name2 = name("Name2");
gApi.groups().create(name2);
-
- exception.expect(ResourceConflictException.class);
- gApi.groups().id(group1.id).name(name2);
+ assertThrows(ResourceConflictException.class, () -> gApi.groups().id(group1.id).name(name2));
}
@Test
@@ -554,8 +558,7 @@
gApi.groups().id(group.id).name(newName);
assertGroupDoesNotExist(name);
- exception.expect(ResourceNotFoundException.class);
- gApi.groups().id(name).get();
+ assertThrows(ResourceNotFoundException.class, () -> gApi.groups().id(name).get());
}
@Test
@@ -626,14 +629,15 @@
assertThat(Url.decode(gApi.groups().id(name).owner().id)).isEqualTo(adminUUID);
// set non existing owner
- exception.expect(UnprocessableEntityException.class);
- gApi.groups().id(name).owner("Non-Existing Group");
+ assertThrows(
+ UnprocessableEntityException.class,
+ () -> gApi.groups().id(name).owner("Non-Existing Group"));
}
@Test
public void listNonExistingGroupIncludes_NotFound() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- gApi.groups().id("non-existing").includedGroups();
+ assertThrows(
+ ResourceNotFoundException.class, () -> gApi.groups().id("non-existing").includedGroups());
}
@Test
@@ -645,8 +649,9 @@
@Test
public void includeNonExistingGroup() throws Exception {
AccountGroup.UUID gx = groupOperations.newGroup().create();
- exception.expect(UnprocessableEntityException.class);
- gApi.groups().id(gx.get()).addGroups("non-existing");
+ assertThrows(
+ UnprocessableEntityException.class,
+ () -> gApi.groups().id(gx.get()).addGroups("non-existing"));
}
@Test
@@ -675,8 +680,7 @@
@Test
public void listNonExistingGroupMembers_NotFound() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- gApi.groups().id("non-existing").members();
+ assertThrows(ResourceNotFoundException.class, () -> gApi.groups().id("non-existing").members());
}
@Test
@@ -820,9 +824,11 @@
assertThat(owned).isEmpty();
// By non-existing group
- exception.expect(UnprocessableEntityException.class);
- exception.expectMessage("Group Not Found: does-not-exist");
- gApi.groups().list().withOwnedBy("does-not-exist").get();
+ UnprocessableEntityException thrown =
+ assertThrows(
+ UnprocessableEntityException.class,
+ () -> gApi.groups().list().withOwnedBy("does-not-exist").get());
+ assertThat(thrown).hasMessageThat().contains("Group Not Found: does-not-exist");
}
@Test
@@ -996,11 +1002,7 @@
gApi.groups().id(uuid.get()).index();
// Verify "sub-group" has been deleted.
- try {
- gApi.groups().id(uuid.get()).get();
- fail("expected ResourceNotFoundException");
- } catch (ResourceNotFoundException e) {
- }
+ assertThrows(ResourceNotFoundException.class, () -> gApi.groups().id(uuid.get()).get());
}
// reindex is tested by {@link AbstractQueryGroupsTest#reindex}
@@ -1023,9 +1025,9 @@
// user cannot reindex any group
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("not allowed to index group");
- gApi.groups().id(group.id).index();
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.groups().id(group.id).index());
+ assertThat(thrown).hasMessageThat().contains("not allowed to index group");
}
@Test
@@ -1045,7 +1047,10 @@
@Test
public void pushToGroupNamesBranchIsRejectedForAllUsersRepo() throws Exception {
// refs/meta/group-names isn't usually available for fetch, so grant ACCESS_DATABASE
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
assertPushToGroupBranch(allUsers, RefNames.REFS_GROUPNAMES, "group update not allowed");
}
@@ -1075,15 +1080,18 @@
private void assertPushToGroupBranch(
Project.NameKey project, String groupRefName, String expectedErrorOnUpdate) throws Exception {
- try (ProjectConfigUpdate u = updateProject(project)) {
- ProjectConfig cfg = u.getConfig();
- Util.allow(cfg, Permission.CREATE, REGISTERED_USERS, RefNames.REFS_GROUPS + "*");
- Util.allow(cfg, Permission.PUSH, REGISTERED_USERS, RefNames.REFS_GROUPS + "*");
- Util.allow(cfg, Permission.CREATE, REGISTERED_USERS, RefNames.REFS_DELETED_GROUPS + "*");
- Util.allow(cfg, Permission.PUSH, REGISTERED_USERS, RefNames.REFS_DELETED_GROUPS + "*");
- Util.allow(cfg, Permission.PUSH, REGISTERED_USERS, RefNames.REFS_GROUPNAMES);
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref(RefNames.REFS_GROUPS + "*").group(REGISTERED_USERS))
+ .add(allow(Permission.PUSH).ref(RefNames.REFS_GROUPS + "*").group(REGISTERED_USERS))
+ .add(
+ allow(Permission.CREATE)
+ .ref(RefNames.REFS_DELETED_GROUPS + "*")
+ .group(REGISTERED_USERS))
+ .add(allow(Permission.PUSH).ref(RefNames.REFS_DELETED_GROUPS + "*").group(REGISTERED_USERS))
+ .add(allow(Permission.PUSH).ref(RefNames.REFS_GROUPNAMES).group(REGISTERED_USERS))
+ .update();
TestRepository<InMemoryRepository> repo = cloneProject(project);
@@ -1102,12 +1110,12 @@
}
private void assertCreateGroupBranch(Project.NameKey project) throws Exception {
- try (ProjectConfigUpdate u = updateProject(project)) {
- ProjectConfig cfg = u.getConfig();
- Util.allow(cfg, Permission.CREATE, REGISTERED_USERS, RefNames.REFS_GROUPS + "*");
- Util.allow(cfg, Permission.PUSH, REGISTERED_USERS, RefNames.REFS_GROUPS + "*");
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref(RefNames.REFS_GROUPS + "*").group(REGISTERED_USERS))
+ .add(allow(Permission.PUSH).ref(RefNames.REFS_GROUPS + "*").group(REGISTERED_USERS))
+ .update();
TestRepository<InMemoryRepository> repo = cloneProject(project);
PushOneCommit.Result r =
pushFactory
@@ -1118,13 +1126,13 @@
}
@Test
- public void pushToGroupBranchForReviewForAllUsersRepoIsRejectedOnSubmit() throws Exception {
+ public void pushToGroupBranchForReviewForAllUsersRepoIsRejectedOnSubmit() throws Throwable {
pushToGroupBranchForReviewAndSubmit(
allUsers, RefNames.refsGroups(adminGroupUuid()), "group update not allowed");
}
@Test
- public void pushToGroupBranchForReviewForNonAllUsersRepoAndSubmit() throws Exception {
+ public void pushToGroupBranchForReviewForNonAllUsersRepoAndSubmit() throws Throwable {
String groupRef = RefNames.refsGroups(adminGroupUuid());
createBranch(project, groupRef);
pushToGroupBranchForReviewAndSubmit(project, groupRef, null);
@@ -1188,15 +1196,22 @@
}
// refs/meta/group-names is only visible with ACCESS_DATABASE
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
testCannotCreateGroupBranch(RefNames.REFS_GROUPNAMES, RefNames.REFS_GROUPNAMES);
}
}
private void testCannotCreateGroupBranch(String refPattern, String groupRef) throws Exception {
- grant(allUsers, refPattern, Permission.CREATE);
- grant(allUsers, refPattern, Permission.PUSH);
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref(refPattern).group(adminGroupUuid()))
+ .add(allow(Permission.PUSH).ref(refPattern).group(adminGroupUuid()))
+ .update();
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
PushOneCommit.Result r = pushFactory.create(admin.newIdent(), allUsersRepo).to(groupRef);
@@ -1223,13 +1238,20 @@
@Test
public void cannotDeleteGroupNamesBranch() throws Exception {
// refs/meta/group-names is only visible with ACCESS_DATABASE
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
testCannotDeleteGroupBranch(RefNames.REFS_GROUPNAMES, RefNames.REFS_GROUPNAMES);
}
private void testCannotDeleteGroupBranch(String refPattern, String groupRef) throws Exception {
- grant(allUsers, refPattern, Permission.DELETE, true, REGISTERED_USERS);
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.DELETE).ref(refPattern).group(REGISTERED_USERS).force(true))
+ .update();
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
PushResult r = deleteRef(allUsersRepo, groupRef);
@@ -1411,10 +1433,17 @@
}
private void pushToGroupBranchForReviewAndSubmit(
- Project.NameKey project, String groupRef, String expectedError) throws Exception {
- grantLabel(
- "Code-Review", -2, 2, project, RefNames.REFS_GROUPS + "*", false, REGISTERED_USERS, false);
- grant(project, RefNames.REFS_GROUPS + "*", Permission.SUBMIT, false, REGISTERED_USERS);
+ Project.NameKey project, String groupRef, String expectedError) throws Throwable {
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(
+ allowLabel("Code-Review")
+ .ref(RefNames.REFS_GROUPS + "*")
+ .group(REGISTERED_USERS)
+ .range(-2, 2))
+ .add(allow(Permission.SUBMIT).ref(RefNames.REFS_GROUPS + "*").group(REGISTERED_USERS))
+ .update();
TestRepository<InMemoryRepository> repo = cloneProject(project);
fetch(repo, groupRef + ":groupRef");
@@ -1428,11 +1457,13 @@
assertThat(r.getChange().change().getDest().branch()).isEqualTo(groupRef);
gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
+ ThrowingRunnable submit = () -> gApi.changes().id(r.getChangeId()).current().submit();
if (expectedError != null) {
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("group update not allowed");
+ Throwable thrown = assertThrows(ResourceConflictException.class, submit);
+ assertThat(thrown).hasMessageThat().contains("group update not allowed");
+ } else {
+ submit.run();
}
- gApi.changes().id(r.getChangeId()).current().submit();
}
private void createBranch(Project.NameKey project, String ref) throws IOException {
@@ -1509,16 +1540,11 @@
private static void assertIncludes(List<GroupInfo> includes, String... expectedNames) {
List<String> names = includes.stream().map(i -> i.name).collect(toImmutableList());
assertThat(names).containsExactlyElementsIn(Arrays.asList(expectedNames));
- assertThat(names).isOrdered();
+ assertThat(names).isInOrder();
}
private void assertBadRequest(ListRequest req) throws Exception {
- try {
- req.get();
- fail("Expected BadRequestException");
- } catch (BadRequestException e) {
- // Expected
- }
+ assertThrows(BadRequestException.class, () -> req.get());
}
@Target({METHOD})
diff --git a/javatests/com/google/gerrit/acceptance/api/group/GroupsUpdateIT.java b/javatests/com/google/gerrit/acceptance/api/group/GroupsUpdateIT.java
index 8f0dcee..aba7d18 100644
--- a/javatests/com/google/gerrit/acceptance/api/group/GroupsUpdateIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/group/GroupsUpdateIT.java
@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance.api.group;
import static com.google.common.truth.Truth8.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.common.data.GroupReference;
@@ -36,12 +37,9 @@
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.ExpectedException;
public class GroupsUpdateIT {
@Rule public InMemoryTestEnvironment testEnvironment = new InMemoryTestEnvironment();
- @Rule public ExpectedException expectedException = ExpectedException.none();
-
@Inject @ServerInitiated private Provider<GroupsUpdate> groupsUpdateProvider;
@Inject private Groups groups;
@@ -56,7 +54,7 @@
createGroup(groupCreation, groupUpdate);
Stream<String> allGroupNames = getAllGroupNames();
- assertThat(allGroupNames).containsAllOf("users", "verifiers");
+ assertThat(allGroupNames).containsAtLeast("users", "verifiers");
}
@Test
@@ -72,16 +70,16 @@
updateGroup(AccountGroup.uuid("users-UUID"), groupUpdate);
Stream<String> allGroupNames = getAllGroupNames();
- assertThat(allGroupNames).containsAllOf("contributors", "verifiers");
+ assertThat(allGroupNames).containsAtLeast("contributors", "verifiers");
}
@Test
public void groupUpdateFailsWithExceptionForNotExistingGroup() throws Exception {
InternalGroupUpdate groupUpdate =
InternalGroupUpdate.builder().setDescription("A description for the group").build();
-
- expectedException.expect(NoSuchGroupException.class);
- updateGroup(AccountGroup.uuid("nonexistent-group-UUID"), groupUpdate);
+ assertThrows(
+ NoSuchGroupException.class,
+ () -> updateGroup(AccountGroup.uuid("nonexistent-group-UUID"), groupUpdate));
}
private void createGroup(String groupName, String groupUuid) throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/api/plugin/PluginIT.java b/javatests/com/google/gerrit/acceptance/api/plugin/PluginIT.java
index 1d3eb17..e8af0bb 100644
--- a/javatests/com/google/gerrit/acceptance/api/plugin/PluginIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/plugin/PluginIT.java
@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance.api.plugin;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.stream.Collectors.toList;
@@ -117,12 +118,7 @@
// Non-admin cannot disable
requestScopeOperations.setApiUser(user.id());
- try {
- gApi.plugins().name("plugin-a").disable();
- fail("Expected AuthException");
- } catch (AuthException expected) {
- // Expected
- }
+ assertThrows(AuthException.class, () -> gApi.plugins().name("plugin-a").disable());
}
@SuppressWarnings("deprecation")
@@ -136,15 +132,16 @@
@Test
public void installNotAllowed() throws Exception {
- exception.expect(MethodNotAllowedException.class);
- exception.expectMessage("remote plugin administration is disabled");
- gApi.plugins().install("test.js", new InstallPluginInput());
+ MethodNotAllowedException thrown =
+ assertThrows(
+ MethodNotAllowedException.class,
+ () -> gApi.plugins().install("test.js", new InstallPluginInput()));
+ assertThat(thrown).hasMessageThat().contains("remote plugin administration is disabled");
}
@Test
public void getNonExistingThrowsNotFound() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- gApi.plugins().name("does-not-exist");
+ assertThrows(ResourceNotFoundException.class, () -> gApi.plugins().name("does-not-exist"));
}
private ListRequest list() throws RestApiException {
@@ -170,11 +167,6 @@
}
private void assertBadRequest(ListRequest req) throws Exception {
- try {
- req.get();
- fail("Expected BadRequestException");
- } catch (BadRequestException e) {
- // Expected
- }
+ assertThrows(BadRequestException.class, () -> req.get());
}
}
diff --git a/javatests/com/google/gerrit/acceptance/api/project/CheckAccessIT.java b/javatests/com/google/gerrit/acceptance/api/project/CheckAccessIT.java
index 8cdd2f66..3fcc595 100644
--- a/javatests/com/google/gerrit/acceptance/api/project/CheckAccessIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/project/CheckAccessIT.java
@@ -15,6 +15,11 @@
package com.google.gerrit.acceptance.api.project;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assert_;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.deny;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.acceptance.AbstractDaemonTest;
@@ -32,8 +37,6 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.group.SystemGroupBackend;
-import com.google.gerrit.server.project.ProjectConfig;
-import com.google.gerrit.server.project.testing.Util;
import com.google.inject.Inject;
import java.util.List;
import org.eclipse.jgit.lib.RefUpdate;
@@ -62,36 +65,41 @@
privilegedUser = accountCreator.create("privilegedUser", "snowden@nsa.gov", "Ed Snowden");
groupOperations.group(privilegedGroupUuid).forUpdate().addMember(privilegedUser.id()).update();
- try (ProjectConfigUpdate u = updateProject(secretProject)) {
- ProjectConfig cfg = u.getConfig();
- Util.allow(cfg, Permission.READ, privilegedGroupUuid, "refs/*");
- Util.block(cfg, Permission.READ, SystemGroupBackend.REGISTERED_USERS, "refs/*");
- u.save();
- }
+ projectOperations
+ .project(secretProject)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/*").group(privilegedGroupUuid))
+ .add(block(Permission.READ).ref("refs/*").group(SystemGroupBackend.REGISTERED_USERS))
+ .update();
- try (ProjectConfigUpdate u = updateProject(secretRefProject)) {
- ProjectConfig cfg = u.getConfig();
- Util.deny(cfg, Permission.READ, SystemGroupBackend.ANONYMOUS_USERS, "refs/*");
- Util.allow(cfg, Permission.READ, privilegedGroupUuid, "refs/heads/secret/*");
- Util.block(cfg, Permission.READ, SystemGroupBackend.REGISTERED_USERS, "refs/heads/secret/*");
- Util.allow(cfg, Permission.READ, SystemGroupBackend.REGISTERED_USERS, "refs/heads/*");
- u.save();
- }
+ projectOperations
+ .project(secretRefProject)
+ .forUpdate()
+ .add(deny(Permission.READ).ref("refs/*").group(SystemGroupBackend.ANONYMOUS_USERS))
+ .add(allow(Permission.READ).ref("refs/heads/secret/*").group(privilegedGroupUuid))
+ .add(
+ block(Permission.READ)
+ .ref("refs/heads/secret/*")
+ .group(SystemGroupBackend.REGISTERED_USERS))
+ .add(allow(Permission.READ).ref("refs/heads/*").group(SystemGroupBackend.REGISTERED_USERS))
+ .update();
// Ref permission
- try (ProjectConfigUpdate u = updateProject(normalProject)) {
- ProjectConfig cfg = u.getConfig();
- Util.allow(cfg, Permission.VIEW_PRIVATE_CHANGES, privilegedGroupUuid, "refs/*");
- Util.allow(cfg, Permission.FORGE_SERVER, privilegedGroupUuid, "refs/*");
- u.save();
- }
+ projectOperations
+ .project(normalProject)
+ .forUpdate()
+ .add(allow(Permission.VIEW_PRIVATE_CHANGES).ref("refs/*").group(privilegedGroupUuid))
+ .add(allow(Permission.FORGE_SERVER).ref("refs/*").group(privilegedGroupUuid))
+ .update();
}
@Test
public void emptyInput() throws Exception {
- exception.expect(BadRequestException.class);
- exception.expectMessage("input requires 'account'");
- gApi.projects().name(normalProject.get()).checkAccess(new AccessCheckInput());
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () -> gApi.projects().name(normalProject.get()).checkAccess(new AccessCheckInput()));
+ assertThat(thrown).hasMessageThat().contains("input requires 'account'");
}
@Test
@@ -101,9 +109,11 @@
in.permission = "notapermission";
in.ref = "refs/heads/master";
- exception.expect(BadRequestException.class);
- exception.expectMessage("not recognized");
- gApi.projects().name(normalProject.get()).checkAccess(in);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () -> gApi.projects().name(normalProject.get()).checkAccess(in));
+ assertThat(thrown).hasMessageThat().contains("not recognized");
}
@Test
@@ -112,9 +122,11 @@
in.account = user.email();
in.permission = "forge_author";
- exception.expect(BadRequestException.class);
- exception.expectMessage("must set 'ref'");
- gApi.projects().name(normalProject.get()).checkAccess(in);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () -> gApi.projects().name(normalProject.get()).checkAccess(in));
+ assertThat(thrown).hasMessageThat().contains("must set 'ref'");
}
@Test
@@ -124,9 +136,11 @@
in.permission = "rebase";
in.ref = "refs/heads/master";
- exception.expect(BadRequestException.class);
- exception.expectMessage("recognized as ref permission");
- gApi.projects().name(normalProject.get()).checkAccess(in);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () -> gApi.projects().name(normalProject.get()).checkAccess(in));
+ assertThat(thrown).hasMessageThat().contains("recognized as ref permission");
}
@Test
@@ -136,9 +150,11 @@
in.permission = "rebase";
in.ref = "refs/heads/master";
- exception.expect(UnprocessableEntityException.class);
- exception.expectMessage("Account 'doesnotexist@invalid.com' not found");
- gApi.projects().name(normalProject.get()).checkAccess(in);
+ UnprocessableEntityException thrown =
+ assertThrows(
+ UnprocessableEntityException.class,
+ () -> gApi.projects().name(normalProject.get()).checkAccess(in));
+ assertThat(thrown).hasMessageThat().contains("Account 'doesnotexist@invalid.com' not found");
}
private static class TestCase {
@@ -231,13 +247,15 @@
try {
info = gApi.projects().name(tc.project).checkAccess(tc.input);
} catch (RestApiException e) {
- fail(String.format("check.access(%s, %s): exception %s", tc.project, in, e));
+ assert_().fail(String.format("check.access(%s, %s): exception %s", tc.project, in, e));
}
int want = tc.want;
if (want != info.status) {
- fail(
- String.format("check.access(%s, %s) = %d, want %d", tc.project, in, info.status, want));
+ assert_()
+ .fail(
+ String.format(
+ "check.access(%s, %s) = %d, want %d", tc.project, in, info.status, want));
}
switch (want) {
@@ -253,7 +271,7 @@
assertThat(info.message).isNull();
break;
default:
- fail(String.format("unknown code %d", want));
+ assert_().fail(String.format("unknown code %d", want));
}
}
}
diff --git a/javatests/com/google/gerrit/acceptance/api/project/CheckProjectIT.java b/javatests/com/google/gerrit/acceptance/api/project/CheckProjectIT.java
index bf82603..96ba722 100644
--- a/javatests/com/google/gerrit/acceptance/api/project/CheckProjectIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/project/CheckProjectIT.java
@@ -16,6 +16,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.GitUtil.pushHead;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toSet;
@@ -232,18 +233,21 @@
CheckProjectInput input = new CheckProjectInput();
input.autoCloseableChangesCheck = new AutoCloseableChangesCheckInput();
- exception.expect(BadRequestException.class);
- exception.expectMessage("branch is required");
- gApi.projects().name(project.get()).check(input);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class, () -> gApi.projects().name(project.get()).check(input));
+ assertThat(thrown).hasMessageThat().contains("branch is required");
}
@Test
public void nonExistingBranch() throws Exception {
CheckProjectInput input = checkProjectInputForAutoCloseableCheck("non-existing");
- exception.expect(UnprocessableEntityException.class);
- exception.expectMessage("branch 'non-existing' not found");
- gApi.projects().name(project.get()).check(input);
+ UnprocessableEntityException thrown =
+ assertThrows(
+ UnprocessableEntityException.class,
+ () -> gApi.projects().name(project.get()).check(input));
+ assertThat(thrown).hasMessageThat().contains("branch 'non-existing' not found");
}
@Test
@@ -266,11 +270,14 @@
input.autoCloseableChangesCheck.maxCommits =
ProjectsConsistencyChecker.AUTO_CLOSE_MAX_COMMITS_LIMIT + 1;
- exception.expect(BadRequestException.class);
- exception.expectMessage(
- "max commits can at most be set to "
- + ProjectsConsistencyChecker.AUTO_CLOSE_MAX_COMMITS_LIMIT);
- gApi.projects().name(project.get()).check(input);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class, () -> gApi.projects().name(project.get()).check(input));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ "max commits can at most be set to "
+ + ProjectsConsistencyChecker.AUTO_CLOSE_MAX_COMMITS_LIMIT);
}
private RevCommit pushCommitWithoutChangeIdForReview() throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/api/project/CommitIncludedInIT.java b/javatests/com/google/gerrit/acceptance/api/project/CommitIncludedInIT.java
index 54aa192..749176b8f 100644
--- a/javatests/com/google/gerrit/acceptance/api/project/CommitIncludedInIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/project/CommitIncludedInIT.java
@@ -15,21 +15,26 @@
package com.google.gerrit.acceptance.api.project;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static org.eclipse.jgit.lib.Constants.R_TAGS;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit.Result;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.changes.IncludedInInfo;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.projects.TagInput;
import com.google.gerrit.reviewdb.client.BranchNameKey;
+import com.google.inject.Inject;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
@NoHttpd
public class CommitIncludedInIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
+
@Test
public void includedInOpenChange() throws Exception {
Result result = createChange();
@@ -49,7 +54,11 @@
assertThat(getIncludedIn(result.getCommit().getId()).branches).containsExactly("master");
assertThat(getIncludedIn(result.getCommit().getId()).tags).isEmpty();
- grant(project, R_TAGS + "*", Permission.CREATE_TAG);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.CREATE_TAG).ref(R_TAGS + "*").group(adminGroupUuid()))
+ .update();
gApi.projects().name(result.getChange().project().get()).tag("test-tag").create(new TagInput());
assertThat(getIncludedIn(result.getCommit().getId()).tags).containsExactly("test-tag");
diff --git a/javatests/com/google/gerrit/acceptance/api/project/DashboardIT.java b/javatests/com/google/gerrit/acceptance/api/project/DashboardIT.java
index e51a069..6442645 100644
--- a/javatests/com/google/gerrit/acceptance/api/project/DashboardIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/project/DashboardIT.java
@@ -15,12 +15,15 @@
package com.google.gerrit.acceptance.api.project;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.toList;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.projects.BranchInput;
import com.google.gerrit.extensions.api.projects.DashboardInfo;
@@ -31,6 +34,7 @@
import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.server.restapi.project.DashboardsCollection;
+import com.google.inject.Inject;
import java.util.List;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Repository;
@@ -40,21 +44,25 @@
@NoHttpd
public class DashboardIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
+
@Before
public void setup() throws Exception {
- allow("refs/meta/dashboards/*", Permission.CREATE, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref("refs/meta/dashboards/*").group(REGISTERED_USERS))
+ .update();
}
@Test
public void defaultDashboardDoesNotExist() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- project().defaultDashboard().get();
+ assertThrows(ResourceNotFoundException.class, () -> project().defaultDashboard().get());
}
@Test
public void dashboardDoesNotExist() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- project().dashboard("my:dashboard").get();
+ assertThrows(ResourceNotFoundException.class, () -> project().dashboard("my:dashboard").get());
}
@Test
@@ -110,8 +118,7 @@
project().removeDefaultDashboard();
assertThat(project().dashboard(info.id).get().isDefault).isNull();
- exception.expect(ResourceNotFoundException.class);
- project().defaultDashboard().get();
+ assertThrows(ResourceNotFoundException.class, () -> project().defaultDashboard().get());
}
@Test
@@ -133,9 +140,9 @@
@Test
public void cannotGetDashboardWithInheritedForNonDefault() throws Exception {
DashboardInfo info = createTestDashboard();
- exception.expect(BadRequestException.class);
- exception.expectMessage("inherited flag can only be used with default");
- project().dashboard(info.id).get(true);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> project().dashboard(info.id).get(true));
+ assertThat(thrown).hasMessageThat().contains("inherited flag can only be used with default");
}
private void assertDashboardInfo(DashboardInfo actual, DashboardInfo expected) throws Exception {
@@ -192,9 +199,9 @@
throw e;
}
}
- try (Repository r = repoManager.openRepository(project)) {
- TestRepository<Repository>.CommitBuilder cb =
- new TestRepository<>(r).branch(canonicalRef).commit();
+ try (Repository r = repoManager.openRepository(project);
+ TestRepository<Repository> tr = new TestRepository<>(r)) {
+ TestRepository<Repository>.CommitBuilder cb = tr.branch(canonicalRef).commit();
StringBuilder content = new StringBuilder("[dashboard]\n");
if (info.title != null) {
content.append("title = ").append(info.title).append("\n");
diff --git a/javatests/com/google/gerrit/acceptance/api/project/ProjectIT.java b/javatests/com/google/gerrit/acceptance/api/project/ProjectIT.java
index 1c38cdd..dce0ab2 100644
--- a/javatests/com/google/gerrit/acceptance/api/project/ProjectIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/project/ProjectIT.java
@@ -15,11 +15,14 @@
package com.google.gerrit.acceptance.api.project;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.server.git.QueueProvider.QueueType.BATCH;
import static com.google.gerrit.server.project.ProjectState.INHERITED_FROM_GLOBAL;
import static com.google.gerrit.server.project.ProjectState.INHERITED_FROM_PARENT;
import static com.google.gerrit.server.project.ProjectState.OVERRIDDEN_BY_GLOBAL;
import static com.google.gerrit.server.project.ProjectState.OVERRIDDEN_BY_PARENT;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.toSet;
import com.google.common.collect.ImmutableList;
@@ -165,17 +168,17 @@
public void createProjectWithMismatchedInput() throws Exception {
ProjectInput in = new ProjectInput();
in.name = name("foo");
- exception.expect(BadRequestException.class);
- exception.expectMessage("name must match input.name");
- gApi.projects().name("bar").create(in);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> gApi.projects().name("bar").create(in));
+ assertThat(thrown).hasMessageThat().contains("name must match input.name");
}
@Test
public void createProjectNoNameInInput() throws Exception {
ProjectInput in = new ProjectInput();
- exception.expect(BadRequestException.class);
- exception.expectMessage("input.name is required");
- gApi.projects().create(in);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> gApi.projects().create(in));
+ assertThat(thrown).hasMessageThat().contains("input.name is required");
}
@Test
@@ -183,9 +186,9 @@
ProjectInput in = new ProjectInput();
in.name = name("baz");
gApi.projects().create(in);
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Project already exists");
- gApi.projects().create(in);
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> gApi.projects().create(in));
+ assertThat(thrown).hasMessageThat().contains("Project already exists");
}
@Test
@@ -194,9 +197,9 @@
in.name = name("baz");
in.parent = "non-existing";
- exception.expect(UnprocessableEntityException.class);
- exception.expectMessage("Project Not Found: " + in.parent);
- gApi.projects().create(in);
+ UnprocessableEntityException thrown =
+ assertThrows(UnprocessableEntityException.class, () -> gApi.projects().create(in));
+ assertThat(thrown).hasMessageThat().contains("Project Not Found: " + in.parent);
}
@Test
@@ -205,9 +208,9 @@
in.name = name("baz");
in.parent = in.name;
- exception.expect(UnprocessableEntityException.class);
- exception.expectMessage("Project Not Found: " + in.parent);
- gApi.projects().create(in);
+ UnprocessableEntityException thrown =
+ assertThrows(UnprocessableEntityException.class, () -> gApi.projects().create(in));
+ assertThat(thrown).hasMessageThat().contains("Project Not Found: " + in.parent);
}
@Test
@@ -215,9 +218,11 @@
ProjectInput in = new ProjectInput();
in.name = name("foo");
in.parent = allUsers.get();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage(String.format("Cannot inherit from '%s' project", allUsers.get()));
- gApi.projects().create(in);
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> gApi.projects().create(in));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(String.format("Cannot inherit from '%s' project", allUsers.get()));
}
@Test
@@ -235,7 +240,11 @@
@Test
public void createAndDeleteBranchByPush() throws Exception {
- grant(project, "refs/*", Permission.PUSH, true);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/*").group(adminGroupUuid()).force(true))
+ .update();
projectIndexedCounter.clear();
assertThat(hasHead(project, "foo")).isFalse();
@@ -253,14 +262,14 @@
@Test
public void descriptionChangeCausesRefUpdate() throws Exception {
- RevCommit initialHead = getRemoteHead(project, RefNames.REFS_CONFIG);
+ RevCommit initialHead = projectOperations.project(project).getHead(RefNames.REFS_CONFIG);
assertThat(gApi.projects().name(project.get()).description()).isEmpty();
DescriptionInput in = new DescriptionInput();
in.description = "new project description";
gApi.projects().name(project.get()).description(in);
assertThat(gApi.projects().name(project.get()).description()).isEqualTo(in.description);
- RevCommit updatedHead = getRemoteHead(project, RefNames.REFS_CONFIG);
+ RevCommit updatedHead = projectOperations.project(project).getHead(RefNames.REFS_CONFIG);
eventRecorder.assertRefUpdatedEvents(
project.get(), RefNames.REFS_CONFIG, initialHead, updatedHead);
}
@@ -279,7 +288,7 @@
@Test
public void configChangeCausesRefUpdate() throws Exception {
- RevCommit initialHead = getRemoteHead(project, RefNames.REFS_CONFIG);
+ RevCommit initialHead = projectOperations.project(project).getHead(RefNames.REFS_CONFIG);
ConfigInfo info = gApi.projects().name(project.get()).config();
assertThat(info.defaultSubmitType.value).isEqualTo(SubmitType.MERGE_IF_NECESSARY);
@@ -290,7 +299,7 @@
info = gApi.projects().name(project.get()).config();
assertThat(info.defaultSubmitType.value).isEqualTo(SubmitType.CHERRY_PICK);
- RevCommit updatedHead = getRemoteHead(project, RefNames.REFS_CONFIG);
+ RevCommit updatedHead = projectOperations.project(project).getHead(RefNames.REFS_CONFIG);
eventRecorder.assertRefUpdatedEvents(
project.get(), RefNames.REFS_CONFIG, initialHead, updatedHead);
}
@@ -354,9 +363,9 @@
public void nonOwnerCannotSetConfig() throws Exception {
ConfigInput input = createTestConfigInput();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("write refs/meta/config not permitted");
- gApi.projects().name(project.get()).config(input);
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.projects().name(project.get()).config(input));
+ assertThat(thrown).hasMessageThat().contains("write refs/meta/config not permitted");
}
@Test
@@ -372,8 +381,9 @@
@Test
public void setHeadToNonexistentBranch() throws Exception {
- exception.expect(UnprocessableEntityException.class);
- gApi.projects().name(project.get()).head("does-not-exist");
+ assertThrows(
+ UnprocessableEntityException.class,
+ () -> gApi.projects().name(project.get()).head("does-not-exist"));
}
@Test
@@ -389,9 +399,9 @@
public void setHeadNotAllowed() throws Exception {
gApi.projects().name(project.get()).branch("test").create(new BranchInput());
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("not permitted: set HEAD on refs/heads/test");
- gApi.projects().name(project.get()).head("test");
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> gApi.projects().name(project.get()).head("test"));
+ assertThat(thrown).hasMessageThat().contains("not permitted: set HEAD on refs/heads/test");
}
@Test
@@ -421,8 +431,18 @@
assertThat(gApi.projects().name(project.get()).config().state).isEqualTo(ProjectState.HIDDEN);
// Revoke OWNER permission for admin and block them from reading the project's refs
- block(project, RefNames.REFS + "*", Permission.OWNER, SystemGroupBackend.REGISTERED_USERS);
- block(project, RefNames.REFS + "*", Permission.READ, SystemGroupBackend.REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(
+ block(Permission.OWNER)
+ .ref(RefNames.REFS + "*")
+ .group(SystemGroupBackend.REGISTERED_USERS))
+ .add(
+ block(Permission.READ)
+ .ref(RefNames.REFS + "*")
+ .group(SystemGroupBackend.REGISTERED_USERS))
+ .update();
// HIDDEN => ACTIVE
ConfigInput ci2 = new ConfigInput();
@@ -614,9 +634,9 @@
@Test
public void invalidMaxObjectSizeIsRejected() throws Exception {
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("100 foo");
- setMaxObjectSize("100 foo");
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> setMaxObjectSize("100 foo"));
+ assertThat(thrown).hasMessageThat().contains("100 foo");
}
@Test
@@ -721,7 +741,7 @@
@Nullable
protected RevCommit getRemoteHead(String project, String branch) throws Exception {
- return getRemoteHead(Project.nameKey(project), branch);
+ return projectOperations.project(Project.nameKey(project)).getHead(branch);
}
boolean hasHead(Project.NameKey k, String b) {
diff --git a/javatests/com/google/gerrit/acceptance/api/project/ProjectIndexerIT.java b/javatests/com/google/gerrit/acceptance/api/project/ProjectIndexerIT.java
index 6b511f6..5892536 100644
--- a/javatests/com/google/gerrit/acceptance/api/project/ProjectIndexerIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/project/ProjectIndexerIT.java
@@ -16,6 +16,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.GitUtil.fetch;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.acceptance.AbstractDaemonTest;
@@ -117,15 +118,15 @@
private void updateProjectConfigWithoutIndexUpdate(
Project.NameKey project, Consumer<ProjectConfig> update) throws Exception {
- try (AutoCloseable ignored = disableProjectIndex()) {
- try (ProjectConfigUpdate u = updateProject(project)) {
- update.accept(u.getConfig());
- u.save();
- }
- } catch (UnsupportedOperationException e) {
- // Drop, as we just wanted to drop the index update
- return;
- }
- fail("should have a UnsupportedOperationException");
+ assertThrows(
+ UnsupportedOperationException.class,
+ () -> {
+ try (AutoCloseable ignored = disableProjectIndex()) {
+ try (ProjectConfigUpdate u = updateProject(project)) {
+ update.accept(u.getConfig());
+ u.save();
+ }
+ }
+ });
}
}
diff --git a/javatests/com/google/gerrit/acceptance/api/project/SetParentIT.java b/javatests/com/google/gerrit/acceptance/api/project/SetParentIT.java
index 3c1428d..82eef1d 100644
--- a/javatests/com/google/gerrit/acceptance/api/project/SetParentIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/project/SetParentIT.java
@@ -15,6 +15,8 @@
package com.google.gerrit.acceptance.api.project;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GerritConfig;
@@ -34,7 +36,6 @@
@NoHttpd
public class SetParentIT extends AbstractDaemonTest {
-
@Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@@ -42,8 +43,7 @@
public void setParentNotAllowed() throws Exception {
String parent = projectOperations.newProject().create().get();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- gApi.projects().name(project.get()).parent(parent);
+ assertThrows(AuthException.class, () -> gApi.projects().name(project.get()).parent(parent));
}
@Test
@@ -51,8 +51,7 @@
public void setParentNotAllowedForNonOwners() throws Exception {
String parent = projectOperations.newProject().create().get();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- gApi.projects().name(project.get()).parent(parent);
+ assertThrows(AuthException.class, () -> gApi.projects().name(project.get()).parent(parent));
}
@Test
@@ -75,7 +74,11 @@
public void setParentAllowedForOwners() throws Exception {
String parent = projectOperations.newProject().create().get();
requestScopeOperations.setApiUser(user.id());
- grant(project, "refs/*", Permission.OWNER, false, SystemGroupBackend.REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.OWNER).ref("refs/*").group(SystemGroupBackend.REGISTERED_USERS))
+ .update();
gApi.projects().name(project.get()).parent(parent);
assertThat(gApi.projects().name(project.get()).parent()).isEqualTo(parent);
}
@@ -96,47 +99,63 @@
@Test
public void setParentForAllProjectsNotAllowed() throws Exception {
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("cannot set parent of " + AllProjectsNameProvider.DEFAULT);
- gApi.projects().name(allProjects.get()).parent(project.get());
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.projects().name(allProjects.get()).parent(project.get()));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("cannot set parent of " + AllProjectsNameProvider.DEFAULT);
}
@Test
public void setParentToSelfNotAllowed() throws Exception {
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("cannot set parent to self");
- gApi.projects().name(project.get()).parent(project.get());
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.projects().name(project.get()).parent(project.get()));
+ assertThat(thrown).hasMessageThat().contains("cannot set parent to self");
}
@Test
public void setParentToOwnChildNotAllowed() throws Exception {
String child = projectOperations.newProject().parent(project).create().get();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("cycle exists between");
- gApi.projects().name(project.get()).parent(child);
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.projects().name(project.get()).parent(child));
+ assertThat(thrown).hasMessageThat().contains("cycle exists between");
}
@Test
public void setParentToGrandchildNotAllowed() throws Exception {
Project.NameKey child = projectOperations.newProject().parent(project).create();
String grandchild = projectOperations.newProject().parent(child).create().get();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("cycle exists between");
- gApi.projects().name(project.get()).parent(grandchild);
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.projects().name(project.get()).parent(grandchild));
+ assertThat(thrown).hasMessageThat().contains("cycle exists between");
}
@Test
public void setParentToNonexistentProject() throws Exception {
- exception.expect(UnprocessableEntityException.class);
- exception.expectMessage("not found");
- gApi.projects().name(project.get()).parent("non-existing");
+ UnprocessableEntityException thrown =
+ assertThrows(
+ UnprocessableEntityException.class,
+ () -> gApi.projects().name(project.get()).parent("non-existing"));
+ assertThat(thrown).hasMessageThat().contains("not found");
}
@Test
public void setParentToAllUsersNotAllowed() throws Exception {
- exception.expect(ResourceConflictException.class);
- exception.expectMessage(String.format("Cannot inherit from '%s' project", allUsers.get()));
- gApi.projects().name(project.get()).parent(allUsers.get());
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.projects().name(project.get()).parent(allUsers.get()));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(String.format("Cannot inherit from '%s' project", allUsers.get()));
}
@Test
@@ -145,8 +164,9 @@
String parent = projectOperations.newProject().create().get();
- exception.expect(BadRequestException.class);
- exception.expectMessage("All-Users must inherit from All-Projects");
- gApi.projects().name(allUsers.get()).parent(parent);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class, () -> gApi.projects().name(allUsers.get()).parent(parent));
+ assertThat(thrown).hasMessageThat().contains("All-Users must inherit from All-Projects");
}
}
diff --git a/javatests/com/google/gerrit/acceptance/api/revision/RevisionIT.java b/javatests/com/google/gerrit/acceptance/api/revision/RevisionIT.java
index a569cfa..736c127 100644
--- a/javatests/com/google/gerrit/acceptance/api/revision/RevisionIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/revision/RevisionIT.java
@@ -21,12 +21,14 @@
import static com.google.gerrit.acceptance.PushOneCommit.PATCH;
import static com.google.gerrit.acceptance.PushOneCommit.PATCH_FILE_ONLY;
import static com.google.gerrit.acceptance.PushOneCommit.SUBJECT;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.extensions.client.ListChangesOption.ALL_REVISIONS;
import static com.google.gerrit.extensions.client.ListChangesOption.DETAILED_LABELS;
import static com.google.gerrit.git.ObjectIds.abbreviateName;
import static com.google.gerrit.reviewdb.client.Patch.COMMIT_MSG;
import static com.google.gerrit.reviewdb.client.Patch.MERGE_LIST;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.stream.Collectors.toList;
import static org.eclipse.jgit.lib.Constants.HEAD;
@@ -42,6 +44,7 @@
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.TestProjectInput;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.changes.ChangeApi;
@@ -114,10 +117,10 @@
import org.junit.Test;
public class RevisionIT extends AbstractDaemonTest {
-
@Inject private DynamicSet<ChangeIndexedListener> changeIndexedListeners;
@Inject private DynamicSet<PatchSetWebLink> patchSetLinks;
@Inject private GetRevisionActions getRevisionActions;
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Test
@@ -181,14 +184,13 @@
assertThat(approval.postSubmit).isNull();
// Reducing vote is not allowed.
- try {
- gApi.changes().id(changeId).current().review(ReviewInput.dislike());
- fail("expected ResourceConflictException");
- } catch (ResourceConflictException e) {
- assertThat(e)
- .hasMessageThat()
- .isEqualTo("Cannot reduce vote on labels for closed change: Code-Review");
- }
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(changeId).current().review(ReviewInput.dislike()));
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo("Cannot reduce vote on labels for closed change: Code-Review");
approval = getApproval(changeId, label);
assertThat(approval.value).isEqualTo(1);
assertThat(approval.postSubmit).isNull();
@@ -201,14 +203,13 @@
assertPermitted(gApi.changes().id(changeId).get(DETAILED_LABELS), "Code-Review", 2);
// Decreasing to previous post-submit vote is still not allowed.
- try {
- gApi.changes().id(changeId).current().review(ReviewInput.dislike());
- fail("expected ResourceConflictException");
- } catch (ResourceConflictException e) {
- assertThat(e)
- .hasMessageThat()
- .isEqualTo("Cannot reduce vote on labels for closed change: Code-Review");
- }
+ thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(changeId).current().review(ReviewInput.dislike()));
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo("Cannot reduce vote on labels for closed change: Code-Review");
approval = getApproval(changeId, label);
assertThat(approval.value).isEqualTo(2);
assertThat(approval.postSubmit).isTrue();
@@ -260,9 +261,11 @@
ReviewInput in = new ReviewInput();
in.label("Code-Review", 0);
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Cannot reduce vote on labels for closed change: Code-Review");
- revision(r).review(in);
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> revision(r).review(in));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Cannot reduce vote on labels for closed change: Code-Review");
}
@TestProjectInput(submitType = SubmitType.CHERRY_PICK)
@@ -278,28 +281,36 @@
PatchSetApproval psa =
Iterators.getOnlyElement(
cd.currentApprovals().stream().filter(a -> !a.isLegacySubmit()).iterator());
- assertThat(psa.getPatchSetId().get()).isEqualTo(2);
- assertThat(psa.getLabel()).isEqualTo("Code-Review");
- assertThat(psa.getValue()).isEqualTo(2);
- assertThat(psa.isPostSubmit()).isFalse();
+ assertThat(psa.patchSetId().get()).isEqualTo(2);
+ assertThat(psa.label()).isEqualTo("Code-Review");
+ assertThat(psa.value()).isEqualTo(2);
+ assertThat(psa.postSubmit()).isFalse();
}
@Test
public void voteOnAbandonedChange() throws Exception {
PushOneCommit.Result r = createChange();
gApi.changes().id(r.getChangeId()).abandon();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("change is closed");
- gApi.changes().id(r.getChangeId()).current().review(ReviewInput.reject());
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(r.getChangeId()).current().review(ReviewInput.reject()));
+ assertThat(thrown).hasMessageThat().contains("change is closed");
}
@Test
public void voteNotAllowedWithoutPermission() throws Exception {
PushOneCommit.Result r = createChange();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("is restricted");
- gApi.changes().id(r.getChange().getId().get()).current().review(ReviewInput.approve());
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () ->
+ gApi.changes()
+ .id(r.getChange().getId().get())
+ .current()
+ .review(ReviewInput.approve()));
+ assertThat(thrown).hasMessageThat().contains("is restricted");
}
@Test
@@ -455,9 +466,11 @@
cherry.current().review(ReviewInput.approve());
cherry.current().submit();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Cherry pick failed: identical tree");
- orig.revision(r.getCommit().name()).cherryPick(in);
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> orig.revision(r.getCommit().name()).cherryPick(in));
+ assertThat(thrown).hasMessageThat().contains("Cherry pick failed: identical tree");
}
@Test
@@ -481,9 +494,11 @@
ChangeApi orig = gApi.changes().id(triplet);
assertThat(orig.get().messages).hasSize(1);
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Cherry pick failed: merge conflict");
- orig.revision(r.getCommit().name()).cherryPick(in);
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> orig.revision(r.getCommit().name()).cherryPick(in));
+ assertThat(thrown).hasMessageThat().contains("Cherry pick failed: merge conflict");
}
@Test
@@ -521,12 +536,11 @@
CherryPickInput in = new CherryPickInput();
in.destination = destBranch;
in.message = "Cherry-Pick";
- try {
- changeApi.revision(r.getCommit().name()).cherryPickAsInfo(in);
- fail("expected ResourceConflictException");
- } catch (ResourceConflictException e) {
- assertThat(e.getMessage()).isEqualTo("Cherry pick failed: merge conflict");
- }
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> changeApi.revision(r.getCommit().name()).cherryPickAsInfo(in));
+ assertThat(thrown).hasMessageThat().isEqualTo("Cherry pick failed: merge conflict");
// Cherry-pick with auto merge should succeed.
in.allowConflicts = true;
@@ -550,7 +564,7 @@
ByteArrayOutputStream os = new ByteArrayOutputStream();
bin.writeTo(os);
String fileContent = new String(os.toByteArray(), UTF_8);
- String destSha1 = abbreviateName(getRemoteHead(project, destBranch), 6);
+ String destSha1 = abbreviateName(projectOperations.project(project).getHead(destBranch), 6);
String changeSha1 = abbreviateName(r.getCommit(), 6);
assertThat(fileContent)
.isEqualTo(
@@ -603,16 +617,15 @@
CherryPickInput in = new CherryPickInput();
in.destination = "foo";
in.message = r1.getCommit().getFullMessage();
- try {
- gApi.changes().id(t1).current().cherryPick(in);
- fail("expected ResourceConflictException");
- } catch (ResourceConflictException e) {
- assertThat(e.getMessage())
- .isEqualTo(
- "Cannot create new patch set of change "
- + info(t2)._number
- + " because it is abandoned");
- }
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class, () -> gApi.changes().id(t1).current().cherryPick(in));
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo(
+ "Cannot create new patch set of change "
+ + info(t2)._number
+ + " because it is abandoned");
gApi.changes().id(t2).restore();
gApi.changes().id(t1).current().cherryPick(in);
@@ -690,10 +703,17 @@
cherryPickInput.message = "Cherry-pick a merge commit to another branch";
cherryPickInput.parent = 0;
- exception.expect(BadRequestException.class);
- exception.expectMessage(
- "Cherry Pick: Parent 0 does not exist. Please specify a parent in range [1, 2].");
- gApi.changes().id(mergeChangeResult.getChangeId()).current().cherryPick(cherryPickInput);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () ->
+ gApi.changes()
+ .id(mergeChangeResult.getChangeId())
+ .current()
+ .cherryPick(cherryPickInput));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Cherry Pick: Parent 0 does not exist. Please specify a parent in range [1, 2].");
}
@Test
@@ -711,10 +731,17 @@
cherryPickInput.message = "Cherry-pick a merge commit to another branch";
cherryPickInput.parent = 3;
- exception.expect(BadRequestException.class);
- exception.expectMessage(
- "Cherry Pick: Parent 3 does not exist. Please specify a parent in range [1, 2].");
- gApi.changes().id(mergeChangeResult.getChangeId()).current().cherryPick(cherryPickInput);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () ->
+ gApi.changes()
+ .id(mergeChangeResult.getChangeId())
+ .current()
+ .cherryPick(cherryPickInput));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Cherry Pick: Parent 3 does not exist. Please specify a parent in range [1, 2].");
}
@Test
@@ -851,10 +878,13 @@
input.message = srcChange.getCommit().getFullMessage();
requestScopeOperations.setApiUser(user.id());
- exception.expect(UnprocessableEntityException.class);
- exception.expectMessage(
- String.format("Commit %s does not exist on branch refs/heads/foo", input.base));
- gApi.changes().id(srcChange.getChangeId()).current().cherryPick(input).get();
+ UnprocessableEntityException thrown =
+ assertThrows(
+ UnprocessableEntityException.class,
+ () -> gApi.changes().id(srcChange.getChangeId()).current().cherryPick(input).get());
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(String.format("Commit %s does not exist on branch refs/heads/foo", input.base));
}
@Test
@@ -868,12 +898,16 @@
input.base = change2.getCommit().name();
input.message = change1.getCommit().getFullMessage();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage(
- String.format(
- "Change %s with commit %s is abandoned",
- change2.getChange().getId().get(), input.base));
- gApi.changes().id(change1.getChangeId()).current().cherryPick(input);
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(change1.getChangeId()).current().cherryPick(input));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ String.format(
+ "Change %s with commit %s is abandoned",
+ change2.getChange().getId().get(), input.base));
}
@Test
@@ -885,9 +919,13 @@
input.base = "invalid-sha1";
input.message = change1.getCommit().getFullMessage();
- exception.expect(BadRequestException.class);
- exception.expectMessage(String.format("Base %s doesn't represent a valid SHA-1", input.base));
- gApi.changes().id(change1.getChangeId()).current().cherryPick(input);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () -> gApi.changes().id(change1.getChangeId()).current().cherryPick(input));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(String.format("Base %s doesn't represent a valid SHA-1", input.base));
}
@Test
@@ -996,8 +1034,8 @@
// Make the same change in a separate commit and update server HEAD behind Gerrit's back, which
// will not reindex any open changes.
- try (Repository repo = repoManager.openRepository(project)) {
- TestRepository<?> tr = new TestRepository<>(repo);
+ try (Repository repo = repoManager.openRepository(project);
+ TestRepository<Repository> tr = new TestRepository<>(repo)) {
String ref = "refs/heads/master";
assertThat(repo.exactRef(ref).getObjectId()).isEqualTo(r1.getCommit());
tr.update(ref, tr.getRevWalk().parseCommit(initial));
@@ -1132,16 +1170,26 @@
PushOneCommit.Result r = createChange();
assertDescription(r, "");
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("edit description not permitted");
- gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).description("test");
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () ->
+ gApi.changes()
+ .id(r.getChangeId())
+ .revision(r.getCommit().name())
+ .description("test"));
+ assertThat(thrown).hasMessageThat().contains("edit description not permitted");
}
@Test
public void setDescriptionAllowedWithPermission() throws Exception {
PushOneCommit.Result r = createChange();
assertDescription(r, "");
- grant(project, "refs/heads/master", Permission.OWNER, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.OWNER).ref("refs/heads/master").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
gApi.changes().id(r.getChangeId()).revision(r.getCommit().name()).description("test");
assertDescription(r, "test");
@@ -1317,8 +1365,8 @@
@Test
public void commentOnNonExistingFile() throws Exception {
- PushOneCommit.Result r = createChange();
- r = updateChange(r, "new content");
+ PushOneCommit.Result r1 = createChange();
+ PushOneCommit.Result r2 = updateChange(r1, "new content");
CommentInput in = new CommentInput();
in.line = 1;
in.message = "nit: trailing whitespace";
@@ -1329,10 +1377,14 @@
reviewInput.comments = comments;
reviewInput.message = "comment test";
- exception.expect(BadRequestException.class);
- exception.expectMessage(
- String.format("not found in revision %d,1", r.getChange().change().getId().get()));
- gApi.changes().id(r.getChangeId()).revision(1).review(reviewInput);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () -> gApi.changes().id(r2.getChangeId()).revision(1).review(reviewInput));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ String.format("not found in revision %d,1", r2.getChange().change().getId().get()));
}
@Test
@@ -1360,9 +1412,11 @@
String res = new String(os.toByteArray(), UTF_8);
assertThat(res).isEqualTo(PATCH_FILE_ONLY);
- exception.expect(ResourceNotFoundException.class);
- exception.expectMessage("File not found: nonexistent-file.");
- changeApi.revision(r.getCommit().name()).patch("nonexistent-file");
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> changeApi.revision(r.getCommit().name()).patch("nonexistent-file"));
+ assertThat(thrown).hasMessageThat().contains("File not found: nonexistent-file.");
}
@Test
@@ -1410,13 +1464,16 @@
// check if it's blocked to delete a vote on a non-current patch set.
requestScopeOperations.setApiUser(admin.id());
- exception.expect(MethodNotAllowedException.class);
- exception.expectMessage("Cannot access on non-current patch set");
- gApi.changes()
- .id(r.getChangeId())
- .revision(r.getCommit().getName())
- .reviewer(user.id().toString())
- .deleteVote("Code-Review");
+ MethodNotAllowedException thrown =
+ assertThrows(
+ MethodNotAllowedException.class,
+ () ->
+ gApi.changes()
+ .id(r.getChangeId())
+ .revision(r.getCommit().getName())
+ .reviewer(user.id().toString())
+ .deleteVote("Code-Review"));
+ assertThat(thrown).hasMessageThat().contains("Cannot access on non-current patch set");
}
@Test
diff --git a/javatests/com/google/gerrit/acceptance/api/revision/RobotCommentsIT.java b/javatests/com/google/gerrit/acceptance/api/revision/RobotCommentsIT.java
index ba228f6..62a7037 100644
--- a/javatests/com/google/gerrit/acceptance/api/revision/RobotCommentsIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/revision/RobotCommentsIT.java
@@ -18,6 +18,7 @@
import static com.google.gerrit.acceptance.PushOneCommit.SUBJECT;
import static com.google.gerrit.extensions.common.testing.EditInfoSubject.assertThat;
import static com.google.gerrit.extensions.common.testing.RobotCommentInfoSubject.assertThatList;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.toList;
import com.google.common.collect.ImmutableList;
@@ -164,9 +165,10 @@
int sizeOfRest = 451;
fixReplacementInfo.replacement = getStringFor(defaultSizeLimit - sizeOfRest + 1);
- exception.expect(BadRequestException.class);
- exception.expectMessage("limit");
- addRobotComment(changeId, withFixRobotCommentInput);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class, () -> addRobotComment(changeId, withFixRobotCommentInput));
+ assertThat(thrown).hasMessageThat().contains("limit");
}
@Test
@@ -187,9 +189,10 @@
int sizeLimit = 10 * 1024;
fixReplacementInfo.replacement = getStringFor(sizeLimit);
- exception.expect(BadRequestException.class);
- exception.expectMessage("limit");
- addRobotComment(changeId, withFixRobotCommentInput);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class, () -> addRobotComment(changeId, withFixRobotCommentInput));
+ assertThat(thrown).hasMessageThat().contains("limit");
}
@Test
@@ -254,12 +257,15 @@
public void descriptionOfFixSuggestionIsMandatory() throws Exception {
fixSuggestionInfo.description = null;
- exception.expect(BadRequestException.class);
- exception.expectMessage(
- String.format(
- "A description is required for the suggested fix of the robot comment on %s",
- withFixRobotCommentInput.path));
- addRobotComment(changeId, withFixRobotCommentInput);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class, () -> addRobotComment(changeId, withFixRobotCommentInput));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ String.format(
+ "A description is required for the suggested fix of the robot comment on %s",
+ withFixRobotCommentInput.path));
}
@Test
@@ -278,13 +284,16 @@
public void fixReplacementsAreMandatory() throws Exception {
fixSuggestionInfo.replacements = Collections.emptyList();
- exception.expect(BadRequestException.class);
- exception.expectMessage(
- String.format(
- "At least one replacement is required"
- + " for the suggested fix of the robot comment on %s",
- withFixRobotCommentInput.path));
- addRobotComment(changeId, withFixRobotCommentInput);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class, () -> addRobotComment(changeId, withFixRobotCommentInput));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ String.format(
+ "At least one replacement is required"
+ + " for the suggested fix of the robot comment on %s",
+ withFixRobotCommentInput.path));
}
@Test
@@ -305,12 +314,15 @@
public void pathOfFixReplacementIsMandatory() throws Exception {
fixReplacementInfo.path = null;
- exception.expect(BadRequestException.class);
- exception.expectMessage(
- String.format(
- "A file path must be given for the replacement of the robot comment on %s",
- withFixRobotCommentInput.path));
- addRobotComment(changeId, withFixRobotCommentInput);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class, () -> addRobotComment(changeId, withFixRobotCommentInput));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ String.format(
+ "A file path must be given for the replacement of the robot comment on %s",
+ withFixRobotCommentInput.path));
}
@Test
@@ -331,20 +343,24 @@
public void rangeOfFixReplacementIsMandatory() throws Exception {
fixReplacementInfo.range = null;
- exception.expect(BadRequestException.class);
- exception.expectMessage(
- String.format(
- "A range must be given for the replacement of the robot comment on %s",
- withFixRobotCommentInput.path));
- addRobotComment(changeId, withFixRobotCommentInput);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class, () -> addRobotComment(changeId, withFixRobotCommentInput));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ String.format(
+ "A range must be given for the replacement of the robot comment on %s",
+ withFixRobotCommentInput.path));
}
@Test
public void rangeOfFixReplacementNeedsToBeValid() throws Exception {
fixReplacementInfo.range = createRange(13, 9, 5, 10);
- exception.expect(BadRequestException.class);
- exception.expectMessage("Range (13:9 - 5:10)");
- addRobotComment(changeId, withFixRobotCommentInput);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class, () -> addRobotComment(changeId, withFixRobotCommentInput));
+ assertThat(thrown).hasMessageThat().contains("Range (13:9 - 5:10)");
}
@Test
@@ -364,9 +380,10 @@
createFixSuggestionInfo(fixReplacementInfo1, fixReplacementInfo2);
withFixRobotCommentInput.fixSuggestions = ImmutableList.of(fixSuggestionInfo);
- exception.expect(BadRequestException.class);
- exception.expectMessage("overlap");
- addRobotComment(changeId, withFixRobotCommentInput);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class, () -> addRobotComment(changeId, withFixRobotCommentInput));
+ assertThat(thrown).hasMessageThat().contains("overlap");
}
@Test
@@ -461,13 +478,16 @@
public void replacementStringOfFixReplacementIsMandatory() throws Exception {
fixReplacementInfo.replacement = null;
- exception.expect(BadRequestException.class);
- exception.expectMessage(
- String.format(
- "A content for replacement must be "
- + "indicated for the replacement of the robot comment on %s",
- withFixRobotCommentInput.path));
- addRobotComment(changeId, withFixRobotCommentInput);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class, () -> addRobotComment(changeId, withFixRobotCommentInput));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ String.format(
+ "A content for replacement must be "
+ + "indicated for the replacement of the robot comment on %s",
+ withFixRobotCommentInput.path));
}
@Test
@@ -602,9 +622,11 @@
List<String> fixIds = getFixIds(robotCommentInfos);
gApi.changes().id(changeId).current().applyFix(fixIds.get(0));
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("merge");
- gApi.changes().id(changeId).current().applyFix(fixIds.get(1));
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(changeId).current().applyFix(fixIds.get(1)));
+ assertThat(thrown).hasMessageThat().contains("merge");
}
@Test
@@ -708,8 +730,9 @@
List<String> fixIds = getFixIds(robotCommentInfos);
String fixId = Iterables.getOnlyElement(fixIds);
- exception.expect(ResourceNotFoundException.class);
- gApi.changes().id(changeId).current().applyFix(fixId);
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.changes().id(changeId).current().applyFix(fixId));
}
@Test
@@ -728,9 +751,11 @@
List<String> fixIds = getFixIds(robotCommentInfos);
String fixId = Iterables.getOnlyElement(fixIds);
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("current");
- gApi.changes().id(changeId).revision(previousRevision).applyFix(fixId);
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(changeId).revision(previousRevision).applyFix(fixId));
+ assertThat(thrown).hasMessageThat().contains("current");
}
@Test
@@ -783,9 +808,11 @@
List<String> fixIds = getFixIds(robotCommentInfos);
String fixId = Iterables.getOnlyElement(fixIds);
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("based");
- gApi.changes().id(changeId).current().applyFix(fixId);
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(changeId).current().applyFix(fixId));
+ assertThat(thrown).hasMessageThat().contains("based");
}
@Test
@@ -845,8 +872,9 @@
String fixId = Iterables.getOnlyElement(fixIds);
String nonExistentFixId = fixId + "_non-existent";
- exception.expect(ResourceNotFoundException.class);
- gApi.changes().id(changeId).current().applyFix(nonExistentFixId);
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.changes().id(changeId).current().applyFix(nonExistentFixId));
}
@Test
diff --git a/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java b/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java
index 23020fd..070b98c 100644
--- a/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java
+++ b/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java
@@ -16,6 +16,7 @@
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.extensions.client.ListChangesOption.CURRENT_COMMIT;
import static com.google.gerrit.extensions.client.ListChangesOption.CURRENT_REVISION;
import static com.google.gerrit.extensions.client.ListChangesOption.DETAILED_LABELS;
@@ -24,6 +25,7 @@
import static com.google.gerrit.extensions.restapi.testing.BinaryResultSubject.assertThat;
import static com.google.gerrit.reviewdb.client.Patch.COMMIT_MSG;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.stream.Collectors.toList;
@@ -57,7 +59,7 @@
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.ChangeMessagesUtil;
-import com.google.gerrit.server.project.testing.Util;
+import com.google.gerrit.server.project.testing.TestLabels;
import com.google.gerrit.server.restapi.change.ChangeEdits.EditMessage;
import com.google.gerrit.server.restapi.change.ChangeEdits.Post;
import com.google.gerrit.server.restapi.change.ChangeEdits.Put;
@@ -187,7 +189,7 @@
adminRestSession.post(urlPublish(changeId)).assertNoContent();
assertThat(getEdit(changeId)).isAbsent();
PatchSet newCurrentPatchSet = getCurrentPatchSet(changeId);
- assertThat(newCurrentPatchSet.getId()).isNotEqualTo(oldCurrentPatchSet.getId());
+ assertThat(newCurrentPatchSet.id()).isNotEqualTo(oldCurrentPatchSet.id());
assertChangeMessages(
changeId,
ImmutableList.of(
@@ -240,16 +242,13 @@
PatchSet currentPatchSet = getCurrentPatchSet(changeId2);
Optional<EditInfo> originalEdit = getEdit(changeId2);
- assertThat(originalEdit)
- .value()
- .baseRevision()
- .isEqualTo(previousPatchSet.getCommitId().name());
+ assertThat(originalEdit).value().baseRevision().isEqualTo(previousPatchSet.commitId().name());
Timestamp beforeRebase = originalEdit.get().commit.committer.date;
gApi.changes().id(changeId2).edit().rebase();
ensureSameBytes(getFileContentOfEdit(changeId2, FILE_NAME), CONTENT_NEW);
ensureSameBytes(getFileContentOfEdit(changeId2, FILE_NAME2), CONTENT_NEW2);
Optional<EditInfo> rebasedEdit = getEdit(changeId2);
- assertThat(rebasedEdit).value().baseRevision().isEqualTo(currentPatchSet.getCommitId().name());
+ assertThat(rebasedEdit).value().baseRevision().isEqualTo(currentPatchSet.commitId().name());
assertThat(rebasedEdit).value().commit().committer().date().isNotEqualTo(beforeRebase);
}
@@ -262,16 +261,13 @@
PatchSet currentPatchSet = getCurrentPatchSet(changeId2);
Optional<EditInfo> originalEdit = getEdit(changeId2);
- assertThat(originalEdit)
- .value()
- .baseRevision()
- .isEqualTo(previousPatchSet.getCommitId().name());
+ assertThat(originalEdit).value().baseRevision().isEqualTo(previousPatchSet.commitId().name());
Timestamp beforeRebase = originalEdit.get().commit.committer.date;
adminRestSession.post(urlRebase(changeId2)).assertNoContent();
ensureSameBytes(getFileContentOfEdit(changeId2, FILE_NAME), CONTENT_NEW);
ensureSameBytes(getFileContentOfEdit(changeId2, FILE_NAME2), CONTENT_NEW2);
Optional<EditInfo> rebasedEdit = getEdit(changeId2);
- assertThat(rebasedEdit).value().baseRevision().isEqualTo(currentPatchSet.getCommitId().name());
+ assertThat(rebasedEdit).value().baseRevision().isEqualTo(currentPatchSet.commitId().name());
assertThat(rebasedEdit).value().commit().committer().date().isNotEqualTo(beforeRebase);
}
@@ -281,7 +277,7 @@
createEmptyEditFor(changeId2);
gApi.changes().id(changeId2).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW));
Optional<EditInfo> edit = getEdit(changeId2);
- assertThat(edit).value().baseRevision().isEqualTo(currentPatchSet.getCommitId().name());
+ assertThat(edit).value().baseRevision().isEqualTo(currentPatchSet.commitId().name());
PushOneCommit push =
pushFactory.create(
admin.newIdent(),
@@ -325,9 +321,13 @@
createEmptyEditFor(changeId);
String commitMessage = gApi.changes().id(changeId).edit().getCommitMessage();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("New commit message cannot be same as existing commit message");
- gApi.changes().id(changeId).edit().modifyCommitMessage(commitMessage);
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(changeId).edit().modifyCommitMessage(commitMessage));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("New commit message cannot be same as existing commit message");
}
@Test
@@ -335,9 +335,13 @@
createEmptyEditFor(changeId);
String commitMessage = gApi.changes().id(changeId).edit().getCommitMessage();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("New commit message cannot be same as existing commit message");
- gApi.changes().id(changeId).edit().modifyCommitMessage(commitMessage + "\n\n");
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.changes().id(changeId).edit().modifyCommitMessage(commitMessage + "\n\n"));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("New commit message cannot be same as existing commit message");
}
@Test
@@ -388,7 +392,7 @@
r = adminRestSession.getJsonAccept(urlEditMessage(changeId, true));
try (Repository repo = repoManager.openRepository(project);
RevWalk rw = new RevWalk(repo)) {
- RevCommit commit = rw.parseCommit(ObjectId.fromString(ps.getCommitId().name()));
+ RevCommit commit = rw.parseCommit(ObjectId.fromString(ps.commitId().name()));
assertThat(readContentFromJson(r)).isEqualTo(commit.getFullMessage());
}
@@ -582,16 +586,22 @@
@Test
public void writeNoChanges() throws Exception {
createEmptyEditFor(changeId);
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("no changes were made");
- gApi.changes().id(changeId).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_OLD));
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () ->
+ gApi.changes()
+ .id(changeId)
+ .edit()
+ .modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_OLD)));
+ assertThat(thrown).hasMessageThat().contains("no changes were made");
}
@Test
public void editCommitMessageCopiesLabelScores() throws Exception {
String cr = "Code-Review";
try (ProjectConfigUpdate u = updateProject(project)) {
- LabelType codeReview = Util.codeReview();
+ LabelType codeReview = TestLabels.codeReview();
codeReview.setCopyAllScoresIfNoCodeChange(true);
u.getConfig().getLabelSections().put(cr, codeReview);
u.save();
@@ -684,7 +694,11 @@
TestRepository<InMemoryRepository> userTestRepo = cloneProject(p, user);
// Block default permission
- block(p, "refs/for/*", Permission.ADD_PATCH_SET, REGISTERED_USERS);
+ projectOperations
+ .project(p)
+ .forUpdate()
+ .add(block(Permission.ADD_PATCH_SET).ref("refs/for/*").group(REGISTERED_USERS))
+ .update();
// Create change as user
PushOneCommit push = pushFactory.create(user.newIdent(), userTestRepo);
@@ -692,8 +706,7 @@
r1.assertOkStatus();
// Try to create edit as admin
- exception.expect(AuthException.class);
- createEmptyEditFor(r1.getChangeId());
+ assertThrows(AuthException.class, () -> createEmptyEditFor(r1.getChangeId()));
}
@Test
@@ -702,9 +715,11 @@
gApi.changes().id(changeId).current().review(ReviewInput.approve());
gApi.changes().id(changeId).current().submit();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage(String.format("change %s is merged", change._number));
- createArbitraryEditFor(changeId);
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> createArbitraryEditFor(changeId));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(String.format("change %s is merged", change._number));
}
@Test
@@ -712,9 +727,11 @@
ChangeInfo change = gApi.changes().id(changeId).get();
gApi.changes().id(changeId).abandon();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage(String.format("change %s is abandoned", change._number));
- createArbitraryEditFor(changeId);
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> createArbitraryEditFor(changeId));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(String.format("change %s is abandoned", change._number));
}
private void createArbitraryEditFor(String changeId) throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java b/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
index 50001b1..c27bb69 100644
--- a/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
+++ b/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
@@ -24,6 +24,10 @@
import static com.google.gerrit.acceptance.GitUtil.pushHead;
import static com.google.gerrit.acceptance.GitUtil.pushOne;
import static com.google.gerrit.acceptance.PushOneCommit.FILE_NAME;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.common.FooterConstants.CHANGE_ID;
import static com.google.gerrit.extensions.client.ListChangesOption.ALL_REVISIONS;
import static com.google.gerrit.extensions.client.ListChangesOption.CURRENT_REVISION;
@@ -34,8 +38,8 @@
import static com.google.gerrit.server.git.receive.ReceiveConstants.PUSH_OPTION_SKIP_VALIDATION;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
-import static com.google.gerrit.server.project.testing.Util.category;
-import static com.google.gerrit.server.project.testing.Util.value;
+import static com.google.gerrit.server.project.testing.TestLabels.label;
+import static com.google.gerrit.server.project.testing.TestLabels.value;
import static java.util.Comparator.comparing;
import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.stream.Collectors.joining;
@@ -54,6 +58,7 @@
import com.google.gerrit.acceptance.SkipProjectClone;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.TestProjectInput;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.common.data.LabelType;
@@ -93,7 +98,7 @@
import com.google.gerrit.server.git.receive.ReceiveConstants;
import com.google.gerrit.server.git.validators.CommitValidators.ChangeIdValidator;
import com.google.gerrit.server.group.SystemGroupBackend;
-import com.google.gerrit.server.project.testing.Util;
+import com.google.gerrit.server.project.testing.TestLabels;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.testing.FakeEmailSender.Message;
import com.google.gerrit.testing.TestTimeUtil;
@@ -131,11 +136,17 @@
@SkipProjectClone
public abstract class AbstractPushForReview extends AbstractDaemonTest {
protected enum Protocol {
- // TODO(dborowitz): TEST.
+ // Only test protocols which are actually served by the Gerrit server, since each separate test
+ // class is large and slow.
+ //
+ // This list excludes the test InProcessProtocol, which is used by large numbers of other
+ // acceptance tests. Small tests of InProcessProtocol are still possible, without incurring a
+ // new large slow test.
SSH,
HTTP
}
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
private static String NEW_CHANGE_INDICATOR = " [NEW]";
@@ -154,19 +165,24 @@
@Before
public void setUpPatchSetLock() throws Exception {
try (ProjectConfigUpdate u = updateProject(project)) {
- patchSetLock = Util.patchSetLock();
+ patchSetLock = TestLabels.patchSetLock();
u.getConfig().getLabelSections().put(patchSetLock.getName(), patchSetLock);
- AccountGroup.UUID anonymousUsers = systemGroupBackend.getGroup(ANONYMOUS_USERS).getUUID();
- Util.allow(
- u.getConfig(),
- Permission.forLabel(patchSetLock.getName()),
- 0,
- 1,
- anonymousUsers,
- "refs/heads/*");
u.save();
}
- grant(project, "refs/heads/*", Permission.LABEL + "Patch-Set-Lock");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(
+ allowLabel(patchSetLock.getName())
+ .ref("refs/heads/*")
+ .group(ANONYMOUS_USERS)
+ .range(0, 1))
+ .add(
+ allowLabel(patchSetLock.getName())
+ .ref("refs/heads/*")
+ .group(adminGroupUuid())
+ .range(0, 1))
+ .update();
}
@After
@@ -844,7 +860,7 @@
assertThat(r.getChange().change().isWorkInProgress()).isTrue();
// Admin user trying to move from WIP to ready should succeed.
- GitUtil.fetch(testRepo, r.getPatchSet().getRefName() + ":ps");
+ GitUtil.fetch(testRepo, r.getPatchSet().refName() + ":ps");
testRepo.reset("ps");
r = amendChange(r.getChangeId(), "refs/for/master%ready", user, testRepo);
r.assertOkStatus();
@@ -860,7 +876,7 @@
assertThat(r.getChange().change().isWorkInProgress()).isFalse();
// Admin user trying to move from ready to WIP should succeed.
- GitUtil.fetch(testRepo, r.getPatchSet().getRefName() + ":ps");
+ GitUtil.fetch(testRepo, r.getPatchSet().refName() + ":ps");
testRepo.reset("ps");
r = amendChange(r.getChangeId(), "refs/for/master%wip", admin, testRepo);
r.assertOkStatus();
@@ -871,16 +887,26 @@
// Non owner, non admin and non project owner cannot flip wip bit:
TestAccount user2 = accountCreator.user2();
- grant(
- project, "refs/*", Permission.FORGE_COMMITTER, false, SystemGroupBackend.REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(
+ allow(Permission.FORGE_COMMITTER)
+ .ref("refs/*")
+ .group(SystemGroupBackend.REGISTERED_USERS))
+ .update();
TestRepository<?> user2Repo = cloneProject(project, user2);
- GitUtil.fetch(user2Repo, r.getPatchSet().getRefName() + ":ps");
+ GitUtil.fetch(user2Repo, r.getPatchSet().refName() + ":ps");
user2Repo.reset("ps");
r = amendChange(r.getChangeId(), "refs/for/master%ready", user2, user2Repo);
r.assertErrorStatus(ReceiveConstants.ONLY_CHANGE_OWNER_OR_PROJECT_OWNER_CAN_MODIFY_WIP);
// Project owner trying to move from WIP to ready should succeed.
- allow("refs/*", Permission.OWNER, SystemGroupBackend.REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.OWNER).ref("refs/*").group(SystemGroupBackend.REGISTERED_USERS))
+ .update();
r = amendChange(r.getChangeId(), "refs/for/master%ready", user2, user2Repo);
r.assertOkStatus();
}
@@ -1181,14 +1207,17 @@
@Test
public void pushWithMultipleApprovals() throws Exception {
LabelType Q =
- category("Custom-Label", value(1, "Positive"), value(0, "No score"), value(-1, "Negative"));
- AccountGroup.UUID anon = systemGroupBackend.getGroup(ANONYMOUS_USERS).getUUID();
+ label("Custom-Label", value(1, "Positive"), value(0, "No score"), value(-1, "Negative"));
String heads = "refs/heads/*";
try (ProjectConfigUpdate u = updateProject(project)) {
- Util.allow(u.getConfig(), Permission.forLabel("Custom-Label"), -1, 1, anon, heads);
u.getConfig().getLabelSections().put(Q.getName(), Q);
u.save();
}
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allowLabel("Custom-Label").ref(heads).group(ANONYMOUS_USERS).range(-1, 1))
+ .update();
RevCommit c =
commitBuilder()
@@ -1349,7 +1378,11 @@
r.assertOkStatus();
setUseSignedOffBy(InheritableBoolean.TRUE);
- block(project, "refs/heads/master", Permission.FORGE_COMMITTER, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.FORGE_COMMITTER).ref("refs/heads/master").group(REGISTERED_USERS))
+ .update();
push =
pushFactory.create(
@@ -1405,7 +1438,7 @@
// create a second change as user (depends on the change from admin)
TestRepository<?> userRepo = cloneProject(project, user);
- GitUtil.fetch(userRepo, r.getPatchSet().getRefName() + ":change");
+ GitUtil.fetch(userRepo, r.getPatchSet().refName() + ":change");
userRepo.reset("change");
push =
pushFactory.create(
@@ -1419,7 +1452,11 @@
@Test
public void pushSameCommitTwiceUsingMagicBranchBaseOption() throws Exception {
- grant(project, "refs/heads/master", Permission.PUSH);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/heads/master").group(adminGroupUuid()))
+ .update();
PushOneCommit.Result rBase = pushTo("refs/heads/master");
rBase.assertOkStatus();
@@ -1779,8 +1816,8 @@
Change.Id id2 = r2.getChange().getId();
// Merge change 1 behind Gerrit's back.
- try (Repository repo = repoManager.openRepository(project)) {
- TestRepository<?> tr = new TestRepository<>(repo);
+ try (Repository repo = repoManager.openRepository(project);
+ TestRepository<?> tr = new TestRepository<>(repo)) {
tr.branch("refs/heads/master").update(r1.getCommit());
}
@@ -1802,7 +1839,7 @@
throws Exception {
Change.Id id = accidentallyPushNewPatchSetDirectlyToBranch();
ChangeData cd = byChangeId(id);
- String ps1Rev = Iterables.getOnlyElement(cd.patchSets()).getCommitId().name();
+ String ps1Rev = Iterables.getOnlyElement(cd.patchSets()).commitId().name();
String r = "refs/changes/" + id;
assertPushOk(pushHead(testRepo, r, false), r);
@@ -1820,7 +1857,7 @@
throws Exception {
Change.Id id = accidentallyPushNewPatchSetDirectlyToBranch();
ChangeData cd = byChangeId(id);
- String ps1Rev = Iterables.getOnlyElement(cd.patchSets()).getCommitId().name();
+ String ps1Rev = Iterables.getOnlyElement(cd.patchSets()).commitId().name();
String r = "refs/for/master";
assertPushRejected(pushHead(testRepo, r, false), r, "no new changes");
@@ -1833,7 +1870,11 @@
@Test
public void forcePushAbandonedChange() throws Exception {
- grant(project, "refs/*", Permission.PUSH, true);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/*").group(adminGroupUuid()).force(true))
+ .update();
PushOneCommit push1 =
pushFactory.create(admin.newIdent(), testRepo, "change1", "a.txt", "content");
PushOneCommit.Result r = push1.to("refs/for/master");
@@ -1859,12 +1900,12 @@
Change c = r.getChange().change();
RevCommit ps2Commit;
- try (Repository repo = repoManager.openRepository(project)) {
+ try (Repository repo = repoManager.openRepository(project);
+ TestRepository<?> tr = new TestRepository<>(repo)) {
// Create a new patch set of the change directly in Gerrit's repository,
// without pushing it. In reality it's more likely that the client would
// create and push this behind Gerrit's back (e.g. an admin accidentally
// using direct ssh access to the repo), but that's harder to do in tests.
- TestRepository<?> tr = new TestRepository<>(repo);
ps2Commit =
tr.branch("refs/heads/master")
.commit()
@@ -1906,7 +1947,7 @@
@Test
public void pushNewPatchsetOverridingStickyLabel() throws Exception {
try (ProjectConfigUpdate u = updateProject(project)) {
- LabelType codeReview = Util.codeReview();
+ LabelType codeReview = TestLabels.codeReview();
codeReview.setCopyMaxScore(true);
u.getConfig().getLabelSections().put(codeReview.getName(), codeReview);
u.save();
@@ -1929,7 +1970,11 @@
@Test
public void createChangeForMergedCommit() throws Exception {
String master = "refs/heads/master";
- grant(project, master, Permission.PUSH, true);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref(master).group(adminGroupUuid()).force(true))
+ .update();
// Update master with a direct push.
RevCommit c1 = testRepo.commit().message("Non-change 1").create();
@@ -1980,8 +2025,8 @@
gApi.changes().id(r.getChangeId()).current().review(ReviewInput.approve());
gApi.changes().id(r.getChangeId()).current().submit();
- try (Repository repo = repoManager.openRepository(project)) {
- TestRepository<?> tr = new TestRepository<>(repo);
+ try (Repository repo = repoManager.openRepository(project);
+ TestRepository<Repository> tr = new TestRepository<>(repo)) {
tr.branch("refs/heads/branch").commit().message("Initial commit on branch").create();
}
@@ -2028,7 +2073,11 @@
@Test
public void mergedOptionWithExistingChangeInsertsPatchSet() throws Exception {
String master = "refs/heads/master";
- grant(project, master, Permission.PUSH, true);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref(master).group(adminGroupUuid()).force(true))
+ .update();
PushOneCommit.Result r = pushTo("refs/for/master");
r.assertOkStatus();
@@ -2039,8 +2088,8 @@
// expecting the change to be auto-closed, but the change metadata update
// fails.
ObjectId c2;
- try (Repository repo = repoManager.openRepository(project)) {
- TestRepository<?> tr = new TestRepository<>(repo);
+ try (Repository repo = repoManager.openRepository(project);
+ TestRepository<Repository> tr = new TestRepository<>(repo)) {
RevCommit commit2 =
tr.amend(c1).message("New subject").insertChangeId(r.getChangeId().substring(1)).create();
c2 = commit2.copy();
@@ -2297,12 +2346,19 @@
pr = pushOne(testRepo, c.name(), ref, false, false, opts);
assertPushRejected(pr, ref, "NoteDb update requires access database permission");
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
pr = pushOne(testRepo, c.name(), ref, false, false, opts);
assertPushRejected(pr, ref, "prohibited by Gerrit: not permitted: create");
- grant(project, "refs/changes/*", Permission.CREATE);
- grant(project, "refs/changes/*", Permission.PUSH);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref("refs/changes/*").group(adminGroupUuid()))
+ .add(allow(Permission.PUSH).ref("refs/changes/*").group(adminGroupUuid()))
+ .update();
grantSkipValidation(project, "refs/changes/*", REGISTERED_USERS);
pr = pushOne(testRepo, c.name(), ref, false, false, opts);
assertPushOk(pr, ref);
@@ -2627,7 +2683,7 @@
private static Map<Integer, String> getPatchSetRevisions(ChangeData cd) throws Exception {
Map<Integer, String> revisions = new HashMap<>();
for (PatchSet ps : cd.patchSets()) {
- revisions.put(ps.getPatchSetId(), ps.getCommitId().name());
+ revisions.put(ps.number(), ps.commitId().name());
}
return revisions;
}
@@ -2668,13 +2724,14 @@
private void grantSkipValidation(Project.NameKey project, String ref, AccountGroup.UUID groupUuid)
throws Exception {
// See SKIP_VALIDATION implementation in default permission backend.
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.allow(u.getConfig(), Permission.FORGE_AUTHOR, groupUuid, ref);
- Util.allow(u.getConfig(), Permission.FORGE_COMMITTER, groupUuid, ref);
- Util.allow(u.getConfig(), Permission.FORGE_SERVER, groupUuid, ref);
- Util.allow(u.getConfig(), Permission.PUSH_MERGE, groupUuid, "refs/for/" + ref);
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.FORGE_AUTHOR).ref(ref).group(groupUuid))
+ .add(allow(Permission.FORGE_COMMITTER).ref(ref).group(groupUuid))
+ .add(allow(Permission.FORGE_SERVER).ref(ref).group(groupUuid))
+ .add(allow(Permission.PUSH_MERGE).ref("refs/for/" + ref).group(groupUuid))
+ .update();
}
private PushOneCommit.Result amendChange(String changeId, String ref) throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/git/AbstractSubmoduleSubscription.java b/javatests/com/google/gerrit/acceptance/git/AbstractSubmoduleSubscription.java
index fc2e5cb..c35b891 100644
--- a/javatests/com/google/gerrit/acceptance/git/AbstractSubmoduleSubscription.java
+++ b/javatests/com/google/gerrit/acceptance/git/AbstractSubmoduleSubscription.java
@@ -16,6 +16,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static java.util.stream.Collectors.toList;
import com.google.common.collect.Iterables;
@@ -59,11 +60,12 @@
public abstract class AbstractSubmoduleSubscription extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
+
protected TestRepository<?> superRepo;
protected Project.NameKey superKey;
protected TestRepository<?> subRepo;
protected Project.NameKey subKey;
- @Inject protected ProjectOperations projectOperations;
protected SubmitType getSubmitType() {
return cfg.getEnum("project", null, "submitType", SubmitType.MERGE_IF_NECESSARY);
@@ -105,8 +107,12 @@
}
protected void grantPush(Project.NameKey project) throws Exception {
- grant(project, "refs/heads/*", Permission.PUSH);
- grant(project, "refs/for/refs/heads/*", Permission.SUBMIT);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/heads/*").group(adminGroupUuid()))
+ .add(allow(Permission.SUBMIT).ref("refs/for/refs/heads/*").group(adminGroupUuid()))
+ .update();
}
protected Project.NameKey createProjectForPush(SubmitType submitType) throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/git/BUILD b/javatests/com/google/gerrit/acceptance/git/BUILD
index e4a643c..96710e2 100644
--- a/javatests/com/google/gerrit/acceptance/git/BUILD
+++ b/javatests/com/google/gerrit/acceptance/git/BUILD
@@ -1,8 +1,8 @@
load("//javatests/com/google/gerrit/acceptance:tests.bzl", "acceptance_tests")
-acceptance_tests(
- srcs = glob(["*IT.java"]),
- group = "git",
+[acceptance_tests(
+ srcs = [f],
+ group = f[:f.index(".")],
labels = ["git"],
deps = [
":push_for_review",
@@ -10,7 +10,7 @@
"//java/com/google/gerrit/git",
"//lib/commons:lang",
],
-)
+) for f in glob(["*IT.java"])]
java_library(
name = "push_for_review",
diff --git a/javatests/com/google/gerrit/acceptance/git/ForcePushIT.java b/javatests/com/google/gerrit/acceptance/git/ForcePushIT.java
index eb4845e..5ec7b0e 100644
--- a/javatests/com/google/gerrit/acceptance/git/ForcePushIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/ForcePushIT.java
@@ -16,6 +16,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.GitUtil.deleteRef;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static org.eclipse.jgit.lib.Constants.HEAD;
import static org.eclipse.jgit.transport.RemoteRefUpdate.Status.OK;
import static org.eclipse.jgit.transport.RemoteRefUpdate.Status.REJECTED_OTHER_REASON;
@@ -23,8 +24,10 @@
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.projects.BranchInput;
+import com.google.inject.Inject;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.transport.PushResult;
@@ -33,6 +36,7 @@
@NoHttpd
public class ForcePushIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
@Test
public void forcePushNotAllowed() throws Exception {
@@ -57,7 +61,11 @@
@Test
public void forcePushAllowed() throws Exception {
ObjectId initial = repo().exactRef(HEAD).getLeaf().getObjectId();
- grant(project, "refs/*", Permission.PUSH, true);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/*").group(adminGroupUuid()).force(true))
+ .update();
PushOneCommit push1 =
pushFactory.create(admin.newIdent(), testRepo, "change1", "a.txt", "content");
PushOneCommit.Result r1 = push1.to("refs/heads/master");
@@ -82,19 +90,31 @@
@Test
public void deleteNotAllowedWithOnlyPushPermission() throws Exception {
- grant(project, "refs/*", Permission.PUSH, false);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/*").group(adminGroupUuid()))
+ .update();
assertDeleteRef(REJECTED_OTHER_REASON);
}
@Test
public void deleteAllowedWithForcePushPermission() throws Exception {
- grant(project, "refs/*", Permission.PUSH, true);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/*").group(adminGroupUuid()).force(true))
+ .update();
assertDeleteRef(OK);
}
@Test
public void deleteAllowedWithDeletePermission() throws Exception {
- grant(project, "refs/*", Permission.DELETE, true);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.DELETE).ref("refs/*").group(adminGroupUuid()).force(true))
+ .update();
assertDeleteRef(OK);
}
diff --git a/javatests/com/google/gerrit/acceptance/git/GitmodulesIT.java b/javatests/com/google/gerrit/acceptance/git/GitmodulesIT.java
index ac0cbd8..e2aa666 100644
--- a/javatests/com/google/gerrit/acceptance/git/GitmodulesIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/GitmodulesIT.java
@@ -14,6 +14,9 @@
package com.google.gerrit.acceptance.git;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+
import com.google.gerrit.acceptance.AbstractDaemonTest;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.junit.TestRepository;
@@ -50,8 +53,15 @@
.add(".gitmodules", config.toText())
.create();
- exception.expectMessage(expectedErrorMessage);
- exception.expect(TransportException.class);
- repo.git().push().setRemote("origin").setRefSpecs(new RefSpec("HEAD:refs/for/master")).call();
+ TransportException thrown =
+ assertThrows(
+ TransportException.class,
+ () ->
+ repo.git()
+ .push()
+ .setRemote("origin")
+ .setRefSpecs(new RefSpec("HEAD:refs/for/master"))
+ .call());
+ assertThat(thrown).hasMessageThat().contains(expectedErrorMessage);
}
}
diff --git a/javatests/com/google/gerrit/acceptance/git/HttpPushForReviewIT.java b/javatests/com/google/gerrit/acceptance/git/HttpPushForReviewIT.java
index 35260d0..6b7adf1 100644
--- a/javatests/com/google/gerrit/acceptance/git/HttpPushForReviewIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/HttpPushForReviewIT.java
@@ -71,8 +71,9 @@
public void uploadPackAuditEventLog() throws Exception {
auditService.drainHttpAuditEvents();
// testRepo is already a clone. Make a server-side change so we have something to fetch.
- try (Repository repo = repoManager.openRepository(project)) {
- new TestRepository<>(repo).branch("master").commit().create();
+ try (Repository repo = repoManager.openRepository(project);
+ TestRepository<Repository> tr = new TestRepository<>(repo)) {
+ tr.branch("master").commit().create();
}
testRepo.git().fetch().call();
diff --git a/javatests/com/google/gerrit/acceptance/git/PushPermissionsIT.java b/javatests/com/google/gerrit/acceptance/git/PushPermissionsIT.java
index f682342..46012f4 100644
--- a/javatests/com/google/gerrit/acceptance/git/PushPermissionsIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/PushPermissionsIT.java
@@ -17,6 +17,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.Truth.assert_;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.git.testing.PushResultSubject.assertThat;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static java.util.stream.Collectors.toList;
@@ -24,6 +25,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.GlobalCapability;
@@ -36,7 +38,6 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.project.ProjectConfig;
-import com.google.gerrit.server.project.testing.Util;
import com.google.inject.Inject;
import java.util.Arrays;
import java.util.function.Consumer;
@@ -54,6 +55,7 @@
import org.junit.Test;
public class PushPermissionsIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Before
@@ -73,13 +75,15 @@
Permission.PUSH_MERGE,
Permission.SUBMIT);
removeAllGlobalCapabilities(cfg, GlobalCapability.ADMINISTRATE_SERVER);
-
- // Include some auxiliary permissions.
- Util.allow(cfg, Permission.FORGE_AUTHOR, REGISTERED_USERS, "refs/*");
- Util.allow(cfg, Permission.FORGE_COMMITTER, REGISTERED_USERS, "refs/*");
-
u.save();
}
+
+ // Include some auxiliary permissions.
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allow(Permission.FORGE_AUTHOR).ref("refs/*").group(REGISTERED_USERS))
+ .add(allow(Permission.FORGE_COMMITTER).ref("refs/*").group(REGISTERED_USERS))
+ .update();
}
@Test
@@ -159,8 +163,8 @@
@Test
public void groupRefsByMessage() throws Exception {
- try (Repository repo = repoManager.openRepository(project)) {
- TestRepository<?> tr = new TestRepository<>(repo);
+ try (Repository repo = repoManager.openRepository(project);
+ TestRepository<Repository> tr = new TestRepository<>(repo)) {
tr.branch("foo").commit().create();
tr.branch("bar").commit().create();
}
@@ -202,7 +206,11 @@
@Test
public void refsMetaConfigUpdateRequiresProjectOwner() throws Exception {
- grant(project, "refs/meta/config", Permission.PUSH, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/meta/config").group(REGISTERED_USERS))
+ .update();
forceFetch("refs/meta/config");
ObjectId commit = testRepo.branch("refs/meta/config").commit().create();
@@ -222,7 +230,11 @@
"Contact an administrator to fix the permissions");
assertThat(r).hasProcessed(ImmutableMap.of("refs", 1));
- grant(project, "refs/*", Permission.OWNER, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.OWNER).ref("refs/*").group(REGISTERED_USERS))
+ .update();
// Re-fetch refs/meta/config from the server because the grant changed it, and we want a
// fast-forward.
@@ -249,7 +261,11 @@
@Test
public void updateBySubmitDenied() throws Exception {
- grant(project, "refs/for/refs/heads/*", Permission.PUSH, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/for/refs/heads/*").group(REGISTERED_USERS))
+ .update();
ObjectId commit = testRepo.branch("HEAD").commit().create();
assertThat(push("HEAD:refs/for/master")).onlyRef("refs/for/master").isOk();
@@ -267,7 +283,11 @@
@Test
public void addPatchSetDenied() throws Exception {
- grant(project, "refs/for/refs/heads/*", Permission.PUSH, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/for/refs/heads/*").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
ChangeInput ci = new ChangeInput();
ci.project = project.get();
@@ -288,7 +308,11 @@
@Test
public void skipValidationDenied() throws Exception {
- grant(project, "refs/heads/*", Permission.PUSH, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/heads/*").group(REGISTERED_USERS))
+ .update();
testRepo.branch("HEAD").commit().create();
PushResult r =
@@ -305,7 +329,11 @@
@Test
public void accessDatabaseForNoteDbDenied() throws Exception {
- grant(project, "refs/heads/*", Permission.PUSH, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/heads/*").group(REGISTERED_USERS))
+ .update();
testRepo.branch("HEAD").commit().create();
PushResult r =
@@ -322,8 +350,12 @@
@Test
public void administrateServerForUpdateParentDenied() throws Exception {
- grant(project, "refs/meta/config", Permission.PUSH, false, REGISTERED_USERS);
- grant(project, "refs/*", Permission.OWNER, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/meta/config").group(REGISTERED_USERS))
+ .add(allow(Permission.OWNER).ref("refs/*").group(REGISTERED_USERS))
+ .update();
String project2 = name("project2");
gApi.projects().create(project2);
diff --git a/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java b/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
index 7182b6f..811ef35 100644
--- a/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
@@ -18,11 +18,14 @@
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.TruthJUnit.assume;
import static com.google.gerrit.acceptance.GitUtil.fetch;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.deny;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.permissionKey;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;
-import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.acceptance.AbstractDaemonTest;
@@ -30,6 +33,7 @@
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestAccount;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.AccessSection;
@@ -51,7 +55,6 @@
import com.google.gerrit.server.notedb.Sequences;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.permissions.PermissionBackend.RefFilterOptions;
-import com.google.gerrit.server.project.testing.Util;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.testing.ConfigSuite;
import com.google.inject.Inject;
@@ -71,6 +74,7 @@
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Before;
import org.junit.Test;
@@ -79,12 +83,14 @@
@Inject private AllUsersName allUsersName;
@Inject private ChangeNoteUtil noteUtil;
@Inject private PermissionBackend permissionBackend;
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
private AccountGroup.UUID admins;
private AccountGroup.UUID nonInteractiveUsers;
private ChangeData cd1;
+ private RevCommit rc1;
private String psRef1;
private String metaRef1;
@@ -122,9 +128,12 @@
for (AccessSection sec : u.getConfig().getAccessSections()) {
sec.removePermission(Permission.READ);
}
- Util.allow(u.getConfig(), Permission.READ, admins, "refs/*");
u.save();
}
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allow(Permission.READ).ref("refs/*").group(admins))
+ .update();
// Remove all read permissions on All-Users.
try (ProjectConfigUpdate u = updateProject(allUsers)) {
@@ -140,30 +149,35 @@
// First 2 changes are merged, which means the tags pointing to them are
// visible.
- allow("refs/for/refs/heads/*", Permission.SUBMIT, admins);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.SUBMIT).ref("refs/for/refs/heads/*").group(admins))
+ .update();
PushOneCommit.Result mr =
pushFactory.create(admin.newIdent(), testRepo).to("refs/for/master%submit");
mr.assertOkStatus();
cd1 = mr.getChange();
- psRef1 = cd1.currentPatchSet().getId().toRefName();
+ rc1 = mr.getCommit();
+ psRef1 = cd1.currentPatchSet().id().toRefName();
metaRef1 = RefNames.changeMetaRef(cd1.getId());
PushOneCommit.Result br =
pushFactory.create(admin.newIdent(), testRepo).to("refs/for/branch%submit");
br.assertOkStatus();
cd2 = br.getChange();
- psRef2 = cd2.currentPatchSet().getId().toRefName();
+ psRef2 = cd2.currentPatchSet().id().toRefName();
metaRef2 = RefNames.changeMetaRef(cd2.getId());
// Second 2 changes are unmerged.
mr = pushFactory.create(admin.newIdent(), testRepo).to("refs/for/master");
mr.assertOkStatus();
cd3 = mr.getChange();
- psRef3 = cd3.currentPatchSet().getId().toRefName();
+ psRef3 = cd3.currentPatchSet().id().toRefName();
metaRef3 = RefNames.changeMetaRef(cd3.getId());
br = pushFactory.create(admin.newIdent(), testRepo).to("refs/for/branch");
br.assertOkStatus();
cd4 = br.getChange();
- psRef4 = cd4.currentPatchSet().getId().toRefName();
+ psRef4 = cd4.currentPatchSet().id().toRefName();
metaRef4 = RefNames.changeMetaRef(cd4.getId());
try (Repository repo = repoManager.openRepository(project)) {
@@ -178,17 +192,26 @@
btu.setExpectedOldObjectId(ObjectId.zeroId());
btu.setNewObjectId(repo.exactRef("refs/heads/branch").getObjectId());
assertThat(btu.update()).isEqualTo(RefUpdate.Result.NEW);
+
+ // Create a tag for the tree of the commit on 'master'
+ // tree-tag -> master.tree
+ RefUpdate ttu = repo.updateRef("refs/tags/tree-tag");
+ ttu.setExpectedOldObjectId(ObjectId.zeroId());
+ ttu.setNewObjectId(rc1.getTree().toObjectId());
+ assertThat(ttu.update()).isEqualTo(RefUpdate.Result.NEW);
}
}
@Test
+ @GerritConfig(name = "auth.skipFullRefEvaluationIfAllRefsAreVisible", value = "false")
public void uploadPackAllRefsVisibleNoRefsMetaConfig() throws Exception {
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.allow(u.getConfig(), Permission.READ, REGISTERED_USERS, "refs/*");
- Util.allow(u.getConfig(), Permission.READ, admins, RefNames.REFS_CONFIG);
- Util.doNotInherit(u.getConfig(), Permission.READ, RefNames.REFS_CONFIG);
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .add(allow(Permission.READ).ref(RefNames.REFS_CONFIG).group(admins))
+ .setExclusiveGroup(permissionKey(Permission.READ).ref(RefNames.REFS_CONFIG), true)
+ .update();
requestScopeOperations.setApiUser(user.id());
assertUploadPackRefs(
@@ -205,12 +228,46 @@
"refs/heads/master",
"refs/tags/branch-tag",
"refs/tags/master-tag");
+ // tree-tag not visible. See comment in subsetOfBranchesVisibleIncludingHead.
+ }
+
+ @Test
+ @GerritConfig(name = "auth.skipFullRefEvaluationIfAllRefsAreVisible", value = "true")
+ public void uploadPackAllRefsVisibleNoRefsMetaConfigSkipFullRefEval() throws Exception {
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .add(allow(Permission.READ).ref(RefNames.REFS_CONFIG).group(admins))
+ .setExclusiveGroup(permissionKey(Permission.READ).ref(RefNames.REFS_CONFIG), true)
+ .update();
+
+ requestScopeOperations.setApiUser(user.id());
+ assertUploadPackRefs(
+ "HEAD",
+ psRef1,
+ metaRef1,
+ psRef2,
+ metaRef2,
+ psRef3,
+ metaRef3,
+ psRef4,
+ metaRef4,
+ "refs/heads/branch",
+ "refs/heads/master",
+ "refs/tags/branch-tag",
+ "refs/tags/master-tag",
+ "refs/tags/tree-tag");
}
@Test
public void uploadPackAllRefsVisibleWithRefsMetaConfig() throws Exception {
- allow("refs/*", Permission.READ, REGISTERED_USERS);
- allow(RefNames.REFS_CONFIG, Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .add(allow(Permission.READ).ref(RefNames.REFS_CONFIG).group(REGISTERED_USERS))
+ .update();
assertUploadPackRefs(
"HEAD",
@@ -226,23 +283,46 @@
"refs/heads/master",
RefNames.REFS_CONFIG,
"refs/tags/branch-tag",
- "refs/tags/master-tag");
+ "refs/tags/master-tag",
+ "refs/tags/tree-tag");
+ }
+
+ @Test
+ public void grantReadOnRefsTagsIsNoOp() throws Exception {
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/tags/*").group(REGISTERED_USERS))
+ .update();
+
+ requestScopeOperations.setApiUser(user.id());
+ assertUploadPackRefs(); // We expect no refs returned
}
@Test
public void uploadPackSubsetOfBranchesVisibleIncludingHead() throws Exception {
- allow("refs/heads/master", Permission.READ, REGISTERED_USERS);
- deny("refs/heads/branch", Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/heads/master").group(REGISTERED_USERS))
+ .add(deny(Permission.READ).ref("refs/heads/branch").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
assertUploadPackRefs(
"HEAD", psRef1, metaRef1, psRef3, metaRef3, "refs/heads/master", "refs/tags/master-tag");
+ // tree-tag is not visible because we don't look at trees reachable from
+ // refs
}
@Test
public void uploadPackSubsetOfBranchesVisibleNotIncludingHead() throws Exception {
- deny("refs/heads/master", Permission.READ, REGISTERED_USERS);
- allow("refs/heads/branch", Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(deny(Permission.READ).ref("refs/heads/master").group(REGISTERED_USERS))
+ .add(allow(Permission.READ).ref("refs/heads/branch").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
assertUploadPackRefs(
@@ -255,11 +335,16 @@
// master branch is not visible but master-tag is reachable from branch
// (since PushOneCommit always bases changes on each other).
"refs/tags/master-tag");
+ // tree-tag not visible. See comment in subsetOfBranchesVisibleIncludingHead.
}
@Test
public void uploadPackSubsetOfBranchesVisibleWithEdit() throws Exception {
- allow("refs/heads/master", Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/heads/master").group(REGISTERED_USERS))
+ .update();
// Admin's edit is not visible.
requestScopeOperations.setApiUser(admin.id());
@@ -278,12 +363,17 @@
"refs/heads/master",
"refs/tags/master-tag",
"refs/users/01/1000001/edit-" + cd3.getId() + "/1");
+ // tree-tag not visible. See comment in subsetOfBranchesVisibleIncludingHead.
}
@Test
public void uploadPackSubsetOfBranchesAndEditsVisibleWithViewPrivateChanges() throws Exception {
- allow("refs/heads/master", Permission.READ, REGISTERED_USERS);
- allow("refs/*", Permission.VIEW_PRIVATE_CHANGES, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/heads/master").group(REGISTERED_USERS))
+ .add(allow(Permission.VIEW_PRIVATE_CHANGES).ref("refs/*").group(REGISTERED_USERS))
+ .update();
// Admin's edit on change3 is visible.
requestScopeOperations.setApiUser(admin.id());
@@ -306,13 +396,21 @@
"refs/tags/master-tag",
"refs/users/00/1000000/edit-" + cd3.getId() + "/1",
"refs/users/01/1000001/edit-" + cd3.getId() + "/1");
+ // tree-tag not visible. See comment in subsetOfBranchesVisibleIncludingHead.
}
@Test
public void uploadPackSubsetOfRefsVisibleWithAccessDatabase() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
- deny("refs/heads/master", Permission.READ, REGISTERED_USERS);
- allow("refs/heads/branch", Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(deny(Permission.READ).ref("refs/heads/master").group(REGISTERED_USERS))
+ .add(allow(Permission.READ).ref("refs/heads/branch").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(admin.id());
gApi.changes().id(cd3.getId().get()).edit().create();
@@ -335,6 +433,7 @@
"refs/tags/master-tag",
// All edits are visible due to accessDatabase capability.
"refs/users/00/1000000/edit-" + cd3.getId() + "/1");
+ // tree-tag not visible. See comment in subsetOfBranchesVisibleIncludingHead.
}
@Test
@@ -349,7 +448,11 @@
}
private void uploadPackNoSearchingChangeCacheImpl() throws Exception {
- allow("refs/heads/*", Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/heads/*").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
assertRefs(
@@ -370,19 +473,27 @@
"refs/heads/master",
"refs/tags/branch-tag",
"refs/tags/master-tag");
+ // tree-tag not visible. See comment in subsetOfBranchesVisibleIncludingHead.
}
@Test
public void uploadPackSequencesWithAccessDatabase() throws Exception {
assertRefs(allProjects, user, true);
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
assertRefs(allProjects, user, true, "refs/sequences/changes");
}
@Test
public void uploadPackAllRefsAreVisibleOrphanedTag() throws Exception {
- allow("refs/*", Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
// Delete the pending change on 'branch' and 'branch' itself so that the tag gets orphaned
gApi.changes().id(cd4.getId().get()).delete();
gApi.projects().name(project.get()).branch("refs/heads/branch").delete();
@@ -399,6 +510,35 @@
metaRef3,
"refs/heads/master",
"refs/tags/branch-tag",
+ "refs/tags/master-tag",
+ "refs/tags/tree-tag");
+ }
+
+ @Test
+ public void uploadPackSubsetRefsVisibleOrphanedTagInvisible() throws Exception {
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/heads/branch").group(REGISTERED_USERS))
+ .update();
+ // Create a tag for the pending change on 'branch' so that the tag is orphaned
+ try (Repository repo = repoManager.openRepository(project)) {
+ // change4-tag -> psRef4
+ RefUpdate ctu = repo.updateRef("refs/tags/change4-tag");
+ ctu.setExpectedOldObjectId(ObjectId.zeroId());
+ ctu.setNewObjectId(repo.exactRef(psRef4).getObjectId());
+ assertThat(ctu.update()).isEqualTo(RefUpdate.Result.NEW);
+ }
+
+ requestScopeOperations.setApiUser(user.id());
+ assertUploadPackRefs(
+ psRef2,
+ metaRef2,
+ psRef4,
+ metaRef4,
+ "refs/heads/branch",
+ "refs/tags/branch-tag",
+ // See comment in subsetOfBranchesVisibleNotIncludingHead.
"refs/tags/master-tag");
}
@@ -413,14 +553,19 @@
"refs/heads/master",
"refs/meta/config",
"refs/tags/branch-tag",
- "refs/tags/master-tag");
+ "refs/tags/master-tag",
+ "refs/tags/tree-tag");
assertThat(r.additionalHaves()).containsExactly(obj(cd3, 1), obj(cd4, 1));
}
@Test
public void receivePackRespectsVisibilityOfOpenChanges() throws Exception {
- allow("refs/heads/master", Permission.READ, REGISTERED_USERS);
- deny("refs/heads/branch", Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/heads/master").group(REGISTERED_USERS))
+ .add(deny(Permission.READ).ref("refs/heads/branch").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
assertThat(getReceivePackRefs().additionalHaves()).containsExactly(obj(cd3, 1));
@@ -438,8 +583,8 @@
@Test
public void receivePackOmitsMissingObject() throws Exception {
String rev = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
- try (Repository repo = repoManager.openRepository(project)) {
- TestRepository<?> tr = new TestRepository<>(repo);
+ try (Repository repo = repoManager.openRepository(project);
+ TestRepository<Repository> tr = new TestRepository<>(repo)) {
String subject = "Subject for missing commit";
Change c = new Change(cd3.change());
PatchSet.Id psId = PatchSet.id(cd3.getId(), 2);
@@ -483,7 +628,11 @@
@Test
public void advertisedReferencesOmitUserBranchesOfOtherUsers() throws Exception {
- allow(allUsersName, RefNames.REFS_USERS + "*", Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .project(allUsersName)
+ .forUpdate()
+ .add(allow(Permission.READ).ref(RefNames.REFS_USERS + "*").group(REGISTERED_USERS))
+ .update();
TestRepository<?> userTestRepository = cloneProject(allUsers, user);
try (Git git = userTestRepository.git()) {
assertThat(getUserRefs(git))
@@ -493,7 +642,10 @@
@Test
public void advertisedReferencesIncludeAllUserBranchesWithAccessDatabase() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
TestRepository<?> userTestRepository = cloneProject(allUsers, user);
try (Git git = userTestRepository.git()) {
assertThat(getUserRefs(git))
@@ -515,7 +667,11 @@
@Test
public void advertisedReferencesOmitGroupBranchesOfNonOwnedGroups() throws Exception {
- allow(allUsersName, RefNames.REFS_GROUPS + "*", Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .project(allUsersName)
+ .forUpdate()
+ .add(allow(Permission.READ).ref(RefNames.REFS_GROUPS + "*").group(REGISTERED_USERS))
+ .update();
AccountGroup.UUID users = createGroup("Users", admins, user);
AccountGroup.UUID foos = createGroup("Foos", users);
AccountGroup.UUID bars = createSelfOwnedGroup("Bars", user);
@@ -528,7 +684,10 @@
@Test
public void advertisedReferencesIncludeAllGroupBranchesWithAccessDatabase() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
AccountGroup.UUID users = createGroup("Users", admins);
TestRepository<?> userTestRepository = cloneProject(allUsers, user);
try (Git git = userTestRepository.git()) {
@@ -542,8 +701,15 @@
@Test
public void advertisedReferencesIncludeAllGroupBranchesForAdmins() throws Exception {
- allow(allUsersName, RefNames.REFS_GROUPS + "*", Permission.READ, REGISTERED_USERS);
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ADMINISTRATE_SERVER);
+ projectOperations
+ .project(allUsersName)
+ .forUpdate()
+ .add(allow(Permission.READ).ref(RefNames.REFS_GROUPS + "*").group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ADMINISTRATE_SERVER).group(REGISTERED_USERS))
+ .update();
AccountGroup.UUID users = createGroup("Users", admins);
TestRepository<?> userTestRepository = cloneProject(allUsers, user);
try (Git git = userTestRepository.git()) {
@@ -557,7 +723,11 @@
@Test
public void advertisedReferencesOmitNoteDbNotesBranches() throws Exception {
- allow(allUsersName, RefNames.REFS + "*", Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .project(allUsersName)
+ .forUpdate()
+ .add(allow(Permission.READ).ref(RefNames.REFS + "*").group(REGISTERED_USERS))
+ .update();
TestRepository<?> userTestRepository = cloneProject(allUsers, user);
try (Git git = userTestRepository.git()) {
assertThat(getRefs(git)).containsNoneOf(RefNames.REFS_EXTERNAL_IDS, RefNames.REFS_GROUPNAMES);
@@ -566,11 +736,15 @@
@Test
public void advertisedReferencesOmitPrivateChangesOfOtherUsers() throws Exception {
- allow("refs/heads/master", Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/heads/master").group(REGISTERED_USERS))
+ .update();
TestRepository<?> userTestRepository = cloneProject(project, user);
try (Git git = userTestRepository.git()) {
- String change3RefName = cd3.currentPatchSet().getRefName();
+ String change3RefName = cd3.currentPatchSet().refName();
assertWithMessage("Precondition violated").that(getRefs(git)).contains(change3RefName);
gApi.changes().id(cd3.getId().get()).setPrivate(true, null);
@@ -583,11 +757,15 @@
assume()
.that(baseConfig.getBoolean("auth", "skipFullRefEvaluationIfAllRefsAreVisible", true))
.isTrue();
- allow("refs/*", Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
TestRepository<?> userTestRepository = cloneProject(project, user);
try (Git git = userTestRepository.git()) {
- String change3RefName = cd3.currentPatchSet().getRefName();
+ String change3RefName = cd3.currentPatchSet().refName();
assertWithMessage("Precondition violated").that(getRefs(git)).contains(change3RefName);
gApi.changes().id(cd3.getId().get()).setPrivate(true, null);
@@ -599,11 +777,15 @@
@GerritConfig(name = "auth.skipFullRefEvaluationIfAllRefsAreVisible", value = "false")
public void advertisedReferencesOmitPrivateChangesOfOtherUsersWhenShortcutDisabled()
throws Exception {
- allow("refs/*", Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
TestRepository<?> userTestRepository = cloneProject(project, user);
try (Git git = userTestRepository.git()) {
- String change3RefName = cd3.currentPatchSet().getRefName();
+ String change3RefName = cd3.currentPatchSet().refName();
assertWithMessage("Precondition violated").that(getRefs(git)).contains(change3RefName);
gApi.changes().id(cd3.getId().get()).setPrivate(true, null);
@@ -613,8 +795,16 @@
@Test
public void advertisedReferencesOmitDraftCommentRefsOfOtherUsers() throws Exception {
- allow(project, "refs/*", Permission.READ, REGISTERED_USERS);
- allow(allUsersName, "refs/*", Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .project(allUsersName)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
DraftInput draftInput = new DraftInput();
@@ -633,8 +823,16 @@
@Test
public void advertisedReferencesOmitStarredChangesRefsOfOtherUsers() throws Exception {
- allow(project, "refs/*", Permission.READ, REGISTERED_USERS);
- allow(allUsersName, "refs/*", Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .project(allUsersName)
+ .forUpdate()
+ .add(allow(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
gApi.accounts().self().starChange(cd3.getId().toString());
@@ -649,7 +847,10 @@
@Test
public void hideMetadata() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
// create change
TestRepository<?> allUsersRepo = cloneProject(allUsers);
fetch(allUsersRepo, RefNames.REFS_USERS_SELF + ":userRef");
@@ -719,7 +920,7 @@
}
private List<String> getRefs(Git git) throws Exception {
- return getRefs(git, Predicates.alwaysTrue());
+ return getRefs(git, x -> true);
}
private List<String> getUserRefs(Git git) throws Exception {
@@ -776,7 +977,7 @@
PatchSet.Id psId = PatchSet.id(cd.getId(), psNum);
PatchSet ps = cd.patchSet(psId);
assertWithMessage("%s not found in %s", psId, cd.patchSets()).that(ps).isNotNull();
- return ps.getCommitId();
+ return ps.commitId();
}
private AccountGroup.UUID createSelfOwnedGroup(String name, TestAccount... members)
diff --git a/javatests/com/google/gerrit/acceptance/git/SubmitOnPushIT.java b/javatests/com/google/gerrit/acceptance/git/SubmitOnPushIT.java
index 3d0e116..02f7b0a 100644
--- a/javatests/com/google/gerrit/acceptance/git/SubmitOnPushIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/SubmitOnPushIT.java
@@ -17,12 +17,14 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.GitUtil.assertPushOk;
import static com.google.gerrit.acceptance.GitUtil.pushHead;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static java.util.stream.Collectors.toList;
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.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
@@ -47,10 +49,15 @@
@NoHttpd
public class SubmitOnPushIT extends AbstractDaemonTest {
@Inject private ApprovalsUtil approvalsUtil;
+ @Inject private ProjectOperations projectOperations;
@Test
public void submitOnPush() throws Exception {
- grant(project, "refs/for/refs/heads/master", Permission.SUBMIT);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.SUBMIT).ref("refs/for/refs/heads/master").group(adminGroupUuid()))
+ .update();
PushOneCommit.Result r = pushTo("refs/for/master%submit");
r.assertOkStatus();
r.assertChange(Change.Status.MERGED, null, admin);
@@ -60,7 +67,11 @@
@Test
public void submitOnPushToRefsMetaConfig() throws Exception {
- grant(project, "refs/for/refs/meta/config", Permission.SUBMIT);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.SUBMIT).ref("refs/for/refs/meta/config").group(adminGroupUuid()))
+ .update();
git().fetch().setRefSpecs(new RefSpec("refs/meta/config:refs/meta/config")).call();
testRepo.reset(RefNames.REFS_CONFIG);
@@ -78,7 +89,11 @@
push("refs/heads/master", "one change", "a.txt", "some content");
testRepo.reset(objectId);
- grant(project, "refs/for/refs/heads/master", Permission.SUBMIT);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.SUBMIT).ref("refs/for/refs/heads/master").group(adminGroupUuid()))
+ .update();
PushOneCommit.Result r =
push("refs/for/master%submit", "other change", "a.txt", "other content");
r.assertErrorStatus();
@@ -94,7 +109,11 @@
push(master, "one change", "a.txt", "some content");
testRepo.reset(objectId);
- grant(project, "refs/for/refs/heads/master", Permission.SUBMIT);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.SUBMIT).ref("refs/for/refs/heads/master").group(adminGroupUuid()))
+ .update();
PushOneCommit.Result r =
push("refs/for/master%submit", "other change", "b.txt", "other content");
r.assertOkStatus();
@@ -107,7 +126,11 @@
PushOneCommit.Result r =
push("refs/for/master", PushOneCommit.SUBJECT, "a.txt", "some content");
- grant(project, "refs/for/refs/heads/master", Permission.SUBMIT);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.SUBMIT).ref("refs/for/refs/heads/master").group(adminGroupUuid()))
+ .update();
r =
push(
"refs/for/master%submit",
@@ -147,7 +170,11 @@
@Test
public void mergeOnPushToBranch() throws Exception {
- grant(project, "refs/heads/master", Permission.PUSH);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/heads/master").group(adminGroupUuid()))
+ .update();
PushOneCommit.Result r =
push("refs/for/master", PushOneCommit.SUBJECT, "a.txt", "some content");
r.assertOkStatus();
@@ -158,13 +185,13 @@
ChangeData cd =
Iterables.getOnlyElement(queryProvider.get().byKey(Change.key(r.getChangeId())));
RevCommit c = r.getCommit();
- PatchSet.Id psId = cd.currentPatchSet().getId();
+ PatchSet.Id psId = cd.currentPatchSet().id();
assertThat(psId.get()).isEqualTo(1);
assertThat(cd.change().isMerged()).isTrue();
assertSubmitApproval(psId);
assertThat(cd.patchSets()).hasSize(1);
- assertThat(cd.patchSet(psId).getCommitId()).isEqualTo(c);
+ assertThat(cd.patchSet(psId).commitId()).isEqualTo(c);
}
@Test
@@ -172,10 +199,14 @@
enableCreateNewChangeForAllNotInTarget();
String master = "refs/heads/master";
String other = "refs/heads/other";
- grant(project, master, Permission.PUSH);
- grant(project, other, Permission.CREATE);
- grant(project, other, Permission.PUSH);
- RevCommit masterRev = getRemoteHead();
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref(master).group(adminGroupUuid()))
+ .add(allow(Permission.CREATE).ref(other).group(adminGroupUuid()))
+ .add(allow(Permission.PUSH).ref(other).group(adminGroupUuid()))
+ .update();
+ RevCommit masterRev = projectOperations.project(project).getHead("master");
pushCommitTo(masterRev, other);
PushOneCommit.Result r = createChange();
r.assertOkStatus();
@@ -209,7 +240,11 @@
@Test
public void mergeOnPushToBranchWithNewPatchset() throws Exception {
- grant(project, "refs/heads/master", Permission.PUSH);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/heads/master").group(adminGroupUuid()))
+ .update();
PushOneCommit.Result r = pushTo("refs/for/master");
r.assertOkStatus();
RevCommit c1 = r.getCommit();
@@ -237,13 +272,17 @@
assertSubmitApproval(psId2);
assertThat(cd.patchSets()).hasSize(2);
- assertThat(cd.patchSet(psId1).getCommitId()).isEqualTo(c1);
- assertThat(cd.patchSet(psId2).getCommitId()).isEqualTo(c2);
+ assertThat(cd.patchSet(psId1).commitId()).isEqualTo(c1);
+ assertThat(cd.patchSet(psId2).commitId()).isEqualTo(c2);
}
@Test
public void mergeOnPushToBranchWithOldPatchset() throws Exception {
- grant(project, "refs/heads/master", Permission.PUSH);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/heads/master").group(adminGroupUuid()))
+ .update();
PushOneCommit.Result r = pushTo("refs/for/master");
r.assertOkStatus();
RevCommit c1 = r.getCommit();
@@ -264,16 +303,20 @@
Change c = cd.change();
assertThat(c.isMerged()).isTrue();
assertThat(c.currentPatchSetId()).isEqualTo(psId1);
- assertThat(cd.patchSets().stream().map(PatchSet::getId).collect(toList()))
+ assertThat(cd.patchSets().stream().map(PatchSet::id).collect(toList()))
.containsExactly(psId1, psId2);
}
@Test
public void mergeMultipleOnPushToBranchWithNewPatchset() throws Exception {
- grant(project, "refs/heads/master", Permission.PUSH);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/heads/master").group(adminGroupUuid()))
+ .update();
// Create 2 changes.
- ObjectId initialHead = getRemoteHead();
+ ObjectId initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result r1 = createChange("Change 1", "a", "a");
r1.assertOkStatus();
PushOneCommit.Result r2 = createChange("Change 2", "b", "b");
@@ -304,15 +347,15 @@
assertThat(cd2.change().isMerged()).isTrue();
PatchSet.Id psId2_2 = cd2.change().currentPatchSetId();
assertThat(psId2_2.get()).isEqualTo(2);
- assertThat(cd2.patchSet(psId2_1).getCommitId()).isEqualTo(c2_1);
- assertThat(cd2.patchSet(psId2_2).getCommitId()).isEqualTo(c2_2);
+ assertThat(cd2.patchSet(psId2_1).commitId()).isEqualTo(c2_1);
+ assertThat(cd2.patchSet(psId2_2).commitId()).isEqualTo(c2_2);
ChangeData cd1 = r1.getChange();
assertThat(cd1.change().isMerged()).isTrue();
PatchSet.Id psId1_2 = cd1.change().currentPatchSetId();
assertThat(psId1_2.get()).isEqualTo(2);
- assertThat(cd1.patchSet(psId1_1).getCommitId()).isEqualTo(c1_1);
- assertThat(cd1.patchSet(psId1_2).getCommitId()).isEqualTo(c1_2);
+ assertThat(cd1.patchSet(psId1_1).commitId()).isEqualTo(c1_1);
+ assertThat(cd1.patchSet(psId1_2).commitId()).isEqualTo(c1_2);
}
private PatchSetApproval getSubmitter(PatchSet.Id patchSetId) throws Exception {
@@ -323,8 +366,8 @@
private void assertSubmitApproval(PatchSet.Id patchSetId) throws Exception {
PatchSetApproval a = getSubmitter(patchSetId);
assertThat(a.isLegacySubmit()).isTrue();
- assertThat(a.getValue()).isEqualTo((short) 1);
- assertThat(a.getAccountId()).isEqualTo(admin.id());
+ assertThat(a.value()).isEqualTo((short) 1);
+ assertThat(a.accountId()).isEqualTo(admin.id());
}
private void assertCommit(Project.NameKey project, String branch) throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsIT.java b/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsIT.java
index 2f551a5..e7501e7 100644
--- a/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsIT.java
@@ -22,9 +22,11 @@
import com.google.gerrit.acceptance.GerritConfig;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.testing.ConfigSuite;
import com.google.gerrit.testing.TestTimeUtil;
+import com.google.inject.Inject;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
@@ -45,6 +47,8 @@
return submitWholeTopicEnabledConfig();
}
+ @Inject private ProjectOperations projectOperations;
+
@Test
@GerritConfig(name = "submodule.enableSuperProjectSubscriptions", value = "false")
public void testSubscriptionWithoutGlobalServerSetting() throws Exception {
@@ -649,8 +653,9 @@
}
private ObjectId directUpdateRef(Project.NameKey project, String ref) throws Exception {
- try (Repository serverRepo = repoManager.openRepository(project)) {
- return new TestRepository<>(serverRepo).branch(ref).commit().create().copy();
+ try (Repository serverRepo = repoManager.openRepository(project);
+ TestRepository<Repository> tr = new TestRepository<>(serverRepo)) {
+ return tr.branch(ref).commit().create().copy();
}
}
diff --git a/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java b/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java
index 2cdce4d..eef6e33 100644
--- a/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java
+++ b/javatests/com/google/gerrit/acceptance/git/SubmoduleSubscriptionsWholeTopicMergeIT.java
@@ -17,17 +17,23 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.gerrit.acceptance.GitUtil.getChangeId;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.acceptance.NoHttpd;
+import com.google.gerrit.acceptance.testsuite.ThrowingConsumer;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.client.ChangeStatus;
import com.google.gerrit.extensions.client.SubmitType;
+import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.reviewdb.client.BranchNameKey;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.change.TestSubmitInput;
import com.google.gerrit.testing.ConfigSuite;
+import com.google.inject.Inject;
import java.util.ArrayDeque;
import java.util.Map;
import org.apache.commons.lang.RandomStringUtils;
@@ -67,6 +73,8 @@
return submitByRebaseIfNecessaryConfig();
}
+ @Inject private ProjectOperations projectOperations;
+
@Test
public void subscriptionUpdateOfManyChanges() throws Exception {
allowMatchingSubmoduleSubscription(subKey, "refs/heads/master", superKey, "refs/heads/master");
@@ -282,8 +290,12 @@
.name(prefix + "sub" + i)
.submitType(getSubmitType())
.create();
- grant(subKey[i], "refs/heads/*", Permission.PUSH);
- grant(subKey[i], "refs/for/refs/heads/*", Permission.SUBMIT);
+ projectOperations
+ .project(subKey[i])
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/heads/*").group(adminGroupUuid()))
+ .add(allow(Permission.SUBMIT).ref("refs/for/refs/heads/*").group(adminGroupUuid()))
+ .update();
sub[i] = cloneProject(subKey[i]);
}
@@ -393,7 +405,7 @@
gApi.changes().id(subChangeId).current().submit();
expectToHaveSubmoduleState(superRepo, "master", subKey, subRepo, "master");
- RevCommit superHead = getRemoteHead(superKey, "master");
+ RevCommit superHead = projectOperations.project(superKey).getHead("master");
assertThat(superHead.getShortMessage()).contains("some message");
assertThat(superHead.getId()).isNotEqualTo(superId);
}
@@ -427,7 +439,7 @@
gApi.changes().id(subChangeId).current().submit();
- RevCommit superHead = getRemoteHead(superKey, "master");
+ RevCommit superHead = projectOperations.project(superKey).getHead("master");
assertThat(superHead.getShortMessage()).isEqualTo("some message");
assertThat(superHead.getId()).isEqualTo(superId);
}
@@ -614,7 +626,7 @@
expectToHaveSubmoduleState(topRepo, "master", botKey, bottomRepo, "master");
}
- private String prepareBranchCircularSubscription() throws Exception {
+ private void testBranchCircularSubscription(ThrowingConsumer<String> apiCall) throws Exception {
Project.NameKey topKey = createProjectForPush(getSubmitType());
Project.NameKey midKey = createProjectForPush(getSubmitType());
Project.NameKey botKey = createProjectForPush(getSubmitType());
@@ -634,23 +646,24 @@
String changeId = getChangeId(bottomRepo, bottomMasterHead).get();
approve(changeId);
- exception.expectMessage("Branch level circular subscriptions detected");
- exception.expectMessage(topKey.get() + ",refs/heads/master");
- exception.expectMessage(midKey.get() + ",refs/heads/master");
- exception.expectMessage(botKey.get() + ",refs/heads/master");
- return changeId;
+
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> apiCall.accept(changeId));
+ assertThat(thrown).hasMessageThat().contains("Branch level circular subscriptions detected");
+ assertThat(thrown).hasMessageThat().contains(topKey.get() + ",refs/heads/master");
+ assertThat(thrown).hasMessageThat().contains(midKey.get() + ",refs/heads/master");
+ assertThat(thrown).hasMessageThat().contains(botKey.get() + ",refs/heads/master");
}
@Test
public void branchCircularSubscription() throws Exception {
- String changeId = prepareBranchCircularSubscription();
- gApi.changes().id(changeId).current().submit();
+ testBranchCircularSubscription(changeId -> gApi.changes().id(changeId).current().submit());
}
@Test
public void branchCircularSubscriptionPreview() throws Exception {
- String changeId = prepareBranchCircularSubscription();
- gApi.changes().id(changeId).current().submitPreview();
+ testBranchCircularSubscription(
+ changeId -> gApi.changes().id(changeId).current().submitPreview());
}
@Test
@@ -672,10 +685,13 @@
approve(getChangeId(subRepo, subMasterHead).get());
approve(getChangeId(superRepo, superDevHead).get());
- exception.expectMessage("Project level circular subscriptions detected");
- exception.expectMessage(subKey.get());
- exception.expectMessage(superKey.get());
- gApi.changes().id(getChangeId(subRepo, subMasterHead).get()).current().submit();
+ Throwable thrown =
+ assertThrows(
+ Throwable.class,
+ () -> gApi.changes().id(getChangeId(subRepo, subMasterHead).get()).current().submit());
+ assertThat(thrown).hasMessageThat().contains("Project level circular subscriptions detected");
+ assertThat(thrown).hasMessageThat().contains(subKey.get());
+ assertThat(thrown).hasMessageThat().contains(superKey.get());
}
@Test
@@ -739,13 +755,13 @@
approve(getChangeId(repoB, bDevHead).get());
gApi.changes().id(getChangeId(repoA, aDevHead).get()).current().submit();
- assertThat(getRemoteHead(keyA, "refs/heads/master").getShortMessage())
+ assertThat(projectOperations.project(keyA).getHead("refs/heads/master").getShortMessage())
.contains("some message in a master.txt");
- assertThat(getRemoteHead(keyA, "refs/heads/dev").getShortMessage())
+ assertThat(projectOperations.project(keyA).getHead("refs/heads/dev").getShortMessage())
.contains("some message in a dev.txt");
- assertThat(getRemoteHead(keyB, "refs/heads/master").getShortMessage())
+ assertThat(projectOperations.project(keyB).getHead("refs/heads/master").getShortMessage())
.contains("some message in b master.txt");
- assertThat(getRemoteHead(keyB, "refs/heads/dev").getShortMessage())
+ assertThat(projectOperations.project(keyB).getHead("refs/heads/dev").getShortMessage())
.contains("some message in b dev.txt");
}
@@ -838,13 +854,13 @@
sub1.git().fetch().call();
RevWalk rw1 = sub1.getRevWalk();
- RevCommit master1 = rw1.parseCommit(getRemoteHead(subKey1, "master"));
+ RevCommit master1 = rw1.parseCommit(projectOperations.project(subKey1).getHead("master"));
RevCommit change1Ps = parseCurrentRevision(rw1, changeId1);
assertThat(rw1.isMergedInto(change1Ps, master1)).isTrue();
sub2.git().fetch().call();
RevWalk rw2 = sub2.getRevWalk();
- RevCommit master2 = rw2.parseCommit(getRemoteHead(subKey2, "master"));
+ RevCommit master2 = rw2.parseCommit(projectOperations.project(subKey2).getHead("master"));
RevCommit change2Ps = parseCurrentRevision(rw2, changeId2);
assertThat(rw2.isMergedInto(change2Ps, master2)).isTrue();
diff --git a/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java b/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java
index 26fe5e1..6991a250 100644
--- a/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java
+++ b/javatests/com/google/gerrit/acceptance/pgm/ElasticReindexIT.java
@@ -37,7 +37,7 @@
@ConfigSuite.Config
public static Config elasticsearchV7() {
- return getConfig(ElasticVersion.V7_0);
+ return getConfig(ElasticVersion.V7_1);
}
@Override
diff --git a/javatests/com/google/gerrit/acceptance/rest/account/CapabilitiesIT.java b/javatests/com/google/gerrit/acceptance/rest/account/CapabilitiesIT.java
index e7ce43f..be4fde0 100644
--- a/javatests/com/google/gerrit/acceptance/rest/account/CapabilitiesIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/account/CapabilitiesIT.java
@@ -14,8 +14,11 @@
package com.google.gerrit.acceptance.rest.account;
+import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.capabilityKey;
import static com.google.gerrit.common.data.GlobalCapability.ACCESS_DATABASE;
import static com.google.gerrit.common.data.GlobalCapability.ADMINISTRATE_SERVER;
import static com.google.gerrit.common.data.GlobalCapability.BATCH_CHANGES_LIMIT;
@@ -26,24 +29,30 @@
import static com.google.gerrit.common.data.GlobalCapability.RUN_AS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
-import com.google.common.collect.Iterables;
+import com.google.common.collect.ImmutableList;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
+import com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
+import com.google.inject.Inject;
import org.junit.Test;
public class CapabilitiesIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
+
@Test
public void capabilitiesUser() throws Exception {
- Iterable<String> all =
- Iterables.filter(
- GlobalCapability.getAllNames(),
- c -> !ADMINISTRATE_SERVER.equals(c) && !PRIORITY.equals(c));
-
- allowGlobalCapabilities(REGISTERED_USERS, all);
+ ImmutableList<String> all =
+ GlobalCapability.getAllNames().stream()
+ .filter(c -> !ADMINISTRATE_SERVER.equals(c) && !PRIORITY.equals(c))
+ .collect(toImmutableList());
+ TestProjectUpdate.Builder allowBuilder = projectOperations.allProjectsForUpdate();
+ all.forEach(c -> allowBuilder.add(allowCapability(c).group(REGISTERED_USERS)));
+ allowBuilder.update();
try {
RestResponse r = userRestSession.get("/accounts/self/capabilities");
r.assertOK();
@@ -67,7 +76,9 @@
}
}
} finally {
- removeGlobalCapabilities(REGISTERED_USERS, all);
+ TestProjectUpdate.Builder removeBuilder = projectOperations.allProjectsForUpdate();
+ all.forEach(c -> removeBuilder.remove(capabilityKey(c).group(REGISTERED_USERS)));
+ removeBuilder.update();
}
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/account/EmailIT.java b/javatests/com/google/gerrit/acceptance/rest/account/EmailIT.java
index 84f218d..5adf46f 100644
--- a/javatests/com/google/gerrit/acceptance/rest/account/EmailIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/account/EmailIT.java
@@ -16,6 +16,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.toSet;
import com.google.common.collect.ImmutableMultimap;
@@ -149,16 +150,20 @@
@Test
public void setPreferredEmailToNonExistingEmail() throws Exception {
String email = "non-existing@example.com";
- exception.expect(ResourceNotFoundException.class);
- exception.expectMessage("Not found: " + email);
- gApi.accounts().self().email(email).setPreferred();
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.accounts().self().email(email).setPreferred());
+ assertThat(thrown).hasMessageThat().contains("Not found: " + email);
}
@Test
public void setPreferredEmailToEmailOfOtherAccount() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- exception.expectMessage("Not found: " + user.email());
- gApi.accounts().self().email(user.email()).setPreferred();
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.accounts().self().email(user.email()).setPreferred());
+ assertThat(thrown).hasMessageThat().contains("Not found: " + user.email());
}
@Test
@@ -201,9 +206,11 @@
Context oldCtx =
createContextWithCustomRealm(new RealmWithAdditionalEmails(admin.id(), user.email()));
try {
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("email in use by another account");
- gApi.accounts().self().email(user.email()).setPreferred();
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> gApi.accounts().self().email(user.email()).setPreferred());
+ assertThat(thrown).hasMessageThat().contains("email in use by another account");
} finally {
atrScope.set(oldCtx);
}
@@ -248,9 +255,7 @@
// Now the email is no longer found
requestScopeOperations.resetCurrentApiUser();
- emailApi = gApi.accounts().self().email(email);
- exception.expect(ResourceNotFoundException.class);
- emailApi.get();
+ assertThrows(ResourceNotFoundException.class, () -> gApi.accounts().self().email(email).get());
}
private Set<String> getEmails() throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/rest/account/ExternalIdIT.java b/javatests/com/google/gerrit/acceptance/rest/account/ExternalIdIT.java
index 998a2a4..ba3c7ea 100644
--- a/javatests/com/google/gerrit/acceptance/rest/account/ExternalIdIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/account/ExternalIdIT.java
@@ -18,10 +18,13 @@
import static com.google.common.truth.Truth8.assertThat;
import static com.google.gerrit.acceptance.GitUtil.fetch;
import static com.google.gerrit.acceptance.GitUtil.pushHead;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_MAILTO;
import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_USERNAME;
import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_UUID;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.stream.Collectors.toList;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
@@ -33,6 +36,7 @@
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.TestAccount;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.common.data.Permission;
@@ -91,6 +95,7 @@
@Inject private ExternalIds externalIds;
@Inject private ExternalIdReader externalIdReader;
@Inject private ExternalIdNotes.Factory externalIdNotesFactory;
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Test
@@ -112,14 +117,18 @@
@Test
public void getExternalIdsOfOtherUserNotAllowed() throws Exception {
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("access database not permitted");
- gApi.accounts().id(admin.id().get()).getExternalIds();
+ AuthException thrown =
+ assertThrows(
+ AuthException.class, () -> gApi.accounts().id(admin.id().get()).getExternalIds());
+ assertThat(thrown).hasMessageThat().contains("access database not permitted");
}
@Test
public void getExternalIdsOfOtherUserWithAccessDatabase() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
Collection<ExternalId> expectedIds = getAccountState(admin.id()).getExternalIds();
List<AccountExternalIdInfo> expectedIdInfos = toExternalIdInfos(expectedIds);
@@ -165,27 +174,38 @@
public void deleteExternalIdsOfOtherUserNotAllowed() throws Exception {
List<AccountExternalIdInfo> extIds = gApi.accounts().self().getExternalIds();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("access database not permitted");
- gApi.accounts()
- .id(admin.id().get())
- .deleteExternalIds(extIds.stream().map(e -> e.identity).collect(toList()));
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () ->
+ gApi.accounts()
+ .id(admin.id().get())
+ .deleteExternalIds(extIds.stream().map(e -> e.identity).collect(toList())));
+ assertThat(thrown).hasMessageThat().contains("access database not permitted");
}
@Test
public void deleteExternalIdOfOtherUserUnderOwnAccount_UnprocessableEntity() throws Exception {
List<AccountExternalIdInfo> extIds = gApi.accounts().self().getExternalIds();
requestScopeOperations.setApiUser(user.id());
- exception.expect(UnprocessableEntityException.class);
- exception.expectMessage(String.format("External id %s does not exist", extIds.get(0).identity));
- gApi.accounts()
- .self()
- .deleteExternalIds(extIds.stream().map(e -> e.identity).collect(toList()));
+ UnprocessableEntityException thrown =
+ assertThrows(
+ UnprocessableEntityException.class,
+ () ->
+ gApi.accounts()
+ .self()
+ .deleteExternalIds(extIds.stream().map(e -> e.identity).collect(toList())));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(String.format("External id %s does not exist", extIds.get(0).identity));
}
@Test
public void deleteExternalIdsOfOtherUserWithAccessDatabase() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
List<AccountExternalIdInfo> externalIds = gApi.accounts().self().getExternalIds();
@@ -248,29 +268,33 @@
@Test
public void fetchExternalIdsBranch() throws Exception {
- TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers, user);
+ final TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers, user);
// refs/meta/external-ids is only visible to users with the 'Access Database' capability
- try {
- fetch(allUsersRepo, RefNames.REFS_EXTERNAL_IDS);
- fail("expected TransportException");
- } catch (TransportException e) {
- assertThat(e.getMessage())
- .isEqualTo(
- "Remote does not have " + RefNames.REFS_EXTERNAL_IDS + " available for fetch.");
- }
+ TransportException thrown =
+ assertThrows(
+ TransportException.class, () -> fetch(allUsersRepo, RefNames.REFS_EXTERNAL_IDS));
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo("Remote does not have " + RefNames.REFS_EXTERNAL_IDS + " available for fetch.");
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
// re-clone to get new request context, otherwise the old global capabilities are still cached
// in the IdentifiedUser object
- allUsersRepo = cloneProject(allUsers, user);
- fetch(allUsersRepo, RefNames.REFS_EXTERNAL_IDS);
+ TestRepository<InMemoryRepository> allUsersRepo2 = cloneProject(allUsers, user);
+ fetch(allUsersRepo2, RefNames.REFS_EXTERNAL_IDS);
}
@Test
public void pushToExternalIdsBranch() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
fetch(allUsersRepo, RefNames.REFS_EXTERNAL_IDS + ":" + RefNames.REFS_EXTERNAL_IDS);
@@ -295,7 +319,10 @@
@Test
public void pushToExternalIdsBranchRejectsExternalIdWithoutAccountId() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
fetch(allUsersRepo, RefNames.REFS_EXTERNAL_IDS + ":" + RefNames.REFS_EXTERNAL_IDS);
@@ -313,7 +340,10 @@
@Test
public void pushToExternalIdsBranchRejectsExternalIdWithKeyThatDoesntMatchTheNoteId()
throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
fetch(allUsersRepo, RefNames.REFS_EXTERNAL_IDS + ":" + RefNames.REFS_EXTERNAL_IDS);
@@ -330,7 +360,10 @@
@Test
public void pushToExternalIdsBranchRejectsExternalIdWithInvalidConfig() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
fetch(allUsersRepo, RefNames.REFS_EXTERNAL_IDS + ":" + RefNames.REFS_EXTERNAL_IDS);
@@ -347,7 +380,10 @@
@Test
public void pushToExternalIdsBranchRejectsExternalIdWithEmptyNote() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
fetch(allUsersRepo, RefNames.REFS_EXTERNAL_IDS + ":" + RefNames.REFS_EXTERNAL_IDS);
@@ -387,7 +423,10 @@
private void testPushToExternalIdsBranchRejectsInvalidExternalId(ExternalId invalidExtId)
throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
fetch(allUsersRepo, RefNames.REFS_EXTERNAL_IDS + ":" + RefNames.REFS_EXTERNAL_IDS);
@@ -403,7 +442,10 @@
@Test
public void readExternalIdsWhenInvalidExternalIdsExist() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
requestScopeOperations.resetCurrentApiUser();
insertValidExternalIds();
@@ -424,7 +466,10 @@
@Test
public void checkConsistency() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
requestScopeOperations.resetCurrentApiUser();
insertValidExternalIds();
@@ -446,9 +491,11 @@
@Test
public void checkConsistencyNotAllowed() throws Exception {
- exception.expect(AuthException.class);
- exception.expectMessage("access database not permitted");
- gApi.config().server().checkConsistency(new ConsistencyCheckInput());
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () -> gApi.config().server().checkConsistency(new ConsistencyCheckInput()));
+ assertThat(thrown).hasMessageThat().contains("access database not permitted");
}
private ConsistencyProblemInfo consistencyError(String message) {
@@ -760,8 +807,7 @@
// update external ID branch so that external IDs need to be reloaded
insertExtIdBehindGerritsBack(ExternalId.create("foo", "bar", admin.id()));
- exception.expect(IOException.class);
- externalIds.byAccount(admin.id());
+ assertThrows(IOException.class, () -> externalIds.byAccount(admin.id()));
}
}
@@ -771,8 +817,7 @@
// update external ID branch so that external IDs need to be reloaded
insertExtIdBehindGerritsBack(ExternalId.create("foo", "bar", admin.id()));
- exception.expect(IOException.class);
- externalIds.byEmail(admin.email());
+ assertThrows(IOException.class, () -> externalIds.byEmail(admin.email()));
}
}
@@ -975,9 +1020,13 @@
return info;
}
- private void allowPushOfExternalIds() throws IOException, ConfigInvalidException {
- grant(allUsers, RefNames.REFS_EXTERNAL_IDS, Permission.READ);
- grant(allUsers, RefNames.REFS_EXTERNAL_IDS, Permission.PUSH);
+ private void allowPushOfExternalIds() {
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.READ).ref(RefNames.REFS_EXTERNAL_IDS).group(adminGroupUuid()))
+ .add(allow(Permission.PUSH).ref(RefNames.REFS_EXTERNAL_IDS).group(adminGroupUuid()))
+ .update();
}
private void assertRefUpdateFailure(RemoteRefUpdate update, String msg) {
diff --git a/javatests/com/google/gerrit/acceptance/rest/account/GetAccountIT.java b/javatests/com/google/gerrit/acceptance/rest/account/GetAccountIT.java
index 11f7c0f..931dace 100644
--- a/javatests/com/google/gerrit/acceptance/rest/account/GetAccountIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/account/GetAccountIT.java
@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance.rest.account;
import static com.google.gerrit.acceptance.rest.account.AccountAssert.assertAccountInfo;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
@@ -24,9 +25,9 @@
@NoHttpd
public class GetAccountIT extends AbstractDaemonTest {
- @Test(expected = ResourceNotFoundException.class)
+ @Test
public void getNonExistingAccount_NotFound() throws Exception {
- gApi.accounts().id("non-existing").get();
+ assertThrows(ResourceNotFoundException.class, () -> gApi.accounts().id("non-existing").get());
}
@Test
diff --git a/javatests/com/google/gerrit/acceptance/rest/account/ImpersonationIT.java b/javatests/com/google/gerrit/acceptance/rest/account/ImpersonationIT.java
index 0f7fdbb..1c342ee 100644
--- a/javatests/com/google/gerrit/acceptance/rest/account/ImpersonationIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/account/ImpersonationIT.java
@@ -15,9 +15,15 @@
package com.google.gerrit.acceptance.rest.account;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.capabilityKey;
import static com.google.gerrit.extensions.client.ListChangesOption.MESSAGES;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -28,6 +34,7 @@
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.RestSession;
import com.google.gerrit.acceptance.TestAccount;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.common.data.LabelType;
@@ -59,7 +66,7 @@
import com.google.gerrit.server.ChangeMessagesUtil;
import com.google.gerrit.server.CommentsUtil;
import com.google.gerrit.server.account.AccountControl;
-import com.google.gerrit.server.project.testing.Util;
+import com.google.gerrit.server.project.testing.TestLabels;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.inject.Inject;
import org.apache.http.Header;
@@ -73,6 +80,7 @@
@Inject private ApprovalsUtil approvalsUtil;
@Inject private ChangeMessagesUtil cmUtil;
@Inject private CommentsUtil commentsUtil;
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
private RestSession anonRestSession;
@@ -106,11 +114,11 @@
revision.review(in);
PatchSetApproval psa = Iterables.getOnlyElement(r.getChange().approvals().values());
- assertThat(psa.getPatchSetId().get()).isEqualTo(1);
- assertThat(psa.getLabel()).isEqualTo("Code-Review");
- assertThat(psa.getAccountId()).isEqualTo(user.id());
- assertThat(psa.getValue()).isEqualTo(1);
- assertThat(psa.getRealAccountId()).isEqualTo(admin.id());
+ assertThat(psa.patchSetId().get()).isEqualTo(1);
+ assertThat(psa.label()).isEqualTo("Code-Review");
+ assertThat(psa.accountId()).isEqualTo(user.id());
+ assertThat(psa.value()).isEqualTo(1);
+ assertThat(psa.realAccountId()).isEqualTo(admin.id());
ChangeData cd = r.getChange();
ChangeMessage m = Iterables.getLast(cmUtil.byChange(cd.notes()));
@@ -129,9 +137,10 @@
in.onBehalfOf = user.id().toString();
in.message = "Message on behalf of";
- exception.expect(AuthException.class);
- exception.expectMessage("label required to post review on behalf of \"" + in.onBehalfOf + '"');
- revision.review(in);
+ AuthException thrown = assertThrows(AuthException.class, () -> revision.review(in));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("label required to post review on behalf of \"" + in.onBehalfOf + '"');
}
@Test
@@ -143,9 +152,10 @@
ReviewInput in = new ReviewInput().label("Not-A-Label", 5);
in.onBehalfOf = user.id().toString();
- exception.expect(BadRequestException.class);
- exception.expectMessage("label \"Not-A-Label\" is not a configured label");
- gApi.changes().id(changeId).current().review(in);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class, () -> gApi.changes().id(changeId).current().review(in));
+ assertThat(thrown).hasMessageThat().contains("label \"Not-A-Label\" is not a configured label");
}
@Test
@@ -163,7 +173,7 @@
@Test
public void voteOnBehalfOfLabelNotPermitted() throws Exception {
try (ProjectConfigUpdate u = updateProject(project)) {
- LabelType verified = Util.verified();
+ LabelType verified = TestLabels.verified();
u.getConfig().getLabelSections().put(verified.getName(), verified);
u.save();
}
@@ -175,10 +185,11 @@
in.onBehalfOf = user.id().toString();
in.label("Verified", 1);
- exception.expect(AuthException.class);
- exception.expectMessage(
- "not permitted to modify label \"Verified\" on behalf of \"" + in.onBehalfOf + '"');
- revision.review(in);
+ AuthException thrown = assertThrows(AuthException.class, () -> revision.review(in));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ "not permitted to modify label \"Verified\" on behalf of \"" + in.onBehalfOf + '"');
}
@Test
@@ -207,11 +218,11 @@
gApi.changes().id(r.getChangeId()).current().review(in);
PatchSetApproval psa = Iterables.getOnlyElement(r.getChange().approvals().values());
- assertThat(psa.getPatchSetId().get()).isEqualTo(1);
- assertThat(psa.getLabel()).isEqualTo("Code-Review");
- assertThat(psa.getAccountId()).isEqualTo(user.id());
- assertThat(psa.getValue()).isEqualTo(1);
- assertThat(psa.getRealAccountId()).isEqualTo(admin.id());
+ assertThat(psa.patchSetId().get()).isEqualTo(1);
+ assertThat(psa.label()).isEqualTo("Code-Review");
+ assertThat(psa.accountId()).isEqualTo(user.id());
+ assertThat(psa.value()).isEqualTo(1);
+ assertThat(psa.realAccountId()).isEqualTo(admin.id());
ChangeData cd = r.getChange();
Comment c = Iterables.getOnlyElement(commentsUtil.publishedByChange(cd.notes()));
@@ -266,9 +277,10 @@
in.label("Code-Review", 1);
in.drafts = DraftHandling.PUBLISH;
- exception.expect(AuthException.class);
- exception.expectMessage("not allowed to modify other user's drafts");
- gApi.changes().id(r.getChangeId()).current().review(in);
+ AuthException thrown =
+ assertThrows(
+ AuthException.class, () -> gApi.changes().id(r.getChangeId()).current().review(in));
+ assertThat(thrown).hasMessageThat().contains("not allowed to modify other user's drafts");
}
@Test
@@ -281,10 +293,10 @@
in.onBehalfOf = "doesnotexist";
in.label("Code-Review", 1);
- exception.expect(UnprocessableEntityException.class);
- exception.expectMessage("not found");
- exception.expectMessage("doesnotexist");
- revision.review(in);
+ UnprocessableEntityException thrown =
+ assertThrows(UnprocessableEntityException.class, () -> revision.review(in));
+ assertThat(thrown).hasMessageThat().contains("not found");
+ assertThat(thrown).hasMessageThat().contains("doesnotexist");
}
@Test
@@ -299,9 +311,11 @@
in.onBehalfOf = user.id().toString();
in.label("Code-Review", 1);
- exception.expect(UnprocessableEntityException.class);
- exception.expectMessage("on_behalf_of account " + user.id() + " cannot see change");
- revision.review(in);
+ UnprocessableEntityException thrown =
+ assertThrows(UnprocessableEntityException.class, () -> revision.review(in));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("on_behalf_of account " + user.id() + " cannot see change");
}
@GerritConfig(name = "accounts.visibility", value = "SAME_GROUP")
@@ -318,10 +332,10 @@
in.onBehalfOf = user.id().toString();
in.label("Code-Review", 1);
- exception.expect(UnprocessableEntityException.class);
- exception.expectMessage("not found");
- exception.expectMessage(in.onBehalfOf);
- revision.review(in);
+ UnprocessableEntityException thrown =
+ assertThrows(UnprocessableEntityException.class, () -> revision.review(in));
+ assertThat(thrown).hasMessageThat().contains("not found");
+ assertThat(thrown).hasMessageThat().contains(in.onBehalfOf);
}
@Test
@@ -338,8 +352,8 @@
assertThat(cd.change().isMerged()).isTrue();
PatchSetApproval submitter =
approvalsUtil.getSubmitter(cd.notes(), cd.change().currentPatchSetId());
- assertThat(submitter.getAccountId()).isEqualTo(admin2.id());
- assertThat(submitter.getRealAccountId()).isEqualTo(admin.id());
+ assertThat(submitter.accountId()).isEqualTo(admin2.id());
+ assertThat(submitter.realAccountId()).isEqualTo(admin.id());
}
@Test
@@ -350,10 +364,12 @@
gApi.changes().id(changeId).current().review(ReviewInput.approve());
SubmitInput in = new SubmitInput();
in.onBehalfOf = "doesnotexist";
- exception.expect(UnprocessableEntityException.class);
- exception.expectMessage("not found");
- exception.expectMessage("doesnotexist");
- gApi.changes().id(changeId).current().submit(in);
+ UnprocessableEntityException thrown =
+ assertThrows(
+ UnprocessableEntityException.class,
+ () -> gApi.changes().id(changeId).current().submit(in));
+ assertThat(thrown).hasMessageThat().contains("not found");
+ assertThat(thrown).hasMessageThat().contains("doesnotexist");
}
@Test
@@ -365,9 +381,15 @@
.review(ReviewInput.approve());
SubmitInput in = new SubmitInput();
in.onBehalfOf = admin2.email();
- exception.expect(AuthException.class);
- exception.expectMessage("submit on behalf of other users not permitted");
- gApi.changes().id(project.get() + "~master~" + r.getChangeId()).current().submit(in);
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () ->
+ gApi.changes()
+ .id(project.get() + "~master~" + r.getChangeId())
+ .current()
+ .submit(in));
+ assertThat(thrown).hasMessageThat().contains("submit on behalf of other users not permitted");
}
@Test
@@ -380,9 +402,13 @@
gApi.changes().id(changeId).current().review(ReviewInput.approve());
SubmitInput in = new SubmitInput();
in.onBehalfOf = user.email();
- exception.expect(UnprocessableEntityException.class);
- exception.expectMessage("on_behalf_of account " + user.id() + " cannot see change");
- gApi.changes().id(changeId).current().submit(in);
+ UnprocessableEntityException thrown =
+ assertThrows(
+ UnprocessableEntityException.class,
+ () -> gApi.changes().id(changeId).current().submit(in));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("on_behalf_of account " + user.id() + " cannot see change");
}
@GerritConfig(name = "accounts.visibility", value = "SAME_GROUP")
@@ -397,10 +423,12 @@
gApi.changes().id(changeId).current().review(ReviewInput.approve());
SubmitInput in = new SubmitInput();
in.onBehalfOf = user.email();
- exception.expect(UnprocessableEntityException.class);
- exception.expectMessage("not found");
- exception.expectMessage(in.onBehalfOf);
- gApi.changes().id(changeId).current().submit(in);
+ UnprocessableEntityException thrown =
+ assertThrows(
+ UnprocessableEntityException.class,
+ () -> gApi.changes().id(changeId).current().submit(in));
+ assertThat(thrown).hasMessageThat().contains("not found");
+ assertThat(thrown).hasMessageThat().contains(in.onBehalfOf);
}
@Test
@@ -510,11 +538,11 @@
adminRestSession.postWithHeader(endpoint, runAsHeader(user2.id()), in).assertOK();
PatchSetApproval psa = Iterables.getOnlyElement(r.getChange().approvals().values());
- assertThat(psa.getPatchSetId().get()).isEqualTo(1);
- assertThat(psa.getLabel()).isEqualTo("Code-Review");
- assertThat(psa.getAccountId()).isEqualTo(user.id());
- assertThat(psa.getValue()).isEqualTo(1);
- assertThat(psa.getRealAccountId()).isEqualTo(admin.id()); // not user2
+ assertThat(psa.patchSetId().get()).isEqualTo(1);
+ assertThat(psa.label()).isEqualTo("Code-Review");
+ assertThat(psa.accountId()).isEqualTo(user.id());
+ assertThat(psa.value()).isEqualTo(1);
+ assertThat(psa.realAccountId()).isEqualTo(admin.id()); // not user2
ChangeData cd = r.getChange();
ChangeMessage m = Iterables.getLast(cmUtil.byChange(cd.notes()));
@@ -546,53 +574,53 @@
}
private void allowCodeReviewOnBehalfOf() throws Exception {
- try (ProjectConfigUpdate u = updateProject(project)) {
- LabelType codeReviewType = Util.codeReview();
- String forCodeReviewAs = Permission.forLabelAs(codeReviewType.getName());
- String heads = "refs/heads/*";
- AccountGroup.UUID uuid = systemGroupBackend.getGroup(REGISTERED_USERS).getUUID();
- Util.allow(u.getConfig(), forCodeReviewAs, -1, 1, uuid, heads);
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(
+ allowLabel(TestLabels.codeReview().getName())
+ .impersonation(true)
+ .ref("refs/heads/*")
+ .group(REGISTERED_USERS)
+ .range(-1, 1))
+ .update();
}
private void allowSubmitOnBehalfOf() throws Exception {
- try (ProjectConfigUpdate u = updateProject(project)) {
- String heads = "refs/heads/*";
- AccountGroup.UUID uuid = systemGroupBackend.getGroup(REGISTERED_USERS).getUUID();
- Util.allow(u.getConfig(), Permission.SUBMIT_AS, uuid, heads);
- Util.allow(u.getConfig(), Permission.SUBMIT, uuid, heads);
- LabelType codeReviewType = Util.codeReview();
- Util.allow(u.getConfig(), Permission.forLabel(codeReviewType.getName()), -2, 2, uuid, heads);
- u.save();
- }
+ String heads = "refs/heads/*";
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.SUBMIT_AS).ref(heads).group(REGISTERED_USERS))
+ .add(allow(Permission.SUBMIT).ref(heads).group(REGISTERED_USERS))
+ .add(
+ allowLabel(TestLabels.codeReview().getName())
+ .ref(heads)
+ .group(REGISTERED_USERS)
+ .range(-2, 2))
+ .update();
}
private void blockRead(GroupInfo group) throws Exception {
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.block(u.getConfig(), Permission.READ, AccountGroup.uuid(group.id), "refs/heads/master");
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.READ).ref("refs/heads/master").group(AccountGroup.uuid(group.id)))
+ .update();
}
private void allowRunAs() throws Exception {
- try (ProjectConfigUpdate u = updateProject(allProjects)) {
- Util.allow(
- u.getConfig(),
- GlobalCapability.RUN_AS,
- systemGroupBackend.getGroup(ANONYMOUS_USERS).getUUID());
- u.save();
- }
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.RUN_AS).group(ANONYMOUS_USERS))
+ .update();
}
private void removeRunAs() throws Exception {
- try (ProjectConfigUpdate u = updateProject(allProjects)) {
- Util.remove(
- u.getConfig(),
- GlobalCapability.RUN_AS,
- systemGroupBackend.getGroup(ANONYMOUS_USERS).getUUID());
- u.save();
- }
+ projectOperations
+ .allProjectsForUpdate()
+ .remove(capabilityKey(GlobalCapability.RUN_AS).group(ANONYMOUS_USERS))
+ .update();
}
private static Header runAsHeader(Object user) {
diff --git a/javatests/com/google/gerrit/acceptance/rest/account/WatchedProjectsIT.java b/javatests/com/google/gerrit/acceptance/rest/account/WatchedProjectsIT.java
index d0c1fa4..2c9107c 100644
--- a/javatests/com/google/gerrit/acceptance/rest/account/WatchedProjectsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/account/WatchedProjectsIT.java
@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance.rest.account;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.Lists;
import com.google.gerrit.acceptance.AbstractDaemonTest;
@@ -114,9 +115,11 @@
pwi.notifyNewPatchSets = true;
projectsToWatch.add(pwi);
- exception.expect(BadRequestException.class);
- exception.expectMessage("duplicate entry for project " + projectName);
- gApi.accounts().self().setWatchedProjects(projectsToWatch);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () -> gApi.accounts().self().setWatchedProjects(projectsToWatch));
+ assertThat(thrown).hasMessageThat().contains("duplicate entry for project " + projectName);
}
@Test
@@ -146,9 +149,9 @@
pwi.notifyNewChanges = true;
pwi.notifyAllComments = true;
projectsToWatch.add(pwi);
-
- exception.expect(UnprocessableEntityException.class);
- gApi.accounts().self().setWatchedProjects(projectsToWatch);
+ assertThrows(
+ UnprocessableEntityException.class,
+ () -> gApi.accounts().self().setWatchedProjects(projectsToWatch));
}
@Test
diff --git a/javatests/com/google/gerrit/acceptance/rest/binding/ConfigRestApiBindingsIT.java b/javatests/com/google/gerrit/acceptance/rest/binding/ConfigRestApiBindingsIT.java
index 02c44ef..cef599f 100644
--- a/javatests/com/google/gerrit/acceptance/rest/binding/ConfigRestApiBindingsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/binding/ConfigRestApiBindingsIT.java
@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance.rest.binding;
import static com.google.common.truth.Truth8.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import com.google.common.collect.ImmutableList;
@@ -22,10 +23,12 @@
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.rest.util.RestApiCallHelper;
import com.google.gerrit.acceptance.rest.util.RestCall;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.server.project.ProjectCacheImpl;
import com.google.gerrit.server.restapi.config.ListTasks.TaskInfo;
import com.google.gson.reflect.TypeToken;
+import com.google.inject.Inject;
import java.util.List;
import java.util.Optional;
import org.junit.Test;
@@ -80,10 +83,15 @@
// Task deletion must be tested last
RestCall.delete("/config/server/tasks/%s"));
+ @Inject private ProjectOperations projectOperations;
+
@Test
public void configEndpoints() throws Exception {
// 'Access Database' is needed for the '/config/server/check.consistency' REST endpoint
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ACCESS_DATABASE);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ACCESS_DATABASE).group(REGISTERED_USERS))
+ .update();
RestApiCallHelper.execute(adminRestSession, CONFIG_ENDPOINTS);
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/binding/ProjectsRestApiBindingsIT.java b/javatests/com/google/gerrit/acceptance/rest/binding/ProjectsRestApiBindingsIT.java
index c838cf9..8969386 100644
--- a/javatests/com/google/gerrit/acceptance/rest/binding/ProjectsRestApiBindingsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/binding/ProjectsRestApiBindingsIT.java
@@ -17,6 +17,7 @@
import static com.google.gerrit.acceptance.GitUtil.assertPushOk;
import static com.google.gerrit.acceptance.GitUtil.pushHead;
import static com.google.gerrit.acceptance.rest.util.RestCall.Method.GET;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.reviewdb.client.RefNames.REFS_DASHBOARDS;
import static com.google.gerrit.server.restapi.project.DashboardsCollection.DEFAULT_DASHBOARD_NAME;
import static org.apache.http.HttpStatus.SC_METHOD_NOT_ALLOWED;
@@ -216,7 +217,7 @@
testRepo
.commit()
.message("A change")
- .parent(getRemoteHead())
+ .parent(projectOperations.project(project).getHead("master"))
.add(filename, "content")
.insertChangeId()
.create();
@@ -234,12 +235,16 @@
private void createDefaultDashboard() throws Exception {
String dashboardRef = REFS_DASHBOARDS + "team";
- grant(project, "refs/meta/*", Permission.CREATE);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref("refs/meta/*").group(adminGroupUuid()))
+ .update();
gApi.projects().name(project.get()).branch(dashboardRef).create(new BranchInput());
- try (Repository r = repoManager.openRepository(project)) {
- TestRepository<Repository>.CommitBuilder cb =
- new TestRepository<>(r).branch(dashboardRef).commit();
+ try (Repository r = repoManager.openRepository(project);
+ TestRepository<Repository> tr = new TestRepository<>(r)) {
+ TestRepository<Repository>.CommitBuilder cb = tr.branch(dashboardRef).commit();
StringBuilder content = new StringBuilder("[dashboard]\n");
content.append("title = ").append("Open Changes").append("\n");
content.append("[section \"").append("open").append("\"]\n");
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
index de986ea..6ae6938 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmit.java
@@ -17,15 +17,22 @@
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.common.truth.Truth.assert_;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.common.truth.TruthJUnit.assume;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.extensions.client.ListChangesOption.CURRENT_REVISION;
import static com.google.gerrit.extensions.client.ListChangesOption.DETAILED_LABELS;
import static com.google.gerrit.extensions.client.ListChangesOption.SUBMITTABLE;
import static com.google.gerrit.server.group.SystemGroupBackend.CHANGE_OWNER;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+import static java.util.Objects.requireNonNull;
import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.stream.Collectors.toList;
+import static org.eclipse.jgit.lib.Constants.EMPTY_TREE_ID;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -40,6 +47,7 @@
import com.google.gerrit.acceptance.TestProjectInput;
import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
+import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.changes.ChangeApi;
import com.google.gerrit.extensions.api.changes.SubmitInput;
@@ -74,7 +82,6 @@
import com.google.gerrit.server.change.TestSubmitInput;
import com.google.gerrit.server.git.validators.OnSubmitValidationListener;
import com.google.gerrit.server.notedb.ChangeNotes;
-import com.google.gerrit.server.project.testing.Util;
import com.google.gerrit.server.restapi.change.Submit;
import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.BatchUpdateOp;
@@ -82,6 +89,7 @@
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.gerrit.server.validators.ValidationException;
import com.google.gerrit.testing.ConfigSuite;
+import com.google.gerrit.testing.GerritJUnit.ThrowingRunnable;
import com.google.gerrit.testing.TestTimeUtil;
import com.google.inject.Inject;
import java.io.ByteArrayOutputStream;
@@ -149,7 +157,7 @@
@Test
@TestProjectInput(createEmptyCommit = false)
- public void submitToEmptyRepo() throws Exception {
+ public void submitToEmptyRepo() throws Throwable {
assertThat(projectOperations.project(project).hasHead("master")).isFalse();
PushOneCommit.Result change = createChange();
assertThat(change.getCommit().getParents()).isEmpty();
@@ -158,16 +166,17 @@
assertThat(actual).hasSize(1);
submit(change.getChangeId());
- assertThat(getRemoteHead().getId()).isEqualTo(change.getCommit());
+ assertThat(projectOperations.project(project).getHead("master").getId())
+ .isEqualTo(change.getCommit());
assertTrees(project, actual);
}
@Test
- public void submitSingleChange() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitSingleChange() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange();
Map<BranchNameKey, ObjectId> actual = fetchFromSubmitPreview(change.getChangeId());
- RevCommit headAfterSubmit = getRemoteHead();
+ RevCommit headAfterSubmit = projectOperations.project(project).getHead("master");
assertThat(headAfterSubmit).isEqualTo(initialHead);
assertRefUpdatedEvents();
assertChangeMergedEvents();
@@ -185,13 +194,13 @@
}
@Test
- public void submitMultipleChangesOtherMergeConflictPreview() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitMultipleChangesOtherMergeConflictPreview() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
- RevCommit headAfterFirstSubmit = getRemoteHead();
+ RevCommit headAfterFirstSubmit = projectOperations.project(project).getHead("master");
testRepo.reset(initialHead);
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "other content");
PushOneCommit.Result change3 = createChange("Change 3", "d", "d");
@@ -225,7 +234,7 @@
break;
case REBASE_IF_NECESSARY:
case REBASE_ALWAYS:
- String change2hash = change2.getChange().currentPatchSet().getCommitId().name();
+ String change2hash = change2.getChange().currentPatchSet().commitId().name();
assertThat(e.getMessage())
.isEqualTo(
"Cannot rebase "
@@ -257,11 +266,11 @@
break;
case CHERRY_PICK:
default:
- fail("Should not reach here.");
+ assert_().fail("Should not reach here.");
break;
}
- RevCommit headAfterSubmit = getRemoteHead();
+ RevCommit headAfterSubmit = projectOperations.project(project).getHead("master");
assertThat(headAfterSubmit).isEqualTo(headAfterFirstSubmit);
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit);
assertChangeMergedEvents(change.getChangeId(), headAfterFirstSubmit.name());
@@ -269,8 +278,8 @@
}
@Test
- public void submitMultipleChangesPreview() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitMultipleChangesPreview() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "other content");
PushOneCommit.Result change3 = createChange("Change 3", "d", "d");
PushOneCommit.Result change4 = createChange("Change 4", "e", "e");
@@ -295,7 +304,7 @@
}
// check that the submit preview did not actually submit
- RevCommit headAfterSubmit = getRemoteHead();
+ RevCommit headAfterSubmit = projectOperations.project(project).getHead("master");
assertThat(headAfterSubmit).isEqualTo(initialHead);
assertRefUpdatedEvents();
assertChangeMergedEvents();
@@ -307,10 +316,14 @@
}
@Test
- public void submitNoPermission() throws Exception {
+ public void submitNoPermission() throws Throwable {
// create project where submit is blocked
Project.NameKey p = projectOperations.newProject().create();
- block(p, "refs/*", Permission.SUBMIT, REGISTERED_USERS);
+ projectOperations
+ .project(p)
+ .forUpdate()
+ .add(block(Permission.SUBMIT).ref("refs/*").group(REGISTERED_USERS))
+ .update();
TestRepository<InMemoryRepository> repo = cloneProject(p, admin);
PushOneCommit push = pushFactory.create(admin.newIdent(), repo);
@@ -321,16 +334,16 @@
}
@Test
- public void noSelfSubmit() throws Exception {
+ public void noSelfSubmit() throws Throwable {
// create project where submit is blocked for the change owner
Project.NameKey p = projectOperations.newProject().create();
- try (ProjectConfigUpdate u = updateProject(p)) {
- Util.block(u.getConfig(), Permission.SUBMIT, CHANGE_OWNER, "refs/*");
- Util.allow(u.getConfig(), Permission.SUBMIT, REGISTERED_USERS, "refs/heads/*");
- Util.allow(
- u.getConfig(), Permission.forLabel("Code-Review"), -2, +2, REGISTERED_USERS, "refs/*");
- u.save();
- }
+ projectOperations
+ .project(p)
+ .forUpdate()
+ .add(block(Permission.SUBMIT).ref("refs/*").group(CHANGE_OWNER))
+ .add(allow(Permission.SUBMIT).ref("refs/heads/*").group(REGISTERED_USERS))
+ .add(allowLabel("Code-Review").ref("refs/*").group(REGISTERED_USERS).range(-2, +2))
+ .update();
TestRepository<InMemoryRepository> repo = cloneProject(p, admin);
PushOneCommit push = pushFactory.create(admin.newIdent(), repo);
@@ -347,16 +360,16 @@
}
@Test
- public void onlySelfSubmit() throws Exception {
+ public void onlySelfSubmit() throws Throwable {
// create project where only the change owner can submit
Project.NameKey p = projectOperations.newProject().create();
- try (ProjectConfigUpdate u = updateProject(p)) {
- Util.block(u.getConfig(), Permission.SUBMIT, REGISTERED_USERS, "refs/*");
- Util.allow(u.getConfig(), Permission.SUBMIT, CHANGE_OWNER, "refs/*");
- Util.allow(
- u.getConfig(), Permission.forLabel("Code-Review"), -2, +2, REGISTERED_USERS, "refs/*");
- u.save();
- }
+ projectOperations
+ .project(p)
+ .forUpdate()
+ .add(block(Permission.SUBMIT).ref("refs/*").group(REGISTERED_USERS))
+ .add(allow(Permission.SUBMIT).ref("refs/*").group(CHANGE_OWNER))
+ .add(allowLabel("Code-Review").ref("refs/*").group(REGISTERED_USERS).range(-2, +2))
+ .update();
TestRepository<InMemoryRepository> repo = cloneProject(p, admin);
PushOneCommit push = pushFactory.create(admin.newIdent(), repo);
@@ -374,7 +387,7 @@
}
@Test
- public void submitWholeTopicMultipleProjects() throws Exception {
+ public void submitWholeTopicMultipleProjects() throws Throwable {
assume().that(isSubmitWholeTopicEnabled()).isTrue();
String topic = "test-topic";
@@ -410,7 +423,7 @@
}
@Test
- public void submitWholeTopicMultipleBranchesOnSameProject() throws Exception {
+ public void submitWholeTopicMultipleBranchesOnSameProject() throws Throwable {
assume().that(isSubmitWholeTopicEnabled()).isTrue();
String topic = "test-topic";
@@ -418,7 +431,7 @@
Project.NameKey keyA = createProjectForPush(getSubmitType());
TestRepository<?> repoA = cloneProject(keyA);
- RevCommit initialHead = getRemoteHead(keyA, "master");
+ RevCommit initialHead = projectOperations.project(keyA).getHead("master");
// Create the dev branch on the test project
BranchInput in = new BranchInput();
@@ -452,7 +465,7 @@
}
@Test
- public void submitWholeTopic() throws Exception {
+ public void submitWholeTopic() throws Throwable {
assume().that(isSubmitWholeTopicEnabled()).isTrue();
String topic = "test-topic";
PushOneCommit.Result change1 = createChange("Change 1", "a.txt", "content", topic);
@@ -490,7 +503,7 @@
}
@Test
- public void submitReusingOldTopic() throws Exception {
+ public void submitReusingOldTopic() throws Throwable {
assume().that(isSubmitWholeTopicEnabled()).isTrue();
String topic = "test-topic";
@@ -521,13 +534,13 @@
}
private void assertSubmittedTogether(String changeId, Iterable<String> expected)
- throws Exception {
+ throws Throwable {
assertThat(gApi.changes().id(changeId).submittedTogether().stream().map(i -> i.changeId))
.containsExactlyElementsIn(expected);
}
@Test
- public void submitWorkInProgressChange() throws Exception {
+ public void submitWorkInProgressChange() throws Throwable {
PushOneCommit.Result change = pushTo("refs/for/master%wip");
Change.Id num = change.getChange().getId();
submitWithConflict(
@@ -541,7 +554,7 @@
}
@Test
- public void submitWithHiddenBranchInSameTopic() throws Exception {
+ public void submitWithHiddenBranchInSameTopic() throws Throwable {
assume().that(isSubmitWholeTopicEnabled()).isTrue();
PushOneCommit.Result visible = createChange("refs/for/master/" + name("topic"));
Change.Id num = visible.getChange().getId();
@@ -549,7 +562,11 @@
createBranch(BranchNameKey.create(project, "hidden"));
PushOneCommit.Result hidden = createChange("refs/for/hidden/" + name("topic"));
approve(hidden.getChangeId());
- blockRead("refs/heads/hidden");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.READ).ref("refs/heads/hidden").group(REGISTERED_USERS))
+ .update();
submit(
visible.getChangeId(),
@@ -559,7 +576,7 @@
}
@Test
- public void submitChangeWhenParentOfOtherBranchTip() throws Exception {
+ public void submitChangeWhenParentOfOtherBranchTip() throws Throwable {
// Chain of two commits
// Push both to topic-branch
// Push the first commit for review and submit
@@ -597,7 +614,7 @@
}
@Test
- public void submitMergeOfNonChangeBranchTip() throws Exception {
+ public void submitMergeOfNonChangeBranchTip() throws Throwable {
// Merge a branch with commits that have not been submitted as
// changes.
//
@@ -607,7 +624,7 @@
// | /
// I -- master
//
- RevCommit master = getRemoteHead(project, "master");
+ RevCommit master = projectOperations.project(project).getHead("master");
PushOneCommit stableTip =
pushFactory.create(admin.newIdent(), testRepo, "Tip of branch stable", "stable.txt", "");
PushOneCommit.Result stable = stableTip.to("refs/heads/stable");
@@ -624,7 +641,7 @@
}
@Test
- public void submitMergeOfNonChangeBranchNonTip() throws Exception {
+ public void submitMergeOfNonChangeBranchNonTip() throws Throwable {
// Merge a branch with commits that have not been submitted as
// changes.
//
@@ -635,7 +652,7 @@
// | /
// I -- master
//
- RevCommit initial = getRemoteHead(project, "master");
+ RevCommit initial = projectOperations.project(project).getHead("master");
// push directly to stable to S1
PushOneCommit.Result s1 =
pushFactory
@@ -668,11 +685,11 @@
}
@Test
- public void submitChangeWithCommitThatWasAlreadyMerged() throws Exception {
+ public void submitChangeWithCommitThatWasAlreadyMerged() throws Throwable {
// create and submit a change
PushOneCommit.Result change = createChange();
submit(change.getChangeId());
- RevCommit headAfterSubmit = getRemoteHead();
+ RevCommit headAfterSubmit = projectOperations.project(project).getHead("master");
// set the status of the change back to NEW to simulate a failed submit that
// merged the commit but failed to update the change status
@@ -681,11 +698,11 @@
// submitting the change again should detect that the commit was already
// merged and just fix the change status to be MERGED
submit(change.getChangeId());
- assertThat(getRemoteHead()).isEqualTo(headAfterSubmit);
+ assertThat(projectOperations.project(project).getHead("master")).isEqualTo(headAfterSubmit);
}
@Test
- public void submitChangesWithCommitsThatWereAlreadyMerged() throws Exception {
+ public void submitChangesWithCommitsThatWereAlreadyMerged() throws Throwable {
// create and submit 2 changes
PushOneCommit.Result change1 = createChange();
PushOneCommit.Result change2 = createChange();
@@ -695,7 +712,7 @@
}
submit(change2.getChangeId());
assertMerged(change1.getChangeId());
- RevCommit headAfterSubmit = getRemoteHead();
+ RevCommit headAfterSubmit = projectOperations.project(project).getHead("master");
// set the status of the changes back to NEW to simulate a failed submit that
// merged the commits but failed to update the change status
@@ -705,11 +722,11 @@
// merged and just fix the change status to be MERGED
submit(change1.getChangeId());
submit(change2.getChangeId());
- assertThat(getRemoteHead()).isEqualTo(headAfterSubmit);
+ assertThat(projectOperations.project(project).getHead("master")).isEqualTo(headAfterSubmit);
}
@Test
- public void submitTopicWithCommitsThatWereAlreadyMerged() throws Exception {
+ public void submitTopicWithCommitsThatWereAlreadyMerged() throws Throwable {
assume().that(isSubmitWholeTopicEnabled()).isTrue();
// create and submit 2 changes with the same topic
@@ -719,7 +736,7 @@
approve(change1.getChangeId());
submit(change2.getChangeId());
assertMerged(change1.getChangeId());
- RevCommit headAfterSubmit = getRemoteHead();
+ RevCommit headAfterSubmit = projectOperations.project(project).getHead("master");
// set the status of the second change back to NEW to simulate a failed
// submit that merged the commits but failed to update the change status of
@@ -729,11 +746,11 @@
// submitting the topic again should detect that the commits were already
// merged and just fix the change status to be MERGED
submit(change2.getChangeId());
- assertThat(getRemoteHead()).isEqualTo(headAfterSubmit);
+ assertThat(projectOperations.project(project).getHead("master")).isEqualTo(headAfterSubmit);
}
@Test
- public void submitWithValidation() throws Exception {
+ public void submitWithValidation() throws Throwable {
AtomicBoolean called = new AtomicBoolean(false);
this.addOnSubmitValidationListener(
args -> {
@@ -755,7 +772,7 @@
}
@Test
- public void submitWithValidationMultiRepo() throws Exception {
+ public void submitWithValidationMultiRepo() throws Throwable {
assume().that(isSubmitWholeTopicEnabled()).isTrue();
String topic = "test-topic";
@@ -818,10 +835,10 @@
}
@Test
- public void submitWithCommitAndItsMergeCommitTogether() throws Exception {
+ public void submitWithCommitAndItsMergeCommitTogether() throws Throwable {
assume().that(isSubmitWholeTopicEnabled()).isTrue();
- RevCommit initialHead = getRemoteHead();
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
// Create a stable branch and bootstrap it.
gApi.projects().name(project.get()).branch("stable").create(new BranchInput());
@@ -829,8 +846,8 @@
pushFactory.create(user.newIdent(), testRepo, "initial commit", "a.txt", "a");
PushOneCommit.Result change = push.to("refs/heads/stable");
- RevCommit stable = getRemoteHead(project, "stable");
- RevCommit master = getRemoteHead(project, "master");
+ RevCommit stable = projectOperations.project(project).getHead("stable");
+ RevCommit master = projectOperations.project(project).getHead("master");
assertThat(master).isEqualTo(initialHead);
assertThat(stable).isEqualTo(change.getCommit());
@@ -883,13 +900,13 @@
assertMerged(mergeId);
testRepo.git().fetch().call();
RevWalk rw = testRepo.getRevWalk();
- master = rw.parseCommit(getRemoteHead(project, "master"));
+ master = rw.parseCommit(projectOperations.project(project).getHead("master"));
assertThat(rw.isMergedInto(merge, master)).isTrue();
assertThat(rw.isMergedInto(fix, master)).isTrue();
}
@Test
- public void retrySubmitSingleChangeOnLockFailure() throws Exception {
+ public void retrySubmitSingleChangeOnLockFailure() throws Throwable {
PushOneCommit.Result change = createChange();
String id = change.getChangeId();
approve(id);
@@ -906,7 +923,7 @@
testRepo.git().fetch().call();
RevWalk rw = testRepo.getRevWalk();
- RevCommit master = rw.parseCommit(getRemoteHead(project, "master"));
+ RevCommit master = rw.parseCommit(projectOperations.project(project).getHead("master"));
RevCommit patchSet = parseCurrentRevision(rw, change.getChangeId());
assertThat(rw.isMergedInto(patchSet, master)).isTrue();
@@ -914,7 +931,7 @@
}
@Test
- public void retrySubmitAfterTornTopicOnLockFailure() throws Exception {
+ public void retrySubmitAfterTornTopicOnLockFailure() throws Throwable {
assume().that(isSubmitWholeTopicEnabled()).isTrue();
String topic = "test-topic";
@@ -949,13 +966,13 @@
repoA.git().fetch().call();
RevWalk rwA = repoA.getRevWalk();
- RevCommit masterA = rwA.parseCommit(getRemoteHead(keyA, "master"));
+ RevCommit masterA = rwA.parseCommit(projectOperations.project(keyA).getHead("master"));
RevCommit change1Ps = parseCurrentRevision(rwA, change1.getChangeId());
assertThat(rwA.isMergedInto(change1Ps, masterA)).isTrue();
repoB.git().fetch().call();
RevWalk rwB = repoB.getRevWalk();
- RevCommit masterB = rwB.parseCommit(getRemoteHead(keyB, "master"));
+ RevCommit masterB = rwB.parseCommit(projectOperations.project(keyB).getHead("master"));
RevCommit change2Ps = parseCurrentRevision(rwB, change2.getChangeId());
assertThat(rwB.isMergedInto(change2Ps, masterB)).isTrue();
@@ -963,14 +980,14 @@
}
@Test
- public void authorAndCommitDateAreEqual() throws Exception {
+ public void authorAndCommitDateAreEqual() throws Throwable {
assume().that(getSubmitType()).isNotEqualTo(SubmitType.FAST_FORWARD_ONLY);
ConfigInput ci = new ConfigInput();
ci.matchAuthorToCommitterDate = InheritableBoolean.TRUE;
gApi.projects().name(project.get()).config(ci);
- RevCommit initialHead = getRemoteHead();
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
testRepo.reset(initialHead);
PushOneCommit.Result change = createChange("Change 1", "b", "b");
@@ -984,12 +1001,12 @@
}
submit(change2.getChangeId());
- assertAuthorAndCommitDateEquals(getRemoteHead());
+ assertAuthorAndCommitDateEquals(projectOperations.project(project).getHead("master"));
}
@Test
@TestProjectInput(rejectEmptyCommit = InheritableBoolean.FALSE)
- public void submitEmptyCommitPatchSetCanNotFastForward_emptyCommitAllowed() throws Exception {
+ public void submitEmptyCommitPatchSetCanNotFastForward_emptyCommitAllowed() throws Throwable {
assume().that(getSubmitType()).isNotEqualTo(SubmitType.FAST_FORWARD_ONLY);
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
@@ -1006,7 +1023,7 @@
@Test
@TestProjectInput(rejectEmptyCommit = InheritableBoolean.TRUE)
- public void submitEmptyCommitPatchSetCanNotFastForward_emptyCommitNotAllowed() throws Exception {
+ public void submitEmptyCommitPatchSetCanNotFastForward_emptyCommitNotAllowed() throws Throwable {
assume().that(getSubmitType()).isNotEqualTo(SubmitType.FAST_FORWARD_ONLY);
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
@@ -1019,18 +1036,20 @@
ChangeApi revert2 = gApi.changes().id(change.getChangeId()).revert();
approve(revert2.id());
- exception.expect(ResourceConflictException.class);
- exception.expectMessage(
- "Change "
- + revert2.get()._number
- + ": Change could not be merged because the commit is empty. "
- + "Project policy requires all commits to contain modifications to at least one file.");
- revert2.current().submit();
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> revert2.current().submit());
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ "Change "
+ + revert2.get()._number
+ + ": Change could not be merged because the commit is empty. Project policy"
+ + " requires all commits to contain modifications to at least one file.");
}
@Test
@TestProjectInput(rejectEmptyCommit = InheritableBoolean.FALSE)
- public void submitEmptyCommitPatchSetCanFastForward_emptyCommitAllowed() throws Exception {
+ public void submitEmptyCommitPatchSetCanFastForward_emptyCommitAllowed() throws Throwable {
ChangeInput ci = new ChangeInput();
ci.subject = "Empty change";
ci.project = project.get();
@@ -1042,7 +1061,7 @@
@Test
@TestProjectInput(rejectEmptyCommit = InheritableBoolean.TRUE)
- public void submitEmptyCommitPatchSetCanFastForward_emptyCommitNotAllowed() throws Exception {
+ public void submitEmptyCommitPatchSetCanFastForward_emptyCommitNotAllowed() throws Throwable {
ChangeInput ci = new ChangeInput();
ci.subject = "Empty change";
ci.project = project.get();
@@ -1050,18 +1069,20 @@
ChangeApi change = gApi.changes().create(ci);
approve(change.id());
- exception.expect(ResourceConflictException.class);
- exception.expectMessage(
- "Change "
- + change.get()._number
- + ": Change could not be merged because the commit is empty. "
- + "Project policy requires all commits to contain modifications to at least one file.");
- change.current().submit();
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> change.current().submit());
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ "Change "
+ + change.get()._number
+ + ": Change could not be merged because the commit is empty. Project policy"
+ + " requires all commits to contain modifications to at least one file.");
}
@Test
@TestProjectInput(createEmptyCommit = false, rejectEmptyCommit = InheritableBoolean.TRUE)
- public void submitNonemptyCommitToEmptyRepoWithRejectEmptyCommit_allowed() throws Exception {
+ public void submitNonemptyCommitToEmptyRepoWithRejectEmptyCommit_allowed() throws Throwable {
assertThat(projectOperations.project(project).hasHead("master")).isFalse();
PushOneCommit.Result change = createChange();
assertThat(change.getCommit().getParents()).isEmpty();
@@ -1070,33 +1091,33 @@
assertThat(actual).hasSize(1);
submit(change.getChangeId());
- assertThat(getRemoteHead().getId()).isEqualTo(change.getCommit());
+ assertThat(projectOperations.project(project).getHead("master").getId())
+ .isEqualTo(change.getCommit());
assertTrees(project, actual);
}
@Test
@TestProjectInput(createEmptyCommit = false, rejectEmptyCommit = InheritableBoolean.TRUE)
- public void submitEmptyCommitToEmptyRepoWithRejectEmptyCommit_allowed() throws Exception {
+ public void submitEmptyCommitToEmptyRepoWithRejectEmptyCommit_allowed() throws Throwable {
assertThat(projectOperations.project(project).hasHead("master")).isFalse();
PushOneCommit.Result change =
pushFactory
.create(admin.newIdent(), testRepo, "Change 1", ImmutableMap.of())
.to("refs/for/master");
change.assertOkStatus();
- // TODO(dborowitz): Use EMPTY_TREE_ID after upgrading to https://git.eclipse.org/r/127473
- assertThat(change.getCommit().getTree())
- .isEqualTo(ObjectId.fromString("4b825dc642cb6eb9a060e54bf8d69288fbee4904"));
+ assertThat(change.getCommit().getTree()).isEqualTo(EMPTY_TREE_ID);
Map<BranchNameKey, ObjectId> actual = fetchFromSubmitPreview(change.getChangeId());
assertThat(projectOperations.project(project).hasHead("master")).isFalse();
assertThat(actual).hasSize(1);
submit(change.getChangeId());
- assertThat(getRemoteHead().getId()).isEqualTo(change.getCommit());
+ assertThat(projectOperations.project(project).getHead("master").getId())
+ .isEqualTo(change.getCommit());
assertTrees(project, actual);
}
- private void setChangeStatusToNew(PushOneCommit.Result... changes) throws Exception {
+ private void setChangeStatusToNew(PushOneCommit.Result... changes) throws Throwable {
for (PushOneCommit.Result change : changes) {
try (BatchUpdate bu =
batchUpdateFactory.create(project, userFactory.create(admin.id()), TimeUtil.nowTs())) {
@@ -1115,7 +1136,7 @@
}
}
- private void assertSubmitter(PushOneCommit.Result change) throws Exception {
+ private void assertSubmitter(PushOneCommit.Result change) throws Throwable {
ChangeInfo info = get(change.getChangeId(), ListChangesOption.MESSAGES);
assertThat(info.messages).isNotNull();
Iterable<String> messages = Iterables.transform(info.messages, i -> i.message);
@@ -1138,60 +1159,42 @@
}
}
- protected void submit(String changeId) throws Exception {
+ protected void submit(String changeId) throws Throwable {
submit(changeId, new SubmitInput(), null, null);
}
- protected void submit(String changeId, SubmitInput input) throws Exception {
+ protected void submit(String changeId, SubmitInput input) throws Throwable {
submit(changeId, input, null, null);
}
- protected void submitWithConflict(String changeId, String expectedError) throws Exception {
+ protected void submitWithConflict(String changeId, String expectedError) throws Throwable {
submit(changeId, new SubmitInput(), ResourceConflictException.class, expectedError);
}
protected void submit(
String changeId,
SubmitInput input,
- Class<? extends RestApiException> expectedExceptionType,
+ @Nullable Class<? extends RestApiException> expectedExceptionType,
String expectedExceptionMsg)
- throws Exception {
+ throws Throwable {
approve(changeId);
if (expectedExceptionType == null) {
assertSubmittable(changeId);
+ } else {
+ requireNonNull(expectedExceptionMsg);
}
- try {
- gApi.changes().id(changeId).current().submit(input);
- if (expectedExceptionType != null) {
- fail("Expected exception of type " + expectedExceptionType.getSimpleName());
- }
- } catch (RestApiException e) {
- if (expectedExceptionType == null) {
- throw e;
- }
- // More verbose than using assertThat and/or ExpectedException, but gives
- // us the stack trace.
- if (!expectedExceptionType.isAssignableFrom(e.getClass())
- || !e.getMessage().equals(expectedExceptionMsg)) {
- throw new AssertionError(
- "Expected exception of type "
- + expectedExceptionType.getSimpleName()
- + " with message: \""
- + expectedExceptionMsg
- + "\" but got exception of type "
- + e.getClass().getSimpleName()
- + " with message \""
- + e.getMessage()
- + "\"",
- e);
- }
+ ThrowingRunnable submit = () -> gApi.changes().id(changeId).current().submit(input);
+ if (expectedExceptionType != null) {
+ RestApiException thrown = assertThrows(expectedExceptionType, submit);
+ assertThat(thrown).hasMessageThat().isEqualTo(expectedExceptionMsg);
return;
}
+ submit.run();
ChangeInfo change = gApi.changes().id(changeId).info();
assertMerged(change.changeId);
}
- protected void assertSubmittable(String changeId) throws Exception {
+ protected void assertSubmittable(String changeId) throws Throwable {
assertWithMessage("submit bit on ChangeInfo")
.that(get(changeId, SUBMITTABLE).submittable)
.isTrue();
@@ -1201,16 +1204,16 @@
assertWithMessage("enabled bit on submit action").that(desc.isEnabled()).isTrue();
}
- protected void assertChangeMergedEvents(String... expected) throws Exception {
+ protected void assertChangeMergedEvents(String... expected) throws Throwable {
eventRecorder.assertChangeMergedEvents(project.get(), "refs/heads/master", expected);
}
- protected void assertRefUpdatedEvents(RevCommit... expected) throws Exception {
+ protected void assertRefUpdatedEvents(RevCommit... expected) throws Throwable {
eventRecorder.assertRefUpdatedEvents(project.get(), "refs/heads/master", expected);
}
protected void assertCurrentRevision(String changeId, int expectedNum, ObjectId expectedId)
- throws Exception {
+ throws Throwable {
ChangeInfo c = get(changeId, CURRENT_REVISION);
assertThat(c.currentRevision).isEqualTo(expectedId.name());
assertThat(c.revisions.get(expectedId.name())._number).isEqualTo(expectedNum);
@@ -1222,15 +1225,15 @@
}
}
- protected void assertNew(String changeId) throws Exception {
+ protected void assertNew(String changeId) throws Throwable {
assertThat(info(changeId).status).isEqualTo(ChangeStatus.NEW);
}
- protected void assertApproved(String changeId) throws Exception {
+ protected void assertApproved(String changeId) throws Throwable {
assertApproved(changeId, admin);
}
- protected void assertApproved(String changeId, TestAccount user) throws Exception {
+ protected void assertApproved(String changeId, TestAccount user) throws Throwable {
ChangeInfo c = get(changeId, DETAILED_LABELS);
LabelInfo cr = c.labels.get("Code-Review");
assertThat(cr.all).hasSize(1);
@@ -1255,21 +1258,21 @@
.isEqualTo(commit.getCommitterIdent().getTimeZone());
}
- protected void assertSubmitter(String changeId, int psId) throws Exception {
+ protected void assertSubmitter(String changeId, int psId) throws Throwable {
assertSubmitter(changeId, psId, admin);
}
- protected void assertSubmitter(String changeId, int psId, TestAccount user) throws Exception {
+ protected void assertSubmitter(String changeId, int psId, TestAccount user) throws Throwable {
Change c = getOnlyElement(queryProvider.get().byKeyPrefix(changeId)).change();
ChangeNotes cn = notesFactory.createChecked(c);
PatchSetApproval submitter =
approvalsUtil.getSubmitter(cn, PatchSet.id(cn.getChangeId(), psId));
assertThat(submitter).isNotNull();
assertThat(submitter.isLegacySubmit()).isTrue();
- assertThat(submitter.getAccountId()).isEqualTo(user.id());
+ assertThat(submitter.accountId()).isEqualTo(user.id());
}
- protected void assertNoSubmitter(String changeId, int psId) throws Exception {
+ protected void assertNoSubmitter(String changeId, int psId) throws Throwable {
Change c = getOnlyElement(queryProvider.get().byKeyPrefix(changeId)).change();
ChangeNotes cn = notesFactory.createChecked(c);
PatchSetApproval submitter =
@@ -1278,17 +1281,17 @@
}
protected void assertCherryPick(TestRepository<?> testRepo, boolean contentMerge)
- throws Exception {
+ throws Throwable {
assertRebase(testRepo, contentMerge);
- RevCommit remoteHead = getRemoteHead();
+ RevCommit remoteHead = projectOperations.project(project).getHead("master");
assertThat(remoteHead.getFooterLines("Reviewed-On")).isNotEmpty();
assertThat(remoteHead.getFooterLines("Reviewed-By")).isNotEmpty();
}
- protected void assertRebase(TestRepository<?> testRepo, boolean contentMerge) throws Exception {
+ protected void assertRebase(TestRepository<?> testRepo, boolean contentMerge) throws Throwable {
Repository repo = testRepo.getRepository();
RevCommit localHead = getHead(repo, "HEAD");
- RevCommit remoteHead = getRemoteHead();
+ RevCommit remoteHead = projectOperations.project(project).getHead("master");
assertThat(localHead.getId()).isNotEqualTo(remoteHead.getId());
assertThat(remoteHead.getParentCount()).isEqualTo(1);
if (!contentMerge) {
@@ -1297,7 +1300,7 @@
assertThat(remoteHead.getShortMessage()).isEqualTo(localHead.getShortMessage());
}
- protected List<RevCommit> getRemoteLog(Project.NameKey project, String branch) throws Exception {
+ protected List<RevCommit> getRemoteLog(Project.NameKey project, String branch) throws Throwable {
try (Repository repo = repoManager.openRepository(project);
RevWalk rw = new RevWalk(repo)) {
rw.markStart(rw.parseCommit(repo.exactRef("refs/heads/" + branch).getObjectId()));
@@ -1305,7 +1308,7 @@
}
}
- protected List<RevCommit> getRemoteLog() throws Exception {
+ protected List<RevCommit> getRemoteLog() throws Throwable {
return getRemoteLog(project, "master");
}
@@ -1314,13 +1317,13 @@
onSubmitValidatorHandle = onSubmitValidationListeners.add("gerrit", listener);
}
- private String getLatestDiff(Repository repo) throws Exception {
+ private String getLatestDiff(Repository repo) throws Throwable {
ObjectId oldTreeId = repo.resolve("HEAD~1^{tree}");
ObjectId newTreeId = repo.resolve("HEAD^{tree}");
return getLatestDiff(repo, oldTreeId, newTreeId);
}
- private String getLatestRemoteDiff() throws Exception {
+ private String getLatestRemoteDiff() throws Throwable {
try (Repository repo = repoManager.openRepository(project);
RevWalk rw = new RevWalk(repo)) {
ObjectId oldTreeId = repo.resolve("refs/heads/master~1^{tree}");
@@ -1330,7 +1333,7 @@
}
private String getLatestDiff(Repository repo, ObjectId oldTreeId, ObjectId newTreeId)
- throws Exception {
+ throws Throwable {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try (DiffFormatter fmt = new DiffFormatter(out)) {
fmt.setRepository(repo);
@@ -1341,15 +1344,19 @@
}
// TODO(hanwen): the submodule tests have a similar method; maybe we could share code?
- protected Project.NameKey createProjectForPush(SubmitType submitType) throws Exception {
+ protected Project.NameKey createProjectForPush(SubmitType submitType) throws Throwable {
Project.NameKey project = projectOperations.newProject().submitType(submitType).create();
- grant(project, "refs/heads/*", Permission.PUSH);
- grant(project, "refs/for/refs/heads/*", Permission.SUBMIT);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/heads/*").group(adminGroupUuid()))
+ .add(allow(Permission.SUBMIT).ref("refs/for/refs/heads/*").group(adminGroupUuid()))
+ .update();
return project;
}
protected PushOneCommit.Result createChange(
- String subject, String fileName, String content, String topic) throws Exception {
+ String subject, String fileName, String content, String topic) throws Throwable {
PushOneCommit push = pushFactory.create(admin.newIdent(), testRepo, subject, fileName, content);
return push.to("refs/for/master/" + name(topic));
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByMerge.java b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByMerge.java
index 36a09fd..a4fa84b 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByMerge.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByMerge.java
@@ -19,23 +19,26 @@
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestProjectInput;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.extensions.client.InheritableBoolean;
+import com.google.inject.Inject;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Test;
public abstract class AbstractSubmitByMerge extends AbstractSubmit {
+ @Inject private ProjectOperations projectOperations;
@Test
- public void submitWithMerge() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitWithMerge() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
- RevCommit oldHead = getRemoteHead();
+ RevCommit oldHead = projectOperations.project(project).getHead("master");
testRepo.reset(initialHead);
PushOneCommit.Result change2 = createChange("Change 2", "b.txt", "other content");
submit(change2.getChangeId());
- RevCommit head = getRemoteHead();
+ RevCommit head = projectOperations.project(project).getHead("master");
assertThat(head.getParentCount()).isEqualTo(2);
assertThat(head.getParent(0)).isEqualTo(oldHead);
assertThat(head.getParent(1)).isEqualTo(change2.getCommit());
@@ -43,17 +46,17 @@
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
- public void submitWithContentMerge() throws Exception {
+ public void submitWithContentMerge() throws Throwable {
PushOneCommit.Result change = createChange("Change 1", "a.txt", "aaa\nbbb\nccc\n");
submit(change.getChangeId());
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "aaa\nbbb\nccc\nddd\n");
submit(change2.getChangeId());
- RevCommit oldHead = getRemoteHead();
+ RevCommit oldHead = projectOperations.project(project).getHead("master");
testRepo.reset(change.getCommit());
PushOneCommit.Result change3 = createChange("Change 3", "a.txt", "bbb\nccc\n");
submit(change3.getChangeId());
- RevCommit head = getRemoteHead();
+ RevCommit head = projectOperations.project(project).getHead("master");
assertThat(head.getParentCount()).isEqualTo(2);
assertThat(head.getParent(0)).isEqualTo(oldHead);
assertThat(head.getParent(1)).isEqualTo(change3.getCommit());
@@ -61,12 +64,12 @@
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
- public void submitWithContentMerge_Conflict() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitWithContentMerge_Conflict() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
- RevCommit oldHead = getRemoteHead();
+ RevCommit oldHead = projectOperations.project(project).getHead("master");
testRepo.reset(initialHead);
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "other content");
submitWithConflict(
@@ -78,22 +81,23 @@
+ "Change could not be merged due to a path conflict. "
+ "Please rebase the change locally "
+ "and upload the rebased commit for review.");
- assertThat(getRemoteHead()).isEqualTo(oldHead);
+ assertThat(projectOperations.project(project).getHead("master")).isEqualTo(oldHead);
}
@Test
@TestProjectInput(createEmptyCommit = false)
- public void submitMultipleCommitsToEmptyRepoAsFastForward() throws Exception {
+ public void submitMultipleCommitsToEmptyRepoAsFastForward() throws Throwable {
PushOneCommit.Result change1 = createChange();
PushOneCommit.Result change2 = createChange();
approve(change1.getChangeId());
submit(change2.getChangeId());
- assertThat(getRemoteHead().getId()).isEqualTo(change2.getCommit());
+ assertThat(projectOperations.project(project).getHead("master").getId())
+ .isEqualTo(change2.getCommit());
}
@Test
@TestProjectInput(createEmptyCommit = false)
- public void submitMultipleCommitsToEmptyRepoWithOneMerge() throws Exception {
+ public void submitMultipleCommitsToEmptyRepoWithOneMerge() throws Throwable {
assume().that(isSubmitWholeTopicEnabled()).isTrue();
PushOneCommit.Result change1 =
pushFactory
@@ -108,7 +112,7 @@
approve(change1.getChangeId());
submit(change2.getChangeId());
- RevCommit head = getRemoteHead();
+ RevCommit head = projectOperations.project(project).getHead("master");
assertThat(head.getParents()).hasLength(2);
assertThat(head.getParent(0)).isEqualTo(change1.getCommit());
assertThat(head.getParent(1)).isEqualTo(change2.getCommit());
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByRebase.java b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByRebase.java
index c577e09..e05e0b7 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByRebase.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/AbstractSubmitByRebase.java
@@ -17,12 +17,16 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.GitUtil.getChangeId;
import static com.google.gerrit.acceptance.GitUtil.pushHead;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.TestProjectInput;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.client.ChangeStatus;
@@ -31,7 +35,7 @@
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.reviewdb.client.BranchNameKey;
import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.server.project.testing.Util;
+import com.google.gerrit.server.project.testing.TestLabels;
import com.google.inject.Inject;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
@@ -40,6 +44,7 @@
import org.junit.Test;
public abstract class AbstractSubmitByRebase extends AbstractSubmit {
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Override
@@ -47,42 +52,41 @@
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
- public void submitWithRebase() throws Exception {
+ public void submitWithRebase() throws Throwable {
submitWithRebase(admin);
}
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
- public void submitWithRebaseWithoutAddPatchSetPermission() throws Exception {
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.block(u.getConfig(), Permission.ADD_PATCH_SET, REGISTERED_USERS, "refs/*");
- Util.allow(u.getConfig(), Permission.SUBMIT, REGISTERED_USERS, "refs/heads/*");
- Util.allow(
- u.getConfig(),
- Permission.forLabel(Util.codeReview().getName()),
- -2,
- 2,
- REGISTERED_USERS,
- "refs/heads/*");
- u.save();
- }
+ public void submitWithRebaseWithoutAddPatchSetPermission() throws Throwable {
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.ADD_PATCH_SET).ref("refs/*").group(REGISTERED_USERS))
+ .add(allow(Permission.SUBMIT).ref("refs/heads/*").group(REGISTERED_USERS))
+ .add(
+ allowLabel(TestLabels.codeReview().getName())
+ .ref("refs/heads/*")
+ .group(REGISTERED_USERS)
+ .range(-2, 2))
+ .update();
submitWithRebase(user);
}
protected ImmutableList<PushOneCommit.Result> submitWithRebase(TestAccount submitter)
- throws Exception {
+ throws Throwable {
requestScopeOperations.setApiUser(submitter.id());
- RevCommit initialHead = getRemoteHead();
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
- RevCommit headAfterFirstSubmit = getRemoteHead();
+ RevCommit headAfterFirstSubmit = projectOperations.project(project).getHead("master");
testRepo.reset(initialHead);
PushOneCommit.Result change2 = createChange("Change 2", "b.txt", "other content");
submit(change2.getChangeId());
assertRebase(testRepo, false);
- RevCommit headAfterSecondSubmit = getRemoteHead();
+ RevCommit headAfterSecondSubmit = projectOperations.project(project).getHead("master");
assertThat(headAfterSecondSubmit.getParent(0)).isEqualTo(headAfterFirstSubmit);
assertApproved(change2.getChangeId(), submitter);
assertCurrentRevision(change2.getChangeId(), 2, headAfterSecondSubmit);
@@ -102,11 +106,11 @@
}
@Test
- public void submitWithRebaseMultipleChanges() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitWithRebaseMultipleChanges() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change1 = createChange("Change 1", "a.txt", "content");
submit(change1.getChangeId());
- RevCommit headAfterFirstSubmit = getRemoteHead();
+ RevCommit headAfterFirstSubmit = projectOperations.project(project).getHead("master");
if (getSubmitType() == SubmitType.REBASE_ALWAYS) {
assertCurrentRevision(change1.getChangeId(), 2, headAfterFirstSubmit);
} else {
@@ -127,7 +131,7 @@
assertApproved(change3.getChangeId());
assertApproved(change4.getChangeId());
- RevCommit headAfterSecondSubmit = parse(getRemoteHead());
+ RevCommit headAfterSecondSubmit = parse(projectOperations.project(project).getHead("master"));
assertThat(headAfterSecondSubmit.getShortMessage()).isEqualTo("Change 4");
assertThat(headAfterSecondSubmit).isNotEqualTo(change4.getCommit());
assertCurrentRevision(change4.getChangeId(), 2, headAfterSecondSubmit);
@@ -163,7 +167,7 @@
}
@Test
- public void submitWithRebaseMergeCommit() throws Exception {
+ public void submitWithRebaseMergeCommit() throws Throwable {
/*
* (HEAD, origin/master, origin/HEAD) Merge changes X,Y
|\
@@ -175,7 +179,7 @@
|/
* Initial empty repository
*/
- RevCommit initialHead = getRemoteHead();
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change1 = createChange("Added a", "a.txt", "");
PushOneCommit change2Push =
@@ -193,7 +197,7 @@
approve(change2.getChangeId());
submit(change2.getChangeId());
- RevCommit newHead = getRemoteHead();
+ RevCommit newHead = projectOperations.project(project).getHead("master");
assertThat(newHead.getParentCount()).isEqualTo(2);
RevCommit headParent1 = parse(newHead.getParent(0).getId());
@@ -219,12 +223,12 @@
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
- public void submitWithContentMerge_Conflict() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitWithContentMerge_Conflict() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
- RevCommit headAfterFirstSubmit = getRemoteHead();
+ RevCommit headAfterFirstSubmit = projectOperations.project(project).getHead("master");
testRepo.reset(initialHead);
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "other content");
submitWithConflict(
@@ -232,7 +236,7 @@
"Cannot rebase "
+ change2.getCommit().name()
+ ": The change could not be rebased due to a conflict during merge.");
- RevCommit head = getRemoteHead();
+ RevCommit head = projectOperations.project(project).getHead("master");
assertThat(head).isEqualTo(headAfterFirstSubmit);
assertCurrentRevision(change2.getChangeId(), 1, change2.getCommit());
assertNoSubmitter(change2.getChangeId(), 1);
@@ -241,7 +245,7 @@
assertChangeMergedEvents(change.getChangeId(), headAfterFirstSubmit.name());
}
- protected RevCommit parse(ObjectId id) throws Exception {
+ protected RevCommit parse(ObjectId id) throws Throwable {
try (Repository repo = repoManager.openRepository(project);
RevWalk rw = new RevWalk(repo)) {
RevCommit c = rw.parseCommit(id);
@@ -251,8 +255,8 @@
}
@Test
- public void submitAfterReorderOfCommits() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitAfterReorderOfCommits() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
// Create two commits and push.
RevCommit c1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
@@ -271,15 +275,15 @@
approve(id1);
approve(id2);
submit(id1);
- RevCommit headAfterSubmit = getRemoteHead();
+ RevCommit headAfterSubmit = projectOperations.project(project).getHead("master");
assertRefUpdatedEvents(initialHead, headAfterSubmit);
assertChangeMergedEvents(id2, headAfterSubmit.name(), id1, headAfterSubmit.name());
}
@Test
- public void submitChangesAfterBranchOnSecond() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitChangesAfterBranchOnSecond() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange();
approve(change.getChangeId());
@@ -293,7 +297,7 @@
assertMerged(change2.getChangeId());
assertMerged(change.getChangeId());
- RevCommit newHead = getRemoteHead();
+ RevCommit newHead = projectOperations.project(this.project).getHead("master");
assertRefUpdatedEvents(initialHead, newHead);
assertChangeMergedEvents(
change.getChangeId(), newHead.name(), change2.getChangeId(), newHead.name());
@@ -301,8 +305,8 @@
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
- public void submitFastForwardIdenticalTree() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitFastForwardIdenticalTree() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change1 = createChange("Change 1", "a.txt", "a");
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "a");
@@ -313,18 +317,18 @@
testRepo.reset(initialHead);
PushOneCommit.Result change0 = createChange("Change 0", "b.txt", "b");
submit(change0.getChangeId());
- RevCommit headAfterChange0 = getRemoteHead();
+ RevCommit headAfterChange0 = projectOperations.project(project).getHead("master");
assertThat(headAfterChange0.getShortMessage()).isEqualTo("Change 0");
submit(change1.getChangeId());
- RevCommit headAfterChange1 = getRemoteHead();
+ RevCommit headAfterChange1 = projectOperations.project(project).getHead("master");
assertThat(headAfterChange1.getShortMessage()).isEqualTo("Change 1");
assertThat(headAfterChange0).isEqualTo(headAfterChange1.getParent(0));
// Do manual rebase first.
gApi.changes().id(change2.getChangeId()).current().rebase();
submit(change2.getChangeId());
- RevCommit headAfterChange2 = getRemoteHead();
+ RevCommit headAfterChange2 = projectOperations.project(project).getHead("master");
assertThat(headAfterChange2.getShortMessage()).isEqualTo("Change 2");
assertThat(headAfterChange1).isEqualTo(headAfterChange2.getParent(0));
@@ -334,7 +338,7 @@
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
- public void submitChainOneByOne() throws Exception {
+ public void submitChainOneByOne() throws Throwable {
PushOneCommit.Result change1 = createChange("subject 1", "fileName 1", "content 1");
PushOneCommit.Result change2 = createChange("subject 2", "fileName 2", "content 2");
submit(change1.getChangeId());
@@ -343,7 +347,7 @@
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
- public void submitChainFailsOnRework() throws Exception {
+ public void submitChainFailsOnRework() throws Throwable {
PushOneCommit.Result change1 = createChange("subject 1", "fileName 1", "content 1");
RevCommit headAfterChange1 = change1.getCommit();
PushOneCommit.Result change2 = createChange("subject 2", "fileName 2", "content 2");
@@ -351,7 +355,7 @@
change1 =
amendChange(change1.getChangeId(), "subject 1 amend", "fileName 2", "rework content 2");
submit(change1.getChangeId());
- headAfterChange1 = getRemoteHead();
+ headAfterChange1 = projectOperations.project(project).getHead("master");
submitWithConflict(
change2.getChangeId(),
@@ -359,13 +363,13 @@
+ change2.getCommit().getName()
+ ": "
+ "The change could not be rebased due to a conflict during merge.");
- assertThat(getRemoteHead()).isEqualTo(headAfterChange1);
+ assertThat(projectOperations.project(project).getHead("master")).isEqualTo(headAfterChange1);
}
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
- public void submitChainOneByOneManualRebase() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitChainOneByOneManualRebase() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change1 = createChange("subject 1", "fileName 1", "content 1");
PushOneCommit.Result change2 = createChange("subject 2", "fileName 2", "content 2");
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/AssigneeIT.java b/javatests/com/google/gerrit/acceptance/rest/change/AssigneeIT.java
index 2d6227b..fec0d4b 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/AssigneeIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/AssigneeIT.java
@@ -15,15 +15,17 @@
package com.google.gerrit.acceptance.rest.change;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.extensions.client.ListChangesOption.DETAILED_LABELS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.concurrent.TimeUnit.SECONDS;
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.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.changes.AssigneeInput;
@@ -44,6 +46,7 @@
@NoHttpd
public class AssigneeIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@BeforeClass
@@ -130,20 +133,17 @@
public void setAssigneeToInactiveUser() throws Exception {
PushOneCommit.Result r = createChange();
gApi.accounts().id(user.id().get()).setActive(false);
- try {
- setAssignee(r, user.email());
- assert_().fail("expected UnresolvableAccountException");
- } catch (UnresolvableAccountException e) {
- assertThat(e)
- .hasMessageThat()
- .isEqualTo(
- "Account '"
- + user.email()
- + "' only matches inactive accounts. To use an inactive account, retry with one"
- + " of the following exact account IDs:\n"
- + user.id()
- + ": User <user@example.com>");
- }
+ UnresolvableAccountException thrown =
+ assertThrows(UnresolvableAccountException.class, () -> setAssignee(r, user.email()));
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo(
+ "Account '"
+ + user.email()
+ + "' only matches inactive accounts. To use an inactive account, retry with one"
+ + " of the following exact account IDs:\n"
+ + user.id()
+ + ": User <user@example.com>");
}
@Test
@@ -159,24 +159,26 @@
git().fetch().setRefSpecs(new RefSpec("refs/meta/config:refs/meta/config")).call();
testRepo.reset(RefNames.REFS_CONFIG);
PushOneCommit.Result r = createChange("refs/for/refs/meta/config");
- exception.expect(AuthException.class);
- exception.expectMessage("read not permitted");
- setAssignee(r, user.email());
+ AuthException thrown = assertThrows(AuthException.class, () -> setAssignee(r, user.email()));
+ assertThat(thrown).hasMessageThat().contains("read not permitted");
}
@Test
public void setAssigneeNotAllowedWithoutPermission() throws Exception {
PushOneCommit.Result r = createChange();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("not permitted");
- setAssignee(r, user.email());
+ AuthException thrown = assertThrows(AuthException.class, () -> setAssignee(r, user.email()));
+ assertThat(thrown).hasMessageThat().contains("not permitted");
}
@Test
public void setAssigneeAllowedWithPermission() throws Exception {
PushOneCommit.Result r = createChange();
- grant(project, "refs/heads/master", Permission.EDIT_ASSIGNEE, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.EDIT_ASSIGNEE).ref("refs/heads/master").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
assertThat(setAssignee(r, user.email())._accountId).isEqualTo(user.id().get());
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/ChangeIncludedInIT.java b/javatests/com/google/gerrit/acceptance/rest/change/ChangeIncludedInIT.java
index f05d4dc..def1a39 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/ChangeIncludedInIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/ChangeIncludedInIT.java
@@ -15,20 +15,25 @@
package com.google.gerrit.acceptance.rest.change;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static org.eclipse.jgit.lib.Constants.R_TAGS;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit.Result;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.api.projects.TagInput;
import com.google.gerrit.reviewdb.client.BranchNameKey;
+import com.google.inject.Inject;
import org.junit.Test;
@NoHttpd
public class ChangeIncludedInIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
+
@Test
public void includedInOpenChange() throws Exception {
Result result = createChange();
@@ -49,7 +54,11 @@
.containsExactly("master");
assertThat(gApi.changes().id(result.getChangeId()).includedIn().tags).isEmpty();
- grant(project, R_TAGS + "*", Permission.CREATE_TAG);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.CREATE_TAG).ref(R_TAGS + "*").group(adminGroupUuid()))
+ .update();
gApi.projects().name(project.get()).tag("test-tag").create(new TagInput());
assertThat(gApi.changes().id(result.getChangeId()).includedIn().tags)
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/ChangeMessagesIT.java b/javatests/com/google/gerrit/acceptance/rest/change/ChangeMessagesIT.java
index 1e7fd38..8ddfa45 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/ChangeMessagesIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/ChangeMessagesIT.java
@@ -16,10 +16,12 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.gerrit.acceptance.PushOneCommit.FILE_NAME;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
import static com.google.gerrit.extensions.client.ListChangesOption.MESSAGES;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static com.google.gerrit.server.notedb.ChangeNoteUtil.parseCommitMessageRange;
import static com.google.gerrit.server.restapi.change.DeleteChangeMessage.createNewChangeMessage;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.stream.Collectors.toSet;
import static org.eclipse.jgit.util.RawParseUtils.decode;
@@ -29,6 +31,7 @@
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestAccount;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.api.changes.DeleteChangeMessageInput;
@@ -57,6 +60,7 @@
@RunWith(ConfigSuite.class)
public class ChangeMessagesIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
private String systemTimeZone;
@@ -160,17 +164,17 @@
int changeNum = createOneChangeWithMultipleChangeMessagesInHistory();
requestScopeOperations.setApiUser(user.id());
- try {
- deleteOneChangeMessage(changeNum, 0, user, "spam");
- fail("expected AuthException");
- } catch (AuthException e) {
- assertThat(e.getMessage()).isEqualTo("administrate server not permitted");
- }
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> deleteOneChangeMessage(changeNum, 0, user, "spam"));
+ assertThat(thrown).hasMessageThat().isEqualTo("administrate server not permitted");
}
@Test
public void deleteCanBeAppliedWithAdministrateServerCapability() throws Exception {
- allowGlobalCapabilities(REGISTERED_USERS, GlobalCapability.ADMINISTRATE_SERVER);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.ADMINISTRATE_SERVER).group(REGISTERED_USERS))
+ .update();
int changeNum = createOneChangeWithMultipleChangeMessagesInHistory();
requestScopeOperations.setApiUser(user.id());
deleteOneChangeMessage(changeNum, 0, user, "spam");
@@ -180,12 +184,15 @@
public void deleteCannotBeAppliedWithEmptyChangeMessageUuid() throws Exception {
String changeId = createChange().getChangeId();
- try {
- gApi.changes().id(changeId).message("").delete(new DeleteChangeMessageInput("spam"));
- fail("expected ResourceNotFoundException");
- } catch (ResourceNotFoundException e) {
- assertThat(e.getMessage()).isEqualTo("change message not found");
- }
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class,
+ () ->
+ gApi.changes()
+ .id(changeId)
+ .message("")
+ .delete(new DeleteChangeMessageInput("spam")));
+ assertThat(thrown).hasMessageThat().isEqualTo("change message not found");
}
@Test
@@ -195,12 +202,11 @@
String id = "8473b95934b5732ac55d26311a706c9c2bde9941";
input.reason = "spam";
- try {
- gApi.changes().id(changeId).message(id).delete(input);
- fail("expected ResourceNotFoundException");
- } catch (ResourceNotFoundException e) {
- assertThat(e.getMessage()).isEqualTo(String.format("change message %s not found", id));
- }
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.changes().id(changeId).message(id).delete(input));
+ assertThat(thrown).hasMessageThat().isEqualTo(String.format("change message %s not found", id));
}
@Test
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/ChangeOwnerIT.java b/javatests/com/google/gerrit/acceptance/rest/change/ChangeOwnerIT.java
index d51221e..30d99ac 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/ChangeOwnerIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/ChangeOwnerIT.java
@@ -14,6 +14,11 @@
package com.google.gerrit.acceptance.rest.change;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.blockLabel;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.labelPermissionKey;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.AcceptanceTestRequestScope.Context;
import com.google.gerrit.acceptance.PushOneCommit;
@@ -121,8 +126,7 @@
}
private void assertApproveFails(TestAccount a, String changeId) throws Exception {
- exception.expect(AuthException.class);
- approve(a, changeId);
+ assertThrows(AuthException.class, () -> approve(a, changeId));
}
private void grantApproveToChangeOwner(Project.NameKey project) throws Exception {
@@ -139,11 +143,24 @@
private void grantApprove(Project.NameKey project, AccountGroup.UUID groupUUID, boolean exclusive)
throws Exception {
- grantLabel("Code-Review", -2, 2, project, "refs/heads/*", false, groupUUID, exclusive);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(groupUUID).range(-2, 2))
+ .setExclusiveGroup(labelPermissionKey("Code-Review").ref("refs/heads/*"), exclusive)
+ .update();
}
private void blockApproveForChangeOwner(Project.NameKey project) throws Exception {
- blockLabel("Code-Review", -2, 2, SystemGroupBackend.CHANGE_OWNER, "refs/heads/*", project);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(
+ blockLabel("Code-Review")
+ .ref("refs/heads/*")
+ .group(SystemGroupBackend.CHANGE_OWNER)
+ .range(-2, 2))
+ .update();
}
private String createMyChange(TestRepository<InMemoryRepository> testRepo) throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/ChangeReviewersIT.java b/javatests/com/google/gerrit/acceptance/rest/change/ChangeReviewersIT.java
index 173b78d..e300c91 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/ChangeReviewersIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/ChangeReviewersIT.java
@@ -15,11 +15,13 @@
package com.google.gerrit.acceptance.rest.change;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.extensions.client.ListChangesOption.DETAILED_LABELS;
import static com.google.gerrit.extensions.client.ReviewerState.CC;
import static com.google.gerrit.extensions.client.ReviewerState.REMOVED;
import static com.google.gerrit.extensions.client.ReviewerState.REVIEWER;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static javax.servlet.http.HttpServletResponse.SC_OK;
@@ -31,6 +33,7 @@
import com.google.gerrit.acceptance.Sandboxed;
import com.google.gerrit.acceptance.TestAccount;
import com.google.gerrit.acceptance.testsuite.group.GroupOperations;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.changes.AddReviewerInput;
@@ -66,6 +69,7 @@
public class ChangeReviewersIT extends AbstractDaemonTest {
@Inject private GroupOperations groupOperations;
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Test
@@ -662,9 +666,11 @@
requestScopeOperations.setApiUser(user.id());
gApi.changes().id(r.getChangeId()).current().review(new ReviewInput().label("Code-Review", 1));
requestScopeOperations.setApiUser(newUser.id());
- exception.expect(AuthException.class);
- exception.expectMessage("remove reviewer not permitted");
- gApi.changes().id(r.getChangeId()).reviewer(user.email()).remove();
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () -> gApi.changes().id(r.getChangeId()).reviewer(user.email()).remove());
+ assertThat(thrown).hasMessageThat().contains("remove reviewer not permitted");
}
@Test
@@ -674,7 +680,11 @@
// This test creates a new user so that it can explicitly check the REMOVE_REVIEWER permission
// rather than bypassing the check because of project or ref ownership.
TestAccount newUser = createAccounts(1, name("foo")).get(0);
- grant(project, RefNames.REFS + "*", Permission.REMOVE_REVIEWER, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.REMOVE_REVIEWER).ref(RefNames.REFS + "*").group(REGISTERED_USERS))
+ .update();
gApi.changes().id(r.getChangeId()).addReviewer(user.email());
assertThatUserIsOnlyReviewer(r.getChangeId());
@@ -690,9 +700,11 @@
gApi.changes().id(r.getChangeId()).addReviewer(user.email());
requestScopeOperations.setApiUser(newUser.id());
- exception.expect(AuthException.class);
- exception.expectMessage("remove reviewer not permitted");
- gApi.changes().id(r.getChangeId()).reviewer(user.email()).remove();
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () -> gApi.changes().id(r.getChangeId()).reviewer(user.email()).remove());
+ assertThat(thrown).hasMessageThat().contains("remove reviewer not permitted");
}
@Test
@@ -705,9 +717,11 @@
input.state = ReviewerState.CC;
gApi.changes().id(r.getChangeId()).addReviewer(input);
requestScopeOperations.setApiUser(newUser.id());
- exception.expect(AuthException.class);
- exception.expectMessage("remove reviewer not permitted");
- gApi.changes().id(r.getChangeId()).reviewer(user.email()).remove();
+ AuthException thrown =
+ assertThrows(
+ AuthException.class,
+ () -> gApi.changes().id(r.getChangeId()).reviewer(user.email()).remove());
+ assertThat(thrown).hasMessageThat().contains("remove reviewer not permitted");
}
@Test
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/ConfigChangeIT.java b/javatests/com/google/gerrit/acceptance/rest/change/ConfigChangeIT.java
index 9a907aa..57c0c8c 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/ConfigChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/ConfigChangeIT.java
@@ -15,13 +15,16 @@
package com.google.gerrit.acceptance.rest.change;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
-import static java.nio.charset.StandardCharsets.UTF_8;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+import static com.google.gerrit.truth.ConfigSubject.assertThat;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GitUtil;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestProjectInput;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.changes.ReviewInput;
@@ -31,31 +34,27 @@
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
-import com.google.gerrit.server.project.testing.Util;
import com.google.inject.Inject;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
-import org.eclipse.jgit.lib.ObjectLoader;
-import org.eclipse.jgit.revwalk.RevObject;
-import org.eclipse.jgit.revwalk.RevTree;
-import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.RefSpec;
import org.junit.Before;
import org.junit.Test;
public class ConfigChangeIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Before
public void setUp() throws Exception {
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.allow(u.getConfig(), Permission.OWNER, REGISTERED_USERS, "refs/*");
- Util.allow(u.getConfig(), Permission.PUSH, REGISTERED_USERS, "refs/for/refs/meta/config");
- Util.allow(u.getConfig(), Permission.SUBMIT, REGISTERED_USERS, RefNames.REFS_CONFIG);
- u.save();
- }
-
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.OWNER).ref("refs/*").group(REGISTERED_USERS))
+ .add(allow(Permission.PUSH).ref("refs/for/refs/meta/config").group(REGISTERED_USERS))
+ .add(allow(Permission.SUBMIT).ref(RefNames.REFS_CONFIG).group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
fetchRefsMetaConfig();
}
@@ -75,8 +74,8 @@
}
private String testUpdateProjectConfig() throws Exception {
- Config cfg = readProjectConfig();
- assertThat(cfg.getString("project", null, "description")).isNull();
+ Config cfg = projectOperations.project(project).getConfig();
+ assertThat(cfg).stringValue("project", null, "description").isNull();
String desc = "new project description";
cfg.setString("project", null, "description", desc);
@@ -89,7 +88,12 @@
assertThat(gApi.changes().id(id).info().status).isEqualTo(ChangeStatus.MERGED);
assertThat(gApi.projects().name(project.get()).get().description).isEqualTo(desc);
fetchRefsMetaConfig();
- assertThat(readProjectConfig().getString("project", null, "description")).isEqualTo(desc);
+ assertThat(
+ projectOperations
+ .project(project)
+ .getConfig()
+ .getString("project", null, "description"))
+ .isEqualTo(desc);
String changeRev = gApi.changes().id(id).get().currentRevision;
String branchRev =
gApi.projects().name(project.get()).branch(RefNames.REFS_CONFIG).get().revision;
@@ -107,33 +111,31 @@
gApi.projects().create(parent);
requestScopeOperations.setApiUser(user.id());
- Config cfg = readProjectConfig();
- assertThat(cfg.getString("access", null, "inheritFrom")).isAnyOf(null, allProjects.get());
+ Config cfg = projectOperations.project(project).getConfig();
+ assertThat(cfg).stringValue("access", null, "inheritFrom").isAnyOf(null, allProjects.get());
cfg.setString("access", null, "inheritFrom", parent.name);
PushOneCommit.Result r = createConfigChange(cfg);
String id = r.getChangeId();
gApi.changes().id(id).current().review(ReviewInput.approve());
- try {
- gApi.changes().id(id).current().submit();
- fail("expected submit to fail");
- } catch (ResourceConflictException e) {
- int n = gApi.changes().id(id).info()._number;
- assertThat(e)
- .hasMessageThat()
- .isEqualTo(
- "Failed to submit 1 change due to the following problems:\n"
- + "Change "
- + n
- + ": Change contains a project configuration that"
- + " changes the parent project.\n"
- + "The change must be submitted by a Gerrit administrator.");
- }
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class, () -> gApi.changes().id(id).current().submit());
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo(
+ "Failed to submit 1 change due to the following problems:\n"
+ + "Change "
+ + gApi.changes().id(id).info()._number
+ + ": Change contains a project configuration that"
+ + " changes the parent project.\n"
+ + "The change must be submitted by a Gerrit administrator.");
assertThat(gApi.projects().name(project.get()).get().parent).isEqualTo(allProjects.get());
fetchRefsMetaConfig();
- assertThat(readProjectConfig().getString("access", null, "inheritFrom"))
+ assertThat(
+ projectOperations.project(project).getConfig().getString("access", null, "inheritFrom"))
.isAnyOf(null, allProjects.get());
requestScopeOperations.setApiUser(admin.id());
@@ -141,7 +143,9 @@
assertThat(gApi.changes().id(id).info().status).isEqualTo(ChangeStatus.MERGED);
assertThat(gApi.projects().name(project.get()).get().parent).isEqualTo(parent.name);
fetchRefsMetaConfig();
- assertThat(readProjectConfig().getString("access", null, "inheritFrom")).isEqualTo(parent.name);
+ assertThat(
+ projectOperations.project(project).getConfig().getString("access", null, "inheritFrom"))
+ .isEqualTo(parent.name);
}
@Test
@@ -179,17 +183,6 @@
testRepo.reset(RefNames.REFS_CONFIG);
}
- private Config readProjectConfig() throws Exception {
- RevWalk rw = testRepo.getRevWalk();
- RevTree tree = rw.parseTree(testRepo.getRepository().resolve("HEAD"));
- RevObject obj = rw.parseAny(testRepo.get(tree, "project.config"));
- ObjectLoader loader = rw.getObjectReader().open(obj);
- String text = new String(loader.getCachedBytes(), UTF_8);
- Config cfg = new Config();
- cfg.fromText(text);
- return cfg;
- }
-
private PushOneCommit.Result createConfigChange(Config cfg) throws Exception {
PushOneCommit.Result r =
pushFactory
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/CreateChangeIT.java b/javatests/com/google/gerrit/acceptance/rest/change/CreateChangeIT.java
index d94b02f..43cf655 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/CreateChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/CreateChangeIT.java
@@ -15,9 +15,11 @@
package com.google.gerrit.acceptance.rest.change;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.common.data.Permission.READ;
import static com.google.gerrit.reviewdb.client.RefNames.changeMetaRef;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.eclipse.jgit.lib.Constants.SIGNED_OFF_BY_TAG;
@@ -27,6 +29,7 @@
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.PushOneCommit.Result;
import com.google.gerrit.acceptance.RestResponse;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.extensions.api.changes.ChangeApi;
import com.google.gerrit.extensions.api.changes.CherryPickInput;
@@ -67,6 +70,7 @@
import org.junit.Test;
public class CreateChangeIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@BeforeClass
@@ -259,7 +263,11 @@
public void createChangeWithoutAccessToParentCommitFails() throws Exception {
Map<String, PushOneCommit.Result> results =
changeInTwoBranches("invisible-branch", "a.txt", "visible-branch", "b.txt");
- block(project, "refs/heads/invisible-branch", READ, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(READ).ref("refs/heads/invisible-branch").group(REGISTERED_USERS))
+ .update();
ChangeInput in = newChangeInput(ChangeStatus.NEW);
in.branch = "visible-branch";
@@ -386,7 +394,7 @@
cherry.current().review(ReviewInput.approve());
cherry.current().submit();
- ObjectId remoteId = getRemoteHead();
+ ObjectId remoteId = projectOperations.project(project).getHead("master");
assertThat(remoteId).isNotEqualTo(commitId);
ChangeInput in = newMergeChangeInput("master", commitId.getName(), "");
@@ -450,7 +458,11 @@
@Test
public void createChangeOnExistingBranchNotPermitted() throws Exception {
createBranch(BranchNameKey.create(project, "foo"));
- blockRead("refs/heads/*");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(READ).ref("refs/heads/*").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
ChangeInput input = newChangeInput(ChangeStatus.NEW);
input.branch = "foo";
@@ -460,7 +472,11 @@
@Test
public void createChangeOnNonExistingBranchNotPermitted() throws Exception {
- blockRead("refs/heads/*");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(READ).ref("refs/heads/*").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
ChangeInput input = newChangeInput(ChangeStatus.NEW);
input.branch = "foo";
@@ -507,9 +523,8 @@
private void assertCreateFails(
ChangeInput in, Class<? extends RestApiException> errType, String errSubstring)
throws Exception {
- exception.expect(errType);
- exception.expectMessage(errSubstring);
- gApi.changes().create(in);
+ Throwable thrown = assertThrows(errType, () -> gApi.changes().create(in));
+ assertThat(thrown).hasMessageThat().contains(errSubstring);
}
// TODO(davido): Expose setting of account preferences in the API
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/HashtagsIT.java b/javatests/com/google/gerrit/acceptance/rest/change/HashtagsIT.java
index 186bf82..542c6a9 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/HashtagsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/HashtagsIT.java
@@ -16,7 +16,9 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.TimeUnit.SECONDS;
@@ -26,6 +28,7 @@
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.changes.HashtagsInput;
@@ -40,6 +43,8 @@
@NoHttpd
public class HashtagsIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
+
@BeforeClass
public static void setTimeForTesting() {
TestTimeUtil.resetWithClockStep(1, SECONDS);
@@ -79,9 +84,9 @@
public void addInvalidHashtag() throws Exception {
PushOneCommit.Result r = createChange();
- exception.expect(BadRequestException.class);
- exception.expectMessage("hashtags may not contain commas");
- addHashtags(r, "invalid,hashtag");
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> addHashtags(r, "invalid,hashtag"));
+ assertThat(thrown).hasMessageThat().contains("hashtags may not contain commas");
}
@Test
@@ -259,15 +264,18 @@
public void addHashtagWithoutPermissionNotAllowed() throws Exception {
PushOneCommit.Result r = createChange();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("edit hashtags not permitted");
- addHashtags(r, "MyHashtag");
+ AuthException thrown = assertThrows(AuthException.class, () -> addHashtags(r, "MyHashtag"));
+ assertThat(thrown).hasMessageThat().contains("edit hashtags not permitted");
}
@Test
public void addHashtagWithPermissionAllowed() throws Exception {
PushOneCommit.Result r = createChange();
- grant(project, "refs/heads/master", Permission.EDIT_HASHTAGS, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.EDIT_HASHTAGS).ref("refs/heads/master").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
addHashtags(r, "MyHashtag");
assertThatGet(r).containsExactly("MyHashtag");
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/IndexChangeIT.java b/javatests/com/google/gerrit/acceptance/rest/change/IndexChangeIT.java
index 0087268..e8fd295 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/IndexChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/IndexChangeIT.java
@@ -15,6 +15,8 @@
package com.google.gerrit.acceptance.rest.change;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import com.google.gerrit.acceptance.AbstractDaemonTest;
@@ -27,7 +29,6 @@
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.server.project.testing.Util;
import com.google.inject.Inject;
import java.util.List;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
@@ -48,7 +49,11 @@
@Test
public void indexChangeOnNonVisibleBranch() throws Exception {
String changeId = createChange().getChangeId();
- blockRead("refs/heads/master");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.READ).ref("refs/heads/master").group(REGISTERED_USERS))
+ .update();
userRestSession.post("/changes/" + changeId + "/index/").assertNotFound();
}
@@ -62,15 +67,15 @@
// Create a project and restrict its visibility to the group
Project.NameKey p = projectOperations.newProject().create();
- try (ProjectConfigUpdate u = updateProject(p)) {
- Util.allow(
- u.getConfig(),
- Permission.READ,
- groupCache.get(AccountGroup.nameKey(group)).get().getGroupUUID(),
- "refs/*");
- Util.block(u.getConfig(), Permission.READ, REGISTERED_USERS, "refs/*");
- u.save();
- }
+ projectOperations
+ .project(p)
+ .forUpdate()
+ .add(
+ allow(Permission.READ)
+ .ref("refs/*")
+ .group(groupCache.get(AccountGroup.nameKey(group)).get().getGroupUUID()))
+ .add(block(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
// Clone it and push a change as a regular user
TestRepository<InMemoryRepository> repo = cloneProject(p, user);
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/MoveChangeIT.java b/javatests/com/google/gerrit/acceptance/rest/change/MoveChangeIT.java
index f2a3952..55cff17 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/MoveChangeIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/MoveChangeIT.java
@@ -16,13 +16,17 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.GitUtil.pushHead;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GerritConfig;
import com.google.gerrit.acceptance.GitUtil;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.LabelFunction;
import com.google.gerrit.common.data.LabelType;
@@ -35,10 +39,8 @@
import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.BranchNameKey;
-import com.google.gerrit.server.group.SystemGroupBackend;
-import com.google.gerrit.server.project.testing.Util;
+import com.google.gerrit.server.project.testing.TestLabels;
import com.google.inject.Inject;
import java.util.Arrays;
import org.eclipse.jgit.junit.TestRepository;
@@ -48,6 +50,7 @@
@NoHttpd
public class MoveChangeIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Test
@@ -90,9 +93,13 @@
public void moveChangeToSameRefAsCurrent() throws Exception {
// Move change to the branch same as change's destination
PushOneCommit.Result r = createChange();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Change is already destined for the specified branch");
- move(r.getChangeId(), r.getChange().change().getDest().branch());
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> move(r.getChangeId(), r.getChange().change().getDest().branch()));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Change is already destined for the specified branch");
}
@Test
@@ -103,13 +110,15 @@
createBranch(newBranch);
int changeNum = r.getChange().change().getChangeId();
createChange(newBranch.branch(), r.getChangeId());
- exception.expect(ResourceConflictException.class);
- exception.expectMessage(
- "Destination "
- + newBranch.shortName()
- + " has a different change with same change key "
- + r.getChangeId());
- move(changeNum, newBranch.branch());
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> move(changeNum, newBranch.branch()));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ "Destination "
+ + newBranch.shortName()
+ + " has a different change with same change key "
+ + r.getChangeId());
}
@Test
@@ -118,9 +127,12 @@
PushOneCommit.Result r = createChange();
BranchNameKey newBranch =
BranchNameKey.create(r.getChange().change().getProject(), "does_not_exist");
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Destination " + newBranch.branch() + " not found in the project");
- move(r.getChangeId(), newBranch.branch());
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class, () -> move(r.getChangeId(), newBranch.branch()));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Destination " + newBranch.branch() + " not found in the project");
}
@Test
@@ -130,9 +142,10 @@
BranchNameKey newBranch = BranchNameKey.create(r.getChange().change().getProject(), "moveTest");
createBranch(newBranch);
merge(r);
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Change is merged");
- move(r.getChangeId(), newBranch.branch());
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class, () -> move(r.getChangeId(), newBranch.branch()));
+ assertThat(thrown).hasMessageThat().contains("Change is merged");
}
@Test
@@ -156,9 +169,11 @@
BranchNameKey newBranch =
BranchNameKey.create(r1.getChange().change().getProject(), "moveTest");
createBranch(newBranch);
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Merge commit cannot be moved");
- move(GitUtil.getChangeId(testRepo, c).get(), newBranch.branch());
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> move(GitUtil.getChangeId(testRepo, c).get(), newBranch.branch()));
+ assertThat(thrown).hasMessageThat().contains("Merge commit cannot be moved");
}
@Test
@@ -168,13 +183,14 @@
BranchNameKey newBranch =
BranchNameKey.create(r.getChange().change().getProject(), "blocked_branch");
createBranch(newBranch);
- block(
- "refs/for/" + newBranch.branch(),
- Permission.PUSH,
- systemGroupBackend.getGroup(REGISTERED_USERS).getUUID());
- exception.expect(AuthException.class);
- exception.expectMessage("move not permitted");
- move(r.getChangeId(), newBranch.branch());
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.PUSH).ref("refs/for/" + newBranch.branch()).group(REGISTERED_USERS))
+ .update();
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> move(r.getChangeId(), newBranch.branch()));
+ assertThat(thrown).hasMessageThat().contains("move not permitted");
}
@Test
@@ -183,14 +199,18 @@
PushOneCommit.Result r = createChange();
BranchNameKey newBranch = BranchNameKey.create(r.getChange().change().getProject(), "moveTest");
createBranch(newBranch);
- block(
- r.getChange().change().getDest().branch(),
- Permission.ABANDON,
- systemGroupBackend.getGroup(REGISTERED_USERS).getUUID());
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(
+ block(Permission.ABANDON)
+ .ref(r.getChange().change().getDest().branch())
+ .group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("move not permitted");
- move(r.getChangeId(), newBranch.branch());
+ AuthException thrown =
+ assertThrows(AuthException.class, () -> move(r.getChangeId(), newBranch.branch()));
+ assertThat(thrown).hasMessageThat().contains("move not permitted");
}
@Test
@@ -209,10 +229,11 @@
gApi.projects().name(newBranch.project().get()).branch(newBranch.branch()).create(bi);
// Try to move the change to the branch with the same commit
- exception.expect(ResourceConflictException.class);
- exception.expectMessage(
- "Current patchset revision is reachable from tip of " + newBranch.branch());
- move(changeNum, newBranch.branch());
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> move(changeNum, newBranch.branch()));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Current patchset revision is reachable from tip of " + newBranch.branch());
}
@Test
@@ -222,26 +243,29 @@
BranchNameKey newBranch = BranchNameKey.create(r.getChange().change().getProject(), "moveTest");
createBranch(newBranch);
+ LabelType patchSetLock = TestLabels.patchSetLock();
try (ProjectConfigUpdate u = updateProject(project)) {
- LabelType patchSetLock = Util.patchSetLock();
u.getConfig().getLabelSections().put(patchSetLock.getName(), patchSetLock);
- AccountGroup.UUID registeredUsers = systemGroupBackend.getGroup(REGISTERED_USERS).getUUID();
- Util.allow(
- u.getConfig(),
- Permission.forLabel(patchSetLock.getName()),
- 0,
- 1,
- registeredUsers,
- "refs/heads/*");
u.save();
}
- grant(project, "refs/heads/*", Permission.LABEL + "Patch-Set-Lock");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(
+ allowLabel(patchSetLock.getName())
+ .ref("refs/heads/*")
+ .group(REGISTERED_USERS)
+ .range(0, 1))
+ .update();
revision(r).review(new ReviewInput().label("Patch-Set-Lock", 1));
- exception.expect(ResourceConflictException.class);
- exception.expectMessage(
- String.format("The current patch set of change %s is locked", r.getChange().getId()));
- move(r.getChangeId(), newBranch.branch());
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class, () -> move(r.getChangeId(), newBranch.branch()));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ String.format("The current patch set of change %s is locked", r.getChange().getId()));
}
@Test
@@ -258,16 +282,13 @@
configLabel(testLabelB, LabelFunction.MAX_NO_BLOCK);
configLabel(testLabelC, LabelFunction.NO_BLOCK);
- AccountGroup.UUID registered = SystemGroupBackend.REGISTERED_USERS;
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.allow(
- u.getConfig(), Permission.forLabel(testLabelA), -1, +1, registered, "refs/heads/*");
- Util.allow(
- u.getConfig(), Permission.forLabel(testLabelB), -1, +1, registered, "refs/heads/*");
- Util.allow(
- u.getConfig(), Permission.forLabel(testLabelC), -1, +1, registered, "refs/heads/*");
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allowLabel(testLabelA).ref("refs/heads/*").group(REGISTERED_USERS).range(-1, +1))
+ .add(allowLabel(testLabelB).ref("refs/heads/*").group(REGISTERED_USERS).range(-1, +1))
+ .add(allowLabel(testLabelC).ref("refs/heads/*").group(REGISTERED_USERS).range(-1, +1))
+ .update();
String changeId = createChange().getChangeId();
gApi.changes().id(changeId).current().review(ReviewInput.reject());
@@ -307,12 +328,11 @@
String testLabelA = "Label-A";
configLabel(testLabelA, LabelFunction.MAX_WITH_BLOCK, Arrays.asList("refs/heads/master"));
- AccountGroup.UUID registered = SystemGroupBackend.REGISTERED_USERS;
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.allow(
- u.getConfig(), Permission.forLabel(testLabelA), -1, +1, registered, "refs/heads/master");
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allowLabel(testLabelA).ref("refs/heads/master").group(REGISTERED_USERS).range(-1, +1))
+ .update();
String changeId = createChange().getChangeId();
@@ -334,9 +354,9 @@
public void moveNoDestinationBranchSpecified() throws Exception {
PushOneCommit.Result r = createChange();
- exception.expect(BadRequestException.class);
- exception.expectMessage("destination branch is required");
- move(r.getChangeId(), null);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> move(r.getChangeId(), null));
+ assertThat(thrown).hasMessageThat().contains("destination branch is required");
}
@Test
@@ -344,9 +364,9 @@
public void moveCanBeDisabledByConfig() throws Exception {
PushOneCommit.Result r = createChange();
- exception.expect(MethodNotAllowedException.class);
- exception.expectMessage("move changes endpoint is disabled");
- move(r.getChangeId(), null);
+ MethodNotAllowedException thrown =
+ assertThrows(MethodNotAllowedException.class, () -> move(r.getChangeId(), null));
+ assertThat(thrown).hasMessageThat().contains("move changes endpoint is disabled");
}
private void move(int changeNum, String destination) throws RestApiException {
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/PrivateByDefaultIT.java b/javatests/com/google/gerrit/acceptance/rest/change/PrivateByDefaultIT.java
index ca4288f6..a6fa9fc5 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/PrivateByDefaultIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/PrivateByDefaultIT.java
@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance.rest.change;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GerritConfig;
@@ -81,9 +82,9 @@
setPrivateByDefault(project2, InheritableBoolean.TRUE);
ChangeInput input = new ChangeInput(project2.get(), "master", "empty change");
- exception.expect(MethodNotAllowedException.class);
- exception.expectMessage("private changes are disabled");
- gApi.changes().create(input);
+ MethodNotAllowedException thrown =
+ assertThrows(MethodNotAllowedException.class, () -> gApi.changes().create(input));
+ assertThat(thrown).hasMessageThat().contains("private changes are disabled");
}
@Test
@@ -130,7 +131,7 @@
public void pushDraftsWithPrivateByDefaultAndDisablePrivateChangesTrue() throws Exception {
setPrivateByDefault(project2, InheritableBoolean.TRUE);
- RevCommit initialHead = getRemoteHead(project2, "master");
+ RevCommit initialHead = projectOperations.project(project2).getHead("master");
TestRepository<InMemoryRepository> testRepo = cloneProject(project2);
PushOneCommit.Result result =
pushFactory.create(admin.newIdent(), testRepo).to("refs/for/master%draft");
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByCherryPickIT.java b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByCherryPickIT.java
index d321056..16b7690 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByCherryPickIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByCherryPickIT.java
@@ -21,6 +21,7 @@
import com.google.common.collect.Iterables;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestProjectInput;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.FooterConstants;
import com.google.gerrit.extensions.api.changes.SubmitInput;
import com.google.gerrit.extensions.client.ChangeStatus;
@@ -40,6 +41,7 @@
public class SubmitByCherryPickIT extends AbstractSubmit {
@Inject private DynamicSet<ChangeMessageModifier> changeMessageModifiers;
+ @Inject private ProjectOperations projectOperations;
@Override
protected SubmitType getSubmitType() {
@@ -47,12 +49,12 @@
}
@Test
- public void submitWithCherryPickIfFastForwardPossible() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitWithCherryPickIfFastForwardPossible() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange();
submit(change.getChangeId());
assertCherryPick(testRepo, false);
- RevCommit newHead = getRemoteHead();
+ RevCommit newHead = projectOperations.project(project).getHead("master");
assertThat(newHead.getParent(0)).isEqualTo(change.getCommit().getParent(0));
assertRefUpdatedEvents(initialHead, newHead);
@@ -60,17 +62,17 @@
}
@Test
- public void submitWithCherryPick() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitWithCherryPick() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
- RevCommit headAfterFirstSubmit = getRemoteHead();
+ RevCommit headAfterFirstSubmit = projectOperations.project(project).getHead("master");
testRepo.reset(initialHead);
PushOneCommit.Result change2 = createChange("Change 2", "b.txt", "other content");
submit(change2.getChangeId());
assertCherryPick(testRepo, false);
- RevCommit newHead = getRemoteHead();
+ RevCommit newHead = projectOperations.project(project).getHead("master");
assertThat(newHead.getParentCount()).isEqualTo(1);
assertThat(newHead.getParent(0)).isEqualTo(headAfterFirstSubmit);
assertCurrentRevision(change2.getChangeId(), 2, newHead);
@@ -85,7 +87,7 @@
}
@Test
- public void changeMessageOnSubmit() throws Exception {
+ public void changeMessageOnSubmit() throws Throwable {
PushOneCommit.Result change = createChange();
RegistrationHandle handle =
changeMessageModifiers.add(
@@ -107,20 +109,20 @@
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
- public void submitWithContentMerge() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitWithContentMerge() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "aaa\nbbb\nccc\n");
submit(change.getChangeId());
- RevCommit headAfterFirstSubmit = getRemoteHead();
+ RevCommit headAfterFirstSubmit = projectOperations.project(project).getHead("master");
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "aaa\nbbb\nccc\nddd\n");
submit(change2.getChangeId());
- RevCommit headAfterSecondSubmit = getRemoteHead();
+ RevCommit headAfterSecondSubmit = projectOperations.project(project).getHead("master");
testRepo.reset(change.getCommit());
PushOneCommit.Result change3 = createChange("Change 3", "a.txt", "bbb\nccc\n");
submit(change3.getChangeId());
assertCherryPick(testRepo, true);
- RevCommit headAfterThirdSubmit = getRemoteHead();
+ RevCommit headAfterThirdSubmit = projectOperations.project(project).getHead("master");
assertThat(headAfterThirdSubmit.getParent(0)).isEqualTo(headAfterSecondSubmit);
assertApproved(change3.getChangeId());
assertCurrentRevision(change3.getChangeId(), 2, headAfterThirdSubmit);
@@ -145,12 +147,12 @@
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
- public void submitWithContentMerge_Conflict() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitWithContentMerge_Conflict() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
- RevCommit newHead = getRemoteHead();
+ RevCommit newHead = projectOperations.project(project).getHead("master");
testRepo.reset(initialHead);
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "other content");
submitWithConflict(
@@ -162,7 +164,7 @@
+ "merged due to a path conflict. Please rebase the change locally and "
+ "upload the rebased commit for review.");
- assertThat(getRemoteHead()).isEqualTo(newHead);
+ assertThat(projectOperations.project(project).getHead("master")).isEqualTo(newHead);
assertCurrentRevision(change2.getChangeId(), 1, change2.getCommit());
assertNoSubmitter(change2.getChangeId(), 1);
@@ -171,18 +173,18 @@
}
@Test
- public void submitOutOfOrder() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitOutOfOrder() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
- RevCommit headAfterFirstSubmit = getRemoteHead();
+ RevCommit headAfterFirstSubmit = projectOperations.project(project).getHead("master");
testRepo.reset(initialHead);
createChange("Change 2", "b.txt", "other content");
PushOneCommit.Result change3 = createChange("Change 3", "c.txt", "different content");
submit(change3.getChangeId());
assertCherryPick(testRepo, false);
- RevCommit headAfterSecondSubmit = getRemoteHead();
+ RevCommit headAfterSecondSubmit = projectOperations.project(project).getHead("master");
assertThat(headAfterSecondSubmit.getParent(0)).isEqualTo(headAfterFirstSubmit);
assertApproved(change3.getChangeId());
assertCurrentRevision(change3.getChangeId(), 2, headAfterSecondSubmit);
@@ -199,12 +201,12 @@
}
@Test
- public void submitOutOfOrder_Conflict() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitOutOfOrder_Conflict() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
- RevCommit newHead = getRemoteHead();
+ RevCommit newHead = projectOperations.project(project).getHead("master");
testRepo.reset(initialHead);
createChange("Change 2", "b.txt", "other content");
PushOneCommit.Result change3 = createChange("Change 3", "b.txt", "different content");
@@ -217,7 +219,7 @@
+ "merged due to a path conflict. Please rebase the change locally and "
+ "upload the rebased commit for review.");
- assertThat(getRemoteHead()).isEqualTo(newHead);
+ assertThat(projectOperations.project(project).getHead("master")).isEqualTo(newHead);
assertCurrentRevision(change3.getChangeId(), 1, change3.getCommit());
assertNoSubmitter(change3.getChangeId(), 1);
@@ -226,8 +228,8 @@
}
@Test
- public void submitMultipleChanges() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitMultipleChanges() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
testRepo.reset(initialHead);
PushOneCommit.Result change = createChange("Change 1", "b", "b");
@@ -254,8 +256,8 @@
}
@Test
- public void submitDependentNonConflictingChangesOutOfOrder() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitDependentNonConflictingChangesOutOfOrder() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
testRepo.reset(initialHead);
PushOneCommit.Result change = createChange("Change 1", "b", "b");
@@ -264,11 +266,11 @@
// Submit succeeds; change2 is successfully cherry-picked onto head.
submit(change2.getChangeId());
- RevCommit headAfterFirstSubmit = getRemoteHead();
+ RevCommit headAfterFirstSubmit = projectOperations.project(project).getHead("master");
// Submit succeeds; change is successfully cherry-picked onto head
// (which was change2's cherry-pick).
submit(change.getChangeId());
- RevCommit headAfterSecondSubmit = getRemoteHead();
+ RevCommit headAfterSecondSubmit = projectOperations.project(project).getHead("master");
// change is the new tip.
List<RevCommit> log = getRemoteLog();
@@ -290,8 +292,8 @@
}
@Test
- public void submitDependentConflictingChangesOutOfOrder() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitDependentConflictingChangesOutOfOrder() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
testRepo.reset(initialHead);
PushOneCommit.Result change = createChange("Change 1", "b", "b1");
@@ -322,8 +324,8 @@
}
@Test
- public void submitSubsetOfDependentChanges() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitSubsetOfDependentChanges() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
testRepo.reset(initialHead);
PushOneCommit.Result change = createChange("Change 1", "b", "b");
@@ -334,7 +336,7 @@
// related to change 3 by topic or ancestor (due to cherrypicking!)
approve(change2.getChangeId());
submit(change3.getChangeId());
- RevCommit newHead = getRemoteHead();
+ RevCommit newHead = projectOperations.project(project).getHead("master");
assertNew(change.getChangeId());
assertNew(change2.getChangeId());
@@ -345,8 +347,8 @@
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
- public void submitIdenticalTree() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitIdenticalTree() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change1 = createChange("Change 1", "a.txt", "a");
@@ -354,12 +356,13 @@
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "a");
submit(change1.getChangeId());
- RevCommit headAfterFirstSubmit = getRemoteHead();
+ RevCommit headAfterFirstSubmit = projectOperations.project(project).getHead("master");
assertThat(headAfterFirstSubmit.getShortMessage()).isEqualTo("Change 1");
submit(change2.getChangeId(), new SubmitInput(), null, null);
- assertThat(getRemoteHead()).isEqualTo(headAfterFirstSubmit);
+ assertThat(projectOperations.project(project).getHead("master"))
+ .isEqualTo(headAfterFirstSubmit);
ChangeInfo info2 = get(change2.getChangeId(), MESSAGES);
assertThat(info2.status).isEqualTo(ChangeStatus.MERGED);
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByFastForwardIT.java b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByFastForwardIT.java
index 4551ded..aff0cc2 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByFastForwardIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByFastForwardIT.java
@@ -16,19 +16,23 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.GitUtil.pushHead;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import com.google.gerrit.acceptance.GitUtil;
import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.extensions.common.ActionInfo;
import com.google.gerrit.reviewdb.client.Change;
+import com.google.inject.Inject;
import java.util.Map;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.PushResult;
import org.junit.Test;
public class SubmitByFastForwardIT extends AbstractSubmit {
+ @Inject private ProjectOperations projectOperations;
@Override
protected SubmitType getSubmitType() {
@@ -36,11 +40,11 @@
}
@Test
- public void submitWithFastForward() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitWithFastForward() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange();
submit(change.getChangeId());
- RevCommit updatedHead = getRemoteHead();
+ RevCommit updatedHead = projectOperations.project(project).getHead("master");
assertThat(updatedHead.getId()).isEqualTo(change.getCommit());
assertThat(updatedHead.getParent(0)).isEqualTo(initialHead);
assertSubmitter(change.getChangeId(), 1);
@@ -50,8 +54,8 @@
}
@Test
- public void submitMultipleChangesWithFastForward() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitMultipleChangesWithFastForward() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange();
PushOneCommit.Result change2 = createChange();
@@ -64,7 +68,7 @@
approve(id2);
submit(id3);
- RevCommit updatedHead = getRemoteHead();
+ RevCommit updatedHead = projectOperations.project(project).getHead("master");
assertThat(updatedHead.getId()).isEqualTo(change3.getCommit());
assertThat(updatedHead.getParent(0).getId()).isEqualTo(change2.getCommit());
assertSubmitter(change.getChangeId(), 1);
@@ -82,8 +86,8 @@
}
@Test
- public void submitTwoChangesWithFastForward_missingDependency() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitTwoChangesWithFastForward_missingDependency() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change1 = createChange();
PushOneCommit.Result change2 = createChange();
@@ -95,19 +99,19 @@
+ id1
+ ": needs Code-Review");
- RevCommit updatedHead = getRemoteHead();
+ RevCommit updatedHead = projectOperations.project(project).getHead("master");
assertThat(updatedHead.getId()).isEqualTo(initialHead.getId());
assertRefUpdatedEvents();
assertChangeMergedEvents();
}
@Test
- public void submitFastForwardNotPossible_Conflict() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitFastForwardNotPossible_Conflict() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "content");
submit(change.getChangeId());
- RevCommit headAfterFirstSubmit = getRemoteHead();
+ RevCommit headAfterFirstSubmit = projectOperations.project(project).getHead("master");
testRepo.reset(initialHead);
PushOneCommit.Result change2 = createChange("Change 2", "b.txt", "other content");
@@ -128,7 +132,8 @@
+ ": Project policy requires "
+ "all submissions to be a fast-forward. Please rebase the change "
+ "locally and upload again for review.");
- assertThat(getRemoteHead()).isEqualTo(headAfterFirstSubmit);
+ assertThat(projectOperations.project(project).getHead("master"))
+ .isEqualTo(headAfterFirstSubmit);
assertSubmitter(change.getChangeId(), 1);
assertRefUpdatedEvents(initialHead, headAfterFirstSubmit);
@@ -136,11 +141,15 @@
}
@Test
- public void submitSameCommitsAsInExperimentalBranch() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitSameCommitsAsInExperimentalBranch() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
- grant(project, "refs/heads/*", Permission.CREATE);
- grant(project, "refs/heads/experimental", Permission.PUSH);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref("refs/heads/*").group(adminGroupUuid()))
+ .add(allow(Permission.PUSH).ref("refs/heads/experimental").group(adminGroupUuid()))
+ .update();
RevCommit c1 = commitBuilder().add("b.txt", "1").message("commit at tip").create();
String id1 = GitUtil.getChangeId(testRepo, c1).get();
@@ -153,9 +162,9 @@
.isEqualTo(c1.getId());
submit(id1);
- RevCommit headAfterSubmit = getRemoteHead();
+ RevCommit headAfterSubmit = projectOperations.project(project).getHead("master");
- assertThat(getRemoteHead().getId()).isEqualTo(c1.getId());
+ assertThat(projectOperations.project(project).getHead("master").getId()).isEqualTo(c1.getId());
assertSubmitter(id1, 1);
assertRefUpdatedEvents(initialHead, headAfterSubmit);
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByMergeAlwaysIT.java b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByMergeAlwaysIT.java
index 9bc5a2f..f80bdca 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByMergeAlwaysIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByMergeAlwaysIT.java
@@ -17,11 +17,14 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.extensions.client.SubmitType;
+import com.google.inject.Inject;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Test;
public class SubmitByMergeAlwaysIT extends AbstractSubmitByMerge {
+ @Inject private ProjectOperations projectOperations;
@Override
protected SubmitType getSubmitType() {
@@ -29,11 +32,11 @@
}
@Test
- public void submitWithMergeIfFastForwardPossible() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitWithMergeIfFastForwardPossible() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange();
submit(change.getChangeId());
- RevCommit headAfterSubmit = getRemoteHead();
+ RevCommit headAfterSubmit = projectOperations.project(project).getHead("master");
assertThat(headAfterSubmit.getParentCount()).isEqualTo(2);
assertThat(headAfterSubmit.getParent(0)).isEqualTo(initialHead);
assertThat(headAfterSubmit.getParent(1)).isEqualTo(change.getCommit());
@@ -46,8 +49,8 @@
}
@Test
- public void submitMultipleChanges() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitMultipleChanges() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
// Submit a change so that the remote head advances
PushOneCommit.Result change = createChange("Change 1", "b", "b");
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java
index f43b73b..64fa5c5 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java
@@ -16,8 +16,13 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.TruthJUnit.assume;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
+import static com.google.gerrit.common.data.Permission.READ;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.acceptance.GitUtil;
import com.google.gerrit.acceptance.PushOneCommit;
@@ -63,11 +68,11 @@
}
@Test
- public void submitWithFastForward() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitWithFastForward() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange();
submit(change.getChangeId());
- RevCommit updatedHead = getRemoteHead();
+ RevCommit updatedHead = projectOperations.project(project).getHead("master");
assertThat(updatedHead.getId()).isEqualTo(change.getCommit());
assertThat(updatedHead.getParent(0)).isEqualTo(initialHead);
assertSubmitter(change.getChangeId(), 1);
@@ -79,8 +84,8 @@
}
@Test
- public void submitMultipleChanges() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitMultipleChanges() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
testRepo.reset(initialHead);
PushOneCommit.Result change = createChange("Change 1", "b", "b");
@@ -136,13 +141,13 @@
}
@Test
- public void submitChangesAcrossRepos() throws Exception {
+ public void submitChangesAcrossRepos() throws Throwable {
Project.NameKey p1 = projectOperations.newProject().create();
Project.NameKey p2 = projectOperations.newProject().create();
Project.NameKey p3 = projectOperations.newProject().create();
- RevCommit initialHead2 = getRemoteHead(p2, "master");
- RevCommit initialHead3 = getRemoteHead(p3, "master");
+ RevCommit initialHead2 = projectOperations.project(p2).getHead("master");
+ RevCommit initialHead3 = projectOperations.project(p3).getHead("master");
TestRepository<?> repo1 = cloneProject(p1);
TestRepository<?> repo2 = cloneProject(p2);
@@ -213,7 +218,7 @@
}
@Test
- public void submitChangesAcrossReposBlocked() throws Exception {
+ public void submitChangesAcrossReposBlocked() throws Throwable {
Project.NameKey p1 = projectOperations.newProject().create();
Project.NameKey p2 = projectOperations.newProject().create();
Project.NameKey p3 = projectOperations.newProject().create();
@@ -222,9 +227,9 @@
TestRepository<?> repo2 = cloneProject(p2);
TestRepository<?> repo3 = cloneProject(p3);
- RevCommit initialHead1 = getRemoteHead(p1, "master");
- RevCommit initialHead2 = getRemoteHead(p2, "master");
- RevCommit initialHead3 = getRemoteHead(p3, "master");
+ RevCommit initialHead1 = projectOperations.project(p1).getHead("master");
+ RevCommit initialHead2 = projectOperations.project(p2).getHead("master");
+ RevCommit initialHead3 = projectOperations.project(p3).getHead("master");
PushOneCommit.Result change1a =
createChange(
@@ -277,15 +282,12 @@
+ "and upload the rebased commit for review.";
// Get a preview before submitting:
- try (BinaryResult r = gApi.changes().id(change1b.getChangeId()).current().submitPreview()) {
- // We cannot just use the ExpectedException infrastructure as provided
- // by AbstractDaemonTest, as then we'd stop early and not test the
- // actual submit.
+ RestApiException thrown =
+ assertThrows(
+ RestApiException.class,
+ () -> gApi.changes().id(change1b.getChangeId()).current().submitPreview().close());
+ assertThat(thrown.getMessage()).isEqualTo(msg);
- fail("expected failure");
- } catch (RestApiException e) {
- assertThat(e.getMessage()).isEqualTo(msg);
- }
submitWithConflict(change1b.getChangeId(), msg);
} else {
submit(change1b.getChangeId());
@@ -313,13 +315,13 @@
}
@Test
- public void submitWithMergedAncestorsOnOtherBranch() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitWithMergedAncestorsOnOtherBranch() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change1 =
createChange(testRepo, "master", "base commit", "a.txt", "1", "");
submit(change1.getChangeId());
- RevCommit headAfterFirstSubmit = getRemoteHead();
+ RevCommit headAfterFirstSubmit = projectOperations.project(project).getHead("master");
gApi.projects().name(project.get()).branch("branch").create(new BranchInput());
@@ -362,12 +364,12 @@
}
@Test
- public void submitWithOpenAncestorsOnOtherBranch() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitWithOpenAncestorsOnOtherBranch() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change1 =
createChange(testRepo, "master", "base commit", "a.txt", "1", "");
submit(change1.getChangeId());
- RevCommit headAfterFirstSubmit = getRemoteHead();
+ RevCommit headAfterFirstSubmit = projectOperations.project(project).getHead("master");
gApi.projects().name(project.get()).branch("branch").create(new BranchInput());
@@ -395,7 +397,7 @@
Project.NameKey p3 = projectOperations.newProject().create();
TestRepository<?> repo3 = cloneProject(p3);
- RevCommit repo3Head = getRemoteHead(p3, "master");
+ RevCommit repo3Head = projectOperations.project(p3).getHead("master");
PushOneCommit.Result change3b =
createChange(
repo3,
@@ -435,8 +437,8 @@
}
@Test
- public void gerritWorkflow() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void gerritWorkflow() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
// We'll setup a master and a stable branch.
// Then we create a change to be applied to master, which is
@@ -462,8 +464,8 @@
gApi.changes().id(cherryId).current().submit();
// Create the merge locally
- RevCommit stable = getRemoteHead(project, "stable");
- RevCommit master = getRemoteHead(project, "master");
+ RevCommit stable = projectOperations.project(project).getHead("stable");
+ RevCommit master = projectOperations.project(project).getHead("master");
testRepo.git().fetch().call();
testRepo.git().branchCreate().setName("stable").setStartPoint(stable).call();
testRepo.git().branchCreate().setName("master").setStartPoint(master).call();
@@ -493,7 +495,7 @@
}
@Test
- public void openChangeForTargetBranchPreventsMerge() throws Exception {
+ public void openChangeForTargetBranchPreventsMerge() throws Throwable {
gApi.projects().name(project.get()).branch("stable").create(new BranchInput());
// Propose a change for master, but leave it open for master!
@@ -532,7 +534,7 @@
}
@Test
- public void dependencyOnOutdatedPatchSetPreventsMerge() throws Exception {
+ public void dependencyOnOutdatedPatchSetPreventsMerge() throws Throwable {
// Create a change
PushOneCommit change = pushFactory.create(user.newIdent(), testRepo, "fix", "a.txt", "foo");
PushOneCommit.Result changeResult = change.to("refs/for/master");
@@ -574,7 +576,7 @@
}
@Test
- public void dependencyOnDeletedChangePreventsMerge() throws Exception {
+ public void dependencyOnDeletedChangePreventsMerge() throws Throwable {
// Create a change
PushOneCommit change = pushFactory.create(user.newIdent(), testRepo, "fix", "a.txt", "foo");
PushOneCommit.Result changeResult = change.to("refs/for/master");
@@ -608,9 +610,13 @@
}
@Test
- public void dependencyOnChangeForNonVisibleBranchPreventsMerge() throws Exception {
- grantLabel("Code-Review", -2, 2, project, "refs/heads/*", false, REGISTERED_USERS, false);
- grant(project, "refs/*", Permission.SUBMIT, false, REGISTERED_USERS);
+ public void dependencyOnChangeForNonVisibleBranchPreventsMerge() throws Throwable {
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(REGISTERED_USERS).range(-2, 2))
+ .add(allow(Permission.SUBMIT).ref("refs/*").group(REGISTERED_USERS))
+ .update();
// Create a change
PushOneCommit change = pushFactory.create(admin.newIdent(), testRepo, "fix", "a.txt", "foo");
@@ -630,17 +636,20 @@
.branch(secretBranch.branch())
.create(new BranchInput());
gApi.changes().id(changeResult.getChangeId()).move(secretBranch.branch());
- block(secretBranch.branch(), "read", ANONYMOUS_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(READ).ref(secretBranch.branch()).group(ANONYMOUS_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
// Verify that user cannot see the first change.
- try {
- gApi.changes().id(changeResult.getChangeId()).get();
- fail("expected failure");
- } catch (ResourceNotFoundException e) {
- assertThat(e.getMessage()).isEqualTo("Not found: " + changeResult.getChangeId());
- }
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.changes().id(changeResult.getChangeId()).get());
+ assertThat(thrown).hasMessageThat().isEqualTo("Not found: " + changeResult.getChangeId());
// Submit is expected to fail.
submitWithConflict(
@@ -663,9 +672,13 @@
}
@Test
- public void dependencyOnHiddenChangePreventsMerge() throws Exception {
- grantLabel("Code-Review", -2, 2, project, "refs/heads/*", false, REGISTERED_USERS, false);
- grant(project, "refs/*", Permission.SUBMIT, false, REGISTERED_USERS);
+ public void dependencyOnHiddenChangePreventsMerge() throws Throwable {
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(REGISTERED_USERS).range(-2, 2))
+ .add(allow(Permission.SUBMIT).ref("refs/*").group(REGISTERED_USERS))
+ .update();
// Create a change
PushOneCommit change = pushFactory.create(admin.newIdent(), testRepo, "fix", "a.txt", "foo");
@@ -684,30 +697,29 @@
requestScopeOperations.setApiUser(user.id());
// Verify that user cannot see the first change.
- try {
- gApi.changes().id(changeResult.getChangeId()).get();
- fail("expected failure");
- } catch (ResourceNotFoundException e) {
- assertThat(e.getMessage()).isEqualTo("Not found: " + changeResult.getChangeId());
- }
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.changes().id(changeResult.getChangeId()).get());
+ assertThat(thrown).hasMessageThat().isEqualTo("Not found: " + changeResult.getChangeId());
// Submit is expected to fail.
- try {
- gApi.changes().id(change2Result.getChangeId()).current().submit();
- fail("expected failure");
- } catch (AuthException e) {
- assertThat(e.getMessage())
- .isEqualTo(
- "A change to be submitted with "
- + change2Result.getChange().getId().get()
- + " is not visible");
- }
+ AuthException thrown2 =
+ assertThrows(
+ AuthException.class,
+ () -> gApi.changes().id(change2Result.getChangeId()).current().submit());
+ assertThat(thrown2)
+ .hasMessageThat()
+ .isEqualTo(
+ "A change to be submitted with "
+ + change2Result.getChange().getId().get()
+ + " is not visible");
assertRefUpdatedEvents();
assertChangeMergedEvents();
}
@Test
- public void dependencyOnHiddenChangeUsingTopicPreventsMerge() throws Exception {
+ public void dependencyOnHiddenChangeUsingTopicPreventsMerge() throws Throwable {
// Construct a topic where a change included by topic depends on a private change that is not
// visible to the submitting user
// (c1) --- topic --- (c2b)
@@ -718,10 +730,18 @@
Project.NameKey p1 = projectOperations.newProject().create();
Project.NameKey p2 = projectOperations.newProject().create();
- grantLabel("Code-Review", -2, 2, p1, "refs/heads/*", false, REGISTERED_USERS, false);
- grant(p1, "refs/*", Permission.SUBMIT, false, REGISTERED_USERS);
- grantLabel("Code-Review", -2, 2, p2, "refs/heads/*", false, REGISTERED_USERS, false);
- grant(p2, "refs/*", Permission.SUBMIT, false, REGISTERED_USERS);
+ projectOperations
+ .project(p1)
+ .forUpdate()
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(REGISTERED_USERS).range(-2, 2))
+ .add(allow(Permission.SUBMIT).ref("refs/*").group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .project(p2)
+ .forUpdate()
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(REGISTERED_USERS).range(-2, 2))
+ .add(allow(Permission.SUBMIT).ref("refs/*").group(REGISTERED_USERS))
+ .update();
TestRepository<?> repo1 = cloneProject(p1);
TestRepository<?> repo2 = cloneProject(p2);
@@ -744,30 +764,27 @@
requestScopeOperations.setApiUser(user.id());
// Verify that user cannot see change2a
- try {
- gApi.changes().id(change2a.getChangeId()).get();
- fail("expected failure");
- } catch (ResourceNotFoundException e) {
- assertThat(e.getMessage()).isEqualTo("Not found: " + change2a.getChangeId());
- }
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class, () -> gApi.changes().id(change2a.getChangeId()).get());
+ assertThat(thrown).hasMessageThat().isEqualTo("Not found: " + change2a.getChangeId());
// Submit is expected to fail.
- try {
- gApi.changes().id(change1.getChangeId()).current().submit();
- fail("expected failure");
- } catch (AuthException e) {
- assertThat(e.getMessage())
- .isEqualTo(
- "A change to be submitted with "
- + change1.getChange().getId().get()
- + " is not visible");
- }
+ AuthException thrown2 =
+ assertThrows(
+ AuthException.class, () -> gApi.changes().id(change1.getChangeId()).current().submit());
+ assertThat(thrown2)
+ .hasMessageThat()
+ .isEqualTo(
+ "A change to be submitted with "
+ + change1.getChange().getId().get()
+ + " is not visible");
assertRefUpdatedEvents();
assertChangeMergedEvents();
}
@Test
- public void testPreviewSubmitTgz() throws Exception {
+ public void testPreviewSubmitTgz() throws Throwable {
Project.NameKey p1 = projectOperations.newProject().create();
TestRepository<?> repo1 = cloneProject(p1);
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByRebaseAlwaysIT.java b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByRebaseAlwaysIT.java
index 1462c97..1808480 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByRebaseAlwaysIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByRebaseAlwaysIT.java
@@ -15,13 +15,14 @@
package com.google.gerrit.acceptance.rest.change;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
import static com.google.gerrit.extensions.client.ListChangesOption.CURRENT_REVISION;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestProjectInput;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.FooterConstants;
import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.client.SubmitType;
@@ -44,6 +45,7 @@
public class SubmitByRebaseAlwaysIT extends AbstractSubmitByRebase {
@Inject private DynamicSet<ChangeMessageModifier> changeMessageModifiers;
@Inject private DynamicItem<UrlFormatter> urlFormatter;
+ @Inject private ProjectOperations projectOperations;
@Override
protected SubmitType getSubmitType() {
@@ -52,12 +54,12 @@
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
- public void submitWithPossibleFastForward() throws Exception {
- RevCommit oldHead = getRemoteHead();
+ public void submitWithPossibleFastForward() throws Throwable {
+ RevCommit oldHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange();
submit(change.getChangeId());
- RevCommit head = getRemoteHead();
+ RevCommit head = projectOperations.project(project).getHead("master");
assertThat(head.getId()).isNotEqualTo(change.getCommit());
assertThat(head.getParent(0)).isEqualTo(oldHead);
assertApproved(change.getChangeId());
@@ -72,7 +74,7 @@
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
- public void alwaysAddFooters() throws Exception {
+ public void alwaysAddFooters() throws Throwable {
PushOneCommit.Result change1 = createChange();
PushOneCommit.Result change2 = createChange();
@@ -89,7 +91,7 @@
}
@Test
- public void rebaseInvokesChangeMessageModifiers() throws Exception {
+ public void rebaseInvokesChangeMessageModifiers() throws Throwable {
ChangeMessageModifier modifier1 =
(msg, orig, tip, dest) -> msg + "This-change-before-rebase: " + orig.name() + "\n";
ChangeMessageModifier modifier2 =
@@ -102,8 +104,8 @@
ChangeData cd1 = changes.get(0).getChange();
ChangeData cd2 = changes.get(1).getChange();
assertThat(cd2.patchSets()).hasSize(2);
- String change1CurrentCommit = cd1.currentPatchSet().getCommitId().name();
- String change2Ps1Commit = cd2.patchSet(PatchSet.id(cd2.getId(), 1)).getCommitId().name();
+ String change1CurrentCommit = cd1.currentPatchSet().commitId().name();
+ String change2Ps1Commit = cd2.patchSet(PatchSet.id(cd2.getId(), 1)).commitId().name();
assertThat(gApi.changes().id(cd2.getId().get()).revision(2).commit(false).message)
.isEqualTo(
@@ -120,42 +122,36 @@
}
@Test
- public void failingChangeMessageModifierShortCircuits() throws Exception {
+ public void failingChangeMessageModifierShortCircuits() throws Throwable {
ChangeMessageModifier modifier1 =
(msg, orig, tip, dest) -> {
throw new IllegalStateException("boom");
};
ChangeMessageModifier modifier2 = (msg, orig, tip, dest) -> msg + "A-footer: value\n";
try (AutoCloseable ignored = installChangeMessageModifiers(modifier1, modifier2)) {
- try {
- submitWithRebase();
- assert_().fail("expected ResourceConflictException");
- } catch (ResourceConflictException e) {
- Throwable cause = Throwables.getRootCause(e);
- assertThat(cause).isInstanceOf(RuntimeException.class);
- assertThat(cause).hasMessageThat().isEqualTo("boom");
- }
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> submitWithRebase());
+ Throwable cause = Throwables.getRootCause(thrown);
+ assertThat(cause).isInstanceOf(RuntimeException.class);
+ assertThat(cause).hasMessageThat().isEqualTo("boom");
}
}
@Test
- public void changeMessageModifierReturningNullShortCircuits() throws Exception {
+ public void changeMessageModifierReturningNullShortCircuits() throws Throwable {
ChangeMessageModifier modifier1 = (msg, orig, tip, dest) -> null;
ChangeMessageModifier modifier2 = (msg, orig, tip, dest) -> msg + "A-footer: value\n";
try (AutoCloseable ignored = installChangeMessageModifiers(modifier1, modifier2)) {
- try {
- submitWithRebase();
- assert_().fail("expected ResourceConflictException");
- } catch (ResourceConflictException e) {
- Throwable cause = Throwables.getRootCause(e);
- assertThat(cause).isInstanceOf(RuntimeException.class);
- assertThat(cause)
- .hasMessageThat()
- .isEqualTo(
- modifier1.getClass().getName()
- + ".onSubmit from plugin modifier-1 returned null instead of new commit"
- + " message");
- }
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> submitWithRebase());
+ Throwable cause = Throwables.getRootCause(thrown);
+ assertThat(cause).isInstanceOf(RuntimeException.class);
+ assertThat(cause)
+ .hasMessageThat()
+ .isEqualTo(
+ modifier1.getClass().getName()
+ + ".onSubmit from plugin modifier-1 returned null instead of new commit"
+ + " message");
}
}
@@ -171,14 +167,14 @@
};
}
- private void assertLatestRevisionHasFooters(PushOneCommit.Result change) throws Exception {
+ private void assertLatestRevisionHasFooters(PushOneCommit.Result change) throws Throwable {
RevCommit c = getCurrentCommit(change);
assertThat(c.getFooterLines(FooterConstants.CHANGE_ID)).isNotEmpty();
assertThat(c.getFooterLines(FooterConstants.REVIEWED_BY)).isNotEmpty();
assertThat(c.getFooterLines(FooterConstants.REVIEWED_ON)).isNotEmpty();
}
- private RevCommit getCurrentCommit(PushOneCommit.Result change) throws Exception {
+ private RevCommit getCurrentCommit(PushOneCommit.Result change) throws Throwable {
testRepo.git().fetch().setRemote("origin").call();
ChangeInfo info = get(change.getChangeId(), CURRENT_REVISION);
RevCommit c = testRepo.getRevWalk().parseCommit(ObjectId.fromString(info.currentRevision));
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByRebaseIfNecessaryIT.java b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByRebaseIfNecessaryIT.java
index 7bb31a0..01b58ee 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/SubmitByRebaseIfNecessaryIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/SubmitByRebaseIfNecessaryIT.java
@@ -18,12 +18,15 @@
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.TestProjectInput;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.client.SubmitType;
+import com.google.inject.Inject;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Test;
public class SubmitByRebaseIfNecessaryIT extends AbstractSubmitByRebase {
+ @Inject private ProjectOperations projectOperations;
@Override
protected SubmitType getSubmitType() {
@@ -32,11 +35,11 @@
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
- public void submitWithFastForward() throws Exception {
- RevCommit oldHead = getRemoteHead();
+ public void submitWithFastForward() throws Throwable {
+ RevCommit oldHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange();
submit(change.getChangeId());
- RevCommit head = getRemoteHead();
+ RevCommit head = projectOperations.project(project).getHead("master");
assertThat(head.getId()).isEqualTo(change.getCommit());
assertThat(head.getParent(0)).isEqualTo(oldHead);
assertApproved(change.getChangeId());
@@ -50,20 +53,20 @@
@Test
@TestProjectInput(useContentMerge = InheritableBoolean.TRUE)
- public void submitWithContentMerge() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ public void submitWithContentMerge() throws Throwable {
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
PushOneCommit.Result change = createChange("Change 1", "a.txt", "aaa\nbbb\nccc\n");
submit(change.getChangeId());
- RevCommit headAfterFirstSubmit = getRemoteHead();
+ RevCommit headAfterFirstSubmit = projectOperations.project(project).getHead("master");
PushOneCommit.Result change2 = createChange("Change 2", "a.txt", "aaa\nbbb\nccc\nddd\n");
submit(change2.getChangeId());
- RevCommit headAfterSecondSubmit = getRemoteHead();
+ RevCommit headAfterSecondSubmit = projectOperations.project(project).getHead("master");
testRepo.reset(change.getCommit());
PushOneCommit.Result change3 = createChange("Change 3", "a.txt", "bbb\nccc\n");
submit(change3.getChangeId());
assertRebase(testRepo, true);
- RevCommit headAfterThirdSubmit = getRemoteHead();
+ RevCommit headAfterThirdSubmit = projectOperations.project(project).getHead("master");
assertThat(headAfterThirdSubmit.getParent(0)).isEqualTo(headAfterSecondSubmit);
assertApproved(change3.getChangeId());
assertCurrentRevision(change3.getChangeId(), 2, headAfterThirdSubmit);
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/SuggestReviewersIT.java b/javatests/com/google/gerrit/acceptance/rest/change/SuggestReviewersIT.java
index 9bbe1dd..5401a2c 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/SuggestReviewersIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/SuggestReviewersIT.java
@@ -16,6 +16,10 @@
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
+import static com.google.gerrit.common.data.Permission.READ;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
import static java.util.stream.Collectors.toList;
@@ -160,8 +164,12 @@
List<SuggestedReviewerInfo> reviewers;
requestScopeOperations.setApiUser(user3.id());
- block("refs/*", "read", ANONYMOUS_USERS);
- allow("refs/*", "read", group1);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(READ).ref("refs/*").group(ANONYMOUS_USERS))
+ .add(allow(READ).ref("refs/*").group(group1))
+ .update();
reviewers = suggestReviewers(changeId, user2.username(), 2);
assertThat(reviewers).isEmpty();
}
@@ -178,7 +186,10 @@
// Clear cached group info.
requestScopeOperations.setApiUser(user1.id());
- allowGlobalCapabilities(group1, GlobalCapability.VIEW_ALL_ACCOUNTS);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.VIEW_ALL_ACCOUNTS).group(group1))
+ .update();
reviewers = suggestReviewers(changeId, user2.username(), 2);
assertThat(reviewers).hasSize(1);
assertThat(Iterables.getOnlyElement(reviewers).account.name).isEqualTo(user2.fullName());
diff --git a/javatests/com/google/gerrit/acceptance/rest/config/CacheOperationsIT.java b/javatests/com/google/gerrit/acceptance/rest/config/CacheOperationsIT.java
index 7ef915b..daeb032 100644
--- a/javatests/com/google/gerrit/acceptance/rest/config/CacheOperationsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/config/CacheOperationsIT.java
@@ -15,19 +15,24 @@
package com.google.gerrit.acceptance.rest.config;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.capabilityKey;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static com.google.gerrit.server.restapi.config.PostCaches.Operation.FLUSH;
import static com.google.gerrit.server.restapi.config.PostCaches.Operation.FLUSH_ALL;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.server.restapi.config.ListCaches.CacheInfo;
import com.google.gerrit.server.restapi.config.PostCaches;
+import com.google.inject.Inject;
import java.util.Arrays;
import org.junit.Test;
public class CacheOperationsIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
@Test
public void flushAll() throws Exception {
@@ -124,8 +129,11 @@
@Test
public void flushWebSessions_Forbidden() throws Exception {
- allowGlobalCapabilities(
- REGISTERED_USERS, GlobalCapability.FLUSH_CACHES, GlobalCapability.VIEW_CACHES);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.FLUSH_CACHES).group(REGISTERED_USERS))
+ .add(allowCapability(GlobalCapability.VIEW_CACHES).group(REGISTERED_USERS))
+ .update();
try {
RestResponse r =
userRestSession.post(
@@ -138,8 +146,11 @@
"/config/server/caches/", new PostCaches.Input(FLUSH, Arrays.asList("web_sessions")))
.assertForbidden();
} finally {
- removeGlobalCapabilities(
- REGISTERED_USERS, GlobalCapability.FLUSH_CACHES, GlobalCapability.VIEW_CACHES);
+ projectOperations
+ .allProjectsForUpdate()
+ .remove(capabilityKey(GlobalCapability.FLUSH_CACHES).group(REGISTERED_USERS))
+ .remove(capabilityKey(GlobalCapability.VIEW_CACHES).group(REGISTERED_USERS))
+ .update();
}
}
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/config/FlushCacheIT.java b/javatests/com/google/gerrit/acceptance/rest/config/FlushCacheIT.java
index caecefa..a161ec4 100644
--- a/javatests/com/google/gerrit/acceptance/rest/config/FlushCacheIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/config/FlushCacheIT.java
@@ -15,15 +15,20 @@
package com.google.gerrit.acceptance.rest.config;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.capabilityKey;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.server.restapi.config.ListCaches.CacheInfo;
+import com.google.inject.Inject;
import org.junit.Test;
public class FlushCacheIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
@Test
public void flushCache() throws Exception {
@@ -65,8 +70,11 @@
@Test
public void flushWebSessionsCache_Forbidden() throws Exception {
- allowGlobalCapabilities(
- REGISTERED_USERS, GlobalCapability.VIEW_CACHES, GlobalCapability.FLUSH_CACHES);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.FLUSH_CACHES).group(REGISTERED_USERS))
+ .add(allowCapability(GlobalCapability.VIEW_CACHES).group(REGISTERED_USERS))
+ .update();
try {
RestResponse r = userRestSession.post("/config/server/caches/accounts/flush");
r.assertOK();
@@ -74,8 +82,11 @@
userRestSession.post("/config/server/caches/web_sessions/flush").assertForbidden();
} finally {
- removeGlobalCapabilities(
- REGISTERED_USERS, GlobalCapability.VIEW_CACHES, GlobalCapability.FLUSH_CACHES);
+ projectOperations
+ .allProjectsForUpdate()
+ .remove(capabilityKey(GlobalCapability.FLUSH_CACHES).group(REGISTERED_USERS))
+ .remove(capabilityKey(GlobalCapability.VIEW_CACHES).group(REGISTERED_USERS))
+ .update();
}
}
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/AbstractPushTag.java b/javatests/com/google/gerrit/acceptance/rest/project/AbstractPushTag.java
index bea1748..e2818d2 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/AbstractPushTag.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/AbstractPushTag.java
@@ -21,14 +21,18 @@
import static com.google.gerrit.acceptance.GitUtil.updateAnnotatedTag;
import static com.google.gerrit.acceptance.rest.project.AbstractPushTag.TagType.ANNOTATED;
import static com.google.gerrit.acceptance.rest.project.AbstractPushTag.TagType.LIGHTWEIGHT;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.permissionKey;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import com.google.common.base.MoreObjects;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GitUtil;
import com.google.gerrit.acceptance.NoHttpd;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.reviewdb.client.RefNames;
+import com.google.inject.Inject;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.PushResult;
@@ -50,6 +54,8 @@
}
}
+ @Inject private ProjectOperations projectOperations;
+
private RevCommit initialHead;
private TagType tagType;
@@ -58,7 +64,7 @@
// clone with user to avoid inherited tag permissions of admin user
testRepo = cloneProject(project, user);
- initialHead = getRemoteHead();
+ initialHead = projectOperations.project(project).getHead("master");
tagType = getTagType();
}
@@ -207,7 +213,11 @@
}
if (!newCommit) {
- grant(project, "refs/for/refs/heads/master", Permission.SUBMIT, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.SUBMIT).ref("refs/for/refs/heads/master").group(REGISTERED_USERS))
+ .update();
pushHead(testRepo, "refs/for/master%submit");
}
@@ -229,26 +239,46 @@
}
private void allowTagCreation() throws Exception {
- grant(project, "refs/tags/*", tagType.createPermission, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(tagType.createPermission).ref("refs/tags/*").group(REGISTERED_USERS))
+ .update();
}
private void allowPushOnRefsTags() throws Exception {
removePushFromRefsTags();
- grant(project, "refs/tags/*", Permission.PUSH, false, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/tags/*").group(REGISTERED_USERS))
+ .update();
}
private void allowForcePushOnRefsTags() throws Exception {
removePushFromRefsTags();
- grant(project, "refs/tags/*", Permission.PUSH, true, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/tags/*").group(REGISTERED_USERS).force(true))
+ .update();
}
private void allowTagDeletion() throws Exception {
removePushFromRefsTags();
- grant(project, "refs/tags/*", Permission.DELETE, true, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.DELETE).ref("refs/tags/*").group(REGISTERED_USERS).force(true))
+ .update();
}
private void removePushFromRefsTags() throws Exception {
- removePermission(project, "refs/tags/*", Permission.PUSH);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .remove(permissionKey(Permission.PUSH).ref("refs/tags/*"))
+ .update();
}
private void commit(PersonIdent ident, String subject) throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/AccessIT.java b/javatests/com/google/gerrit/acceptance/rest/project/AccessIT.java
index 72af075..bb043c2 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/AccessIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/AccessIT.java
@@ -15,8 +15,11 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.extensions.client.ListChangesOption.MESSAGES;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+import static com.google.gerrit.truth.ConfigSubject.assertThat;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.GitUtil;
@@ -32,7 +35,6 @@
import com.google.gerrit.extensions.api.access.ProjectAccessInfo;
import com.google.gerrit.extensions.api.access.ProjectAccessInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
-import com.google.gerrit.extensions.api.projects.BranchInfo;
import com.google.gerrit.extensions.api.projects.ProjectApi;
import com.google.gerrit.extensions.client.ChangeStatus;
import com.google.gerrit.extensions.common.ChangeInfo;
@@ -125,7 +127,7 @@
@Test
public void addAccessSection() throws Exception {
- RevCommit initialHead = getRemoteHead(newProjectName, RefNames.REFS_CONFIG);
+ RevCommit initialHead = projectOperations.project(newProjectName).getHead(RefNames.REFS_CONFIG);
ProjectAccessInput accessInput = newProjectAccessInput();
AccessSectionInfo accessSectionInfo = createDefaultAccessSectionInfo();
@@ -135,7 +137,7 @@
assertThat(pApi().access().local).isEqualTo(accessInput.add);
- RevCommit updatedHead = getRemoteHead(newProjectName, RefNames.REFS_CONFIG);
+ RevCommit updatedHead = projectOperations.project(newProjectName).getHead(RefNames.REFS_CONFIG);
eventRecorder.assertRefUpdatedEvents(
newProjectName.get(), RefNames.REFS_CONFIG, null, initialHead, initialHead, updatedHead);
}
@@ -143,8 +145,7 @@
@Test
public void createAccessChangeNop() throws Exception {
ProjectAccessInput accessInput = newProjectAccessInput();
- exception.expect(BadRequestException.class);
- pApi().accessChange(accessInput);
+ assertThrows(BadRequestException.class, () -> pApi().accessChange(accessInput));
}
@Test
@@ -169,7 +170,11 @@
@Test
public void createAccessChange() throws Exception {
- allow(newProjectName, RefNames.REFS_CONFIG, Permission.READ, REGISTERED_USERS);
+ projectOperations
+ .project(newProjectName)
+ .forUpdate()
+ .add(allow(Permission.READ).ref(RefNames.REFS_CONFIG).group(REGISTERED_USERS))
+ .update();
// User can see the branch
requestScopeOperations.setApiUser(user.id());
pApi().branch("refs/heads/master").get();
@@ -206,12 +211,7 @@
// check that the change took effect.
requestScopeOperations.setApiUser(user.id());
- try {
- BranchInfo info = pApi().branch("refs/heads/master").get();
- fail("wanted failure, got " + newGson().toJson(info));
- } catch (ResourceNotFoundException e) {
- // OK.
- }
+ assertThrows(ResourceNotFoundException.class, () -> pApi().branch("refs/heads/master").get());
// Restore.
accessInput.add.clear();
@@ -326,8 +326,7 @@
pApi().access(accessInput);
requestScopeOperations.setApiUser(user.id());
- exception.expect(ResourceNotFoundException.class);
- pApi().access();
+ assertThrows(ResourceNotFoundException.class, () -> pApi().access());
}
@Test
@@ -346,8 +345,7 @@
accessInfoToApply.add.put(REFS_HEADS, accessSectionInfoToApply);
requestScopeOperations.setApiUser(user.id());
- exception.expect(ResourceNotFoundException.class);
- pApi().access();
+ assertThrows(ResourceNotFoundException.class, () -> pApi().access());
}
@Test
@@ -409,9 +407,8 @@
accessInput.parent = newParentProjectName;
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- exception.expectMessage("administrate server not permitted");
- pApi().access(accessInput);
+ AuthException thrown = assertThrows(AuthException.class, () -> pApi().access(accessInput));
+ assertThat(thrown).hasMessageThat().contains("administrate server not permitted");
}
@Test
@@ -436,8 +433,8 @@
accessInput.add.put(AccessSection.GLOBAL_CAPABILITIES, accessSectionInfo);
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- gApi.projects().name(allProjects.get()).access(accessInput);
+ assertThrows(
+ AuthException.class, () -> gApi.projects().name(allProjects.get()).access(accessInput));
}
@Test
@@ -465,8 +462,7 @@
accessInput.add.put(AccessSection.GLOBAL_CAPABILITIES, accessSectionInfo);
- exception.expect(BadRequestException.class);
- pApi().access(accessInput);
+ assertThrows(BadRequestException.class, () -> pApi().access(accessInput));
}
@Test
@@ -479,9 +475,9 @@
accessSectionInfo.permissions.put(Permission.PUSH, permissionInfo);
accessInput.add.put(AccessSection.GLOBAL_CAPABILITIES, accessSectionInfo);
-
- exception.expect(BadRequestException.class);
- gApi.projects().name(allProjects.get()).access(accessInput);
+ assertThrows(
+ BadRequestException.class,
+ () -> gApi.projects().name(allProjects.get()).access(accessInput));
}
@Test
@@ -492,8 +488,8 @@
accessInput.remove.put(AccessSection.GLOBAL_CAPABILITIES, accessSectionInfo);
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- gApi.projects().name(allProjects.get()).access(accessInput);
+ assertThrows(
+ AuthException.class, () -> gApi.projects().name(allProjects.get()).access(accessInput));
}
@Test
@@ -572,7 +568,7 @@
.file(ProjectConfig.PROJECT_CONFIG)
.asString();
cfg.fromText(config);
- assertThat(cfg.getString(access, refsFor, unknownPermission)).isEqualTo(registeredUsers);
+ assertThat(cfg).stringValue(access, refsFor, unknownPermission).isEqualTo(registeredUsers);
// Make permission change through API
ProjectAccessInput accessInput = newProjectAccessInput();
@@ -591,16 +587,20 @@
.file(ProjectConfig.PROJECT_CONFIG)
.asString();
cfg.fromText(config);
- assertThat(cfg.getString(access, refsFor, unknownPermission)).isEqualTo(registeredUsers);
+ assertThat(cfg).stringValue(access, refsFor, unknownPermission).isEqualTo(registeredUsers);
}
@Test
public void allUsersCanOnlyInheritFromAllProjects() throws Exception {
ProjectAccessInput accessInput = newProjectAccessInput();
accessInput.parent = project.get();
- exception.expect(BadRequestException.class);
- exception.expectMessage(allUsers.get() + " must inherit from " + allProjects.get());
- gApi.projects().name(allUsers.get()).access(accessInput);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () -> gApi.projects().name(allUsers.get()).access(accessInput));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(allUsers.get() + " must inherit from " + allProjects.get());
}
@Test
@@ -650,9 +650,9 @@
String invalidRef = Constants.R_HEADS + "stable_*";
accessInput.add.put(invalidRef, accessSectionInfo);
- exception.expect(BadRequestException.class);
- exception.expectMessage("Invalid Name: " + invalidRef);
- pApi().access(accessInput);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> pApi().access(accessInput));
+ assertThat(thrown).hasMessageThat().contains("Invalid Name: " + invalidRef);
}
@Test
@@ -664,9 +664,9 @@
String invalidRef = Constants.R_HEADS + "stable_*";
accessInput.add.put(invalidRef, accessSectionInfo);
- exception.expect(BadRequestException.class);
- exception.expectMessage("Invalid Name: " + invalidRef);
- pApi().accessChange(accessInput);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> pApi().accessChange(accessInput));
+ assertThat(thrown).hasMessageThat().contains("Invalid Name: " + invalidRef);
}
private ProjectApi pApi() throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/CheckMergeabilityIT.java b/javatests/com/google/gerrit/acceptance/rest/project/CheckMergeabilityIT.java
index 10e3e99..22fb829 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/CheckMergeabilityIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/CheckMergeabilityIT.java
@@ -20,12 +20,14 @@
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.RestResponse;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
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.common.MergeableInfo;
import com.google.gerrit.reviewdb.client.BranchNameKey;
+import com.google.inject.Inject;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.RefSpec;
@@ -34,6 +36,8 @@
public class CheckMergeabilityIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
+
private BranchNameKey branch;
@Before
@@ -44,7 +48,7 @@
@Test
public void checkMergeableCommit() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
testRepo
.branch("HEAD")
.commit()
@@ -79,7 +83,7 @@
@Test
public void checkUnMergeableCommit() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
testRepo
.branch("HEAD")
.commit()
@@ -114,7 +118,7 @@
@Test
public void checkOursMergeStrategy() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
testRepo
.branch("HEAD")
.commit()
@@ -208,7 +212,7 @@
cherry.current().review(ReviewInput.approve());
cherry.current().submit();
- ObjectId remoteId = getRemoteHead();
+ ObjectId remoteId = projectOperations.project(project).getHead("master");
assertThat(remoteId).isNotEqualTo(commitId);
assertContentMerged("master", commitId.getName(), "recursive");
}
@@ -234,7 +238,7 @@
@Test
public void checkInvalidStrategy() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
testRepo
.branch("HEAD")
.commit()
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/CreateBranchIT.java b/javatests/com/google/gerrit/acceptance/rest/project/CreateBranchIT.java
index 7ebf96b..41fa128 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/CreateBranchIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/CreateBranchIT.java
@@ -16,12 +16,16 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.reviewdb.client.RefNames.REFS_HEADS;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.projects.BranchApi;
@@ -39,6 +43,7 @@
import org.junit.Test;
public class CreateBranchIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
private BranchNameKey testBranch;
@@ -102,15 +107,23 @@
@Test
public void createMetaBranch() throws Exception {
String metaRef = RefNames.REFS_META + "foo";
- allow(metaRef, Permission.CREATE, REGISTERED_USERS);
- allow(metaRef, Permission.PUSH, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref(metaRef).group(REGISTERED_USERS))
+ .add(allow(Permission.PUSH).ref(metaRef).group(REGISTERED_USERS))
+ .update();
assertCreateSucceeds(BranchNameKey.create(project, metaRef));
}
@Test
public void createUserBranch_Conflict() throws Exception {
- allow(allUsers, RefNames.REFS_USERS + "*", Permission.CREATE, REGISTERED_USERS);
- allow(allUsers, RefNames.REFS_USERS + "*", Permission.PUSH, REGISTERED_USERS);
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref(RefNames.REFS_USERS + "*").group(REGISTERED_USERS))
+ .add(allow(Permission.PUSH).ref(RefNames.REFS_USERS + "*").group(REGISTERED_USERS))
+ .update();
assertCreateFails(
BranchNameKey.create(allUsers, RefNames.refsUsers(Account.id(1))),
RefNames.refsUsers(admin.id()),
@@ -120,8 +133,12 @@
@Test
public void createGroupBranch_Conflict() throws Exception {
- allow(allUsers, RefNames.REFS_GROUPS + "*", Permission.CREATE, REGISTERED_USERS);
- allow(allUsers, RefNames.REFS_GROUPS + "*", Permission.PUSH, REGISTERED_USERS);
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref(RefNames.REFS_GROUPS + "*").group(REGISTERED_USERS))
+ .add(allow(Permission.PUSH).ref(RefNames.REFS_GROUPS + "*").group(REGISTERED_USERS))
+ .update();
assertCreateFails(
BranchNameKey.create(allUsers, RefNames.refsGroups(AccountGroup.uuid("foo"))),
RefNames.refsGroups(adminGroupUuid()),
@@ -130,11 +147,19 @@
}
private void blockCreateReference() throws Exception {
- block("refs/*", Permission.CREATE, ANONYMOUS_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.CREATE).ref("refs/*").group(ANONYMOUS_USERS))
+ .update();
}
private void grantOwner() throws Exception {
- allow("refs/*", Permission.OWNER, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.OWNER).ref("refs/*").group(REGISTERED_USERS))
+ .update();
}
private BranchApi branch(BranchNameKey branch) throws Exception {
@@ -160,11 +185,10 @@
throws Exception {
BranchInput in = new BranchInput();
in.revision = revision;
+ RestApiException thrown = assertThrows(errType, () -> branch(branch).create(in));
if (errMsg != null) {
- exception.expectMessage(errMsg);
+ assertThat(thrown).hasMessageThat().contains(errMsg);
}
- exception.expect(errType);
- branch(branch).create(in);
}
private void assertCreateFails(BranchNameKey branch, Class<? extends RestApiException> errType)
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java b/javatests/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
index e5bafc7..043bde7 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/CreateProjectIT.java
@@ -19,7 +19,10 @@
import static com.google.common.truth.Truth8.assertThat;
import static com.google.gerrit.acceptance.rest.project.ProjectAssert.assertProjectInfo;
import static com.google.gerrit.acceptance.rest.project.ProjectAssert.assertProjectOwners;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.capabilityKey;
import static com.google.gerrit.server.project.ProjectConfig.PROJECT_CONFIG;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.collect.ImmutableList;
@@ -30,6 +33,7 @@
import com.google.gerrit.acceptance.GerritConfig;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.UseLocalDisk;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.api.projects.ConfigInfo;
@@ -72,6 +76,7 @@
import org.junit.Test;
public class CreateProjectIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Test
@@ -323,7 +328,12 @@
@Test
public void createProjectWithCapability() throws Exception {
- allowGlobalCapabilities(SystemGroupBackend.REGISTERED_USERS, GlobalCapability.CREATE_PROJECT);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(
+ allowCapability(GlobalCapability.CREATE_PROJECT)
+ .group(SystemGroupBackend.REGISTERED_USERS))
+ .update();
try {
requestScopeOperations.setApiUser(user.id());
ProjectInput in = new ProjectInput();
@@ -331,8 +341,12 @@
ProjectInfo p = gApi.projects().create(in).get();
assertThat(p.name).isEqualTo(in.name);
} finally {
- removeGlobalCapabilities(
- SystemGroupBackend.REGISTERED_USERS, GlobalCapability.CREATE_PROJECT);
+ projectOperations
+ .allProjectsForUpdate()
+ .remove(
+ capabilityKey(GlobalCapability.CREATE_PROJECT)
+ .group(SystemGroupBackend.REGISTERED_USERS))
+ .update();
}
}
@@ -355,7 +369,12 @@
public void createProjectWithCreateProjectCapabilityAndParentNotVisible() throws Exception {
Project parent = projectCache.get(allProjects).getProject();
parent.setState(com.google.gerrit.extensions.client.ProjectState.HIDDEN);
- allowGlobalCapabilities(SystemGroupBackend.REGISTERED_USERS, GlobalCapability.CREATE_PROJECT);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(
+ allowCapability(GlobalCapability.CREATE_PROJECT)
+ .group(SystemGroupBackend.REGISTERED_USERS))
+ .update();
try {
requestScopeOperations.setApiUser(user.id());
ProjectInput in = new ProjectInput();
@@ -364,8 +383,12 @@
assertThat(p.name).isEqualTo(in.name);
} finally {
parent.setState(com.google.gerrit.extensions.client.ProjectState.ACTIVE);
- removeGlobalCapabilities(
- SystemGroupBackend.REGISTERED_USERS, GlobalCapability.CREATE_PROJECT);
+ projectOperations
+ .allProjectsForUpdate()
+ .remove(
+ capabilityKey(GlobalCapability.CREATE_PROJECT)
+ .group(SystemGroupBackend.REGISTERED_USERS))
+ .update();
}
}
@@ -469,13 +492,12 @@
private void assertCreateFails(ProjectInput in, Class<? extends RestApiException> errType)
throws Exception {
- exception.expect(errType);
- gApi.projects().create(in);
+ assertThrows(errType, () -> gApi.projects().create(in));
}
private Optional<String> readProjectConfig(String projectName) throws Exception {
- try (Repository repo = repoManager.openRepository(Project.nameKey(projectName))) {
- TestRepository<?> tr = new TestRepository<>(repo);
+ try (Repository repo = repoManager.openRepository(Project.nameKey(projectName));
+ TestRepository<Repository> tr = new TestRepository<>(repo)) {
RevWalk rw = tr.getRevWalk();
Ref ref = repo.exactRef(RefNames.REFS_CONFIG);
if (ref == null) {
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/DeleteBranchIT.java b/javatests/com/google/gerrit/acceptance/rest/project/DeleteBranchIT.java
index 557ffe7..c44c11a 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/DeleteBranchIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/DeleteBranchIT.java
@@ -15,8 +15,11 @@
package com.google.gerrit.acceptance.rest.project;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.eclipse.jgit.lib.Constants.R_HEADS;
import com.google.gerrit.acceptance.AbstractDaemonTest;
@@ -121,8 +124,12 @@
@Test
public void deleteMetaBranch() throws Exception {
String metaRef = RefNames.REFS_META + "foo";
- allow(metaRef, Permission.CREATE, REGISTERED_USERS);
- allow(metaRef, Permission.PUSH, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref(metaRef).group(REGISTERED_USERS))
+ .add(allow(Permission.PUSH).ref(metaRef).group(REGISTERED_USERS))
+ .update();
BranchNameKey metaBranch = BranchNameKey.create(project, metaRef);
branch(metaBranch).create(new BranchInput());
@@ -133,38 +140,68 @@
@Test
public void deleteUserBranch_Conflict() throws Exception {
- allow(allUsers, RefNames.REFS_USERS + "*", Permission.CREATE, REGISTERED_USERS);
- allow(allUsers, RefNames.REFS_USERS + "*", Permission.PUSH, REGISTERED_USERS);
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref(RefNames.REFS_USERS + "*").group(REGISTERED_USERS))
+ .add(allow(Permission.PUSH).ref(RefNames.REFS_USERS + "*").group(REGISTERED_USERS))
+ .update();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Not allowed to delete user branch.");
- branch(BranchNameKey.create(allUsers, RefNames.refsUsers(admin.id()))).delete();
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () -> branch(BranchNameKey.create(allUsers, RefNames.refsUsers(admin.id()))).delete());
+ assertThat(thrown).hasMessageThat().contains("Not allowed to delete user branch.");
}
@Test
public void deleteGroupBranch_Conflict() throws Exception {
- allow(allUsers, RefNames.REFS_GROUPS + "*", Permission.CREATE, REGISTERED_USERS);
- allow(allUsers, RefNames.REFS_GROUPS + "*", Permission.PUSH, REGISTERED_USERS);
+ projectOperations
+ .project(allUsers)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref(RefNames.REFS_GROUPS + "*").group(REGISTERED_USERS))
+ .add(allow(Permission.PUSH).ref(RefNames.REFS_GROUPS + "*").group(REGISTERED_USERS))
+ .update();
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Not allowed to delete group branch.");
- branch(BranchNameKey.create(allUsers, RefNames.refsGroups(adminGroupUuid()))).delete();
+ ResourceConflictException thrown =
+ assertThrows(
+ ResourceConflictException.class,
+ () ->
+ branch(BranchNameKey.create(allUsers, RefNames.refsGroups(adminGroupUuid())))
+ .delete());
+ assertThat(thrown).hasMessageThat().contains("Not allowed to delete group branch.");
}
private void blockForcePush() throws Exception {
- block("refs/heads/*", Permission.PUSH, ANONYMOUS_USERS).setForce(true);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS).force(true))
+ .update();
}
private void grantForcePush() throws Exception {
- grant(project, "refs/heads/*", Permission.PUSH, true, ANONYMOUS_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS).force(true))
+ .update();
}
private void grantDelete() throws Exception {
- allow("refs/*", Permission.DELETE, ANONYMOUS_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.DELETE).ref("refs/*").group(ANONYMOUS_USERS))
+ .update();
}
private void grantOwner() throws Exception {
- allow("refs/*", Permission.OWNER, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.OWNER).ref("refs/*").group(REGISTERED_USERS))
+ .update();
}
private BranchApi branch(BranchNameKey branch) throws Exception {
@@ -179,8 +216,7 @@
+ "/branches/"
+ IdString.fromDecoded(ref).encoded());
r.assertNoContent();
- exception.expect(ResourceNotFoundException.class);
- branch(branch).get();
+ assertThrows(ResourceNotFoundException.class, () -> branch(branch).get());
}
private void assertDeleteSucceeds(BranchNameKey branch) throws Exception {
@@ -189,14 +225,12 @@
branch(branch).delete();
eventRecorder.assertRefUpdatedEvents(
project.get(), branch.branch(), null, branchRev, branchRev, null);
- exception.expect(ResourceNotFoundException.class);
- branch(branch).get();
+ assertThrows(ResourceNotFoundException.class, () -> branch(branch).get());
}
private void assertDeleteForbidden(BranchNameKey branch) throws Exception {
assertThat(branch(branch).get().canDelete).isNull();
- exception.expect(AuthException.class);
- exception.expectMessage("not permitted: delete");
- branch(branch).delete();
+ AuthException thrown = assertThrows(AuthException.class, () -> branch(branch).delete());
+ assertThat(thrown).hasMessageThat().contains("not permitted: delete");
}
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/DeleteBranchesIT.java b/javatests/com/google/gerrit/acceptance/rest/project/DeleteBranchesIT.java
index 47b6a78..523b711 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/DeleteBranchesIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/DeleteBranchesIT.java
@@ -15,7 +15,9 @@
package com.google.gerrit.acceptance.rest.project;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.toList;
import static org.eclipse.jgit.lib.Constants.R_HEADS;
import static org.eclipse.jgit.lib.Constants.R_REFS;
@@ -24,6 +26,7 @@
import com.google.common.collect.Lists;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.projects.BranchInput;
@@ -46,12 +49,17 @@
private static final ImmutableList<String> BRANCHES =
ImmutableList.of("refs/heads/test-1", "refs/heads/test-2", "test-3", "refs/meta/foo");
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Before
public void setUp() throws Exception {
- allow("refs/*", Permission.CREATE, REGISTERED_USERS);
- allow("refs/*", Permission.PUSH, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref("refs/*").group(REGISTERED_USERS))
+ .add(allow(Permission.PUSH).ref("refs/*").group(REGISTERED_USERS))
+ .update();
for (String name : BRANCHES) {
project().branch(name).create(new BranchInput());
}
@@ -75,12 +83,8 @@
DeleteBranchesInput input = new DeleteBranchesInput();
input.branches = branchToDelete;
requestScopeOperations.setApiUser(user.id());
- try {
- project().deleteBranches(input);
- fail("Expected AuthException");
- } catch (AuthException e) {
- assertThat(e).hasMessageThat().isEqualTo("not permitted: delete on refs/heads/test-1");
- }
+ AuthException thrown = assertThrows(AuthException.class, () -> project().deleteBranches(input));
+ assertThat(thrown).hasMessageThat().isEqualTo("not permitted: delete on refs/heads/test-1");
requestScopeOperations.setApiUser(admin.id());
assertBranches(BRANCHES);
}
@@ -90,12 +94,9 @@
DeleteBranchesInput input = new DeleteBranchesInput();
input.branches = BRANCHES;
requestScopeOperations.setApiUser(user.id());
- try {
- project().deleteBranches(input);
- fail("Expected ResourceConflictException");
- } catch (ResourceConflictException e) {
- assertThat(e).hasMessageThat().isEqualTo(errorMessageForBranches(BRANCHES));
- }
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> project().deleteBranches(input));
+ assertThat(thrown).hasMessageThat().isEqualTo(errorMessageForBranches(BRANCHES));
requestScopeOperations.setApiUser(admin.id());
assertBranches(BRANCHES);
}
@@ -106,14 +107,11 @@
List<String> branches = Lists.newArrayList(BRANCHES);
branches.add("refs/heads/does-not-exist");
input.branches = branches;
- try {
- project().deleteBranches(input);
- fail("Expected ResourceConflictException");
- } catch (ResourceConflictException e) {
- assertThat(e)
- .hasMessageThat()
- .isEqualTo(errorMessageForBranches(ImmutableList.of("refs/heads/does-not-exist")));
- }
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> project().deleteBranches(input));
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo(errorMessageForBranches(ImmutableList.of("refs/heads/does-not-exist")));
assertBranchesDeleted(BRANCHES);
}
@@ -125,40 +123,37 @@
List<String> branches = Lists.newArrayList("refs/heads/does-not-exist");
branches.addAll(BRANCHES);
input.branches = branches;
- try {
- project().deleteBranches(input);
- fail("Expected ResourceConflictException");
- } catch (ResourceConflictException e) {
- assertThat(e)
- .hasMessageThat()
- .isEqualTo(errorMessageForBranches(ImmutableList.of("refs/heads/does-not-exist")));
- }
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> project().deleteBranches(input));
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo(errorMessageForBranches(ImmutableList.of("refs/heads/does-not-exist")));
assertBranchesDeleted(BRANCHES);
}
@Test
public void missingInput() throws Exception {
DeleteBranchesInput input = null;
- exception.expect(BadRequestException.class);
- exception.expectMessage("branches must be specified");
- project().deleteBranches(input);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> project().deleteBranches(input));
+ assertThat(thrown).hasMessageThat().contains("branches must be specified");
}
@Test
public void missingBranchList() throws Exception {
DeleteBranchesInput input = new DeleteBranchesInput();
- exception.expect(BadRequestException.class);
- exception.expectMessage("branches must be specified");
- project().deleteBranches(input);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> project().deleteBranches(input));
+ assertThat(thrown).hasMessageThat().contains("branches must be specified");
}
@Test
public void emptyBranchList() throws Exception {
DeleteBranchesInput input = new DeleteBranchesInput();
input.branches = Lists.newArrayList();
- exception.expect(BadRequestException.class);
- exception.expectMessage("branches must be specified");
- project().deleteBranches(input);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> project().deleteBranches(input));
+ assertThat(thrown).hasMessageThat().contains("branches must be specified");
}
private String errorMessageForBranches(List<String> branches) {
@@ -176,7 +171,7 @@
private HashMap<String, RevCommit> initialRevisions(List<String> branches) throws Exception {
HashMap<String, RevCommit> result = new HashMap<>();
for (String branch : branches) {
- result.put(branch, getRemoteHead(project, branch));
+ result.put(branch, projectOperations.project(project).getHead(branch));
}
return result;
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/DeleteTagIT.java b/javatests/com/google/gerrit/acceptance/rest/project/DeleteTagIT.java
index 07bb2b1..9770031 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/DeleteTagIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/DeleteTagIT.java
@@ -15,12 +15,16 @@
package com.google.gerrit.acceptance.rest.project;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.eclipse.jgit.lib.Constants.R_TAGS;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.RestResponse;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.projects.TagApi;
@@ -35,6 +39,7 @@
public class DeleteTagIT extends AbstractDaemonTest {
private static final String TAG = "refs/tags/test";
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Before
@@ -97,19 +102,35 @@
}
private void blockForcePush() throws Exception {
- block("refs/tags/*", Permission.PUSH, ANONYMOUS_USERS).setForce(true);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.PUSH).ref("refs/tags/*").group(ANONYMOUS_USERS).force(true))
+ .update();
}
private void grantForcePush() throws Exception {
- grant(project, "refs/tags/*", Permission.PUSH, true, ANONYMOUS_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.PUSH).ref("refs/tags/*").group(ANONYMOUS_USERS).force(true))
+ .update();
}
private void grantDelete() throws Exception {
- allow("refs/tags/*", Permission.DELETE, ANONYMOUS_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.DELETE).ref("refs/tags/*").group(ANONYMOUS_USERS))
+ .update();
}
private void grantOwner() throws Exception {
- allow("refs/tags/*", Permission.OWNER, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.OWNER).ref("refs/tags/*").group(REGISTERED_USERS))
+ .update();
}
private TagApi tag() throws Exception {
@@ -122,14 +143,12 @@
String tagRev = tagInfo.revision;
tag().delete();
eventRecorder.assertRefUpdatedEvents(project.get(), TAG, null, tagRev, tagRev, null);
- exception.expect(ResourceNotFoundException.class);
- tag().get();
+ assertThrows(ResourceNotFoundException.class, () -> tag().get());
}
private void assertDeleteForbidden() throws Exception {
assertThat(tag().get().canDelete).isNull();
- exception.expect(AuthException.class);
- exception.expectMessage("not permitted: delete");
- tag().delete();
+ AuthException thrown = assertThrows(AuthException.class, () -> tag().delete());
+ assertThat(thrown).hasMessageThat().contains("not permitted: delete");
}
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/DeleteTagsIT.java b/javatests/com/google/gerrit/acceptance/rest/project/DeleteTagsIT.java
index fae9d00..46e2345 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/DeleteTagsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/DeleteTagsIT.java
@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance.rest.project;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.toList;
import static org.eclipse.jgit.lib.Constants.R_TAGS;
@@ -23,6 +24,7 @@
import com.google.common.collect.Lists;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.extensions.api.projects.DeleteTagsInput;
import com.google.gerrit.extensions.api.projects.ProjectApi;
@@ -41,6 +43,7 @@
private static final ImmutableList<String> TAGS =
ImmutableList.of("refs/tags/test-1", "refs/tags/test-2", "refs/tags/test-3", "test-4");
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Before
@@ -66,12 +69,9 @@
DeleteTagsInput input = new DeleteTagsInput();
input.tags = TAGS;
requestScopeOperations.setApiUser(user.id());
- try {
- project().deleteTags(input);
- fail("Expected ResourceConflictException");
- } catch (ResourceConflictException e) {
- assertThat(e).hasMessageThat().isEqualTo(errorMessageForTags(TAGS));
- }
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> project().deleteTags(input));
+ assertThat(thrown).hasMessageThat().isEqualTo(errorMessageForTags(TAGS));
requestScopeOperations.setApiUser(admin.id());
assertTags(TAGS);
}
@@ -82,14 +82,11 @@
List<String> tags = Lists.newArrayList(TAGS);
tags.add("refs/tags/does-not-exist");
input.tags = tags;
- try {
- project().deleteTags(input);
- fail("Expected ResourceConflictException");
- } catch (ResourceConflictException e) {
- assertThat(e)
- .hasMessageThat()
- .isEqualTo(errorMessageForTags(ImmutableList.of("refs/tags/does-not-exist")));
- }
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> project().deleteTags(input));
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo(errorMessageForTags(ImmutableList.of("refs/tags/does-not-exist")));
assertTagsDeleted();
}
@@ -101,14 +98,11 @@
List<String> tags = Lists.newArrayList("refs/tags/does-not-exist");
tags.addAll(TAGS);
input.tags = tags;
- try {
- project().deleteTags(input);
- fail("Expected ResourceConflictException");
- } catch (ResourceConflictException e) {
- assertThat(e)
- .hasMessageThat()
- .isEqualTo(errorMessageForTags(ImmutableList.of("refs/tags/does-not-exist")));
- }
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> project().deleteTags(input));
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo(errorMessageForTags(ImmutableList.of("refs/tags/does-not-exist")));
assertTagsDeleted();
}
@@ -128,7 +122,7 @@
HashMap<String, RevCommit> result = new HashMap<>();
for (String tag : tags) {
String ref = prefixRef(tag);
- result.put(ref, getRemoteHead(project, ref));
+ result.put(ref, projectOperations.project(project).getHead(ref));
}
return result;
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/FileBranchIT.java b/javatests/com/google/gerrit/acceptance/rest/project/FileBranchIT.java
index ad8cf03..e63b28bc 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/FileBranchIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/FileBranchIT.java
@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance.rest.project;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
@@ -45,9 +46,9 @@
assertThat(content.asString()).isEqualTo(PushOneCommit.FILE_CONTENT);
}
- @Test(expected = ResourceNotFoundException.class)
+ @Test
public void getNonExistingFile() throws Exception {
- branch().file("does-not-exist");
+ assertThrows(ResourceNotFoundException.class, () -> branch().file("does-not-exist"));
}
private BranchApi branch() throws Exception {
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/GetChildProjectIT.java b/javatests/com/google/gerrit/acceptance/rest/project/GetChildProjectIT.java
index d736578..7e45e02 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/GetChildProjectIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/GetChildProjectIT.java
@@ -14,7 +14,9 @@
package com.google.gerrit.acceptance.rest.project;
+import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.rest.project.ProjectAssert.assertProjectInfo;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
@@ -69,8 +71,10 @@
}
private void assertChildNotFound(Project.NameKey parent, String child) throws Exception {
- exception.expect(ResourceNotFoundException.class);
- exception.expectMessage(child);
- gApi.projects().name(parent.get()).child(child).get();
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.projects().name(parent.get()).child(child).get());
+ assertThat(thrown).hasMessageThat().contains(child);
}
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/GetCommitIT.java b/javatests/com/google/gerrit/acceptance/rest/project/GetCommitIT.java
index 18c706b..f9011c7 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/GetCommitIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/GetCommitIT.java
@@ -15,14 +15,18 @@
package com.google.gerrit.acceptance.rest.project;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
+import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
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.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.common.CommitInfo;
+import com.google.inject.Inject;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
@@ -32,12 +36,18 @@
import org.junit.Test;
public class GetCommitIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
+
private TestRepository<Repository> repo;
@Before
public void setUp() throws Exception {
repo = GitUtil.newTestRepository(repoManager.openRepository(project));
- blockRead("refs/*");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
}
@After
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/GetProjectIT.java b/javatests/com/google/gerrit/acceptance/rest/project/GetProjectIT.java
index 989050c..e9aa589 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/GetProjectIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/GetProjectIT.java
@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance.rest.project;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.acceptance.AbstractDaemonTest;
@@ -54,8 +55,9 @@
assertThat(p.name).isEqualTo(name);
}
- @Test(expected = ResourceNotFoundException.class)
+ @Test
public void getProjectNotExisting() throws Exception {
- gApi.projects().name("does-not-exist").get();
+ assertThrows(
+ ResourceNotFoundException.class, () -> gApi.projects().name("does-not-exist").get());
}
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/ListBranchesIT.java b/javatests/com/google/gerrit/acceptance/rest/project/ListBranchesIT.java
index ec1c708..a797b98 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/ListBranchesIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/ListBranchesIT.java
@@ -15,12 +15,17 @@
package com.google.gerrit.acceptance.rest.project;
import static com.google.gerrit.acceptance.rest.project.RefAssert.assertRefs;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
+import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.TestProjectInput;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
+import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.projects.BranchInfo;
import com.google.gerrit.extensions.api.projects.ProjectApi.ListRefsRequest;
import com.google.gerrit.extensions.restapi.BadRequestException;
@@ -31,20 +36,27 @@
@NoHttpd
public class ListBranchesIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Test
public void listBranchesOfNonExistingProject_NotFound() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- gApi.projects().name("non-existing").branches().get();
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.projects().name("non-existing").branches().get());
}
@Test
public void listBranchesOfNonVisibleProject_NotFound() throws Exception {
- blockRead("refs/*");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
- exception.expect(ResourceNotFoundException.class);
- gApi.projects().name(project.get()).branches().get();
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.projects().name(project.get()).branches().get());
}
@Test
@@ -59,7 +71,7 @@
public void listBranches() throws Exception {
String master = pushTo("refs/heads/master").getCommit().name();
String dev = pushTo("refs/heads/dev").getCommit().name();
- String refsConfig = getRemoteHead(project, RefNames.REFS_CONFIG).name();
+ String refsConfig = projectOperations.project(project).getHead(RefNames.REFS_CONFIG).name();
assertRefs(
ImmutableList.of(
branch("HEAD", "master", false),
@@ -71,7 +83,11 @@
@Test
public void listBranchesSomeHidden() throws Exception {
- blockRead("refs/heads/dev");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.READ).ref("refs/heads/dev").group(REGISTERED_USERS))
+ .update();
String master = pushTo("refs/heads/master").getCommit().name();
pushTo("refs/heads/dev");
requestScopeOperations.setApiUser(user.id());
@@ -84,7 +100,11 @@
@Test
public void listBranchesHeadHidden() throws Exception {
- blockRead("refs/heads/master");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.READ).ref("refs/heads/master").group(REGISTERED_USERS))
+ .update();
pushTo("refs/heads/master");
String dev = pushTo("refs/heads/dev").getCommit().name();
requestScopeOperations.setApiUser(user.id());
@@ -96,7 +116,10 @@
public void listBranchesUsingPagination() throws Exception {
BranchInfo head = branch("HEAD", "master", false);
BranchInfo refsConfig =
- branch(RefNames.REFS_CONFIG, getRemoteHead(project, RefNames.REFS_CONFIG).name(), false);
+ branch(
+ RefNames.REFS_CONFIG,
+ projectOperations.project(project).getHead(RefNames.REFS_CONFIG).name(),
+ false);
BranchInfo master =
branch("refs/heads/master", pushTo("refs/heads/master").getCommit().getName(), false);
BranchInfo branch1 =
@@ -170,11 +193,6 @@
}
private void assertBadRequest(ListRefsRequest<BranchInfo> req) throws Exception {
- try {
- req.get();
- fail("Expected BadRequestException");
- } catch (BadRequestException e) {
- // Expected
- }
+ assertThrows(BadRequestException.class, () -> req.get());
}
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/ListChildProjectsIT.java b/javatests/com/google/gerrit/acceptance/rest/project/ListChildProjectsIT.java
index 7746820..0fdeba6 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/ListChildProjectsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/ListChildProjectsIT.java
@@ -14,7 +14,9 @@
package com.google.gerrit.acceptance.rest.project;
+import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.rest.project.ProjectAssert.assertThatNameList;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
@@ -31,9 +33,11 @@
@Test
public void listChildrenOfNonExistingProject_NotFound() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- exception.expectMessage("non-existing");
- gApi.projects().name(name("non-existing")).child("children");
+ ResourceNotFoundException thrown =
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.projects().name(name("non-existing")).child("children"));
+ assertThat(thrown).hasMessageThat().contains("non-existing");
}
@Test
@@ -47,7 +51,7 @@
Project.NameKey child1_1 = projectOperations.newProject().parent(child1).create();
Project.NameKey child1_2 = projectOperations.newProject().parent(child1).create();
- assertThatNameList(gApi.projects().name(child1.get()).children()).isOrdered();
+ assertThatNameList(gApi.projects().name(child1.get()).children()).isInOrder();
assertThatNameList(gApi.projects().name(child1.get()).children())
.containsExactly(child1_1, child1_2);
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/ListProjectsIT.java b/javatests/com/google/gerrit/acceptance/rest/project/ListProjectsIT.java
index f29069c..caef689 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/ListProjectsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/ListProjectsIT.java
@@ -16,7 +16,10 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.rest.project.ProjectAssert.assertThatNameList;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.stream.Collectors.toList;
import com.google.common.base.Splitter;
@@ -40,7 +43,6 @@
import com.google.gerrit.json.OutputFormat;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.project.ProjectCacheImpl;
-import com.google.gerrit.server.project.testing.Util;
import com.google.gerrit.server.restapi.project.ListProjects;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
@@ -64,7 +66,7 @@
Project.NameKey someProject = projectOperations.newProject().create();
assertThatNameList(gApi.projects().list().get())
.containsExactly(allProjects, allUsers, project, someProject);
- assertThatNameList(gApi.projects().list().get()).isOrdered();
+ assertThatNameList(gApi.projects().list().get()).isInOrder();
}
@Test
@@ -72,10 +74,11 @@
requestScopeOperations.setApiUser(user.id());
assertThatNameList(gApi.projects().list().get()).contains(project);
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.block(u.getConfig(), Permission.READ, REGISTERED_USERS, "refs/*");
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
assertThatNameList(gApi.projects().list().get()).doesNotContain(project);
}
@@ -147,7 +150,9 @@
listProjects.displayToStream(displayOut);
List<String> lines =
- Splitter.on("\n").omitEmptyStrings().splitToList(new String(displayOut.toByteArray()));
+ Splitter.on("\n")
+ .omitEmptyStrings()
+ .splitToList(new String(displayOut.toByteArray(), UTF_8));
assertThat(lines).isEqualTo(testProjects);
}
}
@@ -176,7 +181,7 @@
listProjects.setFormat(jsonFormat);
listProjects.displayToStream(displayOut);
- String projectsJsonOutput = new String(displayOut.toByteArray());
+ String projectsJsonOutput = new String(displayOut.toByteArray(), UTF_8);
Gson gson = jsonFormat.newGson();
Set<String> projectsJsonNames = gson.fromJson(projectsJsonOutput, JsonObject.class).keySet();
@@ -334,11 +339,6 @@
}
private void assertBadRequest(ListRequest req) throws Exception {
- try {
- req.get();
- fail("Expected BadRequestException");
- } catch (BadRequestException expected) {
- // Expected.
- }
+ assertThrows(BadRequestException.class, () -> req.get());
}
}
diff --git a/javatests/com/google/gerrit/acceptance/rest/project/TagsIT.java b/javatests/com/google/gerrit/acceptance/rest/project/TagsIT.java
index 0165ead..3d1a148 100644
--- a/javatests/com/google/gerrit/acceptance/rest/project/TagsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/project/TagsIT.java
@@ -15,7 +15,10 @@
package com.google.gerrit.acceptance.rest.project;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.eclipse.jgit.lib.Constants.R_TAGS;
import com.google.common.collect.FluentIterable;
@@ -23,6 +26,7 @@
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.projects.ProjectApi.ListRefsRequest;
@@ -58,33 +62,44 @@
+ "=XFeC\n"
+ "-----END PGP SIGNATURE-----";
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Test
public void listTagsOfNonExistingProject() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- gApi.projects().name("does-not-exist").tags().get();
+ assertThrows(
+ ResourceNotFoundException.class, () -> gApi.projects().name("does-not-exist").tags().get());
}
@Test
public void getTagOfNonExistingProject() throws Exception {
- exception.expect(ResourceNotFoundException.class);
- gApi.projects().name("does-not-exist").tag("tag").get();
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.projects().name("does-not-exist").tag("tag").get());
}
@Test
public void listTagsOfNonVisibleProject() throws Exception {
- blockRead("refs/*");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
requestScopeOperations.setApiUser(user.id());
- exception.expect(ResourceNotFoundException.class);
- gApi.projects().name(project.get()).tags().get();
+ assertThrows(
+ ResourceNotFoundException.class, () -> gApi.projects().name(project.get()).tags().get());
}
@Test
public void getTagOfNonVisibleProject() throws Exception {
- blockRead("refs/*");
- exception.expect(ResourceNotFoundException.class);
- gApi.projects().name(project.get()).tag("tag").get();
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> gApi.projects().name(project.get()).tag("tag").get());
}
@Test
@@ -159,7 +174,11 @@
assertThat(tags.get(1).ref).isEqualTo(R_TAGS + tag2.ref);
assertThat(tags.get(1).revision).isEqualTo(tag2.revision);
- blockRead("refs/heads/hidden");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.READ).ref("refs/heads/hidden").group(REGISTERED_USERS))
+ .update();
tags = getTags().get();
assertThat(tags).hasSize(1);
assertThat(tags.get(0).ref).isEqualTo(R_TAGS + tag1.ref);
@@ -247,30 +266,38 @@
assertThat(result.ref).isEqualTo(R_TAGS + "test");
input.ref = "refs/tags/test";
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("tag \"" + R_TAGS + "test\" already exists");
- tag(input.ref).create(input);
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> tag(input.ref).create(input));
+ assertThat(thrown).hasMessageThat().contains("tag \"" + R_TAGS + "test\" already exists");
}
@Test
public void createTagNotAllowed() throws Exception {
- block(R_TAGS + "*", Permission.CREATE, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.CREATE).ref(R_TAGS + "*").group(REGISTERED_USERS))
+ .update();
TagInput input = new TagInput();
input.ref = "test";
- exception.expect(AuthException.class);
- exception.expectMessage("not permitted: create");
- tag(input.ref).create(input);
+ AuthException thrown = assertThrows(AuthException.class, () -> tag(input.ref).create(input));
+ assertThat(thrown).hasMessageThat().contains("not permitted: create");
}
@Test
public void createAnnotatedTagNotAllowed() throws Exception {
- block(R_TAGS + "*", Permission.CREATE_TAG, REGISTERED_USERS);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(block(Permission.CREATE_TAG).ref(R_TAGS + "*").group(REGISTERED_USERS))
+ .update();
TagInput input = new TagInput();
input.ref = "test";
input.message = "annotation";
- exception.expect(AuthException.class);
- exception.expectMessage("Cannot create annotated tag \"" + R_TAGS + "test\"");
- tag(input.ref).create(input);
+ AuthException thrown = assertThrows(AuthException.class, () -> tag(input.ref).create(input));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Cannot create annotated tag \"" + R_TAGS + "test\"");
}
@Test
@@ -278,9 +305,9 @@
TagInput input = new TagInput();
input.ref = "test";
input.message = SIGNED_ANNOTATION;
- exception.expect(MethodNotAllowedException.class);
- exception.expectMessage("Cannot create signed tag \"" + R_TAGS + "test\"");
- tag(input.ref).create(input);
+ MethodNotAllowedException thrown =
+ assertThrows(MethodNotAllowedException.class, () -> tag(input.ref).create(input));
+ assertThat(thrown).hasMessageThat().contains("Cannot create signed tag \"" + R_TAGS + "test\"");
}
@Test
@@ -288,9 +315,9 @@
TagInput input = new TagInput();
input.ref = "test";
- exception.expect(BadRequestException.class);
- exception.expectMessage("ref must match URL");
- tag("TEST").create(input);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> tag("TEST").create(input));
+ assertThat(thrown).hasMessageThat().contains("ref must match URL");
}
@Test
@@ -300,9 +327,9 @@
TagInput input = new TagInput();
input.ref = "refs/heads/test";
- exception.expect(BadRequestException.class);
- exception.expectMessage("invalid tag name \"" + input.ref + "\"");
- tag(input.ref).create(input);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> tag(input.ref).create(input));
+ assertThat(thrown).hasMessageThat().contains("invalid tag name \"" + input.ref + "\"");
}
@Test
@@ -312,9 +339,9 @@
TagInput input = new TagInput();
input.ref = "//";
- exception.expect(BadRequestException.class);
- exception.expectMessage("invalid tag name \"refs/tags/\"");
- tag(input.ref).create(input);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> tag(input.ref).create(input));
+ assertThat(thrown).hasMessageThat().contains("invalid tag name \"refs/tags/\"");
}
@Test
@@ -325,9 +352,9 @@
input.ref = "test";
input.revision = "abcdefg";
- exception.expect(BadRequestException.class);
- exception.expectMessage("Invalid base revision");
- tag(input.ref).create(input);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> tag(input.ref).create(input));
+ assertThat(thrown).hasMessageThat().contains("Invalid base revision");
}
private void assertTagList(FluentIterable<String> expected, List<TagInfo> actual)
@@ -367,18 +394,17 @@
}
private void assertBadRequest(ListRefsRequest<TagInfo> req) throws Exception {
- try {
- req.get();
- fail("Expected BadRequestException");
- } catch (BadRequestException e) {
- // Expected
- }
+ assertThrows(BadRequestException.class, () -> req.get());
}
private void grantTagPermissions() throws Exception {
- grant(project, R_TAGS + "*", Permission.CREATE);
- grant(project, R_TAGS + "", Permission.DELETE);
- grant(project, R_TAGS + "*", Permission.CREATE_TAG);
- grant(project, R_TAGS + "*", Permission.CREATE_SIGNED_TAG);
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.CREATE).ref(R_TAGS + "*").group(adminGroupUuid()))
+ .add(allow(Permission.DELETE).ref(R_TAGS + "").group(adminGroupUuid()))
+ .add(allow(Permission.CREATE_TAG).ref(R_TAGS + "*").group(adminGroupUuid()))
+ .add(allow(Permission.CREATE_SIGNED_TAG).ref(R_TAGS + "*").group(adminGroupUuid()))
+ .update();
}
}
diff --git a/javatests/com/google/gerrit/acceptance/server/account/AccountResolverIT.java b/javatests/com/google/gerrit/acceptance/server/account/AccountResolverIT.java
index 2832ee5..4aebbad 100644
--- a/javatests/com/google/gerrit/acceptance/server/account/AccountResolverIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/account/AccountResolverIT.java
@@ -16,8 +16,8 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
-import static com.google.common.truth.Truth.assert_;
import static com.google.common.truth.Truth8.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
@@ -82,26 +82,16 @@
}
private void checkBySelfFails() throws Exception {
- Result result = resolveAsResult("self");
- assertThat(result.asIdSet()).isEmpty();
- assertThat(result.isSelf()).isTrue();
- try {
- result.asUnique();
- assert_().fail("expected UnresolvableAccountException");
- } catch (UnresolvableAccountException e) {
- assertThat(e).hasMessageThat().isEqualTo("Resolving account 'self' requires login");
- assertThat(e.isSelf()).isTrue();
- }
-
- result = resolveAsResult("me");
- assertThat(result.asIdSet()).isEmpty();
- assertThat(result.isSelf()).isTrue();
- try {
- result.asUnique();
- assert_().fail("expected UnresolvableAccountException");
- } catch (UnresolvableAccountException e) {
- assertThat(e).hasMessageThat().isEqualTo("Resolving account 'me' requires login");
- assertThat(e.isSelf()).isTrue();
+ for (String input : ImmutableList.of("self", "me")) {
+ Result result = resolveAsResult(input);
+ assertThat(result.asIdSet()).isEmpty();
+ assertThat(result.isSelf()).isTrue();
+ UnresolvableAccountException thrown =
+ assertThrows(UnresolvableAccountException.class, () -> result.asUnique());
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo(String.format("Resolving account '%s' requires login", input));
+ assertThat(thrown.isSelf()).isTrue();
}
}
@@ -268,21 +258,18 @@
for (String input : inputs) {
Result result = accountResolver.resolve(input);
assertWithMessage("results for %s (inactive)", input).that(result.asIdSet()).isEmpty();
- try {
- result.asUnique();
- assert_().fail("expected UnresolvableAccountException");
- } catch (UnresolvableAccountException e) {
- assertThat(e)
- .hasMessageThat()
- .isEqualTo(
- "Account '"
- + input
- + "' only matches inactive accounts. To use an inactive account, retry"
- + " with one of the following exact account IDs:\n"
- + id
- + ": "
- + nameEmail);
- }
+ UnresolvableAccountException thrown =
+ assertThrows(UnresolvableAccountException.class, () -> result.asUnique());
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo(
+ "Account '"
+ + input
+ + "' only matches inactive accounts. To use an inactive account, retry"
+ + " with one of the following exact account IDs:\n"
+ + id
+ + ": "
+ + nameEmail);
assertWithMessage("results by name or email for %s (inactive)", input)
.that(resolveByNameOrEmail(input))
.isEmpty();
diff --git a/javatests/com/google/gerrit/acceptance/server/change/CommentsIT.java b/javatests/com/google/gerrit/acceptance/server/change/CommentsIT.java
index 15dd3fb..a2a6f09 100644
--- a/javatests/com/google/gerrit/acceptance/server/change/CommentsIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/change/CommentsIT.java
@@ -18,10 +18,10 @@
import static com.google.common.truth.Truth8.assertThat;
import static com.google.gerrit.acceptance.PushOneCommit.FILE_NAME;
import static com.google.gerrit.acceptance.PushOneCommit.SUBJECT;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;
-import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
@@ -64,6 +64,7 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.function.Function;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -94,8 +95,9 @@
PushOneCommit.Result r = createChange();
String changeId = r.getChangeId();
String revId = r.getCommit().getName();
- exception.expect(ResourceNotFoundException.class);
- getPublishedComment(changeId, revId, "non-existing");
+ assertThrows(
+ ResourceNotFoundException.class,
+ () -> getPublishedComment(changeId, revId, "non-existing"));
}
@Test
@@ -131,8 +133,7 @@
addDraft(changeId, revId, c4);
Map<String, List<CommentInfo>> result = getDraftComments(changeId, revId);
assertThat(result).hasSize(1);
- assertThat(Lists.transform(result.get(path), infoToDraft(path)))
- .containsExactly(c1, c2, c3, c4);
+ assertThat(result.get(path).stream().map(infoToDraft(path))).containsExactly(c1, c2, c3, c4);
}
}
@@ -233,8 +234,7 @@
revision(r).review(input);
Map<String, List<CommentInfo>> result = getPublishedComments(changeId, revId);
assertThat(result).isNotEmpty();
- assertThat(Lists.transform(result.get(file), infoToInput(file)))
- .containsExactly(c1, c2, c3, c4);
+ assertThat(result.get(file).stream().map(infoToInput(file))).containsExactly(c1, c2, c3, c4);
}
// for the commit message comments on the auto-merge are not possible
@@ -252,7 +252,7 @@
revision(r).review(input);
Map<String, List<CommentInfo>> result = getPublishedComments(changeId, revId);
assertThat(result).isNotEmpty();
- assertThat(Lists.transform(result.get(file), infoToInput(file))).containsExactly(c1, c2, c3);
+ assertThat(result.get(file).stream().map(infoToInput(file))).containsExactly(c1, c2, c3);
}
}
@@ -263,9 +263,11 @@
CommentInput c = newComment(Patch.COMMIT_MSG, Side.PARENT, 0, "comment on auto-merge", false);
input.comments = new HashMap<>();
input.comments.put(Patch.COMMIT_MSG, ImmutableList.of(c));
- exception.expect(BadRequestException.class);
- exception.expectMessage("cannot comment on " + Patch.COMMIT_MSG + " on auto-merge");
- revision(r).review(input);
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> revision(r).review(input));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("cannot comment on " + Patch.COMMIT_MSG + " on auto-merge");
}
@Test
@@ -291,7 +293,7 @@
Map<String, List<CommentInfo>> result = getPublishedComments(changeId, revId);
assertThat(result).isNotEmpty();
List<CommentInfo> actualComments = result.get(file);
- assertThat(Lists.transform(actualComments, infoToInput(file)))
+ assertThat(actualComments.stream().map(infoToInput(file)))
.containsExactlyElementsIn(expectedComments);
}
@@ -338,7 +340,7 @@
Map<String, List<CommentInfo>> result = getDraftComments(changeId, revId);
assertThat(result).isNotEmpty();
List<CommentInfo> actualComments = result.get(file);
- assertThat(Lists.transform(actualComments, infoToDraft(file)))
+ assertThat(actualComments.stream().map(infoToDraft(file)))
.containsExactlyElementsIn(expectedDrafts);
}
@@ -769,8 +771,9 @@
DeleteCommentInput input = new DeleteCommentInput("contains confidential information");
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- gApi.changes().id(result.getChangeId()).current().comment(uuid).delete(input);
+ assertThrows(
+ AuthException.class,
+ () -> gApi.changes().id(result.getChangeId()).current().comment(uuid).delete(input));
}
@Test
diff --git a/javatests/com/google/gerrit/acceptance/server/change/ConsistencyCheckerIT.java b/javatests/com/google/gerrit/acceptance/server/change/ConsistencyCheckerIT.java
index b820f4a..b1a2ed0 100644
--- a/javatests/com/google/gerrit/acceptance/server/change/ConsistencyCheckerIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/change/ConsistencyCheckerIT.java
@@ -131,7 +131,7 @@
assertProblems(
notes,
null,
- problem("Ref missing: " + ps.getId().toRefName()),
+ problem("Ref missing: " + ps.id().toRefName()),
problem("Object missing: patch set 2: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
}
@@ -142,7 +142,7 @@
PatchSet ps = insertMissingPatchSet(notes, rev);
notes = reload(notes);
- String refName = ps.getId().toRefName();
+ String refName = ps.id().toRefName();
assertProblems(
notes,
new FixInput(),
@@ -153,7 +153,7 @@
@Test
public void patchSetRefMissing() throws Exception {
ChangeNotes notes = insertChange();
- serverSideTestRepo.update("refs/other/foo", psUtil.current(notes).getCommitId());
+ serverSideTestRepo.update("refs/other/foo", psUtil.current(notes).commitId());
String refName = notes.getChange().currentPatchSetId().toRefName();
deleteRef(refName);
@@ -163,7 +163,7 @@
@Test
public void patchSetRefMissingWithFix() throws Exception {
ChangeNotes notes = insertChange();
- ObjectId commitId = psUtil.current(notes).getCommitId();
+ ObjectId commitId = psUtil.current(notes).commitId();
serverSideTestRepo.update("refs/other/foo", commitId);
String refName = notes.getChange().currentPatchSetId().toRefName();
deleteRef(refName);
@@ -188,13 +188,13 @@
assertProblems(
notes,
fix,
- problem("Ref missing: " + ps2.getId().toRefName()),
+ problem("Ref missing: " + ps2.id().toRefName()),
problem("Object missing: patch set 2: " + rev2, FIXED, "Deleted patch set"));
notes = reload(notes);
assertThat(notes.getChange().currentPatchSetId().get()).isEqualTo(1);
- assertThat(psUtil.get(notes, ps1.getId())).isNotNull();
- assertThat(psUtil.get(notes, ps2.getId())).isNull();
+ assertThat(psUtil.get(notes, ps1.id())).isNotNull();
+ assertThat(psUtil.get(notes, ps2.id())).isNull();
}
@Test
@@ -217,17 +217,17 @@
assertProblems(
notes,
fix,
- problem("Ref missing: " + ps2.getId().toRefName()),
+ problem("Ref missing: " + ps2.id().toRefName()),
problem("Object missing: patch set 2: " + rev2, FIXED, "Deleted patch set"),
- problem("Ref missing: " + ps4.getId().toRefName()),
+ problem("Ref missing: " + ps4.id().toRefName()),
problem("Object missing: patch set 4: " + rev4, FIXED, "Deleted patch set"));
notes = reload(notes);
assertThat(notes.getChange().currentPatchSetId().get()).isEqualTo(3);
- assertThat(psUtil.get(notes, ps1.getId())).isNotNull();
- assertThat(psUtil.get(notes, ps2.getId())).isNull();
- assertThat(psUtil.get(notes, ps3.getId())).isNotNull();
- assertThat(psUtil.get(notes, ps4.getId())).isNull();
+ assertThat(psUtil.get(notes, ps1.id())).isNotNull();
+ assertThat(psUtil.get(notes, ps2.id())).isNull();
+ assertThat(psUtil.get(notes, ps3.id())).isNotNull();
+ assertThat(psUtil.get(notes, ps4.id())).isNull();
}
@Test
@@ -264,7 +264,7 @@
assertProblems(
notes,
fix,
- problem("Ref missing: " + ps.getId().toRefName()),
+ problem("Ref missing: " + ps.id().toRefName()),
problem(
"Object missing: patch set 1: " + rev,
FIX_FAILED,
@@ -280,13 +280,12 @@
ChangeNotes notes = insertChange();
PatchSet ps1 = psUtil.current(notes);
- notes =
- incrementPatchSet(notes, serverSideTestRepo.getRevWalk().parseCommit(ps1.getCommitId()));
+ notes = incrementPatchSet(notes, serverSideTestRepo.getRevWalk().parseCommit(ps1.commitId()));
assertProblems(
notes,
null,
- problem("Multiple patch sets pointing to " + ps1.getCommitId().name() + ": [1, 2]"));
+ problem("Multiple patch sets pointing to " + ps1.commitId().name() + ": [1, 2]"));
}
@Test
@@ -328,7 +327,7 @@
null,
problem(
"Patch set 1 ("
- + psUtil.current(notes).getCommitId().name()
+ + psUtil.current(notes).commitId().name()
+ ") is not merged into destination ref"
+ " refs/heads/master ("
+ tip.name()
@@ -338,7 +337,7 @@
@Test
public void newChangeIsMerged() throws Exception {
ChangeNotes notes = insertChange();
- ObjectId commitId = psUtil.current(notes).getCommitId();
+ ObjectId commitId = psUtil.current(notes).commitId();
serverSideTestRepo
.branch(notes.getChange().getDest().branch())
.update(serverSideTestRepo.getRevWalk().parseCommit(commitId));
@@ -358,7 +357,7 @@
@Test
public void newChangeIsMergedWithFix() throws Exception {
ChangeNotes notes = insertChange();
- ObjectId commitId = psUtil.current(notes).getCommitId();
+ ObjectId commitId = psUtil.current(notes).commitId();
serverSideTestRepo
.branch(notes.getChange().getDest().branch())
.update(serverSideTestRepo.getRevWalk().parseCommit(commitId));
@@ -384,7 +383,7 @@
@Test
public void extensionApiReturnsUpdatedValueAfterFix() throws Exception {
ChangeNotes notes = insertChange();
- ObjectId commitId = psUtil.current(notes).getCommitId();
+ ObjectId commitId = psUtil.current(notes).commitId();
serverSideTestRepo
.branch(notes.getChange().getDest().branch())
.update(serverSideTestRepo.getRevWalk().parseCommit(commitId));
@@ -399,7 +398,7 @@
@Test
public void expectedMergedCommitIsLatestPatchSet() throws Exception {
ChangeNotes notes = insertChange();
- ObjectId commitId = psUtil.current(notes).getCommitId();
+ ObjectId commitId = psUtil.current(notes).commitId();
serverSideTestRepo
.branch(notes.getChange().getDest().branch())
.update(serverSideTestRepo.getRevWalk().parseCommit(commitId));
@@ -428,7 +427,7 @@
public void expectedMergedCommitNotMergedIntoDestination() throws Exception {
ChangeNotes notes = insertChange();
RevCommit commit =
- serverSideTestRepo.getRevWalk().parseCommit(psUtil.current(notes).getCommitId());
+ serverSideTestRepo.getRevWalk().parseCommit(psUtil.current(notes).commitId());
serverSideTestRepo.branch(notes.getChange().getDest().branch()).update(commit);
FixInput fix = new FixInput();
@@ -451,7 +450,7 @@
ChangeNotes notes = insertChange();
String dest = notes.getChange().getDest().branch();
RevCommit commit =
- serverSideTestRepo.getRevWalk().parseCommit(psUtil.current(notes).getCommitId());
+ serverSideTestRepo.getRevWalk().parseCommit(psUtil.current(notes).commitId());
RevCommit mergedAs =
serverSideTestRepo
@@ -482,7 +481,7 @@
notes = reload(notes);
PatchSet.Id psId2 = PatchSet.id(notes.getChangeId(), 2);
assertThat(notes.getChange().currentPatchSetId()).isEqualTo(psId2);
- assertThat(psUtil.get(notes, psId2).getCommitId()).isEqualTo(mergedAs);
+ assertThat(psUtil.get(notes, psId2).commitId()).isEqualTo(mergedAs);
assertNoProblems(notes, null);
}
@@ -492,7 +491,7 @@
ChangeNotes notes = insertChange();
String dest = notes.getChange().getDest().branch();
RevCommit commit =
- serverSideTestRepo.getRevWalk().parseCommit(psUtil.current(notes).getCommitId());
+ serverSideTestRepo.getRevWalk().parseCommit(psUtil.current(notes).commitId());
RevCommit mergedAs =
serverSideTestRepo
@@ -530,7 +529,7 @@
notes = reload(notes);
PatchSet.Id psId2 = PatchSet.id(notes.getChangeId(), 2);
assertThat(notes.getChange().currentPatchSetId()).isEqualTo(psId2);
- assertThat(psUtil.get(notes, psId2).getCommitId()).isEqualTo(mergedAs);
+ assertThat(psUtil.get(notes, psId2).commitId()).isEqualTo(mergedAs);
assertNoProblems(notes, null);
}
@@ -538,7 +537,7 @@
@Test
public void expectedMergedCommitIsOldPatchSetOfSameChange() throws Exception {
ChangeNotes notes = insertChange();
- ObjectId commitId1 = psUtil.current(notes).getCommitId();
+ ObjectId commitId1 = psUtil.current(notes).commitId();
notes = incrementPatchSet(notes);
PatchSet ps2 = psUtil.current(notes);
serverSideTestRepo
@@ -573,8 +572,8 @@
PatchSet.Id psId3 = PatchSet.id(notes.getChangeId(), 3);
assertThat(notes.getChange().currentPatchSetId()).isEqualTo(psId3);
assertThat(notes.getChange().isMerged()).isTrue();
- assertThat(psUtil.byChangeAsMap(notes).keySet()).containsExactly(ps2.getId(), psId3);
- assertThat(psUtil.get(notes, psId3).getCommitId()).isEqualTo(commitId1);
+ assertThat(psUtil.byChangeAsMap(notes).keySet()).containsExactly(ps2.id(), psId3);
+ assertThat(psUtil.get(notes, psId3).commitId()).isEqualTo(commitId1);
}
@Test
@@ -589,7 +588,7 @@
notes = incrementPatchSet(notes);
PatchSet ps3 = psUtil.current(notes);
- assertThat(ps3.getId().get()).isEqualTo(3);
+ assertThat(ps3.id().get()).isEqualTo(3);
serverSideTestRepo.branch(notes.getChange().getDest().branch()).update(commit2);
@@ -621,9 +620,8 @@
PatchSet.Id psId4 = PatchSet.id(notes.getChangeId(), 4);
assertThat(notes.getChange().currentPatchSetId()).isEqualTo(psId4);
assertThat(notes.getChange().isMerged()).isTrue();
- assertThat(psUtil.byChangeAsMap(notes).keySet())
- .containsExactly(ps1.getId(), ps3.getId(), psId4);
- assertThat(psUtil.get(notes, psId4).getCommitId()).isEqualTo(commit2);
+ assertThat(psUtil.byChangeAsMap(notes).keySet()).containsExactly(ps1.id(), ps3.id(), psId4);
+ assertThat(psUtil.get(notes, psId4).commitId()).isEqualTo(commit2);
}
@Test
@@ -658,8 +656,8 @@
notes = reload(notes);
assertThat(notes.getChange().currentPatchSetId()).isEqualTo(psId2);
assertThat(notes.getChange().isMerged()).isTrue();
- assertThat(psUtil.byChangeAsMap(notes).keySet()).containsExactly(ps1.getId(), psId2);
- assertThat(psUtil.get(notes, psId2).getCommitId()).isEqualTo(commit2);
+ assertThat(psUtil.byChangeAsMap(notes).keySet()).containsExactly(ps1.id(), psId2);
+ assertThat(psUtil.get(notes, psId2).commitId()).isEqualTo(commit2);
}
@Test
@@ -668,7 +666,7 @@
String dest = notes.getChange().getDest().branch();
RevCommit parent = serverSideTestRepo.branch(dest).commit().message("parent").create();
RevCommit commit =
- serverSideTestRepo.getRevWalk().parseCommit(psUtil.current(notes).getCommitId());
+ serverSideTestRepo.getRevWalk().parseCommit(psUtil.current(notes).commitId());
serverSideTestRepo.branch(dest).update(commit);
String badId = "I0000000000000000000000000000000000000000";
@@ -701,19 +699,19 @@
@Test
public void expectedMergedCommitMatchesMultiplePatchSets() throws Exception {
ChangeNotes notes1 = insertChange();
- PatchSet.Id psId1 = psUtil.current(notes1).getId();
+ PatchSet.Id psId1 = psUtil.current(notes1).id();
String dest = notes1.getChange().getDest().branch();
RevCommit commit =
- serverSideTestRepo.getRevWalk().parseCommit(psUtil.current(notes1).getCommitId());
+ serverSideTestRepo.getRevWalk().parseCommit(psUtil.current(notes1).commitId());
serverSideTestRepo.branch(dest).update(commit);
ChangeNotes notes2 = insertChange();
notes2 = incrementPatchSet(notes2, commit);
- PatchSet.Id psId2 = psUtil.current(notes2).getId();
+ PatchSet.Id psId2 = psUtil.current(notes2).id();
ChangeNotes notes3 = insertChange();
notes3 = incrementPatchSet(notes3, commit);
- PatchSet.Id psId3 = psUtil.current(notes3).getId();
+ PatchSet.Id psId3 = psUtil.current(notes3).id();
FixInput fix = new FixInput();
fix.expectMergedAs = commit.name();
@@ -849,7 +847,7 @@
private ChangeNotes mergeChange(ChangeNotes notes) throws Exception {
ObjectId oldId = getDestRef(notes);
- ObjectId newId = psUtil.current(notes).getCommitId();
+ ObjectId newId = psUtil.current(notes).commitId();
String dest = notes.getChange().getDest().branch();
try (BatchUpdate bu = newUpdate(adminId)) {
diff --git a/javatests/com/google/gerrit/acceptance/server/change/GetRelatedIT.java b/javatests/com/google/gerrit/acceptance/server/change/GetRelatedIT.java
index 8597225..9882c77 100644
--- a/javatests/com/google/gerrit/acceptance/server/change/GetRelatedIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/change/GetRelatedIT.java
@@ -18,6 +18,7 @@
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.gerrit.acceptance.GitUtil.assertPushOk;
import static com.google.gerrit.acceptance.GitUtil.pushHead;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
import static com.google.gerrit.extensions.common.testing.EditInfoSubject.assertThat;
import static java.util.concurrent.TimeUnit.SECONDS;
@@ -30,10 +31,10 @@
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.testsuite.account.AccountOperations;
import com.google.gerrit.acceptance.testsuite.group.GroupOperations;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.RawInputUtil;
import com.google.gerrit.common.data.GlobalCapability;
-import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.extensions.api.changes.RelatedChangeAndCommitInfo;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.common.CommitInfo;
@@ -43,7 +44,6 @@
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.server.project.testing.Util;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.restapi.change.ChangesCollection;
import com.google.gerrit.server.restapi.change.GetRelated;
@@ -81,6 +81,7 @@
@Inject private AccountOperations accountOperations;
@Inject private GroupOperations groupOperations;
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
private String systemTimeZone;
@@ -611,11 +612,10 @@
Account.Id accountId = accountOperations.newAccount().create();
AccountGroup.UUID groupUuid = groupOperations.newGroup().addMember(accountId).create();
- try (ProjectConfigUpdate u = updateProject(allProjects)) {
- PermissionRule rule = Util.allow(u.getConfig(), GlobalCapability.QUERY_LIMIT, groupUuid);
- rule.setRange(0, 2);
- u.save();
- }
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(GlobalCapability.QUERY_LIMIT).group(groupUuid).range(0, 2))
+ .update();
requestScopeOperations.setApiUser(accountId);
assertRelated(lastPsId, expected);
@@ -689,8 +689,7 @@
new BatchUpdateOp() {
@Override
public boolean updateChange(ChangeContext ctx) {
- PatchSet ps = psUtil.get(ctx.getNotes(), psId);
- psUtil.setGroups(ctx.getUpdate(psId), ps, ImmutableList.of());
+ ctx.getUpdate(psId).setGroups(ImmutableList.of());
return true;
}
});
diff --git a/javatests/com/google/gerrit/acceptance/server/change/SubmittedTogetherIT.java b/javatests/com/google/gerrit/acceptance/server/change/SubmittedTogetherIT.java
index 389859c..9d65d39 100644
--- a/javatests/com/google/gerrit/acceptance/server/change/SubmittedTogetherIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/change/SubmittedTogetherIT.java
@@ -113,7 +113,7 @@
@Test
public void respectWholeTopic() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
// Create two independent commits and push.
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
String id1 = getChangeId(c1_1);
@@ -135,7 +135,7 @@
@Test
public void anonymousWholeTopic() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
RevCommit a = commitBuilder().add("a", "1").message("change 1").create();
pushHead(testRepo, "refs/for/master/" + name("topic"), false);
String id1 = getChangeId(a);
@@ -157,7 +157,7 @@
@Test
public void topicChaining() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
String id1 = getChangeId(c1_1);
@@ -185,7 +185,7 @@
@Test
public void respectTopicsOnAncestors() throws Exception {
- RevCommit initialHead = getRemoteHead();
+ RevCommit initialHead = projectOperations.project(project).getHead("master");
RevCommit c1_1 = commitBuilder().add("a.txt", "1").message("subject: 1").create();
String id1 = getChangeId(c1_1);
diff --git a/javatests/com/google/gerrit/acceptance/server/event/CommentAddedEventIT.java b/javatests/com/google/gerrit/acceptance/server/event/CommentAddedEventIT.java
index 4f98dd0..46fc689 100644
--- a/javatests/com/google/gerrit/acceptance/server/event/CommentAddedEventIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/event/CommentAddedEventIT.java
@@ -15,16 +15,17 @@
package com.google.gerrit.acceptance.server.event;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
import static com.google.gerrit.extensions.client.ListChangesOption.DETAILED_LABELS;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
-import static com.google.gerrit.server.project.testing.Util.category;
-import static com.google.gerrit.server.project.testing.Util.value;
+import static com.google.gerrit.server.project.testing.TestLabels.label;
+import static com.google.gerrit.server.project.testing.TestLabels.value;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.LabelType;
-import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.common.ApprovalInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
@@ -32,8 +33,6 @@
import com.google.gerrit.extensions.events.CommentAddedListener;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.registration.RegistrationHandle;
-import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.server.project.testing.Util;
import com.google.inject.Inject;
import org.junit.After;
import org.junit.Before;
@@ -43,37 +42,25 @@
public class CommentAddedEventIT extends AbstractDaemonTest {
@Inject private DynamicSet<CommentAddedListener> source;
+ @Inject private ProjectOperations projectOperations;
private final LabelType label =
- category("CustomLabel", value(1, "Positive"), value(0, "No score"), value(-1, "Negative"));
+ label("CustomLabel", value(1, "Positive"), value(0, "No score"), value(-1, "Negative"));
private final LabelType pLabel =
- category("CustomLabel2", value(1, "Positive"), value(0, "No score"));
+ label("CustomLabel2", value(1, "Positive"), value(0, "No score"));
private RegistrationHandle eventListenerRegistration;
private CommentAddedListener.Event lastCommentAddedEvent;
@Before
public void setUp() throws Exception {
- try (ProjectConfigUpdate u = updateProject(project)) {
- AccountGroup.UUID anonymousUsers = systemGroupBackend.getGroup(ANONYMOUS_USERS).getUUID();
- Util.allow(
- u.getConfig(),
- Permission.forLabel(label.getName()),
- -1,
- 1,
- anonymousUsers,
- "refs/heads/*");
- Util.allow(
- u.getConfig(),
- Permission.forLabel(pLabel.getName()),
- 0,
- 1,
- anonymousUsers,
- "refs/heads/*");
- u.save();
- }
-
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allowLabel(label.getName()).ref("refs/heads/*").group(ANONYMOUS_USERS).range(-1, 1))
+ .add(allowLabel(pLabel.getName()).ref("refs/heads/*").group(ANONYMOUS_USERS).range(0, 1))
+ .update();
eventListenerRegistration = source.add("gerrit", event -> lastCommentAddedEvent = event);
}
diff --git a/javatests/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java b/javatests/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java
index abf02d5..804462e 100644
--- a/javatests/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java
@@ -14,6 +14,9 @@
package com.google.gerrit.acceptance.server.mail;
+import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
import static com.google.gerrit.extensions.api.changes.NotifyHandling.ALL;
import static com.google.gerrit.extensions.api.changes.NotifyHandling.NONE;
import static com.google.gerrit.extensions.api.changes.NotifyHandling.OWNER;
@@ -31,6 +34,7 @@
import com.google.common.truth.Truth;
import com.google.gerrit.acceptance.AbstractNotificationTest;
import com.google.gerrit.acceptance.TestAccount;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.Permission;
@@ -51,8 +55,6 @@
import com.google.gerrit.extensions.common.CommitInfo;
import com.google.gerrit.extensions.common.CommitMessageInput;
import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.server.project.ProjectConfig;
-import com.google.gerrit.server.project.testing.Util;
import com.google.gerrit.server.restapi.change.PostReview;
import com.google.inject.Inject;
import org.eclipse.jgit.junit.TestRepository;
@@ -61,6 +63,7 @@
import org.junit.Test;
public class ChangeNotificationsIT extends AbstractNotificationTest {
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
/*
@@ -80,14 +83,14 @@
@Before
public void grantPermissions() throws Exception {
- try (ProjectConfigUpdate u = updateProject(project)) {
- ProjectConfig cfg = u.getConfig();
- Util.allow(cfg, Permission.FORGE_COMMITTER, REGISTERED_USERS, "refs/*");
- Util.allow(cfg, Permission.SUBMIT, REGISTERED_USERS, "refs/*");
- Util.allow(cfg, Permission.ABANDON, REGISTERED_USERS, "refs/*");
- Util.allow(cfg, Permission.forLabel("Code-Review"), -2, +2, REGISTERED_USERS, "refs/*");
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.FORGE_COMMITTER).ref("refs/*").group(REGISTERED_USERS))
+ .add(allow(Permission.SUBMIT).ref("refs/*").group(REGISTERED_USERS))
+ .add(allow(Permission.ABANDON).ref("refs/*").group(REGISTERED_USERS))
+ .add(allowLabel("Code-Review").ref("refs/*").group(REGISTERED_USERS).range(-2, +2))
+ .update();
}
/*
@@ -1508,22 +1511,24 @@
if (submitType == SubmitType.FAST_FORWARD_ONLY) {
continue;
}
- try (Repository repo = repoManager.openRepository(project)) {
- new TestRepository<>(repo).branch("master").commit().create();
+ try (Repository repo = repoManager.openRepository(project);
+ TestRepository<Repository> tr = new TestRepository<>(repo)) {
+ tr.branch("master").commit().create();
}
name += " after branch has advanced";
}
merge(sc.changeId, sc.owner);
- assertThat(sender)
- .named(name)
+ assertWithMessage(name)
+ .about(fakeEmailSenders())
+ .that(sender)
.sent("merged", sc)
.cc(sc.reviewer, sc.ccer)
.cc(sc.reviewerByEmail, sc.ccerByEmail)
.bcc(sc.starrer)
.bcc(ALL_COMMENTS, SUBMITTED_CHANGES)
.noOneElse();
- assertThat(sender).named(name).didNotSend();
+ assertWithMessage(name).about(fakeEmailSenders()).that(sender).didNotSend();
}
}
diff --git a/javatests/com/google/gerrit/acceptance/server/notedb/BUILD b/javatests/com/google/gerrit/acceptance/server/notedb/BUILD
index bdb3f3b..ee3bcb0 100644
--- a/javatests/com/google/gerrit/acceptance/server/notedb/BUILD
+++ b/javatests/com/google/gerrit/acceptance/server/notedb/BUILD
@@ -7,9 +7,6 @@
"notedb",
"server",
],
- # TODO(dborowitz): Fix leaks in local disk tests so we can reduce heap size.
- # http://crbug.com/gerrit/8567
- vm_args = ["-Xmx1024m"],
deps = [
"//java/com/google/gerrit/server/schema",
"//java/com/google/gerrit/server/util/time",
diff --git a/javatests/com/google/gerrit/acceptance/server/notedb/NoteDbOnlyIT.java b/javatests/com/google/gerrit/acceptance/server/notedb/NoteDbOnlyIT.java
index 708d162..5e7070b 100644
--- a/javatests/com/google/gerrit/acceptance/server/notedb/NoteDbOnlyIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/notedb/NoteDbOnlyIT.java
@@ -18,6 +18,7 @@
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.gerrit.extensions.client.ListChangesOption.MESSAGES;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.toList;
import com.google.common.collect.Iterables;
@@ -127,12 +128,9 @@
throw new ResourceConflictException(msg);
}
});
- try {
- bu.execute();
- fail("expected ResourceConflictException");
- } catch (ResourceConflictException e) {
- assertThat(e).hasMessageThat().isEqualTo(msg);
- }
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> bu.execute());
+ assertThat(thrown).hasMessageThat().isEqualTo(msg);
}
// If updateChange hadn't failed, backup would have been updated to master2.
@@ -195,12 +193,7 @@
}
private void assertNoSuchChangeException(Callable<?> callable) throws Exception {
- try {
- callable.call();
- fail("expected NoSuchChangeException");
- } catch (NoSuchChangeException e) {
- // Expected.
- }
+ assertThrows(NoSuchChangeException.class, () -> callable.call());
}
private class ConcurrentWritingListener implements BatchUpdateListener {
diff --git a/javatests/com/google/gerrit/acceptance/server/project/CustomLabelIT.java b/javatests/com/google/gerrit/acceptance/server/project/CustomLabelIT.java
index 6cbe40e..f80f86b 100644
--- a/javatests/com/google/gerrit/acceptance/server/project/CustomLabelIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/project/CustomLabelIT.java
@@ -15,6 +15,8 @@
package com.google.gerrit.acceptance.server.project;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.labelPermissionKey;
import static com.google.gerrit.common.data.LabelFunction.ANY_WITH_BLOCK;
import static com.google.gerrit.common.data.LabelFunction.MAX_NO_BLOCK;
import static com.google.gerrit.common.data.LabelFunction.MAX_WITH_BLOCK;
@@ -24,15 +26,17 @@
import static com.google.gerrit.extensions.client.ListChangesOption.LABELS;
import static com.google.gerrit.extensions.client.ListChangesOption.SUBMITTABLE;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
-import static com.google.gerrit.server.project.testing.Util.category;
-import static com.google.gerrit.server.project.testing.Util.value;
+import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.server.project.testing.TestLabels.label;
+import static com.google.gerrit.server.project.testing.TestLabels.value;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.LabelFunction;
import com.google.gerrit.common.data.LabelType;
-import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.changes.AddReviewerInput;
import com.google.gerrit.extensions.api.changes.ReviewInput;
import com.google.gerrit.extensions.common.ChangeInfo;
@@ -41,10 +45,7 @@
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.registration.RegistrationHandle;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
-import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.project.ProjectConfig;
-import com.google.gerrit.server.project.testing.Util;
import com.google.inject.Inject;
import java.util.Arrays;
import org.junit.After;
@@ -55,31 +56,24 @@
public class CustomLabelIT extends AbstractDaemonTest {
@Inject private DynamicSet<CommentAddedListener> source;
+ @Inject private ProjectOperations projectOperations;
private final LabelType label =
- category("CustomLabel", value(1, "Positive"), value(0, "No score"), value(-1, "Negative"));
+ label("CustomLabel", value(1, "Positive"), value(0, "No score"), value(-1, "Negative"));
- private final LabelType P = category("CustomLabel2", value(1, "Positive"), value(0, "No score"));
+ private final LabelType P = label("CustomLabel2", value(1, "Positive"), value(0, "No score"));
private RegistrationHandle eventListenerRegistration;
private CommentAddedListener.Event lastCommentAddedEvent;
@Before
public void setUp() throws Exception {
- try (ProjectConfigUpdate u = updateProject(project)) {
- AccountGroup.UUID anonymousUsers = systemGroupBackend.getGroup(ANONYMOUS_USERS).getUUID();
- Util.allow(
- u.getConfig(),
- Permission.forLabel(label.getName()),
- -1,
- 1,
- anonymousUsers,
- "refs/heads/*");
- Util.allow(
- u.getConfig(), Permission.forLabel(P.getName()), 0, 1, anonymousUsers, "refs/heads/*");
- u.save();
- }
-
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allowLabel(label.getName()).ref("refs/heads/*").group(ANONYMOUS_USERS).range(-1, 1))
+ .add(allowLabel(P.getName()).ref("refs/heads/*").group(ANONYMOUS_USERS).range(0, 1))
+ .update();
eventListenerRegistration = source.add("gerrit", event -> lastCommentAddedEvent = event);
}
@@ -265,15 +259,17 @@
assertPermitted(info, P.getName(), 0, 1);
assertPermitted(info, label.getName());
- ReviewInput in = new ReviewInput();
- in.label(P.getName(), P.getMax().getValue());
- revision(r).review(in);
+ ReviewInput postSubmitReview1 = new ReviewInput();
+ postSubmitReview1.label(P.getName(), P.getMax().getValue());
+ revision(r).review(postSubmitReview1);
- in = new ReviewInput();
- in.label(label.getName(), label.getMax().getValue());
- exception.expect(ResourceConflictException.class);
- exception.expectMessage("Voting on labels disallowed after submit: " + label.getName());
- revision(r).review(in);
+ ReviewInput postSubmitReview2 = new ReviewInput();
+ postSubmitReview2.label(label.getName(), label.getMax().getValue());
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> revision(r).review(postSubmitReview2));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Voting on labels disallowed after submit: " + label.getName());
}
@Test
@@ -289,11 +285,11 @@
value(-1, "I would prefer this is not merged as is"),
value(-2, "This shall not be merged"));
- AccountGroup.UUID registered = SystemGroupBackend.REGISTERED_USERS;
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.allow(u.getConfig(), Permission.forLabel(testLabel), -2, +2, registered, "refs/heads/*");
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allowLabel(testLabel).ref("refs/heads/*").group(REGISTERED_USERS).range(-2, +2))
+ .update();
PushOneCommit.Result result = createChange();
String changeId = result.getChangeId();
@@ -311,11 +307,12 @@
assertThat(gApi.changes().id(changeId).get().submittable).isTrue();
// Update admin's permitted range for 'Test-Label' to be -1...+1.
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.remove(u.getConfig(), Permission.forLabel(testLabel), registered, "refs/heads/*");
- Util.allow(u.getConfig(), Permission.forLabel(testLabel), -1, +1, registered, "refs/heads/*");
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .remove(labelPermissionKey(testLabel).ref("refs/heads/*").group(REGISTERED_USERS))
+ .add(allowLabel(testLabel).ref("refs/heads/*").group(REGISTERED_USERS).range(-1, +1))
+ .update();
// Verify admin doesn't have +2 permission any more.
assertPermitted(gApi.changes().id(changeId).get(), testLabel, -1, 0, 1);
diff --git a/javatests/com/google/gerrit/acceptance/server/project/ProjectWatchIT.java b/javatests/com/google/gerrit/acceptance/server/project/ProjectWatchIT.java
index f3b5009..1d656ea 100644
--- a/javatests/com/google/gerrit/acceptance/server/project/ProjectWatchIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/project/ProjectWatchIT.java
@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance.server.project;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.server.StarredChangesUtil.IGNORE_LABEL;
import com.google.common.collect.ImmutableSet;
@@ -511,12 +512,14 @@
// create group that can view all private changes
GroupInfo groupThatCanViewPrivateChanges =
gApi.groups().create("groupThatCanViewPrivateChanges").get();
- grant(
- Project.nameKey(watchedProject),
- "refs/*",
- Permission.VIEW_PRIVATE_CHANGES,
- false,
- AccountGroup.uuid(groupThatCanViewPrivateChanges.id));
+ projectOperations
+ .project(Project.nameKey(watchedProject))
+ .forUpdate()
+ .add(
+ allow(Permission.VIEW_PRIVATE_CHANGES)
+ .ref("refs/*")
+ .group(AccountGroup.uuid(groupThatCanViewPrivateChanges.id)))
+ .update();
// watch project as user that can't view private changes
requestScopeOperations.setApiUser(user.id());
diff --git a/javatests/com/google/gerrit/acceptance/server/project/ReflogIT.java b/javatests/com/google/gerrit/acceptance/server/project/ReflogIT.java
index de29fa0..a230e35 100644
--- a/javatests/com/google/gerrit/acceptance/server/project/ReflogIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/project/ReflogIT.java
@@ -16,11 +16,14 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
import static com.google.gerrit.reviewdb.client.RefNames.changeMetaRef;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.UseLocalDisk;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.changes.ReviewInput;
@@ -30,7 +33,6 @@
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.server.project.testing.Util;
import com.google.inject.Inject;
import java.io.File;
import java.util.List;
@@ -40,6 +42,7 @@
@UseLocalDisk
public class ReflogIT extends AbstractDaemonTest {
+ @Inject private ProjectOperations projectOperations;
@Inject private RequestScopeOperations requestScopeOperations;
@Test
@@ -86,8 +89,8 @@
@Test
public void regularUserIsNotAllowedToGetReflog() throws Exception {
requestScopeOperations.setApiUser(user.id());
- exception.expect(AuthException.class);
- gApi.projects().name(project.get()).branch("master").reflog();
+ assertThrows(
+ AuthException.class, () -> gApi.projects().name(project.get()).branch("master").reflog());
}
@Test
@@ -95,10 +98,11 @@
GroupApi groupApi = gApi.groups().create(name("get-reflog"));
groupApi.addMembers("user");
- try (ProjectConfigUpdate u = updateProject(project)) {
- Util.allow(u.getConfig(), Permission.OWNER, AccountGroup.uuid(groupApi.get().id), "refs/*");
- u.save();
- }
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(Permission.OWNER).ref("refs/*").group(AccountGroup.uuid(groupApi.get().id)))
+ .update();
requestScopeOperations.setApiUser(user.id());
gApi.projects().name(project.get()).branch("master").reflog();
diff --git a/javatests/com/google/gerrit/acceptance/server/quota/DefaultQuotaBackendIT.java b/javatests/com/google/gerrit/acceptance/server/quota/DefaultQuotaBackendIT.java
index 286e5ae..47d23a4 100644
--- a/javatests/com/google/gerrit/acceptance/server/quota/DefaultQuotaBackendIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/quota/DefaultQuotaBackendIT.java
@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance.server.quota;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.resetToStrict;
@@ -133,9 +134,8 @@
QuotaResponse.Aggregated result = quotaBackend.user(identifiedAdmin).requestToken("testGroup");
assertThat(result).isEqualTo(singletonAggregation(QuotaResponse.error("failed")));
- exception.expect(QuotaException.class);
- exception.expectMessage("failed");
- result.throwOnError();
+ QuotaException thrown = assertThrows(QuotaException.class, () -> result.throwOnError());
+ assertThat(thrown).hasMessageThat().contains("failed");
}
@Test
@@ -143,9 +143,9 @@
QuotaRequestContext ctx = QuotaRequestContext.builder().user(identifiedAdmin).build();
expect(quotaEnforcer.requestTokens("testGroup", ctx, 1)).andThrow(new NullPointerException());
replay(quotaEnforcer);
-
- exception.expect(NullPointerException.class);
- quotaBackend.user(identifiedAdmin).requestToken("testGroup");
+ assertThrows(
+ NullPointerException.class,
+ () -> quotaBackend.user(identifiedAdmin).requestToken("testGroup"));
}
private static QuotaResponse.Aggregated singletonAggregation(QuotaResponse response) {
diff --git a/javatests/com/google/gerrit/acceptance/server/quota/MultipleQuotaPluginsIT.java b/javatests/com/google/gerrit/acceptance/server/quota/MultipleQuotaPluginsIT.java
index 8b9ffc5..1caaf00 100644
--- a/javatests/com/google/gerrit/acceptance/server/quota/MultipleQuotaPluginsIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/quota/MultipleQuotaPluginsIT.java
@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance.server.quota;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
@@ -98,12 +99,11 @@
replay(quotaEnforcerA);
replay(quotaEnforcerB);
- try {
- quotaBackend.user(identifiedAdmin).requestToken("testGroup");
- fail("expected a NullPointerException");
- } catch (NullPointerException e) {
- assertThat(exception).isEqualTo(e);
- }
+ NullPointerException thrown =
+ assertThrows(
+ NullPointerException.class,
+ () -> quotaBackend.user(identifiedAdmin).requestToken("testGroup"));
+ assertThat(exception).isEqualTo(thrown);
verify(quotaEnforcerA);
}
diff --git a/javatests/com/google/gerrit/acceptance/server/rules/RulesIT.java b/javatests/com/google/gerrit/acceptance/server/rules/RulesIT.java
index c69712c..5634b27 100644
--- a/javatests/com/google/gerrit/acceptance/server/rules/RulesIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/rules/RulesIT.java
@@ -19,6 +19,7 @@
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
import com.google.gerrit.acceptance.PushOneCommit;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.SubmitRecord;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.project.SubmitRuleEvaluator;
@@ -26,7 +27,6 @@
import com.google.gerrit.server.query.change.ChangeData;
import com.google.inject.Inject;
import java.util.Collection;
-import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Repository;
import org.junit.Before;
@@ -41,6 +41,7 @@
private static final String RULE_TEMPLATE =
"submit_rule(submit(W)) :- \n" + "%s,\n" + "W = label('OK', ok(user(1000000))).";
+ @Inject private ProjectOperations projectOperations;
@Inject private SubmitRuleEvaluator.Factory evaluatorFactory;
@Before
@@ -85,7 +86,7 @@
}
private SubmitRecord.Status statusForRule() throws Exception {
- String oldHead = getRemoteHead().name();
+ String oldHead = projectOperations.project(project).getHead("master").name();
PushOneCommit.Result result1 =
pushFactory.create(user.newIdent(), testRepo).to("refs/for/master");
testRepo.reset(oldHead);
@@ -107,8 +108,8 @@
private void modifySubmitRules(String ruleTested) throws Exception {
String newContent = String.format(RULE_TEMPLATE, ruleTested);
- try (Repository repo = repoManager.openRepository(project)) {
- TestRepository<?> testRepo = new TestRepository<>((InMemoryRepository) repo);
+ try (Repository repo = repoManager.openRepository(project);
+ TestRepository<Repository> testRepo = new TestRepository<>(repo)) {
testRepo
.branch(RefNames.REFS_CONFIG)
.commit()
diff --git a/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java b/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java
index 7f2abc8..eaf65ae 100644
--- a/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java
+++ b/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java
@@ -36,7 +36,7 @@
@ConfigSuite.Config
public static Config elasticsearchV7() {
- return getConfig(ElasticVersion.V7_0);
+ return getConfig(ElasticVersion.V7_1);
}
@Override
diff --git a/javatests/com/google/gerrit/acceptance/ssh/QueryIT.java b/javatests/com/google/gerrit/acceptance/ssh/QueryIT.java
index 0f47a4a..78960bb 100644
--- a/javatests/com/google/gerrit/acceptance/ssh/QueryIT.java
+++ b/javatests/com/google/gerrit/acceptance/ssh/QueryIT.java
@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance.ssh;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import com.google.common.collect.Lists;
import com.google.gerrit.acceptance.AbstractDaemonTest;
@@ -294,8 +295,8 @@
// computation while formatting the output, such as labels, reviewers etc.
merge(r);
for (ListChangesOption option : ListChangesOption.values()) {
- assertThat(gApi.changes().query(r.getChangeId()).withOption(option).get())
- .named("Option: " + option)
+ assertWithMessage("Option: " + option)
+ .that(gApi.changes().query(r.getChangeId()).withOption(option).get())
.hasSize(1);
}
}
diff --git a/javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java b/javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java
index fd51618..de13552 100644
--- a/javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java
+++ b/javatests/com/google/gerrit/acceptance/ssh/UploadArchiveIT.java
@@ -15,6 +15,7 @@
package com.google.gerrit.acceptance.ssh;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assert_;
import com.google.common.base.Splitter;
import com.google.gerrit.acceptance.AbstractDaemonTest;
@@ -117,7 +118,7 @@
// that is currently not public.
char channel = packet.charAt(0);
if (channel != 1) {
- fail("got packet on channel " + (int) channel, packet);
+ assert_().fail("got packet on channel " + (int) channel, packet);
}
}
}
diff --git a/javatests/com/google/gerrit/acceptance/testsuite/group/GroupOperationsImplTest.java b/javatests/com/google/gerrit/acceptance/testsuite/group/GroupOperationsImplTest.java
index 1961294..bb84689 100644
--- a/javatests/com/google/gerrit/acceptance/testsuite/group/GroupOperationsImplTest.java
+++ b/javatests/com/google/gerrit/acceptance/testsuite/group/GroupOperationsImplTest.java
@@ -17,6 +17,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.Truth8.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableSet;
import com.google.common.truth.Correspondence;
@@ -227,9 +228,8 @@
@Test
public void retrievingNotExistingGroupFails() throws Exception {
AccountGroup.UUID notExistingGroupUuid = AccountGroup.uuid("not-existing-group");
-
- exception.expect(IllegalStateException.class);
- groupOperations.group(notExistingGroupUuid).get();
+ assertThrows(
+ IllegalStateException.class, () -> groupOperations.group(notExistingGroupUuid).get());
}
@Test
diff --git a/javatests/com/google/gerrit/acceptance/testsuite/project/ProjectOperationsImplTest.java b/javatests/com/google/gerrit/acceptance/testsuite/project/ProjectOperationsImplTest.java
index 3f537c0..f5066db 100644
--- a/javatests/com/google/gerrit/acceptance/testsuite/project/ProjectOperationsImplTest.java
+++ b/javatests/com/google/gerrit/acceptance/testsuite/project/ProjectOperationsImplTest.java
@@ -15,14 +15,41 @@
package com.google.gerrit.acceptance.testsuite.project;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.blockLabel;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.capabilityKey;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.deny;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.labelPermissionKey;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.permissionKey;
+import static com.google.gerrit.common.data.GlobalCapability.ADMINISTRATE_SERVER;
+import static com.google.gerrit.common.data.GlobalCapability.DEFAULT_MAX_QUERY_LIMIT;
+import static com.google.gerrit.common.data.GlobalCapability.QUERY_LIMIT;
+import static com.google.gerrit.reviewdb.client.RefNames.REFS_CONFIG;
+import static com.google.gerrit.server.group.SystemGroupBackend.PROJECT_OWNERS;
+import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+import static com.google.gerrit.truth.ConfigSubject.assertThat;
import static java.util.stream.Collectors.toList;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableListMultimap;
import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.TestPermission;
+import com.google.gerrit.common.data.Permission;
import com.google.gerrit.extensions.api.projects.BranchInfo;
+import com.google.gerrit.extensions.api.projects.ConfigInput;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.project.ProjectConfig;
+import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject;
import java.util.List;
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.StoredConfig;
import org.junit.Test;
public class ProjectOperationsImplTest extends AbstractDaemonTest {
@@ -48,9 +75,517 @@
@Test
public void emptyCommit() throws Exception {
Project.NameKey key = projectOperations.newProject().create();
+
List<BranchInfo> branches = gApi.projects().name(key.get()).branches().get();
assertThat(branches).isNotEmpty();
assertThat(branches.stream().map(x -> x.ref).collect(toList()))
.isEqualTo(ImmutableList.of("HEAD", "refs/meta/config", "refs/heads/master"));
}
+
+ @Test
+ public void getProjectConfig() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ assertThat(projectOperations.project(key).getProjectConfig().getProject().getDescription())
+ .isEmpty();
+
+ ConfigInput input = new ConfigInput();
+ input.description = "my fancy project";
+ gApi.projects().name(key.get()).config(input);
+
+ assertThat(projectOperations.project(key).getProjectConfig().getProject().getDescription())
+ .isEqualTo("my fancy project");
+ }
+
+ @Test
+ public void mutatingResultOfGetProjectConfigDoesNotMutateGlobalCachedValue() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ ProjectConfig projectConfig = projectOperations.project(key).getProjectConfig();
+ ProjectState cachedProjectState1 = projectCache.checkedGet(key);
+ ProjectConfig cachedProjectConfig1 = cachedProjectState1.getConfig();
+ assertThat(cachedProjectConfig1).isNotSameInstanceAs(projectConfig);
+ assertThat(cachedProjectConfig1.getProject().getDescription()).isEmpty();
+ assertThat(projectConfig.getProject().getDescription()).isEmpty();
+ projectConfig.getProject().setDescription("my fancy project");
+
+ ProjectConfig cachedProjectConfig2 = projectCache.checkedGet(key).getConfig();
+ assertThat(cachedProjectConfig2).isNotSameInstanceAs(projectConfig);
+ assertThat(cachedProjectConfig2.getProject().getDescription()).isEmpty();
+ }
+
+ @Test
+ public void getProjectConfigNoRefsMetaConfig() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ deleteRefsMetaConfig(key);
+
+ ProjectConfig projectConfig = projectOperations.project(key).getProjectConfig();
+ assertThat(projectConfig.getName()).isEqualTo(key);
+ assertThat(projectConfig.getRevision()).isNull();
+ }
+
+ @Test
+ public void getConfig() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ Config config = projectOperations.project(key).getConfig();
+ assertThat(config).isNotInstanceOf(StoredConfig.class);
+ assertThat(config).text().isEmpty();
+
+ ConfigInput input = new ConfigInput();
+ input.description = "my fancy project";
+ gApi.projects().name(key.get()).config(input);
+
+ config = projectOperations.project(key).getConfig();
+ assertThat(config).isNotInstanceOf(StoredConfig.class);
+ assertThat(config).sections().containsExactly("project");
+ assertThat(config).subsections("project").isEmpty();
+ assertThat(config).sectionValues("project").containsExactly("description", "my fancy project");
+ }
+
+ @Test
+ public void getConfigNoRefsMetaConfig() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ deleteRefsMetaConfig(key);
+
+ Config config = projectOperations.project(key).getConfig();
+ assertThat(config).isNotInstanceOf(StoredConfig.class);
+ assertThat(config).isEmpty();
+ }
+
+ @Test
+ public void addAllowPermission() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .add(allow(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS))
+ .update();
+
+ Config config = projectOperations.project(key).getConfig();
+ assertThat(config).sections().containsExactly("access");
+ assertThat(config).subsections("access").containsExactly("refs/foo");
+ assertThat(config)
+ .subsectionValues("access", "refs/foo")
+ .containsExactly("abandon", "group global:Registered-Users");
+ }
+
+ @Test
+ public void addDenyPermission() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .add(deny(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS))
+ .update();
+
+ Config config = projectOperations.project(key).getConfig();
+ assertThat(config).sections().containsExactly("access");
+ assertThat(config).subsections("access").containsExactly("refs/foo");
+ assertThat(config)
+ .subsectionValues("access", "refs/foo")
+ .containsExactly("abandon", "deny group global:Registered-Users");
+ }
+
+ @Test
+ public void addBlockPermission() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .add(block(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS))
+ .update();
+
+ Config config = projectOperations.project(key).getConfig();
+ assertThat(config).sections().containsExactly("access");
+ assertThat(config).subsections("access").containsExactly("refs/foo");
+ assertThat(config)
+ .subsectionValues("access", "refs/foo")
+ .containsExactly("abandon", "block group global:Registered-Users");
+ }
+
+ @Test
+ public void addAllowForcePermission() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .add(allow(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS).force(true))
+ .update();
+
+ Config config = projectOperations.project(key).getConfig();
+ assertThat(config).sections().containsExactly("access");
+ assertThat(config).subsections("access").containsExactly("refs/foo");
+ assertThat(config)
+ .subsectionValues("access", "refs/foo")
+ .containsExactly("abandon", "+force group global:Registered-Users");
+ }
+
+ @Test
+ public void updateExclusivePermission() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .add(allow(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS))
+ .setExclusiveGroup(permissionKey(Permission.ABANDON).ref("refs/foo"), true)
+ .update();
+
+ Config config = projectOperations.project(key).getConfig();
+ assertThat(config).sections().containsExactly("access");
+ assertThat(config).subsections("access").containsExactly("refs/foo");
+ assertThat(config)
+ .subsectionValues("access", "refs/foo")
+ .containsExactly(
+ "abandon", "group global:Registered-Users",
+ "exclusiveGroupPermissions", "abandon");
+
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .setExclusiveGroup(permissionKey(Permission.ABANDON).ref("refs/foo"), false)
+ .update();
+
+ config = projectOperations.project(key).getConfig();
+ assertThat(config).sections().containsExactly("access");
+ assertThat(config).subsections("access").containsExactly("refs/foo");
+ assertThat(config)
+ .subsectionValues("access", "refs/foo")
+ .containsExactly("abandon", "group global:Registered-Users");
+ }
+
+ @Test
+ public void addMultipleExclusivePermission() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .setExclusiveGroup(permissionKey(Permission.ABANDON).ref("refs/foo"), true)
+ .setExclusiveGroup(permissionKey(Permission.CREATE).ref("refs/foo"), true)
+ .update();
+ assertThat(projectOperations.project(key).getConfig())
+ .subsectionValues("access", "refs/foo")
+ .containsEntry("exclusiveGroupPermissions", "abandon create");
+
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .setExclusiveGroup(permissionKey(Permission.ABANDON).ref("refs/foo"), false)
+ .update();
+ assertThat(projectOperations.project(key).getConfig())
+ .subsectionValues("access", "refs/foo")
+ .containsEntry("exclusiveGroupPermissions", "create");
+ }
+
+ @Test
+ public void addMultiplePermissions() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .add(allow(Permission.ABANDON).ref("refs/foo").group(PROJECT_OWNERS))
+ .add(allow(Permission.CREATE).ref("refs/foo").group(REGISTERED_USERS))
+ .update();
+
+ Config config = projectOperations.project(key).getConfig();
+ assertThat(config).sections().containsExactly("access");
+ assertThat(config).subsections("access").containsExactly("refs/foo");
+ assertThat(config)
+ .subsectionValues("access", "refs/foo")
+ .containsExactly(
+ "abandon", "group global:Project-Owners",
+ "create", "group global:Registered-Users");
+ }
+
+ @Test
+ public void addDuplicatePermissions() throws Exception {
+ TestPermission permission =
+ TestProjectUpdate.allow(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS).build();
+ Project.NameKey key = projectOperations.newProject().create();
+ projectOperations.project(key).forUpdate().add(permission).add(permission).update();
+
+ Config config = projectOperations.project(key).getConfig();
+ assertThat(config).sections().containsExactly("access");
+ assertThat(config).subsections("access").containsExactly("refs/foo");
+ assertThat(config)
+ .subsectionValues("access", "refs/foo")
+ .containsExactly(
+ "abandon", "group global:Registered-Users",
+ "abandon", "group global:Registered-Users");
+
+ projectOperations.project(key).forUpdate().add(permission).update();
+ config = projectOperations.project(key).getConfig();
+ assertThat(config).sections().containsExactly("access");
+ assertThat(config).subsections("access").containsExactly("refs/foo");
+ assertThat(config)
+ .subsectionValues("access", "refs/foo")
+ .containsExactly(
+ "abandon", "group global:Registered-Users",
+ "abandon", "group global:Registered-Users",
+ "abandon", "group global:Registered-Users");
+ }
+
+ @Test
+ public void addAllowLabelPermission() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .add(allowLabel("Code-Review").ref("refs/foo").group(REGISTERED_USERS).range(-1, 2))
+ .update();
+
+ Config config = projectOperations.project(key).getConfig();
+ assertThat(config).sections().containsExactly("access");
+ assertThat(config).subsections("access").containsExactly("refs/foo");
+ assertThat(config)
+ .subsectionValues("access", "refs/foo")
+ .containsExactly("label-Code-Review", "-1..+2 group global:Registered-Users");
+ }
+
+ @Test
+ public void addBlockLabelPermission() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .add(blockLabel("Code-Review").ref("refs/foo").group(REGISTERED_USERS).range(-1, 2))
+ .update();
+
+ Config config = projectOperations.project(key).getConfig();
+ assertThat(config).sections().containsExactly("access");
+ assertThat(config).subsections("access").containsExactly("refs/foo");
+ assertThat(config)
+ .subsectionValues("access", "refs/foo")
+ .containsExactly("label-Code-Review", "block -1..+2 group global:Registered-Users");
+ }
+
+ @Test
+ public void addAllowExclusiveLabelPermission() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .add(allowLabel("Code-Review").ref("refs/foo").group(REGISTERED_USERS).range(-1, 2))
+ .setExclusiveGroup(labelPermissionKey("Code-Review").ref("refs/foo"), true)
+ .update();
+
+ Config config = projectOperations.project(key).getConfig();
+ assertThat(config).sections().containsExactly("access");
+ assertThat(config).subsections("access").containsExactly("refs/foo");
+ assertThat(config)
+ .subsectionValues("access", "refs/foo")
+ .containsExactly(
+ "label-Code-Review", "-1..+2 group global:Registered-Users",
+ "exclusiveGroupPermissions", "label-Code-Review");
+
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .setExclusiveGroup(labelPermissionKey("Code-Review").ref("refs/foo"), false)
+ .update();
+
+ config = projectOperations.project(key).getConfig();
+ assertThat(config).sections().containsExactly("access");
+ assertThat(config).subsections("access").containsExactly("refs/foo");
+ assertThat(config)
+ .subsectionValues("access", "refs/foo")
+ .containsExactly("label-Code-Review", "-1..+2 group global:Registered-Users");
+ }
+
+ @Test
+ public void addAllowLabelAsPermission() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .add(
+ allowLabel("Code-Review")
+ .ref("refs/foo")
+ .group(REGISTERED_USERS)
+ .range(-1, 2)
+ .impersonation(true))
+ .update();
+
+ Config config = projectOperations.project(key).getConfig();
+ assertThat(config).sections().containsExactly("access");
+ assertThat(config).subsections("access").containsExactly("refs/foo");
+ assertThat(config)
+ .subsectionValues("access", "refs/foo")
+ .containsExactly("labelAs-Code-Review", "-1..+2 group global:Registered-Users");
+ }
+
+ @Test
+ public void addAllowCapability() throws Exception {
+ Config config = projectOperations.project(allProjects).getConfig();
+ assertThat(config)
+ .sectionValues("capability")
+ .doesNotContainEntry("administrateServer", "group Registered Users");
+
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(ADMINISTRATE_SERVER).group(REGISTERED_USERS))
+ .update();
+
+ assertThat(projectOperations.project(allProjects).getConfig())
+ .sectionValues("capability")
+ .containsEntry("administrateServer", "group Registered Users");
+ }
+
+ @Test
+ public void addAllowCapabilityWithRange() throws Exception {
+ Config config = projectOperations.project(allProjects).getConfig();
+ assertThat(config).sectionValues("capability").doesNotContainKey("queryLimit");
+
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(QUERY_LIMIT).group(REGISTERED_USERS).range(0, 5000))
+ .update();
+
+ assertThat(projectOperations.project(allProjects).getConfig())
+ .sectionValues("capability")
+ .containsEntry("queryLimit", "+0..+5000 group Registered Users");
+ }
+
+ @Test
+ public void addAllowCapabilityWithDefaultRange() throws Exception {
+ Config config = projectOperations.project(allProjects).getConfig();
+ assertThat(config).sectionValues("capability").doesNotContainKey("queryLimit");
+
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(QUERY_LIMIT).group(REGISTERED_USERS))
+ .update();
+
+ assertThat(projectOperations.project(allProjects).getConfig())
+ .sectionValues("capability")
+ .containsEntry("queryLimit", "+0..+" + DEFAULT_MAX_QUERY_LIMIT + " group Registered Users");
+ }
+
+ @Test
+ public void removePermission() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .add(allow(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS))
+ .add(allow(Permission.ABANDON).ref("refs/foo").group(PROJECT_OWNERS))
+ .update();
+ assertThat(projectOperations.project(key).getConfig())
+ .subsectionValues("access", "refs/foo")
+ .containsExactly(
+ "abandon", "group global:Registered-Users",
+ "abandon", "group global:Project-Owners");
+
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .remove(permissionKey(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS))
+ .update();
+ assertThat(projectOperations.project(key).getConfig())
+ .subsectionValues("access", "refs/foo")
+ .containsExactly("abandon", "group global:Project-Owners");
+ }
+
+ @Test
+ public void removeLabelPermission() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .add(allowLabel("Code-Review").ref("refs/foo").group(REGISTERED_USERS).range(-1, 2))
+ .add(allowLabel("Code-Review").ref("refs/foo").group(PROJECT_OWNERS).range(-2, 1))
+ .update();
+ assertThat(projectOperations.project(key).getConfig())
+ .subsectionValues("access", "refs/foo")
+ .containsExactly(
+ "label-Code-Review", "-1..+2 group global:Registered-Users",
+ "label-Code-Review", "-2..+1 group global:Project-Owners");
+
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .remove(labelPermissionKey("Code-Review").ref("refs/foo").group(REGISTERED_USERS))
+ .update();
+ assertThat(projectOperations.project(key).getConfig())
+ .subsectionValues("access", "refs/foo")
+ .containsExactly("label-Code-Review", "-2..+1 group global:Project-Owners");
+ }
+
+ @Test
+ public void removeCapability() throws Exception {
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowCapability(ADMINISTRATE_SERVER).group(REGISTERED_USERS))
+ .add(allowCapability(ADMINISTRATE_SERVER).group(PROJECT_OWNERS))
+ .update();
+ assertThat(projectOperations.project(allProjects).getConfig())
+ .sectionValues("capability")
+ .containsAtLeastEntriesIn(
+ ImmutableListMultimap.of(
+ "administrateServer", "group Registered Users",
+ "administrateServer", "group Project Owners"));
+
+ projectOperations
+ .allProjectsForUpdate()
+ .remove(capabilityKey(ADMINISTRATE_SERVER).group(REGISTERED_USERS))
+ .update();
+ assertThat(projectOperations.project(allProjects).getConfig())
+ .sectionValues("capability")
+ .doesNotContainEntry("administrateServer", "group Registered Users");
+ }
+
+ @Test
+ public void removeOnePermissionForAllGroupsFromOneAccessSection() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .add(allow(Permission.ABANDON).ref("refs/foo").group(PROJECT_OWNERS))
+ .add(allow(Permission.ABANDON).ref("refs/foo").group(REGISTERED_USERS))
+ .add(allow(Permission.CREATE).ref("refs/foo").group(REGISTERED_USERS))
+ .update();
+ assertThat(projectOperations.project(key).getConfig())
+ .subsectionValues("access", "refs/foo")
+ .containsAtLeastEntriesIn(
+ ImmutableListMultimap.of(
+ "abandon", "group global:Project-Owners",
+ "abandon", "group global:Registered-Users",
+ "create", "group global:Registered-Users"));
+
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .remove(permissionKey(Permission.ABANDON).ref("refs/foo"))
+ .update();
+ Config config = projectOperations.project(key).getConfig();
+ assertThat(config).subsectionValues("access", "refs/foo").doesNotContainKey("abandon");
+ assertThat(config)
+ .subsectionValues("access", "refs/foo")
+ .containsEntry("create", "group global:Registered-Users");
+ }
+
+ @Test
+ public void updatingCapabilitiesNotAllowedForNonAllProjects() throws Exception {
+ Project.NameKey key = projectOperations.newProject().create();
+ assertThrows(
+ RuntimeException.class,
+ () ->
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .add(allowCapability(ADMINISTRATE_SERVER).group(REGISTERED_USERS))
+ .update());
+ assertThrows(
+ RuntimeException.class,
+ () ->
+ projectOperations
+ .project(key)
+ .forUpdate()
+ .remove(capabilityKey(ADMINISTRATE_SERVER))
+ .update());
+ }
+
+ private void deleteRefsMetaConfig(Project.NameKey key) throws Exception {
+ try (Repository repo = repoManager.openRepository(key);
+ TestRepository<Repository> tr = new TestRepository<>(repo)) {
+ tr.delete(REFS_CONFIG);
+ }
+ }
}
diff --git a/javatests/com/google/gerrit/acceptance/testsuite/project/TestProjectUpdateTest.java b/javatests/com/google/gerrit/acceptance/testsuite/project/TestProjectUpdateTest.java
new file mode 100644
index 0000000..b81b23d
--- /dev/null
+++ b/javatests/com/google/gerrit/acceptance/testsuite/project/TestProjectUpdateTest.java
@@ -0,0 +1,202 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.acceptance.testsuite.project;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowCapability;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.capabilityKey;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.labelPermissionKey;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.permissionKey;
+import static com.google.gerrit.common.data.GlobalCapability.ADMINISTRATE_SERVER;
+import static com.google.gerrit.common.data.GlobalCapability.BATCH_CHANGES_LIMIT;
+import static com.google.gerrit.common.data.GlobalCapability.DEFAULT_MAX_BATCH_CHANGES_LIMIT;
+import static com.google.gerrit.common.data.GlobalCapability.DEFAULT_MAX_QUERY_LIMIT;
+import static com.google.gerrit.common.data.GlobalCapability.QUERY_LIMIT;
+import static com.google.gerrit.common.data.Permission.ABANDON;
+import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+
+import com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.TestCapability;
+import com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.TestLabelPermission;
+import com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.TestPermissionKey;
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.config.AllProjectsName;
+import java.util.function.Function;
+import org.junit.Test;
+
+public class TestProjectUpdateTest {
+ private static final AllProjectsName ALL_PROJECTS_NAME = new AllProjectsName("All-Projects");
+
+ @Test
+ public void testCapabilityDisallowsZeroRangeOnCapabilityThatHasNoRange() throws Exception {
+ assertThrows(
+ RuntimeException.class,
+ () -> allowCapability(ADMINISTRATE_SERVER).group(REGISTERED_USERS).range(0, 0).build());
+ }
+
+ @Test
+ public void testCapabilityAllowsZeroRangeOnCapabilityThatHasRange() throws Exception {
+ TestCapability c = allowCapability(QUERY_LIMIT).group(REGISTERED_USERS).range(0, 0).build();
+ assertThat(c.min()).isEqualTo(0);
+ assertThat(c.max()).isEqualTo(0);
+ }
+
+ @Test
+ public void testCapabilityDisallowsInvertedRange() throws Exception {
+ assertThrows(
+ RuntimeException.class,
+ () -> allowCapability(QUERY_LIMIT).group(REGISTERED_USERS).range(1, 0).build());
+ }
+
+ @Test
+ public void testCapabilityDisallowsRangeIfCapabilityDoesNotSupportRange() throws Exception {
+ assertThrows(
+ RuntimeException.class,
+ () -> allowCapability(ADMINISTRATE_SERVER).group(REGISTERED_USERS).range(-1, 1).build());
+ }
+
+ @Test
+ public void testCapabilityRangeIsZeroIfCapabilityDoesNotSupportRange() throws Exception {
+ TestCapability c = allowCapability(ADMINISTRATE_SERVER).group(REGISTERED_USERS).build();
+ assertThat(c.min()).isEqualTo(0);
+ assertThat(c.max()).isEqualTo(0);
+ }
+
+ @Test
+ public void testCapabilityUsesDefaultRangeIfUnspecified() throws Exception {
+ TestCapability c = allowCapability(QUERY_LIMIT).group(REGISTERED_USERS).build();
+ assertThat(c.min()).isEqualTo(0);
+ assertThat(c.max()).isEqualTo(DEFAULT_MAX_QUERY_LIMIT);
+
+ c = allowCapability(BATCH_CHANGES_LIMIT).group(REGISTERED_USERS).build();
+ assertThat(c.min()).isEqualTo(0);
+ assertThat(c.max()).isEqualTo(DEFAULT_MAX_BATCH_CHANGES_LIMIT);
+ }
+
+ @Test
+ public void testCapabilityUsesExplicitRangeIfSpecified() throws Exception {
+ TestCapability c = allowCapability(QUERY_LIMIT).group(REGISTERED_USERS).range(5, 20).build();
+ assertThat(c.min()).isEqualTo(5);
+ assertThat(c.max()).isEqualTo(20);
+ }
+
+ @Test
+ public void testLabelPermissionRequiresValidLabelName() throws Exception {
+ Function<String, TestLabelPermission.Builder> labelBuilder =
+ name -> allowLabel(name).ref("refs/*").group(REGISTERED_USERS).range(-1, 1);
+ assertThat(labelBuilder.apply("Code-Review").build().name()).isEqualTo("Code-Review");
+ assertThrows(RuntimeException.class, () -> labelBuilder.apply("not a label").build());
+ assertThrows(RuntimeException.class, () -> labelBuilder.apply("label-Code-Review").build());
+ }
+
+ @Test
+ public void testLabelPermissionDisallowsZeroRange() throws Exception {
+ assertThrows(
+ RuntimeException.class,
+ () -> allowLabel("Code-Review").ref("refs/*").group(REGISTERED_USERS).range(0, 0).build());
+ }
+
+ @Test
+ public void testLabelPermissionDisallowsInvertedRange() throws Exception {
+ assertThrows(
+ RuntimeException.class,
+ () -> allowLabel("Code-Review").ref("refs/*").group(REGISTERED_USERS).range(1, 0).build());
+ }
+
+ @Test
+ public void testPermissionKeyRequiresValidRefName() throws Exception {
+ Function<String, TestPermissionKey.Builder> keyBuilder =
+ ref -> permissionKey(ABANDON).ref(ref).group(REGISTERED_USERS);
+ assertThat(keyBuilder.apply("refs/*").build().section()).isEqualTo("refs/*");
+ assertThrows(RuntimeException.class, () -> keyBuilder.apply(null).build());
+ assertThrows(RuntimeException.class, () -> keyBuilder.apply("foo").build());
+ }
+
+ @Test
+ public void testLabelPermissionKeyRequiresValidLabelName() throws Exception {
+ Function<String, TestPermissionKey.Builder> keyBuilder =
+ label -> labelPermissionKey(label).ref("refs/*").group(REGISTERED_USERS);
+ assertThat(keyBuilder.apply("Code-Review").build().name()).isEqualTo("label-Code-Review");
+ assertThrows(RuntimeException.class, () -> keyBuilder.apply(null).build());
+ assertThrows(RuntimeException.class, () -> keyBuilder.apply("not a label").build());
+ assertThrows(RuntimeException.class, () -> keyBuilder.apply("label-Code-Review").build());
+ }
+
+ @Test
+ public void testPermissionKeyDisallowsSettingRefOnGlobalCapability() throws Exception {
+ assertThrows(RuntimeException.class, () -> capabilityKey(ADMINISTRATE_SERVER).ref("refs/*"));
+ }
+
+ @Test
+ public void testProjectUpdateDisallowsGroupOnExclusiveGroupPermissionKey() throws Exception {
+ TestPermissionKey.Builder b = permissionKey(ABANDON).ref("refs/*");
+ Function<TestPermissionKey.Builder, TestProjectUpdate.Builder> updateBuilder =
+ kb -> builder().setExclusiveGroup(kb, true);
+
+ assertThat(updateBuilder.apply(b).build().exclusiveGroupPermissions())
+ .containsExactly(b.build(), true);
+
+ b.group(REGISTERED_USERS);
+ assertThrows(RuntimeException.class, () -> updateBuilder.apply(b).build());
+ }
+
+ @Test
+ public void hasCapabilityUpdates() throws Exception {
+ assertThat(builder().build().hasCapabilityUpdates()).isFalse();
+ assertThat(
+ builder()
+ .add(allow(ABANDON).ref("refs/*").group(REGISTERED_USERS))
+ .add(allowLabel("Code-Review").ref("refs/*").group(REGISTERED_USERS).range(0, 1))
+ .remove(permissionKey(ABANDON).ref("refs/foo"))
+ .remove(labelPermissionKey("Code-Review").ref("refs/foo"))
+ .setExclusiveGroup(permissionKey(ABANDON).ref("refs/bar"), true)
+ .setExclusiveGroup(labelPermissionKey(ABANDON).ref("refs/bar"), true)
+ .build()
+ .hasCapabilityUpdates())
+ .isFalse();
+ assertThat(
+ builder(ALL_PROJECTS_NAME)
+ .add(allowCapability(ADMINISTRATE_SERVER).group(REGISTERED_USERS))
+ .build()
+ .hasCapabilityUpdates())
+ .isTrue();
+ assertThat(
+ builder(ALL_PROJECTS_NAME)
+ .remove(capabilityKey(ADMINISTRATE_SERVER))
+ .build()
+ .hasCapabilityUpdates())
+ .isTrue();
+ }
+
+ @Test
+ public void updatingCapabilitiesNotAllowedForNonAllProjects() throws Exception {
+ assertThrows(
+ RuntimeException.class,
+ () -> builder().add(allowCapability(ADMINISTRATE_SERVER).group(REGISTERED_USERS)).update());
+ assertThrows(
+ RuntimeException.class,
+ () -> builder().remove(capabilityKey(ADMINISTRATE_SERVER)).update());
+ }
+
+ private static TestProjectUpdate.Builder builder() {
+ return builder(Project.nameKey("test-project"));
+ }
+
+ private static TestProjectUpdate.Builder builder(Project.NameKey nameKey) {
+ return TestProjectUpdate.builder(nameKey, ALL_PROJECTS_NAME, u -> {});
+ }
+}
diff --git a/javatests/com/google/gerrit/acceptance/testsuite/request/RequestScopeOperationsImplTest.java b/javatests/com/google/gerrit/acceptance/testsuite/request/RequestScopeOperationsImplTest.java
index 4d0bb52..90f581d 100644
--- a/javatests/com/google/gerrit/acceptance/testsuite/request/RequestScopeOperationsImplTest.java
+++ b/javatests/com/google/gerrit/acceptance/testsuite/request/RequestScopeOperationsImplTest.java
@@ -16,8 +16,8 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
-import static com.google.common.truth.Truth.assert_;
import static com.google.common.truth.Truth8.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.acceptance.AbstractDaemonTest;
@@ -68,12 +68,9 @@
@Test
public void setApiUserToNonExistingUser() throws Exception {
fastCheckCurrentUser(admin.id());
- try {
- requestScopeOperations.setApiUser(Account.id(sequences.nextAccountId()));
- assert_().fail("expected RuntimeException");
- } catch (RuntimeException e) {
- // Expected.
- }
+ assertThrows(
+ RuntimeException.class,
+ () -> requestScopeOperations.setApiUser(Account.id(sequences.nextAccountId())));
checkCurrentUser(admin.id());
}
diff --git a/javatests/com/google/gerrit/common/AutoValueTest.java b/javatests/com/google/gerrit/common/AutoValueTest.java
index 89d7bf4..947fe4a 100644
--- a/javatests/com/google/gerrit/common/AutoValueTest.java
+++ b/javatests/com/google/gerrit/common/AutoValueTest.java
@@ -17,10 +17,9 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.auto.value.AutoValue;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class AutoValueTest extends GerritBaseTests {
+public class AutoValueTest {
@AutoValue
abstract static class Auto {
static Auto create(String val) {
diff --git a/javatests/com/google/gerrit/common/data/AccessSectionTest.java b/javatests/com/google/gerrit/common/data/AccessSectionTest.java
index faf9d6c..e775cbc 100644
--- a/javatests/com/google/gerrit/common/data/AccessSectionTest.java
+++ b/javatests/com/google/gerrit/common/data/AccessSectionTest.java
@@ -15,16 +15,16 @@
package com.google.gerrit.common.data;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableList;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.junit.Before;
import org.junit.Test;
-public class AccessSectionTest extends GerritBaseTests {
+public class AccessSectionTest {
private static final String REF_PATTERN = "refs/heads/master";
private AccessSection accessSection;
@@ -57,16 +57,17 @@
Permission submitPermission = new Permission(Permission.SUBMIT);
accessSection.setPermissions(ImmutableList.of(submitPermission));
assertThat(accessSection.getPermissions()).containsExactly(submitPermission);
-
- exception.expect(NullPointerException.class);
- accessSection.setPermissions(null);
+ assertThrows(NullPointerException.class, () -> accessSection.setPermissions(null));
}
@Test
public void cannotSetDuplicatePermissions() {
- exception.expect(IllegalArgumentException.class);
- accessSection.setPermissions(
- ImmutableList.of(new Permission(Permission.ABANDON), new Permission(Permission.ABANDON)));
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ accessSection.setPermissions(
+ ImmutableList.of(
+ new Permission(Permission.ABANDON), new Permission(Permission.ABANDON))));
}
@Test
@@ -76,9 +77,11 @@
Permission abandonPermissionUpperCase =
new Permission(Permission.ABANDON.toUpperCase(Locale.US));
- exception.expect(IllegalArgumentException.class);
- accessSection.setPermissions(
- ImmutableList.of(abandonPermissionLowerCase, abandonPermissionUpperCase));
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ accessSection.setPermissions(
+ ImmutableList.of(abandonPermissionLowerCase, abandonPermissionUpperCase)));
}
@Test
@@ -92,9 +95,7 @@
Permission submitPermission = new Permission(Permission.SUBMIT);
accessSection.setPermissions(ImmutableList.of(submitPermission));
assertThat(accessSection.getPermission(Permission.SUBMIT)).isEqualTo(submitPermission);
-
- exception.expect(NullPointerException.class);
- accessSection.getPermission(null);
+ assertThrows(NullPointerException.class, () -> accessSection.getPermission(null));
}
@Test
@@ -112,8 +113,7 @@
assertThat(accessSection.getPermission(Permission.SUBMIT, true))
.isEqualTo(new Permission(Permission.SUBMIT));
- exception.expect(NullPointerException.class);
- accessSection.getPermission(null, true);
+ assertThrows(NullPointerException.class, () -> accessSection.getPermission(null, true));
}
@Test
@@ -130,9 +130,7 @@
assertThat(accessSection.getPermissions())
.containsExactly(abandonPermission, rebasePermission, submitPermission)
.inOrder();
-
- exception.expect(NullPointerException.class);
- accessSection.addPermission(null);
+ assertThrows(NullPointerException.class, () -> accessSection.addPermission(null));
}
@Test
@@ -166,9 +164,7 @@
assertThat(accessSection.getPermissions())
.containsExactly(abandonPermission, rebasePermission)
.inOrder();
-
- exception.expect(NullPointerException.class);
- accessSection.remove(null);
+ assertThrows(NullPointerException.class, () -> accessSection.remove(null));
}
@Test
@@ -187,8 +183,7 @@
.containsExactly(abandonPermission, rebasePermission)
.inOrder();
- exception.expect(NullPointerException.class);
- accessSection.removePermission(null);
+ assertThrows(NullPointerException.class, () -> accessSection.removePermission(null));
}
@Test
@@ -229,9 +224,7 @@
assertThat(accessSection1.getPermissions())
.containsExactly(abandonPermission, rebasePermission, submitPermission)
.inOrder();
-
- exception.expect(NullPointerException.class);
- accessSection.mergeFrom(null);
+ assertThrows(NullPointerException.class, () -> accessSection.mergeFrom(null));
}
@Test
diff --git a/javatests/com/google/gerrit/common/data/EncodePathSeparatorTest.java b/javatests/com/google/gerrit/common/data/EncodePathSeparatorTest.java
index 3dd2db3..dcd3c05 100644
--- a/javatests/com/google/gerrit/common/data/EncodePathSeparatorTest.java
+++ b/javatests/com/google/gerrit/common/data/EncodePathSeparatorTest.java
@@ -16,10 +16,9 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class EncodePathSeparatorTest extends GerritBaseTests {
+public class EncodePathSeparatorTest {
@Test
public void defaultBehaviour() {
assertThat(new GitwebType().replacePathSeparator("a/b")).isEqualTo("a/b");
diff --git a/javatests/com/google/gerrit/common/data/FilenameComparatorTest.java b/javatests/com/google/gerrit/common/data/FilenameComparatorTest.java
index 055f57d..ec71e05 100644
--- a/javatests/com/google/gerrit/common/data/FilenameComparatorTest.java
+++ b/javatests/com/google/gerrit/common/data/FilenameComparatorTest.java
@@ -16,10 +16,9 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class FilenameComparatorTest extends GerritBaseTests {
+public class FilenameComparatorTest {
private FilenameComparator comparator = FilenameComparator.INSTANCE;
@Test
diff --git a/javatests/com/google/gerrit/common/data/GroupReferenceTest.java b/javatests/com/google/gerrit/common/data/GroupReferenceTest.java
index 9b4f617..c4f59a1 100644
--- a/javatests/com/google/gerrit/common/data/GroupReferenceTest.java
+++ b/javatests/com/google/gerrit/common/data/GroupReferenceTest.java
@@ -15,13 +15,13 @@
package com.google.gerrit.common.data;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.AccountGroup.UUID;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class GroupReferenceTest extends GerritBaseTests {
+public class GroupReferenceTest {
@Test
public void forGroupDescription() {
String name = "foo";
@@ -75,8 +75,8 @@
@Test
public void cannotCreateWithoutName() {
- exception.expect(NullPointerException.class);
- new GroupReference(AccountGroup.uuid("uuid"), null);
+ assertThrows(
+ NullPointerException.class, () -> new GroupReference(AccountGroup.uuid("uuid"), null));
}
@Test
@@ -125,8 +125,7 @@
groupReference.setName(name2);
assertThat(groupReference.getName()).isEqualTo(name2);
- exception.expect(NullPointerException.class);
- groupReference.setName(null);
+ assertThrows(NullPointerException.class, () -> groupReference.setName(null));
}
@Test
diff --git a/javatests/com/google/gerrit/common/data/LabelFunctionTest.java b/javatests/com/google/gerrit/common/data/LabelFunctionTest.java
index f6b4300..8f2778a 100644
--- a/javatests/com/google/gerrit/common/data/LabelFunctionTest.java
+++ b/javatests/com/google/gerrit/common/data/LabelFunctionTest.java
@@ -22,14 +22,13 @@
import com.google.gerrit.reviewdb.client.LabelId;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
-import com.google.gerrit.testing.GerritBaseTests;
-import java.sql.Date;
import java.time.Instant;
import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
import org.junit.Test;
-public class LabelFunctionTest extends GerritBaseTests {
+public class LabelFunctionTest {
private static final String LABEL_NAME = "Verified";
private static final LabelId LABEL_ID = LabelId.create(LABEL_NAME);
private static final Change.Id CHANGE_ID = Change.id(100);
@@ -82,7 +81,7 @@
SubmitRecord.Label myLabel = LabelFunction.MAX_NO_BLOCK.check(VERIFIED_LABEL, approvals);
assertThat(myLabel.status).isEqualTo(SubmitRecord.Label.Status.OK);
- assertThat(myLabel.appliedBy).isEqualTo(APPROVAL_2.getAccountId());
+ assertThat(myLabel.appliedBy).isEqualTo(APPROVAL_2.accountId());
}
private static LabelType makeLabel() {
@@ -97,14 +96,11 @@
}
private static PatchSetApproval makeApproval(int value) {
- Account.Id accountId = Account.id(10000 + value);
- PatchSetApproval.Key key = makeKey(PS_ID, accountId, LABEL_ID);
- return new PatchSetApproval(key, (short) value, Date.from(Instant.now()));
- }
-
- private static PatchSetApproval.Key makeKey(
- PatchSet.Id psId, Account.Id accountId, LabelId labelId) {
- return PatchSetApproval.key(psId, accountId, labelId);
+ return PatchSetApproval.builder()
+ .key(PatchSetApproval.key(PS_ID, Account.id(10000 + value), LABEL_ID))
+ .value(value)
+ .granted(Date.from(Instant.now()))
+ .build();
}
private static void checkBlockWorks(LabelFunction function) {
@@ -113,7 +109,7 @@
SubmitRecord.Label myLabel = function.check(VERIFIED_LABEL, approvals);
assertThat(myLabel.status).isEqualTo(SubmitRecord.Label.Status.REJECT);
- assertThat(myLabel.appliedBy).isEqualTo(APPROVAL_M2.getAccountId());
+ assertThat(myLabel.appliedBy).isEqualTo(APPROVAL_M2.accountId());
}
private static void checkNothingHappens(LabelFunction function) {
@@ -144,6 +140,6 @@
SubmitRecord.Label myLabel = function.check(VERIFIED_LABEL, approvals);
assertThat(myLabel.status).isEqualTo(SubmitRecord.Label.Status.OK);
- assertThat(myLabel.appliedBy).isEqualTo(APPROVAL_2.getAccountId());
+ assertThat(myLabel.appliedBy).isEqualTo(APPROVAL_2.accountId());
}
}
diff --git a/javatests/com/google/gerrit/common/data/LabelTypeTest.java b/javatests/com/google/gerrit/common/data/LabelTypeTest.java
index db0df2e..6c3befb 100644
--- a/javatests/com/google/gerrit/common/data/LabelTypeTest.java
+++ b/javatests/com/google/gerrit/common/data/LabelTypeTest.java
@@ -17,10 +17,9 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.ImmutableList;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class LabelTypeTest extends GerritBaseTests {
+public class LabelTypeTest {
@Test
public void sortLabelValues() {
LabelValue v0 = new LabelValue((short) 0, "Zero");
diff --git a/javatests/com/google/gerrit/common/data/ParameterizedStringTest.java b/javatests/com/google/gerrit/common/data/ParameterizedStringTest.java
index b22a511..b646d2b 100644
--- a/javatests/com/google/gerrit/common/data/ParameterizedStringTest.java
+++ b/javatests/com/google/gerrit/common/data/ParameterizedStringTest.java
@@ -17,12 +17,11 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.ImmutableMap;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
-public class ParameterizedStringTest extends GerritBaseTests {
+public class ParameterizedStringTest {
@Test
public void emptyString() {
ParameterizedString p = new ParameterizedString("");
diff --git a/javatests/com/google/gerrit/common/data/PermissionRuleTest.java b/javatests/com/google/gerrit/common/data/PermissionRuleTest.java
index 77b3d81..1b70a8a 100644
--- a/javatests/com/google/gerrit/common/data/PermissionRuleTest.java
+++ b/javatests/com/google/gerrit/common/data/PermissionRuleTest.java
@@ -15,14 +15,14 @@
package com.google.gerrit.common.data;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.common.data.PermissionRule.Action;
import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Before;
import org.junit.Test;
-public class PermissionRuleTest extends GerritBaseTests {
+public class PermissionRuleTest {
private GroupReference groupReference;
private PermissionRule permissionRule;
@@ -42,8 +42,7 @@
@Test
public void cannotSetActionToNull() {
- exception.expect(NullPointerException.class);
- permissionRule.setAction(null);
+ assertThrows(NullPointerException.class, () -> permissionRule.setAction(null));
}
@Test
diff --git a/javatests/com/google/gerrit/common/data/PermissionTest.java b/javatests/com/google/gerrit/common/data/PermissionTest.java
index dd5b4c0..0202b10 100644
--- a/javatests/com/google/gerrit/common/data/PermissionTest.java
+++ b/javatests/com/google/gerrit/common/data/PermissionTest.java
@@ -18,13 +18,12 @@
import com.google.common.collect.ImmutableList;
import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
-public class PermissionTest extends GerritBaseTests {
+public class PermissionTest {
private static final String PERMISSION_NAME = "foo";
private Permission permission;
diff --git a/javatests/com/google/gerrit/common/data/SubmitRecordTest.java b/javatests/com/google/gerrit/common/data/SubmitRecordTest.java
index 5b9fde7..5386b87 100644
--- a/javatests/com/google/gerrit/common/data/SubmitRecordTest.java
+++ b/javatests/com/google/gerrit/common/data/SubmitRecordTest.java
@@ -16,12 +16,11 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.ArrayList;
import java.util.Collection;
import org.junit.Test;
-public class SubmitRecordTest extends GerritBaseTests {
+public class SubmitRecordTest {
private static final SubmitRecord OK_RECORD;
private static final SubmitRecord FORCED_RECORD;
private static final SubmitRecord NOT_READY_RECORD;
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticConfigurationTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticConfigurationTest.java
index 9ce1456..7e044c3 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticConfigurationTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticConfigurationTest.java
@@ -21,17 +21,17 @@
import static com.google.gerrit.elasticsearch.ElasticConfiguration.KEY_SERVER;
import static com.google.gerrit.elasticsearch.ElasticConfiguration.KEY_USERNAME;
import static com.google.gerrit.elasticsearch.ElasticConfiguration.SECTION_ELASTICSEARCH;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.toList;
import com.google.common.collect.ImmutableList;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.inject.ProvisionException;
import java.util.Arrays;
import org.apache.http.HttpHost;
import org.eclipse.jgit.lib.Config;
import org.junit.Test;
-public class ElasticConfigurationTest extends GerritBaseTests {
+public class ElasticConfigurationTest {
@Test
public void singleServerNoOtherConfig() throws Exception {
Config cfg = newConfig();
@@ -121,9 +121,9 @@
.containsExactly(hostURIs);
}
- private void assertProvisionException(Config cfg) throws Exception {
- exception.expect(ProvisionException.class);
- exception.expectMessage("No valid Elasticsearch servers configured");
- new ElasticConfiguration(cfg);
+ private void assertProvisionException(Config cfg) {
+ ProvisionException thrown =
+ assertThrows(ProvisionException.class, () -> new ElasticConfiguration(cfg));
+ assertThat(thrown).hasMessageThat().contains("No valid Elasticsearch servers configured");
}
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java b/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
index 8400d02..adcfcb5 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
@@ -49,9 +49,11 @@
case V6_6:
return "docker.elastic.co/elasticsearch/elasticsearch-oss:6.6.2";
case V6_7:
- return "docker.elastic.co/elasticsearch/elasticsearch-oss:6.7.1";
+ return "docker.elastic.co/elasticsearch/elasticsearch-oss:6.7.2";
case V7_0:
- return "docker.elastic.co/elasticsearch/elasticsearch-oss:7.0.0";
+ return "docker.elastic.co/elasticsearch/elasticsearch-oss:7.0.1";
+ case V7_1:
+ return "docker.elastic.co/elasticsearch/elasticsearch-oss:7.1.0";
}
throw new IllegalStateException("No tests for version: " + version.name());
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticTestUtils.java b/javatests/com/google/gerrit/elasticsearch/ElasticTestUtils.java
index 9aaf4bb..6802873 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticTestUtils.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticTestUtils.java
@@ -15,7 +15,6 @@
package com.google.gerrit.elasticsearch;
import com.google.gerrit.index.IndexDefinition;
-import com.google.gerrit.server.index.IndexModule.IndexType;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
@@ -33,7 +32,7 @@
}
public static void configure(Config config, int port, String prefix, ElasticVersion version) {
- config.setEnum("index", null, "type", IndexType.ELASTICSEARCH);
+ config.setString("index", null, "type", "elasticsearch");
config.setString("elasticsearch", null, "server", "http://localhost:" + port);
config.setString("elasticsearch", null, "prefix", prefix);
config.setInt("index", null, "maxLimit", 10000);
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryAccountsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryAccountsTest.java
index 27868d2..e5bd19f 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryAccountsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryAccountsTest.java
@@ -62,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = getSanitizedMethodName();
+ String indicesPrefix = testName.getSanitizedMethodName();
ElasticTestUtils.configure(
elasticsearchConfig, nodeInfo.port, indicesPrefix, ElasticVersion.V5_6);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig));
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryChangesTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryChangesTest.java
index 2e4e22a..e1aadb8 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryChangesTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryChangesTest.java
@@ -17,6 +17,7 @@
import com.google.gerrit.elasticsearch.ElasticTestUtils.ElasticNodeInfo;
import com.google.gerrit.server.query.change.AbstractQueryChangesTest;
import com.google.gerrit.testing.ConfigSuite;
+import com.google.gerrit.testing.GerritTestName;
import com.google.gerrit.testing.InMemoryModule;
import com.google.gerrit.testing.IndexConfig;
import com.google.inject.Guice;
@@ -24,6 +25,7 @@
import org.eclipse.jgit.lib.Config;
import org.junit.AfterClass;
import org.junit.BeforeClass;
+import org.junit.Rule;
public class ElasticV5QueryChangesTest extends AbstractQueryChangesTest {
@ConfigSuite.Default
@@ -52,6 +54,8 @@
}
}
+ @Rule public final GerritTestName testName = new GerritTestName();
+
@Override
protected void initAfterLifecycleStart() throws Exception {
super.initAfterLifecycleStart();
@@ -62,7 +66,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = getSanitizedMethodName();
+ String indicesPrefix = testName.getSanitizedMethodName();
ElasticTestUtils.configure(
elasticsearchConfig, nodeInfo.port, indicesPrefix, ElasticVersion.V5_6);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig));
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryGroupsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryGroupsTest.java
index 98c4321..fcec859 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryGroupsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryGroupsTest.java
@@ -62,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = getSanitizedMethodName();
+ String indicesPrefix = testName.getSanitizedMethodName();
ElasticTestUtils.configure(
elasticsearchConfig, nodeInfo.port, indicesPrefix, ElasticVersion.V5_6);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig));
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java
index 6b4b58c..16f06d5 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java
@@ -62,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = getSanitizedMethodName();
+ String indicesPrefix = testName.getSanitizedMethodName();
ElasticTestUtils.configure(
elasticsearchConfig, nodeInfo.port, indicesPrefix, ElasticVersion.V5_6);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig));
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryAccountsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryAccountsTest.java
index 219eecd..9c79270 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryAccountsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryAccountsTest.java
@@ -62,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = getSanitizedMethodName();
+ String indicesPrefix = testName.getSanitizedMethodName();
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig));
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java
index 1b0822c..8a20e07 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryChangesTest.java
@@ -17,6 +17,7 @@
import com.google.gerrit.elasticsearch.ElasticTestUtils.ElasticNodeInfo;
import com.google.gerrit.server.query.change.AbstractQueryChangesTest;
import com.google.gerrit.testing.ConfigSuite;
+import com.google.gerrit.testing.GerritTestName;
import com.google.gerrit.testing.InMemoryModule;
import com.google.gerrit.testing.IndexConfig;
import com.google.inject.Guice;
@@ -24,6 +25,7 @@
import org.eclipse.jgit.lib.Config;
import org.junit.AfterClass;
import org.junit.BeforeClass;
+import org.junit.Rule;
public class ElasticV6QueryChangesTest extends AbstractQueryChangesTest {
@ConfigSuite.Default
@@ -52,6 +54,8 @@
}
}
+ @Rule public final GerritTestName testName = new GerritTestName();
+
@Override
protected void initAfterLifecycleStart() throws Exception {
super.initAfterLifecycleStart();
@@ -62,7 +66,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = getSanitizedMethodName();
+ String indicesPrefix = testName.getSanitizedMethodName();
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig));
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryGroupsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryGroupsTest.java
index 2782b7f..4f152bd 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryGroupsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryGroupsTest.java
@@ -62,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = getSanitizedMethodName();
+ String indicesPrefix = testName.getSanitizedMethodName();
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig));
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryProjectsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryProjectsTest.java
index f01138a..96d9296 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryProjectsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV6QueryProjectsTest.java
@@ -62,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = getSanitizedMethodName();
+ String indicesPrefix = testName.getSanitizedMethodName();
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig));
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
index 6972a18..78c3684 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryAccountsTest.java
@@ -41,7 +41,7 @@
return;
}
- container = ElasticContainer.createAndStart(ElasticVersion.V7_0);
+ container = ElasticContainer.createAndStart(ElasticVersion.V7_1);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
}
@@ -62,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = getSanitizedMethodName();
+ String indicesPrefix = testName.getSanitizedMethodName();
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig));
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
index 988abca..ae00e0d 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryChangesTest.java
@@ -14,9 +14,12 @@
package com.google.gerrit.elasticsearch;
+import static java.util.concurrent.TimeUnit.MINUTES;
+
import com.google.gerrit.elasticsearch.ElasticTestUtils.ElasticNodeInfo;
import com.google.gerrit.server.query.change.AbstractQueryChangesTest;
import com.google.gerrit.testing.ConfigSuite;
+import com.google.gerrit.testing.GerritTestName;
import com.google.gerrit.testing.InMemoryModule;
import com.google.gerrit.testing.IndexConfig;
import com.google.inject.Guice;
@@ -29,6 +32,7 @@
import org.junit.After;
import org.junit.AfterClass;
import org.junit.BeforeClass;
+import org.junit.Rule;
public class ElasticV7QueryChangesTest extends AbstractQueryChangesTest {
@ConfigSuite.Default
@@ -47,7 +51,7 @@
return;
}
- container = ElasticContainer.createAndStart(ElasticVersion.V7_0);
+ container = ElasticContainer.createAndStart(ElasticVersion.V7_1);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
client = HttpAsyncClients.createDefault();
client.start();
@@ -60,14 +64,19 @@
}
}
+ @Rule public final GerritTestName testName = new GerritTestName();
+
@After
- public void closeIndex() {
- client.execute(
- new HttpPost(
- String.format(
- "http://localhost:%d/%s*/_close", nodeInfo.port, getSanitizedMethodName())),
- HttpClientContext.create(),
- null);
+ public void closeIndex() throws Exception {
+ client
+ .execute(
+ new HttpPost(
+ String.format(
+ "http://localhost:%d/%s*/_close",
+ nodeInfo.port, testName.getSanitizedMethodName())),
+ HttpClientContext.create(),
+ null)
+ .get(5, MINUTES);
}
@Override
@@ -80,7 +89,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = getSanitizedMethodName();
+ String indicesPrefix = testName.getSanitizedMethodName();
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig));
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
index 534bc36..301b5dd 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryGroupsTest.java
@@ -41,7 +41,7 @@
return;
}
- container = ElasticContainer.createAndStart(ElasticVersion.V7_0);
+ container = ElasticContainer.createAndStart(ElasticVersion.V7_1);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
}
@@ -62,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = getSanitizedMethodName();
+ String indicesPrefix = testName.getSanitizedMethodName();
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig));
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
index 1f4653c..e1b7e3f 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticV7QueryProjectsTest.java
@@ -41,7 +41,7 @@
return;
}
- container = ElasticContainer.createAndStart(ElasticVersion.V7_0);
+ container = ElasticContainer.createAndStart(ElasticVersion.V7_1);
nodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort());
}
@@ -62,7 +62,7 @@
protected Injector createInjector() {
Config elasticsearchConfig = new Config(config);
InMemoryModule.setDefaults(elasticsearchConfig);
- String indicesPrefix = getSanitizedMethodName();
+ String indicesPrefix = testName.getSanitizedMethodName();
ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix);
return Guice.createInjector(new InMemoryModule(elasticsearchConfig));
}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java
index 61ad068..0bd33c6 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticVersionTest.java
@@ -15,11 +15,11 @@
package com.google.gerrit.elasticsearch;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class ElasticVersionTest extends GerritBaseTests {
+public class ElasticVersionTest {
@Test
public void supportedVersion() throws Exception {
assertThat(ElasticVersion.forVersion("5.6.0")).isEqualTo(ElasticVersion.V5_6);
@@ -49,10 +49,14 @@
@Test
public void unsupportedVersion() throws Exception {
- exception.expect(ElasticVersion.UnsupportedVersion.class);
- exception.expectMessage(
- "Unsupported version: [4.0.0]. Supported versions: " + ElasticVersion.supportedVersions());
- ElasticVersion.forVersion("4.0.0");
+ ElasticVersion.UnsupportedVersion thrown =
+ assertThrows(
+ ElasticVersion.UnsupportedVersion.class, () -> ElasticVersion.forVersion("4.0.0"));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ "Unsupported version: [4.0.0]. Supported versions: "
+ + ElasticVersion.supportedVersions());
}
@Test
@@ -63,10 +67,23 @@
assertThat(ElasticVersion.V6_4.isV6OrLater()).isTrue();
assertThat(ElasticVersion.V6_5.isV6OrLater()).isTrue();
assertThat(ElasticVersion.V6_6.isV6OrLater()).isTrue();
+ assertThat(ElasticVersion.V6_7.isV6OrLater()).isTrue();
assertThat(ElasticVersion.V7_0.isV6OrLater()).isTrue();
}
@Test
+ public void atLeastMinorVersion() throws Exception {
+ assertThat(ElasticVersion.V5_6.isAtLeastMinorVersion(ElasticVersion.V6_7)).isFalse();
+ assertThat(ElasticVersion.V6_2.isAtLeastMinorVersion(ElasticVersion.V6_7)).isFalse();
+ assertThat(ElasticVersion.V6_3.isAtLeastMinorVersion(ElasticVersion.V6_7)).isFalse();
+ assertThat(ElasticVersion.V6_4.isAtLeastMinorVersion(ElasticVersion.V6_7)).isFalse();
+ assertThat(ElasticVersion.V6_5.isAtLeastMinorVersion(ElasticVersion.V6_7)).isFalse();
+ assertThat(ElasticVersion.V6_6.isAtLeastMinorVersion(ElasticVersion.V6_7)).isFalse();
+ assertThat(ElasticVersion.V6_7.isAtLeastMinorVersion(ElasticVersion.V6_7)).isTrue();
+ assertThat(ElasticVersion.V7_0.isAtLeastMinorVersion(ElasticVersion.V6_7)).isFalse();
+ }
+
+ @Test
public void version7() throws Exception {
assertThat(ElasticVersion.V5_6.isV7OrLater()).isFalse();
assertThat(ElasticVersion.V6_2.isV7OrLater()).isFalse();
@@ -74,6 +91,7 @@
assertThat(ElasticVersion.V6_4.isV7OrLater()).isFalse();
assertThat(ElasticVersion.V6_5.isV7OrLater()).isFalse();
assertThat(ElasticVersion.V6_6.isV7OrLater()).isFalse();
+ assertThat(ElasticVersion.V6_7.isV7OrLater()).isFalse();
assertThat(ElasticVersion.V7_0.isV7OrLater()).isTrue();
}
}
diff --git a/javatests/com/google/gerrit/extensions/api/lfs/LfsDefinitionsTest.java b/javatests/com/google/gerrit/extensions/api/lfs/LfsDefinitionsTest.java
index 86dce04..0be10ee 100644
--- a/javatests/com/google/gerrit/extensions/api/lfs/LfsDefinitionsTest.java
+++ b/javatests/com/google/gerrit/extensions/api/lfs/LfsDefinitionsTest.java
@@ -16,12 +16,11 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Test;
-public class LfsDefinitionsTest extends GerritBaseTests {
+public class LfsDefinitionsTest {
private static final String[] URL_PREFIXES = new String[] {"/", "/a/", "/p/", "/a/p/"};
@Test
diff --git a/javatests/com/google/gerrit/extensions/client/ListOptionTest.java b/javatests/com/google/gerrit/extensions/client/ListOptionTest.java
index 4bb9107..5e8c7b6 100644
--- a/javatests/com/google/gerrit/extensions/client/ListOptionTest.java
+++ b/javatests/com/google/gerrit/extensions/client/ListOptionTest.java
@@ -21,11 +21,10 @@
import static com.google.gerrit.extensions.client.ListOptionTest.MyOption.FOO;
import com.google.common.math.IntMath;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.EnumSet;
import org.junit.Test;
-public class ListOptionTest extends GerritBaseTests {
+public class ListOptionTest {
enum MyOption implements ListOption {
FOO(0),
BAR(1),
diff --git a/javatests/com/google/gerrit/extensions/client/RangeTest.java b/javatests/com/google/gerrit/extensions/client/RangeTest.java
index 2c713b5..b8938aa 100644
--- a/javatests/com/google/gerrit/extensions/client/RangeTest.java
+++ b/javatests/com/google/gerrit/extensions/client/RangeTest.java
@@ -16,10 +16,9 @@
import static com.google.gerrit.extensions.common.testing.RangeSubject.assertThat;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class RangeTest extends GerritBaseTests {
+public class RangeTest {
@Test
public void rangeOverMultipleLinesWithSmallerEndCharacterIsValid() {
diff --git a/javatests/com/google/gerrit/extensions/conditions/BooleanConditionTest.java b/javatests/com/google/gerrit/extensions/conditions/BooleanConditionTest.java
index 81cb719..f9f1fa85 100644
--- a/javatests/com/google/gerrit/extensions/conditions/BooleanConditionTest.java
+++ b/javatests/com/google/gerrit/extensions/conditions/BooleanConditionTest.java
@@ -20,10 +20,9 @@
import static com.google.gerrit.extensions.conditions.BooleanCondition.valueOf;
import static org.junit.Assert.assertEquals;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class BooleanConditionTest extends GerritBaseTests {
+public class BooleanConditionTest {
private static final BooleanCondition NO_TRIVIAL_EVALUATION =
new BooleanCondition() {
diff --git a/javatests/com/google/gerrit/extensions/registration/DynamicSetTest.java b/javatests/com/google/gerrit/extensions/registration/DynamicSetTest.java
index d950224..0542c35 100644
--- a/javatests/com/google/gerrit/extensions/registration/DynamicSetTest.java
+++ b/javatests/com/google/gerrit/extensions/registration/DynamicSetTest.java
@@ -17,14 +17,13 @@
import static com.google.common.truth.Truth.assertThat;
import static java.util.stream.Collectors.toSet;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.util.Providers;
import java.util.Iterator;
import org.junit.Test;
-public class DynamicSetTest extends GerritBaseTests {
+public class DynamicSetTest {
// In tests for {@link DynamicSet#contains(Object)}, be sure to avoid
// {@code assertThat(ds).contains(...) @} and
// {@code assertThat(ds).DoesNotContains(...) @} as (since
diff --git a/javatests/com/google/gerrit/git/ObjectIdsTest.java b/javatests/com/google/gerrit/git/ObjectIdsTest.java
index 36c10a4..b254d6f 100644
--- a/javatests/com/google/gerrit/git/ObjectIdsTest.java
+++ b/javatests/com/google/gerrit/git/ObjectIdsTest.java
@@ -15,8 +15,9 @@
package com.google.gerrit.git;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
+import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.gerrit.git.ObjectIds.abbreviateName;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.eclipse.jgit.lib.Constants.OBJECT_ID_STRING_LENGTH;
import java.util.function.Function;
@@ -26,6 +27,7 @@
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevBlob;
import org.junit.Test;
@@ -111,8 +113,8 @@
assertThat(ObjectIds.matchesAbbreviation(ID, "")).isTrue();
for (int i = 1; i <= OBJECT_ID_STRING_LENGTH; i++) {
String prefix = ID.name().substring(0, i);
- assertThat(ObjectIds.matchesAbbreviation(ID, prefix))
- .named("match %s against %s", ID.name(), prefix)
+ assertWithMessage("match %s against %s", ID.name(), prefix)
+ .that(ObjectIds.matchesAbbreviation(ID, prefix))
.isTrue();
}
@@ -128,24 +130,20 @@
}
private static void assertRuntimeException(Func func) throws Exception {
- try {
- func.call();
- assert_().fail("Expected RuntimeException");
- } catch (RuntimeException e) {
- // Expected.
- }
+ assertThrows(RuntimeException.class, () -> func.call());
}
private static ObjectReader newReaderWithAmbiguousIds() throws Exception {
// Recipe for creating ambiguous IDs courtesy of git core:
// https://github.com/git/git/blob/df799f5d99ac51d4fc791d546de3f936088582fc/t/t1512-rev-parse-disambiguation.sh
- TestRepository<?> tr =
- new TestRepository<>(new InMemoryRepository(new DfsRepositoryDescription("repo")));
- String blobData = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n\nb1rwzyc3\n";
- RevBlob blob = tr.blob(blobData);
- assertThat(blob.name()).isEqualTo(AMBIGUOUS_BLOB_ID.name());
- assertThat(tr.tree(tr.file("a0blgqsjc", blob)).name()).isEqualTo(AMBIGUOUS_TREE_ID.name());
- return tr.getRevWalk().getObjectReader();
+ try (TestRepository<Repository> tr =
+ new TestRepository<>(new InMemoryRepository(new DfsRepositoryDescription("repo")))) {
+ String blobData = "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n\nb1rwzyc3\n";
+ RevBlob blob = tr.blob(blobData);
+ assertThat(blob.name()).isEqualTo(AMBIGUOUS_BLOB_ID.name());
+ assertThat(tr.tree(tr.file("a0blgqsjc", blob)).name()).isEqualTo(AMBIGUOUS_TREE_ID.name());
+ return tr.getRevWalk().getObjectReader();
+ }
}
private static class MyObjectId extends ObjectId {
diff --git a/javatests/com/google/gerrit/git/RefUpdateUtilRepoTest.java b/javatests/com/google/gerrit/git/RefUpdateUtilRepoTest.java
index cdc94c2..60b90f3 100644
--- a/javatests/com/google/gerrit/git/RefUpdateUtilRepoTest.java
+++ b/javatests/com/google/gerrit/git/RefUpdateUtilRepoTest.java
@@ -19,7 +19,6 @@
import com.google.common.collect.ImmutableList;
import com.google.common.io.MoreFiles;
import com.google.common.io.RecursiveDeleteOption;
-import com.google.gerrit.testing.GerritBaseTests;
import java.nio.file.Files;
import java.nio.file.Path;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
@@ -36,7 +35,7 @@
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
-public class RefUpdateUtilRepoTest extends GerritBaseTests {
+public class RefUpdateUtilRepoTest {
public enum RepoSetup {
LOCAL_DISK {
@Override
@@ -110,7 +109,10 @@
@Test
public void deleteRef() throws Exception {
String ref = "refs/heads/foo";
- new TestRepository<>(repo).branch(ref).commit().create();
+ try (TestRepository<Repository> tr = new TestRepository<>(repo)) {
+ tr.branch(ref).commit().create();
+ }
+
assertThat(repo.exactRef(ref)).isNotNull();
RefUpdateUtil.deleteChecked(repo, "refs/heads/foo");
assertThat(repo.exactRef(ref)).isNull();
diff --git a/javatests/com/google/gerrit/git/RefUpdateUtilTest.java b/javatests/com/google/gerrit/git/RefUpdateUtilTest.java
index 429583a..1d021f7 100644
--- a/javatests/com/google/gerrit/git/RefUpdateUtilTest.java
+++ b/javatests/com/google/gerrit/git/RefUpdateUtilTest.java
@@ -16,10 +16,9 @@
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableList;
-import com.google.gerrit.testing.GerritBaseTests;
import java.io.IOException;
import java.util.function.Consumer;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
@@ -33,7 +32,7 @@
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
-public class RefUpdateUtilTest extends GerritBaseTests {
+public class RefUpdateUtilTest {
private static final Consumer<ReceiveCommand> OK = c -> c.setResult(ReceiveCommand.Result.OK);
private static final Consumer<ReceiveCommand> LOCK_FAILURE =
c -> c.setResult(ReceiveCommand.Result.LOCK_FAILURE);
@@ -81,23 +80,18 @@
@SafeVarargs
private static void assertIoException(Consumer<ReceiveCommand>... resultSetters) {
- try {
- RefUpdateUtil.checkResults(newBatchRefUpdate(resultSetters));
- assert_().fail("expected IOException");
- } catch (IOException e) {
- assertThat(e).isNotInstanceOf(LockFailureException.class);
- }
+ IOException thrown =
+ assertThrows(
+ IOException.class, () -> RefUpdateUtil.checkResults(newBatchRefUpdate(resultSetters)));
+ assertThat(thrown).isNotInstanceOf(LockFailureException.class);
}
@SafeVarargs
private static void assertLockFailureException(Consumer<ReceiveCommand>... resultSetters)
throws Exception {
- try {
- RefUpdateUtil.checkResults(newBatchRefUpdate(resultSetters));
- assert_().fail("expected LockFailureException");
- } catch (LockFailureException e) {
- // Expected.
- }
+ assertThrows(
+ LockFailureException.class,
+ () -> RefUpdateUtil.checkResults(newBatchRefUpdate(resultSetters)));
}
@SafeVarargs
diff --git a/javatests/com/google/gerrit/git/testing/PushResultSubjectTest.java b/javatests/com/google/gerrit/git/testing/PushResultSubjectTest.java
index 5ab52d4..3bf815b 100644
--- a/javatests/com/google/gerrit/git/testing/PushResultSubjectTest.java
+++ b/javatests/com/google/gerrit/git/testing/PushResultSubjectTest.java
@@ -18,10 +18,9 @@
import static com.google.gerrit.git.testing.PushResultSubject.parseProcessed;
import static com.google.gerrit.git.testing.PushResultSubject.trimMessages;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class PushResultSubjectTest extends GerritBaseTests {
+public class PushResultSubjectTest {
@Test
public void testTrimMessages() {
assertThat(trimMessages(null)).isNull();
diff --git a/javatests/com/google/gerrit/gpg/GerritPublicKeyCheckerTest.java b/javatests/com/google/gerrit/gpg/GerritPublicKeyCheckerTest.java
index 220361e..bc035af 100644
--- a/javatests/com/google/gerrit/gpg/GerritPublicKeyCheckerTest.java
+++ b/javatests/com/google/gerrit/gpg/GerritPublicKeyCheckerTest.java
@@ -41,7 +41,6 @@
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.schema.SchemaCreator;
import com.google.gerrit.server.util.ThreadLocalRequestContext;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.InMemoryModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
@@ -64,7 +63,7 @@
import org.junit.Test;
/** Unit tests for {@link GerritPublicKeyChecker}. */
-public class GerritPublicKeyCheckerTest extends GerritBaseTests {
+public class GerritPublicKeyCheckerTest {
@Inject @ServerInitiated private Provider<AccountsUpdate> accountsUpdateProvider;
@Inject private AccountManager accountManager;
diff --git a/javatests/com/google/gerrit/gpg/PublicKeyCheckerTest.java b/javatests/com/google/gerrit/gpg/PublicKeyCheckerTest.java
index 145b9cf..7703fb0 100644
--- a/javatests/com/google/gerrit/gpg/PublicKeyCheckerTest.java
+++ b/javatests/com/google/gerrit/gpg/PublicKeyCheckerTest.java
@@ -38,7 +38,6 @@
import static org.junit.Assert.assertEquals;
import com.google.gerrit.gpg.testing.TestKey;
-import com.google.gerrit.testing.GerritBaseTests;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
@@ -60,7 +59,7 @@
import org.junit.Before;
import org.junit.Test;
-public class PublicKeyCheckerTest extends GerritBaseTests {
+public class PublicKeyCheckerTest {
private InMemoryRepository repo;
private PublicKeyStore store;
diff --git a/javatests/com/google/gerrit/gpg/PublicKeyStoreTest.java b/javatests/com/google/gerrit/gpg/PublicKeyStoreTest.java
index be65752..3727d38 100644
--- a/javatests/com/google/gerrit/gpg/PublicKeyStoreTest.java
+++ b/javatests/com/google/gerrit/gpg/PublicKeyStoreTest.java
@@ -29,7 +29,6 @@
import com.google.common.collect.Iterators;
import com.google.gerrit.gpg.testing.TestKey;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
@@ -51,7 +50,7 @@
import org.junit.Before;
import org.junit.Test;
-public class PublicKeyStoreTest extends GerritBaseTests {
+public class PublicKeyStoreTest {
private TestRepository<?> tr;
private PublicKeyStore store;
diff --git a/javatests/com/google/gerrit/gpg/PushCertificateCheckerTest.java b/javatests/com/google/gerrit/gpg/PushCertificateCheckerTest.java
index 67bf050..266f868 100644
--- a/javatests/com/google/gerrit/gpg/PushCertificateCheckerTest.java
+++ b/javatests/com/google/gerrit/gpg/PushCertificateCheckerTest.java
@@ -23,7 +23,6 @@
import static org.junit.Assert.assertEquals;
import com.google.gerrit.gpg.testing.TestKey;
-import com.google.gerrit.testing.GerritBaseTests;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStreamReader;
@@ -54,7 +53,7 @@
import org.junit.Before;
import org.junit.Test;
-public class PushCertificateCheckerTest extends GerritBaseTests {
+public class PushCertificateCheckerTest {
private InMemoryRepository repo;
private PublicKeyStore store;
private SignedPushConfig signedPushConfig;
diff --git a/javatests/com/google/gerrit/httpd/AllRequestFilterFilterProxyTest.java b/javatests/com/google/gerrit/httpd/AllRequestFilterFilterProxyTest.java
index e2c58d8..1c6559b0 100644
--- a/javatests/com/google/gerrit/httpd/AllRequestFilterFilterProxyTest.java
+++ b/javatests/com/google/gerrit/httpd/AllRequestFilterFilterProxyTest.java
@@ -21,7 +21,6 @@
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.registration.ReloadableRegistrationHandle;
import com.google.gerrit.server.plugins.Plugin;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.util.http.testutil.FakeHttpServletRequest;
import com.google.gerrit.util.http.testutil.FakeHttpServletResponse;
import com.google.inject.Key;
@@ -36,7 +35,7 @@
import org.junit.Before;
import org.junit.Test;
-public class AllRequestFilterFilterProxyTest extends GerritBaseTests {
+public class AllRequestFilterFilterProxyTest {
/**
* Set of filters for FilterProxy
*
diff --git a/javatests/com/google/gerrit/httpd/RemoteUserUtilTest.java b/javatests/com/google/gerrit/httpd/RemoteUserUtilTest.java
index e19085d..f012ee3 100644
--- a/javatests/com/google/gerrit/httpd/RemoteUserUtilTest.java
+++ b/javatests/com/google/gerrit/httpd/RemoteUserUtilTest.java
@@ -17,10 +17,9 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.httpd.RemoteUserUtil.extractUsername;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class RemoteUserUtilTest extends GerritBaseTests {
+public class RemoteUserUtilTest {
@Test
public void testExtractUsername() {
assertThat(extractUsername(null)).isNull();
diff --git a/javatests/com/google/gerrit/httpd/plugins/ContextMapperTest.java b/javatests/com/google/gerrit/httpd/plugins/ContextMapperTest.java
index 2de3788..684a241 100644
--- a/javatests/com/google/gerrit/httpd/plugins/ContextMapperTest.java
+++ b/javatests/com/google/gerrit/httpd/plugins/ContextMapperTest.java
@@ -16,12 +16,11 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.util.http.testutil.FakeHttpServletRequest;
import javax.servlet.http.HttpServletRequest;
import org.junit.Test;
-public class ContextMapperTest extends GerritBaseTests {
+public class ContextMapperTest {
private static final String CONTEXT = "/context";
private static final String PLUGIN_NAME = "my-plugin";
diff --git a/javatests/com/google/gerrit/httpd/raw/IndexHtmlUtilTest.java b/javatests/com/google/gerrit/httpd/raw/IndexHtmlUtilTest.java
new file mode 100644
index 0000000..a4b6ab2
--- /dev/null
+++ b/javatests/com/google/gerrit/httpd/raw/IndexHtmlUtilTest.java
@@ -0,0 +1,66 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.httpd.raw;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.httpd.raw.IndexHtmlUtil.staticTemplateData;
+
+import com.google.template.soy.data.SanitizedContent;
+import com.google.template.soy.data.UnsafeSanitizedContentOrdainer;
+import org.junit.Test;
+
+public class IndexHtmlUtilTest {
+ @Test
+ public void noPathAndNoCDN() throws Exception {
+ assertThat(staticTemplateData("http://example.com/", null, null, IndexHtmlUtilTest::ordain))
+ .containsExactly("canonicalPath", "", "staticResourcePath", ordain(""));
+ }
+
+ @Test
+ public void pathAndNoCDN() throws Exception {
+ assertThat(
+ staticTemplateData("http://example.com/gerrit/", null, null, IndexHtmlUtilTest::ordain))
+ .containsExactly("canonicalPath", "/gerrit", "staticResourcePath", ordain("/gerrit"));
+ }
+
+ @Test
+ public void noPathAndCDN() throws Exception {
+ assertThat(
+ staticTemplateData(
+ "http://example.com/",
+ "http://my-cdn.com/foo/bar/",
+ null,
+ IndexHtmlUtilTest::ordain))
+ .containsExactly(
+ "canonicalPath", "", "staticResourcePath", ordain("http://my-cdn.com/foo/bar/"));
+ }
+
+ @Test
+ public void pathAndCDN() throws Exception {
+ assertThat(
+ staticTemplateData(
+ "http://example.com/gerrit",
+ "http://my-cdn.com/foo/bar/",
+ null,
+ IndexHtmlUtilTest::ordain))
+ .containsExactly(
+ "canonicalPath", "/gerrit", "staticResourcePath", ordain("http://my-cdn.com/foo/bar/"));
+ }
+
+ private static SanitizedContent ordain(String s) {
+ return UnsafeSanitizedContentOrdainer.ordainAsSafe(
+ s, SanitizedContent.ContentKind.TRUSTED_RESOURCE_URI);
+ }
+}
diff --git a/javatests/com/google/gerrit/httpd/raw/IndexServletTest.java b/javatests/com/google/gerrit/httpd/raw/IndexServletTest.java
index b4f8e7a..99835dd 100644
--- a/javatests/com/google/gerrit/httpd/raw/IndexServletTest.java
+++ b/javatests/com/google/gerrit/httpd/raw/IndexServletTest.java
@@ -15,67 +15,64 @@
package com.google.gerrit.httpd.raw;
import static com.google.common.truth.Truth.assertThat;
-import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
-import com.google.gerrit.testing.GerritBaseTests;
-import com.google.template.soy.data.SoyMapData;
-import java.net.URISyntaxException;
+import com.google.common.collect.ImmutableList;
+import com.google.gerrit.extensions.api.GerritApi;
+import com.google.gerrit.extensions.api.accounts.Accounts;
+import com.google.gerrit.extensions.api.config.Config;
+import com.google.gerrit.extensions.api.config.Server;
+import com.google.gerrit.extensions.common.ServerInfo;
+import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.util.http.testutil.FakeHttpServletRequest;
+import com.google.gerrit.util.http.testutil.FakeHttpServletResponse;
import org.junit.Test;
-public class IndexServletTest extends GerritBaseTests {
- static class TestIndexServlet extends IndexServlet {
- private static final long serialVersionUID = 1L;
-
- TestIndexServlet(String canonicalURL, String cdnPath, String faviconPath)
- throws URISyntaxException {
- super(canonicalURL, cdnPath, faviconPath);
- }
-
- String getIndexSource() {
- return new String(indexSource, UTF_8);
- }
- }
+public class IndexServletTest {
@Test
- public void noPathAndNoCDN() throws URISyntaxException {
- SoyMapData data = IndexServlet.getTemplateData("http://example.com/", null, null);
- assertThat(data.getSingle("canonicalPath").stringValue()).isEqualTo("");
- assertThat(data.getSingle("staticResourcePath").stringValue()).isEqualTo("");
- }
+ public void renderTemplate() throws Exception {
+ Accounts accountsApi = createMock(Accounts.class);
+ expect(accountsApi.self()).andThrow(new AuthException("user needs to be authenticated"));
- @Test
- public void pathAndNoCDN() throws URISyntaxException {
- SoyMapData data = IndexServlet.getTemplateData("http://example.com/gerrit/", null, null);
- assertThat(data.getSingle("canonicalPath").stringValue()).isEqualTo("/gerrit");
- assertThat(data.getSingle("staticResourcePath").stringValue()).isEqualTo("/gerrit");
- }
+ Server serverApi = createMock(Server.class);
+ expect(serverApi.getVersion()).andReturn("123");
+ expect(serverApi.topMenus()).andReturn(ImmutableList.of());
+ ServerInfo serverInfo = new ServerInfo();
+ serverInfo.defaultTheme = "my-default-theme";
+ expect(serverApi.getInfo()).andReturn(serverInfo);
- @Test
- public void noPathAndCDN() throws URISyntaxException {
- SoyMapData data =
- IndexServlet.getTemplateData("http://example.com/", "http://my-cdn.com/foo/bar/", null);
- assertThat(data.getSingle("canonicalPath").stringValue()).isEqualTo("");
- assertThat(data.getSingle("staticResourcePath").stringValue())
- .isEqualTo("http://my-cdn.com/foo/bar/");
- }
+ Config configApi = createMock(Config.class);
+ expect(configApi.server()).andReturn(serverApi);
- @Test
- public void pathAndCDN() throws URISyntaxException {
- SoyMapData data =
- IndexServlet.getTemplateData(
- "http://example.com/gerrit", "http://my-cdn.com/foo/bar/", null);
- assertThat(data.getSingle("canonicalPath").stringValue()).isEqualTo("/gerrit");
- assertThat(data.getSingle("staticResourcePath").stringValue())
- .isEqualTo("http://my-cdn.com/foo/bar/");
- }
+ GerritApi gerritApi = createMock(GerritApi.class);
+ expect(gerritApi.accounts()).andReturn(accountsApi);
+ expect(gerritApi.config()).andReturn(configApi);
- @Test
- public void renderTemplate() throws URISyntaxException {
String testCanonicalUrl = "foo-url";
String testCdnPath = "bar-cdn";
String testFaviconURL = "zaz-url";
- TestIndexServlet servlet = new TestIndexServlet(testCanonicalUrl, testCdnPath, testFaviconURL);
- String output = servlet.getIndexSource();
+ IndexServlet servlet =
+ new IndexServlet(testCanonicalUrl, testCdnPath, testFaviconURL, gerritApi);
+
+ FakeHttpServletResponse response = new FakeHttpServletResponse();
+
+ replay(gerritApi);
+ replay(configApi);
+ replay(serverApi);
+ replay(accountsApi);
+
+ servlet.doGet(new FakeHttpServletRequest(), response);
+
+ verify(gerritApi);
+ verify(configApi);
+ verify(serverApi);
+ verify(accountsApi);
+
+ String output = response.getActualBodyString();
assertThat(output).contains("<!DOCTYPE html>");
assertThat(output).contains("window.CANONICAL_PATH = '" + testCanonicalUrl);
assertThat(output).contains("<link rel=\"preload\" href=\"" + testCdnPath);
@@ -85,5 +82,12 @@
+ testCanonicalUrl
+ "/"
+ testFaviconURL);
+ assertThat(output)
+ .contains(
+ "window.INITIAL_DATA = JSON.parse("
+ + "'\\x7b\\x22\\/config\\/server\\/version\\x22: \\x22123\\x22, "
+ + "\\x22\\/config\\/server\\/info\\x22: \\x7b\\x22default_theme\\x22:"
+ + "\\x22my-default-theme\\x22\\x7d, \\x22\\/config\\/server\\/top-menus\\x22: "
+ + "\\x5b\\x5d\\x7d');</script>");
}
}
diff --git a/javatests/com/google/gerrit/httpd/raw/ResourceServletTest.java b/javatests/com/google/gerrit/httpd/raw/ResourceServletTest.java
index 3ef9ec5..dd594d6 100644
--- a/javatests/com/google/gerrit/httpd/raw/ResourceServletTest.java
+++ b/javatests/com/google/gerrit/httpd/raw/ResourceServletTest.java
@@ -29,7 +29,6 @@
import com.google.common.jimfs.Configuration;
import com.google.common.jimfs.Jimfs;
import com.google.gerrit.httpd.raw.ResourceServlet.Resource;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.util.http.testutil.FakeHttpServletRequest;
import com.google.gerrit.util.http.testutil.FakeHttpServletResponse;
import java.io.ByteArrayInputStream;
@@ -46,7 +45,7 @@
import org.junit.Before;
import org.junit.Test;
-public class ResourceServletTest extends GerritBaseTests {
+public class ResourceServletTest {
private static Cache<Path, Resource> newCache(int size) {
return CacheBuilder.newBuilder().maximumSize(size).recordStats().build();
}
diff --git a/javatests/com/google/gerrit/httpd/restapi/HttpLogRedactTest.java b/javatests/com/google/gerrit/httpd/restapi/HttpLogRedactTest.java
index fa3eaea..fb1ebd9 100644
--- a/javatests/com/google/gerrit/httpd/restapi/HttpLogRedactTest.java
+++ b/javatests/com/google/gerrit/httpd/restapi/HttpLogRedactTest.java
@@ -16,10 +16,9 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class HttpLogRedactTest extends GerritBaseTests {
+public class HttpLogRedactTest {
@Test
public void redactAuth() {
assertThat(LogRedactUtil.redactQueryString("query=status:open")).isEqualTo("query=status:open");
diff --git a/javatests/com/google/gerrit/httpd/restapi/ParameterParserTest.java b/javatests/com/google/gerrit/httpd/restapi/ParameterParserTest.java
index 30d318b..a550ac7 100644
--- a/javatests/com/google/gerrit/httpd/restapi/ParameterParserTest.java
+++ b/javatests/com/google/gerrit/httpd/restapi/ParameterParserTest.java
@@ -15,21 +15,20 @@
package com.google.gerrit.httpd.restapi;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.httpd.restapi.ParameterParser.QueryParams;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.util.http.testutil.FakeHttpServletRequest;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import org.junit.Test;
-public class ParameterParserTest extends GerritBaseTests {
+public class ParameterParserTest {
@Test
public void convertFormToJson() throws BadRequestException {
JsonObject obj =
@@ -110,35 +109,26 @@
public void rejectDuplicateMethod() {
FakeHttpServletRequest req = new FakeHttpServletRequest();
req.setQueryString("$m=PUT&$m=DELETE");
- try {
- ParameterParser.getQueryParams(req);
- fail("expected BadRequestException");
- } catch (BadRequestException bad) {
- assertThat(bad).hasMessageThat().isEqualTo("duplicate $m");
- }
+ BadRequestException bad =
+ assertThrows(BadRequestException.class, () -> ParameterParser.getQueryParams(req));
+ assertThat(bad).hasMessageThat().isEqualTo("duplicate $m");
}
@Test
public void rejectDuplicateContentType() {
FakeHttpServletRequest req = new FakeHttpServletRequest();
req.setQueryString("$ct=json&$ct=string");
- try {
- ParameterParser.getQueryParams(req);
- fail("expected BadRequestException");
- } catch (BadRequestException bad) {
- assertThat(bad).hasMessageThat().isEqualTo("duplicate $ct");
- }
+ BadRequestException bad =
+ assertThrows(BadRequestException.class, () -> ParameterParser.getQueryParams(req));
+ assertThat(bad).hasMessageThat().isEqualTo("duplicate $ct");
}
@Test
public void rejectInvalidMethod() {
FakeHttpServletRequest req = new FakeHttpServletRequest();
req.setQueryString("$m=CONNECT");
- try {
- ParameterParser.getQueryParams(req);
- fail("expected BadRequestException");
- } catch (BadRequestException bad) {
- assertThat(bad).hasMessageThat().isEqualTo("invalid $m");
- }
+ BadRequestException bad =
+ assertThrows(BadRequestException.class, () -> ParameterParser.getQueryParams(req));
+ assertThat(bad).hasMessageThat().isEqualTo("invalid $m");
}
}
diff --git a/javatests/com/google/gerrit/index/BUILD b/javatests/com/google/gerrit/index/BUILD
index a1f60de..a77525e 100644
--- a/javatests/com/google/gerrit/index/BUILD
+++ b/javatests/com/google/gerrit/index/BUILD
@@ -10,6 +10,7 @@
"//java/com/google/gerrit/index",
"//java/com/google/gerrit/index:query_exception",
"//java/com/google/gerrit/index/query/testing",
+ "//java/com/google/gerrit/server",
"//java/com/google/gerrit/testing:gerrit-test-util",
"//lib:guava",
"//lib:junit",
diff --git a/javatests/com/google/gerrit/index/SchemaUtilTest.java b/javatests/com/google/gerrit/index/SchemaUtilTest.java
index d6b8421..698e00a 100644
--- a/javatests/com/google/gerrit/index/SchemaUtilTest.java
+++ b/javatests/com/google/gerrit/index/SchemaUtilTest.java
@@ -18,13 +18,13 @@
import static com.google.gerrit.index.SchemaUtil.getNameParts;
import static com.google.gerrit.index.SchemaUtil.getPersonParts;
import static com.google.gerrit.index.SchemaUtil.schema;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.Map;
import org.eclipse.jgit.lib.PersonIdent;
import org.junit.Test;
-public class SchemaUtilTest extends GerritBaseTests {
+public class SchemaUtilTest {
static class TestSchemas {
static final Schema<String> V1 = schema();
static final Schema<String> V2 = schema();
@@ -43,9 +43,9 @@
assertThat(all.get(1)).isEqualTo(TestSchemas.V1);
assertThat(all.get(2)).isEqualTo(TestSchemas.V2);
assertThat(all.get(4)).isEqualTo(TestSchemas.V4);
-
- exception.expect(IllegalArgumentException.class);
- SchemaUtil.schemasFromClass(TestSchemas.class, Object.class);
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> SchemaUtil.schemasFromClass(TestSchemas.class, Object.class));
}
@Test
diff --git a/javatests/com/google/gerrit/index/query/AndPredicateTest.java b/javatests/com/google/gerrit/index/query/AndPredicateTest.java
index 21098b3..16828dd 100644
--- a/javatests/com/google/gerrit/index/query/AndPredicateTest.java
+++ b/javatests/com/google/gerrit/index/query/AndPredicateTest.java
@@ -16,12 +16,12 @@
import static com.google.common.collect.ImmutableList.of;
import static com.google.gerrit.index.query.Predicate.and;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
import java.util.List;
import org.junit.Test;
@@ -43,28 +43,13 @@
final TestPredicate b = f("author", "bob");
final Predicate<String> n = and(a, b);
- try {
- n.getChildren().clear();
- fail("Expected UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // Expected
- }
+ assertThrows(UnsupportedOperationException.class, () -> n.getChildren().clear());
assertChildren("clear", n, of(a, b));
- try {
- n.getChildren().remove(0);
- fail("Expected UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // Expected
- }
+ assertThrows(UnsupportedOperationException.class, () -> n.getChildren().remove(0));
assertChildren("remove(0)", n, of(a, b));
- try {
- n.getChildren().iterator().remove();
- fail("Expected UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // Expected
- }
+ assertThrows(UnsupportedOperationException.class, () -> n.getChildren().iterator().remove());
assertChildren("iterator().remove()", n, of(a, b));
}
diff --git a/javatests/com/google/gerrit/index/query/FieldPredicateTest.java b/javatests/com/google/gerrit/index/query/FieldPredicateTest.java
index 805f31c..2d2c99e 100644
--- a/javatests/com/google/gerrit/index/query/FieldPredicateTest.java
+++ b/javatests/com/google/gerrit/index/query/FieldPredicateTest.java
@@ -14,6 +14,8 @@
package com.google.gerrit.index.query;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
@@ -61,8 +63,9 @@
assertSame(f, f.copy(Collections.emptyList()));
assertSame(f, f.copy(f.getChildren()));
- exception.expect(IllegalArgumentException.class);
- exception.expectMessage("Expected 0 children");
- f.copy(Collections.singleton(f("owner", "bob")));
+ IllegalArgumentException thrown =
+ assertThrows(
+ IllegalArgumentException.class, () -> f.copy(Collections.singleton(f("owner", "bob"))));
+ assertThat(thrown).hasMessageThat().contains("Expected 0 children");
}
}
diff --git a/javatests/com/google/gerrit/index/query/LazyDataSourceTest.java b/javatests/com/google/gerrit/index/query/LazyDataSourceTest.java
new file mode 100644
index 0000000..7064f64
--- /dev/null
+++ b/javatests/com/google/gerrit/index/query/LazyDataSourceTest.java
@@ -0,0 +1,106 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.index.query;
+
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+
+import com.google.common.collect.ImmutableList;
+import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.server.query.change.ChangeDataSource;
+import com.google.gerrit.server.query.change.OrSource;
+import java.util.Collection;
+import java.util.Iterator;
+import org.junit.Test;
+
+/**
+ * Tests that boolean data sources are lazy in that they don't call {@link ResultSet#toList()} or
+ * {@link ResultSet#toList()}. This is necessary because it allows Gerrit to send multiple queries
+ * to the index in parallel, have the results come in asynchronously and wait for them only when we
+ * call aforementioned methods on the {@link ResultSet}.
+ */
+public class LazyDataSourceTest {
+
+ /** Helper to avoid a mock which would be hard to create because of the type inference. */
+ static class LazyPredicate extends Predicate<ChangeData> implements ChangeDataSource {
+ @Override
+ public int getCardinality() {
+ return 1;
+ }
+
+ @Override
+ public ResultSet<ChangeData> read() {
+ return new FailingResultSet<>();
+ }
+
+ @Override
+ public ResultSet<FieldBundle> readRaw() {
+ return new FailingResultSet<>();
+ }
+
+ @Override
+ public Predicate<ChangeData> copy(Collection<? extends Predicate<ChangeData>> children) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public int hashCode() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ throw new UnsupportedOperationException("not implemented");
+ }
+
+ @Override
+ public boolean hasChange() {
+ throw new UnsupportedOperationException("not implemented");
+ }
+ }
+
+ /** Implementation that throws {@link AssertionError} when accessing results. */
+ static class FailingResultSet<T> implements ResultSet<T> {
+ @Override
+ public Iterator<T> iterator() {
+ throw new AssertionError(
+ "called iterator() on the result set, but shouldn't have because the data source must be lazy");
+ }
+
+ @Override
+ public ImmutableList<T> toList() {
+ throw new AssertionError(
+ "called toList() on the result set, but shouldn't have because the data source must be lazy");
+ }
+
+ @Override
+ public void close() {
+ // No-op
+ }
+ }
+
+ @Test
+ public void andSourceIsLazy() {
+ AndSource<ChangeData> and = new AndSource<>(ImmutableList.of(new LazyPredicate()));
+ ResultSet<ChangeData> resultSet = and.read();
+ assertThrows(AssertionError.class, () -> resultSet.toList());
+ }
+
+ @Test
+ public void orSourceIsLazy() {
+ OrSource or = new OrSource(ImmutableList.of(new LazyPredicate()));
+ ResultSet<ChangeData> resultSet = or.read();
+ assertThrows(AssertionError.class, () -> resultSet.toList());
+ }
+}
diff --git a/javatests/com/google/gerrit/index/query/NotPredicateTest.java b/javatests/com/google/gerrit/index/query/NotPredicateTest.java
index d10d2df..3d1839d 100644
--- a/javatests/com/google/gerrit/index/query/NotPredicateTest.java
+++ b/javatests/com/google/gerrit/index/query/NotPredicateTest.java
@@ -16,12 +16,12 @@
import static com.google.gerrit.index.query.Predicate.and;
import static com.google.gerrit.index.query.Predicate.not;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
import java.util.Collections;
import java.util.List;
@@ -50,26 +50,14 @@
final TestPredicate p = f("author", "bob");
final Predicate<String> n = not(p);
- try {
- n.getChildren().clear();
- fail("Expected UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- assertOnlyChild("clear", p, n);
- }
+ assertThrows(UnsupportedOperationException.class, () -> n.getChildren().clear());
+ assertOnlyChild("clear", p, n);
- try {
- n.getChildren().remove(0);
- fail("Expected UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- assertOnlyChild("remove(0)", p, n);
- }
+ assertThrows(UnsupportedOperationException.class, () -> n.getChildren().remove(0));
+ assertOnlyChild("remove(0)", p, n);
- try {
- n.getChildren().iterator().remove();
- fail("Expected UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- assertOnlyChild("remove()", p, n);
- }
+ assertThrows(UnsupportedOperationException.class, () -> n.getChildren().iterator().remove());
+ assertOnlyChild("remove()", p, n);
}
private static void assertOnlyChild(String o, Predicate<String> c, Predicate<String> p) {
@@ -112,18 +100,11 @@
assertNotSame(n, n.copy(sb));
assertEquals(sb, n.copy(sb).getChildren());
- try {
- n.copy(Collections.emptyList());
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- assertEquals("Expected exactly one child", e.getMessage());
- }
+ IllegalArgumentException e =
+ assertThrows(IllegalArgumentException.class, () -> n.copy(Collections.emptyList()));
+ assertEquals("Expected exactly one child", e.getMessage());
- try {
- n.copy(and(a, b).getChildren());
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- assertEquals("Expected exactly one child", e.getMessage());
- }
+ e = assertThrows(IllegalArgumentException.class, () -> n.copy(and(a, b).getChildren()));
+ assertEquals("Expected exactly one child", e.getMessage());
}
}
diff --git a/javatests/com/google/gerrit/index/query/OrPredicateTest.java b/javatests/com/google/gerrit/index/query/OrPredicateTest.java
index 255a3f8..1cbcb75 100644
--- a/javatests/com/google/gerrit/index/query/OrPredicateTest.java
+++ b/javatests/com/google/gerrit/index/query/OrPredicateTest.java
@@ -16,12 +16,12 @@
import static com.google.common.collect.ImmutableList.of;
import static com.google.gerrit.index.query.Predicate.or;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
import java.util.List;
import org.junit.Test;
@@ -43,28 +43,13 @@
final TestPredicate b = f("author", "bob");
final Predicate<String> n = or(a, b);
- try {
- n.getChildren().clear();
- fail("Expected UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // Expected
- }
+ assertThrows(UnsupportedOperationException.class, () -> n.getChildren().clear());
assertChildren("clear", n, of(a, b));
- try {
- n.getChildren().remove(0);
- fail("Expected UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // Expected
- }
+ assertThrows(UnsupportedOperationException.class, () -> n.getChildren().remove(0));
assertChildren("remove(0)", n, of(a, b));
- try {
- n.getChildren().iterator().remove();
- fail("Expected UnsupportedOperationException");
- } catch (UnsupportedOperationException e) {
- // Expected
- }
+ assertThrows(UnsupportedOperationException.class, () -> n.getChildren().iterator().remove());
assertChildren("iterator().remove()", n, of(a, b));
}
diff --git a/javatests/com/google/gerrit/index/query/PredicateTest.java b/javatests/com/google/gerrit/index/query/PredicateTest.java
index 2295a60..3ec7f13 100644
--- a/javatests/com/google/gerrit/index/query/PredicateTest.java
+++ b/javatests/com/google/gerrit/index/query/PredicateTest.java
@@ -14,11 +14,10 @@
package com.google.gerrit.index.query;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Ignore;
@Ignore
-public abstract class PredicateTest extends GerritBaseTests {
+public abstract class PredicateTest {
protected static final class TestPredicate extends OperatorPredicate<String> {
protected TestPredicate(String name, String value) {
super(name, value);
diff --git a/javatests/com/google/gerrit/index/query/QueryBuilderTest.java b/javatests/com/google/gerrit/index/query/QueryBuilderTest.java
index 6a397dc..f653759 100644
--- a/javatests/com/google/gerrit/index/query/QueryBuilderTest.java
+++ b/javatests/com/google/gerrit/index/query/QueryBuilderTest.java
@@ -17,12 +17,11 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.common.truth.ThrowableSubject;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.Collection;
import java.util.Objects;
import org.junit.Test;
-public class QueryBuilderTest extends GerritBaseTests {
+public class QueryBuilderTest {
private static class TestPredicate extends Predicate<Object> {
private final String field;
private final String value;
diff --git a/javatests/com/google/gerrit/index/query/QueryParserTest.java b/javatests/com/google/gerrit/index/query/QueryParserTest.java
index b4dd1ee..776a2c4 100644
--- a/javatests/com/google/gerrit/index/query/QueryParserTest.java
+++ b/javatests/com/google/gerrit/index/query/QueryParserTest.java
@@ -14,7 +14,6 @@
package com.google.gerrit.index.query;
-import static com.google.common.truth.Truth.assert_;
import static com.google.gerrit.index.query.QueryParser.AND;
import static com.google.gerrit.index.query.QueryParser.COLON;
import static com.google.gerrit.index.query.QueryParser.DEFAULT_FIELD;
@@ -22,12 +21,12 @@
import static com.google.gerrit.index.query.QueryParser.SINGLE_WORD;
import static com.google.gerrit.index.query.QueryParser.parse;
import static com.google.gerrit.index.query.testing.TreeSubject.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import com.google.gerrit.testing.GerritBaseTests;
import org.antlr.runtime.tree.Tree;
import org.junit.Test;
-public class QueryParserTest extends GerritBaseTests {
+public class QueryParserTest {
@Test
public void fieldNameAndValue() throws Exception {
Tree r = parse("project:tools/gerrit");
@@ -206,11 +205,6 @@
}
private static void assertParseFails(String query) {
- try {
- parse(query);
- assert_().fail("expected parse to fail: %s", query);
- } catch (QueryParseException e) {
- // Expected.
- }
+ assertThrows(QueryParseException.class, () -> parse(query));
}
}
diff --git a/javatests/com/google/gerrit/json/BUILD b/javatests/com/google/gerrit/json/BUILD
index 4894cdb..2d95652 100644
--- a/javatests/com/google/gerrit/json/BUILD
+++ b/javatests/com/google/gerrit/json/BUILD
@@ -5,6 +5,7 @@
srcs = glob(["*.java"]),
deps = [
"//java/com/google/gerrit/json",
+ "//java/com/google/gerrit/testing:gerrit-test-util",
"//lib:guava",
"//lib/truth",
],
diff --git a/javatests/com/google/gerrit/json/JavaSqlTimestampHelperTest.java b/javatests/com/google/gerrit/json/JavaSqlTimestampHelperTest.java
index a8488a9..05a9cfb 100644
--- a/javatests/com/google/gerrit/json/JavaSqlTimestampHelperTest.java
+++ b/javatests/com/google/gerrit/json/JavaSqlTimestampHelperTest.java
@@ -15,8 +15,8 @@
package com.google.gerrit.json;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
import static com.google.gerrit.json.JavaSqlTimestampHelper.parseTimestamp;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
@@ -73,12 +73,7 @@
}
private static void assertInvalid(String input) {
- try {
- parseTimestamp(input);
- assert_().fail("Expected IllegalArgumentException for: " + input);
- } catch (IllegalArgumentException e) {
- // Expected;
- }
+ assertThrows(IllegalArgumentException.class, () -> parseTimestamp(input));
}
private String reformat(String input) {
diff --git a/javatests/com/google/gerrit/mail/AbstractParserTest.java b/javatests/com/google/gerrit/mail/AbstractParserTest.java
index 1d92977..c7359f3 100644
--- a/javatests/com/google/gerrit/mail/AbstractParserTest.java
+++ b/javatests/com/google/gerrit/mail/AbstractParserTest.java
@@ -18,7 +18,6 @@
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Comment;
-import com.google.gerrit.testing.GerritBaseTests;
import java.sql.Timestamp;
import java.time.Instant;
import java.util.ArrayList;
@@ -26,7 +25,7 @@
import org.junit.Ignore;
@Ignore
-public class AbstractParserTest extends GerritBaseTests {
+public class AbstractParserTest {
protected static final String CHANGE_URL =
"https://gerrit-review.googlesource.com/c/project/+/123";
diff --git a/javatests/com/google/gerrit/mail/AddressTest.java b/javatests/com/google/gerrit/mail/AddressTest.java
index 53ff1fe..da26123 100644
--- a/javatests/com/google/gerrit/mail/AddressTest.java
+++ b/javatests/com/google/gerrit/mail/AddressTest.java
@@ -15,12 +15,11 @@
package com.google.gerrit.mail;
import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class AddressTest extends GerritBaseTests {
+public class AddressTest {
@Test
public void parse_NameEmail1() {
final Address a = Address.parse("A U Thor <author@example.com>");
@@ -97,12 +96,9 @@
}
private void assertInvalid(String in) {
- try {
- Address.parse(in);
- fail("Expected IllegalArgumentException for " + in);
- } catch (IllegalArgumentException e) {
- assertThat(e.getMessage()).isEqualTo("Invalid email address: " + in);
- }
+ IllegalArgumentException thrown =
+ assertThrows(IllegalArgumentException.class, () -> Address.parse(in));
+ assertThat(thrown).hasMessageThat().isEqualTo("Invalid email address: " + in);
}
@Test
diff --git a/javatests/com/google/gerrit/mail/MailHeaderParserTest.java b/javatests/com/google/gerrit/mail/MailHeaderParserTest.java
index cdc8d7a..2d2c2ea 100644
--- a/javatests/com/google/gerrit/mail/MailHeaderParserTest.java
+++ b/javatests/com/google/gerrit/mail/MailHeaderParserTest.java
@@ -16,14 +16,13 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.gerrit.testing.GerritBaseTests;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.ZoneOffset;
import org.junit.Test;
-public class MailHeaderParserTest extends GerritBaseTests {
+public class MailHeaderParserTest {
@Test
public void parseMetadataFromHeader() {
// This tests if the metadata parser is able to parse metadata from the
diff --git a/javatests/com/google/gerrit/mail/ParserUtilTest.java b/javatests/com/google/gerrit/mail/ParserUtilTest.java
index ed40a57..47a5367 100644
--- a/javatests/com/google/gerrit/mail/ParserUtilTest.java
+++ b/javatests/com/google/gerrit/mail/ParserUtilTest.java
@@ -16,10 +16,9 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class ParserUtilTest extends GerritBaseTests {
+public class ParserUtilTest {
@Test
public void trimQuotationLineOnMessageWithoutQuoatationLine() throws Exception {
assertThat(ParserUtil.trimQuotation("One line")).isEqualTo("One line");
diff --git a/javatests/com/google/gerrit/mail/RawMailParserTest.java b/javatests/com/google/gerrit/mail/RawMailParserTest.java
index 9049704..0ab2811 100644
--- a/javatests/com/google/gerrit/mail/RawMailParserTest.java
+++ b/javatests/com/google/gerrit/mail/RawMailParserTest.java
@@ -23,10 +23,9 @@
import com.google.gerrit.mail.data.QuotedPrintableHeaderMessage;
import com.google.gerrit.mail.data.RawMailMessage;
import com.google.gerrit.mail.data.SimpleTextMessage;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class RawMailParserTest extends GerritBaseTests {
+public class RawMailParserTest {
@Test
public void parseEmail() throws Exception {
RawMailMessage[] messages =
diff --git a/javatests/com/google/gerrit/metrics/dropwizard/DropWizardMetricMakerTest.java b/javatests/com/google/gerrit/metrics/dropwizard/DropWizardMetricMakerTest.java
index d6bcb62..9b21bf6 100644
--- a/javatests/com/google/gerrit/metrics/dropwizard/DropWizardMetricMakerTest.java
+++ b/javatests/com/google/gerrit/metrics/dropwizard/DropWizardMetricMakerTest.java
@@ -16,10 +16,9 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class DropWizardMetricMakerTest extends GerritBaseTests {
+public class DropWizardMetricMakerTest {
DropWizardMetricMaker metrics =
new DropWizardMetricMaker(null /* MetricRegistry unused in tests */);
diff --git a/javatests/com/google/gerrit/metrics/proc/ProcMetricModuleTest.java b/javatests/com/google/gerrit/metrics/proc/ProcMetricModuleTest.java
index 0a5dabf..db75cd8 100644
--- a/javatests/com/google/gerrit/metrics/proc/ProcMetricModuleTest.java
+++ b/javatests/com/google/gerrit/metrics/proc/ProcMetricModuleTest.java
@@ -15,6 +15,8 @@
package com.google.gerrit.metrics.proc;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.codahale.metrics.Counter;
import com.codahale.metrics.Gauge;
@@ -30,7 +32,6 @@
import com.google.gerrit.metrics.Field;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.metrics.dropwizard.DropWizardMetricMaker;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
@@ -39,7 +40,7 @@
import org.junit.Before;
import org.junit.Test;
-public class ProcMetricModuleTest extends GerritBaseTests {
+public class ProcMetricModuleTest {
@Inject MetricMaker metrics;
@Inject MetricRegistry registry;
@@ -147,14 +148,16 @@
@Test
public void invalidName1() {
- exception.expect(IllegalArgumentException.class);
- metrics.newCounter("invalid name", new Description("fail"));
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> metrics.newCounter("invalid name", new Description("fail")));
}
@Test
public void invalidName2() {
- exception.expect(IllegalArgumentException.class);
- metrics.newCounter("invalid/ name", new Description("fail"));
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> metrics.newCounter("invalid/ name", new Description("fail")));
}
@SuppressWarnings({"unchecked", "cast"})
@@ -164,8 +167,8 @@
private <M extends Metric> M get(String name, Class<M> type) {
Metric m = registry.getMetrics().get(name);
- assertThat(m).named(name).isNotNull();
- assertThat(m).named(name).isInstanceOf(type);
+ assertWithMessage(name).that(m).isNotNull();
+ assertWithMessage(name).that(m).isInstanceOf(type);
@SuppressWarnings("unchecked")
M result = (M) m;
diff --git a/javatests/com/google/gerrit/pgm/init/LibrariesTest.java b/javatests/com/google/gerrit/pgm/init/LibrariesTest.java
index 47b7509..543f765 100644
--- a/javatests/com/google/gerrit/pgm/init/LibrariesTest.java
+++ b/javatests/com/google/gerrit/pgm/init/LibrariesTest.java
@@ -21,12 +21,11 @@
import com.google.gerrit.pgm.init.api.ConsoleUI;
import com.google.gerrit.server.config.SitePaths;
-import com.google.gerrit.testing.GerritBaseTests;
import java.nio.file.Paths;
import java.util.Collections;
import org.junit.Test;
-public class LibrariesTest extends GerritBaseTests {
+public class LibrariesTest {
@Test
public void create() throws Exception {
final SitePaths site = new SitePaths(Paths.get("."));
diff --git a/javatests/com/google/gerrit/pgm/init/api/AllProjectsConfigTest.java b/javatests/com/google/gerrit/pgm/init/api/AllProjectsConfigTest.java
index 326e996..a34007e 100644
--- a/javatests/com/google/gerrit/pgm/init/api/AllProjectsConfigTest.java
+++ b/javatests/com/google/gerrit/pgm/init/api/AllProjectsConfigTest.java
@@ -82,8 +82,8 @@
public void noBaseConfig() throws Exception {
assertThat(getConfig().getString("foo", null, "bar")).isNull();
- try (Repository repo = new FileRepository(allProjectsRepoFile)) {
- TestRepository<?> tr = new TestRepository<>(repo);
+ try (Repository repo = new FileRepository(allProjectsRepoFile);
+ TestRepository<Repository> tr = new TestRepository<>(repo)) {
tr.branch("refs/meta/config").commit().add("project.config", "[foo]\nbar = baz").create();
}
@@ -100,8 +100,8 @@
assertThat(getConfig().getString("foo", null, "bar")).isEqualTo("base");
- try (Repository repo = new FileRepository(allProjectsRepoFile)) {
- TestRepository<?> tr = new TestRepository<>(repo);
+ try (Repository repo = new FileRepository(allProjectsRepoFile);
+ TestRepository<Repository> tr = new TestRepository<>(repo)) {
tr.branch("refs/meta/config").commit().add("project.config", "[foo]\nbar = baz").create();
}
diff --git a/javatests/com/google/gerrit/proto/ProtosTest.java b/javatests/com/google/gerrit/proto/ProtosTest.java
index 29e8fe0..550bcc5 100644
--- a/javatests/com/google/gerrit/proto/ProtosTest.java
+++ b/javatests/com/google/gerrit/proto/ProtosTest.java
@@ -14,17 +14,16 @@
package com.google.gerrit.proto;
-import static com.google.common.truth.Truth.assert_;
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.server.cache.proto.Cache.ChangeNotesKeyProto;
import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.protobuf.ByteString;
import java.util.Arrays;
import org.junit.Test;
-public class ProtosTest extends GerritBaseTests {
+public class ProtosTest {
@Test
public void parseUncheckedByteArrayWrongProtoType() {
ChangeNotesKeyProto proto =
@@ -34,23 +33,17 @@
.setId(ByteString.copyFromUtf8("foo"))
.build();
byte[] bytes = Protos.toByteArray(proto);
- try {
- Protos.parseUnchecked(ChangeNotesStateProto.parser(), bytes);
- assert_().fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // Expected.
- }
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> Protos.parseUnchecked(ChangeNotesStateProto.parser(), bytes));
}
@Test
public void parseUncheckedByteArrayInvalidData() {
byte[] bytes = new byte[] {0x00};
- try {
- Protos.parseUnchecked(ChangeNotesStateProto.parser(), bytes);
- assert_().fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // Expected.
- }
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> Protos.parseUnchecked(ChangeNotesStateProto.parser(), bytes));
}
@Test
@@ -74,23 +67,17 @@
.setId(ByteString.copyFromUtf8("foo"))
.build();
byte[] bytes = Protos.toByteArray(proto);
- try {
- Protos.parseUnchecked(ChangeNotesStateProto.parser(), bytes, 0, bytes.length);
- assert_().fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // Expected.
- }
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> Protos.parseUnchecked(ChangeNotesStateProto.parser(), bytes, 0, bytes.length));
}
@Test
public void parseUncheckedSegmentOfByteArrayInvalidData() {
byte[] bytes = new byte[] {0x00};
- try {
- Protos.parseUnchecked(ChangeNotesStateProto.parser(), bytes, 0, bytes.length);
- assert_().fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // Expected.
- }
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> Protos.parseUnchecked(ChangeNotesStateProto.parser(), bytes, 0, bytes.length));
}
@Test
@@ -123,23 +110,17 @@
.setId(ByteString.copyFromUtf8("foo"))
.build();
ByteString byteString = Protos.toByteString(proto);
- try {
- Protos.parseUnchecked(ChangeNotesStateProto.parser(), byteString);
- assert_().fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // Expected.
- }
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> Protos.parseUnchecked(ChangeNotesStateProto.parser(), byteString));
}
@Test
public void parseUncheckedByteStringInvalidData() {
ByteString byteString = ByteString.copyFrom(new byte[] {0x00});
- try {
- Protos.parseUnchecked(ChangeNotesStateProto.parser(), byteString);
- assert_().fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // Expected.
- }
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> Protos.parseUnchecked(ChangeNotesStateProto.parser(), byteString));
}
@Test
diff --git a/javatests/com/google/gerrit/reviewdb/client/PatchSetApprovalTest.java b/javatests/com/google/gerrit/reviewdb/client/PatchSetApprovalTest.java
index af078f6..c73f327 100644
--- a/javatests/com/google/gerrit/reviewdb/client/PatchSetApprovalTest.java
+++ b/javatests/com/google/gerrit/reviewdb/client/PatchSetApprovalTest.java
@@ -16,12 +16,11 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
-public class PatchSetApprovalTest extends GerritBaseTests {
+public class PatchSetApprovalTest {
@Test
public void keyEquality() {
PatchSetApproval.Key k1 =
diff --git a/javatests/com/google/gerrit/reviewdb/client/PatchSetTest.java b/javatests/com/google/gerrit/reviewdb/client/PatchSetTest.java
index 77822e2..c195533 100644
--- a/javatests/com/google/gerrit/reviewdb/client/PatchSetTest.java
+++ b/javatests/com/google/gerrit/reviewdb/client/PatchSetTest.java
@@ -15,9 +15,9 @@
package com.google.gerrit.reviewdb.client;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
import static com.google.gerrit.reviewdb.client.PatchSet.joinGroups;
import static com.google.gerrit.reviewdb.client.PatchSet.splitGroups;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
@@ -65,18 +65,23 @@
@Test
public void testSplitGroups() {
+ assertRuntimeException(() -> splitGroups(null));
assertThat(splitGroups("")).containsExactly("");
assertThat(splitGroups("abcd")).containsExactly("abcd");
assertThat(splitGroups("ab,cd")).containsExactly("ab", "cd").inOrder();
+ assertThat(splitGroups("ab , cd")).containsExactly("ab ", " cd").inOrder();
assertThat(splitGroups("ab,")).containsExactly("ab", "").inOrder();
assertThat(splitGroups(",cd")).containsExactly("", "cd").inOrder();
}
@Test
public void testJoinGroups() {
+ assertRuntimeException(() -> joinGroups(null));
+ assertRuntimeException(() -> joinGroups(ImmutableList.of("a,", "b")));
assertThat(joinGroups(ImmutableList.of(""))).isEqualTo("");
assertThat(joinGroups(ImmutableList.of("abcd"))).isEqualTo("abcd");
assertThat(joinGroups(ImmutableList.of("ab", "cd"))).isEqualTo("ab,cd");
+ assertThat(joinGroups(ImmutableList.of("ab ", " cd"))).isEqualTo("ab , cd");
assertThat(joinGroups(ImmutableList.of("ab", ""))).isEqualTo("ab,");
assertThat(joinGroups(ImmutableList.of("", "cd"))).isEqualTo(",cd");
}
@@ -117,11 +122,10 @@
}
private static void assertInvalidId(String str) {
- try {
- PatchSet.Id.parse(str);
- assert_().fail("expected RuntimeException");
- } catch (RuntimeException e) {
- // Expected.
- }
+ assertRuntimeException(() -> PatchSet.Id.parse(str));
+ }
+
+ private static void assertRuntimeException(Runnable runnable) {
+ assertThrows(RuntimeException.class, () -> runnable.run());
}
}
diff --git a/javatests/com/google/gerrit/reviewdb/client/PatchTest.java b/javatests/com/google/gerrit/reviewdb/client/PatchTest.java
index 5c8b37f..d9a30e5 100644
--- a/javatests/com/google/gerrit/reviewdb/client/PatchTest.java
+++ b/javatests/com/google/gerrit/reviewdb/client/PatchTest.java
@@ -15,12 +15,11 @@
package com.google.gerrit.reviewdb.client;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class PatchTest extends GerritBaseTests {
+public class PatchTest {
@Test
public void isMagic() {
assertThat(Patch.isMagic("/COMMIT_MSG")).isTrue();
@@ -50,11 +49,6 @@
}
private static void assertInvalidKey(String str) {
- try {
- Patch.Key.parse(str);
- assert_().fail("expected RuntimeException");
- } catch (RuntimeException e) {
- // Expected.
- }
+ assertThrows(RuntimeException.class, () -> Patch.Key.parse(str));
}
}
diff --git a/javatests/com/google/gerrit/reviewdb/client/ProjectTest.java b/javatests/com/google/gerrit/reviewdb/client/ProjectTest.java
index b97b0b8..a24cff7 100644
--- a/javatests/com/google/gerrit/reviewdb/client/ProjectTest.java
+++ b/javatests/com/google/gerrit/reviewdb/client/ProjectTest.java
@@ -16,10 +16,9 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class ProjectTest extends GerritBaseTests {
+public class ProjectTest {
@Test
public void parseId() {
assertThat(Project.NameKey.parse("foo")).isEqualTo(new Project.NameKey("foo"));
diff --git a/javatests/com/google/gerrit/reviewdb/client/RefNamesTest.java b/javatests/com/google/gerrit/reviewdb/client/RefNamesTest.java
index b401094..7f22275 100644
--- a/javatests/com/google/gerrit/reviewdb/client/RefNamesTest.java
+++ b/javatests/com/google/gerrit/reviewdb/client/RefNamesTest.java
@@ -20,18 +20,14 @@
import static com.google.gerrit.reviewdb.client.RefNames.parseShardedRefPart;
import static com.google.gerrit.reviewdb.client.RefNames.parseShardedUuidFromRefPart;
import static com.google.gerrit.reviewdb.client.RefNames.skipShardedRefPart;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import org.junit.Rule;
import org.junit.Test;
-import org.junit.rules.ExpectedException;
public class RefNamesTest {
private static final String TEST_GROUP_UUID = "ccab3195282a8ce4f5014efa391e82d10f884c64";
private static final String TEST_SHARDED_GROUP_UUID =
TEST_GROUP_UUID.substring(0, 2) + "/" + TEST_GROUP_UUID;
-
- @Rule public ExpectedException expectedException = ExpectedException.none();
-
private final Account.Id accountId = Account.id(1011123);
private final Change.Id changeId = Change.id(67473);
private final PatchSet.Id psId = PatchSet.id(changeId, 42);
@@ -66,8 +62,7 @@
@Test
public void refForGroupWithUuidLessThanTwoCharsIsRejected() throws Exception {
AccountGroup.UUID groupUuid = AccountGroup.uuid("A");
- expectedException.expect(IllegalArgumentException.class);
- RefNames.refsGroups(groupUuid);
+ assertThrows(IllegalArgumentException.class, () -> RefNames.refsGroups(groupUuid));
}
@Test
@@ -80,8 +75,7 @@
@Test
public void refForDeletedGroupWithUuidLessThanTwoCharsIsRejected() throws Exception {
AccountGroup.UUID groupUuid = AccountGroup.uuid("A");
- expectedException.expect(IllegalArgumentException.class);
- RefNames.refsDeletedGroups(groupUuid);
+ assertThrows(IllegalArgumentException.class, () -> RefNames.refsDeletedGroups(groupUuid));
}
@Test
diff --git a/javatests/com/google/gerrit/reviewdb/converter/BUILD b/javatests/com/google/gerrit/reviewdb/converter/BUILD
index 1c4810c..e745344 100644
--- a/javatests/com/google/gerrit/reviewdb/converter/BUILD
+++ b/javatests/com/google/gerrit/reviewdb/converter/BUILD
@@ -8,6 +8,7 @@
"//java/com/google/gerrit/reviewdb:server",
"//lib:guava",
"//lib:protobuf",
+ "//lib/guice",
"//lib/jgit/org.eclipse.jgit:jgit",
"//lib/truth",
"//lib/truth:truth-proto-extension",
diff --git a/javatests/com/google/gerrit/reviewdb/converter/PatchSetApprovalProtoConverterTest.java b/javatests/com/google/gerrit/reviewdb/converter/PatchSetApprovalProtoConverterTest.java
index f65f204..acb7d98 100644
--- a/javatests/com/google/gerrit/reviewdb/converter/PatchSetApprovalProtoConverterTest.java
+++ b/javatests/com/google/gerrit/reviewdb/converter/PatchSetApprovalProtoConverterTest.java
@@ -26,10 +26,12 @@
import com.google.gerrit.reviewdb.client.LabelId;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
+import com.google.inject.TypeLiteral;
import com.google.protobuf.Parser;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.util.Date;
+import java.util.Optional;
import org.junit.Test;
public class PatchSetApprovalProtoConverterTest {
@@ -39,14 +41,16 @@
@Test
public void allValuesConvertedToProto() {
PatchSetApproval patchSetApproval =
- new PatchSetApproval(
- PatchSetApproval.key(
- PatchSet.id(Change.id(42), 14), Account.id(100013), LabelId.create("label-8")),
- (short) 456,
- new Date(987654L));
- patchSetApproval.setTag("tag-21");
- patchSetApproval.setRealAccountId(Account.id(612));
- patchSetApproval.setPostSubmit(true);
+ PatchSetApproval.builder()
+ .key(
+ PatchSetApproval.key(
+ PatchSet.id(Change.id(42), 14), Account.id(100013), LabelId.create("label-8")))
+ .value(456)
+ .granted(new Date(987654L))
+ .tag("tag-21")
+ .realAccountId(Account.id(612))
+ .postSubmit(true)
+ .build();
Entities.PatchSetApproval proto = protoConverter.toProto(patchSetApproval);
@@ -72,11 +76,13 @@
@Test
public void mandatoryValuesConvertedToProto() {
PatchSetApproval patchSetApproval =
- new PatchSetApproval(
- PatchSetApproval.key(
- PatchSet.id(Change.id(42), 14), Account.id(100013), LabelId.create("label-8")),
- (short) 456,
- new Date(987654L));
+ PatchSetApproval.builder()
+ .key(
+ PatchSetApproval.key(
+ PatchSet.id(Change.id(42), 14), Account.id(100013), LabelId.create("label-8")))
+ .value(456)
+ .granted(new Date(987654L))
+ .build();
Entities.PatchSetApproval proto = protoConverter.toProto(patchSetApproval);
@@ -101,14 +107,16 @@
@Test
public void allValuesConvertedToProtoAndBackAgain() {
PatchSetApproval patchSetApproval =
- new PatchSetApproval(
- PatchSetApproval.key(
- PatchSet.id(Change.id(42), 14), Account.id(100013), LabelId.create("label-8")),
- (short) 456,
- new Date(987654L));
- patchSetApproval.setTag("tag-21");
- patchSetApproval.setRealAccountId(Account.id(612));
- patchSetApproval.setPostSubmit(true);
+ PatchSetApproval.builder()
+ .key(
+ PatchSetApproval.key(
+ PatchSet.id(Change.id(42), 14), Account.id(100013), LabelId.create("label-8")))
+ .value(456)
+ .granted(new Date(987654L))
+ .tag("tag-21")
+ .realAccountId(Account.id(612))
+ .postSubmit(true)
+ .build();
PatchSetApproval convertedPatchSetApproval =
protoConverter.fromProto(protoConverter.toProto(patchSetApproval));
@@ -118,11 +126,13 @@
@Test
public void mandatoryValuesConvertedToProtoAndBackAgain() {
PatchSetApproval patchSetApproval =
- new PatchSetApproval(
- PatchSetApproval.key(
- PatchSet.id(Change.id(42), 14), Account.id(100013), LabelId.create("label-8")),
- (short) 456,
- new Date(987654L));
+ PatchSetApproval.builder()
+ .key(
+ PatchSetApproval.key(
+ PatchSet.id(Change.id(42), 14), Account.id(100013), LabelId.create("label-8")))
+ .value(456)
+ .granted(new Date(987654L))
+ .build();
PatchSetApproval convertedPatchSetApproval =
protoConverter.fromProto(protoConverter.toProto(patchSetApproval));
@@ -146,13 +156,13 @@
.build();
PatchSetApproval patchSetApproval = protoConverter.fromProto(proto);
- assertThat(patchSetApproval.getPatchSetId()).isEqualTo(PatchSet.id(Change.id(42), 14));
- assertThat(patchSetApproval.getAccountId()).isEqualTo(Account.id(100013));
- assertThat(patchSetApproval.getLabelId()).isEqualTo(LabelId.create("label-8"));
+ assertThat(patchSetApproval.patchSetId()).isEqualTo(PatchSet.id(Change.id(42), 14));
+ assertThat(patchSetApproval.accountId()).isEqualTo(Account.id(100013));
+ assertThat(patchSetApproval.labelId()).isEqualTo(LabelId.create("label-8"));
// Default values for unset protobuf fields which can't be unset in the entity object.
- assertThat(patchSetApproval.getValue()).isEqualTo(0);
- assertThat(patchSetApproval.getGranted()).isEqualTo(new Timestamp(0));
- assertThat(patchSetApproval.isPostSubmit()).isEqualTo(false);
+ assertThat(patchSetApproval.value()).isEqualTo(0);
+ assertThat(patchSetApproval.granted()).isEqualTo(new Timestamp(0));
+ assertThat(patchSetApproval.postSubmit()).isEqualTo(false);
}
@Test
@@ -182,14 +192,15 @@
@Test
public void fieldsExistAsExpected() {
assertThatSerializedClass(PatchSetApproval.class)
- .hasFields(
+ .hasAutoValueMethods(
ImmutableMap.<String, Type>builder()
.put("key", PatchSetApproval.Key.class)
.put("value", short.class)
.put("granted", Timestamp.class)
- .put("tag", String.class)
+ .put("tag", new TypeLiteral<Optional<String>>() {}.getType())
.put("realAccountId", Account.Id.class)
.put("postSubmit", boolean.class)
+ .put("toBuilder", PatchSetApproval.Builder.class)
.build());
}
}
diff --git a/javatests/com/google/gerrit/reviewdb/converter/PatchSetProtoConverterTest.java b/javatests/com/google/gerrit/reviewdb/converter/PatchSetProtoConverterTest.java
index 2fd801b..ffc6068 100644
--- a/javatests/com/google/gerrit/reviewdb/converter/PatchSetProtoConverterTest.java
+++ b/javatests/com/google/gerrit/reviewdb/converter/PatchSetProtoConverterTest.java
@@ -25,9 +25,11 @@
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.inject.TypeLiteral;
import com.google.protobuf.Parser;
import java.lang.reflect.Type;
import java.sql.Timestamp;
+import java.util.Optional;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
@@ -37,14 +39,15 @@
@Test
public void allValuesConvertedToProto() {
PatchSet patchSet =
- new PatchSet(
- PatchSet.id(Change.id(103), 73),
- ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
- patchSet.setUploader(Account.id(452));
- patchSet.setCreatedOn(new Timestamp(930349320L));
- patchSet.setGroups(ImmutableList.of("group1, group2"));
- patchSet.setPushCertificate("my push certificate");
- patchSet.setDescription("This is a patch set description.");
+ PatchSet.builder()
+ .id(PatchSet.id(Change.id(103), 73))
+ .commitId(ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"))
+ .uploader(Account.id(452))
+ .createdOn(new Timestamp(930349320L))
+ .groups(ImmutableList.of("group1", " group2"))
+ .pushCertificate("my push certificate")
+ .description("This is a patch set description.")
+ .build();
Entities.PatchSet proto = patchSetProtoConverter.toProto(patchSet);
@@ -68,9 +71,12 @@
@Test
public void mandatoryValuesConvertedToProto() {
PatchSet patchSet =
- new PatchSet(
- PatchSet.id(Change.id(103), 73),
- ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
+ PatchSet.builder()
+ .id(PatchSet.id(Change.id(103), 73))
+ .commitId(ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"))
+ .uploader(Account.id(452))
+ .createdOn(new Timestamp(930349320L))
+ .build();
Entities.PatchSet proto = patchSetProtoConverter.toProto(patchSet);
@@ -82,6 +88,8 @@
.setId(73))
.setCommitId(
Entities.ObjectId.newBuilder().setName("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"))
+ .setUploaderAccountId(Entities.Account_Id.newBuilder().setId(452))
+ .setCreatedOn(930349320L)
.build();
assertThat(proto).isEqualTo(expectedProto);
}
@@ -89,14 +97,15 @@
@Test
public void allValuesConvertedToProtoAndBackAgain() {
PatchSet patchSet =
- new PatchSet(
- PatchSet.id(Change.id(103), 73),
- ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
- patchSet.setUploader(Account.id(452));
- patchSet.setCreatedOn(new Timestamp(930349320L));
- patchSet.setGroups(ImmutableList.of("group1, group2"));
- patchSet.setPushCertificate("my push certificate");
- patchSet.setDescription("This is a patch set description.");
+ PatchSet.builder()
+ .id(PatchSet.id(Change.id(103), 73))
+ .commitId(ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"))
+ .uploader(Account.id(452))
+ .createdOn(new Timestamp(930349320L))
+ .groups(ImmutableList.of("group1", " group2"))
+ .pushCertificate("my push certificate")
+ .description("This is a patch set description.")
+ .build();
PatchSet convertedPatchSet =
patchSetProtoConverter.fromProto(patchSetProtoConverter.toProto(patchSet));
@@ -106,9 +115,12 @@
@Test
public void mandatoryValuesConvertedToProtoAndBackAgain() {
PatchSet patchSet =
- new PatchSet(
- PatchSet.id(Change.id(103), 73),
- ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
+ PatchSet.builder()
+ .id(PatchSet.id(Change.id(103), 73))
+ .commitId(ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"))
+ .uploader(Account.id(452))
+ .createdOn(new Timestamp(930349320L))
+ .build();
PatchSet convertedPatchSet =
patchSetProtoConverter.fromProto(patchSetProtoConverter.toProto(patchSet));
@@ -116,6 +128,27 @@
}
@Test
+ public void previouslyOptionalValuesMayBeMissingFromProto() {
+ Entities.PatchSet proto =
+ Entities.PatchSet.newBuilder()
+ .setId(
+ Entities.PatchSet_Id.newBuilder()
+ .setChangeId(Entities.Change_Id.newBuilder().setId(103))
+ .setId(73))
+ .build();
+
+ PatchSet convertedPatchSet = patchSetProtoConverter.fromProto(proto);
+ Truth.assertThat(convertedPatchSet)
+ .isEqualTo(
+ PatchSet.builder()
+ .id(PatchSet.id(Change.id(103), 73))
+ .commitId(ObjectId.fromString("0000000000000000000000000000000000000000"))
+ .uploader(Account.id(0))
+ .createdOn(new Timestamp(0))
+ .build());
+ }
+
+ @Test
public void protoCanBeParsedFromBytes() throws Exception {
Entities.PatchSet proto =
Entities.PatchSet.newBuilder()
@@ -136,15 +169,15 @@
@Test
public void fieldsExistAsExpected() {
assertThatSerializedClass(PatchSet.class)
- .hasFields(
+ .hasAutoValueMethods(
ImmutableMap.<String, Type>builder()
.put("id", PatchSet.Id.class)
.put("commitId", ObjectId.class)
.put("uploader", Account.Id.class)
.put("createdOn", Timestamp.class)
- .put("groups", String.class)
- .put("pushCertificate", String.class)
- .put("description", String.class)
+ .put("groups", new TypeLiteral<ImmutableList<String>>() {}.getType())
+ .put("pushCertificate", new TypeLiteral<Optional<String>>() {}.getType())
+ .put("description", new TypeLiteral<Optional<String>>() {}.getType())
.build());
}
}
diff --git a/javatests/com/google/gerrit/server/BUILD b/javatests/com/google/gerrit/server/BUILD
index 321d1fd..5066368 100644
--- a/javatests/com/google/gerrit/server/BUILD
+++ b/javatests/com/google/gerrit/server/BUILD
@@ -34,6 +34,7 @@
],
deps = [
":custom-truth-subjects",
+ "//java/com/google/gerrit/acceptance/testsuite/project",
"//java/com/google/gerrit/common:annotations",
"//java/com/google/gerrit/common:server",
"//java/com/google/gerrit/exceptions",
@@ -59,6 +60,7 @@
"//java/com/google/gerrit/server/schema",
"//java/com/google/gerrit/server/schema/testing",
"//java/com/google/gerrit/server/util/time",
+ "//java/com/google/gerrit/testing:assertable-executor",
"//java/com/google/gerrit/testing:gerrit-test-util",
"//java/com/google/gerrit/truth",
"//java/org/eclipse/jgit:server",
diff --git a/javatests/com/google/gerrit/server/ChangeUtilTest.java b/javatests/com/google/gerrit/server/ChangeUtilTest.java
index 5cb474d..5f73d2c 100644
--- a/javatests/com/google/gerrit/server/ChangeUtilTest.java
+++ b/javatests/com/google/gerrit/server/ChangeUtilTest.java
@@ -16,11 +16,10 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.regex.Pattern;
import org.junit.Test;
-public class ChangeUtilTest extends GerritBaseTests {
+public class ChangeUtilTest {
@Test
public void changeMessageUuid() throws Exception {
Pattern pat = Pattern.compile("^[0-9a-f]{8}_[0-9a-f]{8}$");
diff --git a/javatests/com/google/gerrit/server/IdentifiedUserTest.java b/javatests/com/google/gerrit/server/IdentifiedUserTest.java
index e4278c2..d6fb5d9 100644
--- a/javatests/com/google/gerrit/server/IdentifiedUserTest.java
+++ b/javatests/com/google/gerrit/server/IdentifiedUserTest.java
@@ -31,7 +31,6 @@
import com.google.gerrit.server.util.time.TimeUtil;
import com.google.gerrit.testing.ConfigSuite;
import com.google.gerrit.testing.FakeAccountCache;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
@@ -45,7 +44,7 @@
import org.junit.runner.RunWith;
@RunWith(ConfigSuite.class)
-public class IdentifiedUserTest extends GerritBaseTests {
+public class IdentifiedUserTest {
@ConfigSuite.Parameter public Config config;
private IdentifiedUser identifiedUser;
diff --git a/javatests/com/google/gerrit/server/account/AccountResolverTest.java b/javatests/com/google/gerrit/server/account/AccountResolverTest.java
index b2484c2..d4ad7d7 100644
--- a/javatests/com/google/gerrit/server/account/AccountResolverTest.java
+++ b/javatests/com/google/gerrit/server/account/AccountResolverTest.java
@@ -17,7 +17,7 @@
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.joining;
import com.google.common.collect.ImmutableList;
@@ -29,15 +29,14 @@
import com.google.gerrit.server.account.AccountResolver.UnresolvableAccountException;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.Arrays;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Stream;
import org.junit.Test;
-public class AccountResolverTest extends GerritBaseTests {
- private class TestSearcher extends StringSearcher {
+public class AccountResolverTest {
+ private static class TestSearcher extends StringSearcher {
private final String pattern;
private final boolean shortCircuit;
private final ImmutableList<AccountState> accounts;
@@ -225,15 +224,14 @@
@Test
public void asUniqueWithNoResults() throws Exception {
- try {
- String input = "foo";
- ImmutableList<Searcher<?>> searchers = ImmutableList.of();
- Supplier<Predicate<AccountState>> visibilitySupplier = allVisible();
- search(input, searchers, visibilitySupplier).asUnique();
- assert_().fail("Expected UnresolvableAccountException");
- } catch (UnresolvableAccountException e) {
- assertThat(e).hasMessageThat().isEqualTo("Account 'foo' not found");
- }
+ String input = "foo";
+ ImmutableList<Searcher<?>> searchers = ImmutableList.of();
+ Supplier<Predicate<AccountState>> visibilitySupplier = allVisible();
+ UnresolvableAccountException thrown =
+ assertThrows(
+ UnresolvableAccountException.class,
+ () -> search(input, searchers, visibilitySupplier).asUnique());
+ assertThat(thrown).hasMessageThat().isEqualTo("Account 'foo' not found");
}
@Test
@@ -249,14 +247,13 @@
public void asUniqueWithMultipleResults() throws Exception {
ImmutableList<Searcher<?>> searchers =
ImmutableList.of(new TestSearcher("foo", false, newAccount(1), newAccount(2)));
- try {
- search("foo", searchers, allVisible()).asUnique();
- assert_().fail("Expected UnresolvableAccountException");
- } catch (UnresolvableAccountException e) {
- assertThat(e)
- .hasMessageThat()
- .isEqualTo("Account 'foo' is ambiguous:\n1: Anonymous Name (1)\n2: Anonymous Name (2)");
- }
+ UnresolvableAccountException thrown =
+ assertThrows(
+ UnresolvableAccountException.class,
+ () -> search("foo", searchers, allVisible()).asUnique());
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo("Account 'foo' is ambiguous:\n1: Anonymous Name (1)\n2: Anonymous Name (2)");
}
@Test
diff --git a/javatests/com/google/gerrit/server/account/AuthorizedKeysTest.java b/javatests/com/google/gerrit/server/account/AuthorizedKeysTest.java
index fb98ab5..e85c575 100644
--- a/javatests/com/google/gerrit/server/account/AuthorizedKeysTest.java
+++ b/javatests/com/google/gerrit/server/account/AuthorizedKeysTest.java
@@ -17,13 +17,12 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.junit.Test;
-public class AuthorizedKeysTest extends GerritBaseTests {
+public class AuthorizedKeysTest {
private static final String KEY1 =
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCgug5VyMXQGnem2H1KVC4/HcRcD4zzBqS"
+ "uJBRWVonSSoz3RoAZ7bWXCVVGwchtXwUURD689wFYdiPecOrWOUgeeyRq754YWRhU+W28"
diff --git a/javatests/com/google/gerrit/server/account/DestinationListTest.java b/javatests/com/google/gerrit/server/account/DestinationListTest.java
index 71dc5ef..4bef44a 100644
--- a/javatests/com/google/gerrit/server/account/DestinationListTest.java
+++ b/javatests/com/google/gerrit/server/account/DestinationListTest.java
@@ -19,7 +19,6 @@
import com.google.gerrit.reviewdb.client.BranchNameKey;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.git.ValidationError;
-import com.google.gerrit.testing.GerritBaseTests;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
@@ -27,7 +26,7 @@
import java.util.Set;
import org.junit.Test;
-public class DestinationListTest extends GerritBaseTests {
+public class DestinationListTest {
public static final String R_FOO = "refs/heads/foo";
public static final String R_BAR = "refs/heads/bar";
diff --git a/javatests/com/google/gerrit/server/account/GroupUUIDTest.java b/javatests/com/google/gerrit/server/account/GroupUUIDTest.java
index 70887e6..3b72b08 100644
--- a/javatests/com/google/gerrit/server/account/GroupUUIDTest.java
+++ b/javatests/com/google/gerrit/server/account/GroupUUIDTest.java
@@ -17,11 +17,10 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.testing.GerritBaseTests;
import org.eclipse.jgit.lib.PersonIdent;
import org.junit.Test;
-public class GroupUUIDTest extends GerritBaseTests {
+public class GroupUUIDTest {
@Test
public void createdUuidsForSameInputShouldBeDifferent() {
String groupName = "Users";
diff --git a/javatests/com/google/gerrit/server/account/HashedPasswordTest.java b/javatests/com/google/gerrit/server/account/HashedPasswordTest.java
index 9a0c9cb9..82943af 100644
--- a/javatests/com/google/gerrit/server/account/HashedPasswordTest.java
+++ b/javatests/com/google/gerrit/server/account/HashedPasswordTest.java
@@ -15,13 +15,13 @@
package com.google.gerrit.server.account;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.base.Strings;
-import com.google.gerrit.testing.GerritBaseTests;
import org.apache.commons.codec.DecoderException;
import org.junit.Test;
-public class HashedPasswordTest extends GerritBaseTests {
+public class HashedPasswordTest {
@Test
public void encodeOneLine() throws Exception {
@@ -41,9 +41,9 @@
assertThat(roundtrip.checkPassword("not the password")).isFalse();
}
- @Test(expected = DecoderException.class)
+ @Test
public void invalidDecode() throws Exception {
- HashedPassword.decode("invalid");
+ assertThrows(DecoderException.class, () -> HashedPassword.decode("invalid"));
}
@Test
diff --git a/javatests/com/google/gerrit/server/account/QueryListTest.java b/javatests/com/google/gerrit/server/account/QueryListTest.java
index a0876e1..7d491c9 100644
--- a/javatests/com/google/gerrit/server/account/QueryListTest.java
+++ b/javatests/com/google/gerrit/server/account/QueryListTest.java
@@ -17,12 +17,11 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.server.git.ValidationError;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
-public class QueryListTest extends GerritBaseTests {
+public class QueryListTest {
public static final String Q_P = "project:foo";
public static final String Q_B = "branch:bar";
public static final String Q_COMPLEX = "branch:bar AND peers:'is:open\t'";
diff --git a/javatests/com/google/gerrit/server/account/UniversalGroupBackendTest.java b/javatests/com/google/gerrit/server/account/UniversalGroupBackendTest.java
index 0972cb8..8bac910 100644
--- a/javatests/com/google/gerrit/server/account/UniversalGroupBackendTest.java
+++ b/javatests/com/google/gerrit/server/account/UniversalGroupBackendTest.java
@@ -37,13 +37,12 @@
import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.plugincontext.PluginContext.PluginMetrics;
import com.google.gerrit.server.plugincontext.PluginSetContext;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.Set;
import org.eclipse.jgit.lib.Config;
import org.junit.Before;
import org.junit.Test;
-public class UniversalGroupBackendTest extends GerritBaseTests {
+public class UniversalGroupBackendTest {
private static final AccountGroup.UUID OTHER_UUID = AccountGroup.uuid("other");
private UniversalGroupBackend backend;
diff --git a/javatests/com/google/gerrit/server/account/externalids/AllExternalIdsTest.java b/javatests/com/google/gerrit/server/account/externalids/AllExternalIdsTest.java
index efb8cd9..8487de4 100644
--- a/javatests/com/google/gerrit/server/account/externalids/AllExternalIdsTest.java
+++ b/javatests/com/google/gerrit/server/account/externalids/AllExternalIdsTest.java
@@ -25,13 +25,12 @@
import com.google.gerrit.server.account.externalids.AllExternalIds.Serializer;
import com.google.gerrit.server.cache.proto.Cache.AllExternalIdsProto;
import com.google.gerrit.server.cache.proto.Cache.AllExternalIdsProto.ExternalIdProto;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.inject.TypeLiteral;
import java.util.Arrays;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
-public class AllExternalIdsTest extends GerritBaseTests {
+public class AllExternalIdsTest {
@Test
public void serializeEmptyExternalIds() throws Exception {
assertRoundTrip(allExternalIds(), AllExternalIdsProto.getDefaultInstance());
diff --git a/javatests/com/google/gerrit/server/cache/PerThreadCacheTest.java b/javatests/com/google/gerrit/server/cache/PerThreadCacheTest.java
index 6a42577..d19073d 100644
--- a/javatests/com/google/gerrit/server/cache/PerThreadCacheTest.java
+++ b/javatests/com/google/gerrit/server/cache/PerThreadCacheTest.java
@@ -15,12 +15,12 @@
package com.google.gerrit.server.cache;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.function.Supplier;
import org.junit.Test;
-public class PerThreadCacheTest extends GerritBaseTests {
+public class PerThreadCacheTest {
@Test
public void key_respectsClass() {
assertThat(PerThreadCache.Key.create(String.class))
@@ -75,9 +75,9 @@
@Test
public void doubleInstantiationFails() {
try (PerThreadCache ignored = PerThreadCache.create()) {
- exception.expect(IllegalStateException.class);
- exception.expectMessage("called create() twice on the same request");
- PerThreadCache.create();
+ IllegalStateException thrown =
+ assertThrows(IllegalStateException.class, () -> PerThreadCache.create());
+ assertThat(thrown).hasMessageThat().contains("called create() twice on the same request");
}
}
diff --git a/javatests/com/google/gerrit/server/cache/serialize/BooleanCacheSerializerTest.java b/javatests/com/google/gerrit/server/cache/serialize/BooleanCacheSerializerTest.java
index c634a78..ebd7d55 100644
--- a/javatests/com/google/gerrit/server/cache/serialize/BooleanCacheSerializerTest.java
+++ b/javatests/com/google/gerrit/server/cache/serialize/BooleanCacheSerializerTest.java
@@ -15,14 +15,12 @@
package com.google.gerrit.server.cache.serialize;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
-import com.google.gerrit.testing.GerritBaseTests;
-import com.google.protobuf.TextFormat;
import org.junit.Test;
-public class BooleanCacheSerializerTest extends GerritBaseTests {
+public class BooleanCacheSerializerTest {
@Test
public void serialize() throws Exception {
assertThat(BooleanCacheSerializer.INSTANCE.serialize(true))
@@ -53,11 +51,6 @@
}
private static void assertDeserializeFails(byte[] in) {
- try {
- BooleanCacheSerializer.INSTANCE.deserialize(in);
- assert_().fail("expected deserialization to fail for \"%s\"", TextFormat.escapeBytes(in));
- } catch (RuntimeException e) {
- // Expected.
- }
+ assertThrows(RuntimeException.class, () -> BooleanCacheSerializer.INSTANCE.deserialize(in));
}
}
diff --git a/javatests/com/google/gerrit/server/cache/serialize/CacheSerializerTest.java b/javatests/com/google/gerrit/server/cache/serialize/CacheSerializerTest.java
index 14ba779..819189f 100644
--- a/javatests/com/google/gerrit/server/cache/serialize/CacheSerializerTest.java
+++ b/javatests/com/google/gerrit/server/cache/serialize/CacheSerializerTest.java
@@ -15,14 +15,13 @@
package com.google.gerrit.server.cache.serialize;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.auto.value.AutoValue;
import com.google.common.base.Converter;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class CacheSerializerTest extends GerritBaseTests {
+public class CacheSerializerTest {
@AutoValue
abstract static class MyAutoValue {
static MyAutoValue create(int val) {
@@ -46,11 +45,6 @@
@Test
public void deserializeNullFails() throws Exception {
- try {
- SERIALIZER.deserialize(null);
- assert_().fail("expected RuntimeException");
- } catch (RuntimeException e) {
- // Expected.
- }
+ assertThrows(RuntimeException.class, () -> SERIALIZER.deserialize(null));
}
}
diff --git a/javatests/com/google/gerrit/server/cache/serialize/EnumCacheSerializerTest.java b/javatests/com/google/gerrit/server/cache/serialize/EnumCacheSerializerTest.java
index c6efc21..7bfcc59 100644
--- a/javatests/com/google/gerrit/server/cache/serialize/EnumCacheSerializerTest.java
+++ b/javatests/com/google/gerrit/server/cache/serialize/EnumCacheSerializerTest.java
@@ -15,13 +15,12 @@
package com.google.gerrit.server.cache.serialize;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class EnumCacheSerializerTest extends GerritBaseTests {
+public class EnumCacheSerializerTest {
@Test
public void serialize() throws Exception {
assertRoundTrip(MyEnum.FOO);
@@ -50,11 +49,6 @@
private static void assertDeserializeFails(byte[] in) {
CacheSerializer<MyEnum> s = new EnumCacheSerializer<>(MyEnum.class);
- try {
- s.deserialize(in);
- assert_().fail("expected RuntimeException");
- } catch (RuntimeException e) {
- // Expected.
- }
+ assertThrows(RuntimeException.class, () -> s.deserialize(in));
}
}
diff --git a/javatests/com/google/gerrit/server/cache/serialize/IntegerCacheSerializerTest.java b/javatests/com/google/gerrit/server/cache/serialize/IntegerCacheSerializerTest.java
index 2ddafe0..40ff0ac 100644
--- a/javatests/com/google/gerrit/server/cache/serialize/IntegerCacheSerializerTest.java
+++ b/javatests/com/google/gerrit/server/cache/serialize/IntegerCacheSerializerTest.java
@@ -15,15 +15,14 @@
package com.google.gerrit.server.cache.serialize;
import static com.google.common.truth.Truth.assertWithMessage;
-import static com.google.common.truth.Truth.assert_;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableList;
import com.google.common.primitives.Bytes;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.protobuf.TextFormat;
import org.junit.Test;
-public class IntegerCacheSerializerTest extends GerritBaseTests {
+public class IntegerCacheSerializerTest {
@Test
public void serialize() throws Exception {
for (int i :
@@ -55,11 +54,6 @@
}
private static void assertDeserializeFails(byte[] in) {
- try {
- IntegerCacheSerializer.INSTANCE.deserialize(in);
- assert_().fail("expected RuntimeException");
- } catch (RuntimeException e) {
- // Expected.
- }
+ assertThrows(RuntimeException.class, () -> IntegerCacheSerializer.INSTANCE.deserialize(in));
}
}
diff --git a/javatests/com/google/gerrit/server/cache/serialize/JavaCacheSerializerTest.java b/javatests/com/google/gerrit/server/cache/serialize/JavaCacheSerializerTest.java
index 9fcb8a4..6596730 100644
--- a/javatests/com/google/gerrit/server/cache/serialize/JavaCacheSerializerTest.java
+++ b/javatests/com/google/gerrit/server/cache/serialize/JavaCacheSerializerTest.java
@@ -17,11 +17,10 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.auto.value.AutoValue;
-import com.google.gerrit.testing.GerritBaseTests;
import java.io.Serializable;
import org.junit.Test;
-public class JavaCacheSerializerTest extends GerritBaseTests {
+public class JavaCacheSerializerTest {
@Test
public void builtInTypes() throws Exception {
assertRoundTrip("foo");
diff --git a/javatests/com/google/gerrit/server/cache/serialize/ObjectIdCacheSerializerTest.java b/javatests/com/google/gerrit/server/cache/serialize/ObjectIdCacheSerializerTest.java
index 257be54..7d6647a 100644
--- a/javatests/com/google/gerrit/server/cache/serialize/ObjectIdCacheSerializerTest.java
+++ b/javatests/com/google/gerrit/server/cache/serialize/ObjectIdCacheSerializerTest.java
@@ -15,14 +15,13 @@
package com.google.gerrit.server.cache.serialize;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
import static com.google.gerrit.server.cache.testing.CacheSerializerTestUtil.byteArray;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import com.google.gerrit.testing.GerritBaseTests;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
-public class ObjectIdCacheSerializerTest extends GerritBaseTests {
+public class ObjectIdCacheSerializerTest {
@Test
public void serialize() {
ObjectId id = ObjectId.fromString("aabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
@@ -47,11 +46,7 @@
}
private void assertDeserializeFails(byte[] bytes) {
- try {
- ObjectIdCacheSerializer.INSTANCE.deserialize(bytes);
- assert_().fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // Expected.
- }
+ assertThrows(
+ IllegalArgumentException.class, () -> ObjectIdCacheSerializer.INSTANCE.deserialize(bytes));
}
}
diff --git a/javatests/com/google/gerrit/server/cache/serialize/ObjectIdConverterTest.java b/javatests/com/google/gerrit/server/cache/serialize/ObjectIdConverterTest.java
index c5ea2ea..f6d6c8a 100644
--- a/javatests/com/google/gerrit/server/cache/serialize/ObjectIdConverterTest.java
+++ b/javatests/com/google/gerrit/server/cache/serialize/ObjectIdConverterTest.java
@@ -15,15 +15,14 @@
package com.google.gerrit.server.cache.serialize;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
import static com.google.gerrit.server.cache.testing.CacheSerializerTestUtil.byteString;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.protobuf.ByteString;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
-public class ObjectIdConverterTest extends GerritBaseTests {
+public class ObjectIdConverterTest {
@Test
public void objectIdFromByteString() {
ObjectIdConverter idConverter = ObjectIdConverter.create();
@@ -43,12 +42,9 @@
@Test
public void objectIdFromByteStringWrongSize() {
- try {
- ObjectIdConverter.create().fromByteString(ByteString.copyFromUtf8("foo"));
- assert_().fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // Expected.
- }
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> ObjectIdConverter.create().fromByteString(ByteString.copyFromUtf8("foo")));
}
@Test
diff --git a/javatests/com/google/gerrit/server/cache/serialize/ProtobufSerializerTest.java b/javatests/com/google/gerrit/server/cache/serialize/ProtobufSerializerTest.java
index 845da9b..04d2f73 100644
--- a/javatests/com/google/gerrit/server/cache/serialize/ProtobufSerializerTest.java
+++ b/javatests/com/google/gerrit/server/cache/serialize/ProtobufSerializerTest.java
@@ -17,10 +17,9 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.proto.testing.Test.SerializableProto;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class ProtobufSerializerTest extends GerritBaseTests {
+public class ProtobufSerializerTest {
@Test
public void requiredAndOptionalTypes() {
assertRoundTrip(SerializableProto.newBuilder().setId(123));
diff --git a/javatests/com/google/gerrit/server/cache/serialize/StringCacheSerializerTest.java b/javatests/com/google/gerrit/server/cache/serialize/StringCacheSerializerTest.java
index ff0cf9a..dc22805 100644
--- a/javatests/com/google/gerrit/server/cache/serialize/StringCacheSerializerTest.java
+++ b/javatests/com/google/gerrit/server/cache/serialize/StringCacheSerializerTest.java
@@ -15,14 +15,13 @@
package com.google.gerrit.server.cache.serialize;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import com.google.gerrit.testing.GerritBaseTests;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.StandardCharsets;
import org.junit.Test;
-public class StringCacheSerializerTest extends GerritBaseTests {
+public class StringCacheSerializerTest {
@Test
public void serialize() {
assertThat(StringCacheSerializer.INSTANCE.serialize("")).isEmpty();
@@ -35,12 +34,11 @@
@Test
public void serializeInvalidChar() {
// Can't use UTF-8 for the test, since it can encode all Unicode code points.
- try {
- StringCacheSerializer.serialize(StandardCharsets.US_ASCII, "\u1234");
- assert_().fail("expected IllegalStateException");
- } catch (IllegalStateException expected) {
- assertThat(expected).hasCauseThat().isInstanceOf(CharacterCodingException.class);
- }
+ IllegalStateException thrown =
+ assertThrows(
+ IllegalStateException.class,
+ () -> StringCacheSerializer.serialize(StandardCharsets.US_ASCII, "\u1234"));
+ assertThat(thrown).hasCauseThat().isInstanceOf(CharacterCodingException.class);
}
@Test
@@ -56,11 +54,10 @@
@Test
public void deserializeInvalidChar() {
- try {
- StringCacheSerializer.INSTANCE.deserialize(new byte[] {(byte) 0xff});
- assert_().fail("expected IllegalStateException");
- } catch (IllegalStateException expected) {
- assertThat(expected).hasCauseThat().isInstanceOf(CharacterCodingException.class);
- }
+ IllegalStateException thrown =
+ assertThrows(
+ IllegalStateException.class,
+ () -> StringCacheSerializer.INSTANCE.deserialize(new byte[] {(byte) 0xff}));
+ assertThat(thrown).hasCauseThat().isInstanceOf(CharacterCodingException.class);
}
}
diff --git a/javatests/com/google/gerrit/server/change/ChangeKindCacheImplTest.java b/javatests/com/google/gerrit/server/change/ChangeKindCacheImplTest.java
index fffb1da..20813f6 100644
--- a/javatests/com/google/gerrit/server/change/ChangeKindCacheImplTest.java
+++ b/javatests/com/google/gerrit/server/change/ChangeKindCacheImplTest.java
@@ -24,11 +24,10 @@
import com.google.gerrit.server.cache.proto.Cache.ChangeKindKeyProto;
import com.google.gerrit.server.cache.serialize.CacheSerializer;
import com.google.gerrit.server.change.ChangeKindCacheImpl.Key;
-import com.google.gerrit.testing.GerritBaseTests;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
-public class ChangeKindCacheImplTest extends GerritBaseTests {
+public class ChangeKindCacheImplTest {
@Test
public void keySerializer() throws Exception {
ChangeKindCacheImpl.Key key =
diff --git a/javatests/com/google/gerrit/server/change/HashtagsTest.java b/javatests/com/google/gerrit/server/change/HashtagsTest.java
index 49d2952..780ac71 100644
--- a/javatests/com/google/gerrit/server/change/HashtagsTest.java
+++ b/javatests/com/google/gerrit/server/change/HashtagsTest.java
@@ -17,10 +17,9 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.Sets;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class HashtagsTest extends GerritBaseTests {
+public class HashtagsTest {
@Test
public void emptyCommitMessage() throws Exception {
assertThat(HashtagsUtil.extractTags("")).isEmpty();
diff --git a/javatests/com/google/gerrit/server/change/IncludedInResolverTest.java b/javatests/com/google/gerrit/server/change/IncludedInResolverTest.java
index 0cfe483..13b58e6 100644
--- a/javatests/com/google/gerrit/server/change/IncludedInResolverTest.java
+++ b/javatests/com/google/gerrit/server/change/IncludedInResolverTest.java
@@ -17,7 +17,6 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.reviewdb.client.RefNames.REFS_TAGS;
-import com.google.gerrit.testing.GerritBaseTests;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
@@ -27,7 +26,7 @@
import org.junit.Before;
import org.junit.Test;
-public class IncludedInResolverTest extends GerritBaseTests {
+public class IncludedInResolverTest {
// Branch names
private static final String BRANCH_MASTER = "master";
private static final String BRANCH_1_0 = "rel-1.0";
diff --git a/javatests/com/google/gerrit/server/change/LabelNormalizerTest.java b/javatests/com/google/gerrit/server/change/LabelNormalizerTest.java
index a50d8a8..beeca21 100644
--- a/javatests/com/google/gerrit/server/change/LabelNormalizerTest.java
+++ b/javatests/com/google/gerrit/server/change/LabelNormalizerTest.java
@@ -14,14 +14,15 @@
package com.google.gerrit.server.change;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
import static com.google.gerrit.common.data.Permission.forLabel;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
-import static com.google.gerrit.server.project.testing.Util.allow;
-import static com.google.gerrit.server.project.testing.Util.category;
-import static com.google.gerrit.server.project.testing.Util.value;
+import static com.google.gerrit.server.project.testing.TestLabels.label;
+import static com.google.gerrit.server.project.testing.TestLabels.value;
import static org.junit.Assert.assertEquals;
import com.google.common.collect.ImmutableList;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.extensions.api.GerritApi;
@@ -45,7 +46,6 @@
import com.google.gerrit.server.schema.SchemaCreator;
import com.google.gerrit.server.util.ThreadLocalRequestContext;
import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.InMemoryModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
@@ -57,7 +57,7 @@
import org.junit.Test;
/** Unit tests for {@link LabelNormalizer}. */
-public class LabelNormalizerTest extends GerritBaseTests {
+public class LabelNormalizerTest {
@Inject private AccountManager accountManager;
@Inject private AllProjectsName allProjects;
@Inject private GitRepositoryManager repoManager;
@@ -70,6 +70,7 @@
@Inject private ChangeNotes.Factory changeNotesFactory;
@Inject private ProjectConfig.Factory projectConfigFactory;
@Inject private GerritApi gApi;
+ @Inject private ProjectOperations projectOperations;
private LifecycleManager lifecycle;
private Account.Id userId;
@@ -103,7 +104,7 @@
}
}
LabelType lt =
- category("Verified", value(1, "Verified"), value(0, "No score"), value(-1, "Fails"));
+ label("Verified", value(1, "Verified"), value(0, "No score"), value(-1, "Fails"));
pc.getLabelSections().put(lt.getName(), lt);
save(pc);
}
@@ -129,10 +130,11 @@
@Test
public void noNormalizeByPermission() throws Exception {
- ProjectConfig pc = loadAllProjects();
- allow(pc, forLabel("Code-Review"), -1, 1, REGISTERED_USERS, "refs/heads/*");
- allow(pc, forLabel("Verified"), -1, 1, REGISTERED_USERS, "refs/heads/*");
- save(pc);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(REGISTERED_USERS).range(-1, 1))
+ .add(allowLabel("Verified").ref("refs/heads/*").group(REGISTERED_USERS).range(-1, 1))
+ .update();
PatchSetApproval cr = psa(userId, "Code-Review", 2);
PatchSetApproval v = psa(userId, "Verified", 1);
@@ -141,10 +143,11 @@
@Test
public void normalizeByType() throws Exception {
- ProjectConfig pc = loadAllProjects();
- allow(pc, forLabel("Code-Review"), -5, 5, REGISTERED_USERS, "refs/heads/*");
- allow(pc, forLabel("Verified"), -5, 5, REGISTERED_USERS, "refs/heads/*");
- save(pc);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(REGISTERED_USERS).range(-5, 5))
+ .add(allowLabel("Verified").ref("refs/heads/*").group(REGISTERED_USERS).range(-5, 5))
+ .update();
PatchSetApproval cr = psa(userId, "Code-Review", 5);
PatchSetApproval v = psa(userId, "Verified", 5);
@@ -162,9 +165,10 @@
@Test
public void explicitZeroVoteOnNonEmptyRangeIsPresent() throws Exception {
- ProjectConfig pc = loadAllProjects();
- allow(pc, forLabel("Code-Review"), -1, 1, REGISTERED_USERS, "refs/heads/*");
- save(pc);
+ projectOperations
+ .allProjectsForUpdate()
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(REGISTERED_USERS).range(-1, 1))
+ .update();
PatchSetApproval cr = psa(userId, "Code-Review", 0);
PatchSetApproval v = psa(userId, "Verified", 0);
@@ -187,16 +191,15 @@
}
private PatchSetApproval psa(Account.Id accountId, String label, int value) {
- return new PatchSetApproval(
- PatchSetApproval.key(change.currentPatchSetId(), accountId, LabelId.create(label)),
- (short) value,
- TimeUtil.nowTs());
+ return PatchSetApproval.builder()
+ .key(PatchSetApproval.key(change.currentPatchSetId(), accountId, LabelId.create(label)))
+ .value(value)
+ .granted(TimeUtil.nowTs())
+ .build();
}
private PatchSetApproval copy(PatchSetApproval src, int newValue) {
- PatchSetApproval result = new PatchSetApproval(src.getKey().patchSetId(), src);
- result.setValue((short) newValue);
- return result;
+ return src.toBuilder().value(newValue).build();
}
private static List<PatchSetApproval> list(PatchSetApproval... psas) {
diff --git a/javatests/com/google/gerrit/server/change/MergeabilityCacheImplTest.java b/javatests/com/google/gerrit/server/change/MergeabilityCacheImplTest.java
index 46ddbc2..19c8998 100644
--- a/javatests/com/google/gerrit/server/change/MergeabilityCacheImplTest.java
+++ b/javatests/com/google/gerrit/server/change/MergeabilityCacheImplTest.java
@@ -23,11 +23,10 @@
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.proto.testing.SerializedClassSubject;
import com.google.gerrit.server.cache.proto.Cache.MergeabilityKeyProto;
-import com.google.gerrit.testing.GerritBaseTests;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
-public class MergeabilityCacheImplTest extends GerritBaseTests {
+public class MergeabilityCacheImplTest {
@Test
public void keySerializer() throws Exception {
MergeabilityCacheImpl.EntryKey key =
diff --git a/javatests/com/google/gerrit/server/change/WalkSorterTest.java b/javatests/com/google/gerrit/server/change/WalkSorterTest.java
index 8857649..4a42140 100644
--- a/javatests/com/google/gerrit/server/change/WalkSorterTest.java
+++ b/javatests/com/google/gerrit/server/change/WalkSorterTest.java
@@ -25,7 +25,6 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.change.WalkSorter.PatchSetData;
import com.google.gerrit.server.query.change.ChangeData;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.InMemoryRepositoryManager;
import com.google.gerrit.testing.InMemoryRepositoryManager.Repo;
import com.google.gerrit.testing.TestChanges;
@@ -38,7 +37,7 @@
import org.junit.Before;
import org.junit.Test;
-public class WalkSorterTest extends GerritBaseTests {
+public class WalkSorterTest {
private Account.Id userId;
private InMemoryRepositoryManager repoManager;
@@ -296,8 +295,7 @@
List<ChangeData> changes = ImmutableList.of(cd1, cd2);
WalkSorter sorter =
- new WalkSorter(repoManager)
- .includePatchSets(ImmutableSet.of(cd1.currentPatchSet().getId()));
+ new WalkSorter(repoManager).includePatchSets(ImmutableSet.of(cd1.currentPatchSet().id()));
assertSorted(sorter, changes, ImmutableList.of(patchSetData(cd1, c1)));
}
@@ -342,7 +340,7 @@
private PatchSet addPatchSet(ChangeData cd, ObjectId id) throws Exception {
TestChanges.incrementPatchSet(cd.change());
- PatchSet ps = new PatchSet(cd.change().currentPatchSetId(), id);
+ PatchSet ps = TestChanges.newPatchSet(cd.change().currentPatchSetId(), id.name(), userId);
List<PatchSet> patchSets = new ArrayList<>(cd.patchSets());
patchSets.add(ps);
cd.setPatchSets(patchSets);
diff --git a/javatests/com/google/gerrit/server/config/ConfigUtilTest.java b/javatests/com/google/gerrit/server/config/ConfigUtilTest.java
index 75fb94e..865bda6 100644
--- a/javatests/com/google/gerrit/server/config/ConfigUtilTest.java
+++ b/javatests/com/google/gerrit/server/config/ConfigUtilTest.java
@@ -15,6 +15,7 @@
package com.google.gerrit.server.config;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.truth.ConfigSubject.assertThat;
import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -22,14 +23,13 @@
import static java.util.concurrent.TimeUnit.SECONDS;
import com.google.gerrit.extensions.client.Theme;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.lib.Config;
import org.junit.Test;
-public class ConfigUtilTest extends GerritBaseTests {
+public class ConfigUtilTest {
private static final String SECT = "foo";
private static final String SUB = "bar";
@@ -91,17 +91,17 @@
Config cfg = new Config();
ConfigUtil.storeSection(cfg, SECT, SUB, in, d);
- assertThat(cfg.getString(SECT, SUB, "CONSTANT")).isNull();
- assertThat(cfg.getString(SECT, SUB, "missing")).isNull();
- assertThat(cfg.getBoolean(SECT, SUB, "b", false)).isEqualTo(in.b);
- assertThat(cfg.getBoolean(SECT, SUB, "bb", false)).isEqualTo(in.bb);
- assertThat(cfg.getInt(SECT, SUB, "i", 0)).isEqualTo(0);
- assertThat(cfg.getInt(SECT, SUB, "ii", 0)).isEqualTo(in.ii);
- assertThat(cfg.getLong(SECT, SUB, "l", 0L)).isEqualTo(0L);
- assertThat(cfg.getLong(SECT, SUB, "ll", 0L)).isEqualTo(in.ll);
- assertThat(cfg.getString(SECT, SUB, "s")).isEqualTo(in.s);
- assertThat(cfg.getString(SECT, SUB, "sd")).isNull();
- assertThat(cfg.getString(SECT, SUB, "nd")).isNull();
+ assertThat(cfg).stringValue(SECT, SUB, "CONSTANT").isNull();
+ assertThat(cfg).stringValue(SECT, SUB, "missing").isNull();
+ assertThat(cfg).booleanValue(SECT, SUB, "b", false).isEqualTo(in.b);
+ assertThat(cfg).booleanValue(SECT, SUB, "bb", false).isEqualTo(in.bb);
+ assertThat(cfg).intValue(SECT, SUB, "i", 0).isEqualTo(0);
+ assertThat(cfg).intValue(SECT, SUB, "ii", 0).isEqualTo(in.ii);
+ assertThat(cfg).longValue(SECT, SUB, "l", 0L).isEqualTo(0L);
+ assertThat(cfg).longValue(SECT, SUB, "ll", 0L).isEqualTo(in.ll);
+ assertThat(cfg).stringValue(SECT, SUB, "s").isEqualTo(in.s);
+ assertThat(cfg).stringValue(SECT, SUB, "sd").isNull();
+ assertThat(cfg).stringValue(SECT, SUB, "nd").isNull();
SectionInfo out = new SectionInfo();
ConfigUtil.loadSection(cfg, SECT, SUB, out, d, null);
diff --git a/javatests/com/google/gerrit/server/config/GitwebConfigTest.java b/javatests/com/google/gerrit/server/config/GitwebConfigTest.java
index bf7e4fd..cb6de34 100644
--- a/javatests/com/google/gerrit/server/config/GitwebConfigTest.java
+++ b/javatests/com/google/gerrit/server/config/GitwebConfigTest.java
@@ -16,10 +16,9 @@
import static com.google.common.truth.Truth.assertWithMessage;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class GitwebConfigTest extends GerritBaseTests {
+public class GitwebConfigTest {
private static final String VALID_CHARACTERS = "*()";
private static final String SOME_INVALID_CHARACTERS = "09AZaz$-_.+!',";
diff --git a/javatests/com/google/gerrit/server/config/ListCapabilitiesTest.java b/javatests/com/google/gerrit/server/config/ListCapabilitiesTest.java
index 30fabdc..de36ccc 100644
--- a/javatests/com/google/gerrit/server/config/ListCapabilitiesTest.java
+++ b/javatests/com/google/gerrit/server/config/ListCapabilitiesTest.java
@@ -27,7 +27,6 @@
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.restapi.config.ListCapabilities;
import com.google.gerrit.server.restapi.config.ListCapabilities.CapabilityInfo;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
@@ -36,7 +35,7 @@
import org.junit.Before;
import org.junit.Test;
-public class ListCapabilitiesTest extends GerritBaseTests {
+public class ListCapabilitiesTest {
private Injector injector;
@Before
diff --git a/javatests/com/google/gerrit/server/config/RepositoryConfigTest.java b/javatests/com/google/gerrit/server/config/RepositoryConfigTest.java
index b62aeb6..895cc7e 100644
--- a/javatests/com/google/gerrit/server/config/RepositoryConfigTest.java
+++ b/javatests/com/google/gerrit/server/config/RepositoryConfigTest.java
@@ -20,7 +20,6 @@
import com.google.common.collect.ImmutableList;
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.testing.GerritBaseTests;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
@@ -28,7 +27,7 @@
import org.junit.Before;
import org.junit.Test;
-public class RepositoryConfigTest extends GerritBaseTests {
+public class RepositoryConfigTest {
private Config cfg;
private RepositoryConfig repoCfg;
diff --git a/javatests/com/google/gerrit/server/config/ScheduleConfigTest.java b/javatests/com/google/gerrit/server/config/ScheduleConfigTest.java
index 6926052..55f0374 100644
--- a/javatests/com/google/gerrit/server/config/ScheduleConfigTest.java
+++ b/javatests/com/google/gerrit/server/config/ScheduleConfigTest.java
@@ -22,7 +22,6 @@
import static java.util.concurrent.TimeUnit.MINUTES;
import com.google.gerrit.server.config.ScheduleConfig.Schedule;
-import com.google.gerrit.testing.GerritBaseTests;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.ZoneOffset;
@@ -32,7 +31,7 @@
import org.eclipse.jgit.lib.Config;
import org.junit.Test;
-public class ScheduleConfigTest extends GerritBaseTests {
+public class ScheduleConfigTest {
// Friday June 13, 2014 10:00 UTC
private static final ZonedDateTime NOW =
diff --git a/javatests/com/google/gerrit/server/config/SitePathsTest.java b/javatests/com/google/gerrit/server/config/SitePathsTest.java
index b4cde14..1e5f41d 100644
--- a/javatests/com/google/gerrit/server/config/SitePathsTest.java
+++ b/javatests/com/google/gerrit/server/config/SitePathsTest.java
@@ -16,9 +16,9 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.server.ioutil.HostPlatform;
-import com.google.gerrit.testing.GerritBaseTests;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.NotDirectoryException;
@@ -26,7 +26,7 @@
import java.nio.file.Paths;
import org.junit.Test;
-public class SitePathsTest extends GerritBaseTests {
+public class SitePathsTest {
@Test
public void create_NotExisting() throws IOException {
final Path root = random();
@@ -72,8 +72,8 @@
final Path root = random();
try {
Files.createFile(root);
- exception.expect(NotDirectoryException.class);
- new SitePaths(root);
+ assertThrows(NotDirectoryException.class, () -> new SitePaths(root));
+
} finally {
Files.delete(root);
}
diff --git a/javatests/com/google/gerrit/server/edit/ChangeEditTest.java b/javatests/com/google/gerrit/server/edit/ChangeEditTest.java
index 307ff89..c7ed865 100644
--- a/javatests/com/google/gerrit/server/edit/ChangeEditTest.java
+++ b/javatests/com/google/gerrit/server/edit/ChangeEditTest.java
@@ -20,10 +20,9 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.RefNames;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class ChangeEditTest extends GerritBaseTests {
+public class ChangeEditTest {
@Test
public void changeEditRef() throws Exception {
Account.Id accountId = Account.id(1000042);
diff --git a/javatests/com/google/gerrit/server/edit/tree/ChangeFileContentModificationSubject.java b/javatests/com/google/gerrit/server/edit/tree/ChangeFileContentModificationSubject.java
index 0919de9..b23c47a 100644
--- a/javatests/com/google/gerrit/server/edit/tree/ChangeFileContentModificationSubject.java
+++ b/javatests/com/google/gerrit/server/edit/tree/ChangeFileContentModificationSubject.java
@@ -38,19 +38,22 @@
return ChangeFileContentModificationSubject::new;
}
+ private final ChangeFileContentModification modification;
+
private ChangeFileContentModificationSubject(
FailureMetadata failureMetadata, ChangeFileContentModification modification) {
super(failureMetadata, modification);
+ this.modification = modification;
}
public StringSubject filePath() {
isNotNull();
- return check("getFilePath()").that(actual().getFilePath());
+ return check("getFilePath()").that(modification.getFilePath());
}
public StringSubject newContent() throws IOException {
isNotNull();
- RawInput newContent = actual().getNewContent();
+ RawInput newContent = modification.getNewContent();
check("getNewContent()").that(newContent).isNotNull();
String contentString =
CharStreams.toString(
diff --git a/javatests/com/google/gerrit/server/edit/tree/TreeModificationSubject.java b/javatests/com/google/gerrit/server/edit/tree/TreeModificationSubject.java
index d898e7d..72759cd 100644
--- a/javatests/com/google/gerrit/server/edit/tree/TreeModificationSubject.java
+++ b/javatests/com/google/gerrit/server/edit/tree/TreeModificationSubject.java
@@ -36,15 +36,18 @@
return ListSubject.assertThat(treeModifications, treeModifications());
}
+ private final TreeModification treeModification;
+
private TreeModificationSubject(
FailureMetadata failureMetadata, TreeModification treeModification) {
super(failureMetadata, treeModification);
+ this.treeModification = treeModification;
}
public ChangeFileContentModificationSubject asChangeFileContentModification() {
isInstanceOf(ChangeFileContentModification.class);
return check("asChangeFileContentModification()")
.about(ChangeFileContentModificationSubject.modifications())
- .that((ChangeFileContentModification) actual());
+ .that((ChangeFileContentModification) treeModification);
}
}
diff --git a/javatests/com/google/gerrit/server/events/EventDeserializerTest.java b/javatests/com/google/gerrit/server/events/EventDeserializerTest.java
index 5d1c9d9..aacee8a 100644
--- a/javatests/com/google/gerrit/server/events/EventDeserializerTest.java
+++ b/javatests/com/google/gerrit/server/events/EventDeserializerTest.java
@@ -25,12 +25,11 @@
import com.google.gerrit.server.data.AccountAttribute;
import com.google.gerrit.server.data.ChangeAttribute;
import com.google.gerrit.server.data.RefUpdateAttribute;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gson.Gson;
import java.sql.Timestamp;
import org.junit.Test;
-public class EventDeserializerTest extends GerritBaseTests {
+public class EventDeserializerTest {
private final Gson gson = new EventGsonProvider().get();
@Test
diff --git a/javatests/com/google/gerrit/server/events/EventJsonTest.java b/javatests/com/google/gerrit/server/events/EventJsonTest.java
index be4b09a..4defda7 100644
--- a/javatests/com/google/gerrit/server/events/EventJsonTest.java
+++ b/javatests/com/google/gerrit/server/events/EventJsonTest.java
@@ -30,7 +30,6 @@
import com.google.gerrit.server.data.ChangeAttribute;
import com.google.gerrit.server.data.RefUpdateAttribute;
import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.TestTimeUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
@@ -39,7 +38,7 @@
import org.junit.Before;
import org.junit.Test;
-public class EventJsonTest extends GerritBaseTests {
+public class EventJsonTest {
private static final String BRANCH = "mybranch";
private static final String CHANGE_ID = "Ideadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
private static final int CHANGE_NUM = 1000;
diff --git a/javatests/com/google/gerrit/server/events/EventTypesTest.java b/javatests/com/google/gerrit/server/events/EventTypesTest.java
index dd5c7f9..c822d6c 100644
--- a/javatests/com/google/gerrit/server/events/EventTypesTest.java
+++ b/javatests/com/google/gerrit/server/events/EventTypesTest.java
@@ -16,10 +16,9 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class EventTypesTest extends GerritBaseTests {
+public class EventTypesTest {
public static class TestEvent extends Event {
private static final String TYPE = "test-event";
diff --git a/javatests/com/google/gerrit/server/extensions/webui/UiActionsTest.java b/javatests/com/google/gerrit/server/extensions/webui/UiActionsTest.java
index 58e0374..7a1cf51 100644
--- a/javatests/com/google/gerrit/server/extensions/webui/UiActionsTest.java
+++ b/javatests/com/google/gerrit/server/extensions/webui/UiActionsTest.java
@@ -32,7 +32,6 @@
import com.google.gerrit.server.permissions.PermissionBackendCondition;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.permissions.ProjectPermission;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
@@ -41,7 +40,7 @@
import org.eclipse.jgit.lib.Repository;
import org.junit.Test;
-public class UiActionsTest extends GerritBaseTests {
+public class UiActionsTest {
private static class FakeForProject extends ForProject {
private boolean allowValueQueries = true;
diff --git a/javatests/com/google/gerrit/server/fixes/FixReplacementInterpreterTest.java b/javatests/com/google/gerrit/server/fixes/FixReplacementInterpreterTest.java
index cc648bf..c8df548 100644
--- a/javatests/com/google/gerrit/server/fixes/FixReplacementInterpreterTest.java
+++ b/javatests/com/google/gerrit/server/fixes/FixReplacementInterpreterTest.java
@@ -15,6 +15,7 @@
package com.google.gerrit.server.fixes;
import static com.google.gerrit.server.edit.tree.TreeModificationSubject.assertThatList;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.replay;
@@ -26,7 +27,6 @@
import com.google.gerrit.server.change.FileContentUtil;
import com.google.gerrit.server.edit.tree.TreeModification;
import com.google.gerrit.server.project.ProjectState;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
@@ -36,7 +36,7 @@
import org.junit.Before;
import org.junit.Test;
-public class FixReplacementInterpreterTest extends GerritBaseTests {
+public class FixReplacementInterpreterTest {
private final FileContentUtil fileContentUtil = createMock(FileContentUtil.class);
private final Repository repository = createMock(Repository.class);
private final ProjectState projectState = createMock(ProjectState.class);
@@ -256,9 +256,7 @@
mockFileContent(filePath1, "First line\nSecond line\nThird line\n");
replay(fileContentUtil);
-
- exception.expect(ResourceConflictException.class);
- toTreeModifications(fixReplacement);
+ assertThrows(ResourceConflictException.class, () -> toTreeModifications(fixReplacement));
}
@Test
@@ -269,8 +267,7 @@
replay(fileContentUtil);
- exception.expect(ResourceConflictException.class);
- toTreeModifications(fixReplacement);
+ assertThrows(ResourceConflictException.class, () -> toTreeModifications(fixReplacement));
}
@Test
@@ -280,9 +277,7 @@
mockFileContent(filePath1, "First line\nSecond line\nThird line\n");
replay(fileContentUtil);
-
- exception.expect(ResourceConflictException.class);
- toTreeModifications(fixReplacement);
+ assertThrows(ResourceConflictException.class, () -> toTreeModifications(fixReplacement));
}
@Test
@@ -293,8 +288,7 @@
replay(fileContentUtil);
- exception.expect(ResourceConflictException.class);
- toTreeModifications(fixReplacement);
+ assertThrows(ResourceConflictException.class, () -> toTreeModifications(fixReplacement));
}
@Test
@@ -304,9 +298,7 @@
mockFileContent(filePath1, "First line\nSecond line\nThird line\n");
replay(fileContentUtil);
-
- exception.expect(ResourceConflictException.class);
- toTreeModifications(fixReplacement);
+ assertThrows(ResourceConflictException.class, () -> toTreeModifications(fixReplacement));
}
private void mockFileContent(String filePath, String fileContent) throws Exception {
diff --git a/javatests/com/google/gerrit/server/fixes/LineIdentifierTest.java b/javatests/com/google/gerrit/server/fixes/LineIdentifierTest.java
index 309f726..ba80c02 100644
--- a/javatests/com/google/gerrit/server/fixes/LineIdentifierTest.java
+++ b/javatests/com/google/gerrit/server/fixes/LineIdentifierTest.java
@@ -15,25 +15,27 @@
package com.google.gerrit.server.fixes;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class LineIdentifierTest extends GerritBaseTests {
+public class LineIdentifierTest {
@Test
public void lineNumberMustBePositive() {
LineIdentifier lineIdentifier = new LineIdentifier("First line\nSecond line");
- exception.expect(StringIndexOutOfBoundsException.class);
- exception.expectMessage("positive");
- lineIdentifier.getStartIndexOfLine(0);
+ StringIndexOutOfBoundsException thrown =
+ assertThrows(
+ StringIndexOutOfBoundsException.class, () -> lineIdentifier.getStartIndexOfLine(0));
+ assertThat(thrown).hasMessageThat().contains("positive");
}
@Test
public void lineNumberMustIndicateAnAvailableLine() {
LineIdentifier lineIdentifier = new LineIdentifier("First line\nSecond line");
- exception.expect(StringIndexOutOfBoundsException.class);
- exception.expectMessage("Line 3 isn't available");
- lineIdentifier.getStartIndexOfLine(3);
+ StringIndexOutOfBoundsException thrown =
+ assertThrows(
+ StringIndexOutOfBoundsException.class, () -> lineIdentifier.getStartIndexOfLine(3));
+ assertThat(thrown).hasMessageThat().contains("Line 3 isn't available");
}
@Test
diff --git a/javatests/com/google/gerrit/server/fixes/StringModifierTest.java b/javatests/com/google/gerrit/server/fixes/StringModifierTest.java
index 185b58c..3447248 100644
--- a/javatests/com/google/gerrit/server/fixes/StringModifierTest.java
+++ b/javatests/com/google/gerrit/server/fixes/StringModifierTest.java
@@ -15,12 +15,12 @@
package com.google.gerrit.server.fixes;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Before;
import org.junit.Test;
-public class StringModifierTest extends GerritBaseTests {
+public class StringModifierTest {
private final String originalString = "This is the original, unmodified string.";
private StringModifier stringModifier;
@@ -63,20 +63,20 @@
@Test
public void replacedPartsMustNotOverlap() {
stringModifier.replace(0, 9, "");
- exception.expect(StringIndexOutOfBoundsException.class);
- stringModifier.replace(8, 32, "The modified");
+ assertThrows(
+ StringIndexOutOfBoundsException.class, () -> stringModifier.replace(8, 32, "The modified"));
}
@Test
public void startIndexMustNotBeGreaterThanEndIndex() {
- exception.expect(StringIndexOutOfBoundsException.class);
- stringModifier.replace(10, 9, "something");
+ assertThrows(
+ StringIndexOutOfBoundsException.class, () -> stringModifier.replace(10, 9, "something"));
}
@Test
public void startIndexMustNotBeNegative() {
- exception.expect(StringIndexOutOfBoundsException.class);
- stringModifier.replace(-1, 9, "something");
+ assertThrows(
+ StringIndexOutOfBoundsException.class, () -> stringModifier.replace(-1, 9, "something"));
}
@Test
@@ -90,13 +90,17 @@
@Test
public void startIndexMustNotBeGreaterThanLengthOfString() {
- exception.expect(StringIndexOutOfBoundsException.class);
- stringModifier.replace(originalString.length() + 1, originalString.length() + 1, "something");
+ assertThrows(
+ StringIndexOutOfBoundsException.class,
+ () ->
+ stringModifier.replace(
+ originalString.length() + 1, originalString.length() + 1, "something"));
}
@Test
public void endIndexMustNotBeGreaterThanLengthOfString() {
- exception.expect(StringIndexOutOfBoundsException.class);
- stringModifier.replace(8, originalString.length() + 1, "something");
+ assertThrows(
+ StringIndexOutOfBoundsException.class,
+ () -> stringModifier.replace(8, originalString.length() + 1, "something"));
}
}
diff --git a/javatests/com/google/gerrit/server/git/GroupCollectorTest.java b/javatests/com/google/gerrit/server/git/GroupCollectorTest.java
index a712c94..2b59544 100644
--- a/javatests/com/google/gerrit/server/git/GroupCollectorTest.java
+++ b/javatests/com/google/gerrit/server/git/GroupCollectorTest.java
@@ -21,7 +21,6 @@
import com.google.common.collect.SortedSetMultimap;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.testing.GerritBaseTests;
import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
@@ -32,7 +31,7 @@
import org.junit.Before;
import org.junit.Test;
-public class GroupCollectorTest extends GerritBaseTests {
+public class GroupCollectorTest {
private TestRepository<?> tr;
@Before
diff --git a/javatests/com/google/gerrit/server/git/JGitConfigTest.java b/javatests/com/google/gerrit/server/git/JGitConfigTest.java
new file mode 100644
index 0000000..9f6b47e
--- /dev/null
+++ b/javatests/com/google/gerrit/server/git/JGitConfigTest.java
@@ -0,0 +1,84 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.git;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.gerrit.server.config.SitePaths;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.eclipse.jgit.internal.storage.file.FileRepository;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.SystemReader;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+public class JGitConfigTest {
+
+ @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ private SitePaths site;
+ private Path gitPath;
+
+ @Before
+ public void setUp() throws IOException {
+ site = new SitePaths(temporaryFolder.newFolder().toPath());
+ Files.createDirectories(site.etc_dir);
+ gitPath = Files.createDirectories(site.resolve("git"));
+
+ Files.write(
+ site.jgit_config, "[core]\n trustFolderStat = false\n".getBytes(StandardCharsets.UTF_8));
+ new SystemReaderInstaller(site).start();
+ }
+
+ @Test
+ public void test() throws IOException {
+ try (Repository repo = new FileRepository(gitPath.resolve("foo").toFile())) {
+ assertThat(repo.getConfig().getString("core", null, "trustFolderStat")).isEqualTo("false");
+ }
+ }
+
+ @Test
+ public void openSystemConfigRespectsParent() throws Exception {
+ Config parent = new Config();
+ parent.setString("foo", null, "bar", "value");
+ FileBasedConfig system = SystemReader.getInstance().openSystemConfig(parent, FS.DETECTED);
+ system.load();
+ assertThat(system.getString("core", null, "trustFolderStat")).isEqualTo("false");
+ assertThat(system.getString("foo", null, "bar")).isEqualTo("value");
+ }
+
+ @Test
+ public void openSystemConfigReturnsDifferentInstances() throws Exception {
+ FileBasedConfig system1 = SystemReader.getInstance().openSystemConfig(null, FS.DETECTED);
+ system1.load();
+ assertThat(system1.getString("core", null, "trustFolderStat")).isEqualTo("false");
+
+ FileBasedConfig system2 = SystemReader.getInstance().openSystemConfig(null, FS.DETECTED);
+ system2.load();
+ assertThat(system2.getString("core", null, "trustFolderStat")).isEqualTo("false");
+
+ system1.setString("core", null, "trustFolderStat", "true");
+ assertThat(system1.getString("core", null, "trustFolderStat")).isEqualTo("true");
+ assertThat(system2.getString("core", null, "trustFolderStat")).isEqualTo("false");
+ }
+}
diff --git a/javatests/com/google/gerrit/server/git/LocalDiskRepositoryManagerTest.java b/javatests/com/google/gerrit/server/git/LocalDiskRepositoryManagerTest.java
index 68afd78..4e79e33 100644
--- a/javatests/com/google/gerrit/server/git/LocalDiskRepositoryManagerTest.java
+++ b/javatests/com/google/gerrit/server/git/LocalDiskRepositoryManagerTest.java
@@ -16,11 +16,11 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.TruthJUnit.assume;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.ioutil.HostPlatform;
-import com.google.gerrit.testing.GerritBaseTests;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -36,7 +36,7 @@
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-public class LocalDiskRepositoryManagerTest extends GerritBaseTests {
+public class LocalDiskRepositoryManagerTest {
@Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
private Config cfg;
@@ -52,9 +52,10 @@
repoManager = new LocalDiskRepositoryManager(site, cfg);
}
- @Test(expected = IllegalStateException.class)
+ @Test
public void testThatNullBasePathThrowsAnException() {
- new LocalDiskRepositoryManager(site, new Config());
+ assertThrows(
+ IllegalStateException.class, () -> new LocalDiskRepositoryManager(site, new Config()));
}
@Test
@@ -69,107 +70,144 @@
assertThat(repoManager.list()).containsExactly(projectA);
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationWithEmptyName() throws Exception {
- repoManager.createRepository(Project.nameKey(""));
+ assertThrows(
+ RepositoryNotFoundException.class, () -> repoManager.createRepository(Project.nameKey("")));
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationWithTrailingSlash() throws Exception {
- repoManager.createRepository(Project.nameKey("projectA/"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.createRepository(Project.nameKey("projectA/")));
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationWithBackSlash() throws Exception {
- repoManager.createRepository(Project.nameKey("a\\projectA"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.createRepository(Project.nameKey("a\\projectA")));
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationAbsolutePath() throws Exception {
- repoManager.createRepository(Project.nameKey("/projectA"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.createRepository(Project.nameKey("/projectA")));
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationStartingWithDotDot() throws Exception {
- repoManager.createRepository(Project.nameKey("../projectA"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.createRepository(Project.nameKey("../projectA")));
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationContainsDotDot() throws Exception {
- repoManager.createRepository(Project.nameKey("a/../projectA"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.createRepository(Project.nameKey("a/../projectA")));
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationDotPathSegment() throws Exception {
- repoManager.createRepository(Project.nameKey("a/./projectA"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.createRepository(Project.nameKey("a/./projectA")));
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationWithTwoSlashes() throws Exception {
- repoManager.createRepository(Project.nameKey("a//projectA"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.createRepository(Project.nameKey("a//projectA")));
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationWithPathSegmentEndingByDotGit() throws Exception {
- repoManager.createRepository(Project.nameKey("a/b.git/projectA"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.createRepository(Project.nameKey("a/b.git/projectA")));
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationWithQuestionMark() throws Exception {
- repoManager.createRepository(Project.nameKey("project?A"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.createRepository(Project.nameKey("project?A")));
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationWithPercentageSign() throws Exception {
- repoManager.createRepository(Project.nameKey("project%A"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.createRepository(Project.nameKey("project%A")));
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationWithWidlcard() throws Exception {
- repoManager.createRepository(Project.nameKey("project*A"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.createRepository(Project.nameKey("project*A")));
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationWithColon() throws Exception {
- repoManager.createRepository(Project.nameKey("project:A"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.createRepository(Project.nameKey("project:A")));
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationWithLessThatSign() throws Exception {
- repoManager.createRepository(Project.nameKey("project<A"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.createRepository(Project.nameKey("project<A")));
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationWithGreaterThatSign() throws Exception {
- repoManager.createRepository(Project.nameKey("project>A"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.createRepository(Project.nameKey("project>A")));
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationWithPipe() throws Exception {
- repoManager.createRepository(Project.nameKey("project|A"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.createRepository(Project.nameKey("project|A")));
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationWithDollarSign() throws Exception {
- repoManager.createRepository(Project.nameKey("project$A"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.createRepository(Project.nameKey("project$A")));
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testProjectCreationWithCarriageReturn() throws Exception {
- repoManager.createRepository(Project.nameKey("project\\rA"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.createRepository(Project.nameKey("project\\rA")));
}
- @Test(expected = IllegalStateException.class)
+ @Test
public void testProjectRecreation() throws Exception {
repoManager.createRepository(Project.nameKey("a"));
- repoManager.createRepository(Project.nameKey("a"));
+ assertThrows(
+ IllegalStateException.class, () -> repoManager.createRepository(Project.nameKey("a")));
}
- @Test(expected = IllegalStateException.class)
+ @Test
public void testProjectRecreationAfterRestart() throws Exception {
repoManager.createRepository(Project.nameKey("a"));
LocalDiskRepositoryManager newRepoManager = new LocalDiskRepositoryManager(site, cfg);
- newRepoManager.createRepository(Project.nameKey("a"));
+ assertThrows(
+ IllegalStateException.class, () -> newRepoManager.createRepository(Project.nameKey("a")));
}
@Test
@@ -182,30 +220,36 @@
assertThat(repoManager.list()).containsExactly(projectA);
}
- @Test(expected = RepositoryCaseMismatchException.class)
+ @Test
public void testNameCaseMismatch() throws Exception {
assume().that(HostPlatform.isWin32() || HostPlatform.isMac()).isTrue();
repoManager.createRepository(Project.nameKey("a"));
- repoManager.createRepository(Project.nameKey("A"));
+ assertThrows(
+ RepositoryCaseMismatchException.class,
+ () -> repoManager.createRepository(Project.nameKey("A")));
}
- @Test(expected = RepositoryCaseMismatchException.class)
+ @Test
public void testNameCaseMismatchWithSymlink() throws Exception {
assume().that(HostPlatform.isWin32() || HostPlatform.isMac()).isTrue();
Project.NameKey name = Project.nameKey("a");
repoManager.createRepository(name);
createSymLink(name, "b.git");
- repoManager.createRepository(Project.nameKey("B"));
+ assertThrows(
+ RepositoryCaseMismatchException.class,
+ () -> repoManager.createRepository(Project.nameKey("B")));
}
- @Test(expected = RepositoryCaseMismatchException.class)
+ @Test
public void testNameCaseMismatchAfterRestart() throws Exception {
assume().that(HostPlatform.isWin32() || HostPlatform.isMac()).isTrue();
Project.NameKey name = Project.nameKey("a");
repoManager.createRepository(name);
LocalDiskRepositoryManager newRepoManager = new LocalDiskRepositoryManager(site, cfg);
- newRepoManager.createRepository(Project.nameKey("A"));
+ assertThrows(
+ RepositoryCaseMismatchException.class,
+ () -> newRepoManager.createRepository(Project.nameKey("A")));
}
private void createSymLink(Project.NameKey project, String link) throws IOException {
@@ -215,9 +259,11 @@
Files.createSymbolicLink(symlink, projectDir);
}
- @Test(expected = RepositoryNotFoundException.class)
+ @Test
public void testOpenRepositoryInvalidName() throws Exception {
- repoManager.openRepository(Project.nameKey("project%?|<>A"));
+ assertThrows(
+ RepositoryNotFoundException.class,
+ () -> repoManager.openRepository(Project.nameKey("project%?|<>A")));
}
@Test
diff --git a/javatests/com/google/gerrit/server/git/MultiBaseLocalDiskRepositoryManagerTest.java b/javatests/com/google/gerrit/server/git/MultiBaseLocalDiskRepositoryManagerTest.java
index 550e379..491594b 100644
--- a/javatests/com/google/gerrit/server/git/MultiBaseLocalDiskRepositoryManagerTest.java
+++ b/javatests/com/google/gerrit/server/git/MultiBaseLocalDiskRepositoryManagerTest.java
@@ -15,6 +15,7 @@
package com.google.gerrit.server.git;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
@@ -24,7 +25,6 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.RepositoryConfig;
import com.google.gerrit.server.config.SitePaths;
-import com.google.gerrit.testing.GerritBaseTests;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -41,7 +41,7 @@
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-public class MultiBaseLocalDiskRepositoryManagerTest extends GerritBaseTests {
+public class MultiBaseLocalDiskRepositoryManagerTest {
@Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
private Config cfg;
@@ -150,11 +150,17 @@
}
}
- @Test(expected = IllegalStateException.class)
+ @Test
public void testRelativeAlternateLocation() {
- configMock = createNiceMock(RepositoryConfig.class);
- expect(configMock.getAllBasePaths()).andReturn(ImmutableList.of(Paths.get("repos"))).anyTimes();
- replay(configMock);
- repoManager = new MultiBaseLocalDiskRepositoryManager(site, cfg, configMock);
+ assertThrows(
+ IllegalStateException.class,
+ () -> {
+ configMock = createNiceMock(RepositoryConfig.class);
+ expect(configMock.getAllBasePaths())
+ .andReturn(ImmutableList.of(Paths.get("repos")))
+ .anyTimes();
+ replay(configMock);
+ repoManager = new MultiBaseLocalDiskRepositoryManager(site, cfg, configMock);
+ });
}
}
diff --git a/javatests/com/google/gerrit/server/git/TagSetHolderTest.java b/javatests/com/google/gerrit/server/git/TagSetHolderTest.java
index d3ddef0..e3ab8d0 100644
--- a/javatests/com/google/gerrit/server/git/TagSetHolderTest.java
+++ b/javatests/com/google/gerrit/server/git/TagSetHolderTest.java
@@ -21,10 +21,9 @@
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.cache.proto.Cache.TagSetHolderProto;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class TagSetHolderTest extends GerritBaseTests {
+public class TagSetHolderTest {
@Test
public void serializerWithTagSet() throws Exception {
TagSetHolder holder = new TagSetHolder(Project.nameKey("project"));
diff --git a/javatests/com/google/gerrit/server/git/TagSetTest.java b/javatests/com/google/gerrit/server/git/TagSetTest.java
index c941e55..7d90d8c 100644
--- a/javatests/com/google/gerrit/server/git/TagSetTest.java
+++ b/javatests/com/google/gerrit/server/git/TagSetTest.java
@@ -30,7 +30,6 @@
import com.google.gerrit.server.cache.proto.Cache.TagSetHolderProto.TagSetProto.TagProto;
import com.google.gerrit.server.git.TagSet.CachedRef;
import com.google.gerrit.server.git.TagSet.Tag;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.inject.TypeLiteral;
import java.lang.reflect.Type;
import java.util.Arrays;
@@ -43,7 +42,7 @@
import org.eclipse.jgit.lib.ObjectIdOwnerMap;
import org.junit.Test;
-public class TagSetTest extends GerritBaseTests {
+public class TagSetTest {
@Test
public void roundTripToProto() {
HashMap<String, CachedRef> refs = new HashMap<>();
diff --git a/javatests/com/google/gerrit/server/git/meta/VersionedMetaDataTest.java b/javatests/com/google/gerrit/server/git/meta/VersionedMetaDataTest.java
index 3d41051..e14b526 100644
--- a/javatests/com/google/gerrit/server/git/meta/VersionedMetaDataTest.java
+++ b/javatests/com/google/gerrit/server/git/meta/VersionedMetaDataTest.java
@@ -27,7 +27,6 @@
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.meta.VersionedMetaData.BatchMetaDataUpdate;
import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.TestTimeUtil;
import java.io.IOException;
import java.util.Arrays;
@@ -51,7 +50,7 @@
import org.junit.Before;
import org.junit.Test;
-public class VersionedMetaDataTest extends GerritBaseTests {
+public class VersionedMetaDataTest {
// If you're considering fleshing out this test and making it more comprehensive, please consider
// instead coming up with a replacement interface for
// VersionedMetaData/BatchMetaDataUpdate/MetaDataUpdate that is easier to use correctly.
diff --git a/javatests/com/google/gerrit/server/group/db/AbstractGroupTest.java b/javatests/com/google/gerrit/server/group/db/AbstractGroupTest.java
index 2bb22ed..2acc7dcf 100644
--- a/javatests/com/google/gerrit/server/group/db/AbstractGroupTest.java
+++ b/javatests/com/google/gerrit/server/group/db/AbstractGroupTest.java
@@ -28,7 +28,6 @@
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.InMemoryRepositoryManager;
import java.io.IOException;
import java.sql.Timestamp;
@@ -44,7 +43,7 @@
import org.junit.Ignore;
@Ignore
-public class AbstractGroupTest extends GerritBaseTests {
+public class AbstractGroupTest {
protected static final TimeZone TZ = TimeZone.getTimeZone("America/Los_Angeles");
protected static final String SERVER_ID = "server-id";
protected static final String SERVER_NAME = "Gerrit Server";
diff --git a/javatests/com/google/gerrit/server/group/db/AuditLogReaderTest.java b/javatests/com/google/gerrit/server/group/db/AuditLogReaderTest.java
index 34a25bd..060079f 100644
--- a/javatests/com/google/gerrit/server/group/db/AuditLogReaderTest.java
+++ b/javatests/com/google/gerrit/server/group/db/AuditLogReaderTest.java
@@ -20,7 +20,7 @@
import com.google.common.collect.Sets;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.client.AccountGroupByIdAud;
+import com.google.gerrit.reviewdb.client.AccountGroupByIdAudit;
import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
import com.google.gerrit.server.account.GroupUUID;
import com.google.gerrit.server.group.InternalGroup;
@@ -78,7 +78,7 @@
// User removes account 100002 from the group.
removeMembers(uuid, ImmutableSet.of(id));
- expAudit2.removed(userId, getTipTimestamp(uuid));
+ expAudit2 = expAudit2.toBuilder().removed(userId, getTipTimestamp(uuid)).build();
assertThat(auditLogReader.getMembersAudit(allUsersRepo, uuid))
.containsExactly(expAudit1, expAudit2)
.inOrder();
@@ -118,13 +118,13 @@
addSubgroups(uuid, ImmutableSet.of(subgroupUuid));
- AccountGroupByIdAud expAudit =
+ AccountGroupByIdAudit expAudit =
createExpGroupAudit(group.getId(), subgroupUuid, userId, getTipTimestamp(uuid));
assertThat(auditLogReader.getSubgroupsAudit(allUsersRepo, uuid)).containsExactly(expAudit);
removeSubgroups(uuid, ImmutableSet.of(subgroupUuid));
- expAudit.removed(userId, getTipTimestamp(uuid));
+ expAudit = expAudit.toBuilder().removed(userId, getTipTimestamp(uuid)).build();
assertThat(auditLogReader.getSubgroupsAudit(allUsersRepo, uuid)).containsExactly(expAudit);
}
@@ -140,9 +140,9 @@
addSubgroups(uuid, ImmutableSet.of(subgroupUuid1, subgroupUuid2));
- AccountGroupByIdAud expAudit1 =
+ AccountGroupByIdAudit expAudit1 =
createExpGroupAudit(group.getId(), subgroupUuid1, userId, getTipTimestamp(uuid));
- AccountGroupByIdAud expAudit2 =
+ AccountGroupByIdAudit expAudit2 =
createExpGroupAudit(group.getId(), subgroupUuid2, userId, getTipTimestamp(uuid));
assertThat(auditLogReader.getSubgroupsAudit(allUsersRepo, uuid))
.containsExactly(expAudit1, expAudit2)
@@ -180,23 +180,23 @@
// Add one subgroup.
addSubgroups(uuid, ImmutableSet.of(subgroupUuid1));
- AccountGroupByIdAud expGroupAudit1 =
+ AccountGroupByIdAudit expGroupAudit1 =
createExpGroupAudit(group.getId(), subgroupUuid1, userId, getTipTimestamp(uuid));
assertThat(auditLogReader.getSubgroupsAudit(allUsersRepo, uuid))
.containsExactly(expGroupAudit1);
// Remove one account.
removeMembers(uuid, ImmutableSet.of(id2));
- expMemberAudit2.removed(userId, getTipTimestamp(uuid));
+ expMemberAudit2 = expMemberAudit2.toBuilder().removed(userId, getTipTimestamp(uuid)).build();
assertThat(auditLogReader.getMembersAudit(allUsersRepo, uuid))
.containsExactly(expMemberAudit, expMemberAudit1, expMemberAudit2)
.inOrder();
// Add two subgroups.
addSubgroups(uuid, ImmutableSet.of(subgroupUuid2, subgroupUuid3));
- AccountGroupByIdAud expGroupAudit2 =
+ AccountGroupByIdAudit expGroupAudit2 =
createExpGroupAudit(group.getId(), subgroupUuid2, userId, getTipTimestamp(uuid));
- AccountGroupByIdAud expGroupAudit3 =
+ AccountGroupByIdAudit expGroupAudit3 =
createExpGroupAudit(group.getId(), subgroupUuid3, userId, getTipTimestamp(uuid));
assertThat(auditLogReader.getSubgroupsAudit(allUsersRepo, uuid))
.containsExactly(expGroupAudit1, expGroupAudit2, expGroupAudit3)
@@ -215,15 +215,15 @@
// Remove two subgroups.
removeSubgroups(uuid, ImmutableSet.of(subgroupUuid1, subgroupUuid3));
- expGroupAudit1.removed(userId, getTipTimestamp(uuid));
- expGroupAudit3.removed(userId, getTipTimestamp(uuid));
+ expGroupAudit1 = expGroupAudit1.toBuilder().removed(userId, getTipTimestamp(uuid)).build();
+ expGroupAudit3 = expGroupAudit3.toBuilder().removed(userId, getTipTimestamp(uuid)).build();
assertThat(auditLogReader.getSubgroupsAudit(allUsersRepo, uuid))
.containsExactly(expGroupAudit1, expGroupAudit2, expGroupAudit3)
.inOrder();
// Add back one removed subgroup.
addSubgroups(uuid, ImmutableSet.of(subgroupUuid1));
- AccountGroupByIdAud expGroupAudit4 =
+ AccountGroupByIdAudit expGroupAudit4 =
createExpGroupAudit(group.getId(), subgroupUuid1, userId, getTipTimestamp(uuid));
assertThat(auditLogReader.getSubgroupsAudit(allUsersRepo, uuid))
.containsExactly(expGroupAudit1, expGroupAudit2, expGroupAudit3, expGroupAudit4)
@@ -303,11 +303,21 @@
private static AccountGroupMemberAudit createExpMemberAudit(
AccountGroup.Id groupId, Account.Id id, Account.Id addedBy, Timestamp addedOn) {
- return new AccountGroupMemberAudit(AccountGroupMemberAudit.key(id, groupId, addedOn), addedBy);
+ return AccountGroupMemberAudit.builder()
+ .groupId(groupId)
+ .memberId(id)
+ .addedOn(addedOn)
+ .addedBy(addedBy)
+ .build();
}
- private static AccountGroupByIdAud createExpGroupAudit(
+ private static AccountGroupByIdAudit createExpGroupAudit(
AccountGroup.Id groupId, AccountGroup.UUID uuid, Account.Id addedBy, Timestamp addedOn) {
- return new AccountGroupByIdAud(AccountGroupByIdAud.key(groupId, uuid, addedOn), addedBy);
+ return AccountGroupByIdAudit.builder()
+ .groupId(groupId)
+ .includeUuid(uuid)
+ .addedOn(addedOn)
+ .addedBy(addedBy)
+ .build();
}
}
diff --git a/javatests/com/google/gerrit/server/group/db/GroupConfigTest.java b/javatests/com/google/gerrit/server/group/db/GroupConfigTest.java
index 7be7f1c..1d75229 100644
--- a/javatests/com/google/gerrit/server/group/db/GroupConfigTest.java
+++ b/javatests/com/google/gerrit/server/group/db/GroupConfigTest.java
@@ -17,8 +17,10 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.gerrit.server.group.testing.InternalGroupSubject.internalGroups;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static com.google.gerrit.truth.OptionalSubject.assertThat;
import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.MatcherAssert.assertThat;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
@@ -33,7 +35,6 @@
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.group.testing.InternalGroupSubject;
import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.truth.OptionalSubject;
import java.io.IOException;
import java.sql.Timestamp;
@@ -55,7 +56,7 @@
import org.junit.Before;
import org.junit.Test;
-public class GroupConfigTest extends GerritBaseTests {
+public class GroupConfigTest {
private Project.NameKey projectName;
private Repository repository;
private TestRepository<?> testRepository;
@@ -113,9 +114,9 @@
GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation);
try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) {
- exception.expectCause(instanceOf(ConfigInvalidException.class));
- exception.expectMessage("Name of the group " + groupUuid);
- groupConfig.commit(metaDataUpdate);
+ Throwable thrown = assertThrows(Throwable.class, () -> groupConfig.commit(metaDataUpdate));
+ assertThat(thrown.getCause(), instanceOf(ConfigInvalidException.class));
+ assertThat(thrown).hasMessageThat().contains("Name of the group " + groupUuid);
}
}
@@ -135,9 +136,9 @@
GroupConfig groupConfig = GroupConfig.createForNewGroup(projectName, repository, groupCreation);
try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) {
- exception.expectCause(instanceOf(ConfigInvalidException.class));
- exception.expectMessage("ID of the group " + groupUuid);
- groupConfig.commit(metaDataUpdate);
+ Throwable thrown = assertThrows(Throwable.class, () -> groupConfig.commit(metaDataUpdate));
+ assertThat(thrown.getCause(), instanceOf(ConfigInvalidException.class));
+ assertThat(thrown).hasMessageThat().contains("ID of the group " + groupUuid);
}
}
@@ -214,9 +215,9 @@
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) {
- exception.expectCause(instanceOf(ConfigInvalidException.class));
- exception.expectMessage("Owner UUID of the group " + groupUuid);
- groupConfig.commit(metaDataUpdate);
+ Throwable thrown = assertThrows(Throwable.class, () -> groupConfig.commit(metaDataUpdate));
+ assertThat(thrown.getCause(), instanceOf(ConfigInvalidException.class));
+ assertThat(thrown).hasMessageThat().contains("Owner UUID of the group " + groupUuid);
}
}
@@ -325,9 +326,11 @@
public void idInConfigMustBeDefined() throws Exception {
populateGroupConfig(groupUuid, "[group]\n\tname = users\n\townerGroupUuid = owners\n");
- exception.expect(ConfigInvalidException.class);
- exception.expectMessage("ID of the group " + groupUuid);
- GroupConfig.loadForGroup(projectName, repository, groupUuid);
+ ConfigInvalidException thrown =
+ assertThrows(
+ ConfigInvalidException.class,
+ () -> GroupConfig.loadForGroup(projectName, repository, groupUuid));
+ assertThat(thrown).hasMessageThat().contains("ID of the group " + groupUuid);
}
@Test
@@ -335,9 +338,11 @@
populateGroupConfig(
groupUuid, "[group]\n\tname = users\n\tid = -5\n\townerGroupUuid = owners\n");
- exception.expect(ConfigInvalidException.class);
- exception.expectMessage("ID of the group " + groupUuid);
- GroupConfig.loadForGroup(projectName, repository, groupUuid);
+ ConfigInvalidException thrown =
+ assertThrows(
+ ConfigInvalidException.class,
+ () -> GroupConfig.loadForGroup(projectName, repository, groupUuid));
+ assertThat(thrown).hasMessageThat().contains("ID of the group " + groupUuid);
}
@Test
@@ -361,9 +366,11 @@
public void ownerGroupUuidInConfigMustBeDefined() throws Exception {
populateGroupConfig(groupUuid, "[group]\n\tname = users\n\tid = 42\n");
- exception.expect(ConfigInvalidException.class);
- exception.expectMessage("Owner UUID of the group " + groupUuid);
- GroupConfig.loadForGroup(projectName, repository, groupUuid);
+ ConfigInvalidException thrown =
+ assertThrows(
+ ConfigInvalidException.class,
+ () -> GroupConfig.loadForGroup(projectName, repository, groupUuid));
+ assertThat(thrown).hasMessageThat().contains("Owner UUID of the group " + groupUuid);
}
@Test
@@ -415,9 +422,9 @@
populateGroupConfig(groupUuid, "[group]\n\tname=users\n\tid = 42\n\townerGroupUuid = owners\n");
populateMembersFile(groupUuid, "One");
- exception.expect(ConfigInvalidException.class);
- exception.expectMessage("Invalid file members");
- loadGroup(groupUuid);
+ ConfigInvalidException thrown =
+ assertThrows(ConfigInvalidException.class, () -> loadGroup(groupUuid));
+ assertThat(thrown).hasMessageThat().contains("Invalid file members");
}
@Test
@@ -425,9 +432,9 @@
populateGroupConfig(groupUuid, "[group]\n\tname=users\n\tid = 42\n\townerGroupUuid = owners\n");
populateMembersFile(groupUuid, "1\t2");
- exception.expect(ConfigInvalidException.class);
- exception.expectMessage("Invalid file members");
- loadGroup(groupUuid);
+ ConfigInvalidException thrown =
+ assertThrows(ConfigInvalidException.class, () -> loadGroup(groupUuid));
+ assertThat(thrown).hasMessageThat().contains("Invalid file members");
}
@Test
@@ -517,9 +524,9 @@
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) {
- exception.expectCause(instanceOf(ConfigInvalidException.class));
- exception.expectMessage("Name of the group " + groupUuid);
- groupConfig.commit(metaDataUpdate);
+ Throwable thrown = assertThrows(Throwable.class, () -> groupConfig.commit(metaDataUpdate));
+ assertThat(thrown.getCause(), instanceOf(ConfigInvalidException.class));
+ assertThat(thrown).hasMessageThat().contains("Name of the group " + groupUuid);
}
}
@@ -584,9 +591,9 @@
groupConfig.setGroupUpdate(groupUpdate, auditLogFormatter);
try (MetaDataUpdate metaDataUpdate = createMetaDataUpdate()) {
- exception.expectCause(instanceOf(ConfigInvalidException.class));
- exception.expectMessage("Owner UUID of the group " + groupUuid);
- groupConfig.commit(metaDataUpdate);
+ Throwable thrown = assertThrows(Throwable.class, () -> groupConfig.commit(metaDataUpdate));
+ assertThat(thrown.getCause(), instanceOf(ConfigInvalidException.class));
+ assertThat(thrown).hasMessageThat().contains("Owner UUID of the group " + groupUuid);
}
}
diff --git a/javatests/com/google/gerrit/server/group/db/GroupNameNotesTest.java b/javatests/com/google/gerrit/server/group/db/GroupNameNotesTest.java
index 085e2ad..9f0b340 100644
--- a/javatests/com/google/gerrit/server/group/db/GroupNameNotesTest.java
+++ b/javatests/com/google/gerrit/server/group/db/GroupNameNotesTest.java
@@ -15,11 +15,11 @@
package com.google.gerrit.server.group.db;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
import static com.google.gerrit.common.data.testing.GroupReferenceSubject.groupReferences;
import static com.google.gerrit.extensions.common.testing.CommitInfoSubject.assertThat;
import static com.google.gerrit.extensions.common.testing.CommitInfoSubject.commits;
import static com.google.gerrit.reviewdb.client.RefNames.REFS_GROUPNAMES;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static com.google.gerrit.truth.OptionalSubject.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
@@ -39,7 +39,6 @@
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.GitTestUtil;
import com.google.gerrit.testing.TestTimeUtil;
import com.google.gerrit.truth.ListSubject;
@@ -69,7 +68,7 @@
import org.junit.Before;
import org.junit.Test;
-public class GroupNameNotesTest extends GerritBaseTests {
+public class GroupNameNotesTest {
private static final String SERVER_NAME = "Gerrit Server";
private static final String SERVER_EMAIL = "noreply@gerritcodereview.com";
private static final TimeZone TZ = TimeZone.getTimeZone("America/Los_Angeles");
@@ -105,14 +104,16 @@
@Test
public void uuidOfNewGroupMustNotBeNull() throws Exception {
- exception.expect(NullPointerException.class);
- GroupNameNotes.forNewGroup(allUsersName, repo, null, groupName);
+ assertThrows(
+ NullPointerException.class,
+ () -> GroupNameNotes.forNewGroup(allUsersName, repo, null, groupName));
}
@Test
public void nameOfNewGroupMustNotBeNull() throws Exception {
- exception.expect(NullPointerException.class);
- GroupNameNotes.forNewGroup(allUsersName, repo, groupUuid, null);
+ assertThrows(
+ NullPointerException.class,
+ () -> GroupNameNotes.forNewGroup(allUsersName, repo, groupUuid, null));
}
@Test
@@ -129,9 +130,11 @@
createGroup(groupUuid, groupName);
AccountGroup.UUID anotherGroupUuid = AccountGroup.uuid("AnotherGroup");
- exception.expect(DuplicateKeyException.class);
- exception.expectMessage(groupName.get());
- GroupNameNotes.forNewGroup(allUsersName, repo, anotherGroupUuid, groupName);
+ DuplicateKeyException thrown =
+ assertThrows(
+ DuplicateKeyException.class,
+ () -> GroupNameNotes.forNewGroup(allUsersName, repo, anotherGroupUuid, groupName));
+ assertThat(thrown).hasMessageThat().contains(groupName.get());
}
@Test
@@ -173,9 +176,9 @@
@Test
public void groupCannotBeRenamedToNull() throws Exception {
createGroup(groupUuid, groupName);
-
- exception.expect(NullPointerException.class);
- GroupNameNotes.forRename(allUsersName, repo, groupUuid, groupName, null);
+ assertThrows(
+ NullPointerException.class,
+ () -> GroupNameNotes.forRename(allUsersName, repo, groupUuid, groupName, null));
}
@Test
@@ -183,8 +186,9 @@
createGroup(groupUuid, groupName);
AccountGroup.NameKey anotherName = AccountGroup.nameKey("admins");
- exception.expect(NullPointerException.class);
- GroupNameNotes.forRename(allUsersName, repo, groupUuid, null, anotherName);
+ assertThrows(
+ NullPointerException.class,
+ () -> GroupNameNotes.forRename(allUsersName, repo, groupUuid, null, anotherName));
}
@Test
@@ -193,9 +197,13 @@
AccountGroup.NameKey anotherOldName = AccountGroup.nameKey("contributors");
AccountGroup.NameKey anotherName = AccountGroup.nameKey("admins");
- exception.expect(ConfigInvalidException.class);
- exception.expectMessage(anotherOldName.get());
- GroupNameNotes.forRename(allUsersName, repo, groupUuid, anotherOldName, anotherName);
+ ConfigInvalidException thrown =
+ assertThrows(
+ ConfigInvalidException.class,
+ () ->
+ GroupNameNotes.forRename(
+ allUsersName, repo, groupUuid, anotherOldName, anotherName));
+ assertThat(thrown).hasMessageThat().contains(anotherOldName.get());
}
@Test
@@ -205,9 +213,13 @@
AccountGroup.NameKey anotherGroupName = AccountGroup.nameKey("admins");
createGroup(anotherGroupUuid, anotherGroupName);
- exception.expect(DuplicateKeyException.class);
- exception.expectMessage(anotherGroupName.get());
- GroupNameNotes.forRename(allUsersName, repo, groupUuid, groupName, anotherGroupName);
+ DuplicateKeyException thrown =
+ assertThrows(
+ DuplicateKeyException.class,
+ () ->
+ GroupNameNotes.forRename(
+ allUsersName, repo, groupUuid, groupName, anotherGroupName));
+ assertThat(thrown).hasMessageThat().contains(anotherGroupName.get());
}
@Test
@@ -215,8 +227,9 @@
createGroup(groupUuid, groupName);
AccountGroup.NameKey anotherName = AccountGroup.nameKey("admins");
- exception.expect(NullPointerException.class);
- GroupNameNotes.forRename(allUsersName, repo, null, groupName, anotherName);
+ assertThrows(
+ NullPointerException.class,
+ () -> GroupNameNotes.forRename(allUsersName, repo, null, groupName, anotherName));
}
@Test
@@ -225,9 +238,13 @@
AccountGroup.UUID anotherGroupUuid = AccountGroup.uuid("admins-ABC");
AccountGroup.NameKey anotherName = AccountGroup.nameKey("admins");
- exception.expect(ConfigInvalidException.class);
- exception.expectMessage(groupUuid.get());
- GroupNameNotes.forRename(allUsersName, repo, anotherGroupUuid, groupName, anotherName);
+ ConfigInvalidException thrown =
+ assertThrows(
+ ConfigInvalidException.class,
+ () ->
+ GroupNameNotes.forRename(
+ allUsersName, repo, anotherGroupUuid, groupName, anotherName));
+ assertThat(thrown).hasMessageThat().contains(groupUuid.get());
}
@Test
@@ -424,35 +441,36 @@
GroupReference g1 = newGroup("a");
GroupReference g2 = newGroup("b");
- TestRepository<?> tr = new TestRepository<>(repo);
- ObjectId k1 = getNoteKey(g1);
- ObjectId k2 = getNoteKey(g2);
- ObjectId k3 = GroupNameNotes.getNoteKey(AccountGroup.nameKey("c"));
- PersonIdent ident = newPersonIdent();
- ObjectId origCommitId =
- tr.branch(REFS_GROUPNAMES)
- .commit()
- .message("Prepopulate group name")
- .author(ident)
- .committer(ident)
- .add(k1.name(), "[group]\n\tuuid = a-1\n\tname = a\nanotherKey = foo\n")
- .add(k2.name(), "[group]\n\tuuid = a-1\n\tname = b\n")
- .add(k3.name(), "[group]\n\tuuid = c-3\n\tname = c\n")
- .create()
- .copy();
+ try (TestRepository<Repository> tr = new TestRepository<>(repo)) {
+ ObjectId k1 = getNoteKey(g1);
+ ObjectId k2 = getNoteKey(g2);
+ ObjectId k3 = GroupNameNotes.getNoteKey(AccountGroup.nameKey("c"));
+ PersonIdent ident = newPersonIdent();
+ ObjectId origCommitId =
+ tr.branch(REFS_GROUPNAMES)
+ .commit()
+ .message("Prepopulate group name")
+ .author(ident)
+ .committer(ident)
+ .add(k1.name(), "[group]\n\tuuid = a-1\n\tname = a\nanotherKey = foo\n")
+ .add(k2.name(), "[group]\n\tuuid = a-1\n\tname = b\n")
+ .add(k3.name(), "[group]\n\tuuid = c-3\n\tname = c\n")
+ .create()
+ .copy();
- ident = newPersonIdent();
- updateAllGroups(ident, g1, g2);
+ ident = newPersonIdent();
+ updateAllGroups(ident, g1, g2);
- assertThat(GroupNameNotes.loadAllGroups(repo)).containsExactly(g1, g2);
+ assertThat(GroupNameNotes.loadAllGroups(repo)).containsExactly(g1, g2);
- ImmutableList<CommitInfo> log = log();
- assertThat(log).hasSize(2);
- assertThat(log.get(0)).commit().isEqualTo(origCommitId.name());
+ ImmutableList<CommitInfo> log = log();
+ assertThat(log).hasSize(2);
+ assertThat(log.get(0)).commit().isEqualTo(origCommitId.name());
- assertThat(log.get(1)).message().isEqualTo("Store 2 group names");
- assertThat(log.get(1)).author().matches(ident);
- assertThat(log.get(1)).committer().matches(ident);
+ assertThat(log.get(1)).message().isEqualTo("Store 2 group names");
+ assertThat(log.get(1)).author().matches(ident);
+ assertThat(log.get(1)).committer().matches(ident);
+ }
// Old note content was overwritten.
assertThat(readNameNote(g1)).isEqualTo("[group]\n\tuuid = a-1\n\tname = a\n");
@@ -560,12 +578,13 @@
try (ObjectInserter inserter = repo.newObjectInserter()) {
BatchRefUpdate bru = repo.getRefDatabase().newBatchUpdate();
PersonIdent ident = newPersonIdent();
- try {
- GroupNameNotes.updateAllGroups(repo, inserter, bru, Arrays.asList(groupRefs), ident);
- assert_().fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- assertThat(e).hasMessageThat().isEqualTo(GroupNameNotes.UNIQUE_REF_ERROR);
- }
+ IllegalArgumentException thrown =
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ GroupNameNotes.updateAllGroups(
+ repo, inserter, bru, Arrays.asList(groupRefs), ident));
+ assertThat(thrown).hasMessageThat().isEqualTo(GroupNameNotes.UNIQUE_REF_ERROR);
}
}
diff --git a/javatests/com/google/gerrit/server/index/account/AccountFieldTest.java b/javatests/com/google/gerrit/server/index/account/AccountFieldTest.java
index 868deeb..5573be7 100644
--- a/javatests/com/google/gerrit/server/index/account/AccountFieldTest.java
+++ b/javatests/com/google/gerrit/server/index/account/AccountFieldTest.java
@@ -28,12 +28,11 @@
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.AllUsersNameProvider;
import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.List;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
-public class AccountFieldTest extends GerritBaseTests {
+public class AccountFieldTest {
@Test
public void refStateFieldValues() throws Exception {
AllUsersName allUsersName = new AllUsersName(AllUsersNameProvider.DEFAULT);
diff --git a/javatests/com/google/gerrit/server/index/change/ChangeFieldTest.java b/javatests/com/google/gerrit/server/index/change/ChangeFieldTest.java
index 98536cf..4defea5 100644
--- a/javatests/com/google/gerrit/server/index/change/ChangeFieldTest.java
+++ b/javatests/com/google/gerrit/server/index/change/ChangeFieldTest.java
@@ -29,7 +29,6 @@
import com.google.gerrit.server.ReviewerSet;
import com.google.gerrit.server.notedb.ReviewerStateInternal;
import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.TestTimeUtil;
import java.sql.Timestamp;
import java.util.Collections;
@@ -39,7 +38,7 @@
import org.junit.Before;
import org.junit.Test;
-public class ChangeFieldTest extends GerritBaseTests {
+public class ChangeFieldTest {
@Before
public void setUp() {
TestTimeUtil.resetWithClockStep(1, TimeUnit.SECONDS);
diff --git a/javatests/com/google/gerrit/server/index/change/ChangeIndexRewriterTest.java b/javatests/com/google/gerrit/server/index/change/ChangeIndexRewriterTest.java
index fd23da3..62b1cbc 100644
--- a/javatests/com/google/gerrit/server/index/change/ChangeIndexRewriterTest.java
+++ b/javatests/com/google/gerrit/server/index/change/ChangeIndexRewriterTest.java
@@ -21,6 +21,7 @@
import static com.google.gerrit.reviewdb.client.Change.Status.MERGED;
import static com.google.gerrit.reviewdb.client.Change.Status.NEW;
import static com.google.gerrit.server.index.change.IndexedChangeQuery.convertOptions;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.junit.Assert.assertEquals;
import com.google.common.collect.ImmutableSet;
@@ -34,14 +35,13 @@
import com.google.gerrit.server.query.change.ChangeQueryBuilder;
import com.google.gerrit.server.query.change.ChangeStatusPredicate;
import com.google.gerrit.server.query.change.OrSource;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
-public class ChangeIndexRewriterTest extends GerritBaseTests {
+public class ChangeIndexRewriterTest {
private static final IndexConfig CONFIG = IndexConfig.createDefault();
private FakeChangeIndex index;
@@ -196,9 +196,8 @@
indexes.setSearchIndex(new FakeChangeIndex(FakeChangeIndex.V1));
- exception.expect(QueryParseException.class);
- exception.expectMessage("Unsupported index predicate: file:a");
- rewrite(in);
+ QueryParseException thrown = assertThrows(QueryParseException.class, () -> rewrite(in));
+ assertThat(thrown).hasMessageThat().contains("Unsupported index predicate: file:a");
}
@Test
@@ -207,9 +206,9 @@
Predicate<ChangeData> in = parse(q);
assertEquals(query(in), rewrite(in));
- exception.expect(QueryParseException.class);
- exception.expectMessage("too many terms in query");
- rewrite(parse(q + " OR file:d"));
+ QueryParseException thrown =
+ assertThrows(QueryParseException.class, () -> rewrite(parse(q + " OR file:d")));
+ assertThat(thrown).hasMessageThat().contains("too many terms in query");
}
@Test
diff --git a/javatests/com/google/gerrit/server/index/change/StalenessCheckerTest.java b/javatests/com/google/gerrit/server/index/change/StalenessCheckerTest.java
index c8f3341..44f33b2 100644
--- a/javatests/com/google/gerrit/server/index/change/StalenessCheckerTest.java
+++ b/javatests/com/google/gerrit/server/index/change/StalenessCheckerTest.java
@@ -15,8 +15,8 @@
package com.google.gerrit.server.index.change;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
import static com.google.gerrit.server.index.change.StalenessChecker.refsAreStale;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.stream.Collectors.toList;
@@ -28,7 +28,6 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.index.change.StalenessChecker.RefStatePattern;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.InMemoryRepositoryManager;
import java.util.stream.Stream;
import org.eclipse.jgit.junit.TestRepository;
@@ -37,7 +36,7 @@
import org.junit.Before;
import org.junit.Test;
-public class StalenessCheckerTest extends GerritBaseTests {
+public class StalenessCheckerTest {
private static final String SHA1 = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
private static final String SHA2 = "badc0feebadc0feebadc0feebadc0feebadc0fee";
@@ -83,12 +82,7 @@
}
private static void assertInvalidState(String state) {
- try {
- RefState.parseStates(byteArrays(state));
- assert_().fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // Expected.
- }
+ assertThrows(IllegalArgumentException.class, () -> RefState.parseStates(byteArrays(state)));
}
@Test
@@ -155,12 +149,8 @@
}
private static void assertInvalidPattern(String state) {
- try {
- StalenessChecker.parsePatterns(byteArrays(state));
- assert_().fail("expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // Expected.
- }
+ assertThrows(
+ IllegalArgumentException.class, () -> StalenessChecker.parsePatterns(byteArrays(state)));
}
@Test
diff --git a/javatests/com/google/gerrit/server/ioutil/BasicSerializationTest.java b/javatests/com/google/gerrit/server/ioutil/BasicSerializationTest.java
index c4f32c7..fae8559 100644
--- a/javatests/com/google/gerrit/server/ioutil/BasicSerializationTest.java
+++ b/javatests/com/google/gerrit/server/ioutil/BasicSerializationTest.java
@@ -23,14 +23,13 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
-import com.google.gerrit.testing.GerritBaseTests;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.junit.Test;
-public class BasicSerializationTest extends GerritBaseTests {
+public class BasicSerializationTest {
@Test
public void testReadVarInt32() throws IOException {
assertEquals(0x00000000, readVarInt32(r(b(0))));
diff --git a/javatests/com/google/gerrit/server/ioutil/ColumnFormatterTest.java b/javatests/com/google/gerrit/server/ioutil/ColumnFormatterTest.java
index 9f5e60a..fe642ba 100644
--- a/javatests/com/google/gerrit/server/ioutil/ColumnFormatterTest.java
+++ b/javatests/com/google/gerrit/server/ioutil/ColumnFormatterTest.java
@@ -14,13 +14,12 @@
package com.google.gerrit.server.ioutil;
-import com.google.gerrit.testing.GerritBaseTests;
import java.io.PrintWriter;
import java.io.StringWriter;
import org.junit.Assert;
import org.junit.Test;
-public class ColumnFormatterTest extends GerritBaseTests {
+public class ColumnFormatterTest {
/**
* Holds an in-memory {@link java.io.PrintWriter} object and allows comparisons of its contents to
* a supplied string via an assert statement.
diff --git a/javatests/com/google/gerrit/server/ioutil/HexFormatTest.java b/javatests/com/google/gerrit/server/ioutil/HexFormatTest.java
index 40fd71f..9bb6951 100644
--- a/javatests/com/google/gerrit/server/ioutil/HexFormatTest.java
+++ b/javatests/com/google/gerrit/server/ioutil/HexFormatTest.java
@@ -16,10 +16,9 @@
import static org.junit.Assert.assertEquals;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class HexFormatTest extends GerritBaseTests {
+public class HexFormatTest {
@Test
public void fromInt() {
diff --git a/javatests/com/google/gerrit/server/ioutil/RegexListSearcherTest.java b/javatests/com/google/gerrit/server/ioutil/RegexListSearcherTest.java
index 33b1c4f..048d59d 100644
--- a/javatests/com/google/gerrit/server/ioutil/RegexListSearcherTest.java
+++ b/javatests/com/google/gerrit/server/ioutil/RegexListSearcherTest.java
@@ -18,11 +18,10 @@
import static com.google.common.truth.Truth8.assertThat;
import com.google.common.collect.ImmutableList;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.List;
import org.junit.Test;
-public class RegexListSearcherTest extends GerritBaseTests {
+public class RegexListSearcherTest {
private static final ImmutableList<String> EMPTY = ImmutableList.of();
@Test
@@ -58,7 +57,7 @@
}
private void assertSearchReturns(List<?> expected, String re, List<String> inputs) {
- assertThat(inputs).isOrdered();
+ assertThat(inputs).isInOrder();
assertThat(RegexListSearcher.ofStrings(re).search(inputs))
.containsExactlyElementsIn(expected)
.inOrder();
diff --git a/javatests/com/google/gerrit/server/ioutil/StringUtilTest.java b/javatests/com/google/gerrit/server/ioutil/StringUtilTest.java
index 817b317..04f806d 100644
--- a/javatests/com/google/gerrit/server/ioutil/StringUtilTest.java
+++ b/javatests/com/google/gerrit/server/ioutil/StringUtilTest.java
@@ -16,10 +16,9 @@
import static org.junit.Assert.assertEquals;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class StringUtilTest extends GerritBaseTests {
+public class StringUtilTest {
/** Test the boundary condition that the first character of a string should be escaped. */
@Test
public void escapeFirstChar() {
diff --git a/javatests/com/google/gerrit/server/logging/LoggingContextAwareExecutorServiceTest.java b/javatests/com/google/gerrit/server/logging/LoggingContextAwareExecutorServiceTest.java
index 463decf..5117c01 100644
--- a/javatests/com/google/gerrit/server/logging/LoggingContextAwareExecutorServiceTest.java
+++ b/javatests/com/google/gerrit/server/logging/LoggingContextAwareExecutorServiceTest.java
@@ -17,7 +17,6 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.common.truth.Expect;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.concurrent.ExecutorService;
@@ -25,7 +24,7 @@
import org.junit.Rule;
import org.junit.Test;
-public class LoggingContextAwareExecutorServiceTest extends GerritBaseTests {
+public class LoggingContextAwareExecutorServiceTest {
@Rule public final Expect expect = Expect.create();
@Test
diff --git a/javatests/com/google/gerrit/server/logging/MutableTagsTest.java b/javatests/com/google/gerrit/server/logging/MutableTagsTest.java
index 113f26c..f6f3b46 100644
--- a/javatests/com/google/gerrit/server/logging/MutableTagsTest.java
+++ b/javatests/com/google/gerrit/server/logging/MutableTagsTest.java
@@ -15,19 +15,18 @@
package com.google.gerrit.server.logging;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.Map;
import java.util.SortedMap;
import java.util.SortedSet;
import org.junit.Before;
import org.junit.Test;
-public class MutableTagsTest extends GerritBaseTests {
+public class MutableTagsTest {
private MutableTags tags;
@Before
@@ -167,11 +166,7 @@
}
private void assertNullPointerException(String expectedMessage, Runnable r) {
- try {
- r.run();
- assert_().fail("expected NullPointerException");
- } catch (NullPointerException e) {
- assertThat(e.getMessage()).isEqualTo(expectedMessage);
- }
+ NullPointerException thrown = assertThrows(NullPointerException.class, () -> r.run());
+ assertThat(thrown).hasMessageThat().isEqualTo(expectedMessage);
}
}
diff --git a/javatests/com/google/gerrit/server/logging/TraceContextTest.java b/javatests/com/google/gerrit/server/logging/TraceContextTest.java
index 19b2eeb..044d237 100644
--- a/javatests/com/google/gerrit/server/logging/TraceContextTest.java
+++ b/javatests/com/google/gerrit/server/logging/TraceContextTest.java
@@ -19,14 +19,13 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.server.logging.TraceContext.TraceIdConsumer;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.Map;
import java.util.SortedMap;
import java.util.SortedSet;
import org.junit.After;
import org.junit.Test;
-public class TraceContextTest extends GerritBaseTests {
+public class TraceContextTest {
@After
public void cleanup() {
LoggingContext.getInstance().clearTags();
diff --git a/javatests/com/google/gerrit/server/mail/AutoReplyMailFilterTest.java b/javatests/com/google/gerrit/server/mail/AutoReplyMailFilterTest.java
index f8a613a..9dcb08c 100644
--- a/javatests/com/google/gerrit/server/mail/AutoReplyMailFilterTest.java
+++ b/javatests/com/google/gerrit/server/mail/AutoReplyMailFilterTest.java
@@ -18,11 +18,10 @@
import com.google.gerrit.mail.Address;
import com.google.gerrit.mail.MailMessage;
-import com.google.gerrit.testing.GerritBaseTests;
import java.time.Instant;
import org.junit.Test;
-public class AutoReplyMailFilterTest extends GerritBaseTests {
+public class AutoReplyMailFilterTest {
private AutoReplyMailFilter autoReplyMailFilter = new AutoReplyMailFilter();
diff --git a/javatests/com/google/gerrit/server/mail/send/CommentFormatterTest.java b/javatests/com/google/gerrit/server/mail/send/CommentFormatterTest.java
index 78116ed..f4fbc78 100644
--- a/javatests/com/google/gerrit/server/mail/send/CommentFormatterTest.java
+++ b/javatests/com/google/gerrit/server/mail/send/CommentFormatterTest.java
@@ -20,11 +20,10 @@
import static com.google.gerrit.server.mail.send.CommentFormatter.BlockType.PRE_FORMATTED;
import static com.google.gerrit.server.mail.send.CommentFormatter.BlockType.QUOTE;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.List;
import org.junit.Test;
-public class CommentFormatterTest extends GerritBaseTests {
+public class CommentFormatterTest {
private void assertBlock(
List<CommentFormatter.Block> list, int index, CommentFormatter.BlockType type, String text) {
CommentFormatter.Block block = list.get(index);
diff --git a/javatests/com/google/gerrit/server/mail/send/CommentSenderTest.java b/javatests/com/google/gerrit/server/mail/send/CommentSenderTest.java
index 0682bb3..78cefdf 100644
--- a/javatests/com/google/gerrit/server/mail/send/CommentSenderTest.java
+++ b/javatests/com/google/gerrit/server/mail/send/CommentSenderTest.java
@@ -16,11 +16,10 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.Collections;
import org.junit.Test;
-public class CommentSenderTest extends GerritBaseTests {
+public class CommentSenderTest {
private static class TestSender extends CommentSender {
TestSender() {
super(null, null, null, null, null);
diff --git a/javatests/com/google/gerrit/server/mail/send/FromAddressGeneratorProviderTest.java b/javatests/com/google/gerrit/server/mail/send/FromAddressGeneratorProviderTest.java
index 73c59f2..128279f 100644
--- a/javatests/com/google/gerrit/server/mail/send/FromAddressGeneratorProviderTest.java
+++ b/javatests/com/google/gerrit/server/mail/send/FromAddressGeneratorProviderTest.java
@@ -28,7 +28,6 @@
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.AllUsersNameProvider;
import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@@ -37,7 +36,7 @@
import org.junit.Before;
import org.junit.Test;
-public class FromAddressGeneratorProviderTest extends GerritBaseTests {
+public class FromAddressGeneratorProviderTest {
private Config config;
private PersonIdent ident;
private AccountCache accountCache;
diff --git a/javatests/com/google/gerrit/server/mail/send/NotificationEmailTest.java b/javatests/com/google/gerrit/server/mail/send/NotificationEmailTest.java
index 5d6fce7..b87c4a1 100644
--- a/javatests/com/google/gerrit/server/mail/send/NotificationEmailTest.java
+++ b/javatests/com/google/gerrit/server/mail/send/NotificationEmailTest.java
@@ -15,28 +15,31 @@
package com.google.gerrit.server.mail.send;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.server.mail.send.NotificationEmail.getInstanceAndProjectName;
+import static com.google.gerrit.server.mail.send.NotificationEmail.getShortProjectName;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class NotificationEmailTest extends GerritBaseTests {
-
+public class NotificationEmailTest {
@Test
- public void getInstanceAndProjectName_returnsTheRightValue() {
- String instanceAndProjectName = NotificationEmail.getInstanceAndProjectName("test", "/my/api");
- assertThat(instanceAndProjectName).isEqualTo("test/api");
+ public void instanceAndProjectName() throws Exception {
+ assertThat(getInstanceAndProjectName("test", "/my/api")).isEqualTo("test/api");
+ assertThat(getInstanceAndProjectName("test", "/api")).isEqualTo("test/api");
+ assertThat(getInstanceAndProjectName("test", "api")).isEqualTo("test/api");
}
@Test
- public void getInstanceAndProjectName_handlesNull() {
- String instanceAndProjectName = NotificationEmail.getInstanceAndProjectName(null, "/my/api");
- assertThat(instanceAndProjectName).isEqualTo("...api");
+ public void instanceAndProjectNameNull() throws Exception {
+ assertThat(getInstanceAndProjectName(null, "/my/api")).isEqualTo("...api");
+ assertThat(getInstanceAndProjectName(null, "/api")).isEqualTo("api");
+ assertThat(getInstanceAndProjectName(null, "api")).isEqualTo("api");
}
@Test
- public void getShortProjectName() {
- assertThat(NotificationEmail.getShortProjectName("/api")).isEqualTo("api");
- assertThat(NotificationEmail.getShortProjectName("/my/api")).isEqualTo("...api");
- assertThat(NotificationEmail.getShortProjectName("/my/sub/project")).isEqualTo("...project");
+ public void shortProjectName() throws Exception {
+ assertThat(getShortProjectName("api")).isEqualTo("api");
+ assertThat(getShortProjectName("/api")).isEqualTo("api");
+ assertThat(getShortProjectName("/my/api")).isEqualTo("...api");
+ assertThat(getShortProjectName("/my/sub/project")).isEqualTo("...project");
}
}
diff --git a/javatests/com/google/gerrit/server/notedb/AbstractChangeNotesTest.java b/javatests/com/google/gerrit/server/notedb/AbstractChangeNotesTest.java
index 269db34..032b141 100644
--- a/javatests/com/google/gerrit/server/notedb/AbstractChangeNotesTest.java
+++ b/javatests/com/google/gerrit/server/notedb/AbstractChangeNotesTest.java
@@ -29,6 +29,7 @@
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.FanOutExecutor;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.InternalUser;
@@ -51,9 +52,9 @@
import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.util.time.TimeUtil;
+import com.google.gerrit.testing.AssertableExecutorService;
import com.google.gerrit.testing.ConfigSuite;
import com.google.gerrit.testing.FakeAccountCache;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.InMemoryRepositoryManager;
import com.google.gerrit.testing.TestChanges;
import com.google.gerrit.testing.TestTimeUtil;
@@ -63,6 +64,7 @@
import com.google.inject.util.Providers;
import java.sql.Timestamp;
import java.util.TimeZone;
+import java.util.concurrent.ExecutorService;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
@@ -76,7 +78,7 @@
@Ignore
@RunWith(ConfigSuite.class)
-public abstract class AbstractChangeNotesTest extends GerritBaseTests {
+public abstract class AbstractChangeNotesTest {
private static final TimeZone TZ = TimeZone.getTimeZone("America/Los_Angeles");
@ConfigSuite.Parameter public Config testConfig;
@@ -92,6 +94,7 @@
protected Project.NameKey project;
protected RevWalk rw;
protected TestRepository<InMemoryRepository> tr;
+ protected AssertableExecutorService assertableFanOutExecutor;
@Inject protected IdentifiedUser.GenericFactory userFactory;
@@ -125,6 +128,7 @@
ou.setFullName("Other Account");
ou.setPreferredEmail("other@account.com");
accountCache.put(ou);
+ assertableFanOutExecutor = new AssertableExecutorService();
injector =
Guice.createInjector(
@@ -157,6 +161,9 @@
.toInstance(serverIdent);
bind(GitReferenceUpdated.class).toInstance(GitReferenceUpdated.DISABLED);
bind(MetricMaker.class).to(DisabledMetricMaker.class);
+ bind(ExecutorService.class)
+ .annotatedWith(FanOutExecutor.class)
+ .toInstance(assertableFanOutExecutor);
}
});
diff --git a/javatests/com/google/gerrit/server/notedb/ChangeNotesParserTest.java b/javatests/com/google/gerrit/server/notedb/ChangeNotesParserTest.java
index 79dcd5b..52000f5 100644
--- a/javatests/com/google/gerrit/server/notedb/ChangeNotesParserTest.java
+++ b/javatests/com/google/gerrit/server/notedb/ChangeNotesParserTest.java
@@ -15,7 +15,7 @@
package com.google.gerrit.server.notedb;
import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.server.notedb.ChangeNotesCommit.ChangeNotesRevWalk;
@@ -545,12 +545,7 @@
}
private void assertParseFails(RevCommit commit) throws Exception {
- try {
- newParser(commit).parseAll();
- fail("Expected parse to fail:\n" + commit.getFullMessage());
- } catch (ConfigInvalidException e) {
- // Expected
- }
+ assertThrows(ConfigInvalidException.class, () -> newParser(commit).parseAll());
}
private ChangeNotesParser newParser(ObjectId tip) throws Exception {
diff --git a/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java b/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java
index 8b9f5bb..3e54863 100644
--- a/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java
+++ b/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java
@@ -49,18 +49,18 @@
import com.google.gerrit.server.cache.serialize.ObjectIdConverter;
import com.google.gerrit.server.notedb.ChangeNotesState.ChangeColumns;
import com.google.gerrit.server.notedb.ChangeNotesState.Serializer;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.inject.TypeLiteral;
import com.google.protobuf.ByteString;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Before;
import org.junit.Test;
-public class ChangeNotesStateTest extends GerritBaseTests {
+public class ChangeNotesStateTest {
private static final Change.Id ID = Change.id(123);
private static final ObjectId SHA =
ObjectId.fromString("1234567812345678123456781234567812345678");
@@ -334,26 +334,28 @@
@Test
public void serializePatchSets() throws Exception {
PatchSet ps1 =
- new PatchSet(
- PatchSet.id(ID, 1), ObjectId.fromString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
- ps1.setUploader(Account.id(2000));
- ps1.setCreatedOn(cols.createdOn());
+ PatchSet.builder()
+ .id(PatchSet.id(ID, 1))
+ .commitId(ObjectId.fromString("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
+ .uploader(Account.id(2000))
+ .createdOn(cols.createdOn())
+ .build();
ByteString ps1Bytes = toByteString(ps1, PatchSetProtoConverter.INSTANCE);
assertThat(ps1Bytes.size()).isEqualTo(66);
PatchSet ps2 =
- new PatchSet(
- PatchSet.id(ID, 2), ObjectId.fromString("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
- ps2.setUploader(Account.id(3000));
- ps2.setCreatedOn(cols.lastUpdatedOn());
+ PatchSet.builder()
+ .id(PatchSet.id(ID, 2))
+ .commitId(ObjectId.fromString("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"))
+ .uploader(Account.id(3000))
+ .createdOn(cols.lastUpdatedOn())
+ .build();
ByteString ps2Bytes = toByteString(ps2, PatchSetProtoConverter.INSTANCE);
assertThat(ps2Bytes.size()).isEqualTo(66);
assertThat(ps2Bytes).isNotEqualTo(ps1Bytes);
assertRoundTrip(
- newBuilder()
- .patchSets(ImmutableMap.of(ps2.getId(), ps2, ps1.getId(), ps1).entrySet())
- .build(),
+ newBuilder().patchSets(ImmutableMap.of(ps2.id(), ps2, ps1.id(), ps1).entrySet()).build(),
ChangeNotesStateProto.newBuilder()
.setMetaId(SHA_BYTES)
.setChangeId(ID.get())
@@ -366,27 +368,31 @@
@Test
public void serializeApprovals() throws Exception {
PatchSetApproval a1 =
- new PatchSetApproval(
- PatchSetApproval.key(
- PatchSet.id(ID, 1), Account.id(2001), LabelId.create("Code-Review")),
- (short) 1,
- new Timestamp(1212L));
+ PatchSetApproval.builder()
+ .key(
+ PatchSetApproval.key(
+ PatchSet.id(ID, 1), Account.id(2001), LabelId.create("Code-Review")))
+ .value(1)
+ .granted(new Timestamp(1212L))
+ .build();
ByteString a1Bytes = toByteString(a1, PatchSetApprovalProtoConverter.INSTANCE);
assertThat(a1Bytes.size()).isEqualTo(43);
PatchSetApproval a2 =
- new PatchSetApproval(
- PatchSetApproval.key(PatchSet.id(ID, 1), Account.id(2002), LabelId.create("Verified")),
- (short) -1,
- new Timestamp(3434L));
+ PatchSetApproval.builder()
+ .key(
+ PatchSetApproval.key(
+ PatchSet.id(ID, 1), Account.id(2002), LabelId.create("Verified")))
+ .value(-1)
+ .granted(new Timestamp(3434L))
+ .build();
ByteString a2Bytes = toByteString(a2, PatchSetApprovalProtoConverter.INSTANCE);
assertThat(a2Bytes.size()).isEqualTo(49);
assertThat(a2Bytes).isNotEqualTo(a1Bytes);
assertRoundTrip(
newBuilder()
- .approvals(
- ImmutableListMultimap.of(a2.getPatchSetId(), a2, a1.getPatchSetId(), a1).entries())
+ .approvals(ImmutableListMultimap.of(a2.patchSetId(), a2, a1.patchSetId(), a1).entries())
.build(),
ChangeNotesStateProto.newBuilder()
.setMetaId(SHA_BYTES)
@@ -766,15 +772,15 @@
@Test
public void patchSetFields() throws Exception {
assertThatSerializedClass(PatchSet.class)
- .hasFields(
+ .hasAutoValueMethods(
ImmutableMap.<String, Type>builder()
.put("id", PatchSet.Id.class)
.put("commitId", ObjectId.class)
.put("uploader", Account.Id.class)
.put("createdOn", Timestamp.class)
- .put("groups", String.class)
- .put("pushCertificate", String.class)
- .put("description", String.class)
+ .put("groups", new TypeLiteral<ImmutableList<String>>() {}.getType())
+ .put("pushCertificate", new TypeLiteral<Optional<String>>() {}.getType())
+ .put("description", new TypeLiteral<Optional<String>>() {}.getType())
.build());
}
@@ -788,14 +794,15 @@
.put("labelId", LabelId.class)
.build());
assertThatSerializedClass(PatchSetApproval.class)
- .hasFields(
+ .hasAutoValueMethods(
ImmutableMap.<String, Type>builder()
.put("key", PatchSetApproval.Key.class)
.put("value", short.class)
.put("granted", Timestamp.class)
- .put("tag", String.class)
+ .put("tag", new TypeLiteral<Optional<String>>() {}.getType())
.put("realAccountId", Account.Id.class)
.put("postSubmit", boolean.class)
+ .put("toBuilder", PatchSetApproval.Builder.class)
.build());
}
diff --git a/javatests/com/google/gerrit/server/notedb/ChangeNotesTest.java b/javatests/com/google/gerrit/server/notedb/ChangeNotesTest.java
index fe01bc7..1e970a1 100644
--- a/javatests/com/google/gerrit/server/notedb/ChangeNotesTest.java
+++ b/javatests/com/google/gerrit/server/notedb/ChangeNotesTest.java
@@ -17,15 +17,16 @@
import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.common.truth.Truth8.assertThat;
import static com.google.gerrit.reviewdb.client.RefNames.changeMetaRef;
import static com.google.gerrit.reviewdb.client.RefNames.refsDraftComments;
import static com.google.gerrit.server.notedb.ReviewerStateInternal.CC;
import static com.google.gerrit.server.notedb.ReviewerStateInternal.REMOVED;
import static com.google.gerrit.server.notedb.ReviewerStateInternal.REVIEWER;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Comparator.comparing;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
-import static org.junit.Assert.fail;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
@@ -101,7 +102,7 @@
update.commit();
ChangeNotes notes = newNotes(c);
- assertThat(notes.getCurrentPatchSet().getDescription()).isEqualTo(description);
+ assertThat(notes.getCurrentPatchSet().description()).hasValue(description);
description = "new, now more descriptive!";
update = newUpdate(c, changeOwner);
@@ -109,7 +110,7 @@
update.commit();
notes = newNotes(c);
- assertThat(notes.getCurrentPatchSet().getDescription()).isEqualTo(description);
+ assertThat(notes.getCurrentPatchSet().description()).hasValue(description);
}
@Test
@@ -162,7 +163,7 @@
ImmutableListMultimap<PatchSet.Id, PatchSetApproval> approvals = notes.getApprovals();
assertThat(approvals).hasSize(1);
- assertThat(approvals.entries().asList().get(0).getValue().getTag()).isEqualTo(tag2);
+ assertThat(approvals.entries().asList().get(0).getValue().tag()).hasValue(tag2);
}
@Test
@@ -209,8 +210,8 @@
ImmutableListMultimap<PatchSet.Id, PatchSetApproval> approvals = notes.getApprovals();
assertThat(approvals).hasSize(1);
PatchSetApproval approval = approvals.entries().asList().get(0).getValue();
- assertThat(approval.getTag()).isEqualTo(integrationTag);
- assertThat(approval.getValue()).isEqualTo(-1);
+ assertThat(approval.tag()).hasValue(integrationTag);
+ assertThat(approval.value()).isEqualTo(-1);
ImmutableListMultimap<ObjectId, Comment> comments = notes.getComments();
assertThat(comments).hasSize(1);
@@ -236,17 +237,17 @@
List<PatchSetApproval> psas = notes.getApprovals().get(c.currentPatchSetId());
assertThat(psas).hasSize(2);
- assertThat(psas.get(0).getPatchSetId()).isEqualTo(c.currentPatchSetId());
- assertThat(psas.get(0).getAccountId().get()).isEqualTo(1);
- assertThat(psas.get(0).getLabel()).isEqualTo("Code-Review");
- assertThat(psas.get(0).getValue()).isEqualTo((short) -1);
- assertThat(psas.get(0).getGranted()).isEqualTo(truncate(after(c, 2000)));
+ assertThat(psas.get(0).patchSetId()).isEqualTo(c.currentPatchSetId());
+ assertThat(psas.get(0).accountId().get()).isEqualTo(1);
+ assertThat(psas.get(0).label()).isEqualTo("Code-Review");
+ assertThat(psas.get(0).value()).isEqualTo((short) -1);
+ assertThat(psas.get(0).granted()).isEqualTo(truncate(after(c, 2000)));
- assertThat(psas.get(1).getPatchSetId()).isEqualTo(c.currentPatchSetId());
- assertThat(psas.get(1).getAccountId().get()).isEqualTo(1);
- assertThat(psas.get(1).getLabel()).isEqualTo("Verified");
- assertThat(psas.get(1).getValue()).isEqualTo((short) 1);
- assertThat(psas.get(1).getGranted()).isEqualTo(psas.get(0).getGranted());
+ assertThat(psas.get(1).patchSetId()).isEqualTo(c.currentPatchSetId());
+ assertThat(psas.get(1).accountId().get()).isEqualTo(1);
+ assertThat(psas.get(1).label()).isEqualTo("Verified");
+ assertThat(psas.get(1).value()).isEqualTo((short) 1);
+ assertThat(psas.get(1).granted()).isEqualTo(psas.get(0).granted());
}
@Test
@@ -268,18 +269,18 @@
assertThat(psas).hasSize(2);
PatchSetApproval psa1 = Iterables.getOnlyElement(psas.get(ps1));
- assertThat(psa1.getPatchSetId()).isEqualTo(ps1);
- assertThat(psa1.getAccountId().get()).isEqualTo(1);
- assertThat(psa1.getLabel()).isEqualTo("Code-Review");
- assertThat(psa1.getValue()).isEqualTo((short) -1);
- assertThat(psa1.getGranted()).isEqualTo(truncate(after(c, 2000)));
+ assertThat(psa1.patchSetId()).isEqualTo(ps1);
+ assertThat(psa1.accountId().get()).isEqualTo(1);
+ assertThat(psa1.label()).isEqualTo("Code-Review");
+ assertThat(psa1.value()).isEqualTo((short) -1);
+ assertThat(psa1.granted()).isEqualTo(truncate(after(c, 2000)));
PatchSetApproval psa2 = Iterables.getOnlyElement(psas.get(ps2));
- assertThat(psa2.getPatchSetId()).isEqualTo(ps2);
- assertThat(psa2.getAccountId().get()).isEqualTo(1);
- assertThat(psa2.getLabel()).isEqualTo("Code-Review");
- assertThat(psa2.getValue()).isEqualTo((short) +1);
- assertThat(psa2.getGranted()).isEqualTo(truncate(after(c, 4000)));
+ assertThat(psa2.patchSetId()).isEqualTo(ps2);
+ assertThat(psa2.accountId().get()).isEqualTo(1);
+ assertThat(psa2.label()).isEqualTo("Code-Review");
+ assertThat(psa2.value()).isEqualTo((short) +1);
+ assertThat(psa2.granted()).isEqualTo(truncate(after(c, 4000)));
}
@Test
@@ -292,8 +293,8 @@
ChangeNotes notes = newNotes(c);
PatchSetApproval psa =
Iterables.getOnlyElement(notes.getApprovals().get(c.currentPatchSetId()));
- assertThat(psa.getLabel()).isEqualTo("Code-Review");
- assertThat(psa.getValue()).isEqualTo((short) -1);
+ assertThat(psa.label()).isEqualTo("Code-Review");
+ assertThat(psa.value()).isEqualTo((short) -1);
update = newUpdate(c, changeOwner);
update.putApproval("Code-Review", (short) 1);
@@ -301,8 +302,8 @@
notes = newNotes(c);
psa = Iterables.getOnlyElement(notes.getApprovals().get(c.currentPatchSetId()));
- assertThat(psa.getLabel()).isEqualTo("Code-Review");
- assertThat(psa.getValue()).isEqualTo((short) 1);
+ assertThat(psa.label()).isEqualTo("Code-Review");
+ assertThat(psa.value()).isEqualTo((short) 1);
}
@Test
@@ -321,17 +322,17 @@
List<PatchSetApproval> psas = notes.getApprovals().get(c.currentPatchSetId());
assertThat(psas).hasSize(2);
- assertThat(psas.get(0).getPatchSetId()).isEqualTo(c.currentPatchSetId());
- assertThat(psas.get(0).getAccountId().get()).isEqualTo(1);
- assertThat(psas.get(0).getLabel()).isEqualTo("Code-Review");
- assertThat(psas.get(0).getValue()).isEqualTo((short) -1);
- assertThat(psas.get(0).getGranted()).isEqualTo(truncate(after(c, 2000)));
+ assertThat(psas.get(0).patchSetId()).isEqualTo(c.currentPatchSetId());
+ assertThat(psas.get(0).accountId().get()).isEqualTo(1);
+ assertThat(psas.get(0).label()).isEqualTo("Code-Review");
+ assertThat(psas.get(0).value()).isEqualTo((short) -1);
+ assertThat(psas.get(0).granted()).isEqualTo(truncate(after(c, 2000)));
- assertThat(psas.get(1).getPatchSetId()).isEqualTo(c.currentPatchSetId());
- assertThat(psas.get(1).getAccountId().get()).isEqualTo(2);
- assertThat(psas.get(1).getLabel()).isEqualTo("Code-Review");
- assertThat(psas.get(1).getValue()).isEqualTo((short) 1);
- assertThat(psas.get(1).getGranted()).isEqualTo(truncate(after(c, 3000)));
+ assertThat(psas.get(1).patchSetId()).isEqualTo(c.currentPatchSetId());
+ assertThat(psas.get(1).accountId().get()).isEqualTo(2);
+ assertThat(psas.get(1).label()).isEqualTo("Code-Review");
+ assertThat(psas.get(1).value()).isEqualTo((short) 1);
+ assertThat(psas.get(1).granted()).isEqualTo(truncate(after(c, 3000)));
}
@Test
@@ -344,9 +345,9 @@
ChangeNotes notes = newNotes(c);
PatchSetApproval psa =
Iterables.getOnlyElement(notes.getApprovals().get(c.currentPatchSetId()));
- assertThat(psa.getAccountId().get()).isEqualTo(1);
- assertThat(psa.getLabel()).isEqualTo("Not-For-Long");
- assertThat(psa.getValue()).isEqualTo((short) 1);
+ assertThat(psa.accountId().get()).isEqualTo(1);
+ assertThat(psa.label()).isEqualTo("Not-For-Long");
+ assertThat(psa.value()).isEqualTo((short) 1);
update = newUpdate(c, changeOwner);
update.removeApproval("Not-For-Long");
@@ -356,8 +357,12 @@
assertThat(notes.getApprovals())
.containsExactlyEntriesIn(
ImmutableListMultimap.of(
- psa.getPatchSetId(),
- new PatchSetApproval(psa.getKey(), (short) 0, update.getWhen())));
+ psa.patchSetId(),
+ PatchSetApproval.builder()
+ .key(psa.key())
+ .value(0)
+ .granted(update.getWhen())
+ .build()));
}
@Test
@@ -370,9 +375,9 @@
ChangeNotes notes = newNotes(c);
PatchSetApproval psa =
Iterables.getOnlyElement(notes.getApprovals().get(c.currentPatchSetId()));
- assertThat(psa.getAccountId()).isEqualTo(otherUserId);
- assertThat(psa.getLabel()).isEqualTo("Not-For-Long");
- assertThat(psa.getValue()).isEqualTo((short) 1);
+ assertThat(psa.accountId()).isEqualTo(otherUserId);
+ assertThat(psa.label()).isEqualTo("Not-For-Long");
+ assertThat(psa.value()).isEqualTo((short) 1);
update = newUpdate(c, changeOwner);
update.removeApprovalFor(otherUserId, "Not-For-Long");
@@ -382,8 +387,12 @@
assertThat(notes.getApprovals())
.containsExactlyEntriesIn(
ImmutableListMultimap.of(
- psa.getPatchSetId(),
- new PatchSetApproval(psa.getKey(), (short) 0, update.getWhen())));
+ psa.patchSetId(),
+ PatchSetApproval.builder()
+ .key(psa.key())
+ .value(0)
+ .granted(update.getWhen())
+ .build()));
// Add back approval on same label.
update = newUpdate(c, otherUser);
@@ -392,9 +401,9 @@
notes = newNotes(c);
psa = Iterables.getOnlyElement(notes.getApprovals().get(c.currentPatchSetId()));
- assertThat(psa.getAccountId()).isEqualTo(otherUserId);
- assertThat(psa.getLabel()).isEqualTo("Not-For-Long");
- assertThat(psa.getValue()).isEqualTo((short) 2);
+ assertThat(psa.accountId()).isEqualTo(otherUserId);
+ assertThat(psa.label()).isEqualTo("Not-For-Long");
+ assertThat(psa.value()).isEqualTo((short) 2);
}
@Test
@@ -408,17 +417,17 @@
ChangeNotes notes = newNotes(c);
ImmutableList<PatchSetApproval> approvals =
notes.getApprovals().get(c.currentPatchSetId()).stream()
- .sorted(comparing(a -> a.getAccountId().get()))
+ .sorted(comparing(a -> a.accountId().get()))
.collect(toImmutableList());
assertThat(approvals).hasSize(2);
- assertThat(approvals.get(0).getAccountId()).isEqualTo(changeOwner.getAccountId());
- assertThat(approvals.get(0).getLabel()).isEqualTo("Code-Review");
- assertThat(approvals.get(0).getValue()).isEqualTo((short) 1);
+ assertThat(approvals.get(0).accountId()).isEqualTo(changeOwner.getAccountId());
+ assertThat(approvals.get(0).label()).isEqualTo("Code-Review");
+ assertThat(approvals.get(0).value()).isEqualTo((short) 1);
- assertThat(approvals.get(1).getAccountId()).isEqualTo(otherUser.getAccountId());
- assertThat(approvals.get(1).getLabel()).isEqualTo("Code-Review");
- assertThat(approvals.get(1).getValue()).isEqualTo((short) -1);
+ assertThat(approvals.get(1).accountId()).isEqualTo(otherUser.getAccountId());
+ assertThat(approvals.get(1).label()).isEqualTo("Code-Review");
+ assertThat(approvals.get(1).value()).isEqualTo((short) -1);
}
@Test
@@ -448,12 +457,12 @@
ChangeNotes notes = newNotes(c);
List<PatchSetApproval> approvals = Lists.newArrayList(notes.getApprovals().values());
assertThat(approvals).hasSize(2);
- assertThat(approvals.get(0).getLabel()).isEqualTo("Verified");
- assertThat(approvals.get(0).getValue()).isEqualTo((short) 1);
- assertThat(approvals.get(0).isPostSubmit()).isFalse();
- assertThat(approvals.get(1).getLabel()).isEqualTo("Code-Review");
- assertThat(approvals.get(1).getValue()).isEqualTo((short) 2);
- assertThat(approvals.get(1).isPostSubmit()).isTrue();
+ assertThat(approvals.get(0).label()).isEqualTo("Verified");
+ assertThat(approvals.get(0).value()).isEqualTo((short) 1);
+ assertThat(approvals.get(0).postSubmit()).isFalse();
+ assertThat(approvals.get(1).label()).isEqualTo("Code-Review");
+ assertThat(approvals.get(1).value()).isEqualTo((short) 2);
+ assertThat(approvals.get(1).postSubmit()).isTrue();
}
@Test
@@ -488,18 +497,18 @@
List<PatchSetApproval> approvals = Lists.newArrayList(notes.getApprovals().values());
assertThat(approvals).hasSize(3);
- assertThat(approvals.get(0).getAccountId()).isEqualTo(ownerId);
- assertThat(approvals.get(0).getLabel()).isEqualTo("Verified");
- assertThat(approvals.get(0).getValue()).isEqualTo(1);
- assertThat(approvals.get(0).isPostSubmit()).isFalse();
- assertThat(approvals.get(1).getAccountId()).isEqualTo(ownerId);
- assertThat(approvals.get(1).getLabel()).isEqualTo("Code-Review");
- assertThat(approvals.get(1).getValue()).isEqualTo(2);
- assertThat(approvals.get(1).isPostSubmit()).isFalse(); // During submit.
- assertThat(approvals.get(2).getAccountId()).isEqualTo(otherId);
- assertThat(approvals.get(2).getLabel()).isEqualTo("Other-Label");
- assertThat(approvals.get(2).getValue()).isEqualTo(2);
- assertThat(approvals.get(2).isPostSubmit()).isTrue();
+ assertThat(approvals.get(0).accountId()).isEqualTo(ownerId);
+ assertThat(approvals.get(0).label()).isEqualTo("Verified");
+ assertThat(approvals.get(0).value()).isEqualTo(1);
+ assertThat(approvals.get(0).postSubmit()).isFalse();
+ assertThat(approvals.get(1).accountId()).isEqualTo(ownerId);
+ assertThat(approvals.get(1).label()).isEqualTo("Code-Review");
+ assertThat(approvals.get(1).value()).isEqualTo(2);
+ assertThat(approvals.get(1).postSubmit()).isFalse(); // During submit.
+ assertThat(approvals.get(2).accountId()).isEqualTo(otherId);
+ assertThat(approvals.get(2).label()).isEqualTo("Other-Label");
+ assertThat(approvals.get(2).value()).isEqualTo(2);
+ assertThat(approvals.get(2).postSubmit()).isTrue();
}
@Test
@@ -580,8 +589,8 @@
ChangeNotes notes = newNotes(c);
List<PatchSetApproval> psas = notes.getApprovals().get(c.currentPatchSetId());
assertThat(psas).hasSize(2);
- assertThat(psas.get(0).getAccountId()).isEqualTo(changeOwner.getAccount().getId());
- assertThat(psas.get(1).getAccountId()).isEqualTo(otherUser.getAccount().getId());
+ assertThat(psas.get(0).accountId()).isEqualTo(changeOwner.getAccount().getId());
+ assertThat(psas.get(1).accountId()).isEqualTo(otherUser.getAccount().getId());
update = newUpdate(c, changeOwner);
update.removeReviewer(otherUser.getAccount().getId());
@@ -590,7 +599,7 @@
notes = newNotes(c);
psas = notes.getApprovals().get(c.currentPatchSetId());
assertThat(psas).hasSize(1);
- assertThat(psas.get(0).getAccountId()).isEqualTo(changeOwner.getAccount().getId());
+ assertThat(psas.get(0).accountId()).isEqualTo(changeOwner.getAccount().getId());
}
@Test
@@ -819,14 +828,17 @@
// Trying to set another Change-Id fails
String otherChangeId = "I577fb248e474018276351785930358ec0450e9f7";
- update = newUpdate(c, changeOwner);
- exception.expect(IllegalArgumentException.class);
- exception.expectMessage(
- "The Change-Id was already set to "
- + c.getKey()
- + ", so we cannot set this Change-Id: "
- + otherChangeId);
- update.setChangeId(otherChangeId);
+ ChangeUpdate failingUpdate = newUpdate(c, changeOwner);
+ IllegalArgumentException thrown =
+ assertThrows(
+ IllegalArgumentException.class, () -> failingUpdate.setChangeId(otherChangeId));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains(
+ "The Change-Id was already set to "
+ + c.getKey()
+ + ", so we cannot set this Change-Id: "
+ + otherChangeId);
}
@Test
@@ -990,19 +1002,15 @@
update.setCommit(rw, commit);
update.commit();
- try {
- newNotes(c);
- fail("Expected IOException");
- } catch (StorageException e) {
- assertCause(
- e,
- ConfigInvalidException.class,
- "Multiple revisions parsed for patch set 1:"
- + " "
- + commit.name()
- + " and "
- + ps.getCommitId().name());
- }
+ StorageException e = assertThrows(StorageException.class, () -> newNotes(c));
+ assertCause(
+ e,
+ ConfigInvalidException.class,
+ "Multiple revisions parsed for patch set 1:"
+ + " "
+ + commit.name()
+ + " and "
+ + ps.commitId().name());
}
@Test
@@ -1012,32 +1020,32 @@
// ps1 created by newChange()
ChangeNotes notes = newNotes(c);
PatchSet ps1 = notes.getCurrentPatchSet();
- assertThat(notes.getChange().currentPatchSetId()).isEqualTo(ps1.getId());
+ assertThat(notes.getChange().currentPatchSetId()).isEqualTo(ps1.id());
assertThat(notes.getChange().getSubject()).isEqualTo("Change subject");
assertThat(notes.getChange().getOriginalSubject()).isEqualTo("Change subject");
- assertThat(ps1.getId()).isEqualTo(PatchSet.id(c.getId(), 1));
- assertThat(ps1.getUploader()).isEqualTo(changeOwner.getAccountId());
+ assertThat(ps1.id()).isEqualTo(PatchSet.id(c.getId(), 1));
+ assertThat(ps1.uploader()).isEqualTo(changeOwner.getAccountId());
// ps2 by other user
RevCommit commit = incrementPatchSet(c, otherUser);
notes = newNotes(c);
PatchSet ps2 = notes.getCurrentPatchSet();
- assertThat(ps2.getId()).isEqualTo(PatchSet.id(c.getId(), 2));
+ assertThat(ps2.id()).isEqualTo(PatchSet.id(c.getId(), 2));
assertThat(notes.getChange().getSubject()).isEqualTo("PS2");
assertThat(notes.getChange().getOriginalSubject()).isEqualTo("Change subject");
- assertThat(notes.getChange().currentPatchSetId()).isEqualTo(ps2.getId());
- assertThat(ps2.getCommitId()).isNotEqualTo(ps1.getCommitId());
- assertThat(ps2.getCommitId()).isEqualTo(commit);
- assertThat(ps2.getUploader()).isEqualTo(otherUser.getAccountId());
- assertThat(ps2.getCreatedOn()).isEqualTo(notes.getChange().getLastUpdatedOn());
+ assertThat(notes.getChange().currentPatchSetId()).isEqualTo(ps2.id());
+ assertThat(ps2.commitId()).isNotEqualTo(ps1.commitId());
+ assertThat(ps2.commitId()).isEqualTo(commit);
+ assertThat(ps2.uploader()).isEqualTo(otherUser.getAccountId());
+ assertThat(ps2.createdOn()).isEqualTo(notes.getChange().getLastUpdatedOn());
// comment on ps1, current patch set is still ps2
ChangeUpdate update = newUpdate(c, changeOwner);
- update.setPatchSetId(ps1.getId());
+ update.setPatchSetId(ps1.id());
update.setChangeMessage("Comment on old patch set.");
update.commit();
notes = newNotes(c);
- assertThat(notes.getChange().currentPatchSetId()).isEqualTo(ps2.getId());
+ assertThat(notes.getChange().currentPatchSetId()).isEqualTo(ps2.id());
}
@Test
@@ -1098,14 +1106,14 @@
PatchSet.Id psId1 = c.currentPatchSetId();
ChangeNotes notes = newNotes(c);
- assertThat(notes.getPatchSets().get(psId1).getGroups()).isEmpty();
+ assertThat(notes.getPatchSets().get(psId1).groups()).isEmpty();
// ps1
ChangeUpdate update = newUpdate(c, changeOwner);
update.setGroups(ImmutableList.of("a", "b"));
update.commit();
notes = newNotes(c);
- assertThat(notes.getPatchSets().get(psId1).getGroups()).containsExactly("a", "b").inOrder();
+ assertThat(notes.getPatchSets().get(psId1).groups()).containsExactly("a", "b").inOrder();
incrementCurrentPatchSetFieldOnly(c);
PatchSet.Id psId2 = c.currentPatchSetId();
@@ -1114,8 +1122,8 @@
update.setGroups(ImmutableList.of("d"));
update.commit();
notes = newNotes(c);
- assertThat(notes.getPatchSets().get(psId2).getGroups()).containsExactly("d");
- assertThat(notes.getPatchSets().get(psId1).getGroups()).containsExactly("a", "b").inOrder();
+ assertThat(notes.getPatchSets().get(psId2).groups()).containsExactly("d");
+ assertThat(notes.getPatchSets().get(psId1).groups()).containsExactly("a", "b").inOrder();
}
@Test
@@ -1144,8 +1152,8 @@
readNote(notes, commit);
Map<PatchSet.Id, PatchSet> patchSets = notes.getPatchSets();
- assertThat(patchSets.get(psId1).getPushCertificate()).isNull();
- assertThat(patchSets.get(psId2).getPushCertificate()).isEqualTo(pushCert);
+ assertThat(patchSets.get(psId1).pushCertificate()).isEmpty();
+ assertThat(patchSets.get(psId2).pushCertificate()).hasValue(pushCert);
assertThat(notes.getComments()).isEmpty();
// comment on ps2
@@ -1172,8 +1180,8 @@
notes = newNotes(c);
patchSets = notes.getPatchSets();
- assertThat(patchSets.get(psId1).getPushCertificate()).isNull();
- assertThat(patchSets.get(psId2).getPushCertificate()).isEqualTo(pushCert);
+ assertThat(patchSets.get(psId1).pushCertificate()).isEmpty();
+ assertThat(patchSets.get(psId2).pushCertificate()).hasValue(pushCert);
assertThat(notes.getComments()).isNotEmpty();
}
@@ -1203,13 +1211,13 @@
List<PatchSetApproval> psas = notes.getApprovals().get(c.currentPatchSetId());
assertThat(psas).hasSize(2);
- assertThat(psas.get(0).getAccountId()).isEqualTo(changeOwner.getAccount().getId());
- assertThat(psas.get(0).getLabel()).isEqualTo("Verified");
- assertThat(psas.get(0).getValue()).isEqualTo((short) 1);
+ assertThat(psas.get(0).accountId()).isEqualTo(changeOwner.getAccount().getId());
+ assertThat(psas.get(0).label()).isEqualTo("Verified");
+ assertThat(psas.get(0).value()).isEqualTo((short) 1);
- assertThat(psas.get(1).getAccountId()).isEqualTo(otherUser.getAccount().getId());
- assertThat(psas.get(1).getLabel()).isEqualTo("Code-Review");
- assertThat(psas.get(1).getValue()).isEqualTo((short) 2);
+ assertThat(psas.get(1).accountId()).isEqualTo(otherUser.getAccount().getId());
+ assertThat(psas.get(1).label()).isEqualTo("Code-Review");
+ assertThat(psas.get(1).value()).isEqualTo((short) 2);
}
@Test
@@ -1317,11 +1325,11 @@
PatchSetApproval approval1 =
newNotes(c1).getApprovals().get(c1.currentPatchSetId()).iterator().next();
- assertThat(approval1.getLabel()).isEqualTo("Verified");
+ assertThat(approval1.label()).isEqualTo("Verified");
PatchSetApproval approval2 =
newNotes(c2).getApprovals().get(c2.currentPatchSetId()).iterator().next();
- assertThat(approval2.getLabel()).isEqualTo("Code-Review");
+ assertThat(approval2.label()).isEqualTo("Code-Review");
}
@Test
@@ -2533,9 +2541,9 @@
assertThat(msg.getMessage()).isEqualTo("A message.");
assertThat(msg.getAuthor()).isNull();
- update = newUpdate(c, internalUser);
- exception.expect(IllegalStateException.class);
- update.putApproval("Code-Review", (short) 1);
+ ChangeUpdate failingUpdate = newUpdate(c, internalUser);
+ assertThrows(
+ IllegalStateException.class, () -> failingUpdate.putApproval("Code-Review", (short) 1));
}
@Test
@@ -3004,9 +3012,9 @@
public void setRevertOfToCurrentChangeFails() throws Exception {
Change c = newChange();
ChangeUpdate update = newUpdate(c, changeOwner);
- exception.expect(IllegalArgumentException.class);
- exception.expectMessage("A change cannot revert itself");
- update.setRevertOf(c.getId().get());
+ IllegalArgumentException thrown =
+ assertThrows(IllegalArgumentException.class, () -> update.setRevertOf(c.getId().get()));
+ assertThat(thrown).hasMessageThat().contains("A change cannot revert itself");
}
@Test
@@ -3014,9 +3022,10 @@
Change c = newChange();
ChangeUpdate update = newUpdate(c, changeOwner);
update.setRevertOf(newChange().getId().get());
- exception.expect(StorageException.class);
- exception.expectMessage("Given ChangeUpdate is only allowed on initial commit");
- update.commit();
+ StorageException thrown = assertThrows(StorageException.class, () -> update.commit());
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Given ChangeUpdate is only allowed on initial commit");
}
@Test
diff --git a/javatests/com/google/gerrit/server/notedb/CommentTimestampAdapterTest.java b/javatests/com/google/gerrit/server/notedb/CommentTimestampAdapterTest.java
index 24c3fe5..02f187d 100644
--- a/javatests/com/google/gerrit/server/notedb/CommentTimestampAdapterTest.java
+++ b/javatests/com/google/gerrit/server/notedb/CommentTimestampAdapterTest.java
@@ -18,7 +18,6 @@
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Comment;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.sql.Timestamp;
@@ -30,7 +29,7 @@
import org.junit.Before;
import org.junit.Test;
-public class CommentTimestampAdapterTest extends GerritBaseTests {
+public class CommentTimestampAdapterTest {
/** Arbitrary time outside of a DST transition, as an ISO instant. */
private static final String NON_DST_STR = "2017-02-07T10:20:30.123Z";
diff --git a/javatests/com/google/gerrit/server/notedb/DraftCommentNotesTest.java b/javatests/com/google/gerrit/server/notedb/DraftCommentNotesTest.java
new file mode 100644
index 0000000..ac13037
--- /dev/null
+++ b/javatests/com/google/gerrit/server/notedb/DraftCommentNotesTest.java
@@ -0,0 +1,99 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.notedb;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.Comment;
+import com.google.gerrit.reviewdb.client.PatchLineComment.Status;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.server.util.time.TimeUtil;
+import org.eclipse.jgit.lib.ObjectId;
+import org.junit.Test;
+
+public class DraftCommentNotesTest extends AbstractChangeNotesTest {
+
+ @Test
+ public void createAndPublishCommentInOneAction_runsDraftOperationAsynchronously()
+ throws Exception {
+ Change c = newChange();
+ ChangeUpdate update = newUpdate(c, otherUser);
+ update.setPatchSetId(c.currentPatchSetId());
+ update.putComment(Status.PUBLISHED, comment(c.currentPatchSetId()));
+ update.commit();
+
+ assertThat(newNotes(c).getDraftComments(otherUserId)).isEmpty();
+ assertableFanOutExecutor.assertInteractions(1);
+ }
+
+ @Test
+ public void createAndPublishComment_runsPublishDraftOperationAsynchronously() throws Exception {
+ Change c = newChange();
+ ChangeUpdate update = newUpdate(c, otherUser);
+
+ update.setPatchSetId(c.currentPatchSetId());
+ update.putComment(Status.DRAFT, comment(c.currentPatchSetId()));
+ update.commit();
+ assertThat(newNotes(c).getDraftComments(otherUserId)).hasSize(1);
+ assertableFanOutExecutor.assertInteractions(0);
+
+ update = newUpdate(c, otherUser);
+ update.putComment(Status.PUBLISHED, comment(c.currentPatchSetId()));
+ update.commit();
+
+ assertThat(newNotes(c).getDraftComments(otherUserId)).isEmpty();
+ assertableFanOutExecutor.assertInteractions(1);
+ }
+
+ @Test
+ public void createAndDeleteDraftComment_runsDraftOperationSynchronously() throws Exception {
+ Change c = newChange();
+
+ ChangeUpdate update = newUpdate(c, otherUser);
+ update.setPatchSetId(c.currentPatchSetId());
+ update.putComment(Status.DRAFT, comment(c.currentPatchSetId()));
+ update.commit();
+
+ ChangeNotes notes = newNotes(c);
+ assertThat(notes.getDraftComments(otherUserId)).hasSize(1);
+ assertableFanOutExecutor.assertInteractions(0);
+
+ update = newUpdate(c, otherUser);
+ update.setPatchSetId(c.currentPatchSetId());
+ update.deleteComment(comment(c.currentPatchSetId()));
+ update.commit();
+
+ notes = newNotes(c);
+ assertThat(notes.getDraftComments(otherUserId)).isEmpty();
+ assertableFanOutExecutor.assertInteractions(0);
+ }
+
+ private Comment comment(PatchSet.Id psId) {
+ return newComment(
+ psId,
+ "filename",
+ "uuid",
+ null,
+ 0,
+ otherUser,
+ null,
+ TimeUtil.nowTs(),
+ "comment",
+ (short) 0,
+ ObjectId.fromString("abcd1234abcd1234abcd1234abcd1234abcd1234"),
+ false);
+ }
+}
diff --git a/javatests/com/google/gerrit/server/notedb/IntBlobTest.java b/javatests/com/google/gerrit/server/notedb/IntBlobTest.java
index 7ddc86f..201f94f 100644
--- a/javatests/com/google/gerrit/server/notedb/IntBlobTest.java
+++ b/javatests/com/google/gerrit/server/notedb/IntBlobTest.java
@@ -15,7 +15,7 @@
package com.google.gerrit.server.notedb;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static com.google.gerrit.truth.OptionalSubject.assertThat;
import com.google.gerrit.exceptions.StorageException;
@@ -59,12 +59,7 @@
public void parseNonBlob() throws Exception {
String refName = "refs/foo/master";
tr.branch(refName).commit().create();
- try {
- IntBlob.parse(repo, refName);
- assert_().fail("Expected IncorrectObjectTypeException");
- } catch (IncorrectObjectTypeException e) {
- // Expected.
- }
+ assertThrows(IncorrectObjectTypeException.class, () -> IntBlob.parse(repo, refName));
}
@Test
@@ -85,12 +80,9 @@
public void parseInvalid() throws Exception {
String refName = "refs/foo";
ObjectId id = tr.update(refName, tr.blob("1 2 3"));
- try {
- IntBlob.parse(repo, refName);
- assert_().fail("Expected StorageException");
- } catch (StorageException e) {
- assertThat(e).hasMessageThat().isEqualTo("invalid value in refs/foo blob at " + id.name());
- }
+ StorageException thrown =
+ assertThrows(StorageException.class, () -> IntBlob.parse(repo, refName));
+ assertThat(thrown).hasMessageThat().isEqualTo("invalid value in refs/foo blob at " + id.name());
}
@Test
@@ -180,19 +172,19 @@
@Test
public void storeWrongOldId() throws Exception {
String refName = "refs/foo";
- try {
- IntBlob.store(
- repo,
- rw,
- projectName,
- refName,
- ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"),
- 123,
- GitReferenceUpdated.DISABLED);
- assert_().fail("expected LockFailureException");
- } catch (LockFailureException e) {
- assertThat(e.getFailedRefs()).containsExactly("refs/foo");
- }
+ LockFailureException thrown =
+ assertThrows(
+ LockFailureException.class,
+ () ->
+ IntBlob.store(
+ repo,
+ rw,
+ projectName,
+ refName,
+ ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"),
+ 123,
+ GitReferenceUpdated.DISABLED));
+ assertThat(thrown.getFailedRefs()).containsExactly("refs/foo");
assertThat(IntBlob.parse(repo, refName)).isEmpty();
}
diff --git a/javatests/com/google/gerrit/server/notedb/RepoSequenceTest.java b/javatests/com/google/gerrit/server/notedb/RepoSequenceTest.java
index 3a4bc5c..b409b9d 100644
--- a/javatests/com/google/gerrit/server/notedb/RepoSequenceTest.java
+++ b/javatests/com/google/gerrit/server/notedb/RepoSequenceTest.java
@@ -16,9 +16,9 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
-import static org.junit.Assert.fail;
import com.github.rholder.retry.Retryer;
import com.github.rholder.retry.RetryerBuilder;
@@ -28,7 +28,6 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.InMemoryRepositoryManager;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
@@ -44,7 +43,7 @@
import org.junit.Before;
import org.junit.Test;
-public class RepoSequenceTest extends GerritBaseTests {
+public class RepoSequenceTest {
// Don't sleep in tests.
private static final Retryer<RefUpdate> RETRYER =
RepoSequence.retryerBuilder().withBlockStrategy(t -> {}).build();
@@ -169,23 +168,22 @@
@Test
public void failOnInvalidValue() throws Exception {
ObjectId id = writeBlob("id", "not a number");
- exception.expect(StorageException.class);
- exception.expectMessage("invalid value in refs/sequences/id blob at " + id.name());
- newSequence("id", 1, 3).next();
+ StorageException thrown =
+ assertThrows(StorageException.class, () -> newSequence("id", 1, 3).next());
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("invalid value in refs/sequences/id blob at " + id.name());
}
@Test
public void failOnWrongType() throws Exception {
- try (Repository repo = repoManager.openRepository(project)) {
- TestRepository<Repository> tr = new TestRepository<>(repo);
+ try (Repository repo = repoManager.openRepository(project);
+ TestRepository<Repository> tr = new TestRepository<>(repo)) {
tr.branch(RefNames.REFS_SEQUENCES + "id").commit().create();
- try {
- newSequence("id", 1, 3).next();
- fail();
- } catch (StorageException e) {
- assertThat(e.getCause()).isInstanceOf(ExecutionException.class);
- assertThat(e.getCause().getCause()).isInstanceOf(IncorrectObjectTypeException.class);
- }
+ StorageException e =
+ assertThrows(StorageException.class, () -> newSequence("id", 1, 3).next());
+ assertThat(e.getCause()).isInstanceOf(ExecutionException.class);
+ assertThat(e.getCause().getCause()).isInstanceOf(IncorrectObjectTypeException.class);
}
}
@@ -201,9 +199,10 @@
RetryerBuilder.<RefUpdate>newBuilder()
.withStopStrategy(StopStrategies.stopAfterAttempt(3))
.build());
- exception.expect(StorageException.class);
- exception.expectMessage("Failed to update refs/sequences/id: LOCK_FAILURE");
- s.next();
+ StorageException thrown = assertThrows(StorageException.class, () -> s.next());
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Failed to update refs/sequences/id: LOCK_FAILURE");
}
@Test
@@ -336,9 +335,10 @@
RetryerBuilder.<RefUpdate>newBuilder()
.withStopStrategy(StopStrategies.stopAfterAttempt(3))
.build());
- exception.expect(StorageException.class);
- exception.expectMessage("Failed to update refs/sequences/id: LOCK_FAILURE");
- s.increaseTo(2);
+ StorageException thrown = assertThrows(StorageException.class, () -> s.increaseTo(2));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Failed to update refs/sequences/id: LOCK_FAILURE");
}
private RepoSequence newSequence(String name, int start, int batchSize) {
diff --git a/javatests/com/google/gerrit/server/patch/IntraLineLoaderTest.java b/javatests/com/google/gerrit/server/patch/IntraLineLoaderTest.java
index 0cc4b00..f544550 100644
--- a/javatests/com/google/gerrit/server/patch/IntraLineLoaderTest.java
+++ b/javatests/com/google/gerrit/server/patch/IntraLineLoaderTest.java
@@ -15,18 +15,18 @@
package com.google.gerrit.server.patch;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.List;
import org.eclipse.jgit.diff.Edit;
import org.eclipse.jgit.diff.EditList;
import org.eclipse.jgit.diff.ReplaceEdit;
import org.junit.Test;
-public class IntraLineLoaderTest extends GerritBaseTests {
+public class IntraLineLoaderTest {
@Test
public void rewriteAtStartOfLineIsRecognized() throws Exception {
@@ -88,22 +88,30 @@
// TODO: expected failure
// the current code does not work on the first line
// and the insert marker is in the wrong location
- @Test(expected = AssertionError.class)
+ @Test
public void preferInsertAtLineBreak2() throws Exception {
- String a = " abc\n def\n";
- String b = " abc\n def\n";
- assertThat(intraline(a, b))
- .isEqualTo(ref().insert(" ").common(" abc\n").insert(" ").common(" def\n").edits);
+ assertThrows(
+ AssertionError.class,
+ () -> {
+ String a = " abc\n def\n";
+ String b = " abc\n def\n";
+ assertThat(intraline(a, b))
+ .isEqualTo(ref().insert(" ").common(" abc\n").insert(" ").common(" def\n").edits);
+ });
}
// TODO: expected failure
// the current code does not work on the first line
- @Test(expected = AssertionError.class)
+ @Test
public void preferDeleteAtLineBreak() throws Exception {
- String a = " abc\n def\n";
- String b = " abc\n def\n";
- assertThat(intraline(a, b))
- .isEqualTo(ref().remove(" ").common(" abc\n").remove(" ").common(" def\n").edits);
+ assertThrows(
+ AssertionError.class,
+ () -> {
+ String a = " abc\n def\n";
+ String b = " abc\n def\n";
+ assertThat(intraline(a, b))
+ .isEqualTo(ref().remove(" ").common(" abc\n").remove(" ").common(" def\n").edits);
+ });
}
@Test
diff --git a/javatests/com/google/gerrit/server/patch/PatchListEntryTest.java b/javatests/com/google/gerrit/server/patch/PatchListEntryTest.java
index 4ed5f4b..81f03af 100644
--- a/javatests/com/google/gerrit/server/patch/PatchListEntryTest.java
+++ b/javatests/com/google/gerrit/server/patch/PatchListEntryTest.java
@@ -20,10 +20,9 @@
import static org.junit.Assert.assertTrue;
import com.google.gerrit.reviewdb.client.Patch;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class PatchListEntryTest extends GerritBaseTests {
+public class PatchListEntryTest {
@Test
public void empty1() {
final String name = "empty-file";
diff --git a/javatests/com/google/gerrit/server/patch/PatchListTest.java b/javatests/com/google/gerrit/server/patch/PatchListTest.java
index ccdd040..6fbafb6 100644
--- a/javatests/com/google/gerrit/server/patch/PatchListTest.java
+++ b/javatests/com/google/gerrit/server/patch/PatchListTest.java
@@ -17,7 +17,6 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.reviewdb.client.Patch;
-import com.google.gerrit.testing.GerritBaseTests;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
@@ -26,7 +25,7 @@
import java.util.Arrays;
import org.junit.Test;
-public class PatchListTest extends GerritBaseTests {
+public class PatchListTest {
@Test
public void fileOrder() {
String[] names = {
diff --git a/javatests/com/google/gerrit/server/permissions/DefaultPermissionsMappingTest.java b/javatests/com/google/gerrit/server/permissions/DefaultPermissionsMappingTest.java
index ff9ac41..305e81b 100644
--- a/javatests/com/google/gerrit/server/permissions/DefaultPermissionsMappingTest.java
+++ b/javatests/com/google/gerrit/server/permissions/DefaultPermissionsMappingTest.java
@@ -18,10 +18,9 @@
import static com.google.gerrit.server.permissions.DefaultPermissionMappings.refPermission;
import com.google.gerrit.common.data.Permission;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class DefaultPermissionsMappingTest extends GerritBaseTests {
+public class DefaultPermissionsMappingTest {
@Test
public void stringToRefPermission() {
assertThat(refPermission("doesnotexist")).isEmpty();
diff --git a/javatests/com/google/gerrit/server/permissions/RefControlTest.java b/javatests/com/google/gerrit/server/permissions/RefControlTest.java
index 0c40d4e..c3b50d8 100644
--- a/javatests/com/google/gerrit/server/permissions/RefControlTest.java
+++ b/javatests/com/google/gerrit/server/permissions/RefControlTest.java
@@ -16,79 +16,66 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.block;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.blockLabel;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.deny;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.labelPermissionKey;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.permissionKey;
import static com.google.gerrit.common.data.Permission.EDIT_TOPIC_NAME;
import static com.google.gerrit.common.data.Permission.LABEL;
import static com.google.gerrit.common.data.Permission.OWNER;
import static com.google.gerrit.common.data.Permission.PUSH;
import static com.google.gerrit.common.data.Permission.READ;
import static com.google.gerrit.common.data.Permission.SUBMIT;
+import static com.google.gerrit.reviewdb.client.RefNames.REFS_CONFIG;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
import static com.google.gerrit.server.group.SystemGroupBackend.CHANGE_OWNER;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
-import static com.google.gerrit.server.project.testing.Util.ADMIN;
-import static com.google.gerrit.server.project.testing.Util.DEVS;
-import static com.google.gerrit.server.project.testing.Util.allow;
-import static com.google.gerrit.server.project.testing.Util.allowExclusive;
-import static com.google.gerrit.server.project.testing.Util.block;
-import static com.google.gerrit.server.project.testing.Util.deny;
-import static com.google.gerrit.server.project.testing.Util.doNotInherit;
-import static com.google.gerrit.testing.InMemoryRepositoryManager.newRepository;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Lists;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.PermissionRange;
-import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.exceptions.InvalidNameException;
-import com.google.gerrit.extensions.api.projects.CommentLinkInfo;
-import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.account.CapabilityCollection;
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.AllProjectsNameProvider;
-import com.google.gerrit.server.config.AllUsersName;
-import com.google.gerrit.server.config.AllUsersNameProvider;
-import com.google.gerrit.server.git.TransferConfig;
+import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.index.SingleVersionModule.SingleVersionListener;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.ProjectConfig;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.project.RefPattern;
-import com.google.gerrit.server.project.testing.Util;
+import com.google.gerrit.server.project.testing.TestLabels;
import com.google.gerrit.server.schema.SchemaCreator;
import com.google.gerrit.server.util.ThreadLocalRequestContext;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.InMemoryModule;
import com.google.gerrit.testing.InMemoryRepositoryManager;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
-import java.io.IOException;
import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
import java.util.Optional;
-import java.util.Set;
-import org.eclipse.jgit.errors.ConfigInvalidException;
-import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
+import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Repository;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-public class RefControlTest extends GerritBaseTests {
- private void assertAdminsAreOwnersAndDevsAreNot() {
- ProjectControl uBlah = user(local, DEVS);
- ProjectControl uAdmin = user(local, DEVS, ADMIN);
+public class RefControlTest {
+ private static final AccountGroup.UUID ADMIN = AccountGroup.uuid("test.admin");
+ private static final AccountGroup.UUID DEVS = AccountGroup.uuid("test.devs");
+
+ private void assertAdminsAreOwnersAndDevsAreNot() throws Exception {
+ ProjectControl uBlah = user(localKey, DEVS);
+ ProjectControl uAdmin = user(localKey, DEVS, ADMIN);
assertWithMessage("not owner").that(uBlah.isOwner()).isFalse();
assertWithMessage("is owner").that(uAdmin.isOwner()).isTrue();
@@ -178,106 +165,29 @@
assertWithMessage("cannot vote " + score).that(range.contains(score)).isFalse();
}
- private final AllProjectsName allProjectsName =
- new AllProjectsName(AllProjectsNameProvider.DEFAULT);
- private final AllUsersName allUsersName = new AllUsersName(AllUsersNameProvider.DEFAULT);
private final AccountGroup.UUID fixers = AccountGroup.uuid("test.fixers");
- private final Map<Project.NameKey, ProjectState> all = new HashMap<>();
- private Project.NameKey localKey = Project.nameKey("local");
- private ProjectConfig local;
- private Project.NameKey parentKey = Project.nameKey("parent");
- private ProjectConfig parent;
- private InMemoryRepositoryManager repoManager;
- private ProjectCache projectCache;
- private PermissionCollection.Factory sectionSorter;
- private ChangeControl.Factory changeControlFactory;
+ private final Project.NameKey localKey = Project.nameKey("local");
+ private final Project.NameKey parentKey = Project.nameKey("parent");
- @Inject private PermissionBackend permissionBackend;
- @Inject private CapabilityCollection.Factory capabilityCollectionFactory;
+ @Inject private AllProjectsName allProjectsName;
+ @Inject private InMemoryRepositoryManager repoManager;
+ @Inject private MetaDataUpdate.Server metaDataUpdateFactory;
+ @Inject private ProjectCache projectCache;
+ @Inject private ProjectControl.Factory projectControlFactory;
+ @Inject private ProjectOperations projectOperations;
@Inject private SchemaCreator schemaCreator;
@Inject private SingleVersionListener singleVersionListener;
@Inject private ThreadLocalRequestContext requestContext;
- @Inject private DefaultRefFilter.Factory refFilterFactory;
- @Inject private TransferConfig transferConfig;
- @Inject private MetricMaker metricMaker;
- @Inject private ProjectConfig.Factory projectConfigFactory;
@Before
public void setUp() throws Exception {
- repoManager = new InMemoryRepositoryManager();
- projectCache =
- new ProjectCache() {
- @Override
- public ProjectState getAllProjects() {
- return get(allProjectsName);
- }
-
- @Override
- public ProjectState getAllUsers() {
- return null;
- }
-
- @Override
- public ProjectState get(Project.NameKey projectName) {
- return all.get(projectName);
- }
-
- @Override
- public void evict(Project p) {}
-
- @Override
- public void remove(Project p) {}
-
- @Override
- public void remove(Project.NameKey name) {}
-
- @Override
- public ImmutableSortedSet<Project.NameKey> all() {
- return ImmutableSortedSet.of();
- }
-
- @Override
- public ImmutableSortedSet<Project.NameKey> byName(String prefix) {
- return ImmutableSortedSet.of();
- }
-
- @Override
- public void onCreateProject(Project.NameKey newProjectName) {}
-
- @Override
- public Set<AccountGroup.UUID> guessRelevantGroupUUIDs() {
- return Collections.emptySet();
- }
-
- @Override
- public ProjectState checkedGet(Project.NameKey projectName) throws IOException {
- return all.get(projectName);
- }
-
- @Override
- public void evict(Project.NameKey p) {}
-
- @Override
- public ProjectState checkedGet(Project.NameKey projectName, boolean strict)
- throws Exception {
- return all.get(projectName);
- }
- };
-
Injector injector = Guice.createInjector(new InMemoryModule());
injector.injectMembers(this);
- try {
- Repository repo = repoManager.createRepository(allProjectsName);
- ProjectConfig allProjects =
- projectConfigFactory.create(Project.nameKey(allProjectsName.get()));
- allProjects.load(repo);
- LabelType cr = Util.codeReview();
- allProjects.getLabelSections().put(cr.getName(), cr);
- add(allProjects);
- } catch (IOException | ConfigInvalidException e) {
- throw new RuntimeException(e);
- }
+ // Tests previously used ProjectConfig.Factory to create ProjectConfigs without going through
+ // the ProjectCache, which was wrong. Manually call getInstance so we don't store it in a
+ // field that is accessible to test methods.
+ ProjectConfig.Factory projectConfigFactory = injector.getInstance(ProjectConfig.Factory.class);
singleVersionListener.start();
try {
@@ -286,58 +196,80 @@
singleVersionListener.stop();
}
- Cache<SectionSortCache.EntryKey, SectionSortCache.EntryVal> c =
- CacheBuilder.newBuilder().build();
- sectionSorter = new PermissionCollection.Factory(new SectionSortCache(c), metricMaker);
+ // Clear out All-Projects and use the lowest-level API possible for project creation, so the
+ // only ACL entries are exactly what is initialized by this test, and we aren't subject to
+ // changing defaults in SchemaCreator or ProjectCreator.
+ try (Repository allProjectsRepo = repoManager.createRepository(allProjectsName);
+ TestRepository<Repository> tr = new TestRepository<>(allProjectsRepo)) {
+ tr.delete(REFS_CONFIG);
+ try (MetaDataUpdate md = metaDataUpdateFactory.create(allProjectsName)) {
+ ProjectConfig allProjectsConfig = projectConfigFactory.create(allProjectsName);
+ allProjectsConfig.load(md);
+ LabelType cr = TestLabels.codeReview();
+ allProjectsConfig.getLabelSections().put(cr.getName(), cr);
+ allProjectsConfig.commit(md);
+ }
+ }
- parent = projectConfigFactory.create(parentKey);
- parent.load(newRepository(parentKey));
- add(parent);
-
- local = projectConfigFactory.create(localKey);
- local.load(newRepository(localKey));
- add(local);
- local.getProject().setParentName(parentKey);
+ repoManager.createRepository(parentKey).close();
+ repoManager.createRepository(localKey).close();
+ try (MetaDataUpdate md = metaDataUpdateFactory.create(localKey)) {
+ ProjectConfig newLocal = projectConfigFactory.create(localKey);
+ newLocal.load(md);
+ newLocal.getProject().setParentName(parentKey);
+ newLocal.commit(md);
+ }
requestContext.setContext(() -> null);
-
- changeControlFactory = injector.getInstance(ChangeControl.Factory.class);
}
@After
- public void tearDown() {
+ public void tearDown() throws Exception {
requestContext.setContext(null);
}
@Test
- public void ownerProject() {
- allow(local, OWNER, ADMIN, "refs/*");
-
+ public void ownerProject() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(OWNER).ref("refs/*").group(ADMIN))
+ .update();
assertAdminsAreOwnersAndDevsAreNot();
}
@Test
- public void denyOwnerProject() {
- allow(local, OWNER, ADMIN, "refs/*");
- deny(local, OWNER, DEVS, "refs/*");
-
+ public void denyOwnerProject() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(OWNER).ref("refs/*").group(ADMIN))
+ .add(deny(OWNER).ref("refs/*").group(DEVS))
+ .update();
assertAdminsAreOwnersAndDevsAreNot();
}
@Test
- public void blockOwnerProject() {
- allow(local, OWNER, ADMIN, "refs/*");
- block(local, OWNER, DEVS, "refs/*");
-
+ public void blockOwnerProject() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(OWNER).ref("refs/*").group(ADMIN))
+ .add(block(OWNER).ref("refs/*").group(DEVS))
+ .update();
assertAdminsAreOwnersAndDevsAreNot();
}
@Test
- public void branchDelegation1() {
- allow(local, OWNER, ADMIN, "refs/*");
- allow(local, OWNER, DEVS, "refs/heads/x/*");
+ public void branchDelegation1() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(OWNER).ref("refs/*").group(ADMIN))
+ .add(allow(OWNER).ref("refs/heads/x/*").group(DEVS))
+ .update();
- ProjectControl uDev = user(local, DEVS);
+ ProjectControl uDev = user(localKey, DEVS);
assertNotOwner(uDev);
assertOwner("refs/heads/x/*", uDev);
@@ -349,13 +281,17 @@
}
@Test
- public void branchDelegation2() {
- allow(local, OWNER, ADMIN, "refs/*");
- allow(local, OWNER, DEVS, "refs/heads/x/*");
- allow(local, OWNER, fixers, "refs/heads/x/y/*");
- doNotInherit(local, OWNER, "refs/heads/x/y/*");
+ public void branchDelegation2() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(OWNER).ref("refs/*").group(ADMIN))
+ .add(allow(OWNER).ref("refs/heads/x/*").group(DEVS))
+ .add(allow(OWNER).ref("refs/heads/x/y/*").group(fixers))
+ .setExclusiveGroup(permissionKey(OWNER).ref("refs/heads/x/y/*"), true)
+ .update();
- ProjectControl uDev = user(local, DEVS);
+ ProjectControl uDev = user(localKey, DEVS);
assertNotOwner(uDev);
assertOwner("refs/heads/x/*", uDev);
@@ -364,7 +300,7 @@
assertNotOwner("refs/*", uDev);
assertNotOwner("refs/heads/master", uDev);
- ProjectControl uFix = user(local, fixers);
+ ProjectControl uFix = user(localKey, fixers);
assertNotOwner(uFix);
assertOwner("refs/heads/x/y/*", uFix);
@@ -376,38 +312,62 @@
}
@Test
- public void inheritRead_SingleBranchDeniesUpload() {
- allow(parent, READ, REGISTERED_USERS, "refs/*");
- allow(parent, PUSH, REGISTERED_USERS, "refs/for/refs/*");
- allow(local, READ, REGISTERED_USERS, "refs/heads/foobar");
- doNotInherit(local, READ, "refs/heads/foobar");
- doNotInherit(local, PUSH, "refs/for/refs/heads/foobar");
+ public void inheritRead_SingleBranchDeniesUpload() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(allow(READ).ref("refs/*").group(REGISTERED_USERS))
+ .add(allow(PUSH).ref("refs/for/refs/*").group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(READ).ref("refs/heads/foobar").group(REGISTERED_USERS))
+ .setExclusiveGroup(permissionKey(READ).ref("refs/heads/foobar"), true)
+ .setExclusiveGroup(permissionKey(PUSH).ref("refs/for/refs/heads/foobar"), true)
+ .update();
- ProjectControl u = user(local);
+ ProjectControl u = user(localKey);
assertCanUpload(u);
assertCreateChange("refs/heads/master", u);
assertCannotCreateChange("refs/heads/foobar", u);
}
@Test
- public void blockPushDrafts() {
- allow(parent, PUSH, REGISTERED_USERS, "refs/for/refs/*");
- block(parent, PUSH, ANONYMOUS_USERS, "refs/drafts/*");
- allow(local, PUSH, REGISTERED_USERS, "refs/drafts/*");
+ public void blockPushDrafts() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(allow(PUSH).ref("refs/for/refs/*").group(REGISTERED_USERS))
+ .add(block(PUSH).ref("refs/drafts/*").group(ANONYMOUS_USERS))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(PUSH).ref("refs/drafts/*").group(REGISTERED_USERS))
+ .update();
- ProjectControl u = user(local);
+ ProjectControl u = user(localKey);
assertCreateChange("refs/heads/master", u);
assertThat(u.controlForRef("refs/drafts/master").canPerform(PUSH)).isFalse();
}
@Test
- public void blockPushDraftsUnblockAdmin() {
- block(parent, PUSH, ANONYMOUS_USERS, "refs/drafts/*");
- allow(parent, PUSH, ADMIN, "refs/drafts/*");
- allow(local, PUSH, REGISTERED_USERS, "refs/drafts/*");
+ public void blockPushDraftsUnblockAdmin() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/drafts/*").group(ANONYMOUS_USERS))
+ .add(allow(PUSH).ref("refs/drafts/*").group(ADMIN))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(PUSH).ref("refs/drafts/*").group(REGISTERED_USERS))
+ .update();
- ProjectControl u = user(local);
- ProjectControl a = user(local, "a", ADMIN);
+ ProjectControl u = user(localKey);
+ ProjectControl a = user(localKey, "a", ADMIN);
assertWithMessage("push is allowed")
.that(a.controlForRef("refs/drafts/master").canPerform(PUSH))
@@ -418,12 +378,20 @@
}
@Test
- public void inheritRead_SingleBranchDoesNotOverrideInherited() {
- allow(parent, READ, REGISTERED_USERS, "refs/*");
- allow(parent, PUSH, REGISTERED_USERS, "refs/for/refs/*");
- allow(local, READ, REGISTERED_USERS, "refs/heads/foobar");
+ public void inheritRead_SingleBranchDoesNotOverrideInherited() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(allow(READ).ref("refs/*").group(REGISTERED_USERS))
+ .add(allow(PUSH).ref("refs/for/refs/*").group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(READ).ref("refs/heads/foobar").group(REGISTERED_USERS))
+ .update();
- ProjectControl u = user(local);
+ ProjectControl u = user(localKey);
assertCanUpload(u);
assertCreateChange("refs/heads/master", u);
assertCreateChange("refs/heads/foobar", u);
@@ -431,31 +399,50 @@
@Test
public void inheritDuplicateSections() throws Exception {
- allow(parent, READ, ADMIN, "refs/*");
- allow(local, READ, DEVS, "refs/heads/*");
- assertCanAccess(user(local, "a", ADMIN));
-
- local = projectConfigFactory.create(localKey);
- local.load(newRepository(localKey));
- local.getProject().setParentName(parentKey);
- allow(local, READ, DEVS, "refs/*");
- assertCanAccess(user(local, "d", DEVS));
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(allow(READ).ref("refs/*").group(ADMIN))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(READ).ref("refs/*").group(DEVS))
+ .update();
+ assertCanAccess(user(localKey, "a", ADMIN));
+ assertCanAccess(user(localKey, "d", DEVS));
}
@Test
- public void inheritRead_OverrideWithDeny() {
- allow(parent, READ, REGISTERED_USERS, "refs/*");
- deny(local, READ, REGISTERED_USERS, "refs/*");
+ public void inheritRead_OverrideWithDeny() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(allow(READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(deny(READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
- assertAccessDenied(user(local));
+ assertAccessDenied(user(localKey));
}
@Test
- public void inheritRead_AppendWithDenyOfRef() {
- allow(parent, READ, REGISTERED_USERS, "refs/*");
- deny(local, READ, REGISTERED_USERS, "refs/heads/*");
+ public void inheritRead_AppendWithDenyOfRef() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(allow(READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(deny(READ).ref("refs/heads/*").group(REGISTERED_USERS))
+ .update();
- ProjectControl u = user(local);
+ ProjectControl u = user(localKey);
assertCanAccess(u);
assertCanRead("refs/master", u);
assertCanRead("refs/tags/foobar", u);
@@ -463,12 +450,20 @@
}
@Test
- public void inheritRead_OverridesAndDeniesOfRef() {
- allow(parent, READ, REGISTERED_USERS, "refs/*");
- deny(local, READ, REGISTERED_USERS, "refs/*");
- allow(local, READ, REGISTERED_USERS, "refs/heads/*");
+ public void inheritRead_OverridesAndDeniesOfRef() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(allow(READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(deny(READ).ref("refs/*").group(REGISTERED_USERS))
+ .add(allow(READ).ref("refs/heads/*").group(REGISTERED_USERS))
+ .update();
- ProjectControl u = user(local);
+ ProjectControl u = user(localKey);
assertCanAccess(u);
assertCannotRead("refs/foobar", u);
assertCannotRead("refs/tags/foobar", u);
@@ -476,100 +471,164 @@
}
@Test
- public void inheritSubmit_OverridesAndDeniesOfRef() {
- allow(parent, SUBMIT, REGISTERED_USERS, "refs/*");
- deny(local, SUBMIT, REGISTERED_USERS, "refs/*");
- allow(local, SUBMIT, REGISTERED_USERS, "refs/heads/*");
+ public void inheritSubmit_OverridesAndDeniesOfRef() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(allow(SUBMIT).ref("refs/*").group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(deny(SUBMIT).ref("refs/*").group(REGISTERED_USERS))
+ .add(allow(SUBMIT).ref("refs/heads/*").group(REGISTERED_USERS))
+ .update();
- ProjectControl u = user(local);
+ ProjectControl u = user(localKey);
assertCannotSubmit("refs/foobar", u);
assertCannotSubmit("refs/tags/foobar", u);
assertCanSubmit("refs/heads/foobar", u);
}
@Test
- public void cannotUploadToAnyRef() {
- allow(parent, READ, REGISTERED_USERS, "refs/*");
- allow(local, READ, DEVS, "refs/heads/*");
- allow(local, PUSH, DEVS, "refs/for/refs/heads/*");
+ public void cannotUploadToAnyRef() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(allow(READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(READ).ref("refs/heads/*").group(DEVS))
+ .add(allow(PUSH).ref("refs/for/refs/heads/*").group(DEVS))
+ .update();
- ProjectControl u = user(local);
+ ProjectControl u = user(localKey);
assertCannotUpload(u);
assertCannotCreateChange("refs/heads/master", u);
}
@Test
- public void usernamePatternCanUploadToAnyRef() {
- allow(local, PUSH, REGISTERED_USERS, "refs/heads/users/${username}/*");
- ProjectControl u = user(local, "a-registered-user");
+ public void usernamePatternCanUploadToAnyRef() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(PUSH).ref("refs/heads/users/${username}/*").group(REGISTERED_USERS))
+ .update();
+ ProjectControl u = user(localKey, "a-registered-user");
assertCanUpload(u);
}
@Test
- public void usernamePatternNonRegex() {
- allow(local, READ, DEVS, "refs/sb/${username}/heads/*");
+ public void usernamePatternNonRegex() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(READ).ref("refs/sb/${username}/heads/*").group(DEVS))
+ .update();
- ProjectControl u = user(local, "u", DEVS);
- ProjectControl d = user(local, "d", DEVS);
+ ProjectControl u = user(localKey, "u", DEVS);
+ ProjectControl d = user(localKey, "d", DEVS);
assertCannotRead("refs/sb/d/heads/foobar", u);
assertCanRead("refs/sb/d/heads/foobar", d);
}
@Test
- public void usernamePatternWithRegex() {
- allow(local, READ, DEVS, "^refs/sb/${username}/heads/.*");
+ public void usernamePatternWithRegex() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(READ).ref("^refs/sb/${username}/heads/.*").group(DEVS))
+ .update();
- ProjectControl u = user(local, "d.v", DEVS);
- ProjectControl d = user(local, "dev", DEVS);
+ ProjectControl u = user(localKey, "d.v", DEVS);
+ ProjectControl d = user(localKey, "dev", DEVS);
assertCannotRead("refs/sb/dev/heads/foobar", u);
assertCanRead("refs/sb/dev/heads/foobar", d);
}
@Test
- public void usernameEmailPatternWithRegex() {
- allow(local, READ, DEVS, "^refs/sb/${username}/heads/.*");
+ public void usernameEmailPatternWithRegex() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(READ).ref("^refs/sb/${username}/heads/.*").group(DEVS))
+ .update();
- ProjectControl u = user(local, "d.v@ger-rit.org", DEVS);
- ProjectControl d = user(local, "dev@ger-rit.org", DEVS);
+ ProjectControl u = user(localKey, "d.v@ger-rit.org", DEVS);
+ ProjectControl d = user(localKey, "dev@ger-rit.org", DEVS);
assertCannotRead("refs/sb/dev@ger-rit.org/heads/foobar", u);
assertCanRead("refs/sb/dev@ger-rit.org/heads/foobar", d);
}
@Test
- public void sortWithRegex() {
- allow(local, READ, DEVS, "^refs/heads/.*");
- allow(parent, READ, ANONYMOUS_USERS, "^refs/heads/.*-QA-.*");
+ public void sortWithRegex() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(READ).ref("^refs/heads/.*").group(DEVS))
+ .update();
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(allow(READ).ref("^refs/heads/.*-QA-.*").group(ANONYMOUS_USERS))
+ .update();
- ProjectControl u = user(local, DEVS);
- ProjectControl d = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
+ ProjectControl d = user(localKey, DEVS);
assertCanRead("refs/heads/foo-QA-bar", u);
assertCanRead("refs/heads/foo-QA-bar", d);
}
@Test
- public void blockRule_ParentBlocksChild() {
- allow(local, PUSH, DEVS, "refs/tags/*");
- block(parent, PUSH, ANONYMOUS_USERS, "refs/tags/*");
- ProjectControl u = user(local, DEVS);
+ public void blockRule_ParentBlocksChild() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(PUSH).ref("refs/tags/*").group(DEVS))
+ .update();
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/tags/*").group(ANONYMOUS_USERS))
+ .update();
+ ProjectControl u = user(localKey, DEVS);
assertCannotUpdate("refs/tags/V10", u);
}
@Test
- public void blockRule_ParentBlocksChildEvenIfAlreadyBlockedInChild() {
- allow(local, PUSH, DEVS, "refs/tags/*");
- block(local, PUSH, ANONYMOUS_USERS, "refs/tags/*");
- block(parent, PUSH, ANONYMOUS_USERS, "refs/tags/*");
+ public void blockRule_ParentBlocksChildEvenIfAlreadyBlockedInChild() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(PUSH).ref("refs/tags/*").group(DEVS))
+ .add(block(PUSH).ref("refs/tags/*").group(ANONYMOUS_USERS))
+ .update();
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/tags/*").group(ANONYMOUS_USERS))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
assertCannotUpdate("refs/tags/V10", u);
}
@Test
- public void blockLabelRange_ParentBlocksChild() {
- allow(local, LABEL + "Code-Review", -2, +2, DEVS, "refs/heads/*");
- block(parent, LABEL + "Code-Review", -2, +2, DEVS, "refs/heads/*");
+ public void blockLabelRange_ParentBlocksChild() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(DEVS).range(-2, +2))
+ .update();
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(blockLabel("Code-Review").ref("refs/heads/*").group(DEVS).range(-2, +2))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
PermissionRange range = u.controlForRef("refs/heads/master").getRange(LABEL + "Code-Review");
assertCanVote(-1, range);
@@ -579,12 +638,20 @@
}
@Test
- public void blockLabelRange_ParentBlocksChildEvenIfAlreadyBlockedInChild() {
- allow(local, LABEL + "Code-Review", -2, +2, DEVS, "refs/heads/*");
- block(local, LABEL + "Code-Review", -2, +2, DEVS, "refs/heads/*");
- block(parent, LABEL + "Code-Review", -2, +2, DEVS, "refs/heads/*");
+ public void blockLabelRange_ParentBlocksChildEvenIfAlreadyBlockedInChild() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(DEVS).range(-2, +2))
+ .add(blockLabel("Code-Review").ref("refs/heads/*").group(DEVS).range(-2, +2))
+ .update();
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(blockLabel("Code-Review").ref("refs/heads/*").group(DEVS).range(-2, +2))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
PermissionRange range = u.controlForRef("refs/heads/master").getRange(LABEL + "Code-Review");
assertCanVote(-1, range);
@@ -594,251 +661,396 @@
}
@Test
- public void inheritSubmit_AllowInChildDoesntAffectUnblockInParent() {
- block(parent, SUBMIT, ANONYMOUS_USERS, "refs/heads/*");
- allow(parent, SUBMIT, REGISTERED_USERS, "refs/heads/*");
- allow(local, SUBMIT, REGISTERED_USERS, "refs/heads/*");
+ public void inheritSubmit_AllowInChildDoesntAffectUnblockInParent() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(block(SUBMIT).ref("refs/heads/*").group(ANONYMOUS_USERS))
+ .add(allow(SUBMIT).ref("refs/heads/*").group(REGISTERED_USERS))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(SUBMIT).ref("refs/heads/*").group(REGISTERED_USERS))
+ .update();
- ProjectControl u = user(local);
+ ProjectControl u = user(localKey);
assertWithMessage("submit is allowed")
.that(u.controlForRef("refs/heads/master").canPerform(SUBMIT))
.isTrue();
}
@Test
- public void unblockNoForce() {
- block(local, PUSH, ANONYMOUS_USERS, "refs/heads/*");
- allow(local, PUSH, DEVS, "refs/heads/*");
+ public void unblockNoForce() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS))
+ .add(allow(PUSH).ref("refs/heads/*").group(DEVS))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
assertCanUpdate("refs/heads/master", u);
}
@Test
- public void unblockForce() {
- PermissionRule r = block(local, PUSH, ANONYMOUS_USERS, "refs/heads/*");
- r.setForce(true);
- allow(local, PUSH, DEVS, "refs/heads/*").setForce(true);
+ public void unblockForce() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS).force(true))
+ .add(allow(PUSH).ref("refs/heads/*").group(DEVS).force(true))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
assertCanForceUpdate("refs/heads/master", u);
}
@Test
- public void unblockRead_NotPossible() {
- block(parent, READ, ANONYMOUS_USERS, "refs/*");
- allow(parent, READ, ADMIN, "refs/*");
- allow(local, READ, ANONYMOUS_USERS, "refs/*");
- allow(local, READ, ADMIN, "refs/*");
- ProjectControl u = user(local);
+ public void unblockRead_NotPossible() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(block(READ).ref("refs/*").group(ANONYMOUS_USERS))
+ .add(allow(READ).ref("refs/*").group(ADMIN))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(READ).ref("refs/*").group(ANONYMOUS_USERS))
+ .add(allow(READ).ref("refs/*").group(ADMIN))
+ .update();
+
+ ProjectControl u = user(localKey);
assertCannotRead("refs/heads/master", u);
}
@Test
- public void unblockForceWithAllowNoForce_NotPossible() {
- PermissionRule r = block(local, PUSH, ANONYMOUS_USERS, "refs/heads/*");
- r.setForce(true);
- allow(local, PUSH, DEVS, "refs/heads/*");
+ public void unblockForceWithAllowNoForce_NotPossible() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS).force(true))
+ .add(allow(PUSH).ref("refs/heads/*").group(DEVS))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
assertCannotForceUpdate("refs/heads/master", u);
}
@Test
- public void unblockMoreSpecificRef_Fails() {
- block(local, PUSH, ANONYMOUS_USERS, "refs/heads/*");
- allow(local, PUSH, DEVS, "refs/heads/master");
+ public void unblockMoreSpecificRef_Fails() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS))
+ .add(allow(PUSH).ref("refs/heads/master").group(DEVS))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
assertCannotUpdate("refs/heads/master", u);
}
@Test
- public void unblockMoreSpecificRefInLocal_Fails() {
- block(parent, PUSH, ANONYMOUS_USERS, "refs/heads/*");
- allow(local, PUSH, DEVS, "refs/heads/master");
+ public void unblockMoreSpecificRefInLocal_Fails() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(PUSH).ref("refs/heads/master").group(DEVS))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
assertCannotUpdate("refs/heads/master", u);
}
@Test
- public void unblockMoreSpecificRefWithExclusiveFlag() {
- block(local, PUSH, ANONYMOUS_USERS, "refs/heads/*");
- allow(local, PUSH, DEVS, "refs/heads/master", true);
+ public void unblockMoreSpecificRefWithExclusiveFlag() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS))
+ .add(allow(PUSH).ref("refs/heads/master").group(DEVS))
+ .setExclusiveGroup(permissionKey(PUSH).ref("refs/heads/master"), true)
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
assertCanUpdate("refs/heads/master", u);
}
@Test
- public void unblockVoteMoreSpecificRefWithExclusiveFlag() {
- String perm = LABEL + "Code-Review";
+ public void unblockVoteMoreSpecificRefWithExclusiveFlag() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(blockLabel("Code-Review").ref("refs/heads/*").group(ANONYMOUS_USERS).range(-1, 1))
+ .add(allowLabel("Code-Review").ref("refs/heads/master").group(DEVS).range(-2, 2))
+ .setExclusiveGroup(labelPermissionKey("Code-Review").ref("refs/heads/master"), true)
+ .update();
- block(local, perm, -1, 1, ANONYMOUS_USERS, "refs/heads/*");
- allowExclusive(local, perm, -2, 2, DEVS, "refs/heads/master");
-
- ProjectControl u = user(local, DEVS);
- PermissionRange range = u.controlForRef("refs/heads/master").getRange(perm);
+ ProjectControl u = user(localKey, DEVS);
+ PermissionRange range = u.controlForRef("refs/heads/master").getRange(LABEL + "Code-Review");
assertCanVote(-2, range);
}
@Test
- public void unblockFromParentDoesNotAffectChild() {
- allow(parent, PUSH, DEVS, "refs/heads/master", true);
- block(local, PUSH, DEVS, "refs/heads/master");
+ public void unblockFromParentDoesNotAffectChild() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(allow(PUSH).ref("refs/heads/master").group(DEVS))
+ .setExclusiveGroup(permissionKey(PUSH).ref("refs/heads/master"), true)
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/heads/master").group(DEVS))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
assertCannotUpdate("refs/heads/master", u);
}
@Test
- public void unblockFromParentDoesNotAffectChildDifferentGroups() {
- allow(parent, PUSH, DEVS, "refs/heads/master", true);
- block(local, PUSH, ANONYMOUS_USERS, "refs/heads/master");
+ public void unblockFromParentDoesNotAffectChildDifferentGroups() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(allow(PUSH).ref("refs/heads/master").group(DEVS))
+ .setExclusiveGroup(permissionKey(PUSH).ref("refs/heads/master"), true)
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/heads/master").group(ANONYMOUS_USERS))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
assertCannotUpdate("refs/heads/master", u);
}
@Test
- public void unblockMoreSpecificRefInLocalWithExclusiveFlag_Fails() {
- block(parent, PUSH, ANONYMOUS_USERS, "refs/heads/*");
- allow(local, PUSH, DEVS, "refs/heads/master", true);
+ public void unblockMoreSpecificRefInLocalWithExclusiveFlag_Fails() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(PUSH).ref("refs/heads/master").group(DEVS))
+ .setExclusiveGroup(permissionKey(PUSH).ref("refs/heads/master"), true)
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
assertCannotUpdate("refs/heads/master", u);
}
@Test
- public void blockMoreSpecificRefWithinProject() {
- block(local, PUSH, ANONYMOUS_USERS, "refs/heads/secret");
- allow(local, PUSH, DEVS, "refs/heads/*", true);
+ public void blockMoreSpecificRefWithinProject() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/heads/secret").group(ANONYMOUS_USERS))
+ .add(allow(PUSH).ref("refs/heads/*").group(DEVS))
+ .setExclusiveGroup(permissionKey(PUSH).ref("refs/heads/*"), true)
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
assertCannotUpdate("refs/heads/secret", u);
assertCanUpdate("refs/heads/master", u);
}
@Test
- public void unblockOtherPermissionWithMoreSpecificRefAndExclusiveFlag_Fails() {
- block(local, PUSH, ANONYMOUS_USERS, "refs/heads/*");
- allow(local, PUSH, DEVS, "refs/heads/master");
- allow(local, SUBMIT, DEVS, "refs/heads/master", true);
+ public void unblockOtherPermissionWithMoreSpecificRefAndExclusiveFlag_Fails() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS))
+ .add(allow(PUSH).ref("refs/heads/master").group(DEVS))
+ .add(allow(SUBMIT).ref("refs/heads/master").group(DEVS))
+ .setExclusiveGroup(permissionKey(SUBMIT).ref("refs/heads/master"), true)
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
assertCannotUpdate("refs/heads/master", u);
}
@Test
- public void unblockLargerScope_Fails() {
- block(local, PUSH, ANONYMOUS_USERS, "refs/heads/master");
- allow(local, PUSH, DEVS, "refs/heads/*");
+ public void unblockLargerScope_Fails() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/heads/master").group(ANONYMOUS_USERS))
+ .add(allow(PUSH).ref("refs/heads/*").group(DEVS))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
assertCannotUpdate("refs/heads/master", u);
}
@Test
- public void unblockInLocal_Fails() {
- block(parent, PUSH, ANONYMOUS_USERS, "refs/heads/*");
- allow(local, PUSH, fixers, "refs/heads/*");
+ public void unblockInLocal_Fails() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(PUSH).ref("refs/heads/*").group(fixers))
+ .update();
- ProjectControl f = user(local, fixers);
+ ProjectControl f = user(localKey, fixers);
assertCannotUpdate("refs/heads/master", f);
}
@Test
- public void unblockInParentBlockInLocal() {
- block(parent, PUSH, ANONYMOUS_USERS, "refs/heads/*");
- allow(parent, PUSH, DEVS, "refs/heads/*");
- block(local, PUSH, DEVS, "refs/heads/*");
+ public void unblockInParentBlockInLocal() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/heads/*").group(ANONYMOUS_USERS))
+ .add(allow(PUSH).ref("refs/heads/*").group(DEVS))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(block(PUSH).ref("refs/heads/*").group(DEVS))
+ .update();
- ProjectControl d = user(local, DEVS);
+ ProjectControl d = user(localKey, DEVS);
assertCannotUpdate("refs/heads/master", d);
}
@Test
- public void unblockForceEditTopicName() {
- block(local, EDIT_TOPIC_NAME, ANONYMOUS_USERS, "refs/heads/*");
- allow(local, EDIT_TOPIC_NAME, DEVS, "refs/heads/*").setForce(true);
+ public void unblockForceEditTopicName() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(block(EDIT_TOPIC_NAME).ref("refs/heads/*").group(ANONYMOUS_USERS))
+ .add(allow(EDIT_TOPIC_NAME).ref("refs/heads/*").group(DEVS).force(true))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
assertWithMessage("u can edit topic name")
.that(u.controlForRef("refs/heads/master").canForceEditTopicName())
.isTrue();
}
@Test
- public void unblockInLocalForceEditTopicName_Fails() {
- block(parent, EDIT_TOPIC_NAME, ANONYMOUS_USERS, "refs/heads/*");
- allow(local, EDIT_TOPIC_NAME, DEVS, "refs/heads/*").setForce(true);
+ public void unblockInLocalForceEditTopicName_Fails() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(block(EDIT_TOPIC_NAME).ref("refs/heads/*").group(ANONYMOUS_USERS))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(EDIT_TOPIC_NAME).ref("refs/heads/*").group(DEVS).force(true))
+ .update();
- ProjectControl u = user(local, REGISTERED_USERS);
+ ProjectControl u = user(localKey, REGISTERED_USERS);
assertWithMessage("u can't edit topic name")
.that(u.controlForRef("refs/heads/master").canForceEditTopicName())
.isFalse();
}
@Test
- public void unblockRange() {
- block(local, LABEL + "Code-Review", -1, +1, ANONYMOUS_USERS, "refs/heads/*");
- allow(local, LABEL + "Code-Review", -2, +2, DEVS, "refs/heads/*");
+ public void unblockRange() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(blockLabel("Code-Review").ref("refs/heads/*").group(ANONYMOUS_USERS).range(-1, +1))
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(DEVS).range(-2, +2))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
PermissionRange range = u.controlForRef("refs/heads/master").getRange(LABEL + "Code-Review");
assertCanVote(-2, range);
assertCanVote(2, range);
}
@Test
- public void unblockRangeOnMoreSpecificRef_Fails() {
- block(local, LABEL + "Code-Review", -1, +1, ANONYMOUS_USERS, "refs/heads/*");
- allow(local, LABEL + "Code-Review", -2, +2, DEVS, "refs/heads/master");
+ public void unblockRangeOnMoreSpecificRef_Fails() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(blockLabel("Code-Review").ref("refs/heads/*").group(ANONYMOUS_USERS).range(-1, +1))
+ .add(allowLabel("Code-Review").ref("refs/heads/master").group(DEVS).range(-2, +2))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
PermissionRange range = u.controlForRef("refs/heads/master").getRange(LABEL + "Code-Review");
assertCannotVote(-2, range);
assertCannotVote(2, range);
}
@Test
- public void unblockRangeOnLargerScope_Fails() {
- block(local, LABEL + "Code-Review", -1, +1, ANONYMOUS_USERS, "refs/heads/master");
- allow(local, LABEL + "Code-Review", -2, +2, DEVS, "refs/heads/*");
+ public void unblockRangeOnLargerScope_Fails() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(
+ blockLabel("Code-Review").ref("refs/heads/master").group(ANONYMOUS_USERS).range(-1, +1))
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(DEVS).range(-2, +2))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
PermissionRange range = u.controlForRef("refs/heads/master").getRange(LABEL + "Code-Review");
assertCannotVote(-2, range);
assertCannotVote(2, range);
}
@Test
- public void nonconfiguredCannotVote() {
- allow(local, LABEL + "Code-Review", -2, +2, DEVS, "refs/heads/*");
+ public void nonconfiguredCannotVote() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(DEVS).range(-2, +2))
+ .update();
- ProjectControl u = user(local, REGISTERED_USERS);
+ ProjectControl u = user(localKey, REGISTERED_USERS);
PermissionRange range = u.controlForRef("refs/heads/master").getRange(LABEL + "Code-Review");
assertCannotVote(-1, range);
assertCannotVote(1, range);
}
@Test
- public void unblockInLocalRange_Fails() {
- block(parent, LABEL + "Code-Review", -1, 1, ANONYMOUS_USERS, "refs/heads/*");
- allow(local, LABEL + "Code-Review", -2, +2, DEVS, "refs/heads/*");
+ public void unblockInLocalRange_Fails() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(blockLabel("Code-Review").ref("refs/heads/*").group(ANONYMOUS_USERS).range(-1, 1))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(DEVS).range(-2, +2))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
PermissionRange range = u.controlForRef("refs/heads/master").getRange(LABEL + "Code-Review");
assertCannotVote(-2, range);
assertCannotVote(2, range);
}
@Test
- public void unblockRangeForChangeOwner() {
- allow(local, LABEL + "Code-Review", -2, +2, CHANGE_OWNER, "refs/heads/*");
+ public void unblockRangeForChangeOwner() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(CHANGE_OWNER).range(-2, +2))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
PermissionRange range =
u.controlForRef("refs/heads/master").getRange(LABEL + "Code-Review", true);
assertCanVote(-2, range);
@@ -846,65 +1058,97 @@
}
@Test
- public void unblockRangeForNotChangeOwner() {
- allow(local, LABEL + "Code-Review", -2, +2, CHANGE_OWNER, "refs/heads/*");
+ public void unblockRangeForNotChangeOwner() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(CHANGE_OWNER).range(-2, +2))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
PermissionRange range = u.controlForRef("refs/heads/master").getRange(LABEL + "Code-Review");
assertCannotVote(-2, range);
assertCannotVote(2, range);
}
@Test
- public void blockChangeOwnerVote() {
- block(local, LABEL + "Code-Review", -2, +2, CHANGE_OWNER, "refs/heads/*");
+ public void blockChangeOwnerVote() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(blockLabel("Code-Review").ref("refs/heads/*").group(CHANGE_OWNER).range(-2, +2))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
PermissionRange range = u.controlForRef("refs/heads/master").getRange(LABEL + "Code-Review");
assertCannotVote(-2, range);
assertCannotVote(2, range);
}
@Test
- public void unionOfPermissibleVotes() {
- allow(local, LABEL + "Code-Review", -1, +1, DEVS, "refs/heads/*");
- allow(local, LABEL + "Code-Review", -2, +2, REGISTERED_USERS, "refs/heads/*");
+ public void unionOfPermissibleVotes() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(DEVS).range(-1, +1))
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(REGISTERED_USERS).range(-2, +2))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
PermissionRange range = u.controlForRef("refs/heads/master").getRange(LABEL + "Code-Review");
assertCanVote(-2, range);
assertCanVote(2, range);
}
@Test
- public void unionOfPermissibleVotesPermissionOrder() {
- allow(local, LABEL + "Code-Review", -2, +2, REGISTERED_USERS, "refs/heads/*");
- allow(local, LABEL + "Code-Review", -1, +1, DEVS, "refs/heads/*");
+ public void unionOfPermissibleVotesPermissionOrder() throws Exception {
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(REGISTERED_USERS).range(-2, +2))
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(DEVS).range(-1, +1))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
PermissionRange range = u.controlForRef("refs/heads/master").getRange(LABEL + "Code-Review");
assertCanVote(-2, range);
assertCanVote(2, range);
}
@Test
- public void unionOfBlockedVotes() {
- allow(parent, LABEL + "Code-Review", -1, +1, DEVS, "refs/heads/*");
- block(parent, LABEL + "Code-Review", -2, +2, REGISTERED_USERS, "refs/heads/*");
- block(local, LABEL + "Code-Review", -2, +1, REGISTERED_USERS, "refs/heads/*");
+ public void unionOfBlockedVotes() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(allowLabel("Code-Review").ref("refs/heads/*").group(DEVS).range(-1, +1))
+ .add(blockLabel("Code-Review").ref("refs/heads/*").group(REGISTERED_USERS).range(-2, +2))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(blockLabel("Code-Review").ref("refs/heads/*").group(REGISTERED_USERS).range(-2, +1))
+ .update();
- ProjectControl u = user(local, DEVS);
+ ProjectControl u = user(localKey, DEVS);
PermissionRange range = u.controlForRef("refs/heads/master").getRange(LABEL + "Code-Review");
assertCanVote(-1, range);
assertCannotVote(1, range);
}
@Test
- public void blockOwner() {
- block(parent, OWNER, ANONYMOUS_USERS, "refs/*");
- allow(local, OWNER, DEVS, "refs/*");
+ public void blockOwner() throws Exception {
+ projectOperations
+ .project(parentKey)
+ .forUpdate()
+ .add(block(OWNER).ref("refs/*").group(ANONYMOUS_USERS))
+ .update();
+ projectOperations
+ .project(localKey)
+ .forUpdate()
+ .add(allow(OWNER).ref("refs/*").group(DEVS))
+ .update();
- assertThat(user(local, DEVS).isOwner()).isFalse();
+ assertThat(user(localKey, DEVS).isOwner()).isFalse();
}
@Test
@@ -915,14 +1159,16 @@
RefPattern.validate("refs/heads/review/${username}/*");
}
- @Test(expected = InvalidNameException.class)
+ @Test
public void testValidateBadRefPatternDoubleCaret() throws Exception {
- RefPattern.validate("^^refs/*");
+ assertThrows(InvalidNameException.class, () -> RefPattern.validate("^^refs/*"));
}
- @Test(expected = InvalidNameException.class)
+ @Test
public void testValidateBadRefPatternDanglingCharacter() throws Exception {
- RefPattern.validate("^refs/heads/tmp/sdk/[0-9]{3,3}_R[1-9][A-Z][0-9]{3,3}*");
+ assertThrows(
+ InvalidNameException.class,
+ () -> RefPattern.validate("^refs/heads/tmp/sdk/[0-9]{3,3}_R[1-9][A-Z][0-9]{3,3}*"));
}
@Test
@@ -930,53 +1176,19 @@
RefPattern.validate("^refs/heads/tmp/sdk/[0-9]{3,3}_R[1-9][A-Z][0-9]{3,3}");
}
- private InMemoryRepository add(ProjectConfig pc) {
- List<CommentLinkInfo> commentLinks = null;
-
- InMemoryRepository repo;
- try {
- repo = repoManager.createRepository(pc.getName());
- if (pc.getProject() == null) {
- pc.load(repo);
- }
- } catch (IOException | ConfigInvalidException e) {
- throw new RuntimeException(e);
- }
- all.put(
- pc.getName(),
- new ProjectState(
- projectCache,
- allProjectsName,
- allUsersName,
- repoManager,
- commentLinks,
- capabilityCollectionFactory,
- transferConfig,
- metricMaker,
- pc));
- return repo;
+ private ProjectState getProjectState(Project.NameKey nameKey) throws Exception {
+ return projectCache.checkedGet(nameKey, true);
}
- private ProjectControl user(ProjectConfig local, AccountGroup.UUID... memberOf) {
- return user(local, null, memberOf);
+ private ProjectControl user(Project.NameKey localKey, AccountGroup.UUID... memberOf)
+ throws Exception {
+ return user(localKey, null, memberOf);
}
private ProjectControl user(
- ProjectConfig local, @Nullable String name, AccountGroup.UUID... memberOf) {
- return new ProjectControl(
- Collections.emptySet(),
- Collections.emptySet(),
- sectionSorter,
- changeControlFactory,
- permissionBackend,
- refFilterFactory,
- new MockUser(name, memberOf),
- newProjectState(local));
- }
-
- private ProjectState newProjectState(ProjectConfig local) {
- add(local);
- return all.get(local.getProject().getNameKey());
+ Project.NameKey localKey, @Nullable String name, AccountGroup.UUID... memberOf)
+ throws Exception {
+ return projectControlFactory.create(new MockUser(name, memberOf), getProjectState(localKey));
}
private static class MockUser extends CurrentUser {
diff --git a/javatests/com/google/gerrit/server/project/CommitsCollectionTest.java b/javatests/com/google/gerrit/server/project/CommitsCollectionTest.java
index e002d12..12c0838 100644
--- a/javatests/com/google/gerrit/server/project/CommitsCollectionTest.java
+++ b/javatests/com/google/gerrit/server/project/CommitsCollectionTest.java
@@ -14,12 +14,18 @@
package com.google.gerrit.server.project;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.deny;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.permissionKey;
import static com.google.gerrit.common.data.Permission.READ;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
+import static org.eclipse.jgit.lib.Constants.R_REFS;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import com.google.common.collect.ImmutableList;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
+import com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.common.data.GroupReference;
@@ -32,9 +38,7 @@
import com.google.gerrit.server.account.AuthRequest;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
-import com.google.gerrit.server.project.testing.Util;
import com.google.gerrit.server.restapi.project.CommitsCollection;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.InMemoryRepositoryManager;
import com.google.gerrit.testing.InMemoryTestEnvironment;
import com.google.inject.Inject;
@@ -44,12 +48,13 @@
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
+import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
/** Unit tests for {@link CommitsCollection}. */
-public class CommitsCollectionTest extends GerritBaseTests {
+public class CommitsCollectionTest {
@Rule public InMemoryTestEnvironment testEnvironment = new InMemoryTestEnvironment();
@Inject private AccountManager accountManager;
@@ -58,10 +63,10 @@
@Inject protected MetaDataUpdate.Server metaDataUpdateFactory;
@Inject protected AllProjectsName allProjects;
@Inject private CommitsCollection commits;
- @Inject private ProjectConfig.Factory projectConfigFactory;
+ @Inject private ProjectOperations projectOperations;
private TestRepository<InMemoryRepository> repo;
- private ProjectConfig project;
+ private Project.NameKey project;
@Before
public void setUp() throws Exception {
@@ -69,17 +74,22 @@
Account.Id user = accountManager.authenticate(AuthRequest.forUser("user")).getAccountId();
testEnvironment.setApiUser(user);
+ project = projectOperations.newProject().create();
+ repo = new TestRepository<>(repoManager.openRepository(project));
+ }
- Project.NameKey name = Project.nameKey("project");
- InMemoryRepository inMemoryRepo = repoManager.createRepository(name);
- project = projectConfigFactory.create(name);
- project.load(inMemoryRepo);
- repo = new TestRepository<>(inMemoryRepo);
+ @After
+ public void tearDown() {
+ repo.getRepository().close();
}
@Test
public void canReadCommitWhenAllRefsVisible() throws Exception {
- allow(project, READ, REGISTERED_USERS, "refs/*");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
ObjectId id = repo.branch("master").commit().create();
ProjectState state = readProjectState();
RevWalk rw = repo.getRevWalk();
@@ -90,8 +100,12 @@
@Test
public void canReadCommitIfTwoRefsVisible() throws Exception {
- allow(project, READ, REGISTERED_USERS, "refs/heads/branch1");
- allow(project, READ, REGISTERED_USERS, "refs/heads/branch2");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(READ).ref("refs/heads/branch1").group(REGISTERED_USERS))
+ .add(allow(READ).ref("refs/heads/branch2").group(REGISTERED_USERS))
+ .update();
ObjectId id1 = repo.branch("branch1").commit().create();
ObjectId id2 = repo.branch("branch2").commit().create();
@@ -106,8 +120,12 @@
@Test
public void canReadCommitIfRefVisible() throws Exception {
- allow(project, READ, REGISTERED_USERS, "refs/heads/branch1");
- deny(project, READ, REGISTERED_USERS, "refs/heads/branch2");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(READ).ref("refs/heads/branch1").group(REGISTERED_USERS))
+ .add(deny(READ).ref("refs/heads/branch2").group(REGISTERED_USERS))
+ .update();
ObjectId id1 = repo.branch("branch1").commit().create();
ObjectId id2 = repo.branch("branch2").commit().create();
@@ -122,8 +140,12 @@
@Test
public void canReadCommitIfReachableFromVisibleRef() throws Exception {
- allow(project, READ, REGISTERED_USERS, "refs/heads/branch1");
- deny(project, READ, REGISTERED_USERS, "refs/heads/branch2");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(READ).ref("refs/heads/branch1").group(REGISTERED_USERS))
+ .add(deny(READ).ref("refs/heads/branch2").group(REGISTERED_USERS))
+ .update();
RevCommit parent1 = repo.commit().create();
repo.branch("branch1").commit().parent(parent1).create();
@@ -140,7 +162,11 @@
@Test
public void cannotReadAfterRollbackWithRestrictedRead() throws Exception {
- allow(project, READ, REGISTERED_USERS, "refs/heads/branch1");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(READ).ref("refs/heads/branch1").group(REGISTERED_USERS))
+ .update();
RevCommit parent1 = repo.commit().create();
ObjectId id1 = repo.branch("branch1").commit().parent(parent1).create();
@@ -159,7 +185,11 @@
@Test
public void canReadAfterRollbackWithAllRefsVisible() throws Exception {
- allow(project, READ, REGISTERED_USERS, "refs/*");
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allow(READ).ref("refs/*").group(REGISTERED_USERS))
+ .update();
RevCommit parent1 = repo.commit().create();
ObjectId id1 = repo.branch("branch1").commit().parent(parent1).create();
@@ -177,41 +207,19 @@
}
private ProjectState readProjectState() throws Exception {
- return projectCache.get(project.getName());
- }
-
- protected void allow(ProjectConfig project, String permission, AccountGroup.UUID id, String ref)
- throws Exception {
- Util.allow(project, permission, id, ref);
- saveProjectConfig(project);
- }
-
- protected void deny(ProjectConfig project, String permission, AccountGroup.UUID id, String ref)
- throws Exception {
- Util.deny(project, permission, id, ref);
- saveProjectConfig(project);
- }
-
- protected void saveProjectConfig(ProjectConfig cfg) throws Exception {
- try (MetaDataUpdate md = metaDataUpdateFactory.create(cfg.getName())) {
- cfg.commit(md);
- }
- projectCache.evict(cfg.getProject());
+ return projectCache.get(project);
}
private void setUpPermissions() throws Exception {
- ImmutableList<AccountGroup.UUID> admins = getAdmins();
-
// Remove read permissions for all users besides admin, because by default
// Anonymous user group has ALLOW READ permission in refs/*.
// This method is idempotent, so is safe to call on every test setup.
- ProjectConfig pc = projectCache.checkedGet(allProjects).getConfig();
- for (AccessSection sec : pc.getAccessSections()) {
- sec.removePermission(Permission.READ);
- }
- for (AccountGroup.UUID admin : admins) {
- allow(pc, Permission.READ, admin, "refs/*");
- }
+ TestProjectUpdate.Builder u = projectOperations.allProjectsForUpdate();
+ projectCache.checkedGet(allProjects).getConfig().getAccessSectionNames().stream()
+ .filter(sec -> sec.startsWith(R_REFS))
+ .forEach(sec -> u.remove(permissionKey(Permission.READ).ref(sec)));
+ getAdmins().forEach(admin -> u.add(allow(Permission.READ).ref("refs/*").group(admin)));
+ u.update();
}
private ImmutableList<AccountGroup.UUID> getAdmins() {
diff --git a/javatests/com/google/gerrit/server/project/GroupListTest.java b/javatests/com/google/gerrit/server/project/GroupListTest.java
index b83a10b..5ccefa0 100644
--- a/javatests/com/google/gerrit/server/project/GroupListTest.java
+++ b/javatests/com/google/gerrit/server/project/GroupListTest.java
@@ -29,7 +29,6 @@
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.git.ValidationError;
-import com.google.gerrit.testing.GerritBaseTests;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
@@ -37,7 +36,7 @@
import org.junit.Before;
import org.junit.Test;
-public class GroupListTest extends GerritBaseTests {
+public class GroupListTest {
private static final Project.NameKey PROJECT = Project.nameKey("project");
private static final String TEXT =
"# UUID \tGroup Name\n"
diff --git a/javatests/com/google/gerrit/server/project/ProjectConfigTest.java b/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
index e227b597..75e1cd7 100644
--- a/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
+++ b/javatests/com/google/gerrit/server/project/ProjectConfigTest.java
@@ -36,8 +36,7 @@
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.ValidationError;
import com.google.gerrit.server.git.meta.MetaDataUpdate;
-import com.google.gerrit.server.project.testing.Util;
-import com.google.gerrit.testing.GerritBaseTests;
+import com.google.gerrit.server.project.testing.TestLabels;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -62,7 +61,7 @@
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-public class ProjectConfigTest extends GerritBaseTests {
+public class ProjectConfigTest {
private static final String LABEL_SCORES_CONFIG =
" copyMinScore = "
+ !LabelType.DEF_COPY_MIN_SCORE
@@ -341,11 +340,11 @@
cfg.getLabelSections()
.put(
"My-Label",
- Util.category(
+ TestLabels.label(
"My-Label",
- Util.value(-1, "Negative"),
- Util.value(0, "No score"),
- Util.value(1, "Positive")));
+ TestLabels.value(-1, "Negative"),
+ TestLabels.value(0, "No score"),
+ TestLabels.value(1, "Positive")));
rev = commit(cfg);
assertThat(text(rev, "project.config"))
.isEqualTo(
diff --git a/javatests/com/google/gerrit/server/query/account/AbstractQueryAccountsTest.java b/javatests/com/google/gerrit/server/query/account/AbstractQueryAccountsTest.java
index f06ceec..2a7523b 100644
--- a/javatests/com/google/gerrit/server/query/account/AbstractQueryAccountsTest.java
+++ b/javatests/com/google/gerrit/server/query/account/AbstractQueryAccountsTest.java
@@ -17,6 +17,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.Truth8.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.toList;
import static org.junit.Assert.fail;
@@ -80,6 +81,7 @@
import com.google.gerrit.server.util.RequestContext;
import com.google.gerrit.server.util.ThreadLocalRequestContext;
import com.google.gerrit.testing.GerritServerTests;
+import com.google.gerrit.testing.GerritTestName;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
@@ -94,10 +96,13 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
@Ignore
public abstract class AbstractQueryAccountsTest extends GerritServerTests {
+ @Rule public final GerritTestName testName = new GerritTestName();
+
@Inject protected Accounts accounts;
@Inject @ServerInitiated protected Provider<AccountsUpdate> accountsUpdate;
@@ -580,9 +585,9 @@
List<AccountInfo> result = newQuery(otherUser.username).withSuggest(true).get();
assertThat(result.get(0).secondaryEmails).isNull();
-
- exception.expect(AuthException.class);
- newQuery(otherUser.username).withOption(ListAccountsOption.ALL_EMAILS).get();
+ assertThrows(
+ AuthException.class,
+ () -> newQuery(otherUser.username).withOption(ListAccountsOption.ALL_EMAILS).get());
}
@Test
@@ -751,7 +756,7 @@
return null;
}
- String suffix = getSanitizedMethodName();
+ String suffix = testName.getSanitizedMethodName();
if (name.contains("@")) {
return name + "." + suffix;
}
diff --git a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
index 0106ba4..4d7ba94 100644
--- a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
+++ b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
@@ -18,13 +18,13 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.TruthJUnit.assume;
+import static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allowLabel;
import static com.google.gerrit.extensions.client.ListChangesOption.DETAILED_LABELS;
import static com.google.gerrit.extensions.client.ListChangesOption.REVIEWED;
import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
-import static com.google.gerrit.server.project.testing.Util.allow;
-import static com.google.gerrit.server.project.testing.Util.category;
-import static com.google.gerrit.server.project.testing.Util.value;
-import static com.google.gerrit.server.project.testing.Util.verified;
+import static com.google.gerrit.server.project.testing.TestLabels.label;
+import static com.google.gerrit.server.project.testing.TestLabels.value;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.MINUTES;
@@ -41,9 +41,9 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Streams;
import com.google.common.truth.ThrowableSubject;
+import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
import com.google.gerrit.common.Nullable;
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.AddReviewerInput;
import com.google.gerrit.extensions.api.changes.AssigneeInput;
@@ -175,6 +175,9 @@
@Inject protected MetaDataUpdate.Server metaDataUpdateFactory;
@Inject protected IdentifiedUser.GenericFactory identifiedUserFactory;
+ @Inject private ProjectConfig.Factory projectConfigFactory;
+ @Inject private ProjectOperations projectOperations;
+
protected Injector injector;
protected LifecycleManager lifecycle;
protected Account.Id userId;
@@ -703,10 +706,10 @@
assertQuery(searchOperator + "\"John Smith\"");
// By invalid query.
- exception.expect(BadRequestException.class);
- exception.expectMessage("invalid value");
// SchemaUtil.getNameParts will return an empty set for query only containing these characters.
- assertQuery(searchOperator + "@.- /_");
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> assertQuery(searchOperator + "@.- /_"));
+ assertThat(thrown).hasMessageThat().contains("invalid value");
}
private Change createChange(TestRepository<Repo> repo, PersonIdent person) throws Exception {
@@ -1048,19 +1051,23 @@
TestRepository<Repo> repo = createProject("repo");
Project.NameKey project =
Project.nameKey(repo.getRepository().getDescription().getRepositoryName());
- ProjectConfig cfg = projectCache.checkedGet(project).getConfig();
LabelType verified =
- category("Verified", value(1, "Passes"), value(0, "No score"), value(-1, "Failed"));
- cfg.getLabelSections().put(verified.getName(), verified);
-
- String heads = RefNames.REFS_HEADS + "*";
- allow(cfg, Permission.forLabel(verified().getName()), -1, 1, REGISTERED_USERS, heads);
-
+ label("Verified", value(1, "Passes"), value(0, "No score"), value(-1, "Failed"));
try (MetaDataUpdate md = metaDataUpdateFactory.create(project)) {
+ ProjectConfig cfg = projectConfigFactory.create(project);
+ cfg.load(md);
+ cfg.getLabelSections().put(verified.getName(), verified);
cfg.commit(md);
}
- projectCache.evict(cfg.getProject());
+ projectCache.evict(project);
+
+ String heads = RefNames.REFS_HEADS + "*";
+ projectOperations
+ .project(project)
+ .forUpdate()
+ .add(allowLabel(verified.getName()).ref(heads).group(REGISTERED_USERS).range(-1, 1))
+ .update();
ReviewInput reviewVerified = new ReviewInput().label("Verified", 1);
ChangeInserter ins = newChange(repo, null, null, null, null, false);
@@ -1385,6 +1392,7 @@
Change change2 = insert(repo, newChangeWithFiles(repo, "bar.H", "bar.CC"));
Change change3 = insert(repo, newChangeWithFiles(repo, "dir/baz.h", "dir/baz.cc"));
Change change4 = insert(repo, newChangeWithFiles(repo, "Quux.java", "foo"));
+ Change change5 = insert(repo, newChangeWithFiles(repo, "foo"));
assertQuery("extension:java", change4);
assertQuery("ext:java", change4);
@@ -1395,7 +1403,7 @@
if (getSchemaVersion() >= 56) {
// matching changes with files that have no extension is possible
- assertQuery("ext:\"\"", change4);
+ assertQuery("ext:\"\"", change5, change4);
assertFailingQuery("ext:");
}
}
@@ -1950,22 +1958,23 @@
assertQuery("draftby:" + userId, change);
assertQuery("commentby:" + userId);
- TestRepository<Repo> allUsers = new TestRepository<>(repoManager.openRepository(allUsersName));
+ try (TestRepository<Repo> allUsers =
+ new TestRepository<>(repoManager.openRepository(allUsersName))) {
+ Ref draftsRef = allUsers.getRepository().exactRef(RefNames.refsDraftComments(id, userId));
+ assertThat(draftsRef).isNotNull();
- Ref draftsRef = allUsers.getRepository().exactRef(RefNames.refsDraftComments(id, userId));
- assertThat(draftsRef).isNotNull();
+ ReviewInput rin = ReviewInput.dislike();
+ rin.drafts = DraftHandling.PUBLISH_ALL_REVISIONS;
+ gApi.changes().id(id.get()).current().review(rin);
- ReviewInput rin = ReviewInput.dislike();
- rin.drafts = DraftHandling.PUBLISH_ALL_REVISIONS;
- gApi.changes().id(id.get()).current().review(rin);
+ assertQuery("draftby:" + userId);
+ assertQuery("commentby:" + userId, change);
+ assertThat(allUsers.getRepository().exactRef(draftsRef.getName())).isNull();
- assertQuery("draftby:" + userId);
- assertQuery("commentby:" + userId, change);
- assertThat(allUsers.getRepository().exactRef(draftsRef.getName())).isNull();
-
- // Re-add drafts ref and ensure it gets filtered out during indexing.
- allUsers.update(draftsRef.getName(), draftsRef.getObjectId());
- assertThat(allUsers.getRepository().exactRef(draftsRef.getName())).isNotNull();
+ // Re-add drafts ref and ensure it gets filtered out during indexing.
+ allUsers.update(draftsRef.getName(), draftsRef.getObjectId());
+ assertThat(allUsers.getRepository().exactRef(draftsRef.getName())).isNotNull();
+ }
indexer.index(project, id);
assertQuery("draftby:" + userId);
@@ -2488,8 +2497,7 @@
assertThat(indexer.reindexIfStale(project, change.getId()).get()).isFalse();
// Delete edit ref behind index's back.
- RefUpdate ru =
- repo.getRepository().updateRef(RefNames.refsEdit(user, change.getId(), ps.getId()));
+ RefUpdate ru = repo.getRepository().updateRef(RefNames.refsEdit(user, change.getId(), ps.id()));
ru.setForceUpdate(true);
assertThat(ru.delete()).isEqualTo(RefUpdate.Result.FORCED);
@@ -3021,16 +3029,18 @@
String destination4 = "refs/heads/master\trepo3";
String destination5 = "refs/heads/other\trepo1";
- TestRepository<Repo> allUsers = new TestRepository<>(repoManager.openRepository(allUsersName));
- String refsUsers = RefNames.refsUsers(userId);
- allUsers.branch(refsUsers).commit().add("destinations/destination1", destination1).create();
- allUsers.branch(refsUsers).commit().add("destinations/destination2", destination2).create();
- allUsers.branch(refsUsers).commit().add("destinations/destination3", destination3).create();
- allUsers.branch(refsUsers).commit().add("destinations/destination4", destination4).create();
- allUsers.branch(refsUsers).commit().add("destinations/destination5", destination5).create();
+ try (TestRepository<Repo> allUsers =
+ new TestRepository<>(repoManager.openRepository(allUsersName))) {
+ String refsUsers = RefNames.refsUsers(userId);
+ allUsers.branch(refsUsers).commit().add("destinations/destination1", destination1).create();
+ allUsers.branch(refsUsers).commit().add("destinations/destination2", destination2).create();
+ allUsers.branch(refsUsers).commit().add("destinations/destination3", destination3).create();
+ allUsers.branch(refsUsers).commit().add("destinations/destination4", destination4).create();
+ allUsers.branch(refsUsers).commit().add("destinations/destination5", destination5).create();
- Ref userRef = allUsers.getRepository().exactRef(refsUsers);
- assertThat(userRef).isNotNull();
+ Ref userRef = allUsers.getRepository().exactRef(refsUsers);
+ assertThat(userRef).isNotNull();
+ }
assertQuery("destination:destination1", change1);
assertQuery("destination:destination2", change2);
@@ -3051,12 +3061,14 @@
+ "query3\tproject:repo branch:stable\n"
+ "query4\tproject:repo branch:other";
- TestRepository<Repo> allUsers = new TestRepository<>(repoManager.openRepository(allUsersName));
- String refsUsers = RefNames.refsUsers(userId);
- allUsers.branch(refsUsers).commit().add("queries", queries).create();
+ try (TestRepository<Repo> allUsers =
+ new TestRepository<>(repoManager.openRepository(allUsersName))) {
+ String refsUsers = RefNames.refsUsers(userId);
+ allUsers.branch(refsUsers).commit().add("queries", queries).create();
- Ref userRef = allUsers.getRepository().exactRef(refsUsers);
- assertThat(userRef).isNotNull();
+ Ref userRef = allUsers.getRepository().exactRef(refsUsers);
+ assertThat(userRef).isNotNull();
+ }
assertThatQueryException("query:foo").hasMessageThat().isEqualTo("Unknown named query: foo");
diff --git a/javatests/com/google/gerrit/server/query/change/BUILD b/javatests/com/google/gerrit/server/query/change/BUILD
index e8a63b8..a128593 100644
--- a/javatests/com/google/gerrit/server/query/change/BUILD
+++ b/javatests/com/google/gerrit/server/query/change/BUILD
@@ -9,6 +9,7 @@
visibility = ["//visibility:public"],
runtime_deps = ["//prolog:gerrit-prolog-common"],
deps = [
+ "//java/com/google/gerrit/acceptance/testsuite/project",
"//java/com/google/gerrit/common:annotations",
"//java/com/google/gerrit/common:server",
"//java/com/google/gerrit/extensions:api",
@@ -64,6 +65,7 @@
"//java/com/google/gerrit/reviewdb:server",
"//java/com/google/gerrit/server",
"//java/com/google/gerrit/server/cache/testing",
+ "//java/com/google/gerrit/server/util/time",
"//java/com/google/gerrit/testing:gerrit-test-util",
"//lib:guava",
"//lib/jgit/org.eclipse.jgit:jgit",
diff --git a/javatests/com/google/gerrit/server/query/change/ChangeDataTest.java b/javatests/com/google/gerrit/server/query/change/ChangeDataTest.java
index fa44f21..0f7292d 100644
--- a/javatests/com/google/gerrit/server/query/change/ChangeDataTest.java
+++ b/javatests/com/google/gerrit/server/query/change/ChangeDataTest.java
@@ -21,23 +21,32 @@
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.testing.GerritBaseTests;
+import com.google.gerrit.server.util.time.TimeUtil;
import com.google.gerrit.testing.TestChanges;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
-public class ChangeDataTest extends GerritBaseTests {
+public class ChangeDataTest {
@Test
public void setPatchSetsClearsCurrentPatchSet() throws Exception {
Project.NameKey project = Project.nameKey("project");
ChangeData cd = ChangeData.createForTest(project, Change.id(1), 1, ObjectId.zeroId());
cd.setChange(TestChanges.newChange(project, Account.id(1000)));
PatchSet curr1 = cd.currentPatchSet();
- int currId = curr1.getId().get();
- PatchSet ps1 = new PatchSet(PatchSet.id(cd.getId(), currId + 1), ObjectId.zeroId());
- PatchSet ps2 = new PatchSet(PatchSet.id(cd.getId(), currId + 2), ObjectId.zeroId());
+ int currId = curr1.id().get();
+ PatchSet ps1 = newPatchSet(cd.getId(), currId + 1);
+ PatchSet ps2 = newPatchSet(cd.getId(), currId + 2);
cd.setPatchSets(ImmutableList.of(ps1, ps2));
PatchSet curr2 = cd.currentPatchSet();
assertThat(curr2).isNotSameInstanceAs(curr1);
}
+
+ private static PatchSet newPatchSet(Change.Id changeId, int num) {
+ return PatchSet.builder()
+ .id(PatchSet.id(changeId, num))
+ .commitId(ObjectId.zeroId())
+ .uploader(Account.id(1234))
+ .createdOn(TimeUtil.nowTs())
+ .build();
+ }
}
diff --git a/javatests/com/google/gerrit/server/query/change/ConflictKeyTest.java b/javatests/com/google/gerrit/server/query/change/ConflictKeyTest.java
index e550f8e..00c1a80 100644
--- a/javatests/com/google/gerrit/server/query/change/ConflictKeyTest.java
+++ b/javatests/com/google/gerrit/server/query/change/ConflictKeyTest.java
@@ -25,11 +25,10 @@
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.proto.testing.SerializedClassSubject;
import com.google.gerrit.server.cache.proto.Cache.ConflictKeyProto;
-import com.google.gerrit.testing.GerritBaseTests;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
-public class ConflictKeyTest extends GerritBaseTests {
+public class ConflictKeyTest {
@Test
public void ffOnlyPreservesInputOrder() {
ObjectId id1 = ObjectId.fromString("badc0feebadc0feebadc0feebadc0feebadc0fee");
diff --git a/javatests/com/google/gerrit/server/query/change/LuceneQueryChangesTest.java b/javatests/com/google/gerrit/server/query/change/LuceneQueryChangesTest.java
index 2ea198f..621f474 100644
--- a/javatests/com/google/gerrit/server/query/change/LuceneQueryChangesTest.java
+++ b/javatests/com/google/gerrit/server/query/change/LuceneQueryChangesTest.java
@@ -14,6 +14,9 @@
package com.google.gerrit.server.query.change;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.server.index.change.ChangeSchemaDefinitions;
@@ -76,8 +79,10 @@
Change change1 = insert(repo, newChange(repo), userId);
String nameEmail = user.asIdentifiedUser().getNameEmail();
- exception.expect(BadRequestException.class);
- exception.expectMessage("Cannot create full-text query with value: \\");
- assertQuery("owner: \"" + nameEmail + "\"\\", change1);
+ BadRequestException thrown =
+ assertThrows(
+ BadRequestException.class,
+ () -> assertQuery("owner: \"" + nameEmail + "\"\\", change1));
+ assertThat(thrown).hasMessageThat().contains("Cannot create full-text query with value: \\");
}
}
diff --git a/javatests/com/google/gerrit/server/query/change/RegexPathPredicateTest.java b/javatests/com/google/gerrit/server/query/change/RegexPathPredicateTest.java
index 45b780e..ac528f2e 100644
--- a/javatests/com/google/gerrit/server/query/change/RegexPathPredicateTest.java
+++ b/javatests/com/google/gerrit/server/query/change/RegexPathPredicateTest.java
@@ -19,12 +19,11 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.Arrays;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
-public class RegexPathPredicateTest extends GerritBaseTests {
+public class RegexPathPredicateTest {
@Test
public void prefixOnlyOptimization() {
RegexPathPredicate p = predicate("^a/b/.*");
diff --git a/javatests/com/google/gerrit/server/query/group/AbstractQueryGroupsTest.java b/javatests/com/google/gerrit/server/query/group/AbstractQueryGroupsTest.java
index db5eac6..3b13041 100644
--- a/javatests/com/google/gerrit/server/query/group/AbstractQueryGroupsTest.java
+++ b/javatests/com/google/gerrit/server/query/group/AbstractQueryGroupsTest.java
@@ -18,6 +18,7 @@
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.common.truth.TruthJUnit.assume;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.toList;
import com.google.common.base.CharMatcher;
@@ -58,6 +59,7 @@
import com.google.gerrit.server.util.RequestContext;
import com.google.gerrit.server.util.ThreadLocalRequestContext;
import com.google.gerrit.testing.GerritServerTests;
+import com.google.gerrit.testing.GerritTestName;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
@@ -69,10 +71,13 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
@Ignore
public abstract class AbstractQueryGroupsTest extends GerritServerTests {
+ @Rule public final GerritTestName testName = new GerritTestName();
+
@Inject protected Accounts accounts;
@Inject @ServerInitiated protected Provider<AccountsUpdate> accountsUpdate;
@@ -185,7 +190,7 @@
@Test
public void byInname() throws Exception {
- String namePart = getSanitizedMethodName();
+ String namePart = testName.getSanitizedMethodName();
namePart = CharMatcher.is('_').removeFrom(namePart);
GroupInfo group1 = createGroup("group-" + namePart);
@@ -205,9 +210,9 @@
assertQuery("description:non-existing");
- exception.expect(BadRequestException.class);
- exception.expectMessage("description operator requires a value");
- assertQuery("description:\"\"");
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> assertQuery("description:\"\""));
+ assertThat(thrown).hasMessageThat().contains("description operator requires a value");
}
@Test
@@ -536,7 +541,7 @@
return null;
}
- return name + "_" + getSanitizedMethodName();
+ return name + "_" + testName.getSanitizedMethodName();
}
protected int getSchemaVersion() {
diff --git a/javatests/com/google/gerrit/server/query/project/AbstractQueryProjectsTest.java b/javatests/com/google/gerrit/server/query/project/AbstractQueryProjectsTest.java
index f80f481..8f13099 100644
--- a/javatests/com/google/gerrit/server/query/project/AbstractQueryProjectsTest.java
+++ b/javatests/com/google/gerrit/server/query/project/AbstractQueryProjectsTest.java
@@ -14,8 +14,10 @@
package com.google.gerrit.server.query.project;
+import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static com.google.common.truth.TruthJUnit.assume;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.util.stream.Collectors.toList;
import com.google.common.base.CharMatcher;
@@ -57,6 +59,7 @@
import com.google.gerrit.server.util.RequestContext;
import com.google.gerrit.server.util.ThreadLocalRequestContext;
import com.google.gerrit.testing.GerritServerTests;
+import com.google.gerrit.testing.GerritTestName;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
@@ -68,10 +71,13 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
@Ignore
public abstract class AbstractQueryProjectsTest extends GerritServerTests {
+ @Rule public final GerritTestName testName = new GerritTestName();
+
@Inject protected Accounts accounts;
@Inject @ServerInitiated protected Provider<AccountsUpdate> accountsUpdate;
@@ -185,7 +191,7 @@
@Test
public void byInname() throws Exception {
- String namePart = getSanitizedMethodName();
+ String namePart = testName.getSanitizedMethodName();
namePart = CharMatcher.is('_').removeFrom(namePart);
ProjectInfo project1 = createProject(name("project1-" + namePart));
@@ -207,9 +213,9 @@
assertQuery("description:non-existing");
- exception.expect(BadRequestException.class);
- exception.expectMessage("description operator requires a value");
- assertQuery("description:\"\"");
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> assertQuery("description:\"\""));
+ assertThat(thrown).hasMessageThat().contains("description operator requires a value");
}
@Test
@@ -224,16 +230,18 @@
@Test
public void byState_emptyQuery() throws Exception {
- exception.expect(BadRequestException.class);
- exception.expectMessage("state operator requires a value");
- assertQuery("state:\"\"");
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> assertQuery("state:\"\""));
+ assertThat(thrown).hasMessageThat().contains("state operator requires a value");
}
@Test
public void byState_badQuery() throws Exception {
- exception.expect(BadRequestException.class);
- exception.expectMessage("state operator must be either 'active' or 'read-only'");
- assertQuery("state:bla");
+ BadRequestException thrown =
+ assertThrows(BadRequestException.class, () -> assertQuery("state:bla"));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("state operator must be either 'active' or 'read-only'");
}
@Test
@@ -443,6 +451,6 @@
return null;
}
- return name + "_" + getSanitizedMethodName();
+ return name + "_" + testName.getSanitizedMethodName();
}
}
diff --git a/javatests/com/google/gerrit/server/rules/GerritCommonTest.java b/javatests/com/google/gerrit/server/rules/GerritCommonTest.java
index 180c16b..be0b8e7 100644
--- a/javatests/com/google/gerrit/server/rules/GerritCommonTest.java
+++ b/javatests/com/google/gerrit/server/rules/GerritCommonTest.java
@@ -14,10 +14,12 @@
package com.google.gerrit.server.rules;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static org.easymock.EasyMock.expect;
import com.google.gerrit.common.data.LabelTypes;
-import com.google.gerrit.server.project.testing.Util;
+import com.google.gerrit.server.project.testing.TestLabels;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.inject.AbstractModule;
import com.googlecode.prolog_cafe.exceptions.CompileException;
@@ -56,7 +58,8 @@
@Override
protected void setUpEnvironment(PrologEnvironment env) throws Exception {
- LabelTypes labelTypes = new LabelTypes(Arrays.asList(Util.codeReview(), Util.verified()));
+ LabelTypes labelTypes =
+ new LabelTypes(Arrays.asList(TestLabels.codeReview(), TestLabels.verified()));
ChangeData cd = EasyMock.createMock(ChangeData.class);
expect(cd.getLabelTypes()).andStubReturn(labelTypes);
EasyMock.replay(cd);
@@ -82,11 +85,14 @@
throw new CompileException("Cannot consult " + nameTerm);
}
- exception.expect(ReductionLimitException.class);
- exception.expectMessage("exceeded reduction limit of 1300");
- env.once(
- Prolog.BUILTIN,
- "call",
- new StructureTerm(":", SymbolTerm.create("user"), SymbolTerm.create("loopy")));
+ ReductionLimitException thrown =
+ assertThrows(
+ ReductionLimitException.class,
+ () ->
+ env.once(
+ Prolog.BUILTIN,
+ "call",
+ new StructureTerm(":", SymbolTerm.create("user"), SymbolTerm.create("loopy"))));
+ assertThat(thrown).hasMessageThat().contains("exceeded reduction limit of 1300");
}
}
diff --git a/javatests/com/google/gerrit/server/rules/IgnoreSelfApprovalRuleTest.java b/javatests/com/google/gerrit/server/rules/IgnoreSelfApprovalRuleTest.java
index 3839a39..d2493cb 100644
--- a/javatests/com/google/gerrit/server/rules/IgnoreSelfApprovalRuleTest.java
+++ b/javatests/com/google/gerrit/server/rules/IgnoreSelfApprovalRuleTest.java
@@ -24,7 +24,6 @@
import com.google.gerrit.reviewdb.client.LabelId;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
-import com.google.gerrit.testing.GerritBaseTests;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
@@ -32,7 +31,7 @@
import java.util.List;
import org.junit.Test;
-public class IgnoreSelfApprovalRuleTest extends GerritBaseTests {
+public class IgnoreSelfApprovalRuleTest {
private static final Change.Id CHANGE_ID = Change.id(100);
private static final PatchSet.Id PS_ID = PatchSet.id(CHANGE_ID, 1);
private static final LabelType VERIFIED = makeLabel("Verified");
@@ -82,13 +81,11 @@
}
private static PatchSetApproval makeApproval(LabelId labelId, Account.Id accountId, int value) {
- PatchSetApproval.Key key = makeKey(PS_ID, accountId, labelId);
- return new PatchSetApproval(key, (short) value, Date.from(Instant.now()));
- }
-
- private static PatchSetApproval.Key makeKey(
- PatchSet.Id psId, Account.Id accountId, LabelId labelId) {
- return PatchSetApproval.key(psId, accountId, labelId);
+ return PatchSetApproval.builder()
+ .key(PatchSetApproval.key(PS_ID, accountId, labelId))
+ .value(value)
+ .granted(Date.from(Instant.now()))
+ .build();
}
private static Account.Id makeAccount(int account) {
diff --git a/javatests/com/google/gerrit/server/rules/PrologRuleEvaluatorTest.java b/javatests/com/google/gerrit/server/rules/PrologRuleEvaluatorTest.java
index 6eb0747..8622b32 100644
--- a/javatests/com/google/gerrit/server/rules/PrologRuleEvaluatorTest.java
+++ b/javatests/com/google/gerrit/server/rules/PrologRuleEvaluatorTest.java
@@ -16,10 +16,9 @@
import static com.google.common.truth.Truth.assertThat;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class PrologRuleEvaluatorTest extends GerritBaseTests {
+public class PrologRuleEvaluatorTest {
@Test
public void validLabelNamesAreKept() {
diff --git a/javatests/com/google/gerrit/server/rules/PrologTestCase.java b/javatests/com/google/gerrit/server/rules/PrologTestCase.java
index f4d8eac..c2b6dbb 100644
--- a/javatests/com/google/gerrit/server/rules/PrologTestCase.java
+++ b/javatests/com/google/gerrit/server/rules/PrologTestCase.java
@@ -19,7 +19,6 @@
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.inject.Guice;
import com.google.inject.Module;
import com.googlecode.prolog_cafe.exceptions.CompileException;
@@ -45,7 +44,7 @@
/** Base class for any tests written in Prolog. */
@Ignore
-public abstract class PrologTestCase extends GerritBaseTests {
+public abstract class PrologTestCase {
private static final SymbolTerm test_1 = SymbolTerm.intern("test", 1);
private String pkg;
diff --git a/javatests/com/google/gerrit/server/schema/AllProjectsCreatorTest.java b/javatests/com/google/gerrit/server/schema/AllProjectsCreatorTest.java
index e5890c9..4c384e0 100644
--- a/javatests/com/google/gerrit/server/schema/AllProjectsCreatorTest.java
+++ b/javatests/com/google/gerrit/server/schema/AllProjectsCreatorTest.java
@@ -21,6 +21,7 @@
import static com.google.gerrit.server.schema.testing.AllProjectsCreatorTestUtil.getAllProjectsWithoutDefaultAcls;
import static com.google.gerrit.server.schema.testing.AllProjectsCreatorTestUtil.getDefaultAllProjectsWithAllDefaultSections;
import static com.google.gerrit.server.schema.testing.AllProjectsCreatorTestUtil.readAllProjectsConfig;
+import static com.google.gerrit.truth.ConfigSubject.assertThat;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.common.data.GroupReference;
@@ -34,7 +35,6 @@
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.notedb.Sequences;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.InMemoryModule;
import com.google.inject.Inject;
import org.eclipse.jgit.lib.Config;
@@ -43,7 +43,7 @@
import org.junit.Before;
import org.junit.Test;
-public class AllProjectsCreatorTest extends GerritBaseTests {
+public class AllProjectsCreatorTest {
private static final LabelType TEST_LABEL =
new LabelType(
"Test-Label",
@@ -127,7 +127,7 @@
allProjectsCreator.create(allProjectsInput);
Config config = readAllProjectsConfig(repoManager, allProjectsName);
- assertThat(config.getString("project", null, "description")).isEqualTo(testDescription);
+ assertThat(config).stringValue("project", null, "description").isEqualTo(testDescription);
}
@Test
@@ -143,7 +143,7 @@
allProjectsCreator.create(allProjectsInput);
Config config = readAllProjectsConfig(repoManager, allProjectsName);
- assertThat(config.getBoolean("submit", null, "rejectEmptyCommit", false)).isTrue();
+ assertThat(config).booleanValue("submit", null, "rejectEmptyCommit", false).isTrue();
}
@Test
diff --git a/javatests/com/google/gerrit/server/schema/NoteDbSchemaUpdaterTest.java b/javatests/com/google/gerrit/server/schema/NoteDbSchemaUpdaterTest.java
index b6887cf..45a05ac 100644
--- a/javatests/com/google/gerrit/server/schema/NoteDbSchemaUpdaterTest.java
+++ b/javatests/com/google/gerrit/server/schema/NoteDbSchemaUpdaterTest.java
@@ -15,9 +15,9 @@
package com.google.gerrit.server.schema;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
import static com.google.common.truth.Truth8.assertThat;
import static com.google.gerrit.server.schema.NoteDbSchemaUpdater.requiredUpgrades;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSortedMap;
@@ -31,7 +31,6 @@
import com.google.gerrit.server.notedb.IntBlob;
import com.google.gerrit.server.notedb.RepoSequence;
import com.google.gerrit.server.notedb.Sequences;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.InMemoryRepositoryManager;
import com.google.gerrit.testing.TestUpdateUI;
import java.io.IOException;
@@ -44,7 +43,7 @@
import org.eclipse.jgit.lib.Repository;
import org.junit.Test;
-public class NoteDbSchemaUpdaterTest extends GerritBaseTests {
+public class NoteDbSchemaUpdaterTest {
@Test
public void requiredUpgradesFromNoVersion() throws Exception {
assertThat(requiredUpgrades(0, versions(10))).containsExactly(10).inOrder();
@@ -62,26 +61,20 @@
@Test
public void downgradeNotSupported() throws Exception {
- try {
- requiredUpgrades(14, versions(10, 11, 12, 13));
- assert_().fail("expected StorageException");
- } catch (StorageException e) {
- assertThat(e)
- .hasMessageThat()
- .contains("Cannot downgrade NoteDb schema from version 14 to 13");
- }
+ StorageException thrown =
+ assertThrows(StorageException.class, () -> requiredUpgrades(14, versions(10, 11, 12, 13)));
+ assertThat(thrown)
+ .hasMessageThat()
+ .contains("Cannot downgrade NoteDb schema from version 14 to 13");
}
@Test
public void skipToFirstVersionNotSupported() throws Exception {
ImmutableSortedSet<Integer> versions = versions(10, 11, 12);
assertThat(requiredUpgrades(9, versions)).containsExactly(10, 11, 12).inOrder();
- try {
- requiredUpgrades(8, versions);
- assert_().fail("expected StorageException");
- } catch (StorageException e) {
- assertThat(e).hasMessageThat().contains("Cannot skip NoteDb schema from version 8 to 10");
- }
+ StorageException thrown =
+ assertThrows(StorageException.class, () -> requiredUpgrades(8, versions));
+ assertThat(thrown).hasMessageThat().contains("Cannot skip NoteDb schema from version 8 to 10");
}
private static class TestUpdate {
@@ -123,9 +116,9 @@
@Override
public void create() throws IOException {
- try (Repository repo = repoManager.createRepository(allProjectsName)) {
+ try (Repository repo = repoManager.createRepository(allProjectsName);
+ TestRepository<Repository> tr = new TestRepository<>(repo)) {
if (initialVersion.isPresent()) {
- TestRepository<?> tr = new TestRepository<>(repo);
tr.update(RefNames.REFS_VERSION, tr.blob(initialVersion.get().toString()));
}
} catch (Exception e) {
@@ -231,12 +224,8 @@
seedGroupSequenceRef();
}
};
- try {
- u.update();
- assert_().fail("expected StorageException");
- } catch (StorageException e) {
- assertThat(e).hasMessageThat().contains("NoteDb change migration was not completed");
- }
+ StorageException thrown = assertThrows(StorageException.class, () -> u.update());
+ assertThat(thrown).hasMessageThat().contains("NoteDb change migration was not completed");
assertThat(u.getMessages()).isEmpty();
assertThat(u.readVersion()).isEmpty();
}
@@ -250,12 +239,8 @@
setNotesMigrationConfig();
}
};
- try {
- u.update();
- assert_().fail("expected StorageException");
- } catch (StorageException e) {
- assertThat(e).hasMessageThat().contains("upgrade to 2.16.x first");
- }
+ StorageException thrown = assertThrows(StorageException.class, () -> u.update());
+ assertThat(thrown).hasMessageThat().contains("upgrade to 2.16.x first");
assertThat(u.getMessages()).isEmpty();
assertThat(u.readVersion()).isEmpty();
}
diff --git a/javatests/com/google/gerrit/server/schema/NoteDbSchemaVersionManagerTest.java b/javatests/com/google/gerrit/server/schema/NoteDbSchemaVersionManagerTest.java
index 9c62d7f..8ccf631 100644
--- a/javatests/com/google/gerrit/server/schema/NoteDbSchemaVersionManagerTest.java
+++ b/javatests/com/google/gerrit/server/schema/NoteDbSchemaVersionManagerTest.java
@@ -15,20 +15,19 @@
package com.google.gerrit.server.schema;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
import static com.google.gerrit.reviewdb.client.RefNames.REFS_VERSION;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.GitRepositoryManager;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.InMemoryRepositoryManager;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Before;
import org.junit.Test;
-public class NoteDbSchemaVersionManagerTest extends GerritBaseTests {
+public class NoteDbSchemaVersionManagerTest {
private NoteDbSchemaVersionManager manager;
private TestRepository<?> tr;
@@ -55,14 +54,10 @@
public void readInvalid() throws Exception {
ObjectId blobId = tr.blob(" 1 2 3 ");
tr.update(REFS_VERSION, blobId);
- try {
- manager.read();
- assert_().fail("expected StorageException");
- } catch (StorageException e) {
- assertThat(e)
- .hasMessageThat()
- .isEqualTo("invalid value in refs/meta/version blob at " + blobId.name());
- }
+ StorageException thrown = assertThrows(StorageException.class, () -> manager.read());
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo("invalid value in refs/meta/version blob at " + blobId.name());
}
@Test
@@ -81,13 +76,9 @@
@Test
public void incrementWrongOldVersion() throws Exception {
tr.update(REFS_VERSION, tr.blob("123"));
- try {
- manager.increment(456);
- assert_().fail("expected StorageException");
- } catch (StorageException e) {
- assertThat(e)
- .hasMessageThat()
- .isEqualTo("Expected old version 456 for refs/meta/version, found 123");
- }
+ StorageException thrown = assertThrows(StorageException.class, () -> manager.increment(456));
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo("Expected old version 456 for refs/meta/version, found 123");
}
}
diff --git a/javatests/com/google/gerrit/server/schema/NoteDbSchemaVersionsTest.java b/javatests/com/google/gerrit/server/schema/NoteDbSchemaVersionsTest.java
index 7bc3848..31697fd 100644
--- a/javatests/com/google/gerrit/server/schema/NoteDbSchemaVersionsTest.java
+++ b/javatests/com/google/gerrit/server/schema/NoteDbSchemaVersionsTest.java
@@ -24,11 +24,10 @@
import com.google.common.collect.Streams;
import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ClassInfo;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.stream.IntStream;
import org.junit.Test;
-public class NoteDbSchemaVersionsTest extends GerritBaseTests {
+public class NoteDbSchemaVersionsTest {
@Test
public void testGuessVersion() {
assertThat(guessVersion(getClass())).isEmpty();
diff --git a/javatests/com/google/gerrit/server/schema/ProjectConfigSchemaUpdateTest.java b/javatests/com/google/gerrit/server/schema/ProjectConfigSchemaUpdateTest.java
index bc5109f..d26771f 100644
--- a/javatests/com/google/gerrit/server/schema/ProjectConfigSchemaUpdateTest.java
+++ b/javatests/com/google/gerrit/server/schema/ProjectConfigSchemaUpdateTest.java
@@ -72,8 +72,8 @@
public void noBaseConfig() throws Exception {
assertThat(getConfig().getString("foo", null, "bar")).isNull();
- try (Repository repo = new FileRepository(allProjectsRepoFile)) {
- TestRepository<?> tr = new TestRepository<>(repo);
+ try (Repository repo = new FileRepository(allProjectsRepoFile);
+ TestRepository<Repository> tr = new TestRepository<>(repo)) {
tr.branch("refs/meta/config").commit().add("project.config", "[foo]\nbar = baz").create();
}
@@ -90,8 +90,8 @@
assertThat(getConfig().getString("foo", null, "bar")).isEqualTo("base");
- try (Repository repo = new FileRepository(allProjectsRepoFile)) {
- TestRepository<?> tr = new TestRepository<>(repo);
+ try (Repository repo = new FileRepository(allProjectsRepoFile);
+ TestRepository<Repository> tr = new TestRepository<>(repo)) {
tr.branch("refs/meta/config").commit().add("project.config", "[foo]\nbar = baz").create();
}
diff --git a/javatests/com/google/gerrit/server/schema/SchemaCreatorImplTest.java b/javatests/com/google/gerrit/server/schema/SchemaCreatorImplTest.java
index 35f580c..c92a8e0 100644
--- a/javatests/com/google/gerrit/server/schema/SchemaCreatorImplTest.java
+++ b/javatests/com/google/gerrit/server/schema/SchemaCreatorImplTest.java
@@ -25,7 +25,6 @@
import com.google.gerrit.server.config.AllProjectsName;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.project.ProjectConfig;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.InMemoryModule;
import com.google.inject.Inject;
import java.util.ArrayList;
@@ -36,7 +35,7 @@
import org.junit.Before;
import org.junit.Test;
-public class SchemaCreatorImplTest extends GerritBaseTests {
+public class SchemaCreatorImplTest {
@Inject private AllProjectsName allProjects;
@Inject private GitRepositoryManager repoManager;
@@ -82,7 +81,7 @@
private void assertValueRange(LabelType label, Integer... range) {
List<Integer> rangeList = Arrays.asList(range);
assertThat(rangeList).isNotEmpty();
- assertThat(rangeList).isStrictlyOrdered();
+ assertThat(rangeList).isInStrictOrder();
assertThat(label.getValues().stream().map(v -> (int) v.getValue()))
.containsExactlyElementsIn(rangeList)
diff --git a/javatests/com/google/gerrit/server/update/BatchUpdateTest.java b/javatests/com/google/gerrit/server/update/BatchUpdateTest.java
index 4626eca..1d84d67 100644
--- a/javatests/com/google/gerrit/server/update/BatchUpdateTest.java
+++ b/javatests/com/google/gerrit/server/update/BatchUpdateTest.java
@@ -17,7 +17,7 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import com.google.common.collect.ImmutableList;
import com.google.gerrit.common.Nullable;
@@ -34,10 +34,9 @@
import com.google.gerrit.server.logging.RequestId;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeUpdate;
-import com.google.gerrit.server.notedb.NoteDbUpdateManager.TooManyUpdatesException;
import com.google.gerrit.server.notedb.Sequences;
+import com.google.gerrit.server.notedb.TooManyUpdatesException;
import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.InMemoryTestEnvironment;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -50,7 +49,7 @@
import org.junit.Rule;
import org.junit.Test;
-public class BatchUpdateTest extends GerritBaseTests {
+public class BatchUpdateTest {
private static final int MAX_UPDATES = 4;
@Rule
@@ -107,12 +106,11 @@
ObjectId oldMetaId = getMetaId(id);
try (BatchUpdate bu = batchUpdateFactory.create(project, user.get(), TimeUtil.nowTs())) {
bu.addOp(id, new AddMessageOp("Excessive update"));
- try {
- bu.execute();
- assert_().fail("expected ResourceConflictException");
- } catch (ResourceConflictException e) {
- assertThat(e).hasMessageThat().isEqualTo(TooManyUpdatesException.message(id, MAX_UPDATES));
- }
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> bu.execute());
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo(TooManyUpdatesException.message(id, MAX_UPDATES));
}
assertThat(getUpdateCount(id)).isEqualTo(MAX_UPDATES);
assertThat(getMetaId(id)).isEqualTo(oldMetaId);
@@ -126,12 +124,11 @@
try (BatchUpdate bu = batchUpdateFactory.create(project, user.get(), TimeUtil.nowTs())) {
bu.addOp(id, new AddMessageOp("Update on PS1", PatchSet.id(id, 1)));
bu.addOp(id, new AddMessageOp("Update on PS2", PatchSet.id(id, 2)));
- try {
- bu.execute();
- assert_().fail("expected ResourceConflictException");
- } catch (ResourceConflictException e) {
- assertThat(e).hasMessageThat().isEqualTo(TooManyUpdatesException.message(id, MAX_UPDATES));
- }
+ ResourceConflictException thrown =
+ assertThrows(ResourceConflictException.class, () -> bu.execute());
+ assertThat(thrown)
+ .hasMessageThat()
+ .isEqualTo(TooManyUpdatesException.message(id, MAX_UPDATES));
}
assertThat(getUpdateCount(id)).isEqualTo(MAX_UPDATES - 1);
assertThat(getMetaId(id)).isEqualTo(oldMetaId);
@@ -251,8 +248,7 @@
ChangeNotes notes = changeNotesFactory.create(project, id);
try (BatchUpdate bu = batchUpdateFactory.create(project, user.get(), TimeUtil.nowTs())) {
- ObjectId commitId =
- repo.amend(notes.getCurrentPatchSet().getCommitId()).message("PS2").create();
+ ObjectId commitId = repo.amend(notes.getCurrentPatchSet().commitId()).message("PS2").create();
bu.addOp(
id,
patchSetInserterFactory
diff --git a/javatests/com/google/gerrit/server/update/RepoViewTest.java b/javatests/com/google/gerrit/server/update/RepoViewTest.java
index 4cd2185..ea80633 100644
--- a/javatests/com/google/gerrit/server/update/RepoViewTest.java
+++ b/javatests/com/google/gerrit/server/update/RepoViewTest.java
@@ -19,7 +19,6 @@
import static org.eclipse.jgit.lib.Constants.R_HEADS;
import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.testing.InMemoryRepositoryManager;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.Config;
@@ -31,7 +30,7 @@
import org.junit.Before;
import org.junit.Test;
-public class RepoViewTest extends GerritBaseTests {
+public class RepoViewTest {
private static final String MASTER = "refs/heads/master";
private static final String BRANCH = "refs/heads/branch";
diff --git a/javatests/com/google/gerrit/server/util/IdGeneratorTest.java b/javatests/com/google/gerrit/server/util/IdGeneratorTest.java
index e702656..808eca8 100644
--- a/javatests/com/google/gerrit/server/util/IdGeneratorTest.java
+++ b/javatests/com/google/gerrit/server/util/IdGeneratorTest.java
@@ -17,11 +17,10 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.HashSet;
import org.junit.Test;
-public class IdGeneratorTest extends GerritBaseTests {
+public class IdGeneratorTest {
@Test
public void test1234() {
final HashSet<Integer> seen = new HashSet<>();
diff --git a/javatests/com/google/gerrit/server/util/LabelVoteTest.java b/javatests/com/google/gerrit/server/util/LabelVoteTest.java
index 3048b75..bda99a8 100644
--- a/javatests/com/google/gerrit/server/util/LabelVoteTest.java
+++ b/javatests/com/google/gerrit/server/util/LabelVoteTest.java
@@ -15,14 +15,13 @@
package com.google.gerrit.server.util;
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assert_;
import static com.google.gerrit.server.util.LabelVote.parse;
import static com.google.gerrit.server.util.LabelVote.parseWithEquals;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class LabelVoteTest extends GerritBaseTests {
+public class LabelVoteTest {
@Test
public void labelVoteParse() {
assertLabelVoteEquals(parse("Code-Review-2"), "Code-Review", -2);
@@ -83,11 +82,6 @@
}
private void assertParseWithEqualsFails(String value) {
- try {
- parseWithEquals(value);
- assert_().fail("expected IllegalArgumentException when parsing \"%s\"", value);
- } catch (IllegalArgumentException e) {
- // Expected.
- }
+ assertThrows(IllegalArgumentException.class, () -> parseWithEquals(value));
}
}
diff --git a/javatests/com/google/gerrit/server/util/MostSpecificComparatorTest.java b/javatests/com/google/gerrit/server/util/MostSpecificComparatorTest.java
index 9ea17f3..025bf84 100644
--- a/javatests/com/google/gerrit/server/util/MostSpecificComparatorTest.java
+++ b/javatests/com/google/gerrit/server/util/MostSpecificComparatorTest.java
@@ -16,10 +16,9 @@
import static org.junit.Assert.assertTrue;
-import com.google.gerrit.testing.GerritBaseTests;
import org.junit.Test;
-public class MostSpecificComparatorTest extends GerritBaseTests {
+public class MostSpecificComparatorTest {
private MostSpecificComparator cmp;
diff --git a/javatests/com/google/gerrit/server/util/SocketUtilTest.java b/javatests/com/google/gerrit/server/util/SocketUtilTest.java
index 018b8db..25114f9 100644
--- a/javatests/com/google/gerrit/server/util/SocketUtilTest.java
+++ b/javatests/com/google/gerrit/server/util/SocketUtilTest.java
@@ -14,17 +14,18 @@
package com.google.gerrit.server.util;
+import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.server.util.SocketUtil.hostname;
import static com.google.gerrit.server.util.SocketUtil.isIPv6;
import static com.google.gerrit.server.util.SocketUtil.parse;
import static com.google.gerrit.server.util.SocketUtil.resolve;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static java.net.InetAddress.getByName;
import static java.net.InetSocketAddress.createUnresolved;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import com.google.gerrit.testing.GerritBaseTests;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
@@ -32,7 +33,7 @@
import java.net.UnknownHostException;
import org.junit.Test;
-public class SocketUtilTest extends GerritBaseTests {
+public class SocketUtilTest {
@Test
public void testIsIPv6() throws UnknownHostException {
final InetAddress ipv6 = getByName("1:2:3:4:5:6:7:8");
@@ -105,16 +106,16 @@
@Test
public void testParseInvalidIPv6() {
- exception.expect(IllegalArgumentException.class);
- exception.expectMessage("invalid IPv6: [:3");
- parse("[:3", 80);
+ IllegalArgumentException thrown =
+ assertThrows(IllegalArgumentException.class, () -> parse("[:3", 80));
+ assertThat(thrown).hasMessageThat().contains("invalid IPv6: [:3");
}
@Test
public void testParseInvalidPort() {
- exception.expect(IllegalArgumentException.class);
- exception.expectMessage("invalid port: localhost:A");
- parse("localhost:A", 80);
+ IllegalArgumentException thrown =
+ assertThrows(IllegalArgumentException.class, () -> parse("localhost:A", 80));
+ assertThat(thrown).hasMessageThat().contains("invalid port: localhost:A");
}
@Test
diff --git a/javatests/com/google/gerrit/server/util/git/SubmoduleSectionParserTest.java b/javatests/com/google/gerrit/server/util/git/SubmoduleSectionParserTest.java
index 6c682a2..50f28ab 100644
--- a/javatests/com/google/gerrit/server/util/git/SubmoduleSectionParserTest.java
+++ b/javatests/com/google/gerrit/server/util/git/SubmoduleSectionParserTest.java
@@ -20,12 +20,11 @@
import com.google.gerrit.reviewdb.client.BranchNameKey;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.SubmoduleSubscription;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.Set;
import org.eclipse.jgit.lib.Config;
import org.junit.Test;
-public class SubmoduleSectionParserTest extends GerritBaseTests {
+public class SubmoduleSectionParserTest {
private static final String THIS_SERVER = "http://localhost/";
@Test
diff --git a/javatests/com/google/gerrit/sshd/commands/ProjectConfigParamParserTest.java b/javatests/com/google/gerrit/sshd/commands/ProjectConfigParamParserTest.java
index b663849..777cb4f 100644
--- a/javatests/com/google/gerrit/sshd/commands/ProjectConfigParamParserTest.java
+++ b/javatests/com/google/gerrit/sshd/commands/ProjectConfigParamParserTest.java
@@ -17,13 +17,12 @@
import static com.google.common.truth.Truth.assertThat;
import com.google.gerrit.extensions.api.projects.ConfigValue;
-import com.google.gerrit.testing.GerritBaseTests;
import java.util.Collections;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
-public class ProjectConfigParamParserTest extends GerritBaseTests {
+public class ProjectConfigParamParserTest {
private CreateProjectCommand cmd;
diff --git a/javatests/com/google/gerrit/testing/GerritJUnitTest.java b/javatests/com/google/gerrit/testing/GerritJUnitTest.java
new file mode 100644
index 0000000..430f48f
--- /dev/null
+++ b/javatests/com/google/gerrit/testing/GerritJUnitTest.java
@@ -0,0 +1,90 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.testing;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assert_;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+
+import org.junit.Test;
+
+public class GerritJUnitTest {
+ private static class MyException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ MyException(String msg) {
+ super(msg);
+ }
+ }
+
+ private static class MySubException extends MyException {
+ private static final long serialVersionUID = 1L;
+
+ MySubException(String msg) {
+ super(msg);
+ }
+ }
+
+ @Test
+ public void assertThrowsCatchesSpecifiedExceptionType() {
+ MyException e =
+ assertThrows(
+ MyException.class,
+ () -> {
+ throw new MyException("foo");
+ });
+ assertThat(e).hasMessageThat().isEqualTo("foo");
+ }
+
+ @Test
+ public void assertThrowsCatchesSubclassOfSpecifiedExceptionType() {
+ MyException e =
+ assertThrows(
+ MyException.class,
+ () -> {
+ throw new MySubException("foo");
+ });
+ assertThat(e).isInstanceOf(MySubException.class);
+ assertThat(e).hasMessageThat().isEqualTo("foo");
+ }
+
+ @Test
+ public void assertThrowsConvertsUnexpectedExceptionTypeToAssertionError() {
+ try {
+ assertThrows(
+ IllegalStateException.class,
+ () -> {
+ throw new MyException("foo");
+ });
+ assert_().fail("expected AssertionError");
+ } catch (AssertionError e) {
+ assertThat(e).hasMessageThat().contains(IllegalStateException.class.getSimpleName());
+ assertThat(e).hasMessageThat().contains(MyException.class.getSimpleName());
+ assertThat(e).hasCauseThat().isInstanceOf(MyException.class);
+ assertThat(e).hasCauseThat().hasMessageThat().isEqualTo("foo");
+ }
+ }
+
+ @Test
+ public void assertThrowsThrowsAssertionErrorWhenNothingThrown() {
+ try {
+ assertThrows(MyException.class, () -> {});
+ assert_().fail("expected AssertionError");
+ } catch (AssertionError e) {
+ assertThat(e).hasMessageThat().contains(MyException.class.getSimpleName());
+ assertThat(e).hasCauseThat().isNull();
+ }
+ }
+}
diff --git a/javatests/com/google/gerrit/testing/IndexVersionsTest.java b/javatests/com/google/gerrit/testing/IndexVersionsTest.java
index 36247f8..0362ddc 100644
--- a/javatests/com/google/gerrit/testing/IndexVersionsTest.java
+++ b/javatests/com/google/gerrit/testing/IndexVersionsTest.java
@@ -16,6 +16,7 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.TruthJUnit.assume;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
import static com.google.gerrit.testing.IndexVersions.ALL;
import static com.google.gerrit.testing.IndexVersions.CURRENT;
import static com.google.gerrit.testing.IndexVersions.PREVIOUS;
@@ -25,7 +26,7 @@
import java.util.List;
import org.junit.Test;
-public class IndexVersionsTest extends GerritBaseTests {
+public class IndexVersionsTest {
private static final ChangeSchemaDefinitions SCHEMA_DEF = ChangeSchemaDefinitions.INSTANCE;
@Test
@@ -133,8 +134,8 @@
}
private void assertIllegalArgument(String value, String expectedMessage) {
- exception.expect(IllegalArgumentException.class);
- exception.expectMessage(expectedMessage);
- get(value);
+ IllegalArgumentException thrown =
+ assertThrows(IllegalArgumentException.class, () -> get(value));
+ assertThat(thrown).hasMessageThat().contains(expectedMessage);
}
}
diff --git a/javatests/com/google/gerrit/util/http/BUILD b/javatests/com/google/gerrit/util/http/BUILD
index 2999fc0..63af18d 100644
--- a/javatests/com/google/gerrit/util/http/BUILD
+++ b/javatests/com/google/gerrit/util/http/BUILD
@@ -9,7 +9,6 @@
"//javatests/com/google/gerrit/util/http/testutil",
"//lib:junit",
"//lib:servlet-api-3_1-without-neverlink",
- "//lib/easymock",
"//lib/truth",
],
)
diff --git a/javatests/com/google/gerrit/util/http/RequestUtilTest.java b/javatests/com/google/gerrit/util/http/RequestUtilTest.java
index adda5e7..bef9d4b1 100644
--- a/javatests/com/google/gerrit/util/http/RequestUtilTest.java
+++ b/javatests/com/google/gerrit/util/http/RequestUtilTest.java
@@ -18,11 +18,10 @@
import static com.google.gerrit.util.http.RequestUtil.getEncodedPathInfo;
import static com.google.gerrit.util.http.RequestUtil.getRestPathWithoutIds;
-import com.google.gerrit.testing.GerritBaseTests;
import com.google.gerrit.util.http.testutil.FakeHttpServletRequest;
import org.junit.Test;
-public class RequestUtilTest extends GerritBaseTests {
+public class RequestUtilTest {
@Test
public void getEncodedPathInfo_emptyContextPath() {
assertThat(getEncodedPathInfo(fakeRequest("", "/s", "/foo/bar"))).isEqualTo("/foo/bar");
diff --git a/lib/BUILD b/lib/BUILD
index 667ba31..56305a5 100644
--- a/lib/BUILD
+++ b/lib/BUILD
@@ -424,13 +424,6 @@
)
java_library(
- name = "derby",
- data = ["//lib:LICENSE-Apache2.0"],
- visibility = ["//visibility:public"],
- exports = ["@derby//jar"],
-)
-
-java_library(
name = "soy",
data = ["//lib:LICENSE-Apache2.0"],
visibility = ["//visibility:public"],
diff --git a/lib/errorprone/BUILD b/lib/errorprone/BUILD
new file mode 100644
index 0000000..b5c130b
--- /dev/null
+++ b/lib/errorprone/BUILD
@@ -0,0 +1,6 @@
+java_library(
+ name = "annotations",
+ data = ["//lib:LICENSE-Apache2.0"],
+ visibility = ["//visibility:public"],
+ exports = ["@error-prone-annotations//jar"],
+)
diff --git a/lib/jgit/jgit.bzl b/lib/jgit/jgit.bzl
index 6828807..b5c4dcc 100644
--- a/lib/jgit/jgit.bzl
+++ b/lib/jgit/jgit.bzl
@@ -1,6 +1,6 @@
load("//tools/bzl:maven_jar.bzl", "MAVEN_CENTRAL", "maven_jar")
-_JGIT_VERS = "5.2.1.201812262042-r"
+_JGIT_VERS = "5.3.1.201904271842-r"
_DOC_VERS = _JGIT_VERS # Set to _JGIT_VERS unless using a snapshot
@@ -40,28 +40,28 @@
name = "jgit-lib",
artifact = "org.eclipse.jgit:org.eclipse.jgit:" + _JGIT_VERS,
repository = _JGIT_REPO,
- sha1 = "34914e63e1463e40ba40e2e28b0392993ea3b938",
- src_sha1 = "b1c9e2ae01dd31ab4957de54756ec11acc99bb30",
+ sha1 = "dba85014483315fa426259bc1b8ccda9373a624b",
+ src_sha1 = "b2ddc76c39d81df716948a00d26faa35e11a0ddf",
unsign = True,
)
maven_jar(
name = "jgit-servlet",
artifact = "org.eclipse.jgit:org.eclipse.jgit.http.server:" + _JGIT_VERS,
repository = _JGIT_REPO,
- sha1 = "18c8938c4d8966abed84fc9de6c09aaea8cc8d87",
+ sha1 = "3287341fca859340a00b51cb5dd3b78b8e532b39",
unsign = True,
)
maven_jar(
name = "jgit-archive",
artifact = "org.eclipse.jgit:org.eclipse.jgit.archive:" + _JGIT_VERS,
repository = _JGIT_REPO,
- sha1 = "08c945bc664e4efe0d0e9a878f96505076da2ca9",
+ sha1 = "3585027e83fb44a5de2c10ae9ddbf976593bf080",
)
maven_jar(
name = "jgit-junit",
artifact = "org.eclipse.jgit:org.eclipse.jgit.junit:" + _JGIT_VERS,
repository = _JGIT_REPO,
- sha1 = "5a5fb36517cb05ca51cbb1f00a520142dc83f793",
+ sha1 = "3d9ba7e610d6ab5d08dcb1e4ba448b592a34de77",
unsign = True,
)
diff --git a/lib/zlib/BUILD b/lib/zlib/BUILD
deleted file mode 100644
index f948117..0000000
--- a/lib/zlib/BUILD
+++ /dev/null
@@ -1,60 +0,0 @@
-package(default_visibility = ["//visibility:public"])
-
-licenses(["notice"]) # BSD/MIT-like license (for zlib)
-
-_ZLIB_HEADERS = [
- "crc32.h",
- "deflate.h",
- "gzguts.h",
- "inffast.h",
- "inffixed.h",
- "inflate.h",
- "inftrees.h",
- "trees.h",
- "zconf.h",
- "zlib.h",
- "zutil.h",
-]
-
-_ZLIB_PREFIXED_HEADERS = ["zlib/include/" + hdr for hdr in _ZLIB_HEADERS]
-
-# In order to limit the damage from the `includes` propagation
-# via `:zlib`, copy the public headers to a subdirectory and
-# expose those.
-genrule(
- name = "copy_public_headers",
- srcs = _ZLIB_HEADERS,
- outs = _ZLIB_PREFIXED_HEADERS,
- cmd = "cp $(SRCS) $(@D)/zlib/include/",
- visibility = ["//visibility:private"],
-)
-
-cc_library(
- name = "zlib",
- srcs = [
- "adler32.c",
- "compress.c",
- "crc32.c",
- "deflate.c",
- "gzclose.c",
- "gzlib.c",
- "gzread.c",
- "gzwrite.c",
- "infback.c",
- "inffast.c",
- "inflate.c",
- "inftrees.c",
- "trees.c",
- "uncompr.c",
- "zutil.c",
- # Include the un-prefixed headers in srcs to work
- # around the fact that zlib isn't consistent in its
- # choice of <> or "" delimiter when including itself.
- ] + _ZLIB_HEADERS,
- hdrs = _ZLIB_PREFIXED_HEADERS,
- copts = [
- "-Wno-unused-variable",
- "-Wno-implicit-function-declaration",
- ],
- includes = ["zlib/include/"],
-)
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..8a18318f
--- /dev/null
+++ b/package.json
@@ -0,0 +1,26 @@
+{
+ "name": "gerrit",
+ "version": "3.1.0-SNAPSHOT",
+ "description": "Gerrit Code Review",
+ "dependencies": {},
+ "devDependencies": {
+ "eslint": "^5.16.0",
+ "eslint-config-google": "^0.13.0",
+ "eslint-plugin-html": "^5.0.5",
+ "fried-twinkie": "^0.2.2",
+ "typescript": "^2.x.x",
+ "web-component-tester": "^6.5.0"
+ },
+ "scripts": {
+ "start": "polygerrit-ui/run-server.sh",
+ "test": "WCT_HEADLESS_MODE=1 WCT_ARGS='--verbose -l chrome' ./polygerrit-ui/app/run_test.sh",
+ "eslint": "./node_modules/eslint/bin/eslint.js --ignore-pattern 'bower_components/' --ignore-pattern 'gr-linked-text' --ignore-pattern 'scripts/vendor' --ext .html,.js polygerrit-ui/app || exit 0",
+ "test-template": "./polygerrit-ui/app/run_template_test.sh"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://gerrit.googlesource.com/gerrit"
+ },
+ "author": "",
+ "license": "Apache-2.0"
+}
diff --git a/plugins/delete-project b/plugins/delete-project
index a4b777a..6e94a1f 160000
--- a/plugins/delete-project
+++ b/plugins/delete-project
@@ -1 +1 @@
-Subproject commit a4b777a173feb2cfaaad591e2fded37f15500e2b
+Subproject commit 6e94a1f4f09c5e0aef86bafd80be35fa8b2842e6
diff --git a/plugins/gitiles b/plugins/gitiles
index bf9313f..a58ae0b 160000
--- a/plugins/gitiles
+++ b/plugins/gitiles
@@ -1 +1 @@
-Subproject commit bf9313fc7dd5b913b4a6484799b899fde4ac3449
+Subproject commit a58ae0ba2c23576a68d457e00aaf0902f41e4bb9
diff --git a/plugins/hooks b/plugins/hooks
index 60fb334..1244739 160000
--- a/plugins/hooks
+++ b/plugins/hooks
@@ -1 +1 @@
-Subproject commit 60fb334f44329caca37d8aa0d43feba651c959b2
+Subproject commit 12447394c90141595ab630129e24ab66d2f39a17
diff --git a/plugins/plugin-manager b/plugins/plugin-manager
index ec349d1..a51055a 160000
--- a/plugins/plugin-manager
+++ b/plugins/plugin-manager
@@ -1 +1 @@
-Subproject commit ec349d12a0b52280a48a66d4c5adf20f900c2393
+Subproject commit a51055a8f3b71f2ccf634016c42eb5b8086a373b
diff --git a/plugins/replication b/plugins/replication
index 486e6f0..b447688 160000
--- a/plugins/replication
+++ b/plugins/replication
@@ -1 +1 @@
-Subproject commit 486e6f0dec5cf7981e750d79cda940314e67ff99
+Subproject commit b44768838ff462b373e932d3d5c340612e28f940
diff --git a/plugins/reviewnotes b/plugins/reviewnotes
index 3e74dbd..4365294 160000
--- a/plugins/reviewnotes
+++ b/plugins/reviewnotes
@@ -1 +1 @@
-Subproject commit 3e74dbd716f3834f1733c8d5aedec0ce2089d4c6
+Subproject commit 436529473abb0f7921a1c2b732577a0a955cddc9
diff --git a/plugins/webhooks b/plugins/webhooks
index 67d2588..8078749 160000
--- a/plugins/webhooks
+++ b/plugins/webhooks
@@ -1 +1 @@
-Subproject commit 67d258822cd33ee7d7ea10679e60cca2c1f1fd29
+Subproject commit 8078749bfd64d9dcd3372bc3f8965d192747c5b4
diff --git a/polygerrit-ui/README.md b/polygerrit-ui/README.md
index c8c8e4f..9ceda8c 100644
--- a/polygerrit-ui/README.md
+++ b/polygerrit-ui/README.md
@@ -31,14 +31,8 @@
dependencies can be installed with:
```sh
-sudo npm install -g \
- eslint \
- eslint-config-google \
- eslint-plugin-html \
- typescript \
- fried-twinkie \
- polylint \
- web-component-tester
+npm install
+sudo npm install -g polylint
```
It may complain about a missing `typescript@2.3.4` peer dependency, which is
@@ -52,7 +46,7 @@
simply execute:
```sh
-./run-server.sh
+./polygerrit-ui/run-server.sh
```
Then visit <http://localhost:8081>.
@@ -65,7 +59,7 @@
the command line:
```sh
-./run-server.sh --plugins=plugins/my_plugin/static/my_plugin.js,plugins/my_plugin/static/my_plugin.html
+./polygerrit-ui/run-server.sh --plugins=plugins/my_plugin/static/my_plugin.js,plugins/my_plugin/static/my_plugin.html
```
The biggest draw back of this method is that you cannot log in, so cannot test
@@ -95,6 +89,7 @@
```sh
$(bazel info output_base)/external/local_jdk/bin/java \
+ -DsourceRoot=$(bazel info workspace) \
-jar bazel-bin/gerrit.war daemon \
-d $GERRIT_SITE \
--console-log \
@@ -115,10 +110,10 @@
changes are picked up on "reload".
Our CI integration ensures that all tests are run when you upload a change to
-Gerrit, but you can also run all tests locally:
+Gerrit, but you can also run all tests locally in headless mode:
```sh
-./polygerrit-ui/app/run_test.sh
+npm test
```
To allow the tests to run in Safari:
@@ -126,17 +121,10 @@
* In the Advanced preferences tab, check "Show Develop menu in menu bar".
* In the Develop menu, enable the "Allow Remote Automation" option.
-If you need to pass additional arguments to `wct`:
-
-```sh
-WCT_ARGS='-p --some-flag="foo bar"' ./polygerrit-ui/app/run_test.sh
-```
-
-
To run Chrome tests in headless mode:
```sh
-WCT_HEADLESS_MODE=1 ./polygerrit-ui/app/run_test.sh
+WCT_HEADLESS_MODE=1 WCT_ARGS='--verbose -l chrome' ./polygerrit-ui/app/run_test.sh
```
## Style guide
@@ -162,11 +150,22 @@
Some useful commands:
* To run ESLint on the whole app, less some dependency code:
-`eslint --ignore-pattern 'bower_components/' --ignore-pattern 'gr-linked-text' --ignore-pattern 'scripts/vendor' --ext .html,.js polygerrit-ui/app`
+
+```sh
+npm run eslint
+```
+
* To run ESLint on just the subdirectory you modified:
-`eslint --ext .html,.js polygerrit-ui/app/$YOUR_DIR_HERE`
+
+```sh
+node_modules/eslint/bin/eslint.js --ext .html,.js polygerrit-ui/app/$YOUR_DIR_HERE
+```
+
* To run the linter on all of your local changes:
-`git diff --name-only master | xargs eslint --ext .html,.js`
+
+```sh
+git diff --name-only master | xargs node_modules/eslint/bin/eslint.js --ext .html,.js
+```
We also use the `polylint` tool to lint use of Polymer. To install polylint,
execute the following command.
@@ -194,6 +193,12 @@
./polygerrit-ui/app/run_template_test.sh
```
+or
+
+```sh
+npm run test-template
+```
+
To run on a specific top level directory (ex: change-list)
```sh
TEMPLATE_NO_DEFAULT=true ./polygerrit-ui/app/run_template_test.sh //polygerrit-ui/app:template_test_change-list
diff --git a/polygerrit-ui/app/BUILD b/polygerrit-ui/app/BUILD
index 19bdcee..6d30a14 100644
--- a/polygerrit-ui/app/BUILD
+++ b/polygerrit-ui/app/BUILD
@@ -51,7 +51,7 @@
[
"bower_components/**/*.html",
"bower_components/**/*.js",
- "bower_components/**/*.map",
+ "bower_components/**/*.js.map",
],
),
)
@@ -191,7 +191,7 @@
"embed/test.html",
"test/common-test-setup.html",
":embed_test_files",
- ":polygerrit_embed_ui.zip",
+ ":pg_code.zip",
":test_components.zip",
],
# Should not run sandboxed.
diff --git a/polygerrit-ui/app/behaviors/async-foreach-behavior/async-foreach-behavior_test.html b/polygerrit-ui/app/behaviors/async-foreach-behavior/async-foreach-behavior_test.html
index fec459b..970bfc7 100644
--- a/polygerrit-ui/app/behaviors/async-foreach-behavior/async-foreach-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/async-foreach-behavior/async-foreach-behavior_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>async-foreach-behavior</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
-<script src="../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="async-foreach-behavior.html">
diff --git a/polygerrit-ui/app/behaviors/base-url-behavior/base-url-behavior_test.html b/polygerrit-ui/app/behaviors/base-url-behavior/base-url-behavior_test.html
index c21e96f..8a76d9d 100644
--- a/polygerrit-ui/app/behaviors/base-url-behavior/base-url-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/base-url-behavior/base-url-behavior_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>base-url-behavior</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
-<script src="../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<script>
/** @type {string} */
diff --git a/polygerrit-ui/app/behaviors/docs-url-behavior/docs-url-behavior_test.html b/polygerrit-ui/app/behaviors/docs-url-behavior/docs-url-behavior_test.html
index 96d4a08..4f16e79 100644
--- a/polygerrit-ui/app/behaviors/docs-url-behavior/docs-url-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/docs-url-behavior/docs-url-behavior_test.html
@@ -15,10 +15,12 @@
limitations under the License.
-->
<!-- Polymer included for the html import polyfill. -->
-<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
-<script src="../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<title>docs-url-behavior</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<link rel="import" href="docs-url-behavior.html">
diff --git a/polygerrit-ui/app/behaviors/dom-util-behavior/dom-util-behavior_test.html b/polygerrit-ui/app/behaviors/dom-util-behavior/dom-util-behavior_test.html
index e445a78..15affee 100644
--- a/polygerrit-ui/app/behaviors/dom-util-behavior/dom-util-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/dom-util-behavior/dom-util-behavior_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>dom-util-behavior</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
-<script src="../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="dom-util-behavior.html">
diff --git a/polygerrit-ui/app/behaviors/gr-access-behavior/gr-access-behavior_test.html b/polygerrit-ui/app/behaviors/gr-access-behavior/gr-access-behavior_test.html
index 0b37a0d..817d26e 100644
--- a/polygerrit-ui/app/behaviors/gr-access-behavior/gr-access-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/gr-access-behavior/gr-access-behavior_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>keyboard-shortcut-behavior</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
-<script src="../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="gr-access-behavior.html">
diff --git a/polygerrit-ui/app/behaviors/gr-admin-nav-behavior/gr-admin-nav-behavior_test.html b/polygerrit-ui/app/behaviors/gr-admin-nav-behavior/gr-admin-nav-behavior_test.html
index 7c23c00..60817aa 100644
--- a/polygerrit-ui/app/behaviors/gr-admin-nav-behavior/gr-admin-nav-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/gr-admin-nav-behavior/gr-admin-nav-behavior_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>keyboard-shortcut-behavior</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
-<script src="../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="gr-admin-nav-behavior.html">
diff --git a/polygerrit-ui/app/behaviors/gr-anonymous-name-behavior/gr-anonymous-name-behavior_test.html b/polygerrit-ui/app/behaviors/gr-anonymous-name-behavior/gr-anonymous-name-behavior_test.html
index 820d6bc..64f0b3a 100644
--- a/polygerrit-ui/app/behaviors/gr-anonymous-name-behavior/gr-anonymous-name-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/gr-anonymous-name-behavior/gr-anonymous-name-behavior_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-anonymous-name-behavior</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
-<script src="../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="gr-anonymous-name-behavior.html">
diff --git a/polygerrit-ui/app/behaviors/gr-change-table-behavior/gr-change-table-behavior_test.html b/polygerrit-ui/app/behaviors/gr-change-table-behavior/gr-change-table-behavior_test.html
index b052d06..9b7339d 100644
--- a/polygerrit-ui/app/behaviors/gr-change-table-behavior/gr-change-table-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/gr-change-table-behavior/gr-change-table-behavior_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>keyboard-shortcut-behavior</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
-<script src="../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="gr-change-table-behavior.html">
diff --git a/polygerrit-ui/app/behaviors/gr-list-view-behavior/gr-list-view-behavior_test.html b/polygerrit-ui/app/behaviors/gr-list-view-behavior/gr-list-view-behavior_test.html
index f6c765f..9973ae8 100644
--- a/polygerrit-ui/app/behaviors/gr-list-view-behavior/gr-list-view-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/gr-list-view-behavior/gr-list-view-behavior_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>keyboard-shortcut-behavior</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
-<script src="../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="gr-list-view-behavior.html">
diff --git a/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior_test.html b/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior_test.html
index b858c51..3db4084 100644
--- a/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior_test.html
@@ -15,10 +15,12 @@
limitations under the License.
-->
<!-- Polymer included for the html import polyfill. -->
-<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
-<script src="../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<title>gr-patch-set-behavior</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<link rel="import" href="gr-patch-set-behavior.html">
diff --git a/polygerrit-ui/app/behaviors/gr-path-list-behavior/gr-path-list-behavior_test.html b/polygerrit-ui/app/behaviors/gr-path-list-behavior/gr-path-list-behavior_test.html
index 75c2433..0046290 100644
--- a/polygerrit-ui/app/behaviors/gr-path-list-behavior/gr-path-list-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/gr-path-list-behavior/gr-path-list-behavior_test.html
@@ -15,10 +15,12 @@
limitations under the License.
-->
<!-- Polymer included for the html import polyfill. -->
-<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
-<script src="../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<title>gr-path-list-behavior</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
<link rel="import" href="gr-path-list-behavior.html">
diff --git a/polygerrit-ui/app/behaviors/gr-tooltip-behavior/gr-tooltip-behavior.html b/polygerrit-ui/app/behaviors/gr-tooltip-behavior/gr-tooltip-behavior.html
index 07d3484..0e2e99f 100644
--- a/polygerrit-ui/app/behaviors/gr-tooltip-behavior/gr-tooltip-behavior.html
+++ b/polygerrit-ui/app/behaviors/gr-tooltip-behavior/gr-tooltip-behavior.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../elements/shared/gr-tooltip/gr-tooltip.html">
<script src="../../scripts/rootElement.js"></script>
diff --git a/polygerrit-ui/app/behaviors/gr-tooltip-behavior/gr-tooltip-behavior_test.html b/polygerrit-ui/app/behaviors/gr-tooltip-behavior/gr-tooltip-behavior_test.html
index 943e000..2c4b376 100644
--- a/polygerrit-ui/app/behaviors/gr-tooltip-behavior/gr-tooltip-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/gr-tooltip-behavior/gr-tooltip-behavior_test.html
@@ -17,9 +17,11 @@
-->
<title>tooltip-behavior</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
-<script src="../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="gr-tooltip-behavior.html">
diff --git a/polygerrit-ui/app/behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior_test.html b/polygerrit-ui/app/behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior_test.html
index d909e86..8601397 100644
--- a/polygerrit-ui/app/behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior_test.html
@@ -17,9 +17,11 @@
-->
<title>gr-url-encoding-behavior</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
-<script src="../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="gr-url-encoding-behavior.html">
diff --git a/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html b/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html
index 4266b22..51adf2e 100644
--- a/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html
+++ b/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html
@@ -96,8 +96,8 @@
NOTE: doc-only shortcuts will not be customizable in the same way that other
shortcuts are.
-->
-<link rel="import" href="../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../bower_components/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
<script>
(function(window) {
diff --git a/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior_test.html b/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior_test.html
index d013299..9d5481d 100644
--- a/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>keyboard-shortcut-behavior</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
-<script src="../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="keyboard-shortcut-behavior.html">
diff --git a/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior.html b/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior.html
index 2cb00f4..88aea2d 100644
--- a/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior.html
+++ b/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../base-url-behavior/base-url-behavior.html">
<script>
(function(window) {
diff --git a/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior_test.html b/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior_test.html
index 6af43dc..013ec2e 100644
--- a/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>keyboard-shortcut-behavior</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
-<script src="../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<script>
/** @type {string} */
diff --git a/polygerrit-ui/app/behaviors/safe-types-behavior/safe-types-behavior.html b/polygerrit-ui/app/behaviors/safe-types-behavior/safe-types-behavior.html
index 68000bc..43022d9 100644
--- a/polygerrit-ui/app/behaviors/safe-types-behavior/safe-types-behavior.html
+++ b/polygerrit-ui/app/behaviors/safe-types-behavior/safe-types-behavior.html
@@ -23,7 +23,7 @@
/** @polymerBehavior Gerrit.SafeTypes */
Gerrit.SafeTypes = {};
- const SAFE_URL_PATTERN = /^(https?:\/\/|mailto:|\/|#)/i;
+ const SAFE_URL_PATTERN = /^(https?:\/\/|mailto:|[^:/?#]*(?:[/?#]|$))/i;
/**
* Wraps a string to be used as a URL. An error is thrown if the string cannot
diff --git a/polygerrit-ui/app/behaviors/safe-types-behavior/safe-types-behavior_test.html b/polygerrit-ui/app/behaviors/safe-types-behavior/safe-types-behavior_test.html
index 6e040a3..5d949a5 100644
--- a/polygerrit-ui/app/behaviors/safe-types-behavior/safe-types-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/safe-types-behavior/safe-types-behavior_test.html
@@ -17,9 +17,11 @@
-->
<title>safe-types-behavior</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../bower_components/webcomponentsjs/webcomponents.min.js"></script>
-<script src="../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../test/common-test-setup.html"/>
<link rel="import" href="safe-types-behavior.html">
@@ -119,4 +121,4 @@
});
});
});
-</script>
\ No newline at end of file
+</script>
diff --git a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.html b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.html
index 45bc5f6..398ed9c 100644
--- a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.html
+++ b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.html
@@ -15,10 +15,10 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-access-behavior/gr-access-behavior.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.js b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.js
index 6adf127..41ce201 100644
--- a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.js
+++ b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section.js
@@ -95,7 +95,8 @@
// For a new section, this is not fired because new permissions and
// rules have to be added in order to save, modifying the ref is not
// enough.
- this.dispatchEvent(new CustomEvent('access-modified', {bubbles: true}));
+ this.dispatchEvent(new CustomEvent(
+ 'access-modified', {bubbles: true, composed: true}));
}
this.section.value.updatedId = this.section.id;
},
@@ -199,12 +200,13 @@
_handleRemoveReference() {
if (this.section.value.added) {
- this.dispatchEvent(new CustomEvent('added-section-removed',
- {bubbles: true}));
+ this.dispatchEvent(new CustomEvent(
+ 'added-section-removed', {bubbles: true, composed: true}));
}
this._deleted = true;
this.section.value.deleted = true;
- this.dispatchEvent(new CustomEvent('access-modified', {bubbles: true}));
+ this.dispatchEvent(
+ new CustomEvent('access-modified', {bubbles: true, composed: true}));
},
_handleUndoRemove() {
diff --git a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section_test.html b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section_test.html
index 21a426f..6b08ed3 100644
--- a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section_test.html
@@ -18,10 +18,12 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-access-section</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/page/page.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/page/page.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-access-section.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.html b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.html
index ea08d89..c448f5b 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.html
+++ b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.html
@@ -15,10 +15,10 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-list-view-behavior/gr-list-view-behavior.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../../styles/gr-table-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_test.html b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_test.html
index 065a757..58c7be4 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_test.html
@@ -18,10 +18,12 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-admin-group-list</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/page/page.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/page/page.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html
index b6a6d27..f70025d 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-admin-nav-behavior/gr-admin-nav-behavior.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
index 56079e3..178d056 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-admin-view</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-admin-view.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.html b/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.html
index 3873083..b7932dd 100644
--- a/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.html
+++ b/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-dialog/gr-dialog.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog_test.html b/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog_test.html
index d735acb..cf9e0fa 100644
--- a/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-confirm-delete-item-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-confirm-delete-item-dialog.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog.html b/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog.html
index da1c871..252dcfd 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog.html
+++ b/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog.html
@@ -15,9 +15,9 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog_test.html b/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog_test.html
index aa4da68..3a3683f 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-create-change-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-create-change-dialog.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog.html b/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog.html
index d96a935..73a3f4e 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog.html
+++ b/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog.html
@@ -15,11 +15,11 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog_test.html b/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog_test.html
index 95ffdb1..300440e 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog_test.html
@@ -18,10 +18,12 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-create-group-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/page/page.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/page/page.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-create-group-dialog.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-create-pointer-dialog/gr-create-pointer-dialog.html b/polygerrit-ui/app/elements/admin/gr-create-pointer-dialog/gr-create-pointer-dialog.html
index 0557021..a1fbd37 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-pointer-dialog/gr-create-pointer-dialog.html
+++ b/polygerrit-ui/app/elements/admin/gr-create-pointer-dialog/gr-create-pointer-dialog.html
@@ -15,11 +15,11 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-create-pointer-dialog/gr-create-pointer-dialog_test.html b/polygerrit-ui/app/elements/admin/gr-create-pointer-dialog/gr-create-pointer-dialog_test.html
index 39e200a..77cce5a 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-pointer-dialog/gr-create-pointer-dialog_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-create-pointer-dialog/gr-create-pointer-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-create-pointer-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-create-pointer-dialog.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog.html b/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog.html
index b38fab5..0feeced 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog.html
+++ b/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog.html
@@ -15,11 +15,11 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-autocomplete/gr-autocomplete.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog_test.html b/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog_test.html
index 79079f5..7e32c5c 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-create-repo-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-create-repo-dialog.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log.html b/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log.html
index 05b176c..071beda 100644
--- a/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log.html
+++ b/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log.html
@@ -16,7 +16,7 @@
-->
<link rel="import" href="../../../behaviors/gr-list-view-behavior/gr-list-view-behavior.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/gr-table-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log_test.html b/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log_test.html
index 59a665b..313d465 100644
--- a/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-group-audit-log</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-group-audit-log.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.html b/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.html
index bcfc9e1..787f2b4 100644
--- a/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.html
+++ b/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.html
@@ -17,9 +17,9 @@
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../../styles/gr-subpage-styles.html">
<link rel="import" href="../../../styles/gr-table-styles.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.js b/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.js
index 76bd558..8a262b8 100644
--- a/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.js
+++ b/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members.js
@@ -205,6 +205,7 @@
this.dispatchEvent(new CustomEvent('show-alert', {
detail: {message: SAVING_ERROR_TEXT},
bubbles: true,
+ composed: true,
}));
return err;
}
diff --git a/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members_test.html b/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members_test.html
index b86d971..15a59c8 100644
--- a/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-group-members</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-group-members.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-group/gr-group.html b/polygerrit-ui/app/elements/admin/gr-group/gr-group.html
index b92dc4b..9f49e4b 100644
--- a/polygerrit-ui/app/elements/admin/gr-group/gr-group.html
+++ b/polygerrit-ui/app/elements/admin/gr-group/gr-group.html
@@ -15,9 +15,9 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../../styles/gr-subpage-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-group/gr-group_test.html b/polygerrit-ui/app/elements/admin/gr-group/gr-group_test.html
index 226f3ab..1672e85 100644
--- a/polygerrit-ui/app/elements/admin/gr-group/gr-group_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-group/gr-group_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-group</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-group.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.html b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.html
index a5bb5fd..78c30ff 100644
--- a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.html
+++ b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.html
@@ -15,9 +15,9 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-access-behavior/gr-access-behavior.html">
-<link rel="import" href="../../../bower_components/paper-toggle-button/paper-toggle-button.html">
+<link rel="import" href="/bower_components/paper-toggle-button/paper-toggle-button.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../../styles/gr-menu-page-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.js b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.js
index a131f4f..1c408df 100644
--- a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.js
+++ b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission.js
@@ -137,17 +137,19 @@
_handleValueChange() {
this.permission.value.modified = true;
// Allows overall access page to know a change has been made.
- this.dispatchEvent(new CustomEvent('access-modified', {bubbles: true}));
+ this.dispatchEvent(
+ new CustomEvent('access-modified', {bubbles: true, composed: true}));
},
_handleRemovePermission() {
if (this.permission.value.added) {
- this.dispatchEvent(new CustomEvent('added-permission-removed',
- {bubbles: true}));
+ this.dispatchEvent(new CustomEvent(
+ 'added-permission-removed', {bubbles: true, composed: true}));
}
this._deleted = true;
this.permission.value.deleted = true;
- this.dispatchEvent(new CustomEvent('access-modified', {bubbles: true}));
+ this.dispatchEvent(
+ new CustomEvent('access-modified', {bubbles: true, composed: true}));
},
_handleRulesChanged(changeRecord) {
@@ -273,7 +275,8 @@
const value = this._rules[this._rules.length - 1].value;
value.added = true;
this.set(['permission', 'value', 'rules', groupId], value);
- this.dispatchEvent(new CustomEvent('access-modified', {bubbles: true}));
+ this.dispatchEvent(
+ new CustomEvent('access-modified', {bubbles: true, composed: true}));
},
_computeHasRange(name) {
diff --git a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.html b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.html
index 5f1f9b5..8e57534 100644
--- a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.html
@@ -18,10 +18,12 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-permission</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/page/page.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/page/page.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-permission.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor.html b/polygerrit-ui/app/elements/admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor.html
index ca98c50..2625d65 100644
--- a/polygerrit-ui/app/elements/admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor.html
+++ b/polygerrit-ui/app/elements/admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor.html
@@ -15,10 +15,10 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
-<link rel="import" href="../../../bower_components/paper-toggle-button/paper-toggle-button.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/paper-toggle-button/paper-toggle-button.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor_test.html b/polygerrit-ui/app/elements/admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor_test.html
index dc3f67e..39e4ddc 100644
--- a/polygerrit-ui/app/elements/admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-plugin-config-array-editor</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-plugin-config-array-editor.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-plugin-list/gr-plugin-list.html b/polygerrit-ui/app/elements/admin/gr-plugin-list/gr-plugin-list.html
index 9e4396a..26f37e1 100644
--- a/polygerrit-ui/app/elements/admin/gr-plugin-list/gr-plugin-list.html
+++ b/polygerrit-ui/app/elements/admin/gr-plugin-list/gr-plugin-list.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-list-view-behavior/gr-list-view-behavior.html">
<link rel="import" href="../../../styles/gr-table-styles.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-plugin-list/gr-plugin-list_test.html b/polygerrit-ui/app/elements/admin/gr-plugin-list/gr-plugin-list_test.html
index 9781cf7..96fff60 100644
--- a/polygerrit-ui/app/elements/admin/gr-plugin-list/gr-plugin-list_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-plugin-list/gr-plugin-list_test.html
@@ -18,10 +18,12 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-plugin-list</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/page/page.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/page/page.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-plugin-list.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.html b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.html
index b6e56de..40d32d4 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-access-behavior/gr-access-behavior.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.js b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.js
index 713bf02..7d2890a 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access.js
@@ -406,8 +406,11 @@
if (!Object.keys(addRemoveObj.add).length &&
!Object.keys(addRemoveObj.remove).length &&
!addRemoveObj.parent) {
- this.dispatchEvent(new CustomEvent('show-alert',
- {detail: {message: NOTHING_TO_SAVE}, bubbles: true}));
+ this.dispatchEvent(new CustomEvent('show-alert', {
+ detail: {message: NOTHING_TO_SAVE},
+ bubbles: true,
+ composed: true,
+ }));
return;
}
const obj = {
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.html b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.html
index 20e2b8e..abd11d6 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.html
@@ -18,10 +18,12 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-repo-access</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/page/page.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/page/page.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-repo-access.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command.html b/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command.html
index 7db4e4c..49ff186 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command.js b/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command.js
index e0becaf..04d9781 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command.js
@@ -34,7 +34,8 @@
*/
_onCommandTap() {
- this.dispatchEvent(new CustomEvent('command-tap', {bubbles: true}));
+ this.dispatchEvent(
+ new CustomEvent('command-tap', {bubbles: true, composed: true}));
},
});
})();
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command_test.html b/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command_test.html
index 9f9ac92..49d8765 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-command/gr-repo-command_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-repo-command</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-repo-command.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.html b/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.html
index dba01aa..ea4d165 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.html
@@ -15,9 +15,9 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../../styles/gr-subpage-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.js b/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.js
index 92b11fc..169672a 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands.js
@@ -75,8 +75,9 @@
_handleRunningGC() {
return this.$.restAPI.runRepoGC(this.repo).then(response => {
if (response.status === 200) {
- this.dispatchEvent(new CustomEvent('show-alert',
- {detail: {message: GC_MESSAGE}, bubbles: true}));
+ this.dispatchEvent(new CustomEvent(
+ 'show-alert',
+ {detail: {message: GC_MESSAGE}, bubbles: true, composed: true}));
}
});
},
@@ -100,8 +101,9 @@
const message = change ?
CREATE_CHANGE_SUCCEEDED_MESSAGE :
CREATE_CHANGE_FAILED_MESSAGE;
- this.dispatchEvent(new CustomEvent('show-alert',
- {detail: {message}, bubbles: true}));
+ this.dispatchEvent(new CustomEvent(
+ 'show-alert',
+ {detail: {message}, bubbles: true, composed: true}));
if (!change) { return; }
Gerrit.Nav.navigateToRelativeUrl(Gerrit.Nav.getEditUrlForDiff(
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands_test.html b/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands_test.html
index 76c65e8..2976923 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands_test.html
@@ -18,10 +18,12 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-repo-commands</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/page/page.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/page/page.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-repo-commands.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-dashboards/gr-repo-dashboards.html b/polygerrit-ui/app/elements/admin/gr-repo-dashboards/gr-repo-dashboards.html
index 1d49db9..6cc0958 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-dashboards/gr-repo-dashboards.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-dashboards/gr-repo-dashboards.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-dashboards/gr-repo-dashboards_test.html b/polygerrit-ui/app/elements/admin/gr-repo-dashboards/gr-repo-dashboards_test.html
index 94bf5e0..4f76983 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-dashboards/gr-repo-dashboards_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-dashboards/gr-repo-dashboards_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-repo-dashboards</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-repo-dashboards.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list.html b/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list.html
index fccfa6a..44b94e1 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list.html
@@ -17,8 +17,8 @@
<link rel="import" href="../../../behaviors/gr-list-view-behavior/gr-list-view-behavior.html">
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../../styles/gr-table-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list_test.html b/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list_test.html
index 5d2a9ad..d8d4f7c 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list_test.html
@@ -18,10 +18,12 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-repo-detail-list</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/page/page.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/page/page.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-repo-detail-list.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.html b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.html
index 0490db2..1a728ab 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.html
@@ -14,10 +14,10 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-list-view-behavior/gr-list-view-behavior.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../../styles/gr-table-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-dialog/gr-dialog.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.html b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.html
index 4bc023f..c77592c 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.html
@@ -18,10 +18,12 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-repo-list</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/page/page.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/page/page.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-repo-list.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config.html b/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config.html
index 7f2cbe7..69c86d9 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config.html
@@ -15,9 +15,9 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
-<link rel="import" href="../../../bower_components/paper-toggle-button/paper-toggle-button.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/paper-toggle-button/paper-toggle-button.html">
<link rel="import" href="../../../behaviors/gr-repo-plugin-config-behavior/gr-repo-plugin-config-behavior.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config.js b/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config.js
index 6d7677e..883a4e1 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config.js
@@ -123,8 +123,8 @@
notifyPath: `${name}.${notifyPath}`,
};
- this.dispatchEvent(new CustomEvent(this.PLUGIN_CONFIG_CHANGED,
- {detail, bubbles: true}));
+ this.dispatchEvent(new CustomEvent(
+ this.PLUGIN_CONFIG_CHANGED, {detail, bubbles: true, composed: true}));
},
});
})();
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config_test.html b/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config_test.html
index 2af2043..07da7c7 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-repo-plugin-config</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-repo-plugin-config.html">
@@ -151,7 +153,8 @@
const select = element.$$('select');
assert.ok(select);
select.value = 'newTest';
- select.dispatchEvent(new Event('change', {bubbles: true}));
+ select.dispatchEvent(new Event(
+ 'change', {bubbles: true, composed: true}));
flushAsynchronousOperations();
assert.isTrue(buildStub.called);
diff --git a/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.html b/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.html
index cd27322..f6b6d29 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.html
@@ -15,9 +15,9 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../plugins/gr-endpoint-decorator/gr-endpoint-decorator.html">
<link rel="import" href="../../shared/gr-download-commands/gr-download-commands.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-repo/gr-repo_test.html b/polygerrit-ui/app/elements/admin/gr-repo/gr-repo_test.html
index c987278..8c77ae0 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo/gr-repo_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo/gr-repo_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-repo</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-repo.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor.html b/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor.html
index c8ae650..7ba541f 100644
--- a/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor.html
+++ b/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-access-behavior/gr-access-behavior.html">
diff --git a/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor.js b/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor.js
index a45b391..4102747 100644
--- a/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor.js
+++ b/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor.js
@@ -210,12 +210,13 @@
_handleRemoveRule() {
if (this.rule.value.added) {
- this.dispatchEvent(new CustomEvent('added-rule-removed',
- {bubbles: true}));
+ this.dispatchEvent(new CustomEvent(
+ 'added-rule-removed', {bubbles: true, composed: true}));
}
this._deleted = true;
this.rule.value.deleted = true;
- this.dispatchEvent(new CustomEvent('access-modified', {bubbles: true}));
+ this.dispatchEvent(
+ new CustomEvent('access-modified', {bubbles: true, composed: true}));
},
_handleUndoRemove() {
@@ -237,7 +238,8 @@
if (!this._originalRuleValues) { return; }
this.rule.value.modified = true;
// Allows overall access page to know a change has been made.
- this.dispatchEvent(new CustomEvent('access-modified', {bubbles: true}));
+ this.dispatchEvent(
+ new CustomEvent('access-modified', {bubbles: true, composed: true}));
},
_setOriginalRuleValues(value) {
diff --git a/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor_test.html b/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor_test.html
index f85c2b2..17e8c6c 100644
--- a/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor_test.html
@@ -18,10 +18,12 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-rule-editor</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/page/page.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/page/page.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-rule-editor.html">
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.html b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.html
index 02a2a08..eaba285 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.html
@@ -19,7 +19,7 @@
<link rel="import" href="../../../behaviors/gr-path-list-behavior/gr-path-list-behavior.html">
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.html">
<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/gr-change-list-styles.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../../shared/gr-account-link/gr-account-link.html">
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
index ecc7532..5d15d60 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item.js
@@ -214,6 +214,7 @@
this.set('change.reviewed', newVal);
this.dispatchEvent(new CustomEvent('toggle-reviewed', {
bubbles: true,
+ composed: true,
detail: {change: this.change, reviewed: newVal},
}));
},
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html
index 3637653..df4a442 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-change-list-item</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="../../../scripts/util.js"></script>
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.html b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.html
index 48d5075..1ca5668 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view.html
@@ -17,7 +17,7 @@
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../../shared/gr-icons/gr-icons.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view_test.html b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view_test.html
index 3911364..2367aac 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view_test.html
@@ -18,10 +18,12 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-change-list-view</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/page/page.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/page/page.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-change-list-view.html">
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.html b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.html
index ef17baa..6167630 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.html
@@ -20,7 +20,7 @@
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/gr-change-list-styles.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../../shared/gr-cursor-manager/gr-cursor-manager.html">
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
index d5b9aa9..dce2a55 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
@@ -18,11 +18,13 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-change-list</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
-<script src="../../../bower_components/page/page.js"></script>
+<script src="/bower_components/page/page.js"></script>
<link rel="import" href="gr-change-list.html">
diff --git a/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help.html b/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help.html
index ecbd67e..11493f4 100644
--- a/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help.html
+++ b/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
diff --git a/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help.js b/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help.js
index 42d7bd7..b9df583b 100644
--- a/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help.js
+++ b/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help.js
@@ -29,7 +29,8 @@
_handleCreateTap(e) {
e.preventDefault();
- this.dispatchEvent(new CustomEvent('create-tap', {bubbles: true}));
+ this.dispatchEvent(
+ new CustomEvent('create-tap', {bubbles: true, composed: true}));
},
});
})();
diff --git a/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help_test.html b/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help_test.html
index 09d95fd..c43d62a 100644
--- a/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-create-change-help</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="../../../scripts/util.js"></script>
diff --git a/polygerrit-ui/app/elements/change-list/gr-create-commands-dialog/gr-create-commands-dialog.html b/polygerrit-ui/app/elements/change-list/gr-create-commands-dialog/gr-create-commands-dialog.html
index e6d123c..4cef6f7 100644
--- a/polygerrit-ui/app/elements/change-list/gr-create-commands-dialog/gr-create-commands-dialog.html
+++ b/polygerrit-ui/app/elements/change-list/gr-create-commands-dialog/gr-create-commands-dialog.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-dialog/gr-dialog.html">
<link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
<link rel="import" href="../../shared/gr-shell-command/gr-shell-command.html">
diff --git a/polygerrit-ui/app/elements/change-list/gr-create-commands-dialog/gr-create-commands-dialog_test.html b/polygerrit-ui/app/elements/change-list/gr-create-commands-dialog/gr-create-commands-dialog_test.html
index e00037d..89ad573 100644
--- a/polygerrit-ui/app/elements/change-list/gr-create-commands-dialog/gr-create-commands-dialog_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-create-commands-dialog/gr-create-commands-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-create-commands-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-create-commands-dialog.html">
diff --git a/polygerrit-ui/app/elements/change-list/gr-create-destination-dialog/gr-create-destination-dialog.html b/polygerrit-ui/app/elements/change-list/gr-create-destination-dialog/gr-create-destination-dialog.html
index d12d84b..def5228 100644
--- a/polygerrit-ui/app/elements/change-list/gr-create-destination-dialog/gr-create-destination-dialog.html
+++ b/polygerrit-ui/app/elements/change-list/gr-create-destination-dialog/gr-create-destination-dialog.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-dialog/gr-dialog.html">
<link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
<link rel="import" href="../../shared/gr-repo-branch-picker/gr-repo-branch-picker.html">
diff --git a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.html b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.html
index b0ba8a2b..4360d5d 100644
--- a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.html
+++ b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../change-list/gr-change-list/gr-change-list.html">
diff --git a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html
index 618ec65..f9eb256 100644
--- a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-dashboard-view</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-dashboard-view.html">
diff --git a/polygerrit-ui/app/elements/change-list/gr-embed-dashboard/gr-embed-dashboard.html b/polygerrit-ui/app/elements/change-list/gr-embed-dashboard/gr-embed-dashboard.html
index 2394e24..d445185 100644
--- a/polygerrit-ui/app/elements/change-list/gr-embed-dashboard/gr-embed-dashboard.html
+++ b/polygerrit-ui/app/elements/change-list/gr-embed-dashboard/gr-embed-dashboard.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../change-list/gr-change-list/gr-change-list.html">
<link rel="import" href="../gr-create-change-help/gr-create-change-help.html">
diff --git a/polygerrit-ui/app/elements/change-list/gr-repo-header/gr-repo-header.html b/polygerrit-ui/app/elements/change-list/gr-repo-header/gr-repo-header.html
index 2328725..0b4459c 100644
--- a/polygerrit-ui/app/elements/change-list/gr-repo-header/gr-repo-header.html
+++ b/polygerrit-ui/app/elements/change-list/gr-repo-header/gr-repo-header.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/dashboard-header-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
diff --git a/polygerrit-ui/app/elements/change-list/gr-repo-header/gr-repo-header_test.html b/polygerrit-ui/app/elements/change-list/gr-repo-header/gr-repo-header_test.html
index a561e09..49af1b4 100644
--- a/polygerrit-ui/app/elements/change-list/gr-repo-header/gr-repo-header_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-repo-header/gr-repo-header_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-repo-header</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-repo-header.html">
diff --git a/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header.html b/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header.html
index 89e2b7d..49faad5 100644
--- a/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header.html
+++ b/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../../shared/gr-avatar/gr-avatar.html">
<link rel="import" href="../../shared/gr-date-formatter/gr-date-formatter.html">
diff --git a/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header_test.html b/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header_test.html
index c33be3b..e837a5b 100644
--- a/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-user-header</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-user-header.html">
diff --git a/polygerrit-ui/app/elements/change/gr-account-entry/gr-account-entry.html b/polygerrit-ui/app/elements/change/gr-account-entry/gr-account-entry.html
index 582c83b..95ef881 100644
--- a/polygerrit-ui/app/elements/change/gr-account-entry/gr-account-entry.html
+++ b/polygerrit-ui/app/elements/change/gr-account-entry/gr-account-entry.html
@@ -16,7 +16,7 @@
-->
<link rel="import" href="../../../behaviors/gr-anonymous-name-behavior/gr-anonymous-name-behavior.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-autocomplete/gr-autocomplete.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/change/gr-account-entry/gr-account-entry.js b/polygerrit-ui/app/elements/change/gr-account-entry/gr-account-entry.js
index fc0b633..147d1f2 100644
--- a/polygerrit-ui/app/elements/change/gr-account-entry/gr-account-entry.js
+++ b/polygerrit-ui/app/elements/change/gr-account-entry/gr-account-entry.js
@@ -118,8 +118,8 @@
_inputTextChanged(text) {
if (text.length && this.allowAnyInput) {
- this.dispatchEvent(new CustomEvent('account-text-changed',
- {bubbles: true}));
+ this.dispatchEvent(new CustomEvent(
+ 'account-text-changed', {bubbles: true, composed: true}));
}
},
diff --git a/polygerrit-ui/app/elements/change/gr-account-entry/gr-account-entry_test.html b/polygerrit-ui/app/elements/change/gr-account-entry/gr-account-entry_test.html
index 20d127d..57bdd1d 100644
--- a/polygerrit-ui/app/elements/change/gr-account-entry/gr-account-entry_test.html
+++ b/polygerrit-ui/app/elements/change/gr-account-entry/gr-account-entry_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-account-entry</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="../../../scripts/util.js"></script>
diff --git a/polygerrit-ui/app/elements/change/gr-account-list/gr-account-list.html b/polygerrit-ui/app/elements/change/gr-account-list/gr-account-list.html
index 1bfc5eb..9cb936a 100644
--- a/polygerrit-ui/app/elements/change/gr-account-list/gr-account-list.html
+++ b/polygerrit-ui/app/elements/change/gr-account-list/gr-account-list.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-account-chip/gr-account-chip.html">
<link rel="import" href="../gr-account-entry/gr-account-entry.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/change/gr-account-list/gr-account-list.js b/polygerrit-ui/app/elements/change/gr-account-list/gr-account-list.js
index 533ae09..c10f3d5 100644
--- a/polygerrit-ui/app/elements/change/gr-account-list/gr-account-list.js
+++ b/polygerrit-ui/app/elements/change/gr-account-list/gr-account-list.js
@@ -123,8 +123,11 @@
// Repopulate the input with what the user tried to enter and have
// a toast tell them why they can't enter it.
this.$.entry.setText(reviewer);
- this.dispatchEvent(new CustomEvent('show-alert',
- {detail: {message: VALID_EMAIL_ALERT}, bubbles: true}));
+ this.dispatchEvent(new CustomEvent('show-alert', {
+ detail: {message: VALID_EMAIL_ALERT},
+ bubbles: true,
+ composed: true,
+ }));
return false;
} else {
const account = {email: reviewer, _pendingAdd: true};
diff --git a/polygerrit-ui/app/elements/change/gr-account-list/gr-account-list_test.html b/polygerrit-ui/app/elements/change/gr-account-list/gr-account-list_test.html
index 544238b..d32c269 100644
--- a/polygerrit-ui/app/elements/change/gr-account-list/gr-account-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-account-list/gr-account-list_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-account-list</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-account-list.html">
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.html b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.html
index 278875e..bcb0df4 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.html
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.html
@@ -15,11 +15,11 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../admin/gr-create-change-dialog/gr-create-change-dialog.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../../core/gr-reporting/gr-reporting.html">
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html
index 1d83819..184e175 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-change-actions</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="../../../scripts/util.js"></script>
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.html b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.html
index 5b36221..b2e8030 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-change-metadata</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="../../plugins/gr-plugin-host/gr-plugin-host.html">
<link rel="import" href="gr-change-metadata.html">
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.html b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.html
index c07a775..4d4ba3a 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.html
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../../styles/gr-voting-styles.html">
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
index 8ca8146..60f0dc2 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
@@ -221,8 +221,8 @@
this._settingTopic = false;
this.set(['change', 'topic'], newTopic);
if (newTopic !== lastTopic) {
- this.dispatchEvent(
- new CustomEvent('topic-changed', {bubbles: true}));
+ this.dispatchEvent(new CustomEvent(
+ 'topic-changed', {bubbles: true, composed: true}));
}
});
},
@@ -246,8 +246,8 @@
this.change._number, {add: [newHashtag]}).then(newHashtag => {
this.set(['change', 'hashtags'], newHashtag);
if (newHashtag !== lastHashtag) {
- this.dispatchEvent(
- new CustomEvent('hashtag-changed', {bubbles: true}));
+ this.dispatchEvent(new CustomEvent(
+ 'hashtag-changed', {bubbles: true, composed: true}));
}
});
},
@@ -378,7 +378,7 @@
target.disabled = false;
this.set(['change', 'topic'], '');
this.dispatchEvent(
- new CustomEvent('topic-changed', {bubbles: true}));
+ new CustomEvent('topic-changed', {bubbles: true, composed: true}));
}).catch(err => {
target.disabled = false;
return;
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
index b23ac8d..e27ca1a 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-change-metadata</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="../../core/gr-router/gr-router.html">
<link rel="import" href="gr-change-metadata.html">
diff --git a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.html b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.html
index e79bce1..80fc1ae 100644
--- a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.html
+++ b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
diff --git a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements_test.html b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements_test.html
index 3f35158..2ceac39 100644
--- a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-change-requirements</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-change-requirements.html">
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
index e8158b8..344c8dd 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.html
@@ -15,11 +15,11 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html">
-<link rel="import" href="../../../bower_components/paper-tabs/paper-tabs.html">
+<link rel="import" href="/bower_components/paper-tabs/paper-tabs.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../../core/gr-reporting/gr-reporting.html">
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
index 48234be..d3ad323 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
@@ -866,9 +866,8 @@
},
/**
- * Gets base patch number, if is a parent try and
- * decide from preference weather to default to `auto merge`
- * or `Parent 1`.
+ * Gets base patch number, if it is a parent try and decide from
+ * preference weather to default to `auto merge`, `Parent 1` or `PARENT`.
* @param {Object} change
* @param {Object} patchRange
* @return {number|string}
@@ -891,7 +890,11 @@
const preferFirst = this._prefs &&
this._prefs.default_base_for_merges === 'FIRST_PARENT';
- return parentCount > 1 && preferFirst ? -1 : 'PARENT';
+ if (parentCount > 1 && preferFirst && !patchRange.patchNum) {
+ return -1;
+ }
+
+ return 'PARENT';
},
_computeShowPrimaryTabs(dynamicTabContentEndpoints) {
@@ -1364,7 +1367,8 @@
// Resolves when the loading flag is set to false, meaning that some
// change content may start appearing.
const loadingFlagSet = detailCompletes
- .then(() => { this._loading = false; });
+ .then(() => { this._loading = false; })
+ .then(() => { this.$.reporting.changeDisplayed(); });
// Resolves when the project config has loaded.
const projectConfigLoaded = detailCompletes
@@ -1436,8 +1440,7 @@
this.$.reporting.changeFullyLoaded();
});
- return coreDataPromise
- .then(() => { this.$.reporting.changeDisplayed(); });
+ return coreDataPromise;
},
/**
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
index 6c24a38..e8de93b 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
@@ -18,11 +18,13 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-change-view</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
-<script src="../../../bower_components/page/page.js"></script>
+<script src="/bower_components/page/page.js"></script>
<link rel="import" href="../../edit/gr-edit-constants.html">
<link rel="import" href="gr-change-view.html">
@@ -1044,6 +1046,53 @@
});
});
+ test('_getBasePatchNum', () => {
+ const _change = {
+ _number: 42,
+ revisions: {
+ '98da160735fb81604b4c40e93c368f380539dd0e': {
+ _number: 1,
+ commit: {
+ parents: [],
+ },
+ },
+ },
+ };
+ const _patchRange = {
+ basePatchNum: 'PARENT',
+ };
+ assert.equal(element._getBasePatchNum(_change, _patchRange), 'PARENT');
+
+ element._prefs = {
+ default_base_for_merges: 'FIRST_PARENT',
+ };
+
+ const _change2 = {
+ _number: 42,
+ revisions: {
+ '98da160735fb81604b4c40e93c368f380539dd0e': {
+ _number: 1,
+ commit: {
+ parents: [
+ {
+ commit: '6e12bdf1176eb4ab24d8491ba3b6d0704409cde8',
+ subject: 'test',
+ },
+ {
+ commit: '22f7db4754b5d9816fc581f3d9a6c0ef8429c841',
+ subject: 'test3',
+ },
+ ],
+ },
+ },
+ },
+ };
+ assert.equal(element._getBasePatchNum(_change2, _patchRange), -1);
+
+ _patchRange.patchNum = 1;
+ assert.equal(element._getBasePatchNum(_change2, _patchRange), 'PARENT');
+ });
+
test('_openReplyDialog called with `ANY` when coming from tap event',
() => {
const openStub = sandbox.stub(element, '_openReplyDialog');
@@ -1552,32 +1601,44 @@
sandbox.stub(Gerrit.Nav, 'navigateToRelativeUrl');
// Delete
- fileList.dispatchEvent(new CustomEvent('file-action-tap',
- {detail: {action: Actions.DELETE.id, path: 'foo'}, bubbles: true}));
+ fileList.dispatchEvent(new CustomEvent('file-action-tap', {
+ detail: {action: Actions.DELETE.id, path: 'foo'},
+ bubbles: true,
+ composed: true,
+ }));
flushAsynchronousOperations();
assert.isTrue(controls.openDeleteDialog.called);
assert.equal(controls.openDeleteDialog.lastCall.args[0], 'foo');
// Restore
- fileList.dispatchEvent(new CustomEvent('file-action-tap',
- {detail: {action: Actions.RESTORE.id, path: 'foo'}, bubbles: true}));
+ fileList.dispatchEvent(new CustomEvent('file-action-tap', {
+ detail: {action: Actions.RESTORE.id, path: 'foo'},
+ bubbles: true,
+ composed: true,
+ }));
flushAsynchronousOperations();
assert.isTrue(controls.openRestoreDialog.called);
assert.equal(controls.openRestoreDialog.lastCall.args[0], 'foo');
// Rename
- fileList.dispatchEvent(new CustomEvent('file-action-tap',
- {detail: {action: Actions.RENAME.id, path: 'foo'}, bubbles: true}));
+ fileList.dispatchEvent(new CustomEvent('file-action-tap', {
+ detail: {action: Actions.RENAME.id, path: 'foo'},
+ bubbles: true,
+ composed: true,
+ }));
flushAsynchronousOperations();
assert.isTrue(controls.openRenameDialog.called);
assert.equal(controls.openRenameDialog.lastCall.args[0], 'foo');
// Open
- fileList.dispatchEvent(new CustomEvent('file-action-tap',
- {detail: {action: Actions.OPEN.id, path: 'foo'}, bubbles: true}));
+ fileList.dispatchEvent(new CustomEvent('file-action-tap', {
+ detail: {action: Actions.OPEN.id, path: 'foo'},
+ bubbles: true,
+ composed: true,
+ }));
flushAsynchronousOperations();
assert.isTrue(Gerrit.Nav.getEditUrlForDiff.called);
diff --git a/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.html b/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.html
index e4183df..f1d677e 100644
--- a/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.html
+++ b/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list.html
@@ -18,7 +18,7 @@
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-path-list-behavior/gr-path-list-behavior.html">
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../../shared/gr-formatted-text/gr-formatted-text.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list_test.html b/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list_test.html
index 9996abc..c18ae8d 100644
--- a/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-comment-list</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-comment-list.html">
diff --git a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.html b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.html
index b6c8fcc..902bf41 100644
--- a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.html
+++ b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-copy-clipboard/gr-copy-clipboard.html">
diff --git a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_test.html b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_test.html
index 438a3f3..d25a871 100644
--- a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_test.html
+++ b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-commit-info</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="../../core/gr-router/gr-router.html">
<link rel="import" href="gr-commit-info.html">
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog.html b/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog.html
index 8803eb3..145d126 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-dialog/gr-dialog.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog_test.html b/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog_test.html
index 95d5374..3a3cad6 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-confirm-abandon-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-confirm-abandon-dialog.html">
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog.html b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog.html
index cd196ec..55b14b1 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-dialog/gr-dialog.html">
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog_test.html b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog_test.html
index 77b102c..dbf332c 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-confirm-cherrypick-conflict-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-confirm-cherrypick-conflict-dialog.html">
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.html b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.html
index 84558ac..508e881 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-autocomplete/gr-autocomplete.html">
<link rel="import" href="../../shared/gr-dialog/gr-dialog.html">
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.html b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.html
index 5c51fe0..22a2aba 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-confirm-cherrypick-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-confirm-cherrypick-dialog.html">
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog.html b/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog.html
index 621ef0a..c07bb37 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-autocomplete/gr-autocomplete.html">
<link rel="import" href="../../shared/gr-dialog/gr-dialog.html">
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog_test.html b/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog_test.html
index e619425..8d6e029 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-confirm-move-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-confirm-move-dialog.html">
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog.html b/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog.html
index 912bbfa6a..116b26f 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-autocomplete/gr-autocomplete.html">
<link rel="import" href="../../shared/gr-dialog/gr-dialog.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog_test.html b/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog_test.html
index c6e9ec4..cd5b130 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-confirm-rebase-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-confirm-rebase-dialog.html">
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog.html b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog.html
index 9e5f1de..c68912c 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-dialog/gr-dialog.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.html b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.html
index c5a1bde..6e41555 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-confirm-revert-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-confirm-revert-dialog.html">
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog.html b/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog.html
index 1036b7f..42ecacf 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../../shared/gr-dialog/gr-dialog.html">
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog_test.html b/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog_test.html
index 86c15f6..40fa29a 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog_test.html
@@ -18,11 +18,13 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-confirm-submit-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
-<script src="../../../bower_components/page/page.js"></script>
+<script src="/bower_components/page/page.js"></script>
<link rel="import" href="gr-confirm-submit-dialog.html">
diff --git a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.html b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.html
index 28d25d2..ab7525f 100644
--- a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.html
+++ b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html">
diff --git a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html
index ee284b9..282d8de 100644
--- a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-download-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-download-dialog.html">
diff --git a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.html b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.html
index f7d90eb..bdb4295 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
diff --git a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.html b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.html
index adfeeb4..ac626ab 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.html
@@ -18,11 +18,13 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-file-list-header</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
-<script src="../../../bower_components/page/page.js"></script>
+<script src="/bower_components/page/page.js"></script>
<link rel="import" href="gr-file-list-header.html">
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
index 29a12df..f087b21 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/async-foreach-behavior/async-foreach-behavior.html">
<link rel="import" href="../../../behaviors/dom-util-behavior/dom-util-behavior.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
index c69c146..9529d38 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
@@ -18,11 +18,13 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-file-list</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
-<script src="../../../bower_components/page/page.js"></script>
+<script src="/bower_components/page/page.js"></script>
<link rel="import" href="../../diff/gr-comment-api/gr-comment-api.html">
<script src="../../../scripts/util.js"></script>
diff --git a/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog.html b/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog.html
index b824f1c..a749431 100644
--- a/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog.html
+++ b/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog_test.html b/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog_test.html
index 539011a..68c77e6 100644
--- a/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-included-in-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-included-in-dialog.html">
diff --git a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.html b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.html
index 27c5baa..571ddf9 100644
--- a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.html
+++ b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-selector/iron-selector.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-selector/iron-selector.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../../styles/gr-voting-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.js b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.js
index d9b961f..fe28a1d 100644
--- a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.js
+++ b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row.js
@@ -133,7 +133,8 @@
const name = e.target.selectedItem.name;
const value = e.target.selectedItem.getAttribute('value');
this.dispatchEvent(new CustomEvent(
- 'labels-changed', {detail: {name, value}, bubbles: true}));
+ 'labels-changed',
+ {detail: {name, value}, bubbles: true, composed: true}));
},
_computeAnyPermittedLabelValues(permittedLabels, label) {
diff --git a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.html b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.html
index 1e4d471..4920e20 100644
--- a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.html
+++ b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-label-score-row</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-label-score-row.html">
diff --git a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.html b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.html
index 7dd4c76..c607a9f 100644
--- a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.html
+++ b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../gr-label-score-row/gr-label-score-row.html">
<link rel="import" href="../../../styles/shared-styles.html">
@@ -28,6 +28,9 @@
text-align: center;
width: 100%;
}
+ gr-label-score-row.no-access {
+ display: var(--label-no-access-display, initial);
+ }
@media only screen and (max-width: 25em) {
:host {
text-align: center;
@@ -36,6 +39,7 @@
</style>
<template is="dom-repeat" items="[[_labels]]" as="label">
<gr-label-score-row
+ class$="[[_computeLabelAccessClass(label.name, permittedLabels)]]"
label="[[label]]"
name="[[label.name]]"
labels="[[change.labels]]"
diff --git a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.js b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.js
index eaf39bc..f18680e 100644
--- a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.js
+++ b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.js
@@ -115,5 +115,19 @@
_changeIsMerged(changeStatus) {
return changeStatus === 'MERGED';
},
+
+ /**
+ * @param label {string|undefined}
+ * @param permittedLabels {Object|undefined}
+ * @return {string}
+ */
+ _computeLabelAccessClass(label, permittedLabels) {
+ if (label == null || permittedLabels == null) {
+ return '';
+ }
+
+ return permittedLabels.hasOwnProperty(label) &&
+ permittedLabels[label].length ? 'access' : 'no-access';
+ },
});
})();
diff --git a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores_test.html b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores_test.html
index 24529ec..f986a58 100644
--- a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores_test.html
+++ b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-label-scores</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-label-scores.html">
@@ -135,6 +137,25 @@
});
});
+ test('_computeLabelAccessClass undefined case', () => {
+ assert.strictEqual(
+ element._computeLabelAccessClass(undefined, undefined), '');
+ assert.strictEqual(
+ element._computeLabelAccessClass('', undefined), '');
+ assert.strictEqual(
+ element._computeLabelAccessClass(undefined, {}), '');
+ });
+
+ test('_computeLabelAccessClass has access', () => {
+ assert.strictEqual(
+ element._computeLabelAccessClass('foo', {foo: ['']}), 'access');
+ });
+
+ test('_computeLabelAccessClass no access', () => {
+ assert.strictEqual(
+ element._computeLabelAccessClass('zap', {foo: ['']}), 'no-access');
+ });
+
test('changes in label score are reflected in _labels', () => {
element.change = {
_number: '123',
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message.html b/polygerrit-ui/app/elements/change/gr-message/gr-message.html
index 32c4c1f..df3cc37 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message.html
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-icon/iron-icon.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-icon/iron-icon.html">
<link rel="import" href="../../shared/gr-account-label/gr-account-label.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-date-formatter/gr-date-formatter.html">
@@ -120,6 +120,7 @@
position: static;
}
.collapsed .author {
+ overflow: hidden;
color: var(--primary-text-color);
margin-right: .4em;
}
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message.js b/polygerrit-ui/app/elements/change/gr-message/gr-message.js
index 837ffe0..a2ec28c 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message.js
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message.js
@@ -228,6 +228,7 @@
e.preventDefault();
this.dispatchEvent(new CustomEvent('message-anchor-tap', {
bubbles: true,
+ composed: true,
detail: {id: this.message.id},
}));
},
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message_test.html b/polygerrit-ui/app/elements/change/gr-message/gr-message_test.html
index 64a5b26..ef5a756 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message_test.html
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-message</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-message.html">
diff --git a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.html b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.html
index 80708a1..7545dd8 100644
--- a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.html
+++ b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/paper-toggle-button/paper-toggle-button.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/paper-toggle-button/paper-toggle-button.html">
<link rel="import" href="../../core/gr-reporting/gr-reporting.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../gr-message/gr-message.html">
diff --git a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.html b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.html
index b75b93a..d6b887f 100644
--- a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-messages-list</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="../../diff/gr-comment-api/gr-comment-api.html">
diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.html b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.html
index 30ebc08..4a70506 100644
--- a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.html
+++ b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html">
diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html
index 48cc565..06b7a5d 100644
--- a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-related-changes-list</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-related-changes-list.html">
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog-it_test.html b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog-it_test.html
index eb06b0f..dd9e397 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog-it_test.html
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog-it_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-reply-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="../../plugins/gr-plugin-host/gr-plugin-host.html">
@@ -150,7 +152,8 @@
flush(() => {
const textarea = element.$.textarea.getNativeTextarea();
textarea.value = 'LGTM';
- textarea.dispatchEvent(new CustomEvent('input', {bubbles: true}));
+ textarea.dispatchEvent(new CustomEvent(
+ 'input', {bubbles: true, composed: true}));
const labelScoreRows = Polymer.dom(element.$.labelScores.root)
.querySelector('gr-label-score-row[name="Code-Review"]');
const selectedBtn = Polymer.dom(labelScoreRows.root)
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.html b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.html
index 45b9c15..32bcc3f 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.html
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.html
@@ -15,12 +15,12 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html">
-<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
+<link rel="import" href="/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
<link rel="import" href="../../core/gr-reporting/gr-reporting.html">
<link rel="import" href="../../plugins/gr-endpoint-decorator/gr-endpoint-decorator.html">
<link rel="import" href="../../shared/gr-account-chip/gr-account-chip.html">
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
index 84c8cee..f775e1c 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
@@ -749,6 +749,7 @@
if (this._sendDisabled) {
this.dispatchEvent(new CustomEvent('show-alert', {
bubbles: true,
+ composed: true,
detail: {message: EMPTY_REPLY_MESSAGE},
}));
return;
@@ -756,9 +757,11 @@
return this.send(this._includeComments, this.canBeStarted)
.then(keepReviewers => {
this._purgeReviewersPendingRemove(false, keepReviewers);
- }).catch(err => {
+ })
+ .catch(err => {
this.dispatchEvent(new CustomEvent('show-error', {
bubbles: true,
+ composed: true,
detail: {message: `Error submitting review ${err}`},
}));
});
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
index f9108c7..b99c3f0 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-reply-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-reply-dialog.html">
@@ -415,7 +417,7 @@
assert.isTrue(element.$$('#ccs').allowAnyInput);
assert.isFalse(element.$$('#reviewers').allowAnyInput);
element.$$('#ccs').dispatchEvent(new CustomEvent('account-text-changed',
- {bubbles: true}));
+ {bubbles: true, composed: true}));
assert.isTrue(element._reviewersMutated);
});
diff --git a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list.html b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list.html
index 73e8bea..72c5b44 100644
--- a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list.html
+++ b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../shared/gr-account-chip/gr-account-chip.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.html b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.html
index 1a406c9..80359e0 100644
--- a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-reviewer-list</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-reviewer-list.html">
diff --git a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.html b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.html
index 4d8e5ae..50782be 100644
--- a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.html
+++ b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/paper-toggle-button/paper-toggle-button.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/paper-toggle-button/paper-toggle-button.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-comment-thread/gr-comment-thread.html">
diff --git a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_test.html b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_test.html
index 792644e..bd4a6ac 100644
--- a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-thread-list</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-thread-list.html">
diff --git a/polygerrit-ui/app/elements/change/gr-upload-help-dialog/gr-upload-help-dialog.html b/polygerrit-ui/app/elements/change/gr-upload-help-dialog/gr-upload-help-dialog.html
index 792c300..ff4ab39 100644
--- a/polygerrit-ui/app/elements/change/gr-upload-help-dialog/gr-upload-help-dialog.html
+++ b/polygerrit-ui/app/elements/change/gr-upload-help-dialog/gr-upload-help-dialog.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-dialog/gr-dialog.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../../shared/gr-shell-command/gr-shell-command.html">
diff --git a/polygerrit-ui/app/elements/change/gr-upload-help-dialog/gr-upload-help-dialog_test.html b/polygerrit-ui/app/elements/change/gr-upload-help-dialog/gr-upload-help-dialog_test.html
index a5a6e76..66d0a01 100644
--- a/polygerrit-ui/app/elements/change/gr-upload-help-dialog/gr-upload-help-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-upload-help-dialog/gr-upload-help-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-upload-help-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-upload-help-dialog.html">
diff --git a/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.html b/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.html
index 2c2fb4e..7949002 100644
--- a/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.html
+++ b/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.html
@@ -16,7 +16,7 @@
-->
<link rel="import" href="../../../behaviors/gr-anonymous-name-behavior/gr-anonymous-name-behavior.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-dropdown/gr-dropdown.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown_test.html b/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown_test.html
index fe63a3e..37d8882 100644
--- a/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown_test.html
+++ b/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-account-dropdown</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-account-dropdown.html">
diff --git a/polygerrit-ui/app/elements/core/gr-error-dialog/gr-error-dialog.html b/polygerrit-ui/app/elements/core/gr-error-dialog/gr-error-dialog.html
index f8bf33c..09b928e 100644
--- a/polygerrit-ui/app/elements/core/gr-error-dialog/gr-error-dialog.html
+++ b/polygerrit-ui/app/elements/core/gr-error-dialog/gr-error-dialog.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-dialog/gr-dialog.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/core/gr-error-dialog/gr-error-dialog_test.html b/polygerrit-ui/app/elements/core/gr-error-dialog/gr-error-dialog_test.html
index e2c314b..648f8be 100644
--- a/polygerrit-ui/app/elements/core/gr-error-dialog/gr-error-dialog_test.html
+++ b/polygerrit-ui/app/elements/core/gr-error-dialog/gr-error-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-error-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-error-dialog.html">
diff --git a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.html b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.html
index 4ca106e..db40496 100644
--- a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.html
+++ b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager.html
@@ -16,7 +16,7 @@
-->
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../core/gr-error-dialog/gr-error-dialog.html">
<link rel="import" href="../../core/gr-reporting/gr-reporting.html">
<link rel="import" href="../../shared/gr-alert/gr-alert.html">
diff --git a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.html b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.html
index 88e3efd..9140c17 100644
--- a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.html
+++ b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-error-manager</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-error-manager.html">
diff --git a/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display.html b/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display.html
index 2ff7953..276db72 100644
--- a/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display.html
+++ b/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<dom-module id="gr-key-binding-display">
diff --git a/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display_test.html b/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display_test.html
index 0361d76..39c8af8 100644
--- a/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display_test.html
+++ b/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display_test.html
@@ -17,9 +17,11 @@
-->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-key-binding-display</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-key-binding-display.html">
diff --git a/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.html b/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.html
index e3552cc..e153074 100644
--- a/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.html
+++ b/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../gr-key-binding-display/gr-key-binding-display.html">
diff --git a/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog_test.html b/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog_test.html
index 50579dd..1a3d6c7 100644
--- a/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog_test.html
+++ b/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog_test.html
@@ -17,9 +17,11 @@
-->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-key-binding-display</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-keyboard-shortcuts-dialog.html">
diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html
index c2b28d6..0213f1a 100644
--- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html
+++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/docs-url-behavior/docs-url-behavior.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.html b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.html
index 03586ea..782a8da 100644
--- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.html
+++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-main-header</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-main-header.html">
diff --git a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation_test.html b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation_test.html
index 2f72338..73ce86a 100644
--- a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation_test.html
+++ b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-navigation</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script>
diff --git a/polygerrit-ui/app/elements/core/gr-reporting/gr-jank-detector_test.html b/polygerrit-ui/app/elements/core/gr-reporting/gr-jank-detector_test.html
index 6faeec1..825a5fc 100644
--- a/polygerrit-ui/app/elements/core/gr-reporting/gr-jank-detector_test.html
+++ b/polygerrit-ui/app/elements/core/gr-reporting/gr-jank-detector_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-jank-detector</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="gr-jank-detector.js"></script>
diff --git a/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.html b/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.html
index 935de6b..6588df4 100644
--- a/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.html
+++ b/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<dom-module id="gr-reporting">
<script src="gr-jank-detector.js"></script>
diff --git a/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting_test.html b/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting_test.html
index 2087790..f7d2f62 100644
--- a/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting_test.html
+++ b/polygerrit-ui/app/elements/core/gr-reporting/gr-reporting_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-reporting</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-reporting.html">
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.html b/polygerrit-ui/app/elements/core/gr-router/gr-router.html
index 68ddef6..6035069 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router.html
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
@@ -28,6 +28,6 @@
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
<gr-reporting id="reporting"></gr-reporting>
</template>
- <script src="../../../bower_components/page/page.js"></script>
+ <script src="/bower_components/page/page.js"></script>
<script src="gr-router.js"></script>
</dom-module>
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
index 4dbcd44..fe28f81 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-router</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-router.html">
diff --git a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.html b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.html
index 3a48213..d766f74 100644
--- a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.html
+++ b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar.html
@@ -17,7 +17,7 @@
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-autocomplete/gr-autocomplete.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar_test.html b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar_test.html
index 93e0e307..1365c00 100644
--- a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar_test.html
+++ b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar_test.html
@@ -18,11 +18,13 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-search-bar</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
-<script src="../../../bower_components/page/page.js"></script>
+<script src="/bower_components/page/page.js"></script>
<link rel="import" href="gr-search-bar.html">
<script src="../../../scripts/util.js"></script>
diff --git a/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.html b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.html
index 4c98068..06e354c 100644
--- a/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.html
+++ b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-anonymous-name-behavior/gr-anonymous-name-behavior.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
diff --git a/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search_test.html b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search_test.html
index af0fc3c..a70eb7c 100644
--- a/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search_test.html
+++ b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-smart-search</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-smart-search.html">
diff --git a/polygerrit-ui/app/elements/diff/gr-comment-api/gr-comment-api.html b/polygerrit-ui/app/elements/diff/gr-comment-api/gr-comment-api.html
index c31bd1166..317e9e5 100644
--- a/polygerrit-ui/app/elements/diff/gr-comment-api/gr-comment-api.html
+++ b/polygerrit-ui/app/elements/diff/gr-comment-api/gr-comment-api.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/diff/gr-comment-api/gr-comment-api_test.html b/polygerrit-ui/app/elements/diff/gr-comment-api/gr-comment-api_test.html
index 1e53a14..c44e8c4 100644
--- a/polygerrit-ui/app/elements/diff/gr-comment-api/gr-comment-api_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-comment-api/gr-comment-api_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-comment-api</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="./gr-comment-api.html">
diff --git a/polygerrit-ui/app/elements/diff/gr-coverage-layer/gr-coverage-layer.html b/polygerrit-ui/app/elements/diff/gr-coverage-layer/gr-coverage-layer.html
index 56a6fb9..d743d92 100644
--- a/polygerrit-ui/app/elements/diff/gr-coverage-layer/gr-coverage-layer.html
+++ b/polygerrit-ui/app/elements/diff/gr-coverage-layer/gr-coverage-layer.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<dom-module id="gr-coverage-layer">
<template>
</template>
diff --git a/polygerrit-ui/app/elements/diff/gr-coverage-layer/gr-coverage-layer_test.html b/polygerrit-ui/app/elements/diff/gr-coverage-layer/gr-coverage-layer_test.html
index edd88a2..45a67e1 100644
--- a/polygerrit-ui/app/elements/diff/gr-coverage-layer/gr-coverage-layer_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-coverage-layer/gr-coverage-layer_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-coverage-layer</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../gr-diff/gr-diff-line.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html
index 7bfec00..fc945cd 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
<link rel="import" href="../gr-coverage-layer/gr-coverage-layer.html">
<link rel="import" href="../gr-diff-processor/gr-diff-processor.html">
@@ -179,7 +179,8 @@
const isBinary = !!(this.isImageDiff || this.diff.binary);
- this.dispatchEvent(new CustomEvent('render-start', {bubbles: true}));
+ this.dispatchEvent(new CustomEvent(
+ 'render-start', {bubbles: true, composed: true}));
this._cancelableRenderPromise = util.makeCancelable(
this.$.processor.process(this.diff.content, isBinary)
.then(() => {
@@ -187,7 +188,7 @@
this._builder.renderDiff();
}
this.dispatchEvent(new CustomEvent('render-content',
- {bubbles: true}));
+ {bubbles: true, composed: true}));
if (this._diffTooLargeForSyntax()) {
this.$.syntaxLayer.enabled = false;
@@ -196,8 +197,8 @@
return this.$.syntaxLayer.process();
})
.then(() => {
- this.dispatchEvent(
- new CustomEvent('render-syntax', {bubbles: true}));
+ this.dispatchEvent(new CustomEvent(
+ 'render-syntax', {bubbles: true, composed: true}));
}));
return this._cancelableRenderPromise
.finally(() => { this._cancelableRenderPromise = null; })
@@ -313,7 +314,7 @@
this.dispatchEvent(new CustomEvent('show-alert', {
detail: {
message,
- }, bubbles: true}));
+ }, bubbles: true, composed: true}));
throw Error(`Invalid preference value: ${pref}`);
},
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder_test.html b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder_test.html
index fa54756..b4a91b3 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-diff-builder</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="../../../scripts/util.js"></script>
<script src="../gr-diff/gr-diff-line.js"></script>
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor.html b/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor.html
index c24574e..99d0498 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-cursor-manager/gr-cursor-manager.html">
<dom-module id="gr-diff-cursor">
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor_test.html b/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor_test.html
index f111378..d36a72d4 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-diff-cursor</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="../../../scripts/util.js"></script>
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-annotation_test.html b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-annotation_test.html
index 652aa4c..86d5e45 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-annotation_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-annotation_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-annotation</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="gr-annotation.js"></script>
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight.html b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight.html
index c912a16..612aab6 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../gr-selection-action-box/gr-selection-action-box.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight_test.html b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight_test.html
index 9ec2b29..b83dd53 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-diff-highlight</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-diff-highlight.html">
@@ -179,8 +181,8 @@
element.commentRanges = [{side: 'right'}];
sandbox.stub(element, 'set');
- threadEl.dispatchEvent(
- new CustomEvent('comment-thread-mouseenter', {bubbles: true}));
+ threadEl.dispatchEvent(new CustomEvent(
+ 'comment-thread-mouseenter', {bubbles: true, composed: true}));
assert.isFalse(element.set.called);
});
@@ -204,8 +206,8 @@
}}];
sandbox.stub(element, 'set');
- threadEl.dispatchEvent(
- new CustomEvent('comment-thread-mouseenter', {bubbles: true}));
+ threadEl.dispatchEvent(new CustomEvent(
+ 'comment-thread-mouseenter', {bubbles: true, composed: true}));
assert.isTrue(element.set.called);
const args = element.set.lastCall.args;
assert.deepEqual(args[0], ['commentRanges', 0, 'hovering']);
@@ -221,8 +223,8 @@
element.commentRanges = [{side: 'right'}];
sandbox.stub(element, 'set');
- threadEl.dispatchEvent(
- new CustomEvent('comment-thread-mouseleave', {bubbles: true}));
+ threadEl.dispatchEvent(new CustomEvent(
+ 'comment-thread-mouseleave', {bubbles: true, composed: true}));
assert.isFalse(element.set.called);
});
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.html b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.html
index 05f48d8..fc71be6 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
<link rel="import" href="../../core/gr-reporting/gr-reporting.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js
index b848ed3..d47a61d 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.js
@@ -110,7 +110,9 @@
commitRange: Object,
filesWeblinks: {
type: Object,
- value() { return {}; },
+ value() {
+ return {};
+ },
notify: true,
},
hidden: {
@@ -309,7 +311,9 @@
},
_getFilesWeblinks(diff) {
- if (!this.commitRange) { return {}; }
+ if (!this.commitRange) {
+ return {};
+ }
return {
meta_a: Gerrit.Nav.getFileWebLinks(
this.projectName, this.commitRange.baseCommit, this.path,
@@ -435,7 +439,9 @@
* Report info about the diff response.
*/
_reportDiff(diff) {
- if (!diff || !diff.content) { return; }
+ if (!diff || !diff.content) {
+ return;
+ }
// Count the delta lines stemming from normal deltas, and from
// due_to_rebase deltas.
@@ -663,7 +669,7 @@
* @param {!Gerrit.Range=} range
* @return {?Node}
*/
- _getThreadEl(lineNum, commentSide, range=undefined) {
+ _getThreadEl(lineNum, commentSide, range = undefined) {
let line;
if (commentSide === GrDiffBuilder.Side.LEFT) {
line = {beforeNumber: lineNum};
@@ -778,7 +784,8 @@
return this.prefs.ignore_whitespace;
},
- _whitespaceChanged(preferredWhitespaceLevel, loadedWhitespaceLevel,
+ _whitespaceChanged(
+ preferredWhitespaceLevel, loadedWhitespaceLevel,
noRenderOnPrefsChange) {
if (preferredWhitespaceLevel !== loadedWhitespaceLevel &&
!noRenderOnPrefsChange) {
@@ -831,8 +838,8 @@
},
_handleCommentSaveOrDiscard() {
- this.dispatchEvent(new CustomEvent('diff-comments-modified',
- {bubbles: true}));
+ this.dispatchEvent(new CustomEvent(
+ 'diff-comments-modified', {bubbles: true, composed: true}));
},
_removeComment(comment) {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.html b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.html
index 7466ade..6d4e408 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-diff</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-diff-host.html">
@@ -269,7 +271,7 @@
suite('render reporting', () => {
test('starts total and content timer on render-start', done => {
element.dispatchEvent(
- new CustomEvent('render-start', {bubbles: true}));
+ new CustomEvent('render-start', {bubbles: true, composed: true}));
assert.isTrue(element.$.reporting.time.calledWithExactly(
'Diff Total Render'));
assert.isTrue(element.$.reporting.time.calledWithExactly(
@@ -279,7 +281,7 @@
test('ends content and starts syntax timer on render-content', done => {
element.dispatchEvent(
- new CustomEvent('render-content', {bubbles: true}));
+ new CustomEvent('render-content', {bubbles: true, composed: true}));
assert.isTrue(element.$.reporting.time.calledWithExactly(
'Diff Syntax Render'));
assert.isTrue(element.$.reporting.timeEnd.calledWithExactly(
@@ -289,7 +291,7 @@
test('ends total and syntax timer on render-syntax', done => {
element.dispatchEvent(
- new CustomEvent('render-syntax', {bubbles: true}));
+ new CustomEvent('render-syntax', {bubbles: true, composed: true}));
assert.isTrue(element.$.reporting.timeEnd.calledWithExactly(
'Diff Total Render'));
assert.isTrue(element.$.reporting.timeEnd.calledWithExactly(
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector.html b/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector.html
index 8251e53..ad7ff11 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector_test.html b/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector_test.html
index c011106..adeaa15 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector_test.html
@@ -18,11 +18,13 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-diff-mode-selector</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
-<script src="../../../bower_components/page/page.js"></script>
+<script src="/bower_components/page/page.js"></script>
<script src="../../../scripts/util.js"></script>
<link rel="import" href="gr-diff-mode-selector.html">
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-preferences-dialog/gr-diff-preferences-dialog.html b/polygerrit-ui/app/elements/diff/gr-diff-preferences-dialog/gr-diff-preferences-dialog.html
index ae53f76..10d2828 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-preferences-dialog/gr-diff-preferences-dialog.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-preferences-dialog/gr-diff-preferences-dialog.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-diff-preferences/gr-diff-preferences.html">
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.html b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.html
index 663cf25..922ac87 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<dom-module id="gr-diff-processor">
<script src="../gr-diff/gr-diff-line.js"></script>
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js
index 800e9b3..83e4680 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor.js
@@ -151,7 +151,7 @@
let currentBatch = 0;
const nextStep = () => {
if (this._isScrolling) {
- this.async(nextStep, 100);
+ this._nextStepHandle = this.async(nextStep, 100);
return;
}
// If we are done, resolve the promise.
@@ -239,19 +239,22 @@
},
_linesFromSection(section, offsetLeft, offsetRight) {
- const lines = [];
if (section.ab) {
- lines.push(...section.ab.map((row, i) =>
- this._lineFromRow(
- GrDiffLine.Type.BOTH, offsetLeft, offsetRight, row, i)));
+ return section.ab.map((row, i) => this._lineFromRow(
+ GrDiffLine.Type.BOTH, offsetLeft, offsetRight, row, i));
}
+ let lines = [];
if (section.a) {
- lines.push(...this._deltaLinesFromRows(
+ // Avoiding a.push(...b) because that causes callstack overflows for
+ // large b, which can occur when large files are added removed.
+ lines = lines.concat(this._deltaLinesFromRows(
GrDiffLine.Type.REMOVE, section.a, offsetLeft,
section[DiffHighlights.REMOVED]));
}
if (section.b) {
- lines.push(...this._deltaLinesFromRows(
+ // Avoiding a.push(...b) because that causes callstack overflows for
+ // large b, which can occur when large files are added removed.
+ lines = lines.concat(this._deltaLinesFromRows(
GrDiffLine.Type.ADD, section.b, offsetRight,
section[DiffHighlights.ADDED]));
}
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor_test.html b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor_test.html
index 0e57dbf..d27fed1 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-diff-processor test</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-diff-processor.html">
@@ -60,7 +62,7 @@
element.context = 4;
});
- test('process loaded content', done => {
+ test('process loaded content', () => {
const content = [
{
ab: [
@@ -86,7 +88,7 @@
},
];
- element.process(content).then(() => {
+ return element.process(content).then(() => {
const groups = element.groups;
assert.equal(groups.length, 4);
@@ -139,31 +141,15 @@
'everyone pretend to shower.',
'Fry: Same as every day. Got it.',
]);
-
- done();
});
});
- test('insert context groups', done => {
+ test('first group is for file', () => {
const content = [
- {ab: []},
- {a: ['all work and no play make andybons a dull boy']},
- {ab: []},
- {b: ['elgoog elgoog elgoog']},
- {ab: []},
+ {b: ['foo']},
];
- for (let i = 0; i < 100; i++) {
- content[0].ab.push('all work and no play make jack a dull boy');
- content[4].ab.push('all work and no play make jill a dull girl');
- }
- for (let i = 0; i < 5; i++) {
- content[2].ab.push('no tv and no beer make homer go crazy');
- }
- const context = 10;
- element.context = context;
-
- element.process(content).then(() => {
+ return element.process(content).then(() => {
const groups = element.groups;
assert.equal(groups[0].type, GrDiffGroup.Type.BOTH);
@@ -171,107 +157,174 @@
assert.equal(groups[0].lines[0].text, '');
assert.equal(groups[0].lines[0].beforeNumber, GrDiffLine.FILE);
assert.equal(groups[0].lines[0].afterNumber, GrDiffLine.FILE);
-
- assert.equal(groups[1].type, GrDiffGroup.Type.CONTEXT_CONTROL);
- assert.instanceOf(groups[1].lines[0].contextGroups[0], GrDiffGroup);
- assert.equal(groups[1].lines[0].contextGroups[0].lines.length, 90);
- for (const l of groups[1].lines[0].contextGroups[0].lines) {
- assert.equal(l.text, content[0].ab[0]);
- }
-
- assert.equal(groups[2].type, GrDiffGroup.Type.BOTH);
- assert.equal(groups[2].lines.length, context);
- for (const l of groups[2].lines) {
- assert.equal(l.text, content[0].ab[0]);
- }
-
- assert.equal(groups[3].type, GrDiffGroup.Type.DELTA);
- assert.equal(groups[3].lines.length, 1);
- assert.equal(groups[3].removes.length, 1);
- assert.equal(groups[3].removes[0].text,
- 'all work and no play make andybons a dull boy');
-
- assert.equal(groups[4].type, GrDiffGroup.Type.BOTH);
- assert.equal(groups[4].lines.length, 5);
- for (const l of groups[4].lines) {
- assert.equal(l.text, content[2].ab[0]);
- }
-
- assert.equal(groups[5].type, GrDiffGroup.Type.DELTA);
- assert.equal(groups[5].lines.length, 1);
- assert.equal(groups[5].adds.length, 1);
- assert.equal(groups[5].adds[0].text, 'elgoog elgoog elgoog');
-
- assert.equal(groups[6].type, GrDiffGroup.Type.BOTH);
- assert.equal(groups[6].lines.length, context);
- for (const l of groups[6].lines) {
- assert.equal(l.text, content[4].ab[0]);
- }
-
- assert.equal(groups[7].type, GrDiffGroup.Type.CONTEXT_CONTROL);
- assert.instanceOf(groups[7].lines[0].contextGroups[0], GrDiffGroup);
- assert.equal(groups[7].lines[0].contextGroups[0].lines.length, 90);
- for (const l of groups[7].lines[0].contextGroups[0].lines) {
- assert.equal(l.text, content[4].ab[0]);
- }
-
- done();
});
});
- test('insert context groups', done => {
- const content = [
- {a: ['all work and no play make andybons a dull boy']},
- {ab: []},
- {b: ['elgoog elgoog elgoog']},
- ];
- for (let i = 0; i < 50; i++) {
- content[1].ab.push('no tv and no beer make homer go crazy');
- }
+ suite('context groups', () => {
+ test('at the beginning, larger than context', () => {
+ element.context = 10;
+ const content = [
+ {ab: new Array(100)
+ .fill('all work and no play make jack a dull boy')},
+ {a: ['all work and no play make andybons a dull boy']},
+ ];
- const context = 10;
- element.context = context;
+ return element.process(content).then(() => {
+ const groups = element.groups;
- element.process(content).then(() => {
- const groups = element.groups;
+ // group[0] is the file group
- assert.equal(groups[0].type, GrDiffGroup.Type.BOTH);
- assert.equal(groups[0].lines.length, 1);
- assert.equal(groups[0].lines[0].text, '');
- assert.equal(groups[0].lines[0].beforeNumber, GrDiffLine.FILE);
- assert.equal(groups[0].lines[0].afterNumber, GrDiffLine.FILE);
+ assert.equal(groups[1].type, GrDiffGroup.Type.CONTEXT_CONTROL);
+ assert.instanceOf(groups[1].lines[0].contextGroups[0], GrDiffGroup);
+ assert.equal(groups[1].lines[0].contextGroups[0].lines.length, 90);
+ for (const l of groups[1].lines[0].contextGroups[0].lines) {
+ assert.equal(l.text, 'all work and no play make jack a dull boy');
+ }
- assert.equal(groups[1].type, GrDiffGroup.Type.DELTA);
- assert.equal(groups[1].lines.length, 1);
- assert.equal(groups[1].removes.length, 1);
- assert.equal(groups[1].removes[0].text,
- 'all work and no play make andybons a dull boy');
+ assert.equal(groups[2].type, GrDiffGroup.Type.BOTH);
+ assert.equal(groups[2].lines.length, 10);
+ for (const l of groups[2].lines) {
+ assert.equal(l.text, 'all work and no play make jack a dull boy');
+ }
+ });
+ });
- assert.equal(groups[2].type, GrDiffGroup.Type.BOTH);
- assert.equal(groups[2].lines.length, context);
- for (const l of groups[2].lines) {
- assert.equal(l.text, content[1].ab[0]);
- }
+ test('at the beginning, smaller than context', () => {
+ element.context = 10;
+ const content = [
+ {ab: new Array(5)
+ .fill('all work and no play make jack a dull boy')},
+ {a: ['all work and no play make andybons a dull boy']},
+ ];
- assert.equal(groups[3].type, GrDiffGroup.Type.CONTEXT_CONTROL);
- assert.instanceOf(groups[3].lines[0].contextGroups[0], GrDiffGroup);
- assert.equal(groups[3].lines[0].contextGroups[0].lines.length, 30);
- for (const l of groups[3].lines[0].contextGroups[0].lines) {
- assert.equal(l.text, content[1].ab[0]);
- }
+ return element.process(content).then(() => {
+ const groups = element.groups;
- assert.equal(groups[4].type, GrDiffGroup.Type.BOTH);
- assert.equal(groups[4].lines.length, context);
- for (const l of groups[4].lines) {
- assert.equal(l.text, content[1].ab[0]);
- }
+ // group[0] is the file group
- assert.equal(groups[5].type, GrDiffGroup.Type.DELTA);
- assert.equal(groups[5].lines.length, 1);
- assert.equal(groups[5].adds.length, 1);
- assert.equal(groups[5].adds[0].text, 'elgoog elgoog elgoog');
+ assert.equal(groups[1].type, GrDiffGroup.Type.BOTH);
+ assert.equal(groups[1].lines.length, 5);
+ for (const l of groups[1].lines) {
+ assert.equal(l.text, 'all work and no play make jack a dull boy');
+ }
+ });
+ });
- done();
+ test('at the end, larger than context', () => {
+ element.context = 10;
+ const content = [
+ {a: ['all work and no play make andybons a dull boy']},
+ {ab: new Array(100)
+ .fill('all work and no play make jill a dull girl')},
+ ];
+
+ return element.process(content).then(() => {
+ const groups = element.groups;
+
+ // group[0] is the file group
+ // group[1] is the "a" group
+
+ assert.equal(groups[2].type, GrDiffGroup.Type.BOTH);
+ assert.equal(groups[2].lines.length, 10);
+ for (const l of groups[2].lines) {
+ assert.equal(
+ l.text, 'all work and no play make jill a dull girl');
+ }
+
+ assert.equal(groups[3].type, GrDiffGroup.Type.CONTEXT_CONTROL);
+ assert.instanceOf(groups[3].lines[0].contextGroups[0], GrDiffGroup);
+ assert.equal(groups[3].lines[0].contextGroups[0].lines.length, 90);
+ for (const l of groups[3].lines[0].contextGroups[0].lines) {
+ assert.equal(
+ l.text, 'all work and no play make jill a dull girl');
+ }
+ });
+ });
+
+ test('at the end, smaller than context', () => {
+ element.context = 10;
+ const content = [
+ {a: ['all work and no play make andybons a dull boy']},
+ {ab: new Array(5)
+ .fill('all work and no play make jill a dull girl')},
+ ];
+
+ return element.process(content).then(() => {
+ const groups = element.groups;
+
+ // group[0] is the file group
+ // group[1] is the "a" group
+
+ assert.equal(groups[2].type, GrDiffGroup.Type.BOTH);
+ assert.equal(groups[2].lines.length, 5);
+ for (const l of groups[2].lines) {
+ assert.equal(
+ l.text, 'all work and no play make jill a dull girl');
+ }
+ });
+ });
+
+ test('in the middle, larger than context', () => {
+ element.context = 10;
+ const content = [
+ {a: ['all work and no play make andybons a dull boy']},
+ {ab: new Array(100)
+ .fill('all work and no play make jill a dull girl')},
+ {a: ['all work and no play make andybons a dull boy']},
+ ];
+
+ return element.process(content).then(() => {
+ const groups = element.groups;
+
+ // group[0] is the file group
+ // group[1] is the "a" group
+
+ assert.equal(groups[2].type, GrDiffGroup.Type.BOTH);
+ assert.equal(groups[2].lines.length, 10);
+ for (const l of groups[2].lines) {
+ assert.equal(
+ l.text, 'all work and no play make jill a dull girl');
+ }
+
+ assert.equal(groups[3].type, GrDiffGroup.Type.CONTEXT_CONTROL);
+ assert.instanceOf(groups[3].lines[0].contextGroups[0], GrDiffGroup);
+ assert.equal(groups[3].lines[0].contextGroups[0].lines.length, 80);
+ for (const l of groups[3].lines[0].contextGroups[0].lines) {
+ assert.equal(
+ l.text, 'all work and no play make jill a dull girl');
+ }
+
+ assert.equal(groups[4].type, GrDiffGroup.Type.BOTH);
+ assert.equal(groups[4].lines.length, 10);
+ for (const l of groups[4].lines) {
+ assert.equal(
+ l.text, 'all work and no play make jill a dull girl');
+ }
+ });
+ });
+
+ test('in the middle, smaller than context', () => {
+ element.context = 10;
+ const content = [
+ {a: ['all work and no play make andybons a dull boy']},
+ {ab: new Array(5)
+ .fill('all work and no play make jill a dull girl')},
+ {a: ['all work and no play make andybons a dull boy']},
+ ];
+
+ return element.process(content).then(() => {
+ const groups = element.groups;
+
+ // group[0] is the file group
+ // group[1] is the "a" group
+
+ assert.equal(groups[2].type, GrDiffGroup.Type.BOTH);
+ assert.equal(groups[2].lines.length, 5);
+ for (const l of groups[2].lines) {
+ assert.equal(
+ l.text, 'all work and no play make jill a dull girl');
+ }
+ });
});
});
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.html b/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.html
index f9822f2..4679b7d 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/dom-util-behavior/dom-util-behavior.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection_test.html b/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection_test.html
index 469a894..0f5c6dd 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-diff-selection</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-diff-selection.html">
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html
index 57525e1..d9cf979 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html
@@ -15,12 +15,12 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
<link rel="import" href="../../../behaviors/gr-path-list-behavior/gr-path-list-behavior.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html">
-<link rel="import" href="../../../bower_components/iron-dropdown/iron-dropdown.html">
+<link rel="import" href="/bower_components/iron-dropdown/iron-dropdown.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../../core/gr-reporting/gr-reporting.html">
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
index c4d6c95..1fde41c 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
@@ -18,11 +18,13 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-diff-view</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
-<script src="../../../bower_components/page/page.js"></script>
+<script src="/bower_components/page/page.js"></script>
<script src="../../../scripts/util.js"></script>
<link rel="import" href="gr-diff-view.html">
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-group_test.html b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-group_test.html
index 9dc5311..11a370a 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-group_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-group_test.html
@@ -18,8 +18,10 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-diff-group</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="gr-diff-line.js"></script>
<script src="gr-diff-group.js"></script>
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html
index 72fc1ee..f78f7fd 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
@@ -155,14 +155,14 @@
content: '\A';
}
.contextControl {
- background-color: var(--diff-context-control-color);
+ background-color: var(--diff-context-control-background-color);
border: 1px solid var(--diff-context-control-border-color);
}
.contextControl gr-button {
display: inline-block;
text-decoration: none;
--gr-button: {
- color: var(--deemphasized-text-color);
+ color: var(--diff-context-control-color);
padding: .2em;
}
}
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js
index 40a7abe..d7e193c 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff.js
@@ -390,12 +390,12 @@
_redispatchHoverEvents(addedThreadEls) {
for (const threadEl of addedThreadEls) {
threadEl.addEventListener('mouseenter', () => {
- threadEl.dispatchEvent(
- new CustomEvent('comment-thread-mouseenter', {bubbles: true}));
+ threadEl.dispatchEvent(new CustomEvent(
+ 'comment-thread-mouseenter', {bubbles: true, composed: true}));
});
threadEl.addEventListener('mouseleave', () => {
- threadEl.dispatchEvent(
- new CustomEvent('comment-thread-mouseleave', {bubbles: true}));
+ threadEl.dispatchEvent(new CustomEvent(
+ 'comment-thread-mouseleave', {bubbles: true, composed: true}));
});
}
},
@@ -551,6 +551,7 @@
this._getIsParentCommentByLineAndContent(lineEl, contentEl);
this.dispatchEvent(new CustomEvent('create-comment', {
bubbles: true,
+ composed: true,
detail: {
lineNum,
side,
@@ -727,14 +728,16 @@
_renderDiffTable() {
this._unobserveIncrementalNodes();
if (!this.prefs) {
- this.dispatchEvent(new CustomEvent('render', {bubbles: true}));
+ this.dispatchEvent(
+ new CustomEvent('render', {bubbles: true, composed: true}));
return;
}
if (this.prefs.context === -1 &&
this._diffLength >= LARGE_DIFF_THRESHOLD_LINES &&
this._safetyBypass === null) {
this._showWarning = true;
- this.dispatchEvent(new CustomEvent('render', {bubbles: true}));
+ this.dispatchEvent(
+ new CustomEvent('render', {bubbles: true, composed: true}));
return;
}
@@ -744,7 +747,7 @@
this.$.diffBuilder.render(keyLocations, this._getBypassPrefs())
.then(() => {
this.dispatchEvent(
- new CustomEvent('render', {bubbles: true}));
+ new CustomEvent('render', {bubbles: true, composed: true}));
});
},
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html
index 42f098b..9641a1e 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-diff</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="../../../scripts/util.js"></script>
@@ -762,7 +764,7 @@
() => {
Promise.resolve();
element.$.diffBuilder.dispatchEvent(
- new CustomEvent('render', {bubbles: true}));
+ new CustomEvent('render', {bubbles: true, composed: true}));
});
const mock = document.createElement('mock-diff-response');
sandbox.stub(element.$.diffBuilder, 'getDiffLength').returns(10000);
diff --git a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.html b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.html
index 3de4284..114d840 100644
--- a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.html
+++ b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.html b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.html
index 99d22c6..922a11c 100644
--- a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.html
@@ -18,11 +18,13 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-patch-range-select</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
-<script src="../../../bower_components/page/page.js"></script>
+<script src="/bower_components/page/page.js"></script>
<link rel="import" href="../../diff/gr-comment-api/gr-comment-api.html">
<link rel="import" href="../../shared/gr-rest-api-interface/mock-diff-response_test.html">
diff --git a/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer.html b/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer.html
index c9e9f50..17a4866 100644
--- a/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer.html
+++ b/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<dom-module id="gr-ranged-comment-layer">
<template>
</template>
diff --git a/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer.js b/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer.js
index e28142b..3c1f45f 100644
--- a/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer.js
+++ b/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer.js
@@ -188,6 +188,7 @@
range.end = line.text.length;
this.dispatchEvent(new CustomEvent('normalize-range', {
bubbles: true,
+ composed: true,
detail: {lineNum, side},
}));
}
diff --git a/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer_test.html b/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer_test.html
index 682c026..b057d69 100644
--- a/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-ranged-comment-layer</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="../gr-diff/gr-diff-line.js"></script>
diff --git a/polygerrit-ui/app/elements/diff/gr-selection-action-box/gr-selection-action-box.html b/polygerrit-ui/app/elements/diff/gr-selection-action-box/gr-selection-action-box.html
index 633530f..c2983f7 100644
--- a/polygerrit-ui/app/elements/diff/gr-selection-action-box/gr-selection-action-box.html
+++ b/polygerrit-ui/app/elements/diff/gr-selection-action-box/gr-selection-action-box.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-tooltip/gr-tooltip.html">
diff --git a/polygerrit-ui/app/elements/diff/gr-selection-action-box/gr-selection-action-box_test.html b/polygerrit-ui/app/elements/diff/gr-selection-action-box/gr-selection-action-box_test.html
index dece366..b950e7b 100644
--- a/polygerrit-ui/app/elements/diff/gr-selection-action-box/gr-selection-action-box_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-selection-action-box/gr-selection-action-box_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-selection-action-box</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-selection-action-box.html">
diff --git a/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.html b/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.html
index 67c32bb..dd6bfec 100644
--- a/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.html
+++ b/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-lib-loader/gr-lib-loader.html">
<dom-module id="gr-syntax-layer">
diff --git a/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer_test.html b/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer_test.html
index b63675a..472db21 100644
--- a/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-syntax-layer</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="../../shared/gr-rest-api-interface/mock-diff-response_test.html">
<link rel="import" href="gr-syntax-layer.html">
diff --git a/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.html b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.html
index 720f353..616172b 100644
--- a/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.html
+++ b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search.html
@@ -14,11 +14,11 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-list-view-behavior/gr-list-view-behavior.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../../styles/gr-table-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-list-view/gr-list-view.html">
diff --git a/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_test.html b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_test.html
index 84addb0..84298e2 100644
--- a/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_test.html
+++ b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_test.html
@@ -18,10 +18,12 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-documentation-search</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/page/page.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/page/page.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-documentation-search.html">
diff --git a/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor.html b/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor.html
index 093e979..5c13ff9 100644
--- a/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor.html
+++ b/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<dom-module id="gr-default-editor">
diff --git a/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor.js b/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor.js
index 01cd9df..bae838e 100644
--- a/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor.js
+++ b/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor.js
@@ -32,8 +32,9 @@
},
_handleTextareaInput(e) {
- this.dispatchEvent(new CustomEvent('content-change',
- {detail: {value: e.target.value}, bubbles: true}));
+ this.dispatchEvent(new CustomEvent(
+ 'content-change',
+ {detail: {value: e.target.value}, bubbles: true, composed: true}));
},
});
})();
diff --git a/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor_test.html b/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor_test.html
index b79cd9d..c986e7c 100644
--- a/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor_test.html
+++ b/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor_test.html
@@ -17,9 +17,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-default-editor</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-default-editor.html">
@@ -50,7 +52,7 @@
element.addEventListener('content-change', contentChangedHandler);
textarea.value = 'test';
textarea.dispatchEvent(new CustomEvent('input',
- {target: textarea, bubbles: true}));
+ {target: textarea, bubbles: true, composed: true}));
});
});
</script>
diff --git a/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls.html b/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls.html
index 81b3c07..ea5024a 100644
--- a/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls.html
+++ b/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls.html
@@ -15,11 +15,11 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
<link rel="import" href="../../../behaviors/gr-path-list-behavior/gr-path-list-behavior.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../../shared/gr-autocomplete/gr-autocomplete.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
diff --git a/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls_test.html b/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls_test.html
index c67a2af..75a371f8 100644
--- a/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls_test.html
+++ b/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls_test.html
@@ -17,9 +17,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-edit-controls</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-edit-controls.html">
diff --git a/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls.html b/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls.html
index c57a147..1ab08a3 100644
--- a/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls.html
+++ b/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-dropdown/gr-dropdown.html">
diff --git a/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls.js b/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls.js
index 9407f18..9c59a9a 100644
--- a/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls.js
+++ b/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls.js
@@ -46,8 +46,9 @@
},
_dispatchFileAction(action, path) {
- this.dispatchEvent(new CustomEvent('file-action-tap',
- {detail: {action, path}, bubbles: true}));
+ this.dispatchEvent(new CustomEvent(
+ 'file-action-tap',
+ {detail: {action, path}, bubbles: true, composed: true}));
},
_computeFileActions(actions) {
diff --git a/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls_test.html b/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls_test.html
index 12d9e0b..7979e57 100644
--- a/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls_test.html
+++ b/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls_test.html
@@ -17,9 +17,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-edit-file-controls</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="../gr-edit-constants.html">
diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.html b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.html
index f80e9f8..6c2cbb5 100644
--- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.html
+++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
<link rel="import" href="../../../behaviors/gr-path-list-behavior/gr-path-list-behavior.html">
diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js
index 8e108bb..ec6f110 100644
--- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js
+++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view.js
@@ -104,7 +104,9 @@
},
_paramsChanged(value) {
- if (value.view !== Gerrit.Nav.View.EDIT) { return; }
+ if (value.view !== Gerrit.Nav.View.EDIT) {
+ return;
+ }
this._changeNum = value.changeNum;
this._path = value.path;
@@ -134,7 +136,9 @@
_handlePathChanged(e) {
const path = e.detail;
- if (path === this._path) { return Promise.resolve(); }
+ if (path === this._path) {
+ return Promise.resolve();
+ }
return this.$.restAPI.renameFileInChangeEdit(this._changeNum,
this._path, path).then(res => {
if (!res.ok) { return; }
@@ -158,8 +162,11 @@
.then(res => {
if (storedContent && storedContent.message &&
storedContent.message !== res.content) {
- this.dispatchEvent(new CustomEvent('show-alert',
- {detail: {message: RESTORED_MESSAGE}, bubbles: true}));
+ this.dispatchEvent(new CustomEvent('show-alert', {
+ detail: {message: RESTORED_MESSAGE},
+ bubbles: true,
+ composed: true,
+ }));
this._newContent = storedContent.message;
} else {
@@ -197,11 +204,14 @@
this.dispatchEvent(new CustomEvent('show-alert', {
detail: {message},
bubbles: true,
+ composed: true,
}));
},
_computeSaveDisabled(content, newContent, saving) {
- if (saving) { return true; }
+ if (saving) {
+ return true;
+ }
return content === newContent;
},
@@ -224,7 +234,9 @@
_handleSaveShortcut(e) {
e.preventDefault();
- if (!this._saveDisabled) { this._saveEdit(); }
+ if (!this._saveDisabled) {
+ this._saveEdit();
+ }
},
});
})();
diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html
index 2f5332d..abb8131 100644
--- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html
+++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.html
@@ -17,9 +17,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-editor-view</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-editor-view.html">
@@ -121,7 +123,7 @@
const storeStub = sandbox.spy(element.$.storage, 'setEditableContentItem');
element._newContent = 'test';
element.$.editorEndpoint.dispatchEvent(new CustomEvent('content-change', {
- bubbles: true,
+ bubbles: true, composed: true,
detail: {value: 'new content value'},
}));
element.flushDebouncer('store');
diff --git a/polygerrit-ui/app/elements/gr-app-it_test.html b/polygerrit-ui/app/elements/gr-app-it_test.html
index 2601aeb..cc8b784 100644
--- a/polygerrit-ui/app/elements/gr-app-it_test.html
+++ b/polygerrit-ui/app/elements/gr-app-it_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-app-it_test</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../test/common-test-setup.html"/>
<link rel="import" href="gr-app.html">
diff --git a/polygerrit-ui/app/elements/gr-app.html b/polygerrit-ui/app/elements/gr-app.html
index ac00fcf..227616b 100644
--- a/polygerrit-ui/app/elements/gr-app.html
+++ b/polygerrit-ui/app/elements/gr-app.html
@@ -34,9 +34,9 @@
window.Gerrit = Gerrit;
</script>
-<link rel="import" href="../bower_components/polymer/polymer.html">
-<link rel="import" href="../bower_components/polymer-resin/standalone/polymer-resin.html">
-<link rel="import" href="../bower_components/polymer/lib/legacy/legacy-data-mixin.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer-resin/standalone/polymer-resin.html">
+<link rel="import" href="/bower_components/polymer/lib/legacy/legacy-data-mixin.html">
<link rel="import" href="../behaviors/safe-types-behavior/safe-types-behavior.html">
<script>
security.polymer_resin.install({
@@ -45,7 +45,7 @@
safeTypesBridge: Gerrit.SafeTypes.safeTypesBridge,
});
</script>
-<script src="../bower_components/moment/moment.js"></script>
+<script src="/bower_components/moment/moment.js"></script>
<link rel="import" href="../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
diff --git a/polygerrit-ui/app/elements/gr-app_test.html b/polygerrit-ui/app/elements/gr-app_test.html
index 71ceab4..19d06a9 100644
--- a/polygerrit-ui/app/elements/gr-app_test.html
+++ b/polygerrit-ui/app/elements/gr-app_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-app</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../test/common-test-setup.html"/>
<link rel="import" href="gr-app.html">
diff --git a/polygerrit-ui/app/elements/plugins/gr-admin-api/gr-admin-api_test.html b/polygerrit-ui/app/elements/plugins/gr-admin-api/gr-admin-api_test.html
index 966efac..6883e7e 100644
--- a/polygerrit-ui/app/elements/plugins/gr-admin-api/gr-admin-api_test.html
+++ b/polygerrit-ui/app/elements/plugins/gr-admin-api/gr-admin-api_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-admin-api</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
<link rel="import" href="gr-admin-api.html">
diff --git a/polygerrit-ui/app/elements/plugins/gr-attribute-helper/gr-attribute-helper.html b/polygerrit-ui/app/elements/plugins/gr-attribute-helper/gr-attribute-helper.html
index 208f1e8..ece8677 100644
--- a/polygerrit-ui/app/elements/plugins/gr-attribute-helper/gr-attribute-helper.html
+++ b/polygerrit-ui/app/elements/plugins/gr-attribute-helper/gr-attribute-helper.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<dom-module id="gr-attribute-helper">
<script src="gr-attribute-helper.js"></script>
diff --git a/polygerrit-ui/app/elements/plugins/gr-attribute-helper/gr-attribute-helper_test.html b/polygerrit-ui/app/elements/plugins/gr-attribute-helper/gr-attribute-helper_test.html
index 86238cf..efd6104 100644
--- a/polygerrit-ui/app/elements/plugins/gr-attribute-helper/gr-attribute-helper_test.html
+++ b/polygerrit-ui/app/elements/plugins/gr-attribute-helper/gr-attribute-helper_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-attribute-helper</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-attribute-helper.html"/>
diff --git a/polygerrit-ui/app/elements/plugins/gr-change-metadata-api/gr-change-metadata-api.html b/polygerrit-ui/app/elements/plugins/gr-change-metadata-api/gr-change-metadata-api.html
index eddb52b..dd532e1 100644
--- a/polygerrit-ui/app/elements/plugins/gr-change-metadata-api/gr-change-metadata-api.html
+++ b/polygerrit-ui/app/elements/plugins/gr-change-metadata-api/gr-change-metadata-api.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<dom-module id="gr-change-metadata-api">
<script src="gr-change-metadata-api.js"></script>
diff --git a/polygerrit-ui/app/elements/plugins/gr-dom-hooks/gr-dom-hooks.html b/polygerrit-ui/app/elements/plugins/gr-dom-hooks/gr-dom-hooks.html
index 252e812..2cdae3c 100644
--- a/polygerrit-ui/app/elements/plugins/gr-dom-hooks/gr-dom-hooks.html
+++ b/polygerrit-ui/app/elements/plugins/gr-dom-hooks/gr-dom-hooks.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
<dom-module id="gr-dom-hooks">
diff --git a/polygerrit-ui/app/elements/plugins/gr-dom-hooks/gr-dom-hooks_test.html b/polygerrit-ui/app/elements/plugins/gr-dom-hooks/gr-dom-hooks_test.html
index 3dde458..1e946c3 100644
--- a/polygerrit-ui/app/elements/plugins/gr-dom-hooks/gr-dom-hooks_test.html
+++ b/polygerrit-ui/app/elements/plugins/gr-dom-hooks/gr-dom-hooks_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-dom-hooks</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-dom-hooks.html"/>
diff --git a/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator.html b/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator.html
index 50b80d5..53ff901 100644
--- a/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator.html
+++ b/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
<dom-module id="gr-endpoint-decorator">
diff --git a/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator.js b/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator.js
index 35e4292..69d7188 100644
--- a/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator.js
+++ b/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator.js
@@ -115,7 +115,8 @@
},
_initModule({moduleName, plugin, type, domHook}) {
- if (this._initializedPlugins.get(plugin.getPluginName())) {
+ const name = plugin.getPluginName() + '.' + moduleName;
+ if (this._initializedPlugins.get(name)) {
return;
}
let initPromise;
@@ -128,10 +129,9 @@
break;
}
if (!initPromise) {
- console.warn('Unable to initialize module' +
- `${moduleName} from ${plugin.getPluginName()}`);
+ console.warn('Unable to initialize module ' + name);
}
- this._initializedPlugins.set(plugin.getPluginName(), true);
+ this._initializedPlugins.set(name, true);
initPromise.then(el => {
domHook.handleInstanceAttached(el);
this._domHooks.set(el, domHook);
diff --git a/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator_test.html b/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator_test.html
index 31d3150..fa097ac 100644
--- a/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator_test.html
+++ b/polygerrit-ui/app/elements/plugins/gr-endpoint-decorator/gr-endpoint-decorator_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-endpoint-decorator</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-endpoint-decorator.html">
<link rel="import" href="../gr-endpoint-param/gr-endpoint-param.html">
@@ -127,6 +129,22 @@
});
});
+ test('two modules', done => {
+ plugin.registerCustomComponent('banana', 'mod-one');
+ plugin.registerCustomComponent('banana', 'mod-two');
+ flush(() => {
+ const element =
+ container.querySelector('gr-endpoint-decorator[name="banana"]');
+ const module1 = Polymer.dom(element.root).children.find(
+ element => element.nodeName === 'MOD-ONE');
+ assert.isOk(module1);
+ const module2 = Polymer.dom(element.root).children.find(
+ element => element.nodeName === 'MOD-TWO');
+ assert.isOk(module2);
+ done();
+ });
+ });
+
test('late param setup', done => {
const element =
container.querySelector('gr-endpoint-decorator[name="banana"]');
diff --git a/polygerrit-ui/app/elements/plugins/gr-endpoint-param/gr-endpoint-param.html b/polygerrit-ui/app/elements/plugins/gr-endpoint-param/gr-endpoint-param.html
index 9d28ac3..6a5b558 100644
--- a/polygerrit-ui/app/elements/plugins/gr-endpoint-param/gr-endpoint-param.html
+++ b/polygerrit-ui/app/elements/plugins/gr-endpoint-param/gr-endpoint-param.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<dom-module id="gr-endpoint-param">
<script src="gr-endpoint-param.js"></script>
diff --git a/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper.html b/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper.html
index d34bdef..717d52b 100644
--- a/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper.html
+++ b/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<dom-module id="gr-event-helper">
<script src="gr-event-helper.js"></script>
diff --git a/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper_test.html b/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper_test.html
index 47274f6..08c1df9 100644
--- a/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper_test.html
+++ b/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-event-helper</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-event-helper.html"/>
diff --git a/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style.html b/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style.html
index a83b2ab..6a55349 100644
--- a/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style.html
+++ b/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
<dom-module id="gr-external-style">
diff --git a/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style_test.html b/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style_test.html
index ec2888d..9566067 100644
--- a/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style_test.html
+++ b/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-external-style</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-external-style.html">
diff --git a/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host.html b/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host.html
index 8e106cc..f277899 100644
--- a/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host.html
+++ b/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
diff --git a/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host_test.html b/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host_test.html
index 9901d9f..e577182 100644
--- a/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host_test.html
+++ b/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-plugin-host</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-plugin-host.html">
diff --git a/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-plugin-popup.html b/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-plugin-popup.html
index ce0bf1b..402d988 100644
--- a/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-plugin-popup.html
+++ b/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-plugin-popup.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
<dom-module id="gr-plugin-popup">
diff --git a/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-plugin-popup_test.html b/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-plugin-popup_test.html
index 91386b9..1f1e81e 100644
--- a/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-plugin-popup_test.html
+++ b/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-plugin-popup_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-plugin-popup</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-plugin-popup.html"/>
diff --git a/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-popup-interface.html b/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-popup-interface.html
index 2fdf28c..26ece30 100644
--- a/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-popup-interface.html
+++ b/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-popup-interface.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
<link rel="import" href="gr-plugin-popup.html">
diff --git a/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-popup-interface_test.html b/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-popup-interface_test.html
index 983c795..53370e2 100644
--- a/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-popup-interface_test.html
+++ b/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-popup-interface_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-popup-interface</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-popup-interface.html"/>
diff --git a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-plugin-repo-command.html b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-plugin-repo-command.html
index c9486ae..2fd4534 100644
--- a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-plugin-repo-command.html
+++ b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-plugin-repo-command.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../admin/gr-repo-command/gr-repo-command.html">
<dom-module id="gr-plugin-repo-command">
diff --git a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api.html b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api.html
index 34c9797..8e6c053 100644
--- a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api.html
+++ b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
<link rel="import" href="gr-plugin-repo-command.html">
diff --git a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.html b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.html
index bb9ae87..7c7564b 100644
--- a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.html
+++ b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-repo-api</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="../gr-endpoint-decorator/gr-endpoint-decorator.html">
<link rel="import" href="gr-repo-api.html">
diff --git a/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api.html b/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api.html
index 7c916dc..20cc71b 100644
--- a/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api.html
+++ b/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../settings/gr-settings-view/gr-settings-item.html">
<link rel="import" href="../../settings/gr-settings-view/gr-settings-menu-item.html">
diff --git a/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api_test.html b/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api_test.html
index cabd26b..d34ca94 100644
--- a/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api_test.html
+++ b/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-settings-api</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="../gr-endpoint-decorator/gr-endpoint-decorator.html">
<link rel="import" href="gr-settings-api.html">
diff --git a/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-custom-plugin-header.html b/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-custom-plugin-header.html
index 496d0e7..97966ed 100644
--- a/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-custom-plugin-header.html
+++ b/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-custom-plugin-header.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<dom-module id="gr-custom-plugin-header">
<template>
diff --git a/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api.html b/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api.html
index b84f5b9..d6e67fe 100644
--- a/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api.html
+++ b/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
<link rel="import" href="gr-custom-plugin-header.html">
diff --git a/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api_test.html b/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api_test.html
index 8d23ea2..82eb0f8 100644
--- a/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api_test.html
+++ b/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-theme-api</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="../gr-endpoint-decorator/gr-endpoint-decorator.html">
<link rel="import" href="gr-theme-api.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.html b/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.html
index f534771..7d469a3 100644
--- a/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.html
+++ b/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-avatar/gr-avatar.html">
<link rel="import" href="../../shared/gr-date-formatter/gr-date-formatter.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info_test.html b/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info_test.html
index f91277a..de222a9 100644
--- a/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-account-info</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-account-info.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-agreements-list/gr-agreements-list.html b/polygerrit-ui/app/elements/settings/gr-agreements-list/gr-agreements-list.html
index 72ea503..852161c 100644
--- a/polygerrit-ui/app/elements/settings/gr-agreements-list/gr-agreements-list.html
+++ b/polygerrit-ui/app/elements/settings/gr-agreements-list/gr-agreements-list.html
@@ -16,7 +16,7 @@
-->
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-agreements-list/gr-agreements-list_test.html b/polygerrit-ui/app/elements/settings/gr-agreements-list/gr-agreements-list_test.html
index 56122a9..e0a3afa 100644
--- a/polygerrit-ui/app/elements/settings/gr-agreements-list/gr-agreements-list_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-agreements-list/gr-agreements-list_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-settings-view</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-agreements-list.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor.html b/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor.html
index 4f69513..43bb2db 100644
--- a/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor.html
+++ b/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
<link rel="import" href="../../../behaviors/gr-change-table-behavior/gr-change-table-behavior.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-date-formatter/gr-date-formatter.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor_test.html b/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor_test.html
index 32fab9d..e1ec32c 100644
--- a/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-settings-view</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-change-table-editor.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view.html b/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view.html
index d5f1dc3..bb5c069 100644
--- a/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view.html
+++ b/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view.html
@@ -16,8 +16,8 @@
-->
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view.js b/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view.js
index a59b886..62bec12 100644
--- a/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view.js
+++ b/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view.js
@@ -66,7 +66,9 @@
_getAgreementsUrl(configUrl) {
let url;
- if (!configUrl) { return ''; }
+ if (!configUrl) {
+ return '';
+ }
if (configUrl.startsWith('http:') || configUrl.startsWith('https:')) {
url = configUrl;
} else {
@@ -100,8 +102,8 @@
},
_createToast(message) {
- this.dispatchEvent(new CustomEvent('show-alert',
- {detail: {message}, bubbles: true}));
+ this.dispatchEvent(new CustomEvent(
+ 'show-alert', {detail: {message}, bubbles: true, composed: true}));
},
_computeShowAgreementsClass(agreements) {
@@ -133,9 +135,13 @@
// then hides the text box and submit button.
_computeHideAgreementClass(name, config) {
for (const key in config) {
- if (!config.hasOwnProperty(key)) { continue; }
+ if (!config.hasOwnProperty(key)) {
+ continue;
+ }
for (const prop in config[key]) {
- if (!config[key].hasOwnProperty(prop)) { continue; }
+ if (!config[key].hasOwnProperty(prop)) {
+ continue;
+ }
if (name === config[key].name &&
!config[key].auto_verify_group) {
return 'hideAgreementsTextBox';
diff --git a/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view_test.html b/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view_test.html
index 2304d15..53d6be1 100644
--- a/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-cla-view</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-cla-view.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences.html b/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences.html
index b3e6990..33fc879 100644
--- a/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences.html
+++ b/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences_test.html b/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences_test.html
index 42171b7..c1c5c52 100644
--- a/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-edit-preferences</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-edit-preferences.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor.html b/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor.html
index 0a7433e..98b9b6d 100644
--- a/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor.html
+++ b/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor_test.html b/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor_test.html
index e937f8b..e8ecd7a 100644
--- a/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-email-editor</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-email-editor.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor.html b/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor.html
index 7a63605..c21e84d 100644
--- a/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor.html
+++ b/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor_test.html b/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor_test.html
index 0a2ae78..c3cd8e1 100644
--- a/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-gpg-editor</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-gpg-editor.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-group-list/gr-group-list.html b/polygerrit-ui/app/elements/settings/gr-group-list/gr-group-list.html
index 2c7afd3..ca500c8 100644
--- a/polygerrit-ui/app/elements/settings/gr-group-list/gr-group-list.html
+++ b/polygerrit-ui/app/elements/settings/gr-group-list/gr-group-list.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-group-list/gr-group-list_test.html b/polygerrit-ui/app/elements/settings/gr-group-list/gr-group-list_test.html
index 3fa5a36..ac17521 100644
--- a/polygerrit-ui/app/elements/settings/gr-group-list/gr-group-list_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-group-list/gr-group-list_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-settings-view</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-group-list.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password.html b/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password.html
index 2fe07ca..8e5db7d 100644
--- a/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password.html
+++ b/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password_test.html b/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password_test.html
index ca50b2b..8924058 100644
--- a/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-settings-view</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-http-password.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-identities/gr-identities.html b/polygerrit-ui/app/elements/settings/gr-identities/gr-identities.html
index 872e558..be851b1 100644
--- a/polygerrit-ui/app/elements/settings/gr-identities/gr-identities.html
+++ b/polygerrit-ui/app/elements/settings/gr-identities/gr-identities.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-identities/gr-identities_test.html b/polygerrit-ui/app/elements/settings/gr-identities/gr-identities_test.html
index c77a1b9..19c9df3 100644
--- a/polygerrit-ui/app/elements/settings/gr-identities/gr-identities_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-identities/gr-identities_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-identities</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-identities.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor.html b/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor.html
index aa42623..56f4cfa 100644
--- a/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor.html
+++ b/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-date-formatter/gr-date-formatter.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor_test.html b/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor_test.html
index c8a54b6..917026a 100644
--- a/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-settings-view</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-menu-editor.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.html b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.html
index 5f1794c..66b06f8 100644
--- a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.html
+++ b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog_test.html b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog_test.html
index 93a3188..d1b5c80 100644
--- a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-registration-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-registration-dialog.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-item.html b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-item.html
index 30a3801..704a8698d 100644
--- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-item.html
+++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-item.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<dom-module id="gr-settings-item">
<template>
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-menu-item.html b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-menu-item.html
index f64d898..846f776 100644
--- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-menu-item.html
+++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-menu-item.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/gr-page-nav-styles.html">
<dom-module id="gr-settings-menu-item">
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html
index 538bab7..68518a0 100644
--- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html
+++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html
@@ -15,10 +15,10 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/docs-url-behavior/docs-url-behavior.html">
-<link rel="import" href="../../../bower_components/paper-toggle-button/paper-toggle-button.html">
+<link rel="import" href="/bower_components/paper-toggle-button/paper-toggle-button.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../../styles/gr-menu-page-styles.html">
<link rel="import" href="../../../styles/gr-page-nav-styles.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js
index 1f76a68..d776b54 100644
--- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js
+++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js
@@ -414,6 +414,7 @@
this.dispatchEvent(new CustomEvent('show-alert', {
detail: {message: RELOAD_MESSAGE},
bubbles: true,
+ composed: true,
}));
this.async(() => {
window.location.reload();
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.html b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.html
index 506c6af..6dcf124 100644
--- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-settings-view</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-settings-view.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor.html b/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor.html
index ab12403..784e0fc 100644
--- a/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor.html
+++ b/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
<link rel="import" href="../../../styles/gr-form-styles.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor_test.html b/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor_test.html
index 1785d1f..991f17c 100644
--- a/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-ssh-editor</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-ssh-editor.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor.html b/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor.html
index 85fe368..e314608 100644
--- a/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor.html
+++ b/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-autocomplete/gr-autocomplete.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor_test.html b/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor_test.html
index 9022bcc..4193382 100644
--- a/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-settings-view</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-watched-projects-editor.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.html b/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.html
index 543ed85..6de10a3 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.html
+++ b/polygerrit-ui/app/elements/shared/gr-account-chip/gr-account-chip.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../gr-account-link/gr-account-link.html">
<link rel="import" href="../gr-button/gr-button.html">
<link rel="import" href="../gr-icons/gr-icons.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.html b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.html
index bdf37bf..fb760d5 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.html
+++ b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label.html
@@ -17,7 +17,7 @@
<link rel="import" href="../../../behaviors/gr-anonymous-name-behavior/gr-anonymous-name-behavior.html">
<link rel="import" href="../../../behaviors/gr-tooltip-behavior/gr-tooltip-behavior.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../gr-avatar/gr-avatar.html">
<link rel="import" href="../gr-limited-text/gr-limited-text.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.html b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.html
index 288a670..d3f29dc 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-account-label</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="../../../scripts/util.js"></script>
diff --git a/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link.html b/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link.html
index 34b0de6..d3575b2 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link.html
+++ b/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link.html
@@ -16,7 +16,7 @@
-->
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../gr-account-label/gr-account-label.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link_test.html b/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link_test.html
index 6d1831e..134c579 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-account-link</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-account-link.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.html b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.html
index b00fded..2b043c4 100644
--- a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.html
+++ b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../gr-button/gr-button.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.html b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.html
index 095e640..2338d55 100644
--- a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-alert</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-alert.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown.html b/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown.html
index 7b82635..383d129 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown.html
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown.html
@@ -15,10 +15,10 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
-<link rel="import" href="../../../bower_components/iron-dropdown/iron-dropdown.html">
+<link rel="import" href="/bower_components/iron-dropdown/iron-dropdown.html">
<link rel="import" href="../../shared/gr-cursor-manager/gr-cursor-manager.html">
<script src="../../../scripts/rootElement.js"></script>
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown_test.html b/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown_test.html
index d4d54ff..07a3762 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-autocomplete-dropdown</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-autocomplete-dropdown.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.html b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.html
index a878174..ac739c3 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.html
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete.html
@@ -14,8 +14,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/paper-input/paper-input.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/paper-input/paper-input.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
<link rel="import" href="../../shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown.html">
<link rel="import" href="../../shared/gr-cursor-manager/gr-cursor-manager.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.html b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.html
index 1a76f98..217321f 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-reviewer-list</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-autocomplete.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar.html b/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar.html
index bc63acf..5c9b66e 100644
--- a/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar.html
+++ b/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar_test.html b/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar_test.html
index 5ce17c0..42d7678 100644
--- a/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-avatar</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-avatar.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-button/gr-button.html b/polygerrit-ui/app/elements/shared/gr-button/gr-button.html
index cdf617f..754c3c0 100644
--- a/polygerrit-ui/app/elements/shared/gr-button/gr-button.html
+++ b/polygerrit-ui/app/elements/shared/gr-button/gr-button.html
@@ -15,11 +15,11 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-tooltip-behavior/gr-tooltip-behavior.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
-<link rel="import" href="../../../bower_components/paper-button/paper-button.html">
+<link rel="import" href="/bower_components/paper-button/paper-button.html">
<link rel="import" href="../../../styles/shared-styles.html">
<dom-module id="gr-button">
diff --git a/polygerrit-ui/app/elements/shared/gr-button/gr-button_test.html b/polygerrit-ui/app/elements/shared/gr-button/gr-button_test.html
index ed0da2e..807d095 100644
--- a/polygerrit-ui/app/elements/shared/gr-button/gr-button_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-button/gr-button_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-button</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-button.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.html b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.html
index a14c652..ebe3a6b 100644
--- a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.html
+++ b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-icons/gr-icons.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.js b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.js
index 44f8c00..98fd94a 100644
--- a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.js
+++ b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star.js
@@ -49,6 +49,7 @@
this.set('change.starred', newVal);
this.dispatchEvent(new CustomEvent('toggle-star', {
bubbles: true,
+ composed: true,
detail: {change: this.change, starred: newVal},
}));
},
diff --git a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star_test.html b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star_test.html
index 0ca9368..7ee22a7 100644
--- a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-change-star</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-change-star.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.html b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.html
index 99ddff1..fa95382 100644
--- a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.html
+++ b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../../shared/gr-tooltip-content/gr-tooltip-content.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status_test.html b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status_test.html
index f73fc02..3ac4016 100644
--- a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-change-status</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-change-status.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.html b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.html
index 8c80b37..bee134b 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.html
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-path-list-behavior/gr-path-list-behavior.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.html b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.html
index 2e1b3bd..86da001 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-comment-thread</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="../../../scripts/util.js"></script>
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.html b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.html
index a470285..1460035 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.html
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.html
@@ -15,9 +15,9 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
-<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
+<link rel="import" href="/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../core/gr-reporting/gr-reporting.html">
<link rel="import" href="../../plugins/gr-endpoint-decorator/gr-endpoint-decorator.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js
index b5481a9..bf7df71 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js
@@ -128,7 +128,8 @@
_numPendingDraftRequests: {
type: Object,
- value: {number: 0}, // Intentional to share the object across instances.
+ value:
+ {number: 0}, // Intentional to share the object across instances.
},
_enableOverlay: {
@@ -230,7 +231,9 @@
*/
save(opt_comment) {
let comment = opt_comment;
- if (!comment) { comment = this.comment; }
+ if (!comment) {
+ comment = this.comment;
+ }
this.set('comment.message', this._messageText);
this.editing = false;
@@ -340,7 +343,9 @@
_computeSaveDisabled(draft, comment, resolved) {
// If resolved state has changed and a msg exists, save should be enabled.
- if (comment.unresolved === resolved && draft) { return false; }
+ if (comment.unresolved === resolved && draft) {
+ return false;
+ }
return !draft || draft.trim() === '';
},
@@ -376,7 +381,9 @@
},
_messageTextChanged(newValue, oldValue) {
- if (!this.comment || (this.comment && this.comment.id)) { return; }
+ if (!this.comment || (this.comment && this.comment.id)) {
+ return;
+ }
this.debounce('store', () => {
const message = this._messageText;
@@ -400,9 +407,12 @@
_handleAnchorTap(e) {
e.preventDefault();
- if (!this.comment.line) { return; }
+ if (!this.comment.line) {
+ return;
+ }
this.dispatchEvent(new CustomEvent('comment-anchor-tap', {
bubbles: true,
+ composed: true,
detail: {
number: this.comment.line || FILE,
side: this.side,
@@ -421,7 +431,9 @@
e.preventDefault();
// Ignore saves started while already saving.
- if (this.disabled) { return; }
+ if (this.disabled) {
+ return;
+ }
const timingLabel = this.comment.id ?
REPORT_UPDATE_DRAFT : REPORT_CREATE_DRAFT;
const timer = this.$.reporting.getTimer(timingLabel);
@@ -450,6 +462,7 @@
_handleFix() {
this.dispatchEvent(new CustomEvent('create-fix-comment', {
bubbles: true,
+ composed: true,
detail: this._getEventPayload(),
}));
},
@@ -512,7 +525,9 @@
},
_getSavingMessage(numPending) {
- if (numPending === 0) { return SAVED_MESSAGE; }
+ if (numPending === 0) {
+ return SAVED_MESSAGE;
+ }
return [
SAVING_MESSAGE,
numPending,
@@ -544,8 +559,8 @@
// Note: the event is fired on the body rather than this element because
// this element may not be attached by the time this executes, in which
// case the event would not bubble.
- document.body.dispatchEvent(new CustomEvent('show-alert',
- {detail: {message}, bubbles: true}));
+ document.body.dispatchEvent(new CustomEvent(
+ 'show-alert', {detail: {message}, bubbles: true, composed: true}));
}, TOAST_DEBOUNCE_INTERVAL);
},
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.html b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.html
index 7ca5242..c829343 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.html
@@ -18,11 +18,13 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-comment</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
-<script src="../../../bower_components/page/page.js"></script>
+<script src="/bower_components/page/page.js"></script>
<script src="../../../scripts/util.js"></script>
<link rel="import" href="gr-comment.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-confirm-delete-comment-dialog/gr-confirm-delete-comment-dialog.html b/polygerrit-ui/app/elements/shared/gr-confirm-delete-comment-dialog/gr-confirm-delete-comment-dialog.html
index 9decfa9..bf20429 100644
--- a/polygerrit-ui/app/elements/shared/gr-confirm-delete-comment-dialog/gr-confirm-delete-comment-dialog.html
+++ b/polygerrit-ui/app/elements/shared/gr-confirm-delete-comment-dialog/gr-confirm-delete-comment-dialog.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-dialog/gr-dialog.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.html b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.html
index 32ca557..f6b4a27 100644
--- a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.html
+++ b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-icons/gr-icons.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.html b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.html
index d6e9dca..c092b7c 100644
--- a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-copy-clipboard</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-copy-clipboard.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-count-string-formatter/gr-count-string-formatter_test.html b/polygerrit-ui/app/elements/shared/gr-count-string-formatter/gr-count-string-formatter_test.html
index e4d896b..d061ac2 100644
--- a/polygerrit-ui/app/elements/shared/gr-count-string-formatter/gr-count-string-formatter_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-count-string-formatter/gr-count-string-formatter_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-count-string-formatter</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-count-string-formatter.html"/>
diff --git a/polygerrit-ui/app/elements/shared/gr-cursor-manager/gr-cursor-manager.html b/polygerrit-ui/app/elements/shared/gr-cursor-manager/gr-cursor-manager.html
index d619b18..94d7aaa 100644
--- a/polygerrit-ui/app/elements/shared/gr-cursor-manager/gr-cursor-manager.html
+++ b/polygerrit-ui/app/elements/shared/gr-cursor-manager/gr-cursor-manager.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<dom-module id="gr-cursor-manager">
<template></template>
diff --git a/polygerrit-ui/app/elements/shared/gr-cursor-manager/gr-cursor-manager_test.html b/polygerrit-ui/app/elements/shared/gr-cursor-manager/gr-cursor-manager_test.html
index adbe618..0793ccd 100644
--- a/polygerrit-ui/app/elements/shared/gr-cursor-manager/gr-cursor-manager_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-cursor-manager/gr-cursor-manager_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-cursor-manager</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-cursor-manager.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter.html b/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter.html
index 481dd2f..f3ea177 100644
--- a/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter.html
+++ b/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-tooltip-behavior/gr-tooltip-behavior.html">
<link rel="import" href="../gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter_test.html b/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter_test.html
index ad4d0da..a0bf207 100644
--- a/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-date-formatter</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="../../../scripts/util.js"></script>
diff --git a/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog.html b/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog.html
index 797c8ea..0321e58 100644
--- a/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog.html
+++ b/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../gr-button/gr-button.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog_test.html b/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog_test.html
index 4a5a181..1456e77 100644
--- a/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-dialog</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-dialog.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences.html b/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences.html
index d7bc704..e21e5a4 100644
--- a/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences.html
+++ b/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-input/iron-input.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-input/iron-input.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../gr-button/gr-button.html">
<link rel="import" href="../gr-rest-api-interface/gr-rest-api-interface.html">
@@ -135,7 +135,7 @@
<input
id="automaticReviewInput"
type="checkbox"
- checked$="[[diffPrefs.manual_review]]"
+ checked$="[[!diffPrefs.manual_review]]"
on-change="_handleAutomaticReviewTap">
</span>
</section>
diff --git a/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences.js b/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences.js
index eb99d7a..89c3d74 100644
--- a/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences.js
+++ b/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences.js
@@ -66,7 +66,7 @@
_handleAutomaticReviewTap() {
this.set('diffPrefs.manual_review',
- this.$.automaticReviewInput.checked);
+ !this.$.automaticReviewInput.checked);
this._handleDiffPrefsChanged();
},
diff --git a/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences_test.html b/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences_test.html
index 511737f..f7b10e0 100644
--- a/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-diff-preferences</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-diff-preferences.html">
@@ -96,7 +98,7 @@
.firstElementChild.checked, diffPreferences.syntax_highlighting);
assert.equal(
valueOf('Automatically mark viewed files reviewed', 'diffPreferences')
- .firstElementChild.checked, diffPreferences.manual_review);
+ .firstElementChild.checked, !diffPreferences.manual_review);
assert.equal(valueOf('Ignore Whitespace', 'diffPreferences')
.firstElementChild.bindValue, diffPreferences.ignore_whitespace);
diff --git a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.html b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.html
index 6aec5a6..d4a2ab2 100644
--- a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.html
+++ b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.html
@@ -15,11 +15,11 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/rest-client-behavior/rest-client-behavior.html">
-<link rel="import" href="../../../bower_components/paper-tabs/paper-tabs.html">
+<link rel="import" href="/bower_components/paper-tabs/paper-tabs.html">
<link rel="import" href="../../shared/gr-shell-command/gr-shell-command.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.html b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.html
index c59e56a..3b7e8f8 100644
--- a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-download-commands</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-download-commands.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list.html b/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list.html
index f4b120a..1d608c0 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list.html
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list.html
@@ -14,11 +14,11 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-dropdown/iron-dropdown.html">
-<link rel="import" href="../../../bower_components/paper-item/paper-item.html">
-<link rel="import" href="../../../bower_components/paper-listbox/paper-listbox.html">
+<link rel="import" href="/bower_components/iron-dropdown/iron-dropdown.html">
+<link rel="import" href="/bower_components/paper-item/paper-item.html">
+<link rel="import" href="/bower_components/paper-listbox/paper-listbox.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list_test.html b/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list_test.html
index 87fd8de..5f07fc9 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-dropdown-list</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-dropdown-list.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.html b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.html
index 47ab03a..22dcbf0 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.html
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.html
@@ -17,8 +17,8 @@
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-dropdown/iron-dropdown.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-dropdown/iron-dropdown.html">
<link rel="import" href="../../shared/gr-button/gr-button.html">
<link rel="import" href="../../shared/gr-cursor-manager/gr-cursor-manager.html">
<link rel="import" href="../../shared/gr-rest-api-interface/gr-rest-api-interface.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html
index 7bb4dce..bf1c9fa 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-dropdown</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-dropdown.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.html b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.html
index 6cd87f5..aa102e4 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.html
+++ b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../gr-storage/gr-storage.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.js b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.js
index 827bb71..dc945a2 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.js
+++ b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.js
@@ -96,8 +96,11 @@
this.$.storage.getEditableContentItem(this.storageKey);
if (storedContent && storedContent.message) {
content = storedContent.message;
- this.dispatchEvent(new CustomEvent('show-alert',
- {detail: {message: RESTORED_MESSAGE}, bubbles: true}));
+ this.dispatchEvent(new CustomEvent('show-alert', {
+ detail: {message: RESTORED_MESSAGE},
+ bubbles: true,
+ composed: true,
+ }));
}
}
if (!content) {
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.html b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.html
index cc44d9b..3f5ccb0 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.html
@@ -18,11 +18,13 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-editable-content</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
-<script src="../../../bower_components/iron-test-helpers/mock-interactions.js"></script>
+<script src="/bower_components/iron-test-helpers/mock-interactions.js"></script>
<link rel="import" href="gr-editable-content.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label.html b/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label.html
index ddc35bf..5faedd2 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label.html
+++ b/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label.html
@@ -14,11 +14,11 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
-<link rel="import" href="../../../bower_components/iron-dropdown/iron-dropdown.html">
-<link rel="import" href="../../../bower_components/paper-input/paper-input.html">
+<link rel="import" href="/bower_components/iron-dropdown/iron-dropdown.html">
+<link rel="import" href="/bower_components/paper-input/paper-input.html">
<link rel="import" href="../../../styles/shared-styles.html">
<dom-module id="gr-editable-label">
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label_test.html b/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label_test.html
index 6815173..5dad9a6 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label_test.html
@@ -18,11 +18,13 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-editable-label</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
-<script src="../../../bower_components/iron-test-helpers/mock-interactions.js"></script>
+<script src="/bower_components/iron-test-helpers/mock-interactions.js"></script>
<link rel="import" href="gr-editable-label.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-fixed-panel/gr-fixed-panel.html b/polygerrit-ui/app/elements/shared/gr-fixed-panel/gr-fixed-panel.html
index 674ff97..47acd0c 100644
--- a/polygerrit-ui/app/elements/shared/gr-fixed-panel/gr-fixed-panel.html
+++ b/polygerrit-ui/app/elements/shared/gr-fixed-panel/gr-fixed-panel.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<dom-module id="gr-fixed-panel">
diff --git a/polygerrit-ui/app/elements/shared/gr-fixed-panel/gr-fixed-panel_test.html b/polygerrit-ui/app/elements/shared/gr-fixed-panel/gr-fixed-panel_test.html
index 9eac7f7..75e9901 100644
--- a/polygerrit-ui/app/elements/shared/gr-fixed-panel/gr-fixed-panel_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-fixed-panel/gr-fixed-panel_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-fixed-panel</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-fixed-panel.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.html b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.html
index 3995595..b6ad1af 100644
--- a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.html
+++ b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../gr-linked-text/gr-linked-text.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.html b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.html
index ad036c5..801190a 100644
--- a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-editable-label</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-formatted-text.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard.html b/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard.html
index 7e3246f..bb6fbb5 100644
--- a/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard.html
+++ b/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
@@ -46,4 +46,4 @@
</template>
<script src="../../../scripts/rootElement.js"></script>
<script src="gr-hovercard.js"></script>
-</dom-module>
\ No newline at end of file
+</dom-module>
diff --git a/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard_test.html b/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard_test.html
index e3e252f..aa13407 100644
--- a/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard_test.html
@@ -18,11 +18,13 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-hovercard</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
-<script src="../../../bower_components/iron-test-helpers/mock-interactions.js"></script>
+<script src="/bower_components/iron-test-helpers/mock-interactions.js"></script>
<link rel="import" href="gr-hovercard.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-icons/gr-icons.html b/polygerrit-ui/app/elements/shared/gr-icons/gr-icons.html
index 1f885af..7bd6f48 100644
--- a/polygerrit-ui/app/elements/shared/gr-icons/gr-icons.html
+++ b/polygerrit-ui/app/elements/shared/gr-icons/gr-icons.html
@@ -14,8 +14,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/iron-icon/iron-icon.html">
-<link rel="import" href="../../../bower_components/iron-iconset-svg/iron-iconset-svg.html">
+<link rel="import" href="/bower_components/iron-icon/iron-icon.html">
+<link rel="import" href="/bower_components/iron-iconset-svg/iron-iconset-svg.html">
<iron-iconset-svg name="gr-icons" size="24">
<svg>
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-context_test.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-context_test.html
index 03c8c5e..653999c 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-context_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-context_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-annotation-actions-context</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<script src="../../diff/gr-diff-highlight/gr-annotation.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-js-api_test.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-js-api_test.html
index bf7c2cb..78f9650 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-js-api_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-js-api_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-annotation-actions-js-api-js-api</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="../../change/gr-change-actions/gr-change-actions.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-actions-js-api_test.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-actions-js-api_test.html
index fef4fc9..30bd366 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-actions-js-api_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-actions-js-api_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-change-actions-js-api</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<!--
This must refer to the element this interface is wrapping around. Otherwise
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-reply-js-api_test.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-reply-js-api_test.html
index 278f95a..842a2fe 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-reply-js-api_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-reply-js-api_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-change-reply-js-api</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<!--
This must refer to the element this interface is wrapping around. Otherwise
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.html
index d8a662e..e04867a 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.html
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
<link rel="import" href="../../core/gr-reporting/gr-reporting.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html
index 113a6f7..055fc3fcb 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-api-interface</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-js-api-interface.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-action-context_test.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-action-context_test.html
index ca87956..cff1a4e 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-action-context_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-action-context_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-plugin-action-context</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-js-api-interface.html"/>
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-endpoints_test.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-endpoints_test.html
index b00b5ac..8ed7f14 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-endpoints_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-endpoints_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-plugin-endpoints</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-js-api-interface.html"/>
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api_test.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api_test.html
index 5983621..8626280 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-plugin-rest-api</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-js-api-interface.html"/>
diff --git a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info.html b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info.html
index ca5c49f..e3cf34b 100644
--- a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info.html
+++ b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/gr-voting-styles.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.html b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.html
index 8bc358d..96d9fd7 100644
--- a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.html
@@ -17,9 +17,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-label-info</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-label-info.html">
@@ -227,4 +229,4 @@
assert.isTrue(isHidden(element.$$('.placeholder')));
});
});
-</script>
\ No newline at end of file
+</script>
diff --git a/polygerrit-ui/app/elements/shared/gr-label/gr-label.html b/polygerrit-ui/app/elements/shared/gr-label/gr-label.html
index fe290b7..55ecc98 100644
--- a/polygerrit-ui/app/elements/shared/gr-label/gr-label.html
+++ b/polygerrit-ui/app/elements/shared/gr-label/gr-label.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-tooltip-behavior/gr-tooltip-behavior.html">
<dom-module id="gr-label">
<template strip-whitespace>
diff --git a/polygerrit-ui/app/elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete.html b/polygerrit-ui/app/elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete.html
index c001ce7..986bce1 100644
--- a/polygerrit-ui/app/elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete.html
+++ b/polygerrit-ui/app/elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-autocomplete/gr-autocomplete.html">
<link rel="import" href="../../../styles/shared-styles.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete_test.html b/polygerrit-ui/app/elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete_test.html
index 6bcaa18..bcd060b 100644
--- a/polygerrit-ui/app/elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete_test.html
@@ -17,9 +17,11 @@
-->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-labeled-autocomplete</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-labeled-autocomplete.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-lib-loader/gr-lib-loader.html b/polygerrit-ui/app/elements/shared/gr-lib-loader/gr-lib-loader.html
index 4137485..fb55c67 100644
--- a/polygerrit-ui/app/elements/shared/gr-lib-loader/gr-lib-loader.html
+++ b/polygerrit-ui/app/elements/shared/gr-lib-loader/gr-lib-loader.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../shared/gr-js-api-interface/gr-js-api-interface.html">
<dom-module id="gr-lib-loader">
diff --git a/polygerrit-ui/app/elements/shared/gr-lib-loader/gr-lib-loader_test.html b/polygerrit-ui/app/elements/shared/gr-lib-loader/gr-lib-loader_test.html
index cf9a41c..10d1608 100644
--- a/polygerrit-ui/app/elements/shared/gr-lib-loader/gr-lib-loader_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-lib-loader/gr-lib-loader_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-lib-loader</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-lib-loader.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-limited-text/gr-limited-text.html b/polygerrit-ui/app/elements/shared/gr-limited-text/gr-limited-text.html
index 91866e5..d00416b 100644
--- a/polygerrit-ui/app/elements/shared/gr-limited-text/gr-limited-text.html
+++ b/polygerrit-ui/app/elements/shared/gr-limited-text/gr-limited-text.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-tooltip-behavior/gr-tooltip-behavior.html">
<dom-module id="gr-limited-text">
diff --git a/polygerrit-ui/app/elements/shared/gr-limited-text/gr-limited-text_test.html b/polygerrit-ui/app/elements/shared/gr-limited-text/gr-limited-text_test.html
index 16eb960..b07971b 100644
--- a/polygerrit-ui/app/elements/shared/gr-limited-text/gr-limited-text_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-limited-text/gr-limited-text_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-limited-text</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-limited-text.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip.html b/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip.html
index fab562a..a3dd054 100644
--- a/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip.html
+++ b/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-tooltip-behavior/gr-tooltip-behavior.html">
<link rel="import" href="../gr-button/gr-button.html">
<link rel="import" href="../gr-icons/gr-icons.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip_test.html b/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip_test.html
index eb57428..22a2eaf 100644
--- a/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip_test.html
@@ -18,11 +18,13 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-linked-chip</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
-<script src="../../../bower_components/iron-test-helpers/mock-interactions.js"></script>
+<script src="/bower_components/iron-test-helpers/mock-interactions.js"></script>
<link rel="import" href="gr-linked-chip.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text.html b/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text.html
index c35768f..5697e77 100644
--- a/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text.html
+++ b/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text.html
@@ -15,11 +15,11 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../core/gr-navigation/gr-navigation.html">
<link rel="import" href="../../../styles/shared-styles.html">
-<script src="../../../bower_components/ba-linkify/ba-linkify.js"></script>
+<script src="/bower_components/ba-linkify/ba-linkify.js"></script>
<script src="link-text-parser.js"></script>
<dom-module id="gr-linked-text">
<template>
diff --git a/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text_test.html b/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text_test.html
index 23c1442..73295b1 100644
--- a/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-linked-text</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="../../../scripts/util.js"></script>
diff --git a/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view.html b/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view.html
index be02d40..1ee168d 100644
--- a/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view.html
+++ b/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view_test.html b/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view_test.html
index 09e68dd..c67d8b2 100644
--- a/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-list-view</title>
-<script src="../../../bower_components/page/page.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
+<script src="/bower_components/page/page.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-list-view.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay.html b/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay.html
index e94b655..82c1169 100644
--- a/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay.html
+++ b/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay.html
@@ -15,8 +15,8 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-overlay-behavior/iron-overlay-behavior.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-overlay-behavior/iron-overlay-behavior.html">
<link rel="import" href="../../../styles/shared-styles.html">
<dom-module id="gr-overlay">
diff --git a/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay_test.html b/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay_test.html
index ee05b69..08b7497 100644
--- a/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay_test.html
@@ -18,10 +18,12 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-overlay</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/page/page.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/page/page.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
diff --git a/polygerrit-ui/app/elements/shared/gr-page-nav/gr-page-nav.html b/polygerrit-ui/app/elements/shared/gr-page-nav/gr-page-nav.html
index 3885497..f1c3a6f 100644
--- a/polygerrit-ui/app/elements/shared/gr-page-nav/gr-page-nav.html
+++ b/polygerrit-ui/app/elements/shared/gr-page-nav/gr-page-nav.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
<link rel="import" href="../../../behaviors/gr-tooltip-behavior/gr-tooltip-behavior.html">
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<dom-module id="gr-page-nav">
diff --git a/polygerrit-ui/app/elements/shared/gr-page-nav/gr-page-nav_test.html b/polygerrit-ui/app/elements/shared/gr-page-nav/gr-page-nav_test.html
index 428bab3..b384b47 100644
--- a/polygerrit-ui/app/elements/shared/gr-page-nav/gr-page-nav_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-page-nav/gr-page-nav_test.html
@@ -18,10 +18,12 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-page-nav</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/page/page.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/page/page.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
diff --git a/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker.html b/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker.html
index d794dd6..416815b 100644
--- a/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker.html
+++ b/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker.html
@@ -14,8 +14,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
-<link rel="import" href="../../../bower_components/iron-icon/iron-icon.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/iron-icon/iron-icon.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../../behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior.html">
<link rel="import" href="../../shared/gr-icons/gr-icons.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker_test.html b/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker_test.html
index 989e838..1ed9151 100644
--- a/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker_test.html
@@ -17,9 +17,11 @@
-->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-repo-branch-picker</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-repo-branch-picker.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-auth_test.html b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-auth_test.html
index a571be9..cfdc6ee 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-auth_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-auth_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-auth</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator.html b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator.html
index c5a0dfe..d3500d8 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator.html
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<dom-module id="gr-etag-decorator">
<script src="gr-etag-decorator.js"></script>
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator_test.html b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator_test.html
index 09ae1da..76c8c2c 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-etag-decorator</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="gr-etag-decorator.js"></script>
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.html b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.html
index 562980c..607802f 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.html
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/base-url-behavior/base-url-behavior.html">
<link rel="import" href="../../../behaviors/gr-patch-set-behavior/gr-patch-set-behavior.html">
<link rel="import" href="../../../behaviors/gr-path-list-behavior/gr-path-list-behavior.html">
@@ -23,8 +23,8 @@
<link rel="import" href="gr-etag-decorator.html">
<!-- NB: es6-promise Needed for IE11 and fetch polyfill support, see Issue 4308 -->
-<script src="../../../bower_components/es6-promise/dist/es6-promise.min.js"></script>
-<script src="../../../bower_components/fetch/fetch.js"></script>
+<script src="/bower_components/es6-promise/dist/es6-promise.min.js"></script>
+<script src="/bower_components/fetch/fetch.js"></script>
<dom-module id="gr-rest-api-interface">
<!-- NB: Order is important, because of namespaced classes. -->
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
index e69c8fc..dc671b1 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
@@ -144,6 +144,14 @@
constructor() {
// Container of per-canonical-path caches.
this._data = new Map();
+ if (window.INITIAL_DATA != undefined) {
+ // Put all data shipped with index.html into the cache. This makes it
+ // so that we spare more round trips to the server when the app loads
+ // initially.
+ Object
+ .entries(window.INITIAL_DATA)
+ .forEach(e => this._cache().set(e[0], e[1]));
+ }
}
// Returns the cache for the current canonical path.
@@ -2772,7 +2780,7 @@
},
getTopMenus(opt_errFn) {
- return this._fetchJSON({
+ return this._fetchSharedCacheURL({
url: '/config/server/top-menus',
errFn: opt_errFn,
reportUrlAsIs: true,
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.html b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.html
index ef4e401..d00e00d 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-rest-api-interface</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="../../../scripts/util.js"></script>
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser_test.html b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser_test.html
index 202c52a..fdf79af 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-reviewer-updates-parser</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<script src="../../../scripts/util.js"></script>
<script src="gr-reviewer-updates-parser.js"></script>
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/mock-diff-response_test.html b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/mock-diff-response_test.html
index 05c2cee..9a24ddc 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/mock-diff-response_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/mock-diff-response_test.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../test/common-test-setup.html"/>
<dom-module id="mock-diff-response">
<template></template>
diff --git a/polygerrit-ui/app/elements/shared/gr-select/gr-select.html b/polygerrit-ui/app/elements/shared/gr-select/gr-select.html
index e73d41c..02afb38 100644
--- a/polygerrit-ui/app/elements/shared/gr-select/gr-select.html
+++ b/polygerrit-ui/app/elements/shared/gr-select/gr-select.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<dom-module id="gr-select">
<slot></slot>
<script src="gr-select.js"></script>
diff --git a/polygerrit-ui/app/elements/shared/gr-select/gr-select_test.html b/polygerrit-ui/app/elements/shared/gr-select/gr-select_test.html
index 1748ec06..66ebb79 100644
--- a/polygerrit-ui/app/elements/shared/gr-select/gr-select_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-select/gr-select_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-select</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-select.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command.html b/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command.html
index fe6ed88..dbbf98b 100644
--- a/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command.html
+++ b/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<link rel="import" href="../../shared/gr-copy-clipboard/gr-copy-clipboard.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_test.html b/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_test.html
index a49f76f..3f2f8ba 100644
--- a/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-shell-command</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-shell-command.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-storage/gr-storage.html b/polygerrit-ui/app/elements/shared/gr-storage/gr-storage.html
index 6fc2f3f..7215b26 100644
--- a/polygerrit-ui/app/elements/shared/gr-storage/gr-storage.html
+++ b/polygerrit-ui/app/elements/shared/gr-storage/gr-storage.html
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<dom-module id="gr-storage">
<script src="gr-storage.js"></script>
</dom-module>
diff --git a/polygerrit-ui/app/elements/shared/gr-storage/gr-storage_test.html b/polygerrit-ui/app/elements/shared/gr-storage/gr-storage_test.html
index 6b89af2..0482584 100644
--- a/polygerrit-ui/app/elements/shared/gr-storage/gr-storage_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-storage/gr-storage_test.html
@@ -17,9 +17,11 @@
-->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-storage</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-storage.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea.html b/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea.html
index 10c9111..fc532af 100644
--- a/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea.html
+++ b/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea.html
@@ -14,14 +14,14 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.html">
<link rel="import" href="../../shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown.html">
<link rel="import" href="../../shared/gr-cursor-manager/gr-cursor-manager.html">
<link rel="import" href="../../shared/gr-overlay/gr-overlay.html">
-<link rel="import" href="../../../bower_components/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
-<link rel="import" href="../../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
+<link rel="import" href="/bower_components/iron-a11y-keys-behavior/iron-a11y-keys-behavior.html">
+<link rel="import" href="/bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
<link rel="import" href="../../../styles/shared-styles.html">
<dom-module id="gr-textarea">
diff --git a/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea_test.html b/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea_test.html
index 3a52543..8b6eff2 100644
--- a/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-textarea</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-textarea.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content.html b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content.html
index 65f1fda..b4fefe1 100644
--- a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content.html
+++ b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../behaviors/gr-tooltip-behavior/gr-tooltip-behavior.html">
<dom-module id="gr-tooltip-content">
diff --git a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.html b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.html
index 438d436..f9350c6 100644
--- a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.html
@@ -17,9 +17,11 @@
-->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-storage</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-tooltip-content.html">
diff --git a/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip.html b/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip.html
index 9947d61..36378f6 100644
--- a/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip.html
+++ b/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip.html
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<link rel="import" href="../../../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../../../styles/shared-styles.html">
<dom-module id="gr-tooltip">
diff --git a/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_test.html b/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_test.html
index 3a47288..f59f6e1 100644
--- a/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_test.html
@@ -17,9 +17,11 @@
-->
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>gr-storage</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="gr-tooltip.html">
diff --git a/polygerrit-ui/app/elements/shared/revision-info/revision-info_test.html b/polygerrit-ui/app/elements/shared/revision-info/revision-info_test.html
index 433872d..7e5810b 100644
--- a/polygerrit-ui/app/elements/shared/revision-info/revision-info_test.html
+++ b/polygerrit-ui/app/elements/shared/revision-info/revision-info_test.html
@@ -18,9 +18,11 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>revision-info</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../../../test/common-test-setup.html"/>
<link rel="import" href="revision-info.html">
diff --git a/polygerrit-ui/app/embed/embed.html b/polygerrit-ui/app/embed/embed.html
index 1b2f20f..783589d 100644
--- a/polygerrit-ui/app/embed/embed.html
+++ b/polygerrit-ui/app/embed/embed.html
@@ -20,7 +20,7 @@
let Gerrit = window.Gerrit || {};
window.Gerrit = Gerrit;
</script>
-<link rel="import" href="../bower_components/polymer/polymer.html">
+<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="../elements/change/gr-change-view/gr-change-view.html">
<link rel="import" href="../elements/core/gr-search-bar/gr-search-bar.html">
<link rel="import" href="../elements/diff/gr-diff-view/gr-diff-view.html">
diff --git a/polygerrit-ui/app/embed/embed_test.html b/polygerrit-ui/app/embed/embed_test.html
index 7ca75c9..1e3f5d7 100644
--- a/polygerrit-ui/app/embed/embed_test.html
+++ b/polygerrit-ui/app/embed/embed_test.html
@@ -18,10 +18,12 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>embed_test</title>
+<script src="/test/common-test-setup.js"></script>
+<script src="/bower_components/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="../../../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../../../bower_components/web-component-tester/browser.js"></script>
-<link rel="import" href="../polygerrit_ui/elements/embed.html"/>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
+<link rel="import" href="embed.html"/>
<script>void(0);</script>
diff --git a/polygerrit-ui/app/embed/test.html b/polygerrit-ui/app/embed/test.html
index eed2fef..955eaee 100644
--- a/polygerrit-ui/app/embed/test.html
+++ b/polygerrit-ui/app/embed/test.html
@@ -19,8 +19,8 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>Embed Test Runner</title>
<meta charset="utf-8">
-<script src="../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<script>
- WCT.loadSuites(['embed_test.html']);
+ WCT.loadSuites(['../embed/embed_test.html']);
</script>
diff --git a/polygerrit-ui/app/embed_test.sh b/polygerrit-ui/app/embed_test.sh
index bb08bb0..0d8f58f 100755
--- a/polygerrit-ui/app/embed_test.sh
+++ b/polygerrit-ui/app/embed_test.sh
@@ -4,15 +4,15 @@
t=$(mktemp -d || mktemp -d -t wct-XXXXXXXXXX)
components=$TEST_SRCDIR/gerrit/polygerrit-ui/app/test_components.zip
-code=$TEST_SRCDIR/gerrit/polygerrit-ui/app/polygerrit_embed_ui.zip
-index=$TEST_SRCDIR/gerrit/polygerrit-ui/app/embed/test.html
-tests=$TEST_SRCDIR/gerrit/polygerrit-ui/app/embed/*_test.html
+code=$TEST_SRCDIR/gerrit/polygerrit-ui/app/pg_code.zip
+echo $t
unzip -qd $t $components
unzip -qd $t $code
+# Purge test/ directory contents coming from pg_code.zip.
+rm -rf $t/test
mkdir -p $t/test
-cp $index $t/test/
-cp $tests $t/test/
+cp $TEST_SRCDIR/gerrit/polygerrit-ui/app/embed/test.html $t/test/
if [ "${WCT_HEADLESS_MODE:-0}" != "0" ]; then
CHROME_OPTIONS=[\'start-maximized\',\'headless\',\'disable-gpu\',\'no-sandbox\']
@@ -61,9 +61,9 @@
};
EOF
-export PATH="$(dirname $WCT):$(dirname $NPM):$PATH"
+export PATH="$(dirname $NPM):$PATH"
cd $t
test -n "${WCT}"
-$(basename ${WCT}) ${WCT_ARGS}
+${WCT} ${WCT_ARGS}
diff --git a/polygerrit-ui/app/run_template_test.sh b/polygerrit-ui/app/run_template_test.sh
index 4cd6e7f..d2b6989 100755
--- a/polygerrit-ui/app/run_template_test.sh
+++ b/polygerrit-ui/app/run_template_test.sh
@@ -3,7 +3,7 @@
if [[ -z "${TEMPLATE_NO_DEFAULT}" ]]; then
bazel test \
--test_env="HOME=$HOME" \
- //polygerrit-ui/app:all
+ //polygerrit-ui/app:all \
--test_tag_filters=template \
"$@" \
--test_output errors \
diff --git a/polygerrit-ui/app/run_test.sh b/polygerrit-ui/app/run_test.sh
index df210b8..3d92e11 100755
--- a/polygerrit-ui/app/run_test.sh
+++ b/polygerrit-ui/app/run_test.sh
@@ -6,9 +6,29 @@
exit 1
fi
+# From https://www.linuxquestions.org/questions/programming-9/bash-script-return-full-path-and-filename-680368/page3.html
+function abs_path {
+ if [[ -d "$1" ]]
+ then
+ pushd "$1" >/dev/null
+ pwd
+ popd >/dev/null
+ elif [[ -e $1 ]]
+ then
+ pushd "$(dirname "$1")" >/dev/null
+ echo "$(pwd)/$(basename "$1")"
+ popd >/dev/null
+ else
+ echo "$1" does not exist! >&2
+ return 127
+ fi
+}
wct_bin=$(which wct)
if [[ -z "$wct_bin" ]]; then
- echo "WCT must be on the path. (https://github.com/Polymer/web-component-tester)"
+ wct_bin=$(abs_path ./node_modules/web-component-tester/bin/wct);
+fi
+if [[ -z "$wct_bin" ]]; then
+ echo "wct_bin must be set or WCT locally installed (npm install wct)."
exit 1
fi
diff --git a/polygerrit-ui/app/styles/themes/app-theme.html b/polygerrit-ui/app/styles/themes/app-theme.html
index a4a2ca4..e3f9d90 100644
--- a/polygerrit-ui/app/styles/themes/app-theme.html
+++ b/polygerrit-ui/app/styles/themes/app-theme.html
@@ -89,7 +89,8 @@
--dark-add-highlight-color: #AAF2AA;
--dark-rebased-remove-highlight-color: #F7E8B7;
--dark-rebased-add-highlight-color: #D7D7F9;
- --diff-context-control-color: #fff7d4;
+ --diff-context-control-color: var(--deemphasized-text-color);
+ --diff-context-control-background-color: #fff7d4;
--diff-context-control-border-color: #f6e6a5;
--diff-tab-indicator-color: var(--deemphasized-text-color);
--diff-trailing-whitespace-indicator: #ff9ad2;
diff --git a/polygerrit-ui/app/styles/themes/dark-theme.html b/polygerrit-ui/app/styles/themes/dark-theme.html
index d5db416..0c51da3 100644
--- a/polygerrit-ui/app/styles/themes/dark-theme.html
+++ b/polygerrit-ui/app/styles/themes/dark-theme.html
@@ -36,7 +36,8 @@
--dark-add-highlight-color: rgba(0, 255, 0, 0.15);
--dark-rebased-remove-highlight-color: rgba(255, 139, 6, 0.15);
--dark-rebased-add-highlight-color: rgba(11, 255, 155, 0.15);
- --diff-context-control-color: var(--table-header-background-color);
+ --diff-context-control-color: var(--deemphasized-text-color);
+ --diff-context-control-background-color: var(--table-header-background-color);
--diff-context-control-border-color: var(--border-color);
--diff-highlight-range-color: rgba(0, 100, 200, 0.5);
--diff-highlight-range-hover-color: rgba(0, 150, 255, 0.5);
diff --git a/polygerrit-ui/app/template_test.sh b/polygerrit-ui/app/template_test.sh
index 7177e8a..b1a2380 100755
--- a/polygerrit-ui/app/template_test.sh
+++ b/polygerrit-ui/app/template_test.sh
@@ -14,19 +14,6 @@
exit 1
fi
-fried_twinkie_config=$(npm list -g | grep -c fried-twinkie)
-if [ -z "$npm_bin" ] || [ "$fried_twinkie_config" -eq "0" ]; then
- echo "You must install fried twinkie and its dependencies from NPM."
- echo "> npm install -g fried-twinkie"
- exit 1
-fi
-
-twinkie_version=$(npm list -g fried-twinkie@\>0.1 | grep fried-twinkie || :)
-if [ -z "$twinkie_version" ]; then
- echo "Outdated version of fried-twinkie found. Bypassing template check."
- exit 0
-fi
-
# Have to find where node_modules are installed and set the NODE_PATH
get_node_path() {
diff --git a/polygerrit-ui/app/test/common-test-setup.html b/polygerrit-ui/app/test/common-test-setup.html
index c5979fa..696f6a5 100644
--- a/polygerrit-ui/app/test/common-test-setup.html
+++ b/polygerrit-ui/app/test/common-test-setup.html
@@ -17,7 +17,8 @@
-->
<link rel="import"
- href="../bower_components/polymer-resin/standalone/polymer-resin.html" />
+ href="/bower_components/polymer-resin/standalone/polymer-resin.html" />
+<link rel="import" href="../behaviors/safe-types-behavior/safe-types-behavior.html">
<script>
security.polymer_resin.install({
allowedIdentifierPrefixes: [''],
@@ -32,6 +33,7 @@
+ JSON.stringify(args));
}
},
+ safeTypesBridge: Gerrit.SafeTypes.safeTypesBridge,
});
</script>
<script>
@@ -58,6 +60,6 @@
})();
</script>
<link rel="import"
- href="../bower_components/iron-test-helpers/iron-test-helpers.html" />
+ href="/bower_components/iron-test-helpers/iron-test-helpers.html" />
<link rel="import" href="test-router.html" />
-<script src="../bower_components/moment/moment.js"></script>
+<script src="/bower_components/moment/moment.js"></script>
diff --git a/polygerrit-ui/app/test/common-test-setup.js b/polygerrit-ui/app/test/common-test-setup.js
new file mode 100644
index 0000000..7be4f04
--- /dev/null
+++ b/polygerrit-ui/app/test/common-test-setup.js
@@ -0,0 +1,18 @@
+/**
+ * @license
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Intentionally blank - will contain shared Polymer 2 test setup code.
diff --git a/polygerrit-ui/app/test/index.html b/polygerrit-ui/app/test/index.html
index bc705a8..9448662 100644
--- a/polygerrit-ui/app/test/index.html
+++ b/polygerrit-ui/app/test/index.html
@@ -19,8 +19,8 @@
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>Elements Test Runner</title>
<meta charset="utf-8">
-<script src="../bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
-<script src="../bower_components/web-component-tester/browser.js"></script>
+<script src="/bower_components/webcomponentsjs/webcomponents-lite.js"></script>
+<script src="/bower_components/web-component-tester/browser.js"></script>
<script>
const testFiles = [];
const elementsPath = '../elements/';
diff --git a/polygerrit-ui/app/wct_test.sh b/polygerrit-ui/app/wct_test.sh
index 81dc109..f1b4666 100755
--- a/polygerrit-ui/app/wct_test.sh
+++ b/polygerrit-ui/app/wct_test.sh
@@ -59,9 +59,9 @@
};
EOF
-export PATH="$(dirname $WCT):$(dirname $NPM):$PATH"
+export PATH="$(dirname $NPM):$PATH"
cd $t
test -n "${WCT}"
-$(basename ${WCT}) ${WCT_ARGS}
+${WCT} ${WCT_ARGS}
diff --git a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
index 85f338c..693604f 100644
--- a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
+++ b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
@@ -19,11 +19,11 @@
{template .Index}
{@param canonicalPath: ?}
{@param staticResourcePath: ?}
+ {@param gerritInitialData: /** {string} map of REST endpoint to response for startup. */ ?}
{@param? assetsPath: ?} /** {string} URL to static assets root, if served from CDN. */
{@param? assetsBundle: ?} /** {string} Assets bundle .html file, served from $assetsPath. */
{@param? faviconPath: ?}
{@param? versionInfo: ?}
- {@param? deprecateGwtUi: ?}
{@param? polymer2: ?}
<!DOCTYPE html>{\n}
<html lang="en">{\n}
@@ -39,11 +39,21 @@
<script>
window.CLOSURE_NO_DEPS = true;
{if $canonicalPath != ''}window.CANONICAL_PATH = '{$canonicalPath}';{/if}
- {if $deprecateGwtUi}window.DEPRECATE_GWT_UI = true;{/if}
{if $versionInfo}window.VERSION_INFO = '{$versionInfo}';{/if}
{if $staticResourcePath != ''}window.STATIC_RESOURCE_PATH = '{$staticResourcePath}';{/if}
{if $assetsPath}window.ASSETS_PATH = '{$assetsPath}';{/if}
{if $polymer2}window.POLYMER2 = true;{/if}
+ {if $gerritInitialData}
+ // INITIAL_DATA is a string that represents a JSON map. It's inlined here so that we can
+ // spare calls to the API when starting up the app.
+ // The map maps from endpoint to returned value. This matches Gerrit's REST API 1:1, so the
+ // values here can be used as a drop-in replacement for calls to the API.
+ //
+ // Example:
+ // '/config/server/version' => '3.0.0-468-g0757b52a7d'
+ // '/accounts/self/detail' => { 'username' : 'gerrit-user' }
+ window.INITIAL_DATA = JSON.parse({$gerritInitialData});
+ {/if}
</script>{\n}
{if $faviconPath}
diff --git a/resources/com/google/gerrit/server/mail/DeleteKey.soy b/resources/com/google/gerrit/server/mail/DeleteKey.soy
new file mode 100644
index 0000000..30548c8
--- /dev/null
+++ b/resources/com/google/gerrit/server/mail/DeleteKey.soy
@@ -0,0 +1,72 @@
+/**
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+{namespace com.google.gerrit.server.mail.template}
+
+/**
+ * The .DeleteKey template will determine the contents of the email related to
+ * deleting a SSH or GPG key.
+ */
+{template .DeleteKey kind="text"}
+ {@param email: ?}
+ One or more {$email.keyType} keys have been deleted on Gerrit Code Review at
+ {sp}{$email.gerritHost}:
+
+ {\n}
+ {\n}
+
+ {if $email.sshKey}
+ {$email.sshKey}
+ {elseif $email.gpgKeyFingerprints}
+ {$email.gpgKeyFingerprints}
+ {/if}
+
+ {\n}
+ {\n}
+
+
+ If this is not expected, please contact your Gerrit Administrators
+ immediately.
+
+ {\n}
+ {\n}
+
+ You can also manage your {$email.keyType} keys by visiting
+ {\n}
+ {if $email.sshKey}
+ {$email.gerritUrl}#/settings/ssh-keys
+ {elseif $email.gpgKey}
+ {$email.gerritUrl}#/settings/gpg-keys
+ {/if}
+ {\n}
+ {if $email.userNameEmail}
+ (while signed in as {$email.userNameEmail})
+ {else}
+ (while signed in as {$email.email})
+ {/if}
+
+ {\n}
+ {\n}
+
+ If clicking the link above does not work, copy and paste the URL in a new
+ browser window instead.
+
+ {\n}
+ {\n}
+
+ This is a send-only email address. Replies to this message will not be read
+ or answered.
+{/template}
diff --git a/resources/com/google/gerrit/server/mail/DeleteKeyHtml.soy b/resources/com/google/gerrit/server/mail/DeleteKeyHtml.soy
new file mode 100644
index 0000000..1ab3955
--- /dev/null
+++ b/resources/com/google/gerrit/server/mail/DeleteKeyHtml.soy
@@ -0,0 +1,64 @@
+/**
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+{namespace com.google.gerrit.server.mail.template}
+
+{template .DeleteKeyHtml}
+ {@param email: ?}
+ <p>
+ One or more {$email.keyType} keys have been deleted on Gerrit Code Review
+ at {$email.gerritHost}:
+ </p>
+
+ {let $keyStyle kind="css"}
+ background: #f0f0f0;
+ border: 1px solid #ccc;
+ color: #555;
+ padding: 12px;
+ width: 400px;
+ {/let}
+
+ {if $email.sshKey}
+ <pre style="{$keyStyle}">{$email.sshKey}</pre>
+ {elseif $email.gpgKeyFingerprints}
+ <pre style="{$keyStyle}">{$email.gpgKeyFingerprints}</pre>
+ {/if}
+
+ <p>
+ If this is not expected, please contact your Gerrit Administrators
+ immediately.
+ </p>
+
+ <p>
+ You can also manage your {$email.keyType} keys by following{sp}
+ {if $email.sshKey}
+ <a href="{$email.gerritUrl}#/settings/ssh-keys">this link</a>
+ {elseif $email.gpgKeyFingerprints}
+ <a href="{$email.gerritUrl}#/settings/gpg-keys">this link</a>
+ {/if}
+ {sp}
+ {if $email.userNameEmail}
+ (while signed in as {$email.userNameEmail})
+ {else}
+ (while signed in as {$email.email})
+ {/if}.
+ </p>
+
+ <p>
+ This is a send-only email address. Replies to this message will not be read
+ or answered.
+ </p>
+{/template}
diff --git a/resources/com/google/gerrit/server/mail/HttpPasswordUpdate.soy b/resources/com/google/gerrit/server/mail/HttpPasswordUpdate.soy
new file mode 100644
index 0000000..38e679e
--- /dev/null
+++ b/resources/com/google/gerrit/server/mail/HttpPasswordUpdate.soy
@@ -0,0 +1,55 @@
+/**
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+{namespace com.google.gerrit.server.mail.template}
+
+/**
+ * The .HttpPasswordUpdate template will determine the contents of the email related to
+ * adding, changing or deleting the HTTP password.
+ */
+{template .HttpPasswordUpdate kind="text"}
+ {@param email: ?}
+ The HTTP password was {$email.operation} on Gerrit Code Review at
+ {sp}{$email.gerritHost}.
+
+ If this is not expected, please contact your Gerrit Administrators
+ immediately.
+
+ {\n}
+ {\n}
+
+ You can also manage your HTTP password by visiting
+ {\n}
+ {$email.gerritUrl}#/settings/http-password
+ {\n}
+ {if $email.userNameEmail}
+ (while signed in as {$email.userNameEmail})
+ {else}
+ (while signed in as {$email.email})
+ {/if}
+
+ {\n}
+ {\n}
+
+ If clicking the link above does not work, copy and paste the URL in a new
+ browser window instead.
+
+ {\n}
+ {\n}
+
+ This is a send-only email address. Replies to this message will not be read
+ or answered.
+{/template}
diff --git a/resources/com/google/gerrit/server/mail/HttpPasswordUpdateHtml.soy b/resources/com/google/gerrit/server/mail/HttpPasswordUpdateHtml.soy
new file mode 100644
index 0000000..3c4594c
--- /dev/null
+++ b/resources/com/google/gerrit/server/mail/HttpPasswordUpdateHtml.soy
@@ -0,0 +1,46 @@
+/**
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+{namespace com.google.gerrit.server.mail.template}
+
+{template .HttpPasswordUpdateHtml}
+ {@param email: ?}
+ <p>
+ The HTTP password was {$email.operation} on Gerrit Code Review
+ at {$email.gerritHost}.
+ </p>
+
+ <p>
+ If this is not expected, please contact your Gerrit Administrators
+ immediately.
+ </p>
+
+ <p>
+ You can also manage your HTTP password by following{sp}
+ <a href="{$email.gerritUrl}#/settings/http-password">this link</a>
+ {sp}
+ {if $email.userNameEmail}
+ (while signed in as {$email.userNameEmail})
+ {else}
+ (while signed in as {$email.email})
+ {/if}.
+ </p>
+
+ <p>
+ This is a send-only email address. Replies to this message will not be read
+ or answered.
+ </p>
+{/template}
diff --git a/tools/BUILD b/tools/BUILD
index 6266456..09adf16 100644
--- a/tools/BUILD
+++ b/tools/BUILD
@@ -23,70 +23,74 @@
visibility = ["//visibility:public"],
)
-# This EP warnings list is based on:
+# Error Prone errors enabled by default; see ../.bazelrc for how this is
+# enabled. This warnings list is originally based on:
# https://github.com/bazelbuild/BUILD_file_generator/blob/master/tools/bazel_defs/java.bzl
+# However, feel free to add any additional errors. Thus far they have all been pretty useful.
java_package_configuration(
name = "error_prone",
javacopts = [
"-XepDisableWarningsInGeneratedCode",
- "-Xep:MissingCasesInEnumSwitch:ERROR",
- "-Xep:ReferenceEquality:WARN",
- "-Xep:StringEquality:WARN",
- "-Xep:WildcardImport:WARN",
- "-Xep:AmbiguousMethodReference:WARN",
- "-Xep:BadAnnotationImplementation:WARN",
- "-Xep:BadComparable:WARN",
+ "-Xep:AmbiguousMethodReference:ERROR",
+ "-Xep:BadAnnotationImplementation:ERROR",
+ "-Xep:BadComparable:ERROR",
"-Xep:BoxedPrimitiveConstructor:ERROR",
- "-Xep:CannotMockFinalClass:WARN",
- "-Xep:ClassCanBeStatic:WARN",
- "-Xep:ClassNewInstance:WARN",
+ "-Xep:CannotMockFinalClass:ERROR",
+ "-Xep:ClassCanBeStatic:ERROR",
+ "-Xep:ClassNewInstance:ERROR",
"-Xep:DefaultCharset:ERROR",
- "-Xep:DoubleCheckedLocking:WARN",
- "-Xep:ElementsCountedInLoop:WARN",
- "-Xep:EqualsHashCode:WARN",
- "-Xep:EqualsIncompatibleType:WARN",
+ "-Xep:DoubleCheckedLocking:ERROR",
+ "-Xep:ElementsCountedInLoop:ERROR",
+ "-Xep:DoubleCheckedLocking:ERROR",
+ "-Xep:ElementsCountedInLoop:ERROR",
+ "-Xep:EqualsHashCode:ERROR",
+ "-Xep:EqualsIncompatibleType:ERROR",
"-Xep:ExpectedExceptionChecker:ERROR",
- "-Xep:Finally:WARN",
- "-Xep:FloatingPointLiteralPrecision:WARN",
- "-Xep:FragmentInjection:WARN",
- "-Xep:FragmentNotInstantiable:WARN",
- "-Xep:FunctionalInterfaceClash:WARN",
- "-Xep:FutureReturnValueIgnored:WARN",
- "-Xep:GetClassOnEnum:WARN",
- "-Xep:ImmutableAnnotationChecker:WARN",
- "-Xep:ImmutableEnumChecker:WARN",
- "-Xep:IncompatibleModifiers:WARN",
- "-Xep:InjectOnConstructorOfAbstractClass:WARN",
- "-Xep:InputStreamSlowMultibyteRead:WARN",
- "-Xep:IterableAndIterator:WARN",
- "-Xep:JUnit3FloatingPointComparisonWithoutDelta:WARN",
- "-Xep:JUnitAmbiguousTestClass:WARN",
- "-Xep:LiteralClassName:WARN",
- "-Xep:MissingFail:WARN",
- "-Xep:MissingOverride:WARN",
+ "-Xep:Finally:ERROR",
+ "-Xep:FloatingPointLiteralPrecision:ERROR",
+ "-Xep:FragmentInjection:ERROR",
+ "-Xep:FragmentNotInstantiable:ERROR",
+ "-Xep:FunctionalInterfaceClash:ERROR",
+ "-Xep:FutureReturnValueIgnored:ERROR",
+ "-Xep:GetClassOnEnum:ERROR",
+ "-Xep:ImmutableAnnotationChecker:ERROR",
+ "-Xep:ImmutableEnumChecker:ERROR",
+ "-Xep:IncompatibleModifiers:ERROR",
+ "-Xep:InjectOnConstructorOfAbstractClass:ERROR",
+ "-Xep:InputStreamSlowMultibyteRead:ERROR",
+ "-Xep:IterableAndIterator:ERROR",
+ "-Xep:JUnit3FloatingPointComparisonWithoutDelta:ERROR",
+ "-Xep:JUnitAmbiguousTestClass:ERROR",
+ "-Xep:LiteralClassName:ERROR",
+ "-Xep:MissingCasesInEnumSwitch:ERROR",
+ "-Xep:MissingFail:ERROR",
+ "-Xep:MissingOverride:ERROR",
"-Xep:MutableConstantField:ERROR",
- "-Xep:NarrowingCompoundAssignment:WARN",
- "-Xep:NonAtomicVolatileUpdate:WARN",
- "-Xep:NonOverridingEquals:WARN",
- "-Xep:NullableConstructor:WARN",
- "-Xep:NullablePrimitive:WARN",
- "-Xep:NullableVoid:WARN",
- "-Xep:OperatorPrecedence:WARN",
- "-Xep:OverridesGuiceInjectableMethod:WARN",
- "-Xep:PreconditionsInvalidPlaceholder:WARN",
- "-Xep:ProtoFieldPreconditionsCheckNotNull:WARN",
- "-Xep:ProtocolBufferOrdinal:WARN",
- "-Xep:RequiredModifiers:WARN",
- "-Xep:ShortCircuitBoolean:WARN",
- "-Xep:SimpleDateFormatConstant:WARN",
- "-Xep:StaticGuardedByInstance:WARN",
- "-Xep:SynchronizeOnNonFinalField:WARN",
- "-Xep:TruthConstantAsserts:WARN",
- "-Xep:TypeParameterShadowing:WARN",
- "-Xep:TypeParameterUnusedInFormals:WARN",
- "-Xep:URLEqualsHashCode:WARN",
- "-Xep:UnsynchronizedOverridesSynchronized:WARN",
- "-Xep:WaitNotInLoop:WARN",
+ "-Xep:NarrowingCompoundAssignment:ERROR",
+ "-Xep:NonAtomicVolatileUpdate:ERROR",
+ "-Xep:NonOverridingEquals:ERROR",
+ "-Xep:NullableConstructor:ERROR",
+ "-Xep:NullablePrimitive:ERROR",
+ "-Xep:NullableVoid:ERROR",
+ "-Xep:OperatorPrecedence:ERROR",
+ "-Xep:OverridesGuiceInjectableMethod:ERROR",
+ "-Xep:PreconditionsInvalidPlaceholder:ERROR",
+ "-Xep:ProtoFieldPreconditionsCheckNotNull:ERROR",
+ "-Xep:ProtocolBufferOrdinal:ERROR",
+ "-Xep:ReferenceEquality:ERROR",
+ "-Xep:RequiredModifiers:ERROR",
+ "-Xep:ShortCircuitBoolean:ERROR",
+ "-Xep:SimpleDateFormatConstant:ERROR",
+ "-Xep:StaticGuardedByInstance:ERROR",
+ "-Xep:StringEquality:ERROR",
+ "-Xep:SynchronizeOnNonFinalField:ERROR",
+ "-Xep:TruthConstantAsserts:ERROR",
+ "-Xep:TypeParameterShadowing:ERROR",
+ "-Xep:TypeParameterUnusedInFormals:ERROR",
+ "-Xep:URLEqualsHashCode:ERROR",
+ "-Xep:UnsynchronizedOverridesSynchronized:ERROR",
+ "-Xep:WaitNotInLoop:ERROR",
+ "-Xep:WildcardImport:ERROR",
],
packages = ["error_prone_packages"],
)
@@ -96,5 +100,16 @@
packages = [
"//java/...",
"//javatests/...",
+ "//plugins/codemirror-editor/...",
+ "//plugins/commit-message-length-validator/...",
+ "//plugins/delete-project/...",
+ "//plugins/download-commands/...",
+ "//plugins/gitiles/...",
+ "//plugins/hooks/...",
+ "//plugins/plugin-manager/...",
+ "//plugins/replication/...",
+ "//plugins/reviewnotes/...",
+ "//plugins/singleusergroup/...",
+ "//plugins/webhooks/...",
],
)
diff --git a/tools/bzl/js.bzl b/tools/bzl/js.bzl
index 83c13a3..a4080e5 100644
--- a/tools/bzl/js.bzl
+++ b/tools/bzl/js.bzl
@@ -304,7 +304,14 @@
else:
bundled = ctx.outputs.html
destdir = ctx.outputs.html.path + ".dir"
- zips = [z for d in ctx.attr.deps for z in d.transitive_zipfiles]
+ zips = [z for d in ctx.attr.deps for z in d.transitive_zipfiles.to_list()]
+
+ # We are splitting off the package dir from the app.path such that
+ # we can set the package dir as the root for the bundler, which means
+ # that absolute imports are interpreted relative to that root.
+ pkg_dir = ctx.attr.pkg.lstrip("/")
+ app_path = ctx.file.app.path
+ app_path = app_path[app_path.index(pkg_dir) + len(pkg_dir):]
hermetic_npm_binary = " ".join([
"python",
@@ -315,10 +322,11 @@
"--strip-comments",
"--out-file",
"$p/" + bundled.path,
- ctx.file.app.path,
+ "--root",
+ pkg_dir,
+ app_path,
])
- pkg_dir = ctx.attr.pkg.lstrip("/")
cmd = " && ".join([
# unpack dependencies.
"export PATH",
diff --git a/tools/bzl/junit.bzl b/tools/bzl/junit.bzl
index 5da5f05..7e5de3e 100644
--- a/tools/bzl/junit.bzl
+++ b/tools/bzl/junit.bzl
@@ -35,7 +35,7 @@
return -1
def _AsClassName(fname):
- fname = [x.path for x in fname.files][0]
+ fname = [x.path for x in fname.files.to_list()][0]
toks = fname[:-5].split("/")
findex = -1
for s in _PREFIXES:
diff --git a/tools/eclipse/project.py b/tools/eclipse/project.py
index 46aeb31..c9d0905 100755
--- a/tools/eclipse/project.py
+++ b/tools/eclipse/project.py
@@ -188,7 +188,8 @@
src.add(m.group(1))
# Exceptions: both source and lib
if p.endswith('libquery_parser.jar') or \
- p.endswith('libgerrit-prolog-common.jar'):
+ p.endswith('libgerrit-prolog-common.jar') or \
+ p.endswith('lucene-core-and-backward-codecs__merged.jar'):
lib.add(p)
# JGit dependency from external repository
if 'gerrit-' not in p and 'jgit' in p:
diff --git a/tools/remote-bazelrc b/tools/remote-bazelrc
new file mode 100644
index 0000000..b26a8e8
--- /dev/null
+++ b/tools/remote-bazelrc
@@ -0,0 +1,107 @@
+# Copyright 2016 The Bazel Authors. All rights reserved.
+#
+# 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.
+
+# This file is auto-generated from release/bazelrc.tpl and should not be
+# modified directly.
+
+# This .bazelrc file contains all of the flags required for the provided
+# toolchain with Remote Build Execution.
+#
+# This .bazelrc file also contains all of the flags required for the local
+# docker sandboxing.
+
+# Depending on how many machines are in the remote execution instance, setting
+# this higher can make builds faster by allowing more jobs to run in parallel.
+# Setting it too high can result in jobs that timeout, however, while waiting
+# for a remote machine to execute them.
+build:remote --jobs=50
+build:remote --disk_cache=
+
+# Set several flags related to specifying the platform, toolchain and java
+# properties.
+# These flags are duplicated rather than imported from (for example)
+# %workspace%/configs/ubuntu16_04_clang/1.2/toolchain.bazelrc to make this
+# bazelrc a standalone file that can be copied more easily.
+# These flags should only be used as is for the rbe-ubuntu16-04 container
+# and need to be adapted to work with other toolchain containers.
+build:remote --host_javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.2:jdk8
+build:remote --javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.2:jdk8
+build:remote --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_hostjdk8
+build:remote --java_toolchain=@bazel_tools//tools/jdk:toolchain_hostjdk8
+build:remote --crosstool_top=@bazel_toolchains//configs/ubuntu16_04_clang/1.2/bazel_0.25.0/default:toolchain
+build:remote --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1
+# Platform flags:
+# The toolchain container used for execution is defined in the target indicated
+# by "extra_execution_platforms", "host_platform" and "platforms".
+# If you are using your own toolchain container, you need to create a platform
+# target with "constraint_values" that allow for the toolchain specified with
+# "extra_toolchains" to be selected (given constraints defined in
+# "exec_compatible_with").
+# More about platforms: https://docs.bazel.build/versions/master/platforms.html
+build:remote --extra_toolchains=@bazel_toolchains//configs/ubuntu16_04_clang/1.2/bazel_0.25.0/cpp:cc-toolchain-clang-x86_64-default
+build:remote --extra_execution_platforms=@bazel_toolchains//configs/ubuntu16_04_clang/1.2:rbe_ubuntu1604
+build:remote --host_platform=@bazel_toolchains//configs/ubuntu16_04_clang/1.2:rbe_ubuntu1604
+build:remote --platforms=@bazel_toolchains//configs/ubuntu16_04_clang/1.2:rbe_ubuntu1604
+
+# Set various strategies so that all actions execute remotely. Mixing remote
+# and local execution will lead to errors unless the toolchain and remote
+# machine exactly match the host machine.
+build:remote --spawn_strategy=remote
+build:remote --strategy=Javac=remote
+build:remote --strategy=Closure=remote
+build:remote --strategy=Genrule=remote
+build:remote --define=EXECUTOR=remote
+
+# Enable the remote cache so action results can be shared across machines,
+# developers, and workspaces.
+build:remote --remote_cache=remotebuildexecution.googleapis.com
+
+# Enable remote execution so actions are performed on the remote systems.
+build:remote --remote_executor=remotebuildexecution.googleapis.com
+
+# Enable encryption.
+build:remote --tls_enabled=true
+
+# Set a higher timeout value, just in case.
+build:remote --remote_timeout=3600
+
+# Enable authentication. This will pick up application default credentials by
+# default. You can use --auth_credentials=some_file.json to use a service
+# account credential instead.
+build:remote --auth_enabled=true
+
+# The following flags are only necessary for local docker sandboxing
+# with the rbe-ubuntu16-04 container. Use of these flags is still experimental.
+build:docker-sandbox --host_javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.2:jdk8
+build:docker-sandbox --javabase=@bazel_toolchains//configs/ubuntu16_04_clang/1.2:jdk8
+build:docker-sandbox --crosstool_top=@bazel_toolchains//configs/ubuntu16_04_clang/1.2/bazel_0.25.0/default:toolchain
+build:docker-sandbox --experimental_docker_image=gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:da0f21c71abce3bbb92c3a0c44c3737f007a82b60f8bd2930abc55fe64fc2729
+build:docker-sandbox --spawn_strategy=docker
+build:docker-sandbox --strategy=Javac=docker
+build:docker-sandbox --strategy=Closure=docker
+build:docker-sandbox --strategy=Genrule=docker
+build:docker-sandbox --define=EXECUTOR=remote
+build:docker-sandbox --experimental_docker_verbose
+build:docker-sandbox --experimental_enable_docker_sandbox
+
+# The following flags enable the remote cache so action results can be shared
+# across machines, developers, and workspaces.
+build:remote-cache --remote_cache=remotebuildexecution.googleapis.com
+build:remote-cache --tls_enabled=true
+build:remote-cache --remote_timeout=3600
+build:remote-cache --auth_enabled=true
+build:remote-cache --spawn_strategy=standalone
+build:remote-cache --strategy=Javac=standalone
+build:remote-cache --strategy=Closure=standalone
+build:remote-cache --strategy=Genrule=standalone
diff --git a/tools/workspace-status.cmd b/tools/workspace-status.cmd
index 4a3b88e..bc1560d 100644
--- a/tools/workspace-status.cmd
+++ b/tools/workspace-status.cmd
@@ -1,2 +1 @@
echo STABLE_BUILD_GERRIT_LABEL dev
-echo STABLE_WORKSPACE_ROOT %cd%
diff --git a/tools/workspace-status.sh b/tools/workspace-status.sh
index af6e180..2b1a4ba 100755
--- a/tools/workspace-status.sh
+++ b/tools/workspace-status.sh
@@ -19,4 +19,3 @@
test -d "$p" || continue
echo STABLE_BUILD_$(echo $(basename $p)_LABEL|tr '[a-z]' '[A-Z]' ) $(rev $p || echo unknown)
done
-echo "STABLE_WORKSPACE_ROOT ${PWD}"