e2e-tests: Add FlushProjectsCache related scenarios

Add a FlushProjectsCache scenario to this core framework. Make it reuse
the added GetProjectsCacheEntries and CheckProjectsCacheFlushEntries
scenarios, which can also be run independently as usual. Make all these
added scenarios extend the introduced CacheFlushSimulation core class,
for consistency and further reusability purposes.

In order for CheckProjectsCacheFlushEntries to run independently, as
opposed to otherwise being composed, introduce the PROJECTS_ENTRIES
optional JAVA_OPTS property ([1]). Default that value to 1, based on the
initial projects cache cardinality showed by locally testing this case.

[1] https://gerrit-review.googlesource.com/Documentation/dev-e2e-tests.html#_environment_properties

Change-Id: Ic5b6554332730763b538767d4946787d37baa9c1
This commit is contained in:
Marco Miller
2020-05-04 13:30:33 -04:00
parent 262bc75266
commit d54dfb17ef
8 changed files with 203 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
[
{
"url": "http://HOSTNAME:HTTP_PORT/a/config/server/caches/projects",
"entries": "PROJECTS_ENTRIES"
}
]

View File

@@ -0,0 +1,5 @@
[
{
"url": "http://HOSTNAME:HTTP_PORT/a/config/server/caches/projects/flush"
}
]

View File

@@ -0,0 +1,5 @@
[
{
"url": "http://HOSTNAME:HTTP_PORT/a/config/server/caches/projects"
}
]

View File

@@ -0,0 +1,32 @@
// 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.google.gerrit.scenarios
class CacheFlushSimulation extends GerritSimulation {
protected val entriesKey = "entries"
protected val memKey = "mem"
protected var producer: Option[CacheFlushSimulation] = None
protected var consumer: Option[CacheFlushSimulation] = None
private var cacheEntriesBeforeFlush: Int = 0
def entriesBeforeFlush(entries: Int): Unit = {
cacheEntriesBeforeFlush = entries
}
def expectedEntriesAfterFlush(): Int = {
cacheEntriesBeforeFlush - 1
}
}

View File

@@ -0,0 +1,48 @@
// 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.google.gerrit.scenarios
import io.gatling.core.Predef.{atOnceUsers, _}
import io.gatling.core.feeder.FeederBuilder
import io.gatling.core.structure.ScenarioBuilder
import io.gatling.http.Predef._
class CheckProjectsCacheFlushEntries extends CacheFlushSimulation {
private val data: FeederBuilder = jsonFile(resource).convert(keys).queue
def this(producer: CacheFlushSimulation) {
this()
this.producer = Some(producer)
}
val test: ScenarioBuilder = scenario(unique)
.feed(data)
.exec(session => {
if (producer.nonEmpty) {
session.set(entriesKey, producer.get.expectedEntriesAfterFlush())
} else {
session
}
})
.exec(http(unique).get("${url}")
.check(regex("\"" + memKey + "\": (\\d+)")
.is(session => session(entriesKey).as[String])))
setUp(
test.inject(
atOnceUsers(1)
),
).protocols(httpProtocol)
}

View File

@@ -0,0 +1,60 @@
// 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.google.gerrit.scenarios
import io.gatling.core.Predef._
import io.gatling.core.feeder.FeederBuilder
import io.gatling.core.structure.ScenarioBuilder
import scala.concurrent.duration._
class FlushProjectsCache extends CacheFlushSimulation {
private val data: FeederBuilder = jsonFile(resource).convert(keys).queue
private val default: String = name
override def relativeRuntimeWeight = 2
private val flushCache: ScenarioBuilder = scenario(unique)
.feed(data)
.exec(httpRequest)
private val createProject = new CreateProject(default)
private val getCacheEntriesAfterProject = new GetProjectsCacheEntries(this)
private val checkCacheEntriesAfterFlush = new CheckProjectsCacheFlushEntries(this)
private val deleteProject = new DeleteProject(default)
setUp(
createProject.test.inject(
nothingFor(stepWaitTime(createProject) seconds),
atOnceUsers(1)
),
getCacheEntriesAfterProject.test.inject(
nothingFor(stepWaitTime(getCacheEntriesAfterProject) seconds),
atOnceUsers(1)
),
flushCache.inject(
nothingFor(stepWaitTime(this) seconds),
atOnceUsers(1)
),
checkCacheEntriesAfterFlush.test.inject(
nothingFor(stepWaitTime(checkCacheEntriesAfterFlush) seconds),
atOnceUsers(1)
),
deleteProject.test.inject(
nothingFor(stepWaitTime(deleteProject) seconds),
atOnceUsers(1)
),
).protocols(httpProtocol)
}

View File

@@ -68,6 +68,8 @@ class GerritSimulation extends Simulation {
case ("project", project) =>
val precedes = replaceKeyWith("_project", name, project.toString)
replaceProperty("project", precedes)
case ("entries", entries) =>
replaceProperty("projects_entries", "1", entries.toString)
}
private def replaceProperty(term: String, in: String): String = {

View File

@@ -0,0 +1,45 @@
// 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.google.gerrit.scenarios
import io.gatling.core.Predef._
import io.gatling.core.feeder.FeederBuilder
import io.gatling.core.structure.ScenarioBuilder
import io.gatling.http.Predef.{http, _}
class GetProjectsCacheEntries extends CacheFlushSimulation {
private val data: FeederBuilder = jsonFile(resource).convert(keys).queue
def this(consumer: CacheFlushSimulation) {
this()
this.consumer = Some(consumer)
}
val test: ScenarioBuilder = scenario(unique)
.feed(data)
.exec(http(unique).get("${url}")
.check(regex("\"" + memKey + "\": (\\d+)").saveAs(entriesKey)))
.exec(session => {
if (consumer.nonEmpty) {
consumer.get.entriesBeforeFlush(session(entriesKey).as[Int])
}
session
})
setUp(
test.inject(
atOnceUsers(1)
)).protocols(httpProtocol)
}