Skip to content

Instantly share code, notes, and snippets.

@rjrudin
Created July 23, 2019 16:19
Show Gist options
  • Save rjrudin/0dd97eaee16b1f8dc75a35c7acf7b4e1 to your computer and use it in GitHub Desktop.
Save rjrudin/0dd97eaee16b1f8dc75a35c7acf7b4e1 to your computer and use it in GitHub Desktop.
Deploying test resources for a DHF 5 application
/**
* The below tasks are used for deploying and undeploying test resources for a DHF 5 application. Just copy everything below
* this comment into the build.gradle file in your DHF application - no properties need to be set for these tasks to work.
*
* The task "hubDeployTestResources" will deploy test versions of your staging and final databases and app servers. You
* can customize these tasks if you don't like the resource names and ports that are used by them. Note that mlDeploy
* does not depend on this task by default - you'll need to invoke it in order to create test resources.
*
* The task "hubUndeployTestResources" will undeploy any test resources that were created. mlUndeploy does depend on
* this task as there's typically no downside to undeploying these resources - if they don't exist, the task will
* quickly complete.
*/
task hubDeployTestStagingDatabase(type: com.marklogic.gradle.task.MarkLogicTask) {
doLast {
File testDbFile = new File(buildDir, "test-staging-database.json")
testDbFile.write(new File("src/main/hub-internal-config/databases/staging-database.json").text)
new DeployHubTestDatabaseCommand(hubConfig, testDbFile, "staging-database.json", mlStagingDbName + "-TEST").execute(mlCommandContext)
}
}
task hubDeployTestFinalDatabase(type: com.marklogic.gradle.task.MarkLogicTask) {
doLast {
File testDbFile = new File(buildDir, "test-final-database.json")
testDbFile.write(new File("src/main/ml-config/databases/final-database.json").text)
new DeployHubTestDatabaseCommand(hubConfig, testDbFile, "final-database.json", mlFinalDbName + "-TEST").execute(mlCommandContext)
}
}
task hubDeployTestDatabases(type: com.marklogic.gradle.task.MarkLogicTask) {
dependsOn = ["hubDeployTestStagingDatabase", "hubDeployTestFinalDatabase"]
}
task hubDeployTestServers(type: com.marklogic.gradle.task.MarkLogicTask) {
doLast {
new DeployHubTestServerCommand("staging-server.json", mlStagingAppserverName + "-TEST", 8014, mlStagingDbName + "-TEST").execute(mlCommandContext);
new DeployHubTestServerCommand("final-server.json", mlFinalAppserverName + "-TEST", 8015, mlFinalDbName + "-TEST").execute(mlCommandContext);
}
}
task hubDeployTestResources {
description = "Deploys test databases and servers"
dependsOn = ["hubDeployTestDatabases", "hubDeployTestServers"]
}
hubDeployTestServers.mustRunAfter hubDeployTestDatabases
task hubUndeployTestResources(type: com.marklogic.gradle.task.MarkLogicTask) {
description = "Undeploys the test servers and databases that were created via hubDeployTestResources"
doLast {
mlAdminManager.invokeActionRequiringRestart({
new com.marklogic.mgmt.resource.appservers.ServerManager(mlManageClient).deleteByIdField(mlStagingAppserverName + "-TEST")
return true
})
mlAdminManager.invokeActionRequiringRestart({
new com.marklogic.mgmt.resource.appservers.ServerManager(mlManageClient).deleteByIdField(mlFinalAppserverName + "-TEST")
return true
})
def dbManager = new com.marklogic.mgmt.resource.databases.DatabaseManager(mlManageClient)
dbManager.deleteByName(mlStagingDbName + "-TEST")
dbManager.deleteByName(mlFinalDbName + "-TEST")
}
}
mlUndeploy.dependsOn hubUndeployTestResources
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.node.ObjectNode
import com.fasterxml.jackson.databind.node.TextNode
import com.marklogic.appdeployer.command.CommandContext;
import com.marklogic.hub.HubConfig
import java.util.regex.Pattern
class DeployHubTestDatabaseCommand extends com.marklogic.hub.deploy.commands.DeployHubDatabaseCommand {
String testDatabaseName
DeployHubTestDatabaseCommand(HubConfig config, File testDbFile, String sourceDatabaseFilename, String testDatabaseName) {
super(config, testDbFile, sourceDatabaseFilename)
this.testDatabaseName = testDatabaseName
}
@Override
protected String getPayload(CommandContext context) {
String payload = super.getPayload(context)
ObjectNode node = new ObjectMapper().readTree(payload)
node.set("database-name", new TextNode(testDatabaseName))
return node.toString()
}
}
class DeployHubTestServerCommand extends com.marklogic.hub.deploy.commands.DeployHubOtherServersCommand {
String serverName
int port
String contentDatabaseName
DeployHubTestServerCommand(String serverFilenamePattern, String serverName, int port, String contentDatabaseName) {
super()
setResourceFilenamesIncludePattern(Pattern.compile(serverFilenamePattern))
this.serverName = serverName
this.port = port
this.contentDatabaseName = contentDatabaseName
}
@Override
protected String copyFileToString(File f) {
String payload = super.copyFileToString(f)
ObjectNode node = new ObjectMapper().readTree(payload)
node.set("server-name", new TextNode(serverName))
node.set("port", new TextNode(port + ""))
node.set("content-database", new TextNode(contentDatabaseName))
return node.toString()
}
}
@paxtonhare
Copy link

