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 (opensearch-project#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.