blob: 4d0df879f004fb18f4b17a98b99eb526ea771d46 [file] [log] [blame]
// Copyright (C) 2017 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.googlesource.gerrit.plugins.analytics.test
import java.io.File
import java.util.{Date, UUID}
import com.google.gerrit.acceptance.{AbstractDaemonTest, GitUtil, _}
import com.google.gerrit.entities.Project
import com.google.gerrit.extensions.client.SubmitType
import com.google.gerrit.extensions.restapi.RestApiModule
import com.google.gerrit.server.project.ProjectResource.PROJECT_KIND
import com.google.gerrit.server.project.ProjectState
import com.google.inject.AbstractModule
import com.googlesource.gerrit.plugins.analytics.common.CommitsStatisticsCache
import com.googlesource.gerrit.plugins.analytics.{AnalyticsConfig, ContributorsResource}
import org.eclipse.jgit.api.MergeCommand.FastForwardMode
import org.eclipse.jgit.api.{Git, MergeResult}
import org.eclipse.jgit.internal.storage.file.FileRepository
import org.eclipse.jgit.junit.TestRepository
import org.eclipse.jgit.lib._
import org.eclipse.jgit.merge.MergeStrategy
import org.eclipse.jgit.revwalk.RevCommit
import org.gitective.core.CommitUtils
import org.junit.runner.Description
import org.junit.runners.model.Statement
import org.scalatest._
trait GerritTestDaemon extends BeforeAndAfterEach {
self: Suite =>
type TestFileRepository = TestRepository[FileRepository]
val daemonTest = GerritTestDaemon
protected abstract override def runTest(testName: String, args: Args): Status = {
var status: Status = FailedStatus
val runLambda = () => super.runTest(testName, args)
daemonTest.testRunner.apply(new Statement() {
override def evaluate(): Unit = {
status = runLambda.apply()
}
}, Description.createTestDescription(getClass.getName, testName)).evaluate()
status
}
var testFileRepository: TestFileRepository = _
implicit var fileRepository: FileRepository = _
implicit var fileRepositoryName: Project.NameKey = null
protected lazy val author = newPersonIdent("Test Author", "author@test.com")
protected lazy val committer = newPersonIdent("Test Committer", "committer@test.com")
def newPersonIdent(name: String = "Test Person", email: String = "person@test.com", ts: Date = new Date()) =
new PersonIdent(new PersonIdent(name, email), ts)
override def beforeEach() = {
daemonTest.setUpTestPlugin()
fileRepositoryName = daemonTest.newProject(testSpecificRepositoryName)
fileRepository = daemonTest.getRepository(fileRepositoryName)
testFileRepository = GitUtil.newTestRepository(fileRepository)
}
protected def testSpecificRepositoryName = "git-test-case-" + UUID.randomUUID().toString
implicit class PimpedGitRepository(repo: TestFileRepository) {
def branch(name: String, startPoint: String): Ref =
repo.git.branchCreate.setName(name).setStartPoint(startPoint).call
def gitClone: TestFileRepository = {
val TmpDir = System.getProperty("java.io.tmpdir")
val clonedRepository = Git.cloneRepository
.setDirectory(new File(s"$TmpDir/${testSpecificRepositoryName}_clone"))
.setURI(repo.getRepository.getDirectory.toURI.toString)
.call()
.getRepository.asInstanceOf[FileRepository]
GitUtil.newTestRepository(clonedRepository)
}
def commitFile(path: String, content: String, author: PersonIdent = author, committer: PersonIdent = committer, branch: String = Constants.MASTER, message: String = ""): RevCommit =
repo.branch(branch).commit()
.add(path, content)
.author(author)
.committer(committer)
.message(message)
.create
def commitFiles(files: Iterable[(String, String)], author: PersonIdent = author, committer: PersonIdent = committer, branch: String = Constants.MASTER, message: String = ""): RevCommit = {
val commit = repo.branch(branch).commit()
.author(author)
.committer(committer)
.message(message)
files.foldLeft(commit) {
(commit, fileAndContent) => commit.add(fileAndContent._1, fileAndContent._2)
}.create()
}
def mergeCommitFile(fileName: String, content: String, author: PersonIdent = author, committer: PersonIdent = committer): MergeResult = {
val currentBranch = repo.getRepository.getFullBranch
val tmpBranch = repo.branch("tmp", currentBranch)
try {
repo.commitFile(fileName, content, branch = tmpBranch.getName, author = author, committer = committer)
repo.mergeBranch(tmpBranch.getName, withCommit = true)
} finally {
repo.git.branchDelete().setBranchNames(tmpBranch.getName).setForce(true).call.get(0)
}
}
def mergeBranch(branch: String, withCommit: Boolean, message: String = "merging branch"): MergeResult = {
repo.git.merge.setStrategy(MergeStrategy.RESOLVE)
.include(CommitUtils.getRef(repo.getRepository, branch))
.setCommit(withCommit)
.setFastForward(FastForwardMode.NO_FF)
.setMessage(message)
.call
}
def push =
repo.git.push.setPushAll.call
}
}
@UseLocalDisk
@TestPlugin(
name = "analytics",
sysModule = "com.googlesource.gerrit.plugins.analytics.test.GerritTestDaemon$TestModule"
)
object GerritTestDaemon extends LightweightPluginDaemonTest {
baseConfig = new Config()
AbstractDaemonTest.temporaryFolder.create()
tempDataDir.create()
def newProject(nameSuffix: String, emptyCommit: Boolean = false) = {
resourcePrefix = ""
super.createProjectOverAPI(nameSuffix, allProjects, emptyCommit, SubmitType.MERGE_IF_NECESSARY)
}
def reloadProject(projectName: Project.NameKey): Option[ProjectState] = {
projectCache.evict(projectName)
Option(projectCache.get(projectName).orElse(null))
}
def getRepository(projectName: Project.NameKey): FileRepository =
repoManager.openRepository(projectName) match {
case repository: FileRepository => repository
case repository => throw new IllegalStateException(s"Expected 'FileRepository', got ${repository.getClass.getName}")
}
def adminAuthor = admin.newIdent
def getInstance[T](clazz: Class[T]): T =
plugin.getSysInjector.getInstance(clazz)
def getCanonicalWebUrl: String = canonicalWebUrl.get()
def restSession: RestSession = adminRestSession
class TestModule extends AbstractModule {
override def configure(): Unit = {
bind(classOf[CommitsStatisticsCache]).to(classOf[CommitsStatisticsNoCache])
bind(classOf[AnalyticsConfig]).toInstance(TestAnalyticsConfig)
install(new RestApiModule() {
override protected def configure() = {
get(PROJECT_KIND, "contributors").to(classOf[ContributorsResource])
}
})
}
}
}