Merge branch 'stable-2.15' into stable-2.16

* stable-2.15:
  Update log4j2 version to 2.17.0
  Update log4j2 version to 2.16.0 to fix CVE-2021-44228


Change-Id: Id6f7e2cefd185136464180f685bbbe6d6a0e4cd4
diff --git a/.bazelversion b/.bazelversion
index 9084fa2..fd2a018 100644
--- a/.bazelversion
+++ b/.bazelversion
@@ -1 +1 @@
-1.1.0
+3.1.0
diff --git a/.gitignore b/.gitignore
index 78857a0..4e7cb7d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,12 @@
+# LC_COLLATE=C sort
+/.apt_generated/
 /.classpath
 /.primary_build_tool
 /.project
 /.settings/
 /bazel-*
+/bin/gc-executor-pid
 /eclipse-out/
-/.apt_generated/
+/gc-executor.jar
+/gc.config
+/startup.log
diff --git a/BUILD b/BUILD
index cb02518..5ddfab4 100644
--- a/BUILD
+++ b/BUILD
@@ -7,26 +7,23 @@
     "gerrit_plugin",
 )
 
-CONDUCTOR_DEPS = [
-    "@postgresql//jar",
+EXECUTOR_DEPS = [
+    "@aopalliance//jar",
     "@dbcp//jar",
-    "@pool//jar",
-]
-
-EXECUTOR_DEPS = CONDUCTOR_DEPS + [
-    "@jgit//jar",
-    "@javaewah//jar",
     "@guava//jar",
     "@guice//jar",
     "@guice-assistedinject//jar",
+    "@javaewah//jar",
     "@javax_inject//jar",
-    "@aopalliance//jar",
-    "@slf4j-api//jar",
-    "@slf4j-ext//jar",
-    "@log4j-slf4j-impl//jar",
+    "@jgit//jar",
     "@log4j-api//jar",
     "@log4j-core//jar",
+    "@log4j-slf4j-impl//jar",
+    "@pool//jar",
+    "@postgresql//jar",
     "@retry//jar",
+    "@slf4j-api//jar",
+    "@slf4j-ext//jar",
 ]
 
 gerrit_plugin(
@@ -47,7 +44,6 @@
         ["src/main/resources/**/*"],
         exclude = ["src/main/resources/log4j2.xml"],
     ),
-    deps = CONDUCTOR_DEPS,
 )
 
 java_library(
@@ -91,7 +87,10 @@
         ":gc-conductor__plugin",
         ":gc-executor_lib",
         "@byte-buddy//jar",
+        "@docker-java-api//jar",
+        "@docker-java-transport//jar",
         "@duct_tape//jar",
+        "@jackson-annotations//jar",
         "@jna//jar",
         "@mockito//jar",
         "@objenesis//jar",
diff --git a/WORKSPACE b/WORKSPACE
index e9bd838..0c20233 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,7 @@
 load("//:bazlets.bzl", "load_bazlets")
 
 load_bazlets(
-    commit = "9af263722b7eafe99af079d6ef7cf1de23e6f8d7",
+    commit = "6c39deb06f58bb62162ccb6865964f531739f512",
     #local_path = "/home/<user>/projects/bazlets",
 )
 
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl
index 7d9fdd6..db6208b 100644
--- a/external_plugin_deps.bzl
+++ b/external_plugin_deps.bzl
@@ -28,8 +28,8 @@
 
     maven_jar(
         name = "duct_tape",
-        artifact = "org.rnorth.duct-tape:duct-tape:1.0.7",
-        sha1 = "a26b5d90d88c91321dc7a3734ea72d2fc019ebb6",
+        artifact = "org.rnorth.duct-tape:duct-tape:1.0.8",
+        sha1 = "92edc22a9ab2f3e17c9bf700aaee377d50e8b530",
     )
 
     maven_jar(
@@ -38,18 +38,18 @@
         sha1 = "639033469776fd37c08358c6b92a4761feb2af4b",
     )
 
-    SLF4J_VERS = "1.7.26"
+    SLF4J_VERS = "1.7.30"
 
     maven_jar(
         name = "slf4j-api",
         artifact = "org.slf4j:slf4j-api:" + SLF4J_VERS,
-        sha1 = "77100a62c2e6f04b53977b9f541044d7d722693d",
+        sha1 = "b5a4b6d16ab13e34a88fae84c35cd5d68cac922c",
     )
 
     maven_jar(
         name = "slf4j-ext",
         artifact = "org.slf4j:slf4j-ext:" + SLF4J_VERS,
-        sha1 = "31cdf122e000322e9efcb38913e9ab07825b17ef",
+        sha1 = "595d5dabfeb29244b8c91776898cee78299080d5",
     )
 
     LOG4J2_VERS = "2.17.0"
@@ -74,8 +74,8 @@
 
     maven_jar(
         name = "postgresql",
-        artifact = "org.postgresql:postgresql:42.2.4",
-        sha1 = "dff98730c28a4b3a3263f0cf4abb9a3392f815a7",
+        artifact = "org.postgresql:postgresql:42.2.5",
+        sha1 = "951b7eda125f3137538a94e2cbdcf744088ad4c2",
     )
 
     maven_jar(
@@ -92,22 +92,22 @@
 
     maven_jar(
         name = "guava",
-        artifact = "com.google.guava:guava:25.1-jre",
-        sha1 = "6c57e4b22b44e89e548b5c9f70f0c45fe10fb0b4",
+        artifact = "com.google.guava:guava:26.0-jre",
+        sha1 = "6a806eff209f36f635f943e16d97491f00f6bfab",
     )
 
-    GUICE_VERS = "4.2.0"
+    GUICE_VERS = "4.2.1"
 
     maven_jar(
         name = "guice",
         artifact = "com.google.inject:guice:" + GUICE_VERS,
-        sha1 = "25e1f4c1d528a1cffabcca0d432f634f3132f6c8",
+        sha1 = "f77dfd89318fe3ff293bafceaa75fbf66e4e4b10",
     )
 
     maven_jar(
         name = "guice-assistedinject",
         artifact = "com.google.inject.extensions:guice-assistedinject:" + GUICE_VERS,
-        sha1 = "e7270305960ad7db56f7e30cb9df6be9ff1cfb45",
+        sha1 = "d327e4aee7c96f08cd657c17da231a1f4a8999ac",
     )
 
     maven_jar(
@@ -125,8 +125,8 @@
     maven_jar(
         name = "jgit",
         artifact =
-            "org.eclipse.jgit:org.eclipse.jgit:4.11.9.201909030838-r",
-        sha1 = "3bc74ffed6186bf2fc37404216e5ef16f904d0b0",
+            "org.eclipse.jgit:org.eclipse.jgit:5.1.16.202106041830-r",
+        sha1 = "1b32273b9b8326a14355374702799b6cd4a94050",
     )
 
     maven_jar(
@@ -149,32 +149,54 @@
 
     maven_jar(
         name = "jna",
-        artifact = "net.java.dev.jna:jna:5.2.0",
-        sha1 = "ed8b772eb077a9cb50e44e90899c66a9a6c00e67",
+        artifact = "net.java.dev.jna:jna:5.5.0",
+        sha1 = "0e0845217c4907822403912ad6828d8e0b256208",
     )
 
-    TESTCONTAINERS_VERS = "1.12.3"
+    DOCKER_JAVA_VERS = "3.2.5"
+
+    maven_jar(
+        name = "docker-java-api",
+        artifact = "com.github.docker-java:docker-java-api:" + DOCKER_JAVA_VERS,
+        sha1 = "8fe5c5e39f940ce58620e77cedc0a2a52d76f9d8",
+    )
+
+    maven_jar(
+        name = "docker-java-transport",
+        artifact = "com.github.docker-java:docker-java-transport:" + DOCKER_JAVA_VERS,
+        sha1 = "27af0ee7ebc2f5672e23ea64769497b5d55ce3ac",
+    )
+
+    # https://github.com/docker-java/docker-java/blob/3.2.5/pom.xml#L61
+    # <=> DOCKER_JAVA_VERS
+    maven_jar(
+        name = "jackson-annotations",
+        artifact = "com.fasterxml.jackson.core:jackson-annotations:2.10.3",
+        sha1 = "0f63b3b1da563767d04d2e4d3fc1ae0cdeffebe7",
+    )
+
+    TESTCONTAINERS_VERS = "1.15.0"
 
     maven_jar(
         name = "testcontainers",
         artifact = "org.testcontainers:testcontainers:" + TESTCONTAINERS_VERS,
-        sha1 = "e424a4549640e120acceac641ac909fcda58bf62",
+        sha1 = "b627535b444d88e7b14953bb953d80d9b7b3bd76",
     )
 
     maven_jar(
         name = "testcontainers-database-commons",
         artifact = "org.testcontainers:database-commons:" + TESTCONTAINERS_VERS,
-        sha1 = "69a857af8c90be1f2ba6d7f70a59bd5687854e8f",
+        sha1 = "bc52637643da33f8fadfb6220cb59a7d8da37325",
     )
 
     maven_jar(
         name = "testcontainers-jdbc",
         artifact = "org.testcontainers:jdbc:" + TESTCONTAINERS_VERS,
-        sha1 = "8f86e3ebf31b3a0439ba537bba770b5be219b55b",
+        sha1 = "3626ed0746c94b337b1872afa90331bf9e2e6e16",
     )
 
     maven_jar(
         name = "testcontainers-postgres",
         artifact = "org.testcontainers:postgresql:" + TESTCONTAINERS_VERS,
-        sha1 = "946fc6dc021b0b760da3fd005d2fd871fce10be4",
+        sha1 = "25daf6c0dd1d52e4a1b899c5b3e07b71d382c7ba",
     )
diff --git a/src/main/java/com/ericsson/gerrit/plugins/gcconductor/EvaluationTask.java b/src/main/java/com/ericsson/gerrit/plugins/gcconductor/EvaluationTask.java
index e8aba71..43803e4 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/gcconductor/EvaluationTask.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/gcconductor/EvaluationTask.java
@@ -197,7 +197,7 @@
 
   private Collection<Ref> getAllRefs(FileRepository repo) throws IOException {
     RefDatabase refdb = repo.getRefDatabase();
-    Collection<Ref> refs = refdb.getRefs(RefDatabase.ALL).values();
+    Collection<Ref> refs = refdb.getRefs();
     List<Ref> addl = refdb.getAdditionalRefs();
     if (!addl.isEmpty()) {
       List<Ref> all = new ArrayList<>(refs.size() + addl.size());
diff --git a/src/main/java/com/ericsson/gerrit/plugins/gcconductor/command/ShowQueue.java b/src/main/java/com/ericsson/gerrit/plugins/gcconductor/command/ShowQueue.java
index fe41af0..4cd7417 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/gcconductor/command/ShowQueue.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/gcconductor/command/ShowQueue.java
@@ -19,9 +19,9 @@
 import com.ericsson.gerrit.plugins.gcconductor.GcQueue;
 import com.ericsson.gerrit.plugins.gcconductor.RepositoryInfo;
 import com.google.common.base.Strings;
-import com.google.gerrit.common.TimeUtil;
 import com.google.gerrit.common.data.GlobalCapability;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
+import com.google.gerrit.server.util.time.TimeUtil;
 import com.google.gerrit.sshd.AdminHighPriorityCommand;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
diff --git a/src/main/java/com/ericsson/gerrit/plugins/gcconductor/evaluator/Evaluator.java b/src/main/java/com/ericsson/gerrit/plugins/gcconductor/evaluator/Evaluator.java
index 5ae7fac..eda5f96 100644
--- a/src/main/java/com/ericsson/gerrit/plugins/gcconductor/evaluator/Evaluator.java
+++ b/src/main/java/com/ericsson/gerrit/plugins/gcconductor/evaluator/Evaluator.java
@@ -31,8 +31,8 @@
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
 import org.eclipse.jgit.errors.RepositoryNotFoundException;
 import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.ObjectId;
@@ -48,7 +48,7 @@
   private static final Logger log = LoggerFactory.getLogger(Evaluator.class);
   private static final ThreadLocal<String> uploadRepositoryPath = new ThreadLocal<String>() {};
 
-  private final ScheduledThreadPoolExecutor executor;
+  private final ExecutorService executor;
   private final EvaluationTask.Factory evaluationTaskFactory;
   private final GitRepositoryManager repoManager;
   private final Map<String, Long> timestamps;
@@ -59,7 +59,7 @@
 
   @Inject
   Evaluator(
-      @EvaluatorExecutor ScheduledThreadPoolExecutor executor,
+      @EvaluatorExecutor ExecutorService executor,
       EvaluationTask.Factory evaluationTaskFactory,
       GitRepositoryManager repoManager,
       EvaluatorConfig config,
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md
index e0049aa..4f2a958 100644
--- a/src/main/resources/Documentation/config.md
+++ b/src/main/resources/Documentation/config.md
@@ -52,7 +52,7 @@
 The configuration can be passed to the gc executor jar by using:
 
 ```
-  java -DconfigFile=/path/to/config_file.config -jar executor.jar
+  java -DconfigFile=/path/to/gc.config -jar gc-executor.jar
 ```
 
 ### File `gc.config`
@@ -62,7 +62,6 @@
 file is modified, gc executor needs to be restarted in order to be able to use the
 new values.
 
-
 #### Sample `gc.config`:
 
 ```
@@ -73,6 +72,7 @@
   javaOptions = -Xmx32g
   javaOptions = -XX:+UseG1GC
   javaOptions = -XX:MaxGCPauseMillis=2000
+
 [core]
   executors = 2
   pickOwnHostOnly = false
@@ -178,10 +178,10 @@
 
 ### GC execution
 
-Executors can be started/stopped using gcctl.sh script.
+Executors can be started/stopped using the gc_ctl script.
 
 ```
-  /opt/gerrit/gc-conductor/gcctl.sh {start|stop|restart|status|check}
+  /opt/gerrit/gc-conductor/bin/gc_ctl {start|stop|restart|status|check}
 ```
 
 [Back to @PLUGIN@ documentation index][index]
diff --git a/src/test/README.md b/src/test/README.md
new file mode 100644
index 0000000..885522e
--- /dev/null
+++ b/src/test/README.md
@@ -0,0 +1,27 @@
+# About this directory structure
+
+```bash
+  ./resources/com
+  ./scala
+```
+
+To start using the files under these directories above, consider the
+[instructions](https://gerrit-documentation.storage.googleapis.com/Documentation/2.16.19/dev-e2e-tests.html)
+on how to use Gerrit core's Gatling framework. These are about running
+non-core test scenarios such as this plugin one below:
+
+```bash
+  sbt "gatling:testOnly com.ericsson.gerrit.plugins.gcconductor.scenarios.CreateChangesTriggeringGc"
+
+```
+
+This is a scenario that can serve as an example for how to start testing
+this plugin, along with its executor component. Both of these components
+should be locally installed along with default configuration. Plugin's
+gc-executor component is assumed to be running alongside Gerrit.
+
+Scenario scala source files and their companion json resource ones are
+stored under the usual src/test directories. That structure follows the
+scala package one from the scenario classes. The core framework expects
+such a directory structure for both the scala and resources (json data)
+files.
diff --git a/src/test/java/com/ericsson/gerrit/plugins/gcconductor/evaluator/EvaluatorTest.java b/src/test/java/com/ericsson/gerrit/plugins/gcconductor/evaluator/EvaluatorTest.java
index 7dc403b..c51d2a8 100644
--- a/src/test/java/com/ericsson/gerrit/plugins/gcconductor/evaluator/EvaluatorTest.java
+++ b/src/test/java/com/ericsson/gerrit/plugins/gcconductor/evaluator/EvaluatorTest.java
@@ -29,7 +29,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ExecutorService;
 import org.eclipse.jgit.errors.RepositoryNotFoundException;
 import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.Repository;
@@ -49,7 +49,7 @@
   @Mock private GitRepositoryManager repoManager;
   @Mock private Repository repository;
   @Mock private Repository repositoryOther;
-  @Mock private ScheduledThreadPoolExecutor executor;
+  @Mock private ExecutorService executor;
   @Mock private EvaluatorConfig config;
   @Mock private Config gerritConfig;
 
diff --git a/src/test/resources/com/ericsson/gerrit/plugins/gcconductor/scenarios/CheckProjectStatisticsAfterGc.json b/src/test/resources/com/ericsson/gerrit/plugins/gcconductor/scenarios/CheckProjectStatisticsAfterGc.json
new file mode 100644
index 0000000..e9df002
--- /dev/null
+++ b/src/test/resources/com/ericsson/gerrit/plugins/gcconductor/scenarios/CheckProjectStatisticsAfterGc.json
@@ -0,0 +1,5 @@
+[
+  {
+    "url": "http://HOSTNAME:HTTP_PORT/a/projects/PROJECT/statistics.git"
+  }
+]
diff --git a/src/test/resources/com/ericsson/gerrit/plugins/gcconductor/scenarios/CreateChangesTriggeringGc-body.json b/src/test/resources/com/ericsson/gerrit/plugins/gcconductor/scenarios/CreateChangesTriggeringGc-body.json
new file mode 100644
index 0000000..23bf26c
--- /dev/null
+++ b/src/test/resources/com/ericsson/gerrit/plugins/gcconductor/scenarios/CreateChangesTriggeringGc-body.json
@@ -0,0 +1,5 @@
+{
+  "project": "${project}",
+  "branch": "master",
+  "subject": "Change"
+}
diff --git a/src/test/resources/com/ericsson/gerrit/plugins/gcconductor/scenarios/CreateChangesTriggeringGc.json b/src/test/resources/com/ericsson/gerrit/plugins/gcconductor/scenarios/CreateChangesTriggeringGc.json
new file mode 100644
index 0000000..c267ab3
--- /dev/null
+++ b/src/test/resources/com/ericsson/gerrit/plugins/gcconductor/scenarios/CreateChangesTriggeringGc.json
@@ -0,0 +1,6 @@
+[
+  {
+    "url": "http://HOSTNAME:HTTP_PORT/a/changes/",
+    "project": "_PROJECT"
+  }
+]
diff --git a/src/test/resources/com/ericsson/gerrit/plugins/gcconductor/scenarios/DeleteChangesAfterGc.json b/src/test/resources/com/ericsson/gerrit/plugins/gcconductor/scenarios/DeleteChangesAfterGc.json
new file mode 100644
index 0000000..a371757
--- /dev/null
+++ b/src/test/resources/com/ericsson/gerrit/plugins/gcconductor/scenarios/DeleteChangesAfterGc.json
@@ -0,0 +1,5 @@
+[
+  {
+    "url": "http://HOSTNAME:HTTP_PORT/a/changes/"
+  }
+]
diff --git a/src/test/resources/log4j2.xml b/src/test/resources/log4j2.xml
index 7ee8d38..7f63ec5 100644
--- a/src/test/resources/log4j2.xml
+++ b/src/test/resources/log4j2.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Configuration status="WARN" shutdownHook="disable">
 	<Properties>
-		<Property name="log.path">opt/gerrit/review_site/logs/gc</Property>
+		<Property name="log.path">/opt/gerrit/review_site/logs/gc</Property>
 	</Properties>
 	<Appenders>
 		<RollingFile name="RollingFile" fileName="${log.path}/gc.log"
diff --git a/src/test/scala/com/ericsson/gerrit/plugins/gcconductor/scenarios/CheckProjectStatisticsAfterGc.scala b/src/test/scala/com/ericsson/gerrit/plugins/gcconductor/scenarios/CheckProjectStatisticsAfterGc.scala
new file mode 100644
index 0000000..fa43e22
--- /dev/null
+++ b/src/test/scala/com/ericsson/gerrit/plugins/gcconductor/scenarios/CheckProjectStatisticsAfterGc.scala
@@ -0,0 +1,41 @@
+// Copyright (C) 2020 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.ericsson.gerrit.plugins.gcconductor.scenarios
+
+import com.google.gerrit.scenarios.ProjectSimulation
+import io.gatling.core.Predef._
+import io.gatling.core.feeder.FeederBuilder
+import io.gatling.core.structure.ScenarioBuilder
+import io.gatling.http.Predef._
+
+class CheckProjectStatisticsAfterGc extends ProjectSimulation {
+  private val data: FeederBuilder = jsonFile(resource).convert(keys).queue
+
+  def this(default: String) {
+    this()
+    this.default = default
+  }
+
+  val test: ScenarioBuilder = scenario(unique)
+    .feed(data)
+    .exec(http(unique).get("${url}")
+      .check(regex("\"number_of_loose_objects\": (\\d+),")
+        .is("0")))
+
+  setUp(
+    test.inject(
+      atOnceUsers(1)
+    )).protocols(httpProtocol)
+}
diff --git a/src/test/scala/com/ericsson/gerrit/plugins/gcconductor/scenarios/CreateChangesTriggeringGc.scala b/src/test/scala/com/ericsson/gerrit/plugins/gcconductor/scenarios/CreateChangesTriggeringGc.scala
new file mode 100644
index 0000000..a61b376
--- /dev/null
+++ b/src/test/scala/com/ericsson/gerrit/plugins/gcconductor/scenarios/CreateChangesTriggeringGc.scala
@@ -0,0 +1,88 @@
+// Copyright (C) 2020 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.ericsson.gerrit.plugins.gcconductor.scenarios
+
+import com.google.gerrit.scenarios._
+import io.gatling.core.Predef.{atOnceUsers, nothingFor, _}
+import io.gatling.core.feeder.FeederBuilder
+import io.gatling.core.structure.ScenarioBuilder
+import io.gatling.http.Predef._
+
+import scala.concurrent.duration._
+
+class CreateChangesTriggeringGc extends GerritSimulation {
+  private val data: FeederBuilder = jsonFile(resource).convert(keys).circular
+  private val default: String = name
+  private val numberKey = "_number"
+
+  private lazy val DefaultSecondsToNextEvaluation = 60
+  private lazy val DefaultSecondsToNextGcDequeue = 60
+  private lazy val DefaultLooseObjectsToEnqueueGc = 400
+  private lazy val LooseObjectsPerChange = 2
+  private lazy val ChangesPerSecond = 4
+  private val ChangesForLastEvaluation = 1
+
+  private lazy val secondsForLastEvaluation = SecondsPerWeightUnit * 2
+  private lazy val secondsForLastGcExecution = secondsForLastEvaluation * 2
+  private lazy val changesToEnqueueGc = DefaultLooseObjectsToEnqueueGc / LooseObjectsPerChange
+  private lazy val secondsToChanges = changesToEnqueueGc / ChangesPerSecond
+  private lazy val maxSecondsToEnqueueGc = secondsToChanges + DefaultSecondsToNextEvaluation + secondsForLastEvaluation
+  private lazy val maxSecondsToExecuteGc = maxSecondsToEnqueueGc + DefaultSecondsToNextGcDequeue + secondsForLastGcExecution
+
+  override def relativeRuntimeWeight: Int = maxSecondsToExecuteGc / SecondsPerWeightUnit
+
+  private val test: ScenarioBuilder = scenario(unique)
+    .feed(data)
+    .exec(httpRequest
+      .body(ElFileBody(body)).asJson
+      .check(regex("\"" + numberKey + "\":(\\d+),").saveAs(numberKey)))
+    .exec(session => {
+      deleteChanges.upToNumber = session(numberKey).as[Int]
+      session
+    })
+
+  private val createProject = new CreateProject(default)
+  private val checkStatsAfterGc = new CheckProjectStatisticsAfterGc(default)
+  private val deleteChanges = new DeleteChangesAfterGc
+  private val deleteProject = new DeleteProject(default)
+
+  setUp(
+    createProject.test.inject(
+      nothingFor(stepWaitTime(createProject) seconds),
+      atOnceUsers(1)
+    ),
+    test.inject(
+      nothingFor(stepWaitTime(this) seconds),
+      constantUsersPerSec(ChangesPerSecond) during (secondsToChanges seconds),
+      nothingFor(DefaultSecondsToNextEvaluation seconds),
+      nothingFor(secondsForLastEvaluation / 2 seconds),
+      atOnceUsers(ChangesForLastEvaluation),
+      nothingFor(secondsForLastEvaluation / 2 seconds)
+    ),
+    checkStatsAfterGc.test.inject(
+      nothingFor(stepWaitTime(checkStatsAfterGc) seconds),
+      atOnceUsers(1)
+    ),
+    deleteChanges.test.inject(
+      nothingFor(stepWaitTime(deleteChanges) seconds),
+      constantUsersPerSec(ChangesPerSecond) during (secondsToChanges seconds),
+      atOnceUsers(ChangesForLastEvaluation)
+    ),
+    deleteProject.test.inject(
+      nothingFor(stepWaitTime(deleteProject) seconds),
+      atOnceUsers(1)
+    ),
+  ).protocols(httpProtocol)
+}
diff --git a/src/test/scala/com/ericsson/gerrit/plugins/gcconductor/scenarios/DeleteChangesAfterGc.scala b/src/test/scala/com/ericsson/gerrit/plugins/gcconductor/scenarios/DeleteChangesAfterGc.scala
new file mode 100644
index 0000000..d72f635
--- /dev/null
+++ b/src/test/scala/com/ericsson/gerrit/plugins/gcconductor/scenarios/DeleteChangesAfterGc.scala
@@ -0,0 +1,42 @@
+// Copyright (C) 2020 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.ericsson.gerrit.plugins.gcconductor.scenarios
+
+import com.google.gerrit.scenarios.GerritSimulation
+import io.gatling.core.Predef._
+import io.gatling.core.feeder.FeederBuilder
+import io.gatling.core.structure.ScenarioBuilder
+import io.gatling.http.Predef.http
+
+class DeleteChangesAfterGc extends GerritSimulation {
+  private val data: FeederBuilder = jsonFile(resource).convert(keys).circular
+  private val numberKey = "number"
+  var upToNumber = 1
+
+  private lazy val OrderOfChangesToDelete = 200
+  private lazy val PerSecond = 4
+  private lazy val secondsToDeleted = OrderOfChangesToDelete / PerSecond
+
+  override def relativeRuntimeWeight: Int = (secondsToDeleted + SecondsPerWeightUnit) / SecondsPerWeightUnit
+
+  val test: ScenarioBuilder = scenario(unique)
+    .feed(data)
+    .exec(session => {
+      val numbered: Session = session.set(numberKey, upToNumber)
+      upToNumber -= 1
+      numbered
+    })
+    .exec(http(unique).delete("${url}${" + numberKey + "}"))
+}
diff --git a/tools/BUILD b/tools/BUILD
new file mode 100644
index 0000000..1fa2160
--- /dev/null
+++ b/tools/BUILD
@@ -0,0 +1 @@
+# Empty file - bazel treat directories with BUILD file as a package
\ No newline at end of file