CreateChangesTriggeringGc: Support existing project

Add a CreateChangesTriggeringGcWithProject scenario that wraps the
CreateChangesTriggeringGc scenario. Do so for the latter to run without
creating its own project anymore. This way, have a scenario that creates
its own project (and deletes it after) still, plus one that doesn't.

This is so that it becomes possible to run the CreateChangesTriggeringGc
scenario with a pre-configured test project. Say, for jgit client
testing purposes in gc-executor, such as changing core.trustfolderstat
and comparing the resulting gc completion times. Local testing showed
roughly doubling gc completion times when changing trustfolderstat to
false, for example.

For the CheckProjectStatisticsUpToGc scenario step to end up reporting
OKs in that trustfolderstat=false case, double its allotted
MaxSecondsForGcToComplete time. This only makes the step or scenario
last 10 seconds longer in other cases.

Make some CreateChangesTriggeringGc fields accessible from a so reusing
scenario, here by CreateChangesTriggeringGcWithProject.

Make CreateChangesTriggeringGc a ProjectSimulation, now that its test
PROJECT name comes either from the aggregating scenario or the execution
environment. Before this change, that project name was automatically
generated, i.e., set to that scenario's class name by default.

Change-Id: I035e32e52fec85b21699a6963be392e5a3639d27
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
index c267ab3..b4ee549 100644
--- a/src/test/resources/com/ericsson/gerrit/plugins/gcconductor/scenarios/CreateChangesTriggeringGc.json
+++ b/src/test/resources/com/ericsson/gerrit/plugins/gcconductor/scenarios/CreateChangesTriggeringGc.json
@@ -1,6 +1,6 @@
 [
   {
     "url": "http://HOSTNAME:HTTP_PORT/a/changes/",
-    "project": "_PROJECT"
+    "project": "PROJECT"
   }
 ]
