Skip to content

Commit

Permalink
Add remote cypress orchestrator integration with intestest script
Browse files Browse the repository at this point in the history
Signed-off-by: manasvinibs <[email protected]>
  • Loading branch information
manasvinibs committed Jan 17, 2024
1 parent 8cd68dc commit d96118f
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 68 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/remote-cypress-workflow.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: Trigger Remote Cypress Workflow

on:
push:
branches: [ '**' ]
workflow_dispatch:
inputs:
repo:
Expand Down Expand Up @@ -28,9 +30,8 @@ jobs:
- name: Checkout code
uses: actions/checkout@v2

- name: Run Bash Script
- name: Run Remote Cypress Orchestrator Script
env:
GITHUB_SECRET_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
./remoteCypress.sh -r "${{ github.event.inputs.repo }}" -w "${{ github.event.inputs.workflow_name }}" -o "${{ github.event.inputs.os_url }}" -d "${{ github.event.inputs.osd_url }}" -b "${{ github.event.inputs.branch_ref }}"
echo "Setting github secret token to an env variable for remoteCypress script to access the token"
73 changes: 70 additions & 3 deletions integtest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,84 @@ echo -e "Test Files List:"
echo $TEST_FILES | tr ',' '\n'
echo "BROWSER_PATH: $BROWSER_PATH"

# Array to store remote cypress workflow background processes IDs when run in parallel
declare -a all_process_pids

run_remote_cypress() {
local repo="$1"
local workflow_name="$2"
local os_url="$3"
local osd_url="$4"
local branch_ref="$5"

# Call the remoteCypress.sh script with the required arguments
source remoteCypress.sh -r "$repo" -w "$workflow_name" -o "$os_url" -d "$osd_url" -b "$branch_ref" &
bg_process_pid=$!
echo "PID for the repo $repo is : $bg_process_pid"
all_process_pids+=($bg_process_pid)
}

# Read inputs from the manifest file using jq
REMOTE_MANIFEST_FILE="remote_cypress_manifest.json"

# Parse the JSON file using jq and iterate over the components array
components=$(jq -c '.components[]' "$REMOTE_MANIFEST_FILE")
release_version=$(jq -r '.build.version' "$REMOTE_MANIFEST_FILE")
echo "Components: $components"
echo "Release version: $release_version"

for component in $components; do
echo "Processing for the component: $component"

repo=$(echo "$component" | jq -r '.["repository"]')
workflow_name=$(echo "$component" | jq -r '.["workflow-name"]')
os_url=$(echo "$component" | jq -r '.["opensearch"]')
osd_url=$(echo "$component" | jq -r '.["opensearch-dashboards"]')
branch_ref=$(echo "$component" | jq -r '.["ref"]')

