Merge branch 'stable-2.14' into stable-2.15

* stable-2.14:
  AbstractQueryChangesTest: Extend byDraftBy to include test for "has:draft"
  AbstractQueryChangesTest: Add explicit tests for is:watched and watchedby:
  AbstractQueryChangesTest: Add explicit tests for is:abandoned and status:abandoned
  user-search: Clarify behavior of default search resulting in single change
  user-search: Fix query used in "My > Watched Changes"
  Documentation: Clarify ref-updated event content when ref is deleted
  Fix markup in Documentation section sendemail
  Allow graceful rolling restarts

Change-Id: Ia48cfdd339aec2274e700ad2a69fc2dbf20b06b6
This commit is contained in:
David Pursehouse
2018-03-22 19:34:53 +09:00
5 changed files with 79 additions and 3 deletions

View File

@@ -2449,6 +2449,21 @@ to permit fast restarts.
+ +
By default, true. By default, true.
[[httpd.gracefulStopTimeout]]httpd.gracefulStopTimeout::
+
Set a graceful stop time. If set, the daemon ensures that all incoming
calls are preserved for a maximum period of time, before starting
the graceful shutdown process. Sites behind a workload balancer such as
HAProxy would need this to be set for avoiding serving errors during
rolling restarts.
+
Values should use common unit suffixes to express their setting:
+
* s, sec, second, seconds
* m, min, minute, minutes
+
By default, 0 seconds (immediate shutdown).
[[httpd.inheritChannel]]httpd.inheritChannel:: [[httpd.inheritChannel]]httpd.inheritChannel::
+ +
If true, permits the daemon to inherit its server socket channel If true, permits the daemon to inherit its server socket channel
@@ -3935,7 +3950,7 @@ By default, MIXED.
Only used when `sendemail.from` is set to `USER`. Only used when `sendemail.from` is set to `USER`.
List of allowed domains. If user's email matches one of the domains, emails will List of allowed domains. If user's email matches one of the domains, emails will
be sent as USER, otherwise as MIXED mode. Wildcards may be specified by be sent as USER, otherwise as MIXED mode. Wildcards may be specified by
including `*` to match any number of characters, for example `*.example.com` including `\*` to match any number of characters, for example `*.example.com`
matches any subdomain of `example.com`. matches any subdomain of `example.com`.
+ +
By default, `*`. By default, `*`.

View File

@@ -157,7 +157,8 @@ Information about a ref that was updated.
oldRev:: The old value of the ref, prior to the update. oldRev:: The old value of the ref, prior to the update.
newRev:: The new value the ref was updated to. newRev:: The new value the ref was updated to. Zero value (`0000000000000000000000000000000000000000`)
indicates that the ref was deleted.
refName:: Full ref name within project. refName:: Full ref name within project.

View File

@@ -12,7 +12,7 @@ query, execute it, and present the results.
|All > Open | status:open '(or is:open)' |All > Open | status:open '(or is:open)'
|All > Merged | status:merged |All > Merged | status:merged
|All > Abandoned | status:abandoned |All > Abandoned | status:abandoned
|My > Watched Changes | status:open is:watched |My > Watched Changes | is:watched is:open
|My > Starred Changes | is:starred |My > Starred Changes | is:starred
|My > Draft Comments | has:draft |My > Draft Comments | has:draft
|Open changes in Foo | status:open project:Foo |Open changes in Foo | status:open project:Foo
@@ -34,6 +34,9 @@ text and let Gerrit figure out the meaning:
|Approval requirement | Code-Review>=+2, Verified=1 |Approval requirement | Code-Review>=+2, Verified=1
|============================================================= |=============================================================
For change searches (i.e. those using a numerical id, Change-Id, or commit
SHA1), if the search results in a single change that change will be
presented instead of a list.
[[search-operators]] [[search-operators]]
== Search Operators == Search Operators

View File

@@ -39,6 +39,7 @@ import java.util.EnumSet;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.servlet.DispatcherType; import javax.servlet.DispatcherType;
import javax.servlet.Filter; import javax.servlet.Filter;
import org.eclipse.jetty.http.HttpScheme; import org.eclipse.jetty.http.HttpScheme;
@@ -56,6 +57,7 @@ import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.RequestLogHandler; import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.eclipse.jetty.server.handler.StatisticsHandler;
import org.eclipse.jetty.server.session.SessionHandler; import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.servlet.DefaultServlet; import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.FilterHolder; import org.eclipse.jetty.servlet.FilterHolder;
@@ -149,6 +151,15 @@ public class JettyServer {
httpd.addBean(mbean); httpd.addBean(mbean);
} }
long gracefulStopTimeout =
cfg.getTimeUnit("httpd", null, "gracefulStopTimeout", 0L, TimeUnit.MILLISECONDS);
if (gracefulStopTimeout > 0) {
StatisticsHandler statsHandler = new StatisticsHandler();
statsHandler.setHandler(app);
app = statsHandler;
httpd.setStopTimeout(gracefulStopTimeout);
}
httpd.setHandler(app); httpd.setHandler(app);
httpd.setStopAtShutdown(false); httpd.setStopAtShutdown(false);
} }

