Skip to content

Commit

Permalink
Make Fast (#16)
Browse files Browse the repository at this point in the history
* Make Fast

* Fix compression

---------

Co-authored-by: Joel Dickson <[email protected]>
  • Loading branch information
joeldickson and dicko2 authored Oct 11, 2024
1 parent cc7191c commit 948b87a
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@ import com.fasterxml.jackson.module.scala.DefaultScalaModule
import scalaj.http.{Http, HttpOptions}

import java.time.Instant
import java.util.UUID
import java.util.{Base64, UUID}
import scala.collection.mutable
import scala.util.{Failure, Success, Try}
import scalaj.http.HttpRequest

import java.io.{ByteArrayOutputStream, OutputStreamWriter}
import java.util.zip.GZIPOutputStream
import java.nio.charset.StandardCharsets
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{ExecutionContext, Future}

class TestMetricsReporter extends Reporter {
private val objectMapper = new ObjectMapper().registerModule(DefaultScalaModule)
private val testCases = mutable.Map[String, TestCaseInfo]()
Expand Down Expand Up @@ -135,24 +141,38 @@ class TestMetricsReporter extends Reporter {

private def sendReportToEndpoint(jsonReport: ObjectNode): Unit = {
val jsonString = objectMapper.writeValueAsString(jsonReport)
Try {
val response = createHttpRequest(endpointUrl)
.postData(jsonString)
.header("Content-Type", "application/json")
.header("Charset", "UTF-8")
.option(HttpOptions.readTimeout(10000))
.asString
if (response.isSuccess) {
println(s"Successfully sent report to $endpointUrl")
} else {
println(s"Failed to send report. Status code: ${response.code}, Body: ${response.body}")
val compressedBody = compressString(jsonString)

Future {
Try {
val response = createHttpRequest(endpointUrl)
.postData(compressedBody)
.header("Content-Type", "application/json")
.header("Content-Encoding", "gzip")
.option(HttpOptions.readTimeout(10000))
.option(HttpOptions.connTimeout(5000))
.asString
if (response.isSuccess) {
println(s"Successfully sent compressed report to $endpointUrl")
} else {
println(s"Failed to send compressed report. Status code: ${response.code}, Body: ${response.body}")
}
} match {
case Success(_) => // Do nothing, already logged
case Failure(exception) => println(s"Exception when sending compressed report: ${exception.getMessage}")
}
} match {
case Success(_) => // Do nothing, already logged
case Failure(exception) => println(s"Exception when sending report: ${exception.getMessage}")
}
}

private def compressString(input: String): Array[Byte] = {
val outputStream = new ByteArrayOutputStream()
val gzipOutputStream = new GZIPOutputStream(outputStream)

gzipOutputStream.write(input.getBytes(StandardCharsets.UTF_8))
gzipOutputStream.close()

outputStream.toByteArray
}
private def determinePlatform(): String = {
if (System.getProperty("java.vendor").contains("Android")) "Android"
else if (System.getenv("DOCKER_CONTAINER") != null) "Docker"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@ import org.mockito.MockitoSugar
import org.mockito.ArgumentMatchers.{any, argThat}
import scalaj.http.{HttpRequest, HttpResponse}
import scalaj.http.HttpOptions.HttpOption
import java.io.{ByteArrayInputStream}
import java.util.zip.GZIPInputStream
import java.nio.charset.StandardCharsets
import scala.concurrent.Await
import scala.concurrent.duration._

class TestMetricsReporterSpec extends AnyFunSpec with Matchers with MockitoSugar {

val objectMapper = new ObjectMapper().registerModule(DefaultScalaModule)

describe("TestMetricsReporter") {
Expand All @@ -21,7 +26,7 @@ class TestMetricsReporterSpec extends AnyFunSpec with Matchers with MockitoSugar
val mockRequest = mock[HttpRequest]
val mockResponse = mock[HttpResponse[String]]

when(mockRequest.postData(any[String])).thenReturn(mockRequest)
when(mockRequest.postData(any[Array[Byte]])).thenReturn(mockRequest)
when(mockRequest.header(any[String], any[String])).thenReturn(mockRequest)
when(mockRequest.option(any[HttpOption]())).thenReturn(mockRequest)
when(mockRequest.asString).thenReturn(mockResponse)
Expand All @@ -31,32 +36,43 @@ class TestMetricsReporterSpec extends AnyFunSpec with Matchers with MockitoSugar
val reporter = new TestMetricsReporter {
override protected def createHttpRequest(url: String): HttpRequest = mockRequest
}

val runStartingEvent = RunStarting(ordinal = new Ordinal(1), testCount = 3, configMap = ConfigMap.empty, formatter = None, location = None, payload = None, threadName = "main", timeStamp = 123)
val testStartingEvent = TestStarting(ordinal = new Ordinal(2), suiteName = "TestSuite", suiteId = "suiteId", suiteClassName = Some("TestSuite"), testName = "test1", testText = "should do something", formatter = None, location = None, rerunner = None, payload = None, threadName = "main", timeStamp = 124)
val testSucceededEvent = TestSucceeded(ordinal = new Ordinal(3), suiteName = "TestSuite", suiteId = "suiteId", suiteClassName = Some("TestSuite"), testName = "test1", testText = "should do something", recordedEvents = Vector.empty, duration = Some(100), formatter = None, location = None, rerunner = None, payload = None, threadName = "main", timeStamp = 224)
val runCompletedEvent = RunCompleted(ordinal = new Ordinal(4), duration = Some(200), summary = Some(Summary(testsSucceededCount = 1, testsFailedCount = 0, testsIgnoredCount = 0, testsPendingCount = 0, testsCanceledCount = 0, suitesCompletedCount = 1, suitesAbortedCount = 0, scopesPendingCount = 0)), formatter = None, location = None, payload = None, threadName = "main", timeStamp = 324)

reporter(runStartingEvent)
reporter(testStartingEvent)
reporter(testSucceededEvent)
reporter(runCompletedEvent)

// Wait for the asynchronous operation to complete
Thread.sleep(1000) // Adjust this value if needed

// Verify that HTTP request was made with correct data
verify(mockRequest).postData(argThat { json: String =>
val jsonNode = objectMapper.readTree(json)
verify(mockRequest, timeout(5000)).postData(argThat { compressedData: Array[Byte] =>
// Decompress the JSON data
val decompressedJson = decompress(compressedData)
val jsonNode = objectMapper.readTree(decompressedJson)
jsonNode.get("totalTests").asInt() == 3 &&
jsonNode.get("succeededTests").asInt() == 1 &&
jsonNode.get("failedTests").asInt() == 0 &&
jsonNode.get("ignoredTests").asInt() == 0 &&
jsonNode.get("runTime").asLong() == 200 &&
jsonNode.get("scalaTestCases").isArray &&
jsonNode.get("scalaTestCases").size() == 1 &&
jsonNode.get("scalaTestCases").get(0).get("name").asText() == "test1" &&
jsonNode.get("scalaTestCases").get(0).get("status").asText() == "Passed"
jsonNode.get("succeededTests").asInt() == 1 &&
jsonNode.get("failedTests").asInt() == 0 &&
jsonNode.get("ignoredTests").asInt() == 0 &&
jsonNode.get("runTime").asLong() == 200 &&
jsonNode.get("scalaTestCases").isArray &&
jsonNode.get("scalaTestCases").size() == 1 &&
jsonNode.get("scalaTestCases").get(0).get("name").asText() == "test1" &&
jsonNode.get("scalaTestCases").get(0).get("status").asText() == "Passed"
})
verify(mockRequest).asString
verify(mockResponse).isSuccess
}
}

// Helper method to decompress the GZIP byte array
private def decompress(compressedData: Array[Byte]): String = {
val gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(compressedData))
scala.io.Source.fromInputStream(gzipInputStream).mkString
}
}

0 comments on commit 948b87a

Please sign in to comment.