UPDATE FOR DHF 5.1

/*** TEST INFRASTRUCTURE *****
 ***
 *** Creates data-hub-FINAL-TEST, data-hub-STAGING-TEST
 ***
 ***/

/**
 * The below tasks are used for deploying and undeploying test resources for a DHF 5 application. Just copy everything below
 * this comment into the build.gradle file in your DHF application - no properties need to be set for these tasks to work.
 *
 * The task "hubDeployTestResources" will deploy test versions of your staging and final databases and app servers. You
 * can customize these tasks if you don't like the resource names and ports that are used by them. Note that mlDeploy
 * does not depend on this task by default - you'll need to invoke it in order to create test resources.
 *
 * The task "hubUndeployTestResources" will undeploy any test resources that were created. mlUndeploy does depend on
 * this task as there's typically no downside to undeploying these resources - if they don't exist, the task will
 * quickly complete.
 */

task hubDeployTestStagingDatabase(type: com.marklogic.gradle.task.MarkLogicTask) {
    doLast {
        File testDbFile = new File(buildDir, "test-staging-database.json")
        testDbFile.write(new File("src/main/hub-internal-config/databases/staging-database.json").text)
        new DeployHubTestDatabaseCommand(hubConfig, testDbFile, "staging-database.json", mlStagingDbName + "-TEST").execute(mlCommandContext)
    }
}

task hubDeployTestFinalDatabase(type: com.marklogic.gradle.task.MarkLogicTask) {
    doLast {
        File testDbFile = new File(buildDir, "test-final-database.json")
        testDbFile.write(new File("src/main/ml-config/databases/final-database.json").text)
        new DeployHubTestDatabaseCommand(hubConfig, testDbFile, "final-database.json", mlFinalDbName + "-TEST").execute(mlCommandContext)
    }
}

task hubDeployTestDatabases(type: com.marklogic.gradle.task.MarkLogicTask) {
    dependsOn = ["hubDeployTestStagingDatabase", "hubDeployTestFinalDatabase"]
}

task hubDeployTestServers(type: com.marklogic.gradle.task.MarkLogicTask) {
    doLast {
        new DeployHubTestServerCommand(dataHub, "staging-server.json", mlStagingAppserverName + "-TEST", 8014, mlStagingDbName + "-TEST").execute(mlCommandContext);
        new DeployHubTestServerCommand(dataHub, "final-server.json", mlFinalAppserverName + "-TEST", 8015, mlFinalDbName + "-TEST").execute(mlCommandContext);
    }
}

task hubDeployTestResources {
    description = "Deploys test databases and servers"
    dependsOn = ["hubDeployTestDatabases", "hubDeployTestServers"]
}
hubDeployTestServers.mustRunAfter hubDeployTestDatabases

task hubUndeployTestResources(type: com.marklogic.gradle.task.MarkLogicTask) {
    description = "Undeploys the test servers and databases that were created via hubDeployTestResources"
    doLast {
        mlAdminManager.invokeActionRequiringRestart({
            new com.marklogic.mgmt.resource.appservers.ServerManager(mlManageClient).deleteByIdField(mlStagingAppserverName + "-TEST")
            return true
        })
        mlAdminManager.invokeActionRequiringRestart({
            new com.marklogic.mgmt.resource.appservers.ServerManager(mlManageClient).deleteByIdField(mlFinalAppserverName + "-TEST")
            return true
        })
        def dbManager = new com.marklogic.mgmt.resource.databases.DatabaseManager(mlManageClient)
        dbManager.deleteByName(mlStagingDbName + "-TEST")
        dbManager.deleteByName(mlFinalDbName + "-TEST")
    }
}
mlUndeploy.dependsOn hubUndeployTestResources

@grtjn
Copy link

grtjn commented Sep 25, 2020

Don't hard-code port numbers.. :P

@s3-4v
Copy link

s3-4v commented Oct 1, 2021

Thanks, this worked in projects before, but now using ml-data-hub 5.5.3, I am seeing build errors about being "unable to resolve class DeployHubTestDatabaseCommand" -- open to suggestions, thanks!

@rjrudin
Copy link
Author

rjrudin commented Oct 1, 2021

Unfortunately the approach above depends on private APIs within the DHF codebase and is thus not guaranteed to work across minor versions. DHF 5.5 does introduce support for reusing marklogic-unit-test, but it does not support standing up test-specific app servers and databases. The general recommendation then is to use a separate cluster for running tests against a DHF instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment