Skip to content

Commit

Permalink
Merge pull request #45 from craigatk/compress-plugin
Browse files Browse the repository at this point in the history
(feature) Compressing results when sending from Gradle plugin to server
  • Loading branch information
craigatk authored Apr 5, 2020
2 parents 6e988e9 + 79f892e commit 7defe52
Show file tree
Hide file tree
Showing 12 changed files with 106 additions and 39 deletions.
5 changes: 3 additions & 2 deletions publishers/gradle-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,13 @@ projektor {

| Parameter | Type | Default | Description |
| ------------------------- | ---------------- | ------- | ------------------------------------------ |
| serverUrl* | `String` | null | Projektor server URL to publish results to |
| serverUrl** | `String` | null | Projektor server URL to publish results to |
| autoPublish | `boolean` | true | Whether results are automatically published at the end of the build |
| autoPublishOnFailureOnly | `boolean` | true | Whether results on automatically published at the end of the build only on failures |
| publishTaskEnabled | `boolean` | true | Whether the `publishResults` task is added to support easily manually publishing results by running a task |
| publishToken | `String` | null | Token to include in publish request to server (only needed when server has publish token set) |
| additionalResultsDirs | `List<String>` | [] | Additional directories to include results from. Useful when you want to include results from a task that isn't `Test` type |
| attachments | `List<FileTree>` | [] | FileTrees to include as attachments to the test report and make available in the UI |
| compressionEnabled | `boolean` | true | Whether to compress the test results with GZIP when sending them to the server |

* _Required_
** _Required_
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import org.gradle.api.invocation.Gradle
import org.gradle.api.logging.Logger
import projektor.plugin.attachments.AttachmentsClient
import projektor.plugin.attachments.AttachmentsPublisher
import projektor.plugin.results.ResultsClient
import projektor.plugin.client.ResultsClient
import projektor.plugin.client.ClientConfig
import projektor.plugin.results.ResultsLogger
import projektor.plugin.results.grouped.GroupedResults
Expand All @@ -23,7 +23,6 @@ class ProjektorBuildFinishedListener implements BuildListener {
private final List<String> additionalResultsDirs
private final List<FileTree> attachments
private final ProjektorTaskFinishedListener projektorTaskFinishedListener
private final OkHttpClient okHttpClient = new OkHttpClient()

ProjektorBuildFinishedListener(
ClientConfig clientConfig,
Expand Down Expand Up @@ -66,13 +65,13 @@ class ProjektorBuildFinishedListener implements BuildListener {
"${projectTestResultsCollector.testGroupsCount()} test tasks")
GroupedResults groupedResults = projectTestResultsCollector.createGroupedResults()

ResultsClient resultsClient = new ResultsClient(okHttpClient, clientConfig, logger)
ResultsClient resultsClient = new ResultsClient(clientConfig, logger)
PublishResult publishResult = resultsClient.sendResultsToServer(groupedResults)

new ResultsLogger(logger).logReportResults(publishResult)

if (attachments) {
AttachmentsClient attachmentsClient = new AttachmentsClient(okHttpClient, clientConfig, logger)
AttachmentsClient attachmentsClient = new AttachmentsClient(clientConfig, logger)
new AttachmentsPublisher(attachmentsClient, logger).publishAttachments(publishResult.publicId, attachments)
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction
import projektor.plugin.attachments.AttachmentsClient
import projektor.plugin.attachments.AttachmentsPublisher
import projektor.plugin.results.ResultsClient
import projektor.plugin.client.ResultsClient
import projektor.plugin.client.ClientConfig
import projektor.plugin.results.ResultsLogger
import projektor.plugin.results.grouped.GroupedResults
Expand All @@ -31,6 +31,10 @@ class ProjektorManualPublishTask extends AbstractTask {
@Optional
List<FileTree> attachments = []

@Input
@Optional
Boolean compressionEnabled = true

@TaskAction
void publish() {
File projectDir = project.projectDir
Expand All @@ -42,12 +46,10 @@ class ProjektorManualPublishTask extends AbstractTask {
)

if (projectTestTaskResultsCollector.hasTestGroups()) {
OkHttpClient okHttpClient = new OkHttpClient()
ClientConfig clientConfig = new ClientConfig(serverUrl, java.util.Optional.ofNullable(publishToken))
ClientConfig clientConfig = new ClientConfig(serverUrl, compressionEnabled, java.util.Optional.ofNullable(publishToken))
GroupedResults groupedResults = projectTestTaskResultsCollector.createGroupedResults()

ResultsClient resultsClient = new ResultsClient(
okHttpClient,
clientConfig,
logger
)
Expand All @@ -56,7 +58,7 @@ class ProjektorManualPublishTask extends AbstractTask {
new ResultsLogger(logger).logReportResults(publishResult)

if (attachments) {
AttachmentsClient attachmentsClient = new AttachmentsClient(okHttpClient, clientConfig, logger)
AttachmentsClient attachmentsClient = new AttachmentsClient(clientConfig, logger)
new AttachmentsPublisher(attachmentsClient, logger).publishAttachments(publishResult.publicId, attachments)
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class ProjektorPublishPlugin implements Plugin<Project> {
project.gradle.taskGraph.addTaskExecutionListener(projektorTaskFinishedListener)

ProjektorBuildFinishedListener projektorBuildFinishedListener = new ProjektorBuildFinishedListener(
new ClientConfig(extension.serverUrl, Optional.ofNullable(extension.publishToken)),
new ClientConfig(extension.serverUrl, extension.compressionEnabled, Optional.ofNullable(extension.publishToken)),
logger,
extension.autoPublishOnFailureOnly,
project.projectDir,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ class ProjektorPublishPluginExtension {
String publishToken
List<String> additionalResultsDirs = []
List<FileTree> attachments = []
boolean compressionEnabled = true
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ import projektor.plugin.client.ClientConfig
import static projektor.plugin.client.ClientToken.conditionallyAddPublishTokenToRequest

class AttachmentsClient {
private final OkHttpClient client
private final ClientConfig config
private final Logger logger
private final OkHttpClient client = new OkHttpClient()

AttachmentsClient(OkHttpClient client, ClientConfig clientConfig, Logger logger) {
this.client = client
AttachmentsClient(ClientConfig clientConfig, Logger logger) {
this.config = clientConfig
this.logger = logger
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package projektor.plugin.client

class ClientConfig {
final String serverUrl
final boolean compressionEnabled
final Optional<String> maybePublishToken

ClientConfig(String serverUrl, Optional<String> maybePublishToken) {
ClientConfig(String serverUrl, boolean compressionEnabled, Optional<String> maybePublishToken) {
this.serverUrl = serverUrl
this.compressionEnabled = compressionEnabled
this.maybePublishToken = maybePublishToken
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package projektor.plugin.client

import java.util.zip.GZIPOutputStream

class CompressionUtil {
static byte[] gzip(String s){
def targetStream = new ByteArrayOutputStream()
def zipStream = new GZIPOutputStream(targetStream)
zipStream.write(s.getBytes('UTF-8'))
zipStream.close()
def zippedBytes = targetStream.toByteArray()
targetStream.close()
return zippedBytes
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package projektor.plugin.results
package projektor.plugin.client

import groovy.json.JsonSlurper
import okhttp3.MediaType
Expand All @@ -8,7 +8,6 @@ import okhttp3.RequestBody
import okhttp3.Response
import org.gradle.api.logging.Logger
import projektor.plugin.PublishResult
import projektor.plugin.client.ClientConfig
import projektor.plugin.results.grouped.GroupedResults
import projektor.plugin.results.grouped.GroupedResultsSerializer

Expand All @@ -19,10 +18,9 @@ class ResultsClient {
private final ClientConfig config
private final Logger logger
private final GroupedResultsSerializer groupedResultsSerializer = new GroupedResultsSerializer()
private final OkHttpClient client
private final OkHttpClient client = new OkHttpClient()

ResultsClient(OkHttpClient client, ClientConfig clientConfig, Logger logger) {
this.client = client
ResultsClient(ClientConfig clientConfig, Logger logger) {
this.config = clientConfig
this.logger = logger
}
Expand All @@ -34,13 +32,19 @@ class ResultsClient {

String groupedResultsJson = groupedResultsSerializer.serializeGroupedResults(groupedResults)

RequestBody body = RequestBody.create(mediaType, groupedResultsJson)
RequestBody body = config.compressionEnabled
? RequestBody.create(mediaType, CompressionUtil.gzip(groupedResultsJson))
: RequestBody.create(mediaType, groupedResultsJson)

String resultsUrl = "${config.serverUrl}/groupedResults"
Request.Builder requestBuilder = new Request.Builder()
.url(resultsUrl)
.post(body)

if (config.compressionEnabled) {
requestBuilder.header("Content-Encoding", "gzip")
}

conditionallyAddPublishTokenToRequest(requestBuilder, config)

Request request = requestBuilder.build()
Expand All @@ -53,7 +57,7 @@ class ResultsClient {
String testRunUri = parsedResponseJson.uri
String reportUrl = "${config.serverUrl}${testRunUri}"

publishResult.publicId= parsedResponseJson.id
publishResult.publicId = parsedResponseJson.id
publishResult.reportUrl = reportUrl
} else {
String responseCode = response ? "- response code ${response.code()}" : ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ class AttachmentsClientSpec extends Specification {

Logger logger = Mock()

OkHttpClient okHttpClient = new OkHttpClient()

@Unroll
void "should send attachment to server token in header #expectedTokenPresent"() {
given:
Expand All @@ -32,8 +30,7 @@ class AttachmentsClientSpec extends Specification {
String publicId = "ATT123"

AttachmentsClient attachmentsClient = new AttachmentsClient(
okHttpClient,
new ClientConfig(serverUrl, maybePublishToken),
new ClientConfig(serverUrl, false, maybePublishToken),
logger
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package projektor.plugin.results
package projektor.plugin.client

import com.github.tomakehurst.wiremock.http.HttpHeader
import com.github.tomakehurst.wiremock.junit.WireMockRule
import com.github.tomakehurst.wiremock.verification.LoggedRequest
import okhttp3.OkHttpClient
import org.gradle.api.logging.Logger
import org.junit.Rule
import projektor.plugin.ResultsWireMockStubber
import projektor.plugin.PublishResult
import projektor.plugin.client.ClientConfig
import projektor.plugin.client.ClientToken
import projektor.plugin.results.grouped.GroupedResults
import spock.lang.Specification

Expand All @@ -24,15 +21,12 @@ class ResultsClientSpec extends Specification {

Logger logger = Mock()

OkHttpClient okHttpClient = new OkHttpClient()

void "should send results to server without token in header"() {
given:
String serverUrl = resultsStubber.serverUrl

ResultsClient resultsClient = new ResultsClient(
okHttpClient,
new ClientConfig(serverUrl, Optional.empty()),
new ClientConfig(serverUrl, true, Optional.empty()),
logger
)

Expand All @@ -55,15 +49,16 @@ class ResultsClientSpec extends Specification {
resultsRequests.size() == 1

resultsRequests[0].bodyAsString == """{"groupedTestSuites":[]}"""

!resultsRequests[0].containsHeader(ClientToken.PUBLISH_TOKEN_NAME)
}

void "should send results to server with token in header"() {
given:
String serverUrl = resultsStubber.serverUrl

ResultsClient resultsClient = new ResultsClient(
okHttpClient,
new ClientConfig(serverUrl, Optional.of("token12345")),
new ClientConfig(serverUrl, true, Optional.of("token12345")),
logger
)

Expand Down Expand Up @@ -96,8 +91,7 @@ class ResultsClientSpec extends Specification {
given:
String serverUrl = "http://resolve.failure.fakedotcom:9999/womp"
ResultsClient resultsClient = new ResultsClient(
okHttpClient,
new ClientConfig(serverUrl, Optional.empty()),
new ClientConfig(serverUrl, true, Optional.empty()),
logger
)
GroupedResults groupedResults = new GroupedResults()
Expand All @@ -107,6 +101,55 @@ class ResultsClientSpec extends Specification {

then:
!publishResult.successful
}

void "when compression enabled should include gzip header"() {
given:
String serverUrl = resultsStubber.serverUrl

ResultsClient resultsClient = new ResultsClient(
new ClientConfig(serverUrl, true, Optional.empty()),
logger
)

GroupedResults groupedResults = new GroupedResults(
groupedTestSuites: []
)

String resultsId = "ABC123"
resultsStubber.stubResultsPostSuccess(resultsId)

when:
PublishResult publishResult = resultsClient.sendResultsToServer(groupedResults)

then:
List<LoggedRequest> resultsRequests = resultsStubber.findResultsRequests()
resultsRequests.size() == 1
resultsRequests[0].header("Content-Encoding").firstValue() == 'gzip'
}

void "when compression not enabled should not include gzip header"() {
given:
String serverUrl = resultsStubber.serverUrl

ResultsClient resultsClient = new ResultsClient(
new ClientConfig(serverUrl, false, Optional.empty()),
logger
)

GroupedResults groupedResults = new GroupedResults(
groupedTestSuites: []
)

String resultsId = "ABC123"
resultsStubber.stubResultsPostSuccess(resultsId)

when:
PublishResult publishResult = resultsClient.sendResultsToServer(groupedResults)

then:
List<LoggedRequest> resultsRequests = resultsStubber.findResultsRequests()
resultsRequests.size() == 1
!resultsRequests[0].containsHeader("Content-Encoding")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import io.ktor.util.KtorExperimentalAPI
import io.ktor.util.getOrFail
import io.micrometer.core.instrument.MeterRegistry
import io.micrometer.core.instrument.Timer
import org.slf4j.LoggerFactory
import projektor.auth.AuthConfig
import projektor.auth.AuthService
import projektor.incomingresults.GroupedTestResultsService
Expand All @@ -23,6 +24,8 @@ import projektor.server.api.PublicId
import projektor.server.api.results.SaveResultsResponse
import projektor.util.ungzip

private val logger = LoggerFactory.getLogger("ResultsRoutes")

@KtorExperimentalAPI
fun Route.results(
testResultsService: TestResultsService,
Expand Down Expand Up @@ -78,6 +81,7 @@ fun Route.results(

private suspend fun receiveResults(call: ApplicationCall): String {
val resultsBlob = if (call.request.header(HttpHeaders.ContentEncoding) == "gzip") {
logger.info("Unzipping compressed results")
ungzip(call.receive<ByteArray>())
} else {
call.receive<String>()
Expand Down

0 comments on commit 7defe52

Please sign in to comment.