Merge branch 'stable-3.1'

* stable-3.1:
  Adapt to deprecation of WindowCacheStats methods in JGit
  Upgrade JGit to v5.6.0.201912101111-r-31-g3d59d1b80
  Fix method name to register custom event types in plugins
  Don't send mails on publish change edits for WIP changes
  PatchSetInserter: allow to set "sendEmail" bit
  e2e-tests: Mention the blog post in documentation
  Set version to 2.16.17-SNAPSHOT
  Set version to 2.16.16
  Treat NoSuchAlgorithmException consistently as IllegalStateException
  CreateMergePatchSet: Do not fail with ISE if given merge strategy is invalid
  MergeUtil#newMerger: Throw a specific exception for invalid strategy
  CreateMergePatchSet: Improve message which is returned if there are conflicts
  Test CreateMergePatchSet when there is a merge conflict
  ChangeIT: Fix/improve tests for CreateMergePatchSet REST endpoint
  GetPatch: Fix NullPointerException
  Fix resource leak warning in GetPatch#apply
  CreateChange#getCommitMessage: Remove unused parameters and variable
  CloneUsingBothProtocols: Align closing parenthesis
  ReplayRecordsFromFeeder: Refactor the after method
  ReplayRecordsFromFeeder: Align scenario building
  ReplayRecordsFromFeeder: Extract request to value
  ReplayRecordsFromFeeder: Un-hardcode json filename
  ReplayRecordsFromFeeder: Group implicit val at top
  ReplayRecordsFromFeeder: Fix braces/parentheses warnings
  ReplayRecordsFromFeeder: Add type to public member
  e2e-tests: Rename ReplayRecordsFromFeeder scenario
  e2e-tests: Reformat ReplayRecordsFromFeeder.scala
  e2e-tests: Upgrade sbt to 1.3.7
  Remove MessageOfTheDay extension
  Revert "Add MessageOfTheDay-entries to ServerInfo"
  Revert "Add UI element to display messages of the day"
  Revert "Document MessageOfTheDay extension"
  Tests: Use helper method for config change
  Generate Change-Ids randomly instead of computing them from commit content and timestamp
  Document MessageOfTheDay extension
  Add UI element to display messages of the day
  Add MessageOfTheDay-entries to ServerInfo

Change-Id: Id6432bb6b90083843c81bc5084957f283195137a
This commit is contained in:
David Pursehouse
2020-02-05 17:08:11 +09:00
12 changed files with 49 additions and 120 deletions

View File

@@ -18,7 +18,9 @@ link:https://github.com/GerritForge/gatling-git[Gatling Git extension,role=exter
to run tests at Git protocol level.
Gatling is written in Scala, but the abstraction provided by the Gatling DSL makes the scenarios
implementation easy even without any Scala knowledge.
implementation easy even without any Scala knowledge. The
link:https://gitenterprise.me/2019/12/20/stress-your-gerrit-with-gatling/[Stress your Gerrit with Gatling]
blog post has more introductory information.
Examples of scenarios can be found in the `e2e-tests` directory. The files in that directory
should be formatted using the mainstream

View File

