Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Socket timeout #337

Merged
merged 5 commits into from
Oct 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion test_runner/src/main/kotlin/ftl/android/AndroidCatalog.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ftl.android

import com.google.api.services.testing.model.AndroidDevice
import ftl.http.executeWithRetry
import ftl.gc.GcTesting

/**
Expand All @@ -9,7 +10,7 @@ import ftl.gc.GcTesting
*/
object AndroidCatalog {
private val androidDeviceCatalog by lazy {
GcTesting.get.testEnvironmentCatalog().get("android").execute().androidDeviceCatalog
GcTesting.get.testEnvironmentCatalog().get("android").executeWithRetry().androidDeviceCatalog
}

val androidModelIds by lazy { androidDeviceCatalog.models.map { it.id } }
Expand Down
28 changes: 16 additions & 12 deletions test_runner/src/main/kotlin/ftl/config/FtlConstants.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package ftl.config

import com.google.api.client.auth.oauth2.Credential
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport
import com.google.api.client.googleapis.testing.auth.oauth2.MockGoogleCredential
import com.google.api.client.googleapis.util.Utils
import com.google.api.client.http.HttpRequestInitializer
import com.google.api.client.http.javanet.NetHttpTransport
import com.google.api.client.json.jackson2.JacksonFactory
import com.google.api.client.json.JsonFactory
import ftl.http.TimeoutHttpRequestInitializer

object FtlConstants {
var useMock = false
Expand All @@ -18,7 +20,7 @@ object FtlConstants {
const val matrixIdsFile = "matrix_ids.json"
const val applicationName = "Flank"
const val GCS_PREFIX = "gs://"
val JSON_FACTORY: JacksonFactory by lazy { JacksonFactory.getDefaultInstance() }
val JSON_FACTORY: JsonFactory by lazy { Utils.getDefaultJsonFactory() }

val httpTransport: NetHttpTransport by lazy {
try {
Expand All @@ -28,20 +30,22 @@ object FtlConstants {
}
}

val credential: Credential by lazy {
val credential: HttpRequestInitializer by lazy {
try {
if (useMock) {
return@lazy MockGoogleCredential.Builder()
.setTransport(MockGoogleCredential.newMockHttpTransportWithSampleTokenResponse())
.build()
}

val defaultCredential = GoogleCredential.getApplicationDefault()
// Scope is required.
// https://developers.google.com/identity/protocols/googlescopes
// https://developers.google.com/identity/protocols/application-default-credentials
// https://cloud.google.com/sdk/gcloud/reference/alpha/compute/instances/set-scopes
return@lazy defaultCredential.createScoped(listOf("https://www.googleapis.com/auth/cloud-platform"))
val credential = if (useMock) {
MockGoogleCredential.Builder()
.setTransport(MockGoogleCredential.newMockHttpTransportWithSampleTokenResponse())
.build()
} else {
GoogleCredential.getApplicationDefault()
.createScoped(listOf("https://www.googleapis.com/auth/cloud-platform"))
}

return@lazy TimeoutHttpRequestInitializer(credential)
} catch (e: Exception) {
throw RuntimeException(e)
}
Expand Down
3 changes: 2 additions & 1 deletion test_runner/src/main/kotlin/ftl/gc/GcTestMatrix.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package ftl.gc

import com.google.api.services.testing.model.TestMatrix
import ftl.args.IArgs
import ftl.http.executeWithRetry
import ftl.util.Utils.sleep
import java.time.Duration.ofHours

Expand Down Expand Up @@ -38,7 +39,7 @@ object GcTestMatrix {

while (failed < maxWait) {
try {
return getMatrix.execute()
return getMatrix.executeWithRetry()
} catch (e: Exception) {
sleep(1)
failed += 1
Expand Down
5 changes: 3 additions & 2 deletions test_runner/src/main/kotlin/ftl/gc/GcToolResults.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import ftl.config.FtlConstants.JSON_FACTORY
import ftl.config.FtlConstants.applicationName
import ftl.config.FtlConstants.credential
import ftl.config.FtlConstants.httpTransport
import ftl.http.executeWithRetry

object GcToolResults {

Expand All @@ -29,7 +30,7 @@ object GcToolResults {
.histories()
.list(args.projectId)
.setFilterByName(args.resultsHistoryName)
.execute()
.executeWithRetry()
return result?.histories ?: emptyList()
}

Expand Down Expand Up @@ -64,7 +65,7 @@ object GcToolResults {
toolResultsStep.executionId,
toolResultsStep.stepId
)
.execute()
.executeWithRetry()
}

fun getDefaultBucket(projectId: String): String? {
Expand Down
21 changes: 21 additions & 0 deletions test_runner/src/main/kotlin/ftl/http/ExecuteWithRetry.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package ftl.http

import com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest
import java.io.IOException

// Only use on calls that don't change state.
// Fetching status is safe to retry on timeout. Creating a matrix is not.
fun <T> AbstractGoogleJsonClientRequest<T>.executeWithRetry(): T {
var lastErr: IOException? = null

for (i in 1..10) {
try {
return this.execute()
} catch (err: IOException) {
lastErr = err
System.err.println("Request failed, retrying ${i}x $err")
}
}

throw IOException("Request failed", lastErr)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package ftl.http

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential
import com.google.api.client.http.HttpRequest
import com.google.api.client.http.HttpRequestInitializer

class TimeoutHttpRequestInitializer(private val googleCredential: GoogleCredential) : HttpRequestInitializer {
override fun initialize(request: HttpRequest?) {
googleCredential.initialize(request)
// timeout in milliseconds. wait 60s instead of default 20s
request?.connectTimeout = 60 * 1000
request?.readTimeout = 60 * 1000
}
}
3 changes: 2 additions & 1 deletion test_runner/src/main/kotlin/ftl/ios/IosCatalog.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ftl.ios

import ftl.http.executeWithRetry
import ftl.gc.GcTesting

/**
Expand All @@ -14,7 +15,7 @@ object IosCatalog {

private val iosDeviceCatalog by lazy {
try {
GcTesting.get.testEnvironmentCatalog().get("ios").execute().iosDeviceCatalog
GcTesting.get.testEnvironmentCatalog().get("ios").executeWithRetry().iosDeviceCatalog
} catch (e: java.lang.Exception) {
throw java.lang.RuntimeException(
"""
Expand Down
1 change: 1 addition & 0 deletions test_runner/src/main/kotlin/ftl/json/SavedMatrix.kt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class SavedMatrix(matrix: TestMatrix) {
billableVirtualMinutes = 0
billablePhysicalMinutes = 0
outcome = success
if (matrix.testExecutions == null) return
matrix.testExecutions.forEach {
val step = GcToolResults.getResults(it.toolResultsStep)
if (step.testExecutionStep == null) return
Expand Down