diff --git a/src/test/scala/com/ericsson/gerrit/plugins/gcconductor/scenarios/CheckProjectStatisticsUpToGc.scala b/src/test/scala/com/ericsson/gerrit/plugins/gcconductor/scenarios/CheckProjectStatisticsUpToGc.scala
index ea02a32..2487a85 100644
--- a/src/test/scala/com/ericsson/gerrit/plugins/gcconductor/scenarios/CheckProjectStatisticsUpToGc.scala
+++ b/src/test/scala/com/ericsson/gerrit/plugins/gcconductor/scenarios/CheckProjectStatisticsUpToGc.scala
@@ -24,7 +24,7 @@
 
 class CheckProjectStatisticsUpToGc extends ProjectSimulation {
   private val data: FeederBuilder = jsonFile(resource).convert(keys).circular
-  lazy val MaxSecondsForGcToComplete = 10
+  lazy val MaxSecondsForGcToComplete = 20
   val ChecksPerSecond = 4
 
   override def relativeRuntimeWeight: Int = MaxSecondsForGcToComplete / SecondsPerWeightUnit
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
index 393397c..404df73 100644
--- a/src/test/scala/com/ericsson/gerrit/plugins/gcconductor/scenarios/CreateChangesTriggeringGc.scala
+++ b/src/test/scala/com/ericsson/gerrit/plugins/gcconductor/scenarios/CreateChangesTriggeringGc.scala
@@ -22,26 +22,31 @@
 
 import scala.concurrent.duration._
 
-class CreateChangesTriggeringGc extends GerritSimulation {
+class CreateChangesTriggeringGc extends ProjectSimulation {
   private val data: FeederBuilder = jsonFile(resource).convert(keys).circular
-  private val default: String = name
   private val numberKey = "_number"
 
-  private lazy val DefaultSecondsToNextEvaluation = 60
+  lazy val DefaultSecondsToNextEvaluation = 60
   private lazy val DefaultLooseObjectsToEnqueueGc = 400
   private lazy val LooseObjectsPerChange = 2
   private lazy val ChangesMultiplier = 8
-  private lazy val changesPerSecond = 4 * ChangesMultiplier
-  private val ChangesForLastEvaluation = 1
+  lazy val changesPerSecond: Int = 4 * ChangesMultiplier
+  val ChangesForLastEvaluation = 1
 
-  private lazy val secondsForLastEvaluation = SecondsPerWeightUnit
+  lazy val secondsForLastEvaluation: Int = SecondsPerWeightUnit
   private lazy val changesToEnqueueGc = DefaultLooseObjectsToEnqueueGc * ChangesMultiplier / LooseObjectsPerChange
-  private lazy val secondsToChanges = changesToEnqueueGc / changesPerSecond
+  lazy val secondsToChanges: Int = changesToEnqueueGc / changesPerSecond
   private lazy val maxSecondsToEnqueueGc = secondsToChanges + DefaultSecondsToNextEvaluation + secondsForLastEvaluation
 
   override def relativeRuntimeWeight: Int = maxSecondsToEnqueueGc / SecondsPerWeightUnit
 
-  private val test: ScenarioBuilder = scenario(unique)
+  def this(default: String, deleteChanges: DeleteChangesAfterGc) {
+    this()
+    this.default = default
+    this.deleteChanges = deleteChanges
+  }
+
+  val test: ScenarioBuilder = scenario(unique)
     .feed(data)
     .exec(httpRequest
       .body(ElFileBody(body)).asJson
@@ -51,16 +56,10 @@
       session
     })
 
-  private val createProject = new CreateProject(default)
   private val checkStatsUpToGc = new CheckProjectStatisticsUpToGc(default)
-  private val deleteChanges = new DeleteChangesAfterGc
-  private val deleteProject = new DeleteProject(default)
+  private var deleteChanges = new DeleteChangesAfterGc
 
   setUp(
-    createProject.test.inject(
-      nothingFor(stepWaitTime(createProject) seconds),
-      atOnceUsers(1)
-    ),
     test.inject(
       nothingFor(stepWaitTime(this) seconds),
       constantUsersPerSec(changesPerSecond) during (secondsToChanges seconds),
@@ -78,9 +77,5 @@
       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/CreateChangesTriggeringGcWithProject.scala b/src/test/scala/com/ericsson/gerrit/plugins/gcconductor/scenarios/CreateChangesTriggeringGcWithProject.scala
new file mode 100644
index 0000000..a6d5f63
--- /dev/null
+++ b/src/test/scala/com/ericsson/gerrit/plugins/gcconductor/scenarios/CreateChangesTriggeringGcWithProject.scala
@@ -0,0 +1,57 @@
+// 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 scala.concurrent.duration._
+
+class CreateChangesTriggeringGcWithProject extends GerritSimulation {
+  private val default: String = name
+
+  private val createProject = new CreateProject(default)
+  private val deleteChanges = new DeleteChangesAfterGc
+  private val createChanges = new CreateChangesTriggeringGc(default, deleteChanges)
+  private val checkStatsUpToGc = new CheckProjectStatisticsUpToGc(default)
+  private val deleteProject = new DeleteProject(default)
+
+  setUp(
+    createProject.test.inject(
+      nothingFor(stepWaitTime(createProject) seconds),
+      atOnceUsers(1)
+    ),
+    createChanges.test.inject(
+      nothingFor(stepWaitTime(createChanges) seconds),
+      constantUsersPerSec(createChanges.changesPerSecond) during (createChanges.secondsToChanges seconds),
+      nothingFor(createChanges.DefaultSecondsToNextEvaluation seconds),
+      nothingFor(createChanges.secondsForLastEvaluation / 2 seconds),
+      atOnceUsers(createChanges.ChangesForLastEvaluation)
+    ),
+    checkStatsUpToGc.test.inject(
+      nothingFor(stepWaitTime(checkStatsUpToGc) seconds),
+      constantUsersPerSec(checkStatsUpToGc.ChecksPerSecond) during (checkStatsUpToGc.MaxSecondsForGcToComplete seconds)
+    ),
+    deleteChanges.test.inject(
+      nothingFor(stepWaitTime(deleteChanges) seconds),
+      constantUsersPerSec(createChanges.changesPerSecond) during (createChanges.secondsToChanges seconds),
+      atOnceUsers(createChanges.ChangesForLastEvaluation)
+    ),
+    deleteProject.test.inject(
+      nothingFor(stepWaitTime(deleteProject) seconds),
+      atOnceUsers(1)
+    ),
+  ).protocols(httpProtocol)
+}