Skip to content

Commit

Permalink
(feature) Ability to publish attachments from Gradle plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
craigatk committed Feb 28, 2020
1 parent 1ebca36 commit 1728aec
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ package projektor.plugin
import okhttp3.OkHttpClient
import org.gradle.BuildListener
import org.gradle.BuildResult
import org.gradle.api.file.FileTree
import org.gradle.api.initialization.Settings
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.ClientConfig
import projektor.plugin.results.ResultsLogger
Expand All @@ -18,6 +21,7 @@ class ProjektorBuildFinishedListener implements BuildListener {
private final boolean publishOnFailureOnly
private final File projectDir
private final List<String> additionalResultsDirs
private final List<FileTree> attachments
private final ProjektorTaskFinishedListener projektorTaskFinishedListener
private final OkHttpClient okHttpClient = new OkHttpClient()

Expand All @@ -27,13 +31,15 @@ class ProjektorBuildFinishedListener implements BuildListener {
boolean publishOnFailureOnly,
File projectDir,
List<String> additionalResultsDirs,
List<FileTree> attachments,
ProjektorTaskFinishedListener projektorTaskFinishedListener
) {
this.clientConfig = clientConfig
this.logger = logger
this.publishOnFailureOnly = publishOnFailureOnly
this.projectDir = projectDir
this.additionalResultsDirs = additionalResultsDirs
this.attachments = attachments
this.projektorTaskFinishedListener = projektorTaskFinishedListener
}

Expand Down Expand Up @@ -64,6 +70,11 @@ class ProjektorBuildFinishedListener implements BuildListener {
PublishResult publishResult = resultsClient.sendResultsToServer(groupedResults)

new ResultsLogger(logger).logReportResults(publishResult)

if (attachments) {
AttachmentsClient attachmentsClient = new AttachmentsClient(okHttpClient, clientConfig, logger)
new AttachmentsPublisher(attachmentsClient, logger).publishAttachments(publishResult.publicId, attachments)
}
} else {
logger.info("Projektor plugin applied but no test results found in this build")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package projektor.plugin

import okhttp3.OkHttpClient
import org.gradle.api.file.FileTree
import org.gradle.api.internal.AbstractTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
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.ClientConfig
import projektor.plugin.results.ResultsLogger
Expand All @@ -23,6 +27,10 @@ class ProjektorManualPublishTask extends AbstractTask {
@Optional
List<String> additionalResultsDirs = []

@InputFiles
@Optional
List<FileTree> attachments = []

@TaskAction
void publish() {
File projectDir = project.projectDir
Expand All @@ -34,16 +42,23 @@ class ProjektorManualPublishTask extends AbstractTask {
)

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

ResultsClient resultsClient = new ResultsClient(
new OkHttpClient(),
new ClientConfig(serverUrl, java.util.Optional.ofNullable(publishToken)),
okHttpClient,
clientConfig,
logger
)
PublishResult publishResult = resultsClient.sendResultsToServer(groupedResults)

new ResultsLogger(logger).logReportResults(publishResult)

if (attachments) {
AttachmentsClient attachmentsClient = new AttachmentsClient(okHttpClient, clientConfig, logger)
new AttachmentsPublisher(attachmentsClient, logger).publishAttachments(publishResult.publicId, attachments)
}
} else {
logger.info("No test tasks found in project ${project.name}")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class ProjektorPublishPlugin implements Plugin<Project> {
extension.autoPublishOnFailureOnly,
project.projectDir,
extension.additionalResultsDirs,
extension.attachments,
projektorTaskFinishedListener
)
project.gradle.addBuildListener(projektorBuildFinishedListener)
Expand All @@ -67,6 +68,7 @@ class ProjektorPublishPlugin implements Plugin<Project> {
task.serverUrl = extension.serverUrl
task.publishToken = extension.publishToken
task.additionalResultsDirs = extension.additionalResultsDirs
task.attachments = extension.attachments
})
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package projektor.plugin

import org.gradle.api.file.FileTree

class ProjektorPublishPluginExtension {
boolean autoPublish = true
boolean autoPublishOnFailureOnly = false
String serverUrl
boolean manualPublishEnabled = true
String publishToken
List<String> additionalResultsDirs = []
List<FileTree> attachments = []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package projektor.plugin.attachments

import org.gradle.api.file.FileTree
import org.gradle.api.logging.Logger

class AttachmentsPublisher {
private final AttachmentsClient attachmentsClient
private final Logger logger

AttachmentsPublisher(AttachmentsClient attachmentsClient, Logger logger) {
this.attachmentsClient = attachmentsClient
this.logger = logger
}

void publishAttachments(String publicId, List<FileTree> attachmentFileTrees) {
List<File> attachments = attachmentFileTrees.collect { it.files }.flatten()
logger.info("Sending ${attachments.size()} attachments to Projektor report ${publicId}")

attachments.each { attachmentsClient.sendAttachmentToServer(publicId, it) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package projektor.plugin.testkit.attachments

import com.github.tomakehurst.wiremock.verification.LoggedRequest
import org.gradle.testkit.runner.GradleRunner
import projektor.plugin.AttachmentsWireMockStubber
import projektor.plugin.testkit.SingleProjectSpec
import projektor.plugin.testkit.util.AttachmentsWriter

import static org.gradle.testkit.runner.TaskOutcome.SUCCESS

class AttachmentsSingleProjectSpec extends SingleProjectSpec {
AttachmentsWireMockStubber attachmentsStubber = new AttachmentsWireMockStubber(wireMockRule)

def "should publish results and attachments to server"() {
given:
File attachmentsDir1 = AttachmentsWriter.createAttachmentsDir(projectRootDir, 'attachments1')
AttachmentsWriter.writeAttachmentFile(attachmentsDir1, "attachment1.txt", "Here is attachment 1")
AttachmentsWriter.writeAttachmentFile(attachmentsDir1, "attachment2.txt", "Here is attachment 2")
File attachmentsDir2 = AttachmentsWriter.createAttachmentsDir(projectRootDir, 'attachments2')
AttachmentsWriter.writeAttachmentFile(attachmentsDir2, "attachment3.txt", "Here is attachment 3")

buildFile << """
projektor {
serverUrl = '${serverUrl}'
attachments = [fileTree(dir: 'attachments1', include: '**/*.txt'), fileTree(dir: 'attachments2', include: '**/*.txt')]
}
""".stripIndent()

File testDirectory = specWriter.createTestDirectory(projectRootDir)
specWriter.writeSpecFile(testDirectory, "SampleSpec")

String resultsId = "ABC123"
resultsStubber.stubResultsPostSuccess(resultsId)
attachmentsStubber.stubAttachmentPostSuccess(resultsId, "attachment1.txt")
attachmentsStubber.stubAttachmentPostSuccess(resultsId, "attachment2.txt")
attachmentsStubber.stubAttachmentPostSuccess(resultsId, "attachment3.txt")

when:
def result = GradleRunner.create()
.withProjectDir(projectRootDir.root)
.withArguments('test')
.withPluginClasspath()
.build()

then:
result.task(":test").outcome == SUCCESS

and:
!result.output.contains("Projektor plugin enabled but no server specified")
result.output.contains("View Projektor report at: ${serverUrl}/tests/${resultsId}")

and:
List<LoggedRequest> resultsRequests = resultsStubber.findResultsRequests()
resultsRequests.size() == 1

and:
List<LoggedRequest> attachmentRequests = attachmentsStubber.findAttachmentsRequests(resultsId)
attachmentRequests.size() == 3
}

def "should publish results and attachments with publish task"() {
given:
File attachmentsDir = AttachmentsWriter.createAttachmentsDir(projectRootDir, 'attachments')
AttachmentsWriter.writeAttachmentFile(attachmentsDir, "attachment1.txt", "Here is attachment 1")
AttachmentsWriter.writeAttachmentFile(attachmentsDir, "attachment2.txt", "Here is attachment 2")

buildFile << """
projektor {
serverUrl = '${serverUrl}'
autoPublish = false
attachments = [fileTree(dir: 'attachments', include: '**/*.txt')]
}
""".stripIndent()

File testDirectory = specWriter.createTestDirectory(projectRootDir)
specWriter.writeSpecFile(testDirectory, "SampleSpec")

String resultsId = "ABC123"
resultsStubber.stubResultsPostSuccess(resultsId)
attachmentsStubber.stubAttachmentPostSuccess(resultsId, "attachment1.txt")
attachmentsStubber.stubAttachmentPostSuccess(resultsId, "attachment2.txt")

when:
def testResult = GradleRunner.create()
.withProjectDir(projectRootDir.root)
.withArguments('test')
.withPluginClasspath()
.build()

then:
testResult.task(":test").outcome == SUCCESS

and:
resultsStubber.findResultsRequests().size() == 0

when:
def publishResults = GradleRunner.create()
.withProjectDir(projectRootDir.root)
.withArguments('publishResults', '--info')
.withPluginClasspath()
.build()

println publishResults.output

then:
publishResults.task(":publishResults").outcome == SUCCESS

and:
publishResults.output.contains("View Projektor report at: ${serverUrl}/tests/${resultsId}")

and:
List<LoggedRequest> resultsRequests = resultsStubber.findResultsRequests()
resultsRequests.size() == 1

and:
List<LoggedRequest> attachmentRequests = attachmentsStubber.findAttachmentsRequests(resultsId)
attachmentRequests.size() == 2
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package projektor.plugin.testkit.util

import org.junit.rules.TemporaryFolder

class AttachmentsWriter {
static File createAttachmentsDir(TemporaryFolder projectDir, String dirName) {
projectDir.newFolder(dirName)
}

static File createAttachmentsDir(File projectDir, String dirName) {
File dir = new File(projectDir, dirName)
dir.mkdirs()
return dir
}

static File writeAttachmentFile(File attachmentsDir, String fileName, String contents) {
File attachmentFile = new File(attachmentsDir, fileName)
attachmentFile.createNewFile()

attachmentFile.text = contents

return attachmentFile
}
}

0 comments on commit 1728aec

Please sign in to comment.