diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..d9cea7813 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,19 @@ +language: java +jdk: + - oraclejdk8 +sudo: true +before_install: + - echo 'America/Los_Angeles' | sudo tee /etc/timezone + - sudo dpkg-reconfigure --frontend noninteractive tzdata + - chmod 755 ./shared/dev-tasks/*.sh + - chmod 755 ./gradlew +install: + - ./shared/dev-tasks/install-dependencies.sh +script: + - ./shared/dev-tasks/run-tests.sh + +#whitelist +branches: + only: + - master + - dev diff --git a/README.md b/README.md index 4a5d0b577..251ba4264 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,11 @@ What is Gradle? =============== -Gradle is a standard build tool that is used for building and deploying primarily Java applications, but it can be used for any codebase. -The full user guide for Gradle is available at http://www.gradle.org/docs/current/userguide/userguide.html. +Gradle is a standard build tool that is used for building and deploying primarily Java applications, but it can be used for any codebase. Check out the [Gradle user guide](http://www.gradle.org/docs/current/userguide/userguide.html) for more information. What is ml-gradle? ========= -ml-gradle is a [Gradle plugin](http://www.gradle.org/plugins "") that supports a number of tasks pertaining to deploying an +ml-gradle is a [Gradle plugin](https://plugins.gradle.org/ "") that supports a number of tasks pertaining to deploying an application to MarkLogic and interacting with other features of MarkLogic via a Gradle build file. The bulk of the functionality provided by ml-gradle is actually in [ml-app-deployer](https://github.com/rjrudin/ml-app-deployer) - ml-gradle is just intended to be a thin wrapper around this library, exposing its functionality via Gradle tasks and properties. diff --git a/build.gradle b/build.gradle index 7fbf2059b..5f818ca94 100644 --- a/build.gradle +++ b/build.gradle @@ -6,10 +6,11 @@ plugins { id "com.jfrog.bintray" version "1.6" id "com.github.jk1.dependency-license-report" version "0.3.11" id "com.gradle.plugin-publish" version "0.9.7" + id "java-gradle-plugin" } -sourceCompatibility = "1.7" -targetCompatibility = "1.7" +sourceCompatibility = "1.8" +targetCompatibility = "1.8" repositories { mavenLocal() // Used for local development only @@ -22,6 +23,13 @@ dependencies { compile mlAppDeployerDependency compile mlcpUtilDependency compile group: 'commons-io', name: 'commons-io', version: '2.5' + + testCompile localGroovy() + testCompile gradleTestKit() + testCompile 'xmlunit:xmlunit:1.3' + testCompile('org.spockframework:spock-core:1.1-groovy-2.4') { + exclude module: 'groovy-all' + } } task sourcesJar(type: Jar, dependsOn: classes) { diff --git a/examples/local-testing-project/gradle.properties b/examples/local-testing-project/gradle.properties index 036832190..c707252a4 100644 --- a/examples/local-testing-project/gradle.properties +++ b/examples/local-testing-project/gradle.properties @@ -1,6 +1,6 @@ # Set this to the version you used when running # "gradle -Pversion=(something) publishToMavenLocal" on your local ml-gradle repo -mlGradleVersion=3.0-beta2 +mlGradleVersion=3.0.0 mlHost=localhost mlAppName=example diff --git a/examples/sample-project/build.gradle b/examples/sample-project/build.gradle index ace47e937..d5c86c7d5 100644 --- a/examples/sample-project/build.gradle +++ b/examples/sample-project/build.gradle @@ -8,7 +8,7 @@ buildscript { jcenter() } dependencies { - classpath "com.marklogic:ml-gradle:3.0-alpha1" + classpath "com.marklogic:ml-gradle:3.0.0" } } @@ -53,7 +53,7 @@ configurations { */ dependencies { // Needed to compile and run the JUnit tests - testCompile "com.marklogic:ml-junit:3.0-alpha1" + testCompile "com.marklogic:ml-junit:3.0.0" testCompile "com.jayway.restassured:rest-assured:2.4.1" // corb jar available from jcenter diff --git a/examples/sample-project/src/test/java/sample/GetClientConfigTest.java b/examples/sample-project/src/test/java/sample/GetClientConfigTest.java index ab4789d3e..67f3afc11 100644 --- a/examples/sample-project/src/test/java/sample/GetClientConfigTest.java +++ b/examples/sample-project/src/test/java/sample/GetClientConfigTest.java @@ -2,7 +2,7 @@ import org.junit.Test; -import com.marklogic.client.ext.helper.DatabaseClientConfig; +import com.marklogic.client.ext.DatabaseClientConfig; public class GetClientConfigTest extends AbstractSampleProjectTest { diff --git a/examples/sample-project/src/test/java/sample/SampleProjectTestConfig.java b/examples/sample-project/src/test/java/sample/SampleProjectTestConfig.java index b1033884d..05eaf0f95 100644 --- a/examples/sample-project/src/test/java/sample/SampleProjectTestConfig.java +++ b/examples/sample-project/src/test/java/sample/SampleProjectTestConfig.java @@ -4,7 +4,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; -import com.marklogic.client.ext.helper.DatabaseClientConfig; +import com.marklogic.client.ext.DatabaseClientConfig; import com.marklogic.junit.spring.BasicTestConfig; @Configuration diff --git a/examples/sample-project/src/test/java/sample/SearchDocumentsViaRestAssuredTest.java b/examples/sample-project/src/test/java/sample/SearchDocumentsViaRestAssuredTest.java index 8fc47c44b..a904bfb85 100644 --- a/examples/sample-project/src/test/java/sample/SearchDocumentsViaRestAssuredTest.java +++ b/examples/sample-project/src/test/java/sample/SearchDocumentsViaRestAssuredTest.java @@ -9,7 +9,7 @@ import com.jayway.restassured.RestAssured; import com.jayway.restassured.path.json.JsonPath; import com.marklogic.client.document.XMLDocumentManager; -import com.marklogic.client.ext.helper.DatabaseClientConfig; +import com.marklogic.client.ext.DatabaseClientConfig; import com.marklogic.client.io.DocumentMetadataHandle; import com.marklogic.client.io.Format; import com.marklogic.client.io.StringHandle; diff --git a/shared/dev-tasks/install-dependencies.sh b/shared/dev-tasks/install-dependencies.sh new file mode 100644 index 000000000..5fd303395 --- /dev/null +++ b/shared/dev-tasks/install-dependencies.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +if [ "${TRAVIS_SECURE_ENV_VARS}" = "true" ] ; then + ./shared/dev-tasks/travis-install-ml.sh release + ./shared/dev-tasks/setup-marklogic.sh +fi diff --git a/shared/dev-tasks/run-tests.sh b/shared/dev-tasks/run-tests.sh new file mode 100644 index 000000000..92046a121 --- /dev/null +++ b/shared/dev-tasks/run-tests.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +if [ "${TRAVIS_SECURE_ENV_VARS}" = "true" ] ; then + cd ${TRAVIS_BUILD_DIR} + ./gradlew test -i +fi diff --git a/shared/dev-tasks/setup-marklogic.sh b/shared/dev-tasks/setup-marklogic.sh new file mode 100644 index 000000000..71f28c339 --- /dev/null +++ b/shared/dev-tasks/setup-marklogic.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +sudo /etc/init.d/MarkLogic start +sleep 10 +curl -X POST -d "" http://localhost:8001/admin/v1/init +sleep 10 +curl -X POST -H "Content-type: application/x-www-form-urlencoded" \ + --data "admin-username=admin" \ + --data "admin-password=admin" \ + --data "realm=public" \ + "http://localhost:8001/admin/v1/instance-admin" +sleep 10 diff --git a/shared/dev-tasks/travis-install-ml.sh b/shared/dev-tasks/travis-install-ml.sh new file mode 100755 index 000000000..46f0e79fb --- /dev/null +++ b/shared/dev-tasks/travis-install-ml.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +# runs command from parameters and exits with the eoror code of the command +# if it fails +function successOrExit { + "$@" + local status=$? + if [ $status -ne 0 ]; then + echo "$1 exited with error: $status" + exit $status + fi +} + +set | grep TRAVIS + +test $1 && arg1=$1 +if [[ $arg1 = 'release' ]]; then + ver=${ML_VERSION} + fname=MarkLogic-${ver}.x86_64.rpm + fnamedeb="marklogic_" + fnamedeb=$fnamedeb$ver + suff="_amd64.deb" + fnamedeb=$fnamedeb$suff + + curl -c cookies.txt --data "email=${MLBUILD_USER}&password=${MLBUILD_PASSWORD}" https://developer.marklogic.com/login + dl_link=$(curl -b cookies.txt --data "download=/download/binaries/9.0/${fname}" https://developer.marklogic.com/get-download-url | perl -pe 's/.*"path":"([^"]+).*/\1/') + url="https://developer.marklogic.com${dl_link}" + + echo "********* Downloading MarkLogic $ver" + + successOrExit curl -k -o ./$fname $url + + fname=$(pwd)/$fname + + sudo apt-get update + sudo apt-get install wajig alien rpm lsb-base dpkg-dev debhelper build-essential + (cd /etc && sudo ln -s default sysconfig) + sudo wajig rpminstall $fname + + echo "********* MarkLogic $ver installed" +else + # find today + day=$(date +"%Y%m%d") + + # if the user passed a day string as a param then use it instead + test $1 && day=$1 + # make a version number out of the date + ver="9.0-$day" + + echo "********* Downloading MarkLogic nightly $ver" + + # fetch/install ML nightly + fname="MarkLogic-$ver.x86_64.rpm" + fnamedeb="marklogic_" + fnamedeb=$fnamedeb$ver + suff="_amd64.deb" + fnamedeb=$fnamedeb$suff + + url="https://root.marklogic.com/nightly/builds/linux64-rh7/rh7v-intel64-90-test-build.marklogic.com/b9_0/pkgs.$day/$fname" + + status=$(curl -k --anyauth -u $MLBUILD_USER:$MLBUILD_PASSWORD --head --write-out %{http_code} --silent --output /dev/null $url) + if [[ $status = 200 ]]; then + successOrExit curl -k --anyauth -u $MLBUILD_USER:$MLBUILD_PASSWORD -o ./$fname $url + + fname=$(pwd)/$fname + + sudo apt-get update + sudo apt-get install alien dpkg-dev debhelper build-essential + sudo alien -d -k $fname + sudo dpkg -i $fnamedeb + + echo "********* MarkLogic nightly $ver installed" + else + echo "CANNOT DOWNLOAD: status = $status for date $day (URL=\"$url\")" + exit 1 + fi +fi diff --git a/src/main/groovy/com/marklogic/gradle/MarkLogicPlugin.groovy b/src/main/groovy/com/marklogic/gradle/MarkLogicPlugin.groovy index 22b575e12..8f1e2e420 100644 --- a/src/main/groovy/com/marklogic/gradle/MarkLogicPlugin.groovy +++ b/src/main/groovy/com/marklogic/gradle/MarkLogicPlugin.groovy @@ -62,14 +62,10 @@ import com.marklogic.mgmt.ManageConfig import com.marklogic.mgmt.admin.AdminConfig import com.marklogic.mgmt.admin.AdminManager import com.marklogic.mgmt.admin.DefaultAdminConfigFactory -import com.sun.jersey.core.spi.component.ProviderServices import org.gradle.api.Plugin import org.gradle.api.Project import org.slf4j.LoggerFactory -import java.util.logging.Level -import java.util.logging.Logger - class MarkLogicPlugin implements Plugin { org.slf4j.Logger logger = LoggerFactory.getLogger(getClass()) @@ -77,8 +73,6 @@ class MarkLogicPlugin implements Plugin { void apply(Project project) { logger.info("\nInitializing ml-gradle") - quietDownJerseyLogging() - initializeAppDeployerObjects(project) project.getConfigurations().create("mlRestApi") @@ -293,16 +287,4 @@ class MarkLogicPlugin implements Plugin { deployer.setCommands(commands) return deployer } - - /** - * When the MarkLogic DatabaseClient class is used in Gradle, the Jersey ProviderServices class spits out - * a lot of not helpful logging at the INFO level. So we bump it down to WARNING to avoid that. - */ - void quietDownJerseyLogging() { - try { - Logger.getLogger(ProviderServices.class.getName()).setLevel(Level.WARNING) - } catch (Exception e) { - // Ignore, not important - } - } } diff --git a/src/test/groovy/com/marklogic/gradle/BaseTest.groovy b/src/test/groovy/com/marklogic/gradle/BaseTest.groovy new file mode 100644 index 000000000..8d33a5f92 --- /dev/null +++ b/src/test/groovy/com/marklogic/gradle/BaseTest.groovy @@ -0,0 +1,87 @@ +package com.marklogic.gradle + +import com.marklogic.mgmt.ManageClient +import com.marklogic.mgmt.ManageConfig +import com.marklogic.mgmt.admin.AdminConfig +import com.marklogic.mgmt.admin.AdminManager +import com.marklogic.mgmt.resource.appservers.ServerManager +import com.marklogic.mgmt.resource.databases.DatabaseManager +import com.marklogic.rest.util.ResourcesFragment +import org.custommonkey.xmlunit.XMLUnit +import org.gradle.testkit.runner.BuildResult +import org.gradle.testkit.runner.GradleRunner +import org.junit.rules.TemporaryFolder +import spock.lang.Specification + +class BaseTest extends Specification { + static final TemporaryFolder testProjectDir = new TemporaryFolder() + static File buildFile + static File propertiesFile + + static BuildResult runTask(String... task) { + return GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments(task) + .withDebug(true) + .withPluginClasspath() + .build() + } + + BuildResult runFailTask(String... task) { + return GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments(task) + .withDebug(true) + .withPluginClasspath().buildAndFail() + } + + static void createBuildFile() { + buildFile = testProjectDir.newFile('build.gradle') + buildFile << """ + plugins { + id 'com.marklogic.ml-gradle' + } + """ + } + + static AdminConfig getAdminConfig() { + return new AdminConfig("localhost", 8001, "admin", "admin") + } + + static AdminManager getAdminManager() { + return new AdminManager(getAdminConfig()) + } + + static ManageClient getManageClient() { + ManageConfig manageConfig = new ManageConfig("localhost", 8002, "admin", "admin") + ManageClient manageClient = new ManageClient(manageConfig) + return manageClient + } + + static ServerManager getServerManager() { + return new ServerManager(getManageClient()); + } + + static DatabaseManager getDatabaseManager() { + return new DatabaseManager(getManageClient()); + } + + static ResourcesFragment getDbConfig() { + return getDatabaseManager().getAsXml() + } + + static ResourcesFragment getServerConfig() { + return getServerManager().getAsXml() + } + + static void createPropertiesFile(contents) { + propertiesFile = testProjectDir.newFile('gradle.properties') + propertiesFile << contents + } + + def setupSpec() { + XMLUnit.setIgnoreWhitespace(true) + testProjectDir.create() + createBuildFile() + } +} diff --git a/src/test/groovy/com/marklogic/gradle/DeployAppTaskTest.groovy b/src/test/groovy/com/marklogic/gradle/DeployAppTaskTest.groovy new file mode 100644 index 000000000..e71457ae4 --- /dev/null +++ b/src/test/groovy/com/marklogic/gradle/DeployAppTaskTest.groovy @@ -0,0 +1,37 @@ +package com.marklogic.gradle + +import org.gradle.testkit.runner.UnexpectedBuildFailure + +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS + +class DeployAppTaskTest extends BaseTest { + + def "deploy barebones app"() { + setup: + print(runTask('mlUnDeploy').output) + + expect: + def srf = getServerConfig() + def drf = getDbConfig() + !srf.resourceExists("my-app") + !drf.resourceExists("my-app-content") + !drf.resourceExists("my-app-modules") + + when: + def result = runTask('mlDeploy') + print(result.output) + + then: + notThrown(UnexpectedBuildFailure) + result.task(":mlDeploy").outcome == SUCCESS + def srf2 = getServerConfig() + def drf2 = getDbConfig() + srf2.resourceExists("my-app") + drf2.resourceExists("my-app-content") + drf2.resourceExists("my-app-modules") + + cleanup: + runTask('mlUndeploy') + } + +}