mirror of
https://github.com/google/nomulus
synced 2026-06-09 16:33:02 +00:00
75524fd403
This commit reverts changes from5599a0eb3dand most of5286b1a0dc(PR #3068) that stripped essential dependencies (buildConsoleForAll, buildNomulusImage, buildToolImage, fragileTest) from the default './gradlew build' target, which broke downstream deployment pipelines. It restores the default build to correctly generate all necessary production artifacts and Docker images. It introduces a new 'fastBuild' target designed explicitly for local developers and CI checks. This lightweight target disables the execution of heavy Docker image builds, Angular compilations, and fragile tests to provide rapid feedback. Sequential execution constraints for parallel Angular builds are maintained to prevent cache corruption. It updates the ':core:generateSqlSchema' task to execute using the 'unittest' environment instead of 'alpha'. The 'alpha' configuration is a private, internal environment config that is not distributed in the open-source repository, which caused the task to fail for public contributors. By switching to 'unittest', the generator can successfully run using the public test configuration. With this fixed, it also includes the newly generated 'db-schema.sql.generated' file, which now correctly tracks the 'FORBID_INSECURE_ALGORITHMS_RFC_9904' feature flag that was recently added. Finally, it implements a split-runner execution strategy for the 'sqlIntegrationTest' task to permanently resolve 'failed to discover tests' and 'NoSuchMethodError' exceptions on Kokoro. Because Kokoro tests cross-version compatibility against both legacy deployed artifacts (compiled with JUnit 4 @RunWith wrappers) and modern artifacts (compiled with JUnit 5 @Suite annotations), we cannot statically configure a single test runner. We now dynamically run both the legacy 'useJUnit()' and modern 'useJUnitPlatform()' runners sequentially with 'failOnNoDiscoveredTests' disabled, allowing the appropriate engine to discover and execute the suite without causing classpath collisions.
750 lines
29 KiB
Groovy
750 lines
29 KiB
Groovy
// Copyright 2019 The Nomulus Authors. All Rights Reserved.
|
|
//
|
|
// 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.
|
|
|
|
import com.google.common.base.CaseFormat
|
|
import java.util.Optional
|
|
|
|
plugins {
|
|
id 'java-library'
|
|
id "org.flywaydb.flyway" version "12.2.0"
|
|
id 'maven-publish'
|
|
}
|
|
|
|
// Path to code generated by ad hoc tasks in this project. A separate path is
|
|
// used for easy inspection.
|
|
def generatedDir = "${project.buildDir}/generated/sources/custom/java/main"
|
|
def resourcesDir = "${project.buildDir}/resources/main"
|
|
def screenshotsDir = "${project.buildDir}/screenshots"
|
|
def screenshotsForGoldensDir = "${project.buildDir}/screenshots_for_goldens"
|
|
def newGoldensDir = "${project.buildDir}/new_golden_images"
|
|
def goldensDir =
|
|
"${javaTestDir}/google/registry/webdriver/goldens/chrome-linux"
|
|
|
|
// Tests that fail when running Gradle in a docker container, e. g. when
|
|
// building the release artifacts in Google Cloud Build.
|
|
def dockerIncompatibleTestPatterns = [
|
|
// The webdriver tests start headless Chrome in a Docker container,
|
|
// resulting in Docker-in-Docker complications. Likewise,
|
|
// GenerateSqlSchemaCommandTest and DumpGoldenSchemaCommandTest launch
|
|
// postgresql in a docker container.
|
|
"google/registry/webdriver/*",
|
|
"google/registry/tools/GenerateSqlSchemaCommandTest.*",
|
|
"google/registry/tools/DumpGoldenSchemaCommandTest.*",
|
|
// PathParameterTest includes tests which validate that file permissions are
|
|
// respected. However when running in Docker the user is root by default, so
|
|
// every file is read/write-able. There is no way to exclude specific test
|
|
// methods, so we exclude the whole test class.
|
|
"google/registry/tools/params/PathParameterTest.*",
|
|
"google/registry/persistence/PersistenceModuleTest.*",
|
|
]
|
|
|
|
// Tests that conflict with members of the main test suite. They seem to be
|
|
// affected by global states outside of Nomulus classes, e.g., threads and
|
|
// objects retained by frameworks.
|
|
// TODO(weiminyu): identify cause and fix offending tests.
|
|
def fragileTestPatterns = dockerIncompatibleTestPatterns
|
|
|
|
sourceSets {
|
|
main {
|
|
java {
|
|
srcDirs += generatedDir
|
|
}
|
|
resources {
|
|
exclude '**/*.xjb'
|
|
}
|
|
}
|
|
nonprod {
|
|
java {
|
|
compileClasspath += main.output
|
|
runtimeClasspath += main.output
|
|
}
|
|
}
|
|
test {
|
|
java {
|
|
compileClasspath += nonprod.output
|
|
runtimeClasspath += nonprod.output
|
|
}
|
|
resources {
|
|
exclude '**/*.xjb', '**/*.xsd'
|
|
}
|
|
}
|
|
}
|
|
|
|
processTestResources {
|
|
exclude '**/webdriver/*'
|
|
}
|
|
|
|
configurations {
|
|
jaxb
|
|
devtool
|
|
|
|
nonprodImplementation.extendsFrom implementation
|
|
nonprodRuntimeOnly.extendsFrom runtimeOnly
|
|
|
|
testImplementation.extendsFrom nonprodImplementation
|
|
|
|
// Published jars that are used for server/schema compatibility tests.
|
|
// See <a href="../integration/README.md">the integration project</a>
|
|
// for details.
|
|
nomulus_test {
|
|
canBeConsumed = true
|
|
canBeResolved = false
|
|
}
|
|
testRuntimeElements {
|
|
canBeConsumed = true
|
|
canBeResolved = false
|
|
extendsFrom testRuntimeOnly
|
|
}
|
|
|
|
// Exclude non-canonical servlet-api jars. Our deployment uses
|
|
// javax.servlet:servlet-api:2.5
|
|
// For reasons we do not understand, marking the following dependencies as
|
|
// compileOnly instead of compile does not exclude them from runtimeClasspath.
|
|
all {
|
|
// servlet-api:3.1 pulled in but not used
|
|
exclude group: 'javax.servlet', module: 'javax.servlet-api'
|
|
}
|
|
}
|
|
|
|
dependencies {
|
|
def deps = rootProject.dependencyMap
|
|
|
|
testRuntimeOnly files(sourceSets.test.resources.srcDirs)
|
|
|
|
implementation deps['com.github.ben-manes.caffeine:caffeine']
|
|
implementation deps['com.google.api:gax']
|
|
implementation deps['com.google.api.grpc:proto-google-common-protos']
|
|
implementation deps['com.google.api.grpc:proto-google-cloud-secretmanager-v1']
|
|
implementation deps['com.google.api-client:google-api-client']
|
|
implementation deps['com.google.api-client:google-api-client-servlet']
|
|
implementation deps['com.google.monitoring-client:metrics']
|
|
implementation deps['com.google.monitoring-client:stackdriver']
|
|
implementation deps['com.google.api-client:google-api-client-java6']
|
|
implementation deps['com.google.api.grpc:proto-google-cloud-tasks-v2']
|
|
implementation deps['com.google.apis:google-api-services-admin-directory']
|
|
implementation deps['com.google.apis:google-api-services-bigquery']
|
|
implementation deps['com.google.apis:google-api-services-dataflow']
|
|
implementation deps['com.google.apis:google-api-services-dns']
|
|
implementation deps['com.google.apis:google-api-services-drive']
|
|
implementation deps['com.google.apis:google-api-services-gmail']
|
|
implementation deps['com.google.apis:google-api-services-groupssettings']
|
|
implementation deps['com.google.apis:google-api-services-iam']
|
|
implementation deps['com.google.apis:google-api-services-monitoring']
|
|
implementation deps['com.google.apis:google-api-services-sheets']
|
|
implementation deps['com.google.apis:google-api-services-storage']
|
|
implementation deps['com.google.auth:google-auth-library-credentials']
|
|
implementation deps['com.google.auth:google-auth-library-oauth2-http']
|
|
implementation deps['com.google.cloud.bigdataoss:util']
|
|
implementation deps['com.google.cloud.sql:jdbc-socket-factory-core']
|
|
runtimeOnly deps['com.google.cloud.sql:postgres-socket-factory']
|
|
implementation deps['com.google.cloud:google-cloud-secretmanager']
|
|
implementation deps['com.google.code.gson:gson']
|
|
implementation deps['com.google.auto.service:auto-service-annotations']
|
|
implementation deps['com.google.auto.value:auto-value-annotations']
|
|
implementation deps['com.google.code.findbugs:jsr305']
|
|
implementation deps['com.google.dagger:dagger']
|
|
implementation deps['com.google.errorprone:error_prone_annotations']
|
|
implementation deps['com.google.flogger:flogger']
|
|
implementation deps['com.google.guava:guava']
|
|
implementation deps['com.google.protobuf:protobuf-java']
|
|
implementation deps['com.google.cloud:google-cloud-compute']
|
|
implementation deps['com.google.cloud:google-cloud-core']
|
|
implementation deps['com.google.cloud:google-cloud-storage']
|
|
implementation deps['com.google.cloud:google-cloud-tasks']
|
|
implementation deps['com.google.http-client:google-http-client']
|
|
implementation deps['com.google.http-client:google-http-client-jackson2']
|
|
implementation deps['com.google.oauth-client:google-oauth-client']
|
|
implementation deps['com.google.oauth-client:google-oauth-client-java6']
|
|
implementation deps['com.google.oauth-client:google-oauth-client-jetty']
|
|
implementation deps['com.google.oauth-client:google-oauth-client-servlet']
|
|
implementation deps['com.google.re2j:re2j']
|
|
implementation deps['org.freemarker:freemarker']
|
|
implementation deps['com.github.mwiede:jsch']
|
|
implementation deps['com.zaxxer:HikariCP']
|
|
implementation deps['com.squareup.okhttp3:okhttp']
|
|
implementation deps['dnsjava:dnsjava']
|
|
testRuntimeOnly deps['guru.nidi:graphviz-java-all-j2v8']
|
|
testImplementation deps['io.github.classgraph:classgraph']
|
|
testRuntimeOnly deps['io.github.java-diff-utils:java-diff-utils']
|
|
testImplementation deps['io.github.ss-bhatt:testcontainers-valkey']
|
|
implementation deps['io.protostuff:protostuff-core']
|
|
implementation deps['io.protostuff:protostuff-runtime']
|
|
implementation deps['jakarta.inject:jakarta.inject-api']
|
|
implementation deps['jakarta.mail:jakarta.mail-api']
|
|
implementation deps['jakarta.persistence:jakarta.persistence-api']
|
|
implementation deps['jakarta.servlet:jakarta.servlet-api']
|
|
implementation deps['jakarta.xml.bind:jakarta.xml.bind-api']
|
|
implementation deps['org.antlr:antlr4']
|
|
implementation deps['org.antlr:antlr4-runtime']
|
|
implementation deps['org.apache.avro:avro']
|
|
testImplementation deps['org.apache.beam:beam-runners-core-construction-java']
|
|
testImplementation deps['org.apache.beam:beam-runners-direct-java']
|
|
implementation deps['org.apache.beam:beam-runners-google-cloud-dataflow-java']
|
|
implementation deps['org.apache.beam:beam-sdks-java-core']
|
|
implementation deps['org.apache.beam:beam-sdks-java-extensions-google-cloud-platform-core']
|
|
implementation deps['org.apache.beam:beam-sdks-java-io-google-cloud-platform']
|
|
implementation deps['org.apache.commons:commons-csv']
|
|
implementation deps['org.apache.commons:commons-lang3']
|
|
testImplementation deps['org.apache.commons:commons-text']
|
|
testImplementation deps['org.apache.ftpserver:ftplet-api']
|
|
testImplementation deps['org.apache.ftpserver:ftpserver-core']
|
|
implementation deps['org.apache.httpcomponents:httpclient']
|
|
implementation deps['org.apache.httpcomponents:httpcore']
|
|
testImplementation deps['org.apache.sshd:sshd-core']
|
|
testImplementation deps['org.apache.sshd:sshd-scp']
|
|
testImplementation deps['org.apache.sshd:sshd-sftp']
|
|
testImplementation deps['org.apache.tomcat:tomcat-annotations-api']
|
|
implementation deps['org.bouncycastle:bcpg-jdk18on']
|
|
implementation deps['org.bouncycastle:bcpkix-jdk18on']
|
|
implementation deps['org.bouncycastle:bcprov-jdk18on']
|
|
implementation deps['com.fasterxml.jackson.dataformat:jackson-dataformat-yaml']
|
|
testImplementation deps['com.fasterxml.jackson.core:jackson-databind']
|
|
implementation deps['org.hibernate.orm:hibernate-ant']
|
|
implementation deps['org.hibernate.orm:hibernate-core']
|
|
implementation deps['org.hibernate.orm:hibernate-hikaricp']
|
|
implementation deps['org.jcommander:jcommander']
|
|
implementation deps['org.jline:jline']
|
|
implementation deps['org.joda:joda-money']
|
|
implementation deps['org.json:json']
|
|
implementation deps['org.jsoup:jsoup']
|
|
testImplementation deps['org.eclipse.jetty:jetty-server']
|
|
testImplementation deps['org.eclipse.jetty.ee10:jetty-ee10-servlet']
|
|
testImplementation deps['org.eclipse.jetty.ee10:jetty-ee10-webapp']
|
|
implementation deps['org.postgresql:postgresql']
|
|
testImplementation deps['org.seleniumhq.selenium:selenium-api']
|
|
testImplementation deps['org.seleniumhq.selenium:selenium-chrome-driver']
|
|
testImplementation deps['org.seleniumhq.selenium:selenium-java']
|
|
testImplementation deps['org.seleniumhq.selenium:selenium-remote-driver']
|
|
runtimeOnly deps['org.slf4j:slf4j-jdk14']
|
|
testImplementation deps['org.testcontainers:jdbc']
|
|
testImplementation deps['org.testcontainers:junit-jupiter']
|
|
implementation deps['org.testcontainers:postgresql']
|
|
testImplementation deps['org.testcontainers:selenium']
|
|
testImplementation deps['org.testcontainers:testcontainers']
|
|
implementation deps['redis.clients:jedis']
|
|
implementation deps['us.fatehi:schemacrawler']
|
|
implementation deps['us.fatehi:schemacrawler-api']
|
|
implementation deps['us.fatehi:schemacrawler-diagram']
|
|
implementation deps['us.fatehi:schemacrawler-tools']
|
|
implementation deps['us.fatehi:schemacrawler-postgresql']
|
|
implementation deps['xerces:xmlParserAPIs']
|
|
implementation deps['org.ogce:xpp3']
|
|
// Known issue: nebula-lint misses inherited dependency.
|
|
implementation project(':common')
|
|
testImplementation project(path: ':common', configuration: 'testing')
|
|
implementation project(':util')
|
|
// Import NomulusPostreSql from ':db' for implementation but exclude dependencies.
|
|
implementation project(path: ':db', configuration: 'implementationApi')
|
|
nonprodRuntimeOnly project(':db')
|
|
testRuntimeOnly project(':db')
|
|
|
|
annotationProcessor deps['com.google.auto.service:auto-service']
|
|
annotationProcessor deps['com.google.auto.value:auto-value']
|
|
testAnnotationProcessor deps['com.google.auto.value:auto-value']
|
|
annotationProcessor deps['com.google.dagger:dagger-compiler']
|
|
testAnnotationProcessor deps['com.google.dagger:dagger-compiler']
|
|
annotationProcessor project(':processor')
|
|
testAnnotationProcessor project(':processor')
|
|
|
|
testImplementation deps['com.google.cloud:google-cloud-nio']
|
|
testImplementation deps['com.google.guava:guava-testlib']
|
|
testImplementation deps['com.google.monitoring-client:contrib']
|
|
testImplementation deps['com.google.protobuf:protobuf-java-util']
|
|
testImplementation deps['com.google.truth:truth']
|
|
testImplementation deps['org.checkerframework:checker-qual']
|
|
testImplementation deps['org.hamcrest:hamcrest']
|
|
testImplementation deps['org.hamcrest:hamcrest-core']
|
|
testImplementation deps['org.hamcrest:hamcrest-library']
|
|
testImplementation deps['org.junit.jupiter:junit-jupiter-api']
|
|
testImplementation deps['org.junit.jupiter:junit-jupiter-engine']
|
|
testImplementation deps['org.junit.jupiter:junit-jupiter-migrationsupport']
|
|
testImplementation deps['org.junit.jupiter:junit-jupiter-params']
|
|
testImplementation deps['org.junit-pioneer:junit-pioneer']
|
|
testImplementation deps['org.junit.platform:junit-platform-runner']
|
|
testImplementation deps['org.junit.platform:junit-platform-suite-api']
|
|
testImplementation deps['org.junit.platform:junit-platform-suite']
|
|
testImplementation deps['org.mockito:mockito-core']
|
|
testImplementation deps['org.mockito:mockito-junit-jupiter']
|
|
|
|
// Indirect dependency found by undeclared-dependency check. Such
|
|
// dependencies should go after all other implementation and testImplementation
|
|
// dependencies to avoid overriding them accidentally.
|
|
implementation deps['com.google.oauth-client:google-oauth-client-java6']
|
|
|
|
// Dependencies needed for jaxb compilation.
|
|
jaxb deps['jakarta.xml.bind:jakarta.xml.bind-api']
|
|
jaxb deps['org.glassfish.jaxb:jaxb-runtime']
|
|
jaxb deps['org.glassfish.jaxb:jaxb-xjc']
|
|
|
|
// Flyway classes needed to generate the golden file.
|
|
implementation deps['org.flywaydb:flyway-core']
|
|
implementation deps['org.flywaydb:flyway-database-postgresql']
|
|
}
|
|
|
|
task jaxbToJava {
|
|
def xsdFilesDir = "${javaDir}/google/registry/xml/xsd"
|
|
def bindingsFile = "${javaDir}/google/registry/xjc/bindings.xjb"
|
|
def pkgInfoTemplate = "${javaDir}/google/registry/xjc/package-info.java.in"
|
|
def pkgInfoMap = "${javaDir}/google/registry/xjc/package-info.map"
|
|
def outputDir = "${generatedDir}/google/registry/xjc"
|
|
|
|
inputs.dir xsdFilesDir
|
|
inputs.files bindingsFile, pkgInfoTemplate, pkgInfoMap
|
|
outputs.dir outputDir
|
|
|
|
doLast {
|
|
file(generatedDir).mkdirs()
|
|
|
|
// Temp dir to hold schema and bindings files. Files must be in the same
|
|
// directory because the bindings (.xjb) file does not declare relative
|
|
// paths to schema (.xsd) files.
|
|
def xjcTempSourceDir = file("${temporaryDir}/xjc")
|
|
xjcTempSourceDir.mkdirs()
|
|
ant.copy(
|
|
todir: "${xjcTempSourceDir}",
|
|
overwrite: true) {
|
|
fileSet(
|
|
dir: xsdFilesDir,
|
|
includes: '**.xsd')
|
|
}
|
|
ant.copy(
|
|
todir: "${xjcTempSourceDir}",
|
|
overwrite: true,
|
|
file: bindingsFile)
|
|
ant.taskdef(
|
|
name: 'xjc',
|
|
classname: 'com.sun.tools.xjc.XJCTask',
|
|
classpath: configurations.jaxb.asPath)
|
|
ant.xjc(
|
|
destdir: "${generatedDir}",
|
|
binding: "${xjcTempSourceDir}/bindings.xjb",
|
|
removeOldOutput: 'yes', extension: 'true') {
|
|
fileTree(
|
|
dir: new File("$xjcTempSourceDir"),
|
|
include: ['**/*.xsd'])
|
|
.addToAntBuilder(ant, 'schema', FileCollection.AntType.FileSet)
|
|
// -npa: do not generate package-info.java files. They will be generated
|
|
// below.
|
|
arg(line: '-npa -quiet -extension')
|
|
}
|
|
new File(pkgInfoMap).eachLine { line ->
|
|
def (packageName, namespace) = line.split()
|
|
ant.copy(
|
|
tofile: "${outputDir}/${packageName}/package-info.java",
|
|
overwrite: true,
|
|
file: "${pkgInfoTemplate}") {
|
|
filterSet() {
|
|
filter(token: 'PACKAGE', value: packageName)
|
|
filter(token: 'NAMESPACE', value: namespace)
|
|
}
|
|
}
|
|
}
|
|
execInBash(
|
|
"find . -name *.java -exec sed -i -e '/" + /\* <p>$/ + "/d' {} +",
|
|
generatedDir)
|
|
}
|
|
}
|
|
|
|
compileJava.dependsOn jaxbToJava
|
|
|
|
// Make testing artifacts available to be depended up on by other projects.
|
|
// TODO: factor out google.registry.testing to be a separate project.
|
|
task testJar(type: Jar) {
|
|
archiveClassifier = 'test'
|
|
from sourceSets.test.output
|
|
}
|
|
|
|
artifacts {
|
|
add('testRuntimeElements', testJar)
|
|
}
|
|
|
|
task findGoldenImages(type: JavaExec) {
|
|
classpath = sourceSets.test.runtimeClasspath
|
|
mainClass = 'google.registry.webdriver.GoldenImageFinder'
|
|
jvmArgs "--sun-misc-unsafe-memory-access=allow"
|
|
def arguments = []
|
|
arguments << "--screenshots_for_goldens_dir=${screenshotsForGoldensDir}"
|
|
arguments << "--new_goldens_dir=${newGoldensDir}"
|
|
arguments << "--existing_goldens_dir=${goldensDir}"
|
|
if (rootProject.findProperty("overrideExistingGoldens") == "true") {
|
|
arguments << "--override_existing_goldens=true"
|
|
}
|
|
args arguments
|
|
}
|
|
|
|
Optional<List<String>> getToolArgsList() {
|
|
// If "-PtoolArgs=..." is present in the command line, use it to set the args,
|
|
// otherwise use the default flag, which is "--args" to set the args.
|
|
def toolArgs = rootProject.findProperty("toolArgs")
|
|
if (toolArgs != null) {
|
|
def delimiter = '|'
|
|
toolArgs += delimiter
|
|
def argsList = []
|
|
def currArg = ''
|
|
for (def i = 0; i < toolArgs.length(); i++) {
|
|
def currChar = toolArgs[i]
|
|
if (currChar != delimiter) {
|
|
currArg += currChar
|
|
} else if (i != 0 && toolArgs[i - 1] == '\\') {
|
|
currArg = currArg.substring(0, currArg.length() - 1) + currChar
|
|
} else {
|
|
argsList.add(currArg)
|
|
currArg = ''
|
|
}
|
|
}
|
|
return Optional.of(argsList)
|
|
}
|
|
return Optional.empty()
|
|
}
|
|
|
|
// To run the nomulus tools with these command line tokens:
|
|
// "--foo", "bar baz", "--qux=quz"
|
|
// gradle core:registryTool --args="--foo 'bar baz' --qux=quz"
|
|
// or:
|
|
// gradle core:registryTool -PtoolArgs="--foo|bar baz|--qux=quz"
|
|
// Note that the delimiting pipe can be backslash escaped if it is part of a
|
|
// parameter.
|
|
ext.createToolTask = {
|
|
taskName,
|
|
mainClassName,
|
|
sourceSet = sourceSets.main ->
|
|
project.tasks.create(taskName, JavaExec) {
|
|
classpath = sourceSet.runtimeClasspath
|
|
mainClass = mainClassName
|
|
jvmArgs "--sun-misc-unsafe-memory-access=allow", "--enable-native-access=ALL-UNNAMED"
|
|
|
|
doFirst {
|
|
getToolArgsList().ifPresent {
|
|
args it
|
|
}
|
|
}
|
|
}
|
|
}
|
|
createToolTask('registryTool', 'google.registry.tools.RegistryTool')
|
|
createToolTask(
|
|
'devTool',
|
|
'google.registry.tools.DevTool',
|
|
sourceSets.nonprod)
|
|
|
|
project.tasks.create('generateSqlSchema', JavaExec) {
|
|
classpath = sourceSets.nonprod.runtimeClasspath
|
|
mainClass = 'google.registry.tools.DevTool'
|
|
jvmArgs "--sun-misc-unsafe-memory-access=allow"
|
|
args = [
|
|
'-e', 'unittest',
|
|
'generate_sql_schema', '--start_postgresql', '-o',
|
|
"${rootProject.projectRootDir}/db/src/main/resources/sql/schema/" +
|
|
"db-schema.sql.generated"
|
|
]
|
|
}
|
|
|
|
task generateGoldenImages(type: FilteringTest) {
|
|
tests = ["**/webdriver/*"]
|
|
|
|
// Sets the maximum number of test executors that may exist at the same time.
|
|
maxParallelForks = 5
|
|
|
|
systemProperty 'test.screenshot.dir', screenshotsForGoldensDir
|
|
systemProperty 'test.screenshot.runAllAttempts', 'true'
|
|
systemProperty 'test.screenshot.maxAttempts', '5'
|
|
|
|
doFirst {
|
|
new File(screenshotsForGoldensDir).deleteDir()
|
|
}
|
|
}
|
|
generateGoldenImages.finalizedBy(findGoldenImages)
|
|
|
|
createUberJar('nomulus', 'nomulus', 'google.registry.tools.RegistryTool')
|
|
|
|
// Build the Uber jar shared by all flex-template based BEAM pipelines.
|
|
// This packages more code and dependency than necessary. However, without
|
|
// restructuring the source tree it is difficult to generate leaner jars.
|
|
createUberJar(
|
|
'beamPipelineCommon',
|
|
'beam_pipeline_common',
|
|
'')
|
|
|
|
// Create beam staging task if the environment is alpha. Production, sandbox and
|
|
// qa use formally released pipelines through CloudBuild, whereas crash and
|
|
// alpha use the pipelines staged on alpha deployment project.
|
|
//
|
|
// User should install gcloud and login to GCP before invoking this tasks.
|
|
if (environment == 'alpha') {
|
|
def pipelines = [
|
|
spec11 :
|
|
[
|
|
mainClass: 'google.registry.beam.spec11.Spec11Pipeline',
|
|
metaData : 'google/registry/beam/spec11_pipeline_metadata.json'
|
|
],
|
|
invoicing :
|
|
[
|
|
mainClass: 'google.registry.beam.billing.InvoicingPipeline',
|
|
metaData : 'google/registry/beam/invoicing_pipeline_metadata.json'
|
|
],
|
|
expandBilling :
|
|
[
|
|
mainClass: 'google.registry.beam.billing.ExpandBillingRecurrencesPipeline',
|
|
metaData : 'google/registry/beam/expand_billing_recurrences_pipeline_metadata.json'
|
|
],
|
|
rde :
|
|
[
|
|
mainClass: 'google.registry.beam.rde.RdePipeline',
|
|
metaData : 'google/registry/beam/rde_pipeline_metadata.json'
|
|
],
|
|
resaveAllEppResources:
|
|
[
|
|
mainClass: 'google.registry.beam.resave.ResaveAllEppResourcesPipeline',
|
|
metaData: 'google/registry/beam/resave_all_epp_resources_pipeline_metadata.json'
|
|
],
|
|
smokeTest:
|
|
[
|
|
mainClass: 'google.registry.beam.common.SmokeTestPipeline',
|
|
metaData: 'google/registry/beam/smoke_test_pipeline_metadata.json'
|
|
],
|
|
]
|
|
project.tasks.create("stageBeamPipelines") {
|
|
doLast {
|
|
pipelines.each {
|
|
if (rootProject.pipeline == ''|| rootProject.pipeline == it.key) {
|
|
def mainClass = it.value['mainClass']
|
|
def metaData = it.value['metaData']
|
|
def pipelineName = CaseFormat.UPPER_CAMEL.to(
|
|
CaseFormat.LOWER_UNDERSCORE,
|
|
mainClass.substring(mainClass.lastIndexOf('.') + 1))
|
|
def imageName = "gcr.io/${gcpProject}/beam/${pipelineName}"
|
|
def metaDataBaseName = metaData.substring(metaData.lastIndexOf('/') + 1)
|
|
def uberJarName = tasks.beamPipelineCommon.outputs.files.asPath
|
|
|
|
def command = "\
|
|
gcloud dataflow flex-template build \
|
|
gs://${gcpProject}-deploy/live/beam/${metaDataBaseName} \
|
|
--image-gcr-path ${imageName}:live \
|
|
--sdk-language JAVA \
|
|
--flex-template-base-image gcr.io/dataflow-templates-base/java25-template-launcher-base:latest \
|
|
--metadata-file ${projectDir}/src/main/resources/${metaData} \
|
|
--jar ${uberJarName} \
|
|
--env FLEX_TEMPLATE_JAVA_MAIN_CLASS=${mainClass} \
|
|
--project ${gcpProject}".toString()
|
|
rootProject.ext.execInBash(command, '/tmp')
|
|
}
|
|
}
|
|
}
|
|
}.dependsOn(tasks.beamPipelineCommon)
|
|
}
|
|
|
|
// A jar with classes and resources from main sourceSet, excluding internal
|
|
// data. See comments on configurations.nomulus_test above for details.
|
|
// TODO(weiminyu): release process should build this using the public repo to eliminate the need
|
|
// for excludes.
|
|
task nomulusFossJar (type: Jar) {
|
|
archiveBaseName = 'nomulus'
|
|
archiveClassifier = 'public'
|
|
from (project.sourceSets.main.output) {
|
|
exclude 'google/registry/config/files/**'
|
|
exclude 'google/registry/proxy/config/**'
|
|
}
|
|
from (project.sourceSets.main.output) {
|
|
include 'google/registry/config/files/default-config.yaml'
|
|
include 'google/registry/config/files/nomulus-config-unittest.yaml'
|
|
}
|
|
}
|
|
|
|
// An UberJar of registry test classes, resources and all dependencies.
|
|
// See comments on configurations.nomulus_test above for details.
|
|
createUberJar(
|
|
'testUberJar',
|
|
'nomulus-tests',
|
|
'',
|
|
[project.configurations.testRuntimeClasspath],
|
|
[project.sourceSets.test.output],
|
|
[
|
|
// Exclude SQL schema, which is a test dependency.
|
|
'sql/flyway/**',
|
|
// ShadowJar includes java source files when used on
|
|
// sourceSets.test.output.
|
|
'**/*.java'
|
|
])
|
|
tasks.testUberJar {
|
|
archiveClassifier = 'alldeps'
|
|
}
|
|
|
|
artifacts {
|
|
nomulus_test nomulusFossJar
|
|
nomulus_test testUberJar
|
|
}
|
|
|
|
task buildToolImage(dependsOn: nomulus, type: Exec) {
|
|
commandLine 'docker', 'build', '-t', 'nomulus-tool', '.'
|
|
}
|
|
|
|
// Build the devtool jar.
|
|
createUberJar(
|
|
'devtool',
|
|
'devtool',
|
|
'google.registry.tools.DevTool',
|
|
[ project.configurations.nonprodRuntimeClasspath ],
|
|
[ project.sourceSets.nonprod.output, sourceSets.main.output ],
|
|
[ '**/*.java' ])
|
|
|
|
artifacts {
|
|
devtool devtool
|
|
}
|
|
|
|
task runTestServer(type: JavaExec) {
|
|
mainClass = 'google.registry.server.RegistryTestServerMain'
|
|
classpath = sourceSets.test.runtimeClasspath
|
|
jvmArgs "--sun-misc-unsafe-memory-access=allow"
|
|
dependsOn(rootProject.project('console-webapp').tasks.named('buildConsoleWebapp'))
|
|
}
|
|
|
|
/**
|
|
* We have to break out the test suites because some of the tests conflict
|
|
* with one another, but unfortunately this breaks the "--tests" flag. The
|
|
* --tests flag only applies to the task named on the command line (usually
|
|
* just "test"), not for all tasks of type "Test".
|
|
*
|
|
* As a better solution, FilteringTest sets testNameIncludePatterns (the
|
|
* internal property that --tests sets) from the value of the "testFilter"
|
|
* property, allowing us to filter across all the tests in core without
|
|
* explicitly specifying a test task or causing errors because there are no
|
|
* matching tests in the main task.
|
|
*
|
|
* To use it, define "testFilter" to be a comma-separated collection of class
|
|
* names (wildcards are allowed):
|
|
*
|
|
* ./gradlew test -P testFilter=*.FooBar,google.registry.tools.ShellCommandTest
|
|
*/
|
|
abstract class FilteringTest extends Test {
|
|
|
|
FilteringTest() {
|
|
useJUnitPlatform();
|
|
testClassesDirs = project.sourceSets.test.output.classesDirs
|
|
classpath = project.sourceSets.test.runtimeClasspath
|
|
}
|
|
|
|
private void applyTestFilter() {
|
|
if (project.testFilter) {
|
|
testNameIncludePatterns = project.testFilter.split(',')
|
|
|
|
// By default, gradle test tasks will produce a failure if no tests
|
|
// match the include/exclude/filter rules. Since test filtering allows us
|
|
// to select a set of tests from a particular task, we don't want this
|
|
// behavior.
|
|
filter.failOnNoMatchingTests = false
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set to false if you also want to include TestCase and TestSuite classes.
|
|
*
|
|
* <p>Must be defined before "test", if at all.
|
|
*/
|
|
@Input
|
|
boolean excludeTestCases = true
|
|
|
|
void setTests(List<String> tests) {
|
|
// Common exclude pattern. See README in parent directory for explanation.
|
|
if (excludeTestCases) {
|
|
exclude "**/*TestCase.*", "**/*TestSuite.*"
|
|
}
|
|
include tests
|
|
applyTestFilter()
|
|
}
|
|
|
|
/**
|
|
* Include all of the tests (except Test{Case,TestSuite}). This actually
|
|
* doesn't explicitly "include" anything, in which cast the Test class tries
|
|
* to include everything that is not explicitly excluded.
|
|
*/
|
|
void includeAllTests() {
|
|
exclude "**/*TestCase.*", "**/*TestSuite.*"
|
|
applyTestFilter()
|
|
}
|
|
}
|
|
|
|
task fragileTest(type: FilteringTest) {
|
|
// Common exclude pattern. See README in parent directory for explanation.
|
|
tests = fragileTestPatterns
|
|
|
|
// Screenshot tests depend on the console being built
|
|
dependsOn(rootProject.project('console-webapp').tasks.named('buildConsoleWebapp'))
|
|
|
|
if (rootProject.findProperty("skipDockerIncompatibleTests") == "true") {
|
|
exclude dockerIncompatibleTestPatterns
|
|
}
|
|
|
|
// Run every test class in a freshly started process.
|
|
forkEvery = 1
|
|
|
|
doFirst {
|
|
new File(screenshotsDir).deleteDir()
|
|
}
|
|
}
|
|
|
|
// Dedicated test suite for schema-dependent tests.
|
|
task sqlIntegrationTest(type: FilteringTest) {
|
|
useJUnitPlatform()
|
|
excludeTestCases = false
|
|
tests = ['google/registry/schema/integration/SqlIntegrationTestSuite.*']
|
|
|
|
testClassesDirs = sourceSets.test.output.classesDirs
|
|
classpath = sourceSets.test.runtimeClasspath
|
|
}
|
|
|
|
// Verifies that RegistryTool can be instantiated:
|
|
// - All dependencies are packaged in nomulus.jar
|
|
// - JPA setup succeeds.
|
|
task registryToolIntegrationTest(dependsOn: nomulus, type: FilteringTest) {
|
|
tests = ['google/registry/tools/RegistryToolTest.*']
|
|
testClassesDirs = sourceSets.test.output.classesDirs
|
|
classpath = nomulus.outputs.files.plus(configurations.testRuntimeClasspath)
|
|
.plus(files(testClassesDirs))
|
|
}
|
|
|
|
task standardTest(type: FilteringTest) {
|
|
includeAllTests()
|
|
exclude fragileTestPatterns
|
|
// See SqlIntegrationTestSuite.java
|
|
exclude '**/*BeforeSuiteTest.*', '**/*AfterSuiteTest.*'
|
|
|
|
if (rootProject.findProperty("skipDockerIncompatibleTests") == "true") {
|
|
exclude dockerIncompatibleTestPatterns
|
|
}
|
|
|
|
// Run every test class in its own process.
|
|
// Uncomment to unblock build while troubleshooting inexplicable test errors.
|
|
// This setting makes the build take 35 minutes, without it it takes about 10.
|
|
// forkEvery = 1
|
|
|
|
// Sets the maximum number of test executors that may exist at the same time.
|
|
// Also, Gradle executes tests in 1 thread and some of our test infrastructures
|
|
// depend on that, e.g. DualDatabaseTestInvocationContextProvider injects
|
|
// different implementation of TransactionManager into TransactionManagerFactory.
|
|
maxParallelForks = 64
|
|
|
|
systemProperty 'test.projectRoot', rootProject.projectRootDir
|
|
systemProperty 'test.resourcesDir', resourcesDir
|
|
}
|
|
|
|
test {
|
|
// Don't run any tests from this task, all testing gets done in the
|
|
// FilteringTest tasks.
|
|
exclude "**"
|
|
}.dependsOn(standardTest, registryToolIntegrationTest, sqlIntegrationTest, fragileTest)
|
|
|
|
// When we override tests, we also break the cleanTest command.
|
|
cleanTest.dependsOn(cleanStandardTest, cleanRegistryToolIntegrationTest, cleanSqlIntegrationTest, cleanFragileTest)
|
|
|
|
project.build.dependsOn devtool, buildToolImage
|