Skip to content

Commit

Permalink
GEODE-5995: Initial import of gradle docker plugin (apache#2790)
Browse files Browse the repository at this point in the history
Also includes:
- Revert java version detection in original code (done for Java 9+ work).
- Handle case where network interface disappears during docker teardown
  • Loading branch information
jdeppe-pivotal authored Nov 7, 2018
1 parent ae8abe2 commit 23af84c
Show file tree
Hide file tree
Showing 15 changed files with 1,696 additions and 1 deletion.
1 change: 0 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ buildscript {
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.6.2'
classpath "com.diffplug.spotless:spotless-plugin-gradle:3.10.0"
classpath "me.champeau.gradle:jmh-gradle-plugin:0.4.7"
classpath "com.pedjak.gradle.plugins:dockerized-test:0.5.6.35-SNAPSHOT"
classpath 'com.github.ben-manes:gradle-versions-plugin:0.17.0'
classpath "com.netflix.nebula:nebula-project-plugin:4.0.1"
}
Expand Down
15 changes: 15 additions & 0 deletions buildSrc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,30 @@

repositories {
mavenCentral()
maven { url "http://geode-maven.s3-website-us-west-2.amazonaws.com" }
}

dependencies {
compile (group: 'org.apache.geode', name: 'geode-junit', version: '1.3.0') {
exclude group: 'org.apache.logging.log4j'
}
compile gradleApi()
compile 'org.apache.commons:commons-lang3:3.3.2'
compile 'org.apache.maven:maven-artifact:3.3.3'
compile 'com.github.docker-java:docker-java:3.1.2-GEODE'

compile group: 'junit', name: 'junit', version: '4.12'

testAnnotationProcessor this.project
}

sourceSets {
main {
java {
srcDirs = []
}
groovy {
srcDirs += ['src/main/java']
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright 2015 the original author or authors.
*
* 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.pedjak.gradle.plugins.dockerizedtest

import org.gradle.api.Project
import org.gradle.api.tasks.testing.Test

import java.util.concurrent.Semaphore

class DefaultWorkerSemaphore implements WorkerSemaphore {
private int maxWorkers = Integer.MAX_VALUE
private Semaphore semaphore
private logger

@Override
void acquire() {
semaphore().acquire()
logger.debug("Semaphore acquired, available: {}/{}", semaphore().availablePermits(), maxWorkers)
}

@Override
void release() {
semaphore().release()
logger.debug("Semaphore released, available: {}/{}", semaphore().availablePermits(), maxWorkers)
}

@Override
synchronized void applyTo(Project project) {
if (semaphore) return
if (!logger) {
logger = project.logger
}

maxWorkers = project.tasks.withType(Test).findAll {
it.extensions.docker?.image != null
}.collect {
def v = it.maxParallelForks
it.maxParallelForks = 10000
v
}.min() ?: 1
semaphore()
}

private synchronized setMaxWorkers(int num) {
if (this.@maxWorkers > num) {
this.@maxWorkers = num
}
}

private synchronized Semaphore semaphore() {
if (semaphore == null) {
semaphore = new Semaphore(maxWorkers)
logger.lifecycle("Do not allow more than {} test workers", maxWorkers)
}
semaphore
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright 2015 the original author or authors.
*
* 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.pedjak.gradle.plugins.dockerizedtest

import com.pedjak.gradle.plugins.dockerizedtest.DockerizedTestExtension
import com.pedjak.gradle.plugins.dockerizedtest.ExitCodeTolerantExecHandle
import com.pedjak.gradle.plugins.dockerizedtest.WorkerSemaphore
import org.gradle.api.internal.file.FileResolver
import org.gradle.initialization.BuildCancellationToken
import org.gradle.process.internal.*
import org.gradle.process.internal.streams.OutputStreamsForwarder

import java.util.concurrent.Executor

class DockerizedJavaExecHandleBuilder extends JavaExecHandleBuilder {

def streamsHandler
def executor
def buildCancellationToken
private final DockerizedTestExtension extension

private final WorkerSemaphore workersSemaphore

DockerizedJavaExecHandleBuilder(DockerizedTestExtension extension, FileResolver fileResolver, Executor executor, BuildCancellationToken buildCancellationToken, WorkerSemaphore workersSemaphore) {
super(fileResolver, executor, buildCancellationToken)
this.extension = extension
this.executor = executor
this.buildCancellationToken = buildCancellationToken
this.workersSemaphore = workersSemaphore
}

def StreamsHandler getStreamsHandler() {
StreamsHandler effectiveHandler;
if (this.streamsHandler != null) {
effectiveHandler = this.streamsHandler;
} else {
boolean shouldReadErrorStream = !redirectErrorStream;
effectiveHandler = new OutputStreamsForwarder(standardOutput, errorOutput, shouldReadErrorStream);
}
return effectiveHandler;
}

ExecHandle build() {

return new ExitCodeTolerantExecHandle(new DockerizedExecHandle(extension, getDisplayName(),
getWorkingDir(),
'java',
allArguments,
getActualEnvironment(),
getStreamsHandler(),
inputHandler,
listeners,
redirectErrorStream,
timeoutMillis,
daemon,
executor,
buildCancellationToken),
workersSemaphore)

}

def timeoutMillis = Integer.MAX_VALUE

@Override
AbstractExecHandleBuilder setTimeout(int timeoutMillis) {
this.timeoutMillis = timeoutMillis
return super.setTimeout(timeoutMillis)
}

boolean redirectErrorStream

@Override
AbstractExecHandleBuilder redirectErrorStream() {
redirectErrorStream = true
return super.redirectErrorStream()
}

def listeners = []

@Override
AbstractExecHandleBuilder listener(ExecHandleListener listener) {
listeners << listener
return super.listener(listener)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright 2015 the original author or authors.
*
* 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.pedjak.gradle.plugins.dockerizedtest

import com.github.dockerjava.api.DockerClient

class DockerizedTestExtension {

String image
Map volumes
String user

Closure beforeContainerCreate

Closure afterContainerCreate

Closure beforeContainerStart

Closure afterContainerStart

Closure afterContainerStop = { containerId, client ->
try {
client.removeContainerCmd(containerId).exec();
} catch (Exception e) {
// ignore any error
}
}

// could be a DockerClient instance or a closure that returns a DockerClient instance
private def clientOrClosure

void setClient(clientOrClosure) {
this.clientOrClosure = clientOrClosure
}

DockerClient getClient() {
if (clientOrClosure == null) return null
if (DockerClient.class.isAssignableFrom(clientOrClosure.getClass())) {
return (DockerClient) clientOrClosure;
} else {
return (DockerClient) ((Closure) clientOrClosure).call();
}
}
}
Loading

0 comments on commit 23af84c

Please sign in to comment.