# Set default values if the opensearch and opensearch-dashboards are not set in the manifest
os_url=${os_url:-https://artifacts.opensearch.org/releases/bundle/opensearch/$release_version/opensearch-$release_version-linux-x64.tar.gz}
osd_url=${osd_url:-https://artifacts.opensearch.org/releases/bundle/opensearch-dashboards/$release_version/opensearch-dashboards-$release_version-linux-x64.tar.gz}

echo "repo: $repo"
echo "workflow_name: $workflow_name"
echo "os_url: $os_url"
echo "osd_url: $osd_url"
echo "branch_ref: $branch_ref"

# Call the function for each component
run_remote_cypress "$repo" "$workflow_name" "$os_url" "$osd_url" "$branch_ref"
done

# Wait for all processes to finish
wait "${all_process_pids[@]}"

log_directory="/tmp/logfiles"

# Read log files in tmp folder and put the output to CI
find "$log_directory" -type f -name "*.txt" | while IFS= read -r log_file; do
if [ -f "$log_file" ]; then
echo "Log content for file: $log_file"
cat "$log_file"
else
echo "Log file not found: $log_file"
fi
done

# Delete the temporary log files and folder after writing to CI
rm -rf "$log_directory"

## WARNING: THIS LOGIC NEEDS TO BE THE LAST IN THIS FILE! ##
# Cypress returns back the test failure count in the error code
# The CI outputs the error code as test failure count.
#
# We need to ensure the cypress tests are the last execute process to
# the error code gets passed to the CI.
if [ $SECURITY_ENABLED = "true" ]
then

if [ $SECURITY_ENABLED = "true" ]; then
echo "run security enabled tests"
yarn cypress:run-with-security --browser "$BROWSER_PATH" --spec "$TEST_FILES"
else
echo "run security disabled tests"
yarn cypress:run-without-security --browser "$BROWSER_PATH" --spec "$TEST_FILES"
fi
fi
28 changes: 17 additions & 11 deletions poll_remote_workflow.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#!/bin/bash

set -e

# Accessing the secret as an environment variable using GitHub actions while invoking this script
GITHUB_TOKEN=$GITHUB_SECRET_TOKEN
REPO="$1"
UNIQUE_WORKFLOW_ID="$2"
API_URL="$3"
exitcode=2

# Function to check the status of the remote github workflow by constantly polling the workflow-run
check_remote_workflow_status() {
Expand Down Expand Up @@ -52,20 +55,22 @@ check_remote_workflow_status() {
-H "Accept: application/vnd.github.v3+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/$REPO/actions/runs/$run_id")
echo "Workflow run details: $run_details"


# Extract status and conclusion from the run details
status=$(echo "$run_details" | jq -r ".status")
conclusion=$(echo "$run_details" | jq -r ".conclusion")

echo "Workflow run status: $status"

# Check if the status indicates that the workflow is complete
if [[ "$status" == "completed" ]]; then
echo "Workflow completed with status: $status"

# Check if it was successful
if [[ $conclusion == "success" ]]; then
echo "Remote workflow completed successfully."
return 0 # Success
exitcode=0 # Success
break;
elif [[ $conclusion == "failure" ]]; then
echo "Remote workflow completed with errors. Conclusion: $conclusion"

Expand All @@ -75,13 +80,15 @@ check_remote_workflow_status() {
"$jobs_url")

# Parse the workflow to find any failures in the test
failures=$(echo "$run_details" | jq -r '.jobs[] | select(.conclusion == "failure") | .name')
failures=$(echo "$job_details" | jq -r '.jobs[] | select(.conclusion == "failure") | .name')
echo "Test failures: $failures"

return 1 # Failure
exitcode=1 # Failure
break;
else
echo "Remote workflow completed with unexpected conclusion. Conclusion: $conclusion"
return 1 # Failure
exitcode=1 # Failure
break;
fi
else
echo "Remote workflow is still running. Waiting..."
Expand All @@ -91,13 +98,12 @@ check_remote_workflow_status() {
done
else
echo "No matching workflow run object found even after retries. Exiting..."
return 1 # Failure
exitcode=1 # Failure
fi

echo "Remote workflow didn't complete within the specified time."
return 1 # Failure
if [ "$exitcode" -eq 2 ]; then
echo "Remote workflow didn't complete within the specified time."
fi
}

check_remote_workflow_status

exit 0
98 changes: 47 additions & 51 deletions remoteCypress.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,61 +53,57 @@ while getopts ":h:r:w:o:d:b:i:" opt; do
esac
done

# Check if required arguments are provided
if [[ -z "$REPO" || -z "$WORKFLOW_NAME" || -z "$OS_URL" || -z "$OSD_URL" || -z "$BRANCH_REF" ]]; then
echo "Error: Missing required arguments. See usage below."
usage
exit 1
fi
log_directory="/tmp/logfiles/${REPO}"
mkdir -p "$log_directory"
log_file="$log_directory/logfile.txt"

# Accessing the secret as an environment variable using Github actions while invoking this script
GITHUB_TOKEN=$GITHUB_SECRET_TOKEN
# This is to uniquely identify each execution workflow. This ID has to be appended to the workflow_run
# name in the component repository yaml file for polling purpose.
UNIQUE_WORKFLOW_ID=$(uuidgen)
echo "Unique Execution ID: $UNIQUE_WORKFLOW_ID"
# For now we are using Github action API to trigger github workflows in plugins component
# ToDo: We can explore other test runners such as Jenkins to integrate with.
API_URL="https://api.github.com/repos/$REPO/actions/workflows/$WORKFLOW_NAME"
PAYLOAD="{\"ref\": \"$BRANCH_REF\",\"inputs\":{\"build_id\":\"$BUILD_ID\", \"OS_URL\":\"$OS_URL\", \"OSD_URL\":\"$OSD_URL\", \"UNIQUE_ID\":\"$UNIQUE_WORKFLOW_ID\"}}"

# Maximum number of retries for triggering the remote runner
MAX_RETRIES=3

# Trigger the remote GitHub workflow using curl and the PAT token
trigger_remote_workflow() {
curl -L -X POST -H "Authorization: Bearer $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
-w "%{http_code}" \
"$API_URL/dispatches" -d "$PAYLOAD"
}

echo "Triggering the remote GitHub workflow for Cypress tests in the repository: $REPO"
# Check if required arguments are provided
if [[ -n "$REPO" && -n "$WORKFLOW_NAME" && -n "$OS_URL" && -n "$OSD_URL" && -n "$BRANCH_REF" ]]; then
# Accessing the secret as an environment variable using Github actions while invoking this script
GITHUB_TOKEN=$GITHUB_SECRET_TOKEN
# This is to uniquely identify each execution workflow. This ID has to be appended to the workflow_run
# name in the component repository yaml file for polling purpose.
UNIQUE_WORKFLOW_ID=$(uuidgen)
echo "Unique Execution ID: $UNIQUE_WORKFLOW_ID"
# For now we are using Github action API to trigger github workflows in plugins component
# ToDo: We can explore other test runners such as Jenkins to integrate with.
API_URL="https://api.github.com/repos/$REPO/actions/workflows/$WORKFLOW_NAME"
PAYLOAD="{\"ref\": \"$BRANCH_REF\",\"inputs\":{\"build_id\":\"$BUILD_ID\", \"OS_URL\":\"$OS_URL\", \"OSD_URL\":\"$OSD_URL\", \"UNIQUE_ID\":\"$UNIQUE_WORKFLOW_ID\"}}"

# Attempt to trigger the remote workflow with retries
for ((i = 1; i <= MAX_RETRIES; i++)); do
echo "Attempting to trigger the remote workflow (Attempt $i)"
status_code=$(trigger_remote_workflow)
echo "status_code: $status_code"
# Trigger the remote GitHub workflow using curl and the PAT token
trigger_remote_workflow() {
curl -L -X POST -H "Authorization: Bearer $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
-w "%{http_code}" \
"$API_URL/dispatches" -d "$PAYLOAD"
}

if [[ $status_code -ge 200 && $status_code -lt 300 ]]; then
echo "Remote workflow triggered successfully."
break
else
echo "Failed to trigger the remote workflow. Retrying..."
sleep 10 # Adds a delay between retries
fi
echo "Triggering the remote GitHub workflow for Cypress tests in the repository: $REPO"

if [ $i -eq $MAX_RETRIES ]; then
echo "Maximum number of retries reached. Exiting."
exit 1
fi
done
status_code=$(trigger_remote_workflow)
echo "status_code: $status_code"

if [[ $status_code -ge 200 && $status_code -lt 300 ]]; then
echo "Remote workflow triggered successfully."

source poll_remote_workflow.sh "$REPO" "$UNIQUE_WORKFLOW_ID" "$API_URL" > "$log_file" 2>&1
echo "Return code: $exitcode"

# Check the status of the remote workflow
source ./poll_remote_workflow.sh "$REPO" "$UNIQUE_WORKFLOW_ID" "$API_URL"
echo "Return code: $?"
if [ "$exitcode" -eq 0 ]; then
echo "Remote workflow for the repo $REPO completed successfully. EXIT CODE 0 " >> "$log_file"
elif [ "$exitcode" -eq 1 ]; then
echo "Remote workflow for the repo $REPO completed with errors. EXIT CODE 1 " >> "$log_file"
else
echo "Remote workflow for the repo $REPO did not complete within the specified time. EXIT CODE 2 " >> "$log_file"
fi

exit 0
else
echo "Failed to trigger the remote workflow. Exiting."
echo "Failed to trigger the remote workflow for repo $REPO : EXIT CODE 1 " >> "$log_file"
fi
else
echo "Error: Missing required arguments. See usage below."
usage
echo "Remote workflow for the repo $REPO did not start due to missing arguments. EXIT CODE 1 " >> "$log_file"
fi
31 changes: 31 additions & 0 deletions remote_cypress_manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"schema-version": "1.0",
"build": {
"name": "OpenSearch Dashboards Functional Test",
"version": "3.0.0"
},
"ci": {
"image": {
}
},
"components": [
{
"name": "OpenSearch-Dashboards",
"repository": "opensearch-project/OpenSearch-Dashboards",
"workflow-name": "",
"ref": "",
"opensearch": "https://artifacts.opensearch.org/releases/bundle/opensearch/3.0.0/opensearch-3.0.0-linux-x64.tar.gz",
"opensearch-dashboards": "https://artifacts.opensearch.org/releases/bundle/opensearch-dashboards/3.0.0/opensearch-dashboards-3.0.0-linux-x64.tar.gz",
"integ-test": {
"test-configs": [
"with-security",
"without-security"
],
"additional-cluster-configs": {
"vis_builder.enabled": true,
"data_source.enabled": true
}
}
}
]
}

0 comments on commit d96118f

Please sign in to comment.