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