Skip to content

Commit

Permalink
Add publishDistributionBuildResults and publishIntegTestResults t…
Browse files Browse the repository at this point in the history
…o publish the OpenSearch build and integration test results (#459)

Signed-off-by: Prudhvi Godithi <[email protected]>
  • Loading branch information
prudhvigodithi authored Jul 22, 2024
1 parent 96cf7bf commit cd984fa
Show file tree
Hide file tree
Showing 6 changed files with 832 additions and 1 deletion.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ lib = library(identifier: 'jenkins@<tag>', retriever: modernSCM([
| [publishGradleCheckTestResults.groovy](./vars/publishGradleCheckTestResults.groovy) | This library runs part of Gradle Check and publishes the failed test data to the [OpenSearch Metrics Cluster](https://metrics.opensearch.org/_dashboards/app/dashboards#/view/e5e64d40-ed31-11ee-be99-69d1dbc75083).
| [gradleCheckFlakyTestDetector.groovy](./vars/gradleCheckFlakyTestDetector.groovy) | This library detects the flaky tests from [OpenSearch Metrics Cluster](https://metrics.opensearch.org/_dashboards/app/dashboards#/view/e5e64d40-ed31-11ee-be99-69d1dbc75083) and generates a test report.
| [gradleCheckFlakyTestGitHubIssue.groovy](./vars/gradleCheckFlakyTestGitHubIssue.groovy) | This library is used in [gradleCheckFlakyTestDetector.groovy](./vars/gradleCheckFlakyTestDetector.groovy) to create/edit the GitHub Issue using the generated test report.
| [publishDistributionBuildResults.groovy](./vars/publishDistributionBuildResults.groovy) | This library is used for publishing the OpenSearch Project Distribution build results to the OpenSearch Metrics cluster.
| [publishIntegTestResults.groovy](./vars/publishIntegTestResults.groovy) | This library is used for publishing the OpenSearch Project Integration Test results to the OpenSearch Metrics cluster.

## Contributing

Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ jacocoTestReport {
}
}

String version = '6.6.1'
String version = '6.7.0'

task updateVersion {
doLast {
Expand Down
212 changes: 212 additions & 0 deletions tests/jenkins/TestPublishDistributionBuildResults.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package jenkins.tests

import org.junit.Before
import static org.mockito.Mockito.*
import groovy.json.JsonSlurper
import org.junit.Test
import groovy.json.JsonOutput

class TestPublishDistributionBuildResults extends BuildPipelineTest {

@Override
@Before
void setUp() {
super.setUp()
binding.setVariable('currentBuild', [
number: 123,
startTimeInMillis: System.currentTimeMillis(),
])
binding.setVariable('env', [
RUN_DISPLAY_URL: 'http://example.com/build/123'
])
binding.setVariable('sh', { cmd -> println cmd })
binding.setVariable('readFile', { filePath -> 'components:\n- name: component1\n repository: repo1\n ref: ref1' })
binding.setVariable('writeFile', { params -> println params.text })
binding.setVariable('withCredentials', { creds, closure -> closure() })
helper.registerAllowedMethod("withAWS", [Map, Closure], { args, closure ->
closure.delegate = delegate
return helper.callClosure(closure)
})
binding.setVariable('curl', { params -> println params })
}

@Test
void testIndexBuildData() {
def indexName = 'test-index'
def testRecordsFile = 'test-records.ndjson'

def script = loadScript('vars/publishDistributionBuildResults.groovy')

def calledCommands = new ArrayList()
script.metaClass.sh = { String command ->
calledCommands << command
if (command.contains("curl -I")) {
return "HTTP/1.1 200 OK"
} else if (command.contains("curl -s -XPUT") && command.contains("test-index")) {
return '{"acknowledged":true}'
} else if (command.contains("curl -XPOST") && command.contains("test-index")) {
return '{"took":10, "errors":false}'
} else {
throw new IllegalArgumentException("Unexpected command: $command")
}
}

script.indexFailedTestData(indexName, testRecordsFile)

def expectedCommandBlock = '''set +e
set +x
echo "INDEX NAME IS test-index"
INDEX_MAPPING='{
"mappings": {
"properties": {
"component": {
"type": "keyword"
},
"component_repo": {
"type": "keyword"
},
"component_ref": {
"type": "keyword"
},
"version": {
"type": "keyword"
},
"distribution_build_number": {
"type": "integer"
},
"distribution_build_url": {
"type": "keyword"
},
"build_start_time": {
"type": "date",
"format": "epoch_millis"
},
"rc": {
"type": "keyword"
},
"rc_number": {
"type": "integer"
},
"component_category": {
"type": "keyword"
},
"component_build_result": {
"type": "keyword"
}
}
}
}'
curl -I "METRICS_HOST_URL/test-index" --aws-sigv4 "aws:amz:us-east-1:es" --user "null:null" -H "x-amz-security-token:null" | grep -E "HTTP\\/[0-9]+(\\.[0-9]+)? 200"
if [ $? -eq 0 ]; then
echo "Index already exists. Indexing Results"
else
echo "Index does not exist. Creating..."
create_index_response=$(curl -s -XPUT "METRICS_HOST_URL/test-index" --aws-sigv4 "aws:amz:us-east-1:es" --user "null:null" -H "x-amz-security-token:null" -H 'Content-Type: application/json' -d "${INDEX_MAPPING}")
if [[ $create_index_response == *'"acknowledged":true'* ]]; then
echo "Index created successfully."
else
echo "Failed to create index. Error message: $create_index_response"
exit 1
fi
fi
if [ -s test-records.ndjson ]; then
echo "File Exists, indexing results."
curl -XPOST "METRICS_HOST_URL/test-index/_bulk" --aws-sigv4 "aws:amz:us-east-1:es" --user "null:null" -H "x-amz-security-token:null" -H "Content-Type: application/x-ndjson" --data-binary "@test-records.ndjson"
else
echo "File Does not exist. No tests records to process."
fi'''
assert calledCommands.size() == 1
assert normalizeString(calledCommands[0]) == normalizeString(expectedCommandBlock)
}

@Test
void testGenerateJson() {
def script = loadScript('vars/publishDistributionBuildResults.groovy')
def result = script.generateJson(
'component1', 'repo1', 'ref1', '1.0', 123,
'http://example.com/build/123', System.currentTimeMillis(), 'rc1', 1, 'test-category', 'failed'
)

def parsedResult = new JsonSlurper().parseText(result)
def expectedJson = [
component: 'component1',
component_repo: 'repo1',
component_ref: 'ref1',
version: '1.0',
distribution_build_number: 123,
distribution_build_url: 'http://example.com/build/123',
// Ignore build_start_time for comparison
rc: 'rc1',
rc_number: 1,
component_category: 'test-category',
component_build_result: 'failed'
]

// Remove the dynamic field for comparison
parsedResult.remove('build_start_time')
assert parsedResult == expectedJson
}

def normalizeString(String str) {
return str.replaceAll(/\s+/, " ").trim()
}

@Test
void testGenerateAndAppendJson() {
def script = loadScript('vars/publishDistributionBuildResults.groovy')
// Test valid parameters
def indexName = "test-index"
def component = "componentA"
def componentRepo = "repoA"
def componentRef = "refA"
def version = "1.0.0"
def distributionBuildNumber = "123"
def distributionBuildUrl = "http://example.com/build/123"
def buildStartTime = "2024-07-19T00:00:00Z"
def rc = true
def rcNumber = "RC1"
def componentCategory = "categoryA"
def status = "success"

def result = script.generateAndAppendJson(indexName, component, componentRepo, componentRef, version, distributionBuildNumber, distributionBuildUrl, buildStartTime, rc, rcNumber, componentCategory, status)
def expectedJson = JsonOutput.toJson([
component: component,
component_repo: componentRepo,
component_ref: componentRef,
version: version,
distribution_build_number: distributionBuildNumber,
distribution_build_url: distributionBuildUrl,
build_start_time: buildStartTime,
rc: rc,
rc_number: rcNumber,
component_category: componentCategory,
component_build_result: status
])
assert result == expectedJson

result = script.generateAndAppendJson(indexName, null, null, null, null, null, null, null, null, null, null, null)
expectedJson = JsonOutput.toJson([
component: null,
component_repo: null,
component_ref: null,
version: null,
distribution_build_number: null,
distribution_build_url: null,
build_start_time: null,
rc: null,
rc_number: null,
component_category: null,
component_build_result: null
])
assert result == expectedJson
}
}
Loading

0 comments on commit cd984fa

Please sign in to comment.