This repository has been archived by the owner on Jan 18, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #126 from mockito/ms
#85 Automated e2e testing
- Loading branch information
Showing
11 changed files
with
336 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
apply plugin: 'base' // for clean task | ||
|
||
// It needs to be commented until first version of release-tools with E2E plugin is released. | ||
// If not, Gradle is unable to configure whole project, because E2E plugin isn't published in any version yet. | ||
// TODO uncomment in next PR | ||
// apply plugin: 'org.mockito.mockito-release-tools.e2e-test' | ||
|
||
/* | ||
Before we can push the code, I'd like to clean it up a little bit (TODO) | ||
4. In order for Gradle to neatly paralelize, | ||
let's have the mockito and mockito-release-tools-example be separate subprojects, | ||
just like I have set it up in PR #100. | ||
This way, the integration tests will run in parallel (Gradle parallelizes per project) | ||
5. Let's have completely separate task for cloning which will be incremental | ||
(e.g. does not clone twice when you run build twice). | ||
The task that performs the test will copy from the files from the clone task into some work dir and execute the test there | ||
6. Let's use relatively shallow clone. We don't need all history. | ||
7. I think we're missing task dependency to root's 'publishToMavenLocal' | ||
Integration testing is a big feature of shipkit! | ||
We will morph it into a plugin that will be part of the release tools plugins. | ||
Take your time engineering it and learn as much Gradle as possible during the process :) | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
rootProject.name="mockito-release-tools" | ||
rootProject.name="mockito-release-tools" | ||
|
||
include "e2eTests" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
src/main/groovy/org/mockito/release/internal/gradle/CloneGitRepositoryTask.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package org.mockito.release.internal.gradle; | ||
|
||
import org.gradle.api.DefaultTask; | ||
import org.gradle.api.logging.Logger; | ||
import org.gradle.api.logging.Logging; | ||
import org.gradle.api.tasks.Input; | ||
import org.gradle.api.tasks.OutputDirectory; | ||
import org.gradle.api.tasks.TaskAction; | ||
import org.mockito.release.exec.ProcessRunner; | ||
|
||
import java.io.File; | ||
|
||
/** | ||
* This task clone git project from repository to target dir. | ||
* It support clone from remote server and from local filesystem. | ||
* | ||
* TODO ms - when you are ready, please move the new task types to the public packages, | ||
* for example "org.mockito.release.*". With 1.0 we need all task types to be public. | ||
* It's because users interface with task types when they work with Gradle build scripts. | ||
* So it makes sense to be explicit that those types are public and we guarantee compatibility. | ||
* See also README.md on the compatibility where I attempted to describe this ;) | ||
*/ | ||
public class CloneGitRepositoryTask extends DefaultTask { | ||
|
||
private static final Logger LOG = Logging.getLogger(CloneGitRepositoryTask.class); | ||
|
||
private String repository; | ||
private File targetDir; | ||
|
||
@TaskAction | ||
public void cloneRepository() { | ||
LOG.lifecycle(" Cloning repository {}\n into {}", repository, targetDir); | ||
getProject().getBuildDir().mkdirs(); // build dir can be not created yet | ||
ProcessRunner processRunner = org.mockito.release.exec.Exec.getProcessRunner(getProject().getBuildDir()); | ||
processRunner.run("git", "clone", repository, targetDir.getAbsolutePath()); | ||
} | ||
|
||
//TODO ms - let's put javadoc on all public methods of the task | ||
// No need to put it on "cloneRepository" method because it is not intended to be used by end users. | ||
// It's nice if javadoc for 'repository' demonstrates an example value | ||
// When reading the API by looking at method signature | ||
// I don't know if repository should be a name of repo or valid url to the repo | ||
@Input | ||
public void setRepository(String repository) { | ||
this.repository = repository; | ||
} | ||
|
||
public String getRepository() { | ||
return repository; | ||
} | ||
|
||
@OutputDirectory | ||
public void setTargetDir(File targetDir) { | ||
this.targetDir = targetDir; | ||
} | ||
|
||
public File getTargetDir() { | ||
return targetDir; | ||
} | ||
} |
102 changes: 102 additions & 0 deletions
102
src/main/groovy/org/mockito/release/internal/gradle/E2ETestingPlugin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package org.mockito.release.internal.gradle; | ||
|
||
import org.gradle.api.Plugin; | ||
import org.gradle.api.Project; | ||
|
||
import java.io.File; | ||
|
||
import static java.util.Arrays.asList; | ||
import static org.mockito.release.internal.gradle.util.StringUtil.capitalize; | ||
|
||
/** | ||
* This plugin tests your library end-to-end (e2e) using client projects. | ||
* Plugin clones client projects to '$buildDir/project-name-pristine' first, next clone project from 'pristine' to | ||
* '$buildDir/project-name-work' and execute 'testRelease' task using the newest mockito-release-tools version | ||
* | ||
* Adds tasks: | ||
* <ul> | ||
* <li>cloneProjectFromGitHub$projectName - {@link CloneGitRepositoryTask}</li> | ||
* <li>cloneProjectToWorkDir$projectName - {@link CloneGitRepositoryTask}</li> | ||
* <li>runTest$projectName - {@link RunTestReleaseTask}</li> | ||
* </ul> | ||
*/ | ||
public class E2ETestingPlugin implements Plugin<Project> { | ||
|
||
public void apply(final Project project) { | ||
E2ETest e2eTest = project.getExtensions().create("e2eTest", E2ETest.class, project); | ||
// TODO hardcoded for now | ||
e2eTest.create("https://github.com/mockito/mockito-release-tools-example"); | ||
} | ||
|
||
//TODO ms - closer to the finish line we need to make this type public in one of the public packages | ||
//this is how users will interface with configuring e2e tests | ||
public static class E2ETest { | ||
|
||
Project project; | ||
|
||
public E2ETest(Project project) { | ||
this.project = project; | ||
} | ||
|
||
void create(String gitHubRepoUrl) { | ||
String repoName = extractRepoName(gitHubRepoUrl); | ||
CloneGitRepositoryTask clone = createCloneProjectFromGitHub(gitHubRepoUrl, repoName); | ||
CloneGitRepositoryTask workDirCloneTask = createCloneProjectToWorkDirTask(repoName, clone); | ||
createRunTestReleaseTask(repoName, workDirCloneTask); | ||
} | ||
|
||
private CloneGitRepositoryTask createCloneProjectFromGitHub(String gitHubRepoUrl, String repoName) { | ||
// TODO add depth clone configuration for shallow clone | ||
CloneGitRepositoryTask clone = project.getTasks().create( | ||
"cloneProjectFromGitHub" + capitalize(repoName), | ||
CloneGitRepositoryTask.class); | ||
clone.setRepository(gitHubRepoUrl); | ||
clone.setTargetDir(new File(project.getBuildDir(), repoName + "-pristine")); | ||
// For now for easier testing | ||
clone.dependsOn("clean"); | ||
return clone; | ||
} | ||
|
||
private CloneGitRepositoryTask createCloneProjectToWorkDirTask(String repoName, CloneGitRepositoryTask clone) { | ||
// Clone from *-pristine to *-work. Copy task will not work because of ignoring git specific files: | ||
// https://discuss.gradle.org/t/copy-git-specific-files/11970 | ||
// Furthermore we can verify push to pristine origin | ||
File workDir = new File(project.getBuildDir(), repoName + "-work"); | ||
CloneGitRepositoryTask copy = project.getTasks().create( | ||
"cloneProjectToWorkDir" + capitalize(repoName), | ||
CloneGitRepositoryTask.class); | ||
copy.dependsOn(clone); | ||
copy.setRepository(clone.getTargetDir().getAbsolutePath()); | ||
copy.setTargetDir(workDir); | ||
return copy; | ||
} | ||
|
||
private void createRunTestReleaseTask(String repoName, CloneGitRepositoryTask copy) { | ||
RunTestReleaseTask run = project.getTasks().create( | ||
"runTestRelease" + capitalize(repoName), | ||
RunTestReleaseTask.class); | ||
run.dependsOn(copy); | ||
run.setWorkDir(copy.getTargetDir()); | ||
run.setRepoName(repoName); | ||
|
||
// Using Gradle's composite builds ("--include-build") so that we're picking up current version of tools | ||
run.setCommand(asList("./gradlew", "publishToMavenLocal", "testRelease", | ||
"-x", "gitPush", "-x", "bintrayUpload", | ||
"--include-build", project.getRootDir().getAbsolutePath(), "-s")); | ||
|
||
// Build log in separate file instead of including it in the console of the parent build | ||
// Otherwise the output will be really messy | ||
run.setBuildOutputFile(new File(project.getBuildDir(), repoName + "-build.log")); | ||
} | ||
|
||
private String extractRepoName(String gitHubRepo) { | ||
String text = gitHubRepo.trim(); | ||
if(text.lastIndexOf('/') == text.length() - 1) { | ||
// cut last slash | ||
text = text.substring(0, text.length() - 1); | ||
} | ||
return text.substring(text.lastIndexOf('/') + 1, text.length()); | ||
} | ||
} | ||
|
||
} |
53 changes: 53 additions & 0 deletions
53
src/main/groovy/org/mockito/release/internal/gradle/RunTestReleaseTask.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package org.mockito.release.internal.gradle; | ||
|
||
import org.gradle.api.DefaultTask; | ||
import org.gradle.api.logging.Logger; | ||
import org.gradle.api.logging.Logging; | ||
import org.gradle.api.tasks.Input; | ||
import org.gradle.api.tasks.OutputFile; | ||
import org.gradle.api.tasks.TaskAction; | ||
import org.mockito.release.exec.ProcessRunner; | ||
|
||
import java.io.File; | ||
import java.util.List; | ||
|
||
/** | ||
* This task run external process and additionally store output of external process to file. | ||
*/ | ||
public class RunTestReleaseTask extends DefaultTask { | ||
|
||
private static final Logger LOG = Logging.getLogger(RunTestReleaseTask.class); | ||
|
||
private List<String> command; | ||
private File buildOutput; | ||
private File workDir; | ||
private String repoName; | ||
|
||
@TaskAction | ||
public void runTest() { | ||
LOG.lifecycle(" Run test of {}. The output will be save in {}", repoName, buildOutput.getAbsoluteFile()); | ||
ProcessRunner processRunner = org.mockito.release.exec.Exec.getProcessRunner(workDir, buildOutput); | ||
processRunner.run(command); | ||
} | ||
|
||
@Input | ||
public void setWorkDir(File workDir) { | ||
this.workDir = workDir; | ||
} | ||
|
||
@Input | ||
public void setCommand(List<String> command) { | ||
this.command = command; | ||
} | ||
|
||
@Input | ||
public void setRepoName(String repoName) { | ||
this.repoName = repoName; | ||
} | ||
|
||
@OutputFile | ||
public void setBuildOutputFile(File file) { | ||
buildOutput = file; | ||
} | ||
|
||
} |
1 change: 1 addition & 0 deletions
1
...n/resources/META-INF/gradle-plugins/org.mockito.mockito-release-tools.e2e-test.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
implementation-class=org.mockito.release.internal.gradle.E2ETestingPlugin |
Oops, something went wrong.