1// Copyright 2017 The gRPC Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15buildscript { 16 // Configuration for building 17 repositories { 18 maven { // The google mirror is less flaky than mavenCentral() 19 url "https://maven-central.storage-download.googleapis.com/maven2/" } 20 } 21 dependencies { 22 classpath 'com.squareup.okhttp:okhttp:2.7.4' 23 } 24} 25 26plugins { 27 id "java" 28 id "war" 29 30 id "ru.vyarus.animalsniffer" 31 id 'com.google.cloud.tools.appengine' version '2.3.0' 32} 33 34description = 'gRPC: gae interop testing (jdk8)' 35 36repositories { 37 // repositories for Jar's you access in your code 38 mavenLocal() 39 maven { // The google mirror is less flaky than mavenCentral() 40 url "https://maven-central.storage-download.googleapis.com/maven2/" } 41} 42 43apply plugin: 'com.google.cloud.tools.appengine' // App Engine tasks 44 45dependencies { 46 providedCompile group: 'javax.servlet', name: 'servlet-api', version:'2.5' 47 runtimeOnly 'com.google.appengine:appengine-api-1.0-sdk:1.9.59' 48 implementation project(':grpc-netty') 49 implementation project(":grpc-stub") 50 implementation (project(':grpc-interop-testing')) { 51 // Avoid grpc-netty-shaded dependency 52 exclude group: 'io.grpc', module: 'grpc-alts' 53 exclude group: 'io.grpc', module: 'grpc-xds' 54 } 55 implementation libraries.junit 56 implementation libraries.protobuf.java 57 runtimeOnly libraries.netty.tcnative, libraries.netty.tcnative.classes 58 signature libraries.signature.java 59} 60 61tasks.named("compileJava").configure { 62 // Disable "No processor claimed any of these annotations: org.junit.Ignore" 63 options.compilerArgs += ["-Xlint:-processing"] 64} 65 66def createDefaultVersion() { 67 return new java.text.SimpleDateFormat("yyyyMMdd't'HHmmss").format(new Date()) 68} 69 70// [START model] 71appengine { 72 // App Engine tasks configuration 73 run { // local (dev_appserver) configuration (standard environments only) 74 port = 8080 // default 75 } 76 77 deploy { 78 // deploy configuration 79 projectId = 'GCLOUD_CONFIG' 80 // default - stop the current version 81 stopPreviousVersion = System.getProperty('gaeStopPreviousVersion') ?: true 82 // default - do not make this the promoted version 83 promote = System.getProperty('gaePromote') ?: false 84 // Use -DgaeDeployVersion if set, otherwise the version is null and the plugin will generate it 85 version = System.getProperty('gaeDeployVersion', createDefaultVersion()) 86 } 87} 88// [END model] 89 90group = 'io.grpc' // Generated output GroupId 91version = '1.0-SNAPSHOT' // Version in generated output 92 93sourceCompatibility = 1.8 94targetCompatibility = 1.8 95 96/** Returns the service name. */ 97String getGaeProject() { 98 def stream = new ByteArrayOutputStream() 99 exec { 100 executable 'gcloud' 101 args = [ 102 'config', 103 'get-value', 104 'project' 105 ] 106 standardOutput = stream 107 } 108 return stream.toString().trim() 109} 110 111String getService(java.nio.file.Path projectPath) { 112 Node xml = new XmlParser().parse(projectPath.resolve("src/main/webapp/WEB-INF/appengine-web.xml").toFile()) 113 if (xml.service.isEmpty()) { 114 return "default" 115 } else { 116 return xml.service.text() 117 } 118} 119 120String getAppUrl(String project, String service, String version) { 121 return "http://${version}.${service}.${project}.appspot.com" 122} 123 124tasks.register("runInteropTestRemote") { 125 dependsOn appengineDeploy 126 doLast { 127 // give remote app some time to settle down 128 sleep(20000) 129 130 def appUrl = getAppUrl( 131 getGaeProject(), 132 getService(project.getProjectDir().toPath()), 133 appengine.deploy.version) 134 logger.log(LogLevel.INFO, "the appURL=" + appUrl) 135 def client = new com.squareup.okhttp.OkHttpClient() 136 // The '?jdk8' argument is ignored by the server, it exists only to tag the request log entry 137 client.setReadTimeout(30, java.util.concurrent.TimeUnit.SECONDS) 138 def request = new com.squareup.okhttp.Request.Builder() 139 .url("${appUrl}/long_lived_channel?jdk8").build() 140 def result1 = client.newCall(request).execute() 141 def result2 = client.newCall(request).execute() 142 if (result1.code() != 200 || result2.code() != 200) { 143 throw new GradleException("Unable to reuse same channel across requests") 144 } 145 146 // The test suite can take a while to run 147 client.setReadTimeout(3, java.util.concurrent.TimeUnit.MINUTES) 148 // The '?jdk8' argument is ignored by the server, it exists only to tag the request log entry 149 def interopRequest = new com.squareup.okhttp.Request.Builder() 150 .url("${appUrl}/?jdk8").build() 151 152 // Retry in case GAE is slow and times out 153 int maxRetries = 5 154 String result = null 155 Throwable caught = null 156 for (int attempt = 0; attempt < maxRetries; attempt++) { 157 try { 158 def response = client.newCall(interopRequest).execute() 159 result = response.body().string() 160 project.println(result) 161 if (response.code() == 200) { 162 return 163 } 164 } catch (Throwable t) { 165 caught = t 166 logger.log(LogLevel.ERROR, "caught exception. will retry if possible", t) 167 } 168 } 169 throw new GradleException("Interop test failed:\nthrowable:${caught}") 170 } 171} 172