Merge branch 'stable-2.15'
* stable-2.15:
setup_gjf.sh: Add support for multiple version
Update .mailmap
SmtpEmailSender: Open Writer in try-with-resource
Open instances of JsonReader in try-with-resource
Set 2.13.12-SNAPSHOT in pom.xml and plugin documentation
Clarify behavior of ownerin: and reviewerin: predicates
AbstractElasticIndex: Open XContentBuilder in try-with-resource
Docs: Clarify that for external groups the name in GroupInfo can be missing
AccountGroupAuditLogScreen: Display group UUID if group name is missing
GetAuditLog: Fix NPE if group UUID cannot be resolved
VersionedMetaData: Open TreeWalk in try-with-resource
FileContentUtil: Open TreeWalk in try-with-resource
Add ProjectCache.remove(Project.NameKey name) method
Set version to 2.13.12-SNAPSHOT
Use SecureRandom instead of Random
Use try with resource in DelegatingClassLoader
AbstractQueryChangesTest: Add test coverage for query: predicate
AbstractQueryChangesTest: Add test coverage for destination: predicate
doc: fix the example of index activate command
doc: add groups index to index activate command
AbstractQueryChangesTest: explicitly cover is:owner
AbstractQueryChangesTest: Add stub test for "query:" predicate
Fix internal errors when 'destination:' refers to non-existing destination
lib/elasticsearch: restore jackson_dataformat_smile
AbstractQueryChangesTest: Add back test for visible: predicate
AbstractQueryChangesTest: Add coverage of is:mergeable
AbstractQueryChangesTest: Add coverage of is:cc and cc:self
AbstractQueryChangesTest: Add coverage for is:visible
AbstractQueryChangesTest#submitRecords: Add coverage for submittable:closed
AbstractQueryChangesTest#bySize: Make it easier to discover size: and delta:
AbstractQueryChangesTest: Use Lists.newArrayList
AbstractQueryChangesTest: Add coverage for the commit: predicate
user-search: Add missing documentation of is:cc predicate
AbstractQueryChangesTest: Add coverage for is:reviewer and reviewer:self
AbstractQueryChangesTest: Add coverage for parentproject: predicate
AbstractQueryChangesTest: Add coverage for is:reviewed and status:reviewed
AbstractQueryChangesTest#byStatusOpen: Add coverage for is:pending
AbstractQueryChangesTest: Add test coverage for since: and until: predicates
AbstractQueryChangesTest: Add test coverage for assignee related queries
Add extra info when checking access to change
Fix logging of a change ID that failed to rebuild.
Log NoteDb migration state transitions
lib/elasticsearch: remove unnecessary dependencies
lib/jest for Elasticsearch: refactor dependencies
Elasticsearch BUILD: remove unneeded dependencies
Change-Id: I93d0c7cd71dfcbfe0fcbd6ec0cd2884a8081bb9d
diff --git a/.mailmap b/.mailmap
index f5f8f3e..b4e81e2 100644
--- a/.mailmap
+++ b/.mailmap
@@ -67,6 +67,7 @@
Ulrik Sjölin <ulrik.sjolin@sonyericsson.com> Ulrik Sjolin <ulrik.sjolin@gmail.com>
Ulrik Sjölin <ulrik.sjolin@sonyericsson.com> Ulrik Sjölin <ulrik.sjolin@sonyericsson.com>
Ulrik Sjölin <ulrik.sjolin@sonyericsson.com> Ulrik Sjolin <ulrik.sjolin@sonyericsson.com>
+Viktar Donich <viktard@google.com> viktard
Yuxuan 'fishy' Wang <fishywang@google.com> Yuxuan Wang <fishywang@google.com>
Zalán Blénessy <zalanb@axis.com> Zalan Blenessy <zalanb@axis.com>
飞 李 <lifei@7v1.net> lifei <lifei@7v1.net>
diff --git a/Documentation/cmd-index-activate.txt b/Documentation/cmd-index-activate.txt
index 418e872..4428d12 100644
--- a/Documentation/cmd-index-activate.txt
+++ b/Documentation/cmd-index-activate.txt
@@ -31,12 +31,13 @@
Currently supported values:
* changes
* accounts
+ * groups
== EXAMPLES
Activate the latest change index:
----
- $ ssh -p 29418 review.example.com gerrit activate changes
+ $ ssh -p 29418 review.example.com gerrit index activate changes
----
GERRIT
diff --git a/Documentation/user-search.txt b/Documentation/user-search.txt
index 2ad8cbd..db42826 100644
--- a/Documentation/user-search.txt
+++ b/Documentation/user-search.txt
@@ -108,7 +108,9 @@
[[ownerin]]
ownerin:'GROUP'::
+
-Changes originally submitted by a user in 'GROUP'.
+Changes originally submitted by a user in 'GROUP'. When no other index
+predicate is explicitly added in the query, defaults to only include
+changes in status 'OPEN'.
[[query]]
query:'NAME'::
@@ -137,7 +139,9 @@
[[reviewerin]]
reviewerin:'GROUP'::
+
-Changes that have been, or need to be, reviewed by a user in 'GROUP'.
+Changes that have been, or need to be, reviewed by a user in 'GROUP'. When
+no other index predicate is explicitly added in the query, defaults to only
+include changes in status 'OPEN'.
[[commit]]
commit:'SHA1'::
@@ -338,6 +342,11 @@
True on any change where the current user is a reviewer.
Same as `reviewer:self`.
+is:cc::
++
+True on any change where the current user is in CC.
+Same as `cc:self`.
+
is:open, is:pending::
+
True if the change is open.
diff --git a/WORKSPACE b/WORKSPACE
index 2041bc7..6967c1f 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -444,12 +444,6 @@
)
maven_jar(
- name = "lucene_codecs",
- artifact = "org.apache.lucene:lucene-codecs:" + LUCENE_VERS,
- sha1 = "afdad570668469b1734fbd32b8f98561561bed48",
-)
-
-maven_jar(
name = "backward_codecs",
artifact = "org.apache.lucene:lucene-backward-codecs:" + LUCENE_VERS,
sha1 = "a933f42e758c54c43083398127ea7342b54d8212",
@@ -486,12 +480,6 @@
)
maven_jar(
- name = "lucene_sandbox",
- artifact = "org.apache.lucene:lucene-sandbox:" + LUCENE_VERS,
- sha1 = "49498bbb2adc333e98bdca4bf6170ae770cbad11",
-)
-
-maven_jar(
name = "lucene_spatial",
artifact = "org.apache.lucene:lucene-spatial:" + LUCENE_VERS,
sha1 = "0217d302dc0ef4d9b8b475ffe327d83c1e0ceba5",
@@ -967,12 +955,6 @@
sha1 = "84ccf145ac2215e6bfa63baa3101c0af41017cfc",
)
-maven_jar(
- name = "jna",
- artifact = "net.java.dev.jna:jna:4.1.0",
- sha1 = "1c12d070e602efd8021891cdd7fd18bc129372d4",
-)
-
JACKSON_VERSION = "2.8.9"
maven_jar(
@@ -982,18 +964,18 @@
)
maven_jar(
- name = "jackson_dataformat_smile",
- artifact = "com.fasterxml.jackson.dataformat:jackson-dataformat-smile:" + JACKSON_VERSION,
- sha1 = "d36cbae6b06ac12fca16fda403759e479316141b",
-)
-
-maven_jar(
name = "jackson_dataformat_cbor",
artifact = "com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:" + JACKSON_VERSION,
sha1 = "93242092324cad33d777e06c0515e40a6b862659",
)
maven_jar(
+ name = "jackson_dataformat_smile",
+ artifact = "com.fasterxml.jackson.dataformat:jackson-dataformat-smile:" + JACKSON_VERSION,
+ sha1 = "d36cbae6b06ac12fca16fda403759e479316141b",
+)
+
+maven_jar(
name = "httpasyncclient",
artifact = "org.apache.httpcomponents:httpasyncclient:4.1.2",
sha1 = "95aa3e6fb520191a0970a73cf09f62948ee614be",
@@ -1005,13 +987,6 @@
sha1 = "a8c5e3c3bfea5ce23fb647c335897e415eb442e3",
)
-maven_jar(
- name = "httpcore_niossl",
- artifact = "org.apache.httpcomponents:httpcore-niossl:4.0-alpha6",
- attach_source = False,
- sha1 = "9c662e7247ca8ceb1de5de629f685c9ef3e4ab58",
-)
-
load("//tools/bzl:js.bzl", "npm_binary", "bower_archive")
npm_binary(
diff --git a/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java b/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
index 3ad31ec..d4d33c7 100644
--- a/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
+++ b/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
@@ -189,21 +189,24 @@
}
private String toDocument(V v) throws IOException {
- XContentBuilder builder = jsonBuilder().startObject();
- for (Values<V> values : schema.buildFields(v)) {
- String name = values.getField().getName();
- if (values.getField().isRepeatable()) {
- builder.field(
- name,
- Streams.stream(values.getValues()).filter(e -> shouldAddElement(e)).collect(toList()));
- } else {
- Object element = Iterables.getOnlyElement(values.getValues(), "");
- if (shouldAddElement(element)) {
- builder.field(name, element);
+ try (XContentBuilder builder = jsonBuilder().startObject()) {
+ for (Values<V> values : schema.buildFields(v)) {
+ String name = values.getField().getName();
+ if (values.getField().isRepeatable()) {
+ builder.field(
+ name,
+ Streams.stream(values.getValues())
+ .filter(e -> shouldAddElement(e))
+ .collect(toList()));
+ } else {
+ Object element = Iterables.getOnlyElement(values.getValues(), "");
+ if (shouldAddElement(element)) {
+ builder.field(name, element);
+ }
}
}
+ return builder.endObject().string();
}
- return builder.endObject().string();
}
protected abstract V fromDocument(JsonObject doc, Set<String> fields);
diff --git a/java/com/google/gerrit/server/account/VersionedAccountDestinations.java b/java/com/google/gerrit/server/account/VersionedAccountDestinations.java
index 0bb5f5e..a57dc7b 100644
--- a/java/com/google/gerrit/server/account/VersionedAccountDestinations.java
+++ b/java/com/google/gerrit/server/account/VersionedAccountDestinations.java
@@ -52,6 +52,9 @@
@Override
protected void onLoad() throws IOException, ConfigInvalidException {
+ if (revision == null) {
+ return;
+ }
String prefix = DestinationList.DIR_NAME + "/";
for (PathInfo p : getPathInfos(true)) {
if (p.fileMode == FileMode.REGULAR_FILE) {
diff --git a/java/com/google/gerrit/server/change/FileContentUtil.java b/java/com/google/gerrit/server/change/FileContentUtil.java
index ff5fb0b..00b7a88 100644
--- a/java/com/google/gerrit/server/change/FileContentUtil.java
+++ b/java/com/google/gerrit/server/change/FileContentUtil.java
@@ -34,7 +34,7 @@
import eu.medsea.mimeutil.MimeType;
import java.io.IOException;
import java.io.OutputStream;
-import java.util.Random;
+import java.security.SecureRandom;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.eclipse.jgit.errors.LargeObjectException;
@@ -42,7 +42,6 @@
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
-import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
@@ -57,7 +56,7 @@
private static final String X_GIT_GITLINK = "x-git/gitlink";
private static final int MAX_SIZE = 5 << 20;
private static final String ZIP_TYPE = "application/zip";
- private static final Random rng = new Random();
+ private static final SecureRandom rng = new SecureRandom();
private final GitRepositoryManager repoManager;
private final FileTypeRegistry registry;
@@ -104,35 +103,35 @@
throws IOException, ResourceNotFoundException {
try (RevWalk rw = new RevWalk(repo)) {
RevCommit commit = rw.parseCommit(revstr);
- ObjectReader reader = rw.getObjectReader();
- TreeWalk tw = TreeWalk.forPath(reader, path, commit.getTree());
- if (tw == null) {
- throw new ResourceNotFoundException();
- }
+ try (TreeWalk tw = TreeWalk.forPath(rw.getObjectReader(), path, commit.getTree())) {
+ if (tw == null) {
+ throw new ResourceNotFoundException();
+ }
- org.eclipse.jgit.lib.FileMode mode = tw.getFileMode(0);
- ObjectId id = tw.getObjectId(0);
- if (mode == org.eclipse.jgit.lib.FileMode.GITLINK) {
- return BinaryResult.create(id.name()).setContentType(X_GIT_GITLINK).base64();
- }
+ org.eclipse.jgit.lib.FileMode mode = tw.getFileMode(0);
+ ObjectId id = tw.getObjectId(0);
+ if (mode == org.eclipse.jgit.lib.FileMode.GITLINK) {
+ return BinaryResult.create(id.name()).setContentType(X_GIT_GITLINK).base64();
+ }
- ObjectLoader obj = repo.open(id, OBJ_BLOB);
- byte[] raw;
- try {
- raw = obj.getCachedBytes(MAX_SIZE);
- } catch (LargeObjectException e) {
- raw = null;
- }
+ ObjectLoader obj = repo.open(id, OBJ_BLOB);
+ byte[] raw;
+ try {
+ raw = obj.getCachedBytes(MAX_SIZE);
+ } catch (LargeObjectException e) {
+ raw = null;
+ }
- String type;
- if (mode == org.eclipse.jgit.lib.FileMode.SYMLINK) {
- type = X_GIT_SYMLINK;
- } else {
- type = registry.getMimeType(path, raw).toString();
- type = resolveContentType(project, path, FileMode.FILE, type);
- }
+ String type;
+ if (mode == org.eclipse.jgit.lib.FileMode.SYMLINK) {
+ type = X_GIT_SYMLINK;
+ } else {
+ type = registry.getMimeType(path, raw).toString();
+ type = resolveContentType(project, path, FileMode.FILE, type);
+ }
- return asBinaryResult(raw, obj).setContentType(type).base64();
+ return asBinaryResult(raw, obj).setContentType(type).base64();
+ }
}
}
@@ -166,30 +165,30 @@
}
commit = rw.parseCommit(commit.getParent(parent - 1));
}
- ObjectReader reader = rw.getObjectReader();
- TreeWalk tw = TreeWalk.forPath(reader, path, commit.getTree());
- if (tw == null) {
- throw new ResourceNotFoundException();
- }
+ try (TreeWalk tw = TreeWalk.forPath(rw.getObjectReader(), path, commit.getTree())) {
+ if (tw == null) {
+ throw new ResourceNotFoundException();
+ }
- int mode = tw.getFileMode(0).getObjectType();
- if (mode != Constants.OBJ_BLOB) {
- throw new ResourceNotFoundException();
- }
+ int mode = tw.getFileMode(0).getObjectType();
+ if (mode != Constants.OBJ_BLOB) {
+ throw new ResourceNotFoundException();
+ }
- ObjectId id = tw.getObjectId(0);
- ObjectLoader obj = repo.open(id, OBJ_BLOB);
- byte[] raw;
- try {
- raw = obj.getCachedBytes(MAX_SIZE);
- } catch (LargeObjectException e) {
- raw = null;
- }
+ ObjectId id = tw.getObjectId(0);
+ ObjectLoader obj = repo.open(id, OBJ_BLOB);
+ byte[] raw;
+ try {
+ raw = obj.getCachedBytes(MAX_SIZE);
+ } catch (LargeObjectException e) {
+ raw = null;
+ }
- MimeType contentType = registry.getMimeType(path, raw);
- return registry.isSafeInline(contentType)
- ? wrapBlob(path, obj, raw, contentType, suffix)
- : zipBlob(path, obj, commit, suffix);
+ MimeType contentType = registry.getMimeType(path, raw);
+ return registry.isSafeInline(contentType)
+ ? wrapBlob(path, obj, raw, contentType, suffix)
+ : zipBlob(path, obj, commit, suffix);
+ }
}
}
diff --git a/java/com/google/gerrit/server/git/meta/VersionedMetaData.java b/java/com/google/gerrit/server/git/meta/VersionedMetaData.java
index 59fd58b2..da1f1ac 100644
--- a/java/com/google/gerrit/server/git/meta/VersionedMetaData.java
+++ b/java/com/google/gerrit/server/git/meta/VersionedMetaData.java
@@ -481,10 +481,11 @@
return new byte[] {};
}
- TreeWalk tw = TreeWalk.forPath(reader, fileName, revision.getTree());
- if (tw != null) {
- ObjectLoader obj = reader.open(tw.getObjectId(0), Constants.OBJ_BLOB);
- return obj.getCachedBytes(Integer.MAX_VALUE);
+ try (TreeWalk tw = TreeWalk.forPath(reader, fileName, revision.getTree())) {
+ if (tw != null) {
+ ObjectLoader obj = reader.open(tw.getObjectId(0), Constants.OBJ_BLOB);
+ return obj.getCachedBytes(Integer.MAX_VALUE);
+ }
}
return new byte[] {};
}
@@ -495,9 +496,10 @@
return null;
}
- TreeWalk tw = TreeWalk.forPath(reader, fileName, revision.getTree());
- if (tw != null) {
- return tw.getObjectId(0);
+ try (TreeWalk tw = TreeWalk.forPath(reader, fileName, revision.getTree())) {
+ if (tw != null) {
+ return tw.getObjectId(0);
+ }
}
return null;
diff --git a/java/com/google/gerrit/server/mail/send/SmtpEmailSender.java b/java/com/google/gerrit/server/mail/send/SmtpEmailSender.java
index a8289c4..b08e594 100644
--- a/java/com/google/gerrit/server/mail/send/SmtpEmailSender.java
+++ b/java/com/google/gerrit/server/mail/send/SmtpEmailSender.java
@@ -200,30 +200,31 @@
}
}
- Writer messageDataWriter = client.sendMessageData();
- if (messageDataWriter == null) {
- /* Include rejected recipient error messages here to not lose that
- * information. That piece of the puzzle is vital if zero recipients
- * are accepted and the server consequently rejects the DATA command.
- */
- throw new EmailException(
- rejected
- + "Server "
- + smtpHost
- + " rejected DATA command: "
- + client.getReplyString());
- }
+ try (Writer messageDataWriter = client.sendMessageData()) {
+ if (messageDataWriter == null) {
+ /* Include rejected recipient error messages here to not lose that
+ * information. That piece of the puzzle is vital if zero recipients
+ * are accepted and the server consequently rejects the DATA command.
+ */
+ throw new EmailException(
+ rejected
+ + "Server "
+ + smtpHost
+ + " rejected DATA command: "
+ + client.getReplyString());
+ }
- render(messageDataWriter, callerHeaders, textBody, htmlBody);
+ render(messageDataWriter, callerHeaders, textBody, htmlBody);
- if (!client.completePendingCommand()) {
- throw new EmailException(
- "Server " + smtpHost + " rejected message body: " + client.getReplyString());
- }
+ if (!client.completePendingCommand()) {
+ throw new EmailException(
+ "Server " + smtpHost + " rejected message body: " + client.getReplyString());
+ }
- client.logout();
- if (rejected.length() > 0) {
- throw new EmailException(rejected.toString());
+ client.logout();
+ if (rejected.length() > 0) {
+ throw new EmailException(rejected.toString());
+ }
}
} finally {
client.disconnect();
diff --git a/java/com/google/gerrit/server/notedb/rebuild/NoteDbMigrator.java b/java/com/google/gerrit/server/notedb/rebuild/NoteDbMigrator.java
index c11aeef..df415ce 100644
--- a/java/com/google/gerrit/server/notedb/rebuild/NoteDbMigrator.java
+++ b/java/com/google/gerrit/server/notedb/rebuild/NoteDbMigrator.java
@@ -615,6 +615,7 @@
log.warn(
"Change {} previously failed to rebuild;"
+ " skipping primary storage migration",
+ id,
e);
} else {
throw e;
@@ -724,6 +725,7 @@
// Only set in-memory state once it's been persisted to storage.
globalNotesMigration.setFrom(newState);
+ log.info("Migration state: {} => {}", expectedOldState, newState);
return newState;
}
diff --git a/java/com/google/gerrit/server/query/change/ChangeIsVisibleToPredicate.java b/java/com/google/gerrit/server/query/change/ChangeIsVisibleToPredicate.java
index 1052d33..063a18c 100644
--- a/java/com/google/gerrit/server/query/change/ChangeIsVisibleToPredicate.java
+++ b/java/com/google/gerrit/server/query/change/ChangeIsVisibleToPredicate.java
@@ -93,7 +93,7 @@
logger.info("No such project: {}", cd.project());
return false;
}
- throw new OrmException("unable to check permissions", e);
+ throw new OrmException("unable to check permissions on change " + cd.getId(), e);
}
if (visible) {
cd.cacheVisibleTo(user);
diff --git a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index 5a04a7c..630f2f3 100644
--- a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -1103,7 +1103,7 @@
VersionedAccountDestinations d = VersionedAccountDestinations.forUser(self());
d.load(git);
Set<Branch.NameKey> destinations = d.getDestinationList().getDestinations(name);
- if (destinations != null) {
+ if (destinations != null && !destinations.isEmpty()) {
return new DestinationPredicate(destinations, name);
}
} catch (RepositoryNotFoundException e) {
diff --git a/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java b/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java
index f4bb2a9..082ef28 100644
--- a/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java
+++ b/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java
@@ -846,16 +846,18 @@
private <T> T readContentFromJson(RestResponse r, Class<T> clazz) throws Exception {
r.assertOK();
- JsonReader jsonReader = new JsonReader(r.getReader());
- jsonReader.setLenient(true);
- return newGson().fromJson(jsonReader, clazz);
+ try (JsonReader jsonReader = new JsonReader(r.getReader())) {
+ jsonReader.setLenient(true);
+ return newGson().fromJson(jsonReader, clazz);
+ }
}
private <T> T readContentFromJson(RestResponse r, TypeToken<T> typeToken) throws Exception {
r.assertOK();
- JsonReader jsonReader = new JsonReader(r.getReader());
- jsonReader.setLenient(true);
- return newGson().fromJson(jsonReader, typeToken.getType());
+ try (JsonReader jsonReader = new JsonReader(r.getReader())) {
+ jsonReader.setLenient(true);
+ return newGson().fromJson(jsonReader, typeToken.getType());
+ }
}
private String readContentFromJson(RestResponse r) 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 f1bba8a..ee5d3b0 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/ChangeReviewersIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/ChangeReviewersIT.java
@@ -830,9 +830,10 @@
private static <T> T readContentFromJson(RestResponse r, int expectedStatus, Class<T> clazz)
throws Exception {
r.assertStatus(expectedStatus);
- JsonReader jsonReader = new JsonReader(r.getReader());
- jsonReader.setLenient(true);
- return newGson().fromJson(jsonReader, clazz);
+ try (JsonReader jsonReader = new JsonReader(r.getReader())) {
+ jsonReader.setLenient(true);
+ return newGson().fromJson(jsonReader, clazz);
+ }
}
private static void assertReviewers(
diff --git a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
index c9c3636..311dd74 100644
--- a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
+++ b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
@@ -57,6 +57,7 @@
import com.google.gerrit.extensions.api.changes.StarsInput;
import com.google.gerrit.extensions.api.groups.GroupInput;
import com.google.gerrit.extensions.api.projects.ConfigInput;
+import com.google.gerrit.extensions.api.projects.ProjectInput;
import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.client.ProjectWatchInfo;
import com.google.gerrit.extensions.client.ReviewerState;
@@ -375,6 +376,7 @@
assertQuery("status:pe", expected);
assertQuery("status:pen", expected);
assertQuery("is:open", expected);
+ assertQuery("is:pending", expected);
}
@Test
@@ -630,13 +632,15 @@
public void byCommit() throws Exception {
TestRepository<Repo> repo = createProject("repo");
ChangeInserter ins = newChange(repo);
- insert(repo, ins);
+ Change change = insert(repo, ins);
String sha = ins.getCommitId().name();
assertQuery("0000000000000000000000000000000000000000");
+ assertQuery("commit:0000000000000000000000000000000000000000");
for (int i = 0; i <= 36; i++) {
String q = sha.substring(0, 40 - i);
- assertQuery(q, ins.getChange());
+ assertQuery(q, change);
+ assertQuery("commit:" + q, change);
}
}
@@ -648,6 +652,7 @@
accountManager.authenticate(AuthRequest.forUser("anotheruser")).getAccountId();
Change change2 = insert(repo, newChange(repo), user2);
+ assertQuery("is:owner", change1);
assertQuery("owner:" + userId.get(), change1);
assertQuery("owner:" + user2, change2);
@@ -749,6 +754,7 @@
assertQuery("ownerin:Administrators", change1);
assertQuery("ownerin:\"Registered Users\"", change2, change1);
+ assertQuery("ownerin:\"Registered Users\" project:repo", change3, change2, change1);
assertQuery("ownerin:\"Registered Users\" status:merged", change3);
}
@@ -766,6 +772,17 @@
}
@Test
+ public void byParentProject() throws Exception {
+ TestRepository<Repo> repo1 = createProject("repo1");
+ TestRepository<Repo> repo2 = createProject("repo2", "repo1");
+ Change change1 = insert(repo1, newChange(repo1));
+ Change change2 = insert(repo2, newChange(repo2));
+
+ assertQuery("parentproject:repo1", change2, change1);
+ assertQuery("parentproject:repo2", change2);
+ }
+
+ @Test
public void byProjectPrefix() throws Exception {
TestRepository<Repo> repo1 = createProject("repo1");
TestRepository<Repo> repo2 = createProject("repo2");
@@ -1363,7 +1380,7 @@
}
@Test
- public void byBefore() throws Exception {
+ public void byBeforeUntil() throws Exception {
long thirtyHoursInMs = MILLISECONDS.convert(30, HOURS);
resetTimeWithClockStep(thirtyHoursInMs, MILLISECONDS);
TestRepository<Repo> repo = createProject("repo");
@@ -1372,20 +1389,22 @@
Change change2 = insert(repo, newChange(repo), null, new Timestamp(startMs + thirtyHoursInMs));
TestTimeUtil.setClockStep(0, MILLISECONDS);
- assertQuery("before:2009-09-29");
- assertQuery("before:2009-09-30");
- assertQuery("before:\"2009-09-30 16:59:00 -0400\"");
- assertQuery("before:\"2009-09-30 20:59:00 -0000\"");
- assertQuery("before:\"2009-09-30 20:59:00\"");
- assertQuery("before:\"2009-09-30 17:02:00 -0400\"", change1);
- assertQuery("before:\"2009-10-01 21:02:00 -0000\"", change1);
- assertQuery("before:\"2009-10-01 21:02:00\"", change1);
- assertQuery("before:2009-10-01", change1);
- assertQuery("before:2009-10-03", change2, change1);
+ for (String predicate : Lists.newArrayList("before:", "until:")) {
+ assertQuery(predicate + "2009-09-29");
+ assertQuery(predicate + "2009-09-30");
+ assertQuery(predicate + "\"2009-09-30 16:59:00 -0400\"");
+ assertQuery(predicate + "\"2009-09-30 20:59:00 -0000\"");
+ assertQuery(predicate + "\"2009-09-30 20:59:00\"");
+ assertQuery(predicate + "\"2009-09-30 17:02:00 -0400\"", change1);
+ assertQuery(predicate + "\"2009-10-01 21:02:00 -0000\"", change1);
+ assertQuery(predicate + "\"2009-10-01 21:02:00\"", change1);
+ assertQuery(predicate + "2009-10-01", change1);
+ assertQuery(predicate + "2009-10-03", change2, change1);
+ }
}
@Test
- public void byAfter() throws Exception {
+ public void byAfterSince() throws Exception {
long thirtyHoursInMs = MILLISECONDS.convert(30, HOURS);
resetTimeWithClockStep(thirtyHoursInMs, MILLISECONDS);
TestRepository<Repo> repo = createProject("repo");
@@ -1394,11 +1413,13 @@
Change change2 = insert(repo, newChange(repo), null, new Timestamp(startMs + thirtyHoursInMs));
TestTimeUtil.setClockStep(0, MILLISECONDS);
- assertQuery("after:2009-10-03");
- assertQuery("after:\"2009-10-01 20:59:59 -0400\"", change2);
- assertQuery("after:\"2009-10-01 20:59:59 -0000\"", change2);
- assertQuery("after:2009-10-01", change2);
- assertQuery("after:2009-09-30", change2, change1);
+ for (String predicate : Lists.newArrayList("after:", "since:")) {
+ assertQuery(predicate + "2009-10-03");
+ assertQuery(predicate + "\"2009-10-01 20:59:59 -0400\"", change2);
+ assertQuery(predicate + "\"2009-10-01 20:59:59 -0000\"", change2);
+ assertQuery(predicate + "2009-10-01", change2);
+ assertQuery(predicate + "2009-09-30", change2, change1);
+ }
}
@Test
@@ -1448,13 +1469,13 @@
assertQuery("deleted:<=0", change1);
- for (String str : Lists.newArrayList("delta", "size")) {
- assertQuery(str + ":<2");
- assertQuery(str + ":3", change1);
- assertQuery(str + ":>2", change1);
- assertQuery(str + ":>=3", change1);
- assertQuery(str + ":<3", change2);
- assertQuery(str + ":<=2", change2);
+ for (String str : Lists.newArrayList("delta:", "size:")) {
+ assertQuery(str + "<2");
+ assertQuery(str + "3", change1);
+ assertQuery(str + ">2", change1);
+ assertQuery(str + ">=3", change1);
+ assertQuery(str + "<3", change2);
+ assertQuery(str + "<=2", change2);
}
}
@@ -1564,6 +1585,28 @@
}
@Test
+ public void visible() throws Exception {
+ TestRepository<Repo> repo = createProject("repo");
+ Change change1 = insert(repo, newChange(repo));
+ Change change2 = insert(repo, newChange(repo));
+
+ gApi.changes().id(change2.getChangeId()).setPrivate(true, "private");
+
+ String q = "project:repo";
+ assertQuery(q, change2, change1);
+
+ // Second user cannot see first user's private change.
+ Account.Id user2 =
+ accountManager.authenticate(AuthRequest.forUser("anotheruser")).getAccountId();
+ assertQuery(q + " visibleto:" + user2.get(), change1);
+
+ requestContext.setContext(
+ newRequestContext(
+ accountManager.authenticate(AuthRequest.forUser("anotheruser")).getAccountId()));
+ assertQuery("is:visible", change1);
+ }
+
+ @Test
public void byCommentBy() throws Exception {
TestRepository<Repo> repo = createProject("repo");
Change change1 = insert(repo, newChange(repo));
@@ -1793,6 +1836,26 @@
}
@Test
+ public void mergeable() throws Exception {
+ TestRepository<Repo> repo = createProject("repo");
+ RevCommit commit1 = repo.parseBody(repo.commit().add("file1", "contents1").create());
+ RevCommit commit2 = repo.parseBody(repo.commit().add("file1", "contents2").create());
+ Change change1 = insert(repo, newChangeForCommit(repo, commit1));
+ Change change2 = insert(repo, newChangeForCommit(repo, commit2));
+
+ assertQuery("conflicts:" + change1.getId().get(), change2);
+ assertQuery("conflicts:" + change2.getId().get(), change1);
+ assertQuery("is:mergeable", change2, change1);
+
+ gApi.changes().id(change1.getChangeId()).revision("current").review(ReviewInput.approve());
+ gApi.changes().id(change1.getChangeId()).revision("current").submit();
+
+ assertQuery("status:open conflicts:" + change2.getId().get());
+ assertQuery("status:open is:mergeable");
+ assertQuery("status:open -is:mergeable", change2);
+ }
+
+ @Test
public void reviewedBy() throws Exception {
resetTimeWithClockStep(2, MINUTES);
TestRepository<Repo> repo = createProject("repo");
@@ -1839,6 +1902,7 @@
TestRepository<Repo> repo = createProject("repo");
Change change1 = insert(repo, newChange(repo));
Change change2 = insert(repo, newChange(repo));
+ Change change3 = insert(repo, newChange(repo));
insert(repo, newChange(repo));
AddReviewerInput rin = new AddReviewerInput();
@@ -1851,16 +1915,49 @@
rin.state = ReviewerState.CC;
gApi.changes().id(change2.getId().get()).addReviewer(rin);
+ assertQuery("is:reviewer");
+ assertQuery("reviewer:self");
+ gApi.changes().id(change3.getChangeId()).revision("current").review(ReviewInput.recommend());
+ assertQuery("is:reviewer", change3);
+ assertQuery("reviewer:self", change3);
+
+ requestContext.setContext(newRequestContext(user1));
if (notesMigration.readChanges()) {
assertQuery("reviewer:" + user1, change1);
assertQuery("cc:" + user1, change2);
+ assertQuery("is:cc", change2);
+ assertQuery("cc:self", change2);
} else {
assertQuery("reviewer:" + user1, change2, change1);
assertQuery("cc:" + user1);
+ assertQuery("is:cc");
+ assertQuery("cc:self");
}
}
@Test
+ public void byReviewed() throws Exception {
+ TestRepository<Repo> repo = createProject("repo");
+ Account.Id otherUser =
+ accountManager.authenticate(AuthRequest.forUser("anotheruser")).getAccountId();
+ Change change1 = insert(repo, newChange(repo));
+ Change change2 = insert(repo, newChange(repo));
+
+ assertQuery("is:reviewed");
+ assertQuery("status:reviewed");
+ assertQuery("-is:reviewed", change2, change1);
+ assertQuery("-status:reviewed", change2, change1);
+
+ requestContext.setContext(newRequestContext(otherUser));
+ gApi.changes().id(change1.getChangeId()).current().review(ReviewInput.recommend());
+
+ assertQuery("is:reviewed", change1);
+ assertQuery("status:reviewed", change1);
+ assertQuery("-is:reviewed", change2);
+ assertQuery("-status:reviewed", change2);
+ }
+
+ @Test
public void reviewerin() throws Exception {
Account.Id user1 = accountManager.authenticate(AuthRequest.forUser("user1")).getAccountId();
Account.Id user2 = accountManager.authenticate(AuthRequest.forUser("user2")).getAccountId();
@@ -1899,6 +1996,7 @@
gApi.changes().id(change2.getId().get()).current().submit();
assertQuery("reviewerin:" + group);
+ assertQuery("project:repo reviewerin:" + group, change2);
assertQuery("status:merged reviewerin:" + group, change2);
}
@@ -2016,6 +2114,10 @@
// NEED records don't have associated users.
assertQuery("label:CodE-RevieW=need,user1");
assertQuery("label:CodE-RevieW=need,user");
+
+ gApi.changes().id(change1.getId().get()).current().submit();
+ assertQuery("submittable:ok");
+ assertQuery("submittable:closed", change1);
}
@Test
@@ -2692,6 +2794,89 @@
mergedOwned);
}
+ @Test
+ public void assignee() throws Exception {
+ TestRepository<Repo> repo = createProject("repo");
+ Change change1 = insert(repo, newChange(repo));
+ Change change2 = insert(repo, newChange(repo));
+
+ AssigneeInput input = new AssigneeInput();
+ input.assignee = user.getUserName().get();
+ gApi.changes().id(change1.getChangeId()).setAssignee(input);
+
+ assertQuery("is:assigned", change1);
+ assertQuery("-is:assigned", change2);
+ assertQuery("is:unassigned", change2);
+ assertQuery("-is:unassigned", change1);
+ assertQuery("assignee:" + user.getUserName().get(), change1);
+ assertQuery("-assignee:" + user.getUserName().get(), change2);
+ }
+
+ @Test
+ public void userDestination() throws Exception {
+ TestRepository<Repo> repo1 = createProject("repo1");
+ Change change1 = insert(repo1, newChange(repo1));
+ TestRepository<Repo> repo2 = createProject("repo2");
+ Change change2 = insert(repo2, newChange(repo2));
+
+ assertThatQueryException("destination:foo")
+ .hasMessageThat()
+ .isEqualTo("Unknown named destination: foo");
+
+ String destination1 = "refs/heads/master\trepo1";
+ String destination2 = "refs/heads/master\trepo2";
+ String destination3 = "refs/heads/master\trepo1\nrefs/heads/master\trepo2";
+ 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();
+
+ Ref userRef = allUsers.getRepository().exactRef(refsUsers);
+ assertThat(userRef).isNotNull();
+
+ assertQuery("destination:destination1", change1);
+ assertQuery("destination:destination2", change2);
+ assertQuery("destination:destination3", change2, change1);
+ assertQuery("destination:destination4");
+ assertQuery("destination:destination5");
+ }
+
+ @Test
+ public void userQuery() throws Exception {
+ TestRepository<Repo> repo = createProject("repo");
+ Change change1 = insert(repo, newChange(repo));
+ Change change2 = insert(repo, newChangeForBranch(repo, "stable"));
+
+ String queries =
+ "query1\tproject:repo\n"
+ + "query2\tproject:repo status:open\n"
+ + "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();
+
+ Ref userRef = allUsers.getRepository().exactRef(refsUsers);
+ assertThat(userRef).isNotNull();
+
+ assertThatQueryException("query:foo").hasMessageThat().isEqualTo("Unknown named query: foo");
+
+ assertQuery("query:query1", change2, change1);
+ assertQuery("query:query2", change2, change1);
+ gApi.changes().id(change1.getChangeId()).revision("current").review(ReviewInput.approve());
+ gApi.changes().id(change1.getChangeId()).revision("current").submit();
+ assertQuery("query:query2", change2);
+ assertQuery("query:query3", change2);
+ assertQuery("query:query4");
+ }
+
protected ChangeInserter newChange(TestRepository<Repo> repo) throws Exception {
return newChange(repo, null, null, null, null, false);
}
@@ -2817,6 +3002,14 @@
return new TestRepository<>(repoManager.openRepository(new Project.NameKey(name)));
}
+ protected TestRepository<Repo> createProject(String name, String parent) throws Exception {
+ ProjectInput input = new ProjectInput();
+ input.name = name;
+ input.parent = parent;
+ gApi.projects().create(input).get();
+ return new TestRepository<>(repoManager.openRepository(new Project.NameKey(name)));
+ }
+
protected QueryRequest newQuery(Object query) {
return gApi.changes().query(query.toString());
}
diff --git a/lib/elasticsearch/BUILD b/lib/elasticsearch/BUILD
index 387cdad..13c033e 100644
--- a/lib/elasticsearch/BUILD
+++ b/lib/elasticsearch/BUILD
@@ -7,7 +7,6 @@
runtime_deps = [
":compress-lzf",
":hppc",
- ":jna",
":joda-time",
":jsr166e",
":netty",
@@ -15,12 +14,10 @@
"//lib/jackson:jackson-core",
"//lib/jackson:jackson-dataformat-cbor",
"//lib/jackson:jackson-dataformat-smile",
- "//lib/lucene:lucene-codecs",
"//lib/lucene:lucene-highlighter",
"//lib/lucene:lucene-join",
"//lib/lucene:lucene-memory",
"//lib/lucene:lucene-queries",
- "//lib/lucene:lucene-sandbox",
"//lib/lucene:lucene-spatial",
"//lib/lucene:lucene-suggest",
],
@@ -73,9 +70,3 @@
visibility = ["//lib/elasticsearch:__pkg__"],
exports = ["@t_digest//jar"],
)
-
-java_library(
- name = "jna",
- data = ["//lib:LICENSE-Apache2.0"],
- exports = ["@jna//jar"],
-)
diff --git a/lib/httpcomponents/BUILD b/lib/httpcomponents/BUILD
index 2b2cc6f..6e8fcd8 100644
--- a/lib/httpcomponents/BUILD
+++ b/lib/httpcomponents/BUILD
@@ -45,9 +45,3 @@
data = ["//lib:LICENSE-Apache2.0"],
exports = ["@httpcore_nio//jar"],
)
-
-java_library(
- name = "httpcore-niossl",
- data = ["//lib:LICENSE-Apache2.0"],
- exports = ["@httpcore_niossl//jar"],
-)
diff --git a/lib/jackson/BUILD b/lib/jackson/BUILD
index 4847371..8ade0cf 100644
--- a/lib/jackson/BUILD
+++ b/lib/jackson/BUILD
@@ -9,13 +9,13 @@
)
java_library(
- name = "jackson-dataformat-smile",
- data = ["//lib:LICENSE-Apache2.0"],
- exports = ["@jackson_dataformat_smile//jar"],
-)
-
-java_library(
name = "jackson-dataformat-cbor",
data = ["//lib:LICENSE-Apache2.0"],
exports = ["@jackson_dataformat_cbor//jar"],
)
+
+java_library(
+ name = "jackson-dataformat-smile",
+ data = ["//lib:LICENSE-Apache2.0"],
+ exports = ["@jackson_dataformat_smile//jar"],
+)
diff --git a/lib/jest/BUILD b/lib/jest/BUILD
index 3fdb5f7..169f271 100644
--- a/lib/jest/BUILD
+++ b/lib/jest/BUILD
@@ -5,6 +5,9 @@
data = ["//lib:LICENSE-Apache2.0"],
visibility = ["//visibility:public"],
exports = ["@jest_common//jar"],
+ runtime_deps = [
+ "//lib/commons:lang3",
+ ],
)
java_library(
@@ -13,11 +16,8 @@
visibility = ["//visibility:public"],
exports = ["@jest//jar"],
runtime_deps = [
- ":jest-common",
- "//lib/commons:lang3",
"//lib/httpcomponents:httpasyncclient",
"//lib/httpcomponents:httpclient",
"//lib/httpcomponents:httpcore-nio",
- "//lib/httpcomponents:httpcore-niossl",
],
)
diff --git a/lib/lucene/BUILD b/lib/lucene/BUILD
index bbf43a6..6590af4 100644
--- a/lib/lucene/BUILD
+++ b/lib/lucene/BUILD
@@ -23,13 +23,6 @@
)
java_library(
- name = "lucene-codecs",
- data = ["//lib:LICENSE-Apache2.0"],
- visibility = ["//visibility:public"],
- exports = ["@lucene_codecs//jar"],
-)
-
-java_library(
name = "lucene-core",
data = ["//lib:LICENSE-Apache2.0"],
visibility = ["//visibility:public"],
@@ -71,12 +64,6 @@
)
java_library(
- name = "lucene-sandbox",
- data = ["//lib:LICENSE-Apache2.0"],
- exports = ["@lucene_sandbox//jar"],
-)
-
-java_library(
name = "lucene-spatial",
data = ["//lib:LICENSE-Apache2.0"],
exports = ["@lucene_spatial//jar"],