View File

@@ -49,6 +49,7 @@ import com.google.gerrit.extensions.api.changes.StarsInput;
import com.google.gerrit.extensions.api.groups.GroupInput; import com.google.gerrit.extensions.api.groups.GroupInput;
import com.google.gerrit.extensions.api.projects.ConfigInput; import com.google.gerrit.extensions.api.projects.ConfigInput;
import com.google.gerrit.extensions.client.InheritableBoolean; import com.google.gerrit.extensions.client.InheritableBoolean;
import com.google.gerrit.extensions.client.ProjectWatchInfo;
import com.google.gerrit.extensions.client.ReviewerState; import com.google.gerrit.extensions.client.ReviewerState;
import com.google.gerrit.extensions.common.AccountInfo; import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ChangeInfo; import com.google.gerrit.extensions.common.ChangeInfo;
@@ -376,6 +377,20 @@ public abstract class AbstractQueryChangesTest extends GerritServerTests {
assertQuery("is:closed", expected); assertQuery("is:closed", expected);
} }
@Test
public void byStatusAbandoned() throws Exception {
TestRepository<Repo> repo = createProject("repo");
ChangeInserter ins1 = newChangeWithStatus(repo, Change.Status.MERGED);
insert(repo, ins1);
ChangeInserter ins2 = newChangeWithStatus(repo, Change.Status.ABANDONED);
Change change1 = insert(repo, ins2);
insert(repo, newChangeWithStatus(repo, Change.Status.NEW));
assertQuery("status:abandoned", change1);
assertQuery("status:ABANDONED", change1);
assertQuery("is:abandoned", change1);
}
@Test @Test
public void byStatusPrefix() throws Exception { public void byStatusPrefix() throws Exception {
TestRepository<Repo> repo = createProject("repo"); TestRepository<Repo> repo = createProject("repo");
@@ -1494,6 +1509,8 @@ public abstract class AbstractQueryChangesTest extends GerritServerTests {
Change change1 = insert(repo, newChange(repo)); Change change1 = insert(repo, newChange(repo));
Change change2 = insert(repo, newChange(repo)); Change change2 = insert(repo, newChange(repo));
assertQuery("has:draft");
DraftInput in = new DraftInput(); DraftInput in = new DraftInput();
in.line = 1; in.line = 1;
in.message = "nit: trailing whitespace"; in.message = "nit: trailing whitespace";
@@ -1509,6 +1526,7 @@ public abstract class AbstractQueryChangesTest extends GerritServerTests {
int user2 = int user2 =
accountManager.authenticate(AuthRequest.forUser("anotheruser")).getAccountId().get(); accountManager.authenticate(AuthRequest.forUser("anotheruser")).getAccountId().get();
assertQuery("has:draft", change2, change1);
assertQuery("draftby:" + userId.get(), change2, change1); assertQuery("draftby:" + userId.get(), change2, change1);
assertQuery("draftby:" + user2); assertQuery("draftby:" + user2);
} }
@@ -2147,6 +2165,34 @@ public abstract class AbstractQueryChangesTest extends GerritServerTests {
.containsExactlyElementsIn(expectedPatterns); .containsExactlyElementsIn(expectedPatterns);
} }
@Test
public void watched() throws Exception {
TestRepository<Repo> repo = createProject("repo");
ChangeInserter ins1 = newChangeWithStatus(repo, Change.Status.NEW);
Change change1 = insert(repo, ins1);
TestRepository<Repo> repo2 = createProject("repo2");
ChangeInserter ins2 = newChangeWithStatus(repo2, Change.Status.NEW);
insert(repo2, ins2);
assertQuery("is:watched");
assertQuery("watchedby:self");
List<ProjectWatchInfo> projectsToWatch = new ArrayList<>();
ProjectWatchInfo pwi = new ProjectWatchInfo();
pwi.project = "repo";
pwi.filter = null;
pwi.notifyAbandonedChanges = true;
pwi.notifyNewChanges = true;
pwi.notifyAllComments = true;
projectsToWatch.add(pwi);
gApi.accounts().self().setWatchedProjects(projectsToWatch);
assertQuery("is:watched", change1);
assertQuery("watchedby:self", change1);
}
@Test @Test
public void selfAndMe() throws Exception { public void selfAndMe() throws Exception {
TestRepository<Repo> repo = createProject("repo"); TestRepository<Repo> repo = createProject("repo");