@@ -476,9 +476,9 @@ class MyPlugin {
----
Plugins which define new Events should register them via the
`com.google.gerrit.server.events.EventTypes.registerClass()`
method. This will make the EventType known to the system.
Deserializing events with the
`com.google.gerrit.server.events.EventTypes.register()` method.
This will make the EventType known to the system. Deserializing
events with the
`com.google.gerrit.server.events.EventDeserializer` class requires
that the event be registered in EventTypes.

View File

@@ -1 +1 @@
sbt.version=1.2.3
sbt.version=1.3.7

View File

@@ -44,8 +44,8 @@ class CloneUsingBothProtocols extends Simulation {
setUp(
test.inject(
constantUsersPerSec(1) during (2 seconds))
).protocols(protocol)
constantUsersPerSec(1) during (2 seconds)
)).protocols(protocol)
after {
Thread.sleep(5000)

View File

@@ -14,59 +14,55 @@
package com.google.gerrit.scenarios
import com.github.barbasa.gatling.git.protocol.GitProtocol
import com.github.barbasa.gatling.git.request.builder.GitRequestBuilder
import io.gatling.core.Predef._
import io.gatling.core.structure.ScenarioBuilder
import java.io._
import com.github.barbasa.gatling.git.{
GatlingGitConfiguration,
GitRequestSession
}
import com.github.barbasa.gatling.git.protocol.GitProtocol
import com.github.barbasa.gatling.git.request.builder.GitRequestBuilder
import com.github.barbasa.gatling.git.{GatlingGitConfiguration, GitRequestSession}
import io.gatling.core.Predef._
import io.gatling.core.feeder.FileBasedFeederBuilder
import io.gatling.core.structure.ScenarioBuilder
import org.apache.commons.io.FileUtils
import scala.concurrent.duration._
import org.eclipse.jgit.hooks._
class ReplayRecordsFromFeederScenario extends Simulation {
import scala.concurrent.duration._
val gitProtocol = GitProtocol()
implicit val conf = GatlingGitConfiguration()
implicit val postMessageHook: Option[String] = Some(
s"hooks/${CommitMsgHook.NAME}")
class ReplayRecordsFromFeeder extends Simulation {
val feeder = jsonFile("data/requests.json").circular
implicit val conf: GatlingGitConfiguration = GatlingGitConfiguration()
implicit val postMessageHook: Option[String] = Some(s"hooks/${CommitMsgHook.NAME}")
val replayCallsScenario: ScenarioBuilder =
scenario("Git commands")
private val name: String = this.getClass.getSimpleName
private val file = s"data/$name.json"
private val data: FileBasedFeederBuilder[Any]#F = jsonFile(file).circular
private val request = new GitRequestBuilder(GitRequestSession("${cmd}", "${url}"))
private val protocol: GitProtocol = GitProtocol()
private val test: ScenarioBuilder = scenario(name)
.repeat(10000) {
feed(feeder)
.exec(new GitRequestBuilder(GitRequestSession("${cmd}", "${url}")))
feed(data)
.exec(request)
}
setUp(
replayCallsScenario.inject(
test.inject(
nothingFor(4 seconds),
atOnceUsers(10),
rampUsers(10) during (5 seconds),
constantUsersPerSec(20) during (15 seconds),
constantUsersPerSec(20) during (15 seconds) randomized
))
.protocols(gitProtocol)
.maxDuration(60 seconds)
)).protocols(protocol)
.maxDuration(60 seconds)
after {
Thread.sleep(5000)
val path = conf.tmpBasePath
try {
//After is often called too early. Some retries should be implemented.
Thread.sleep(5000)
FileUtils.deleteDirectory(new File(conf.tmpBasePath))
FileUtils.deleteDirectory(new File(path))
} catch {
case e: IOException => {
System.err.println(
"Unable to delete temporary directory: " + conf.tmpBasePath)
e.printStackTrace
}
case e: IOException =>
System.err.println("Unable to delete temporary directory " + path)
e.printStackTrace()
}
}
}

View File

@@ -1,63 +0,0 @@
// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.extensions.systemstatus;
import com.google.gerrit.extensions.annotations.ExtensionPoint;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
/**
* Supplies a message of the day when the page is first loaded.
*
* <pre>
* DynamicSet.bind(binder(), MessageOfTheDay.class).to(MyMessage.class);
* </pre>
*/
@ExtensionPoint
public abstract class MessageOfTheDay {
/**
* Retrieve the message of the day as an HTML fragment.
*
* @return message as an HTML fragment; null if no message is available.
*/
public abstract String getHtmlMessage();
/**
* Unique identifier for this message.
*
* <p>Messages with the same identifier will be hidden from the user until redisplay has occurred.
*
* @return unique message identifier. This identifier should be unique within the server.
*/
public abstract String getMessageId();
/**
* When should the message be displayed?
*
* <p>Default implementation returns {@code tomorrow at 00:00:00 GMT}.
*
* @return a future date after which the message should be redisplayed.
*/
public Date getRedisplay() {
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.add(Calendar.DAY_OF_MONTH, 1);
return cal.getTime();
}
}

View File

@@ -28,12 +28,12 @@ public class JGitMetricModule extends MetricModule {
new Description("Bytes of memory retained in JGit block cache.")
.setGauge()
.setUnit(Units.BYTES),
WindowCacheStats::getOpenBytes);
() -> WindowCacheStats.getStats().getOpenByteCount());
metrics.newCallbackMetric(
"jgit/block_cache/open_files",
Integer.class,
Long.class,
new Description("File handles held open by JGit block cache.").setGauge().setUnit("fds"),
WindowCacheStats::getOpenFiles);
() -> WindowCacheStats.getStats().getOpenFileCount());
}
}

