1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20// Following Gradle best practices to keep build logic organized 21 22// ---------------------------------------------------------------------------- 23// Functional testing harness creation. This helps run the cross-check tests. 24// The Makefile precross target invokes the shadowJar task and the tests.json 25// code is changed to call runclient or runserver as needed. 26 27// ---------------------------------------------------------------------------- 28// Cross Test sources are separated in their own sourceSet 29// 30sourceSets { 31 crossTest { 32 java { 33 } 34 } 35} 36 37// see https://docs.gradle.org/current/userguide/java_library_plugin.html 38// 1. defines cross test implementation that includes all test implementation, which in turn 39// contains all implementation dependencies 40// 2. defines cross test runtime that further includes test runtime only dependencies 41// 3. the cross test implementation will need to depends on main and test output 42// 4. shadow jar will package both main and test source set, along with cross test runtime dependencies 43configurations { 44 crossTestImplementation { 45 description "implementation for cross test" 46 extendsFrom testImplementation 47 } 48 crossTestRuntime { 49 description "runtime dependencies for cross test" 50 extendsFrom crossTestImplementation, testRuntimeOnly 51 } 52} 53 54dependencies { 55 crossTestImplementation "org.apache.tomcat.embed:tomcat-embed-core:${tomcatEmbedVersion}" 56 crossTestImplementation sourceSets.main.output 57 crossTestImplementation sourceSets.test.output 58} 59 60// I am using shadow plugin to make a self contained functional test Uber JAR that 61// eliminates startup problems with wrapping the cross-check harness in Gradle. 62// This is used by the runner scripts as the single classpath entry which 63// allows the process to be as lightweight as it can. 64shadowJar { 65 description = 'Assemble a test JAR file for cross-check execution' 66 // make sure the runners are created when this runs 67 dependsOn 'generateRunnerScriptForClient', 'generateRunnerScriptForServer', 'generateRunnerScriptForNonblockingServer', 'generateRunnerScriptForTServletServer' 68 archiveBaseName.set('functionalTest') 69 destinationDirectory = file("$buildDir/functionalTestJar") 70 // We do not need a version number for this internal jar 71 archiveVersion.set(null) 72 // Bundle the complete set of unit test classes including generated code 73 // and the runtime dependencies in one JAR to expedite execution. 74 // see https://imperceptiblethoughts.com/shadow/custom-tasks/ 75 from sourceSets.test.output 76 from sourceSets.crossTest.output 77 configurations = [project.configurations.crossTestRuntime] 78} 79 80// Common script runner configuration elements 81def scriptExt = '' 82def execExt = '' 83def scriptHead = '#!/bin/bash' 84def args = '$*' 85 86// Although this is marked internal it is an available and stable interface 87if (org.gradle.internal.os.OperatingSystem.current().windows) { 88 scriptExt = '.bat' 89 execExt = '.exe' 90 scriptHead = '@echo off' 91 args = '%*' 92} 93 94// The Java executable to use with the runner scripts 95def javaExe = file("${System.getProperty('java.home')}/bin/java${execExt}").canonicalPath 96// The common Uber jar path 97def jarPath = shadowJar.archiveFile.get().asFile.canonicalPath 98def trustStore = file("${projectDir}/src/crossTest/resources/.truststore").canonicalPath 99def keyStore = file("${projectDir}/src/crossTest/resources/.keystore").canonicalPath 100 101task generateRunnerScriptForClient(group: 'Build') { 102 description = 'Generate a runner script for cross-check tests with TestClient' 103 104 def clientFile = file("$buildDir/runclient${scriptExt}") 105 106 def runClientText = """\ 107${scriptHead} 108 109"${javaExe}" -cp "$jarPath" "-Djavax.net.ssl.trustStore=$trustStore" -Djavax.net.ssl.trustStorePassword=thrift org.apache.thrift.test.TestClient $args 110""" 111 inputs.property 'runClientText', runClientText 112 outputs.file clientFile 113 114 doLast { 115 clientFile.parentFile.mkdirs() 116 clientFile.text = runClientText 117 clientFile.setExecutable(true, false) 118 } 119} 120 121task generateRunnerScriptForServer(group: 'Build') { 122 description = 'Generate a runner script for cross-check tests with TestServer' 123 124 def serverFile = file("$buildDir/runserver${scriptExt}") 125 126 def runServerText = """\ 127${scriptHead} 128 129"${javaExe}" -cp "$jarPath" "-Djavax.net.ssl.keyStore=$keyStore" -Djavax.net.ssl.keyStorePassword=thrift org.apache.thrift.test.TestServer $args 130""" 131 132 inputs.property 'runServerText', runServerText 133 outputs.file serverFile 134 135 doLast { 136 serverFile.parentFile.mkdirs() 137 serverFile.text = runServerText 138 serverFile.setExecutable(true, false) 139 } 140} 141 142task generateRunnerScriptForNonblockingServer(group: 'Build') { 143 description = 'Generate a runner script for cross-check tests with TestNonblockingServer' 144 145 def serverFile = file("$buildDir/runnonblockingserver${scriptExt}") 146 147 def runServerText = """\ 148${scriptHead} 149 150"${javaExe}" -cp "$jarPath" "-Djavax.net.ssl.keyStore=$keyStore" -Djavax.net.ssl.keyStorePassword=thrift org.apache.thrift.test.TestNonblockingServer $args 151""" 152 153 inputs.property 'runServerText', runServerText 154 outputs.file serverFile 155 156 doLast { 157 serverFile.parentFile.mkdirs() 158 serverFile.text = runServerText 159 serverFile.setExecutable(true, false) 160 } 161} 162 163task generateRunnerScriptForTServletServer(group: 'Build') { 164 description = 'Generate a runner script for cross-check tests with TestTServletServer' 165 166 def serverFile = file("$buildDir/runservletserver${scriptExt}") 167 168 def runServerText = """\ 169${scriptHead} 170 171"${javaExe}" -cp "$jarPath" "-Djavax.net.ssl.keyStore=$keyStore" -Djavax.net.ssl.keyStorePassword=thrift org.apache.thrift.test.TestTServletServer $args 172""" 173 174 inputs.property 'runServerText', runServerText 175 outputs.file serverFile 176 177 doLast { 178 serverFile.parentFile.mkdirs() 179 serverFile.text = runServerText 180 serverFile.setExecutable(true, false) 181 } 182} 183