View File

@@ -61,7 +61,6 @@ import com.google.gerrit.extensions.events.WorkInProgressStateChangedListener;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.systemstatus.MessageOfTheDay;
import com.google.gerrit.extensions.validators.CommentValidator;
import com.google.gerrit.extensions.webui.BranchWebLink;
import com.google.gerrit.extensions.webui.DiffWebLink;
@@ -365,7 +364,6 @@ public class GerritGlobalModule extends FactoryModule {
DynamicItem.itemOf(binder(), AvatarProvider.class);
DynamicSet.setOf(binder(), LifecycleListener.class);
DynamicSet.setOf(binder(), TopMenu.class);
DynamicSet.setOf(binder(), MessageOfTheDay.class);
DynamicMap.mapOf(binder(), DownloadScheme.class);
DynamicMap.mapOf(binder(), DownloadCommand.class);
DynamicMap.mapOf(binder(), CloneCommand.class);

View File

@@ -126,8 +126,8 @@ public class GetSummary implements RestReadView<ConfigResource> {
long mTotal = r.totalMemory();
long mInuse = mTotal - mFree;
int jgitOpen = WindowCacheStats.getOpenFiles();
long jgitBytes = WindowCacheStats.getOpenBytes();
long jgitOpen = WindowCacheStats.getStats().getOpenFileCount();
long jgitBytes = WindowCacheStats.getStats().getOpenByteCount();
MemSummaryInfo memSummaryInfo = new MemSummaryInfo();
memSummaryInfo.total = bytes(mTotal);
@@ -135,7 +135,7 @@ public class GetSummary implements RestReadView<ConfigResource> {
memSummaryInfo.free = bytes(mFree);
memSummaryInfo.buffers = bytes(jgitBytes);
memSummaryInfo.max = bytes(mMax);
memSummaryInfo.openFiles = toInteger(jgitOpen);
memSummaryInfo.openFiles = Long.valueOf(jgitOpen);
return memSummaryInfo;
}
@@ -258,7 +258,7 @@ public class GetSummary implements RestReadView<ConfigResource> {
public String free;
public String buffers;
public String max;
public Integer openFiles;
public Long openFiles;
}
public static class ThreadSummaryInfo {

View File

@@ -297,6 +297,10 @@ final class ShowCaches extends SshCommand {
return i != null ? i : 0;
}
private static long nullToZero(Long i) {
return i != null ? i : 0;
}
private void sshSummary() {
IoAcceptor acceptor = daemon.getIoAcceptor();
if (acceptor == null) {

View File

@@ -57,7 +57,6 @@ 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.entities.Account;
import com.google.gerrit.entities.BooleanProjectConfig;
import com.google.gerrit.entities.BranchNameKey;
import com.google.gerrit.entities.Change;
import com.google.gerrit.entities.PatchSet;
@@ -645,14 +644,7 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
// |
// C0 -- Master
//
try (ProjectConfigUpdate u = updateProject(project)) {
u.getConfig()
.getProject()
.setBooleanConfig(
BooleanProjectConfig.CREATE_NEW_CHANGE_FOR_ALL_NOT_IN_TARGET,
InheritableBoolean.TRUE);
u.save();
}
enableCreateNewChangeForAllNotInTarget();
PushOneCommit push1 =
pushFactory.create(admin.newIdent(), testRepo, PushOneCommit.SUBJECT, "a.txt", "content");