From 4f28b26bd0064aac7ca927e5e55cb8b2ec7a0a41 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Tue, 17 Sep 2024 15:45:57 -0700 Subject: [PATCH 01/37] add os, python-version, and opa-version inputs to workflow_dispatch --- .github/workflows/run_smoke_test.yml | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index c913a5d7..2eb1fa8a 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -1,7 +1,5 @@ name: Run Smoke Test on: - workflow_call: - workflow_dispatch: pull_request: types: [opened, reopened] branches: @@ -14,16 +12,34 @@ on: # - ".github/actions/setup-dependencies-macos/action.yml" branches: - "main" + workflow_call: + workflow_dispatch: + inputs: + os: + description: "Choose operating system(s), format must be an array of strings:" + required: true + type: string + default: "['windows-latest', 'macos-latest']" + python-version: + description: "Choose python version(s), format must be an array of strings:" + required: true + type: string + default: "['3.10']" + opa-version: + description: "Choose OPA version" + required: true + type: string + default: "0.59.0" jobs: smoke-test: strategy: fail-fast: false matrix: - os: [windows-latest, macos-latest] + os: ${{ fromJSON(inputs.os) }} # See https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json, # ctrl + f and search "python-3..-" for supported versions - python-version: ["3.9", "3.12"] # "3.8 fails with numpy uninstall" + python-version: ${{ fromJSON(inputs.python-version) }} runs-on: ${{ matrix.os }} environment: Development steps: From c9a9435246f897f3c3ccc54bb65944de678fc2b4 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Tue, 17 Sep 2024 15:54:35 -0700 Subject: [PATCH 02/37] Remove numpy uninstall/install 1.24 from steps --- .../setup-dependencies-windows/action.yml | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/.github/actions/setup-dependencies-windows/action.yml b/.github/actions/setup-dependencies-windows/action.yml index 771ee2a8..b279aa89 100644 --- a/.github/actions/setup-dependencies-windows/action.yml +++ b/.github/actions/setup-dependencies-windows/action.yml @@ -1,6 +1,6 @@ name: Setup Dependencies (Windows) inputs: - operating-system: + os: required: true default: "windows" opa-version: @@ -18,7 +18,7 @@ runs: pip install virtualenv python -m venv .venv .venv\Scripts\activate - + - name: Install dependencies shell: powershell run: | @@ -26,16 +26,7 @@ runs: pip install -r requirements.txt pip install pytest pip install selenium - pip uninstall -y numpy - pip install numpy==1.26.4 - - # Below python v3.9, a lower numpy v1.24.4 is used - #$pythonVersion = [version]${{ inputs.python-version }} - #if ($pythonVersion -ge [version]"3.8.18") { - # pip uninstall -y numpy - # pip install numpy==1.26.4 - #} - + - name: Download OPA executable shell: powershell - run: python download_opa.py -v ${{ inputs.opa-version }} -os ${{ inputs.operating-system }} \ No newline at end of file + run: python download_opa.py -v ${{ inputs.opa-version }} -os ${{ inputs.os }} From edc878b80ba73559280331b5fdde8db8460f8c56 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Tue, 17 Sep 2024 15:56:02 -0700 Subject: [PATCH 03/37] Remove uninstall numpy/install 1.24 from macos dep setup --- .github/actions/setup-dependencies-macos/action.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/actions/setup-dependencies-macos/action.yml b/.github/actions/setup-dependencies-macos/action.yml index 06eedebe..435b4508 100644 --- a/.github/actions/setup-dependencies-macos/action.yml +++ b/.github/actions/setup-dependencies-macos/action.yml @@ -1,6 +1,6 @@ name: Setup Dependencies (macOS) inputs: - operating-system: + os: required: true default: "macos" opa-version: @@ -26,11 +26,9 @@ runs: pip install -r requirements.txt pip install pytest pip install selenium - pip uninstall -y numpy - pip install numpy==1.26.4 - + - name: Download OPA executable shell: bash run: | - python download_opa.py -v ${{ inputs.opa-version }} -os ${{ inputs.operating-system }} - chmod +x opa_darwin_amd64 \ No newline at end of file + python download_opa.py -v ${{ inputs.opa-version }} -os ${{ inputs.os }} + chmod +x opa_darwin_amd64 From 98665c7a4f535239e99d384c0716f8f4b250649b Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:29:36 -0700 Subject: [PATCH 04/37] Add some initial input validation prior to smoke-test job execution --- .github/workflows/run_smoke_test.yml | 38 +++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index 2eb1fa8a..9676f6c8 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -6,8 +6,8 @@ on: - "main" push: # Uncomment when testing locally - #paths: - # - ".github/workflows/run_smoke_test.yml" + paths: + - ".github/workflows/run_smoke_test.yml" # - ".github/actions/setup-dependencies-windows/action.yml" # - ".github/actions/setup-dependencies-macos/action.yml" branches: @@ -29,9 +29,33 @@ on: description: "Choose OPA version" required: true type: string - default: "0.59.0" + default: "0.60.0" jobs: + validate-workflow-inputs: + runs-on: ubuntu-latest + steps: + - name: Validate Workflow Dispatch Inputs + run: | + os_input="${{ inputs.os }}" + pythonversion_input="${{ inputs.python-version }}" + + # Validate the input format with a regular expression + if [[ ! "$os_input" =~ ^\['[^']+'(, '[^']+')*\]$ ]]; then + echo "Invalid OS input: $os_input. Expected format: ['os-1', 'os-2', ...]" + exit 1 + else + echo "OS input is valid: $os_input" + fi + + # Validate the input format with a regular expression + if [[ ! "$pythonversion_input" =~ ^\['[^']+'(, '[^']+')*\]$ ]]; then + echo "Invalid Python version input: $pythonversion_input. Expected format: ['3.10', '3.11', ...]" + exit 1 + else + echo "Python version input is valid: $pythonversion_input" + fi + smoke-test: strategy: fail-fast: false @@ -57,16 +81,16 @@ jobs: if: ${{ matrix.os == 'windows-latest' }} uses: ./.github/actions/setup-dependencies-windows with: - operating-system: "windows" - opa-version: "0.60.0" + os: "windows" + opa-version: ${{ inputs.opa-version }} python-version: ${{ matrix.python-version }} - name: Setup Dependencies (macOS) if: ${{ matrix.os == 'macos-latest' }} uses: ./.github/actions/setup-dependencies-macos with: - operating-system: "macos" - opa-version: "0.60.0" + os: "macos" + opa-version: ${{ inputs.opa-version }} python-version: ${{ matrix.python-version }} - name: Setup credentials for service account From c5f31246da181b92ee63ae2a2a44016494f0f085 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:32:29 -0700 Subject: [PATCH 05/37] add dependency to validate-inputs job for smoke-test to run --- .github/workflows/run_smoke_test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index 9676f6c8..87f98236 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -32,7 +32,7 @@ on: default: "0.60.0" jobs: - validate-workflow-inputs: + validate-inputs: runs-on: ubuntu-latest steps: - name: Validate Workflow Dispatch Inputs @@ -57,6 +57,7 @@ jobs: fi smoke-test: + needs: validate-inputs strategy: fail-fast: false matrix: From 7ff346353c2decca5a9d4deffa66d9a3f57cc1cb Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:34:08 -0700 Subject: [PATCH 06/37] set validate-inputs job to run with bash shell --- .github/workflows/run_smoke_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index 87f98236..80c5ca1e 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -36,6 +36,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Validate Workflow Dispatch Inputs + shell: bash run: | os_input="${{ inputs.os }}" pythonversion_input="${{ inputs.python-version }}" From 796538c3dfdcec9d4398a1eadd93ef943ff17c63 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:38:35 -0700 Subject: [PATCH 07/37] fix regex --- .github/workflows/run_smoke_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index 80c5ca1e..c06a8b18 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -42,7 +42,7 @@ jobs: pythonversion_input="${{ inputs.python-version }}" # Validate the input format with a regular expression - if [[ ! "$os_input" =~ ^\['[^']+'(, '[^']+')*\]$ ]]; then + if [[ ! "$os_input" =~ ^\[\'.+\'(, \'.+\')*\]$ ]]; then echo "Invalid OS input: $os_input. Expected format: ['os-1', 'os-2', ...]" exit 1 else @@ -50,7 +50,7 @@ jobs: fi # Validate the input format with a regular expression - if [[ ! "$pythonversion_input" =~ ^\['[^']+'(, '[^']+')*\]$ ]]; then + if [[ ! "$pythonversion_input" =~ ^\[\'.+\'(, \'.+\')*\]$ ]]; then echo "Invalid Python version input: $pythonversion_input. Expected format: ['3.10', '3.11', ...]" exit 1 else From b937bf146120e3c4fb05a60952c6ff458069a9ae Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Tue, 17 Sep 2024 16:59:40 -0700 Subject: [PATCH 08/37] Update run_smoke_test.yml --- .github/workflows/run_smoke_test.yml | 45 ++++++++++++++-------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index c06a8b18..7cad0286 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -32,40 +32,39 @@ on: default: "0.60.0" jobs: - validate-inputs: + configure-inputs: runs-on: ubuntu-latest + outputs: + os: ${{ steps.set.outputs.os }} + python-version: ${{ steps.set.outputs.python-version }} steps: - - name: Validate Workflow Dispatch Inputs - shell: bash + - name: Configure inputs + id: set run: | - os_input="${{ inputs.os }}" - pythonversion_input="${{ inputs.python-version }}" - - # Validate the input format with a regular expression - if [[ ! "$os_input" =~ ^\[\'.+\'(, \'.+\')*\]$ ]]; then - echo "Invalid OS input: $os_input. Expected format: ['os-1', 'os-2', ...]" - exit 1 - else - echo "OS input is valid: $os_input" - fi - - # Validate the input format with a regular expression - if [[ ! "$pythonversion_input" =~ ^\[\'.+\'(, \'.+\')*\]$ ]]; then - echo "Invalid Python version input: $pythonversion_input. Expected format: ['3.10', '3.11', ...]" - exit 1 + if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + os_val="${{ inputs.os }}" + pythonversion_val="${{ inputs.python-version }}" else - echo "Python version input is valid: $pythonversion_input" + # Default values for other events + os_val="['windows-latest', 'macos-latest']" + pythonversion_val="['3.10']" fi - + echo "os=$os_val" >> $GITHUB_ENV + echo "python-version=$pythonversion_val >> $GITHUB_ENV + echo "::set-output name=os::$os_val" + echo "::set-output name=os::$pythonversion_val" + smoke-test: - needs: validate-inputs + needs: configure-inputs strategy: fail-fast: false matrix: - os: ${{ fromJSON(inputs.os) }} + os: ${{ needs.configure-inputs.outputs.os }} + #os: ${{ fromJSON(inputs.os) }} # See https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json, # ctrl + f and search "python-3..-" for supported versions - python-version: ${{ fromJSON(inputs.python-version) }} + #python-version: ${{ fromJSON(inputs.python-version) }} + python-version: ${{ needs.configure-inputs.outputs.python-version }} runs-on: ${{ matrix.os }} environment: Development steps: From 33d23b21d8c280c264096f4f1e91807f6dcb3ef6 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:01:44 -0700 Subject: [PATCH 09/37] Update run_smoke_test.yml --- .github/workflows/run_smoke_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index 7cad0286..003714c1 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -40,6 +40,7 @@ jobs: steps: - name: Configure inputs id: set + shell: bash run: | if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then os_val="${{ inputs.os }}" From 6687a331f18ae31135dde74ba18178e2bf3672fd Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:06:20 -0700 Subject: [PATCH 10/37] Update run_smoke_test.yml --- .github/workflows/run_smoke_test.yml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index 003714c1..2b47e5f1 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -34,9 +34,6 @@ on: jobs: configure-inputs: runs-on: ubuntu-latest - outputs: - os: ${{ steps.set.outputs.os }} - python-version: ${{ steps.set.outputs.python-version }} steps: - name: Configure inputs id: set @@ -52,20 +49,16 @@ jobs: fi echo "os=$os_val" >> $GITHUB_ENV echo "python-version=$pythonversion_val >> $GITHUB_ENV - echo "::set-output name=os::$os_val" - echo "::set-output name=os::$pythonversion_val" smoke-test: needs: configure-inputs strategy: fail-fast: false matrix: - os: ${{ needs.configure-inputs.outputs.os }} - #os: ${{ fromJSON(inputs.os) }} + os: ${{ fromJSON(env.os) }} # See https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json, # ctrl + f and search "python-3..-" for supported versions - #python-version: ${{ fromJSON(inputs.python-version) }} - python-version: ${{ needs.configure-inputs.outputs.python-version }} + python-version: ${{ fromJSON(env.python-version) }} runs-on: ${{ matrix.os }} environment: Development steps: From 3dd0f5240e9fe19f9da27cdb5c1f03b528e60168 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:10:50 -0700 Subject: [PATCH 11/37] Update run_smoke_test.yml --- .github/workflows/run_smoke_test.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index 2b47e5f1..fc1b1db2 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -36,8 +36,6 @@ jobs: runs-on: ubuntu-latest steps: - name: Configure inputs - id: set - shell: bash run: | if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then os_val="${{ inputs.os }}" @@ -49,6 +47,15 @@ jobs: fi echo "os=$os_val" >> $GITHUB_ENV echo "python-version=$pythonversion_val >> $GITHUB_ENV + + test-job: + needs: configure-inputs + runs-on: ubuntu-latest + steps: + - name: Test + run: | + echo ${{ env.os }} + echo ${{ env.python-version }} smoke-test: needs: configure-inputs From 5217a517c51918d8954add48e91d0a028e289c26 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:19:18 -0700 Subject: [PATCH 12/37] Update run_smoke_test.yml --- .github/workflows/run_smoke_test.yml | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index fc1b1db2..6c2d6d4b 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -32,10 +32,14 @@ on: default: "0.60.0" jobs: - configure-inputs: + configuration: runs-on: ubuntu-latest + outputs: + os: ${{ steps.variables.outputs.os }} + python-version: ${{ steps.variables.outputs.python-version }} steps: - - name: Configure inputs + - name: Configure variable outputs + id: variables run: | if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then os_val="${{ inputs.os }}" @@ -45,27 +49,18 @@ jobs: os_val="['windows-latest', 'macos-latest']" pythonversion_val="['3.10']" fi - echo "os=$os_val" >> $GITHUB_ENV - echo "python-version=$pythonversion_val >> $GITHUB_ENV + echo "os=$os_val" >> $GITHUB_OUTPUT + echo "python-version=$pythonversion_val >> $GITHUB_OUTPUT - test-job: - needs: configure-inputs - runs-on: ubuntu-latest - steps: - - name: Test - run: | - echo ${{ env.os }} - echo ${{ env.python-version }} - smoke-test: - needs: configure-inputs + needs: configuration strategy: fail-fast: false matrix: - os: ${{ fromJSON(env.os) }} + os: ${{ fromJSON(needs.configuration.outputs.os) }} # See https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json, # ctrl + f and search "python-3..-" for supported versions - python-version: ${{ fromJSON(env.python-version) }} + python-version: ${{ fromJSON(needs.configuration.outputs.python-version) }} runs-on: ${{ matrix.os }} environment: Development steps: From 2a6928b38a008dbf44807e811ea7dbcfc1d39dc7 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:20:50 -0700 Subject: [PATCH 13/37] Update run_smoke_test.yml --- .github/workflows/run_smoke_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index 6c2d6d4b..c28d103c 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -49,8 +49,8 @@ jobs: os_val="['windows-latest', 'macos-latest']" pythonversion_val="['3.10']" fi - echo "os=$os_val" >> $GITHUB_OUTPUT - echo "python-version=$pythonversion_val >> $GITHUB_OUTPUT + echo "os=$os_val" >> "$GITHUB_OUTPUT" + echo "python-version=$pythonversion_val >> "$GITHUB_OUTPUT" smoke-test: needs: configuration From bc655bd300d0cef17348953696f8314fd2d04a60 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:25:04 -0700 Subject: [PATCH 14/37] Update run_smoke_test.yml --- .github/workflows/run_smoke_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index c28d103c..21ce6f96 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -50,7 +50,7 @@ jobs: pythonversion_val="['3.10']" fi echo "os=$os_val" >> "$GITHUB_OUTPUT" - echo "python-version=$pythonversion_val >> "$GITHUB_OUTPUT" + echo "python-version=$pythonversion_val" >> "$GITHUB_OUTPUT" smoke-test: needs: configuration From 75cdff498062f1bf74517fe826b1a589534f581b Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:26:40 -0700 Subject: [PATCH 15/37] Update run_smoke_test.yml --- .github/workflows/run_smoke_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index 21ce6f96..53e063ca 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -12,6 +12,7 @@ on: # - ".github/actions/setup-dependencies-macos/action.yml" branches: - "main" + - "*smoketest*" workflow_call: workflow_dispatch: inputs: From 553406011e50f134794b71659f78dca137b735cb Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:32:31 -0700 Subject: [PATCH 16/37] fix configure job to include opa version --- .github/workflows/run_smoke_test.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index 53e063ca..a557e679 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -42,13 +42,17 @@ jobs: - name: Configure variable outputs id: variables run: | + # For manual runs if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then os_val="${{ inputs.os }}" pythonversion_val="${{ inputs.python-version }}" + opaversion_val="${{ inputs.opa-version }}" + + # Default values for other events else - # Default values for other events os_val="['windows-latest', 'macos-latest']" pythonversion_val="['3.10']" + opaversion_val="0.60.0" fi echo "os=$os_val" >> "$GITHUB_OUTPUT" echo "python-version=$pythonversion_val" >> "$GITHUB_OUTPUT" From 6da7b94a212736871dba288664b6acfc0d2af01f Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Tue, 17 Sep 2024 17:35:57 -0700 Subject: [PATCH 17/37] update opa-version to needs.configuration.outputs.opa-version for setup dep macos/windows --- .github/workflows/run_smoke_test.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index a557e679..83c0b667 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -38,6 +38,7 @@ jobs: outputs: os: ${{ steps.variables.outputs.os }} python-version: ${{ steps.variables.outputs.python-version }} + opa-version: ${{ steps.variables.outputs.opa-version }} steps: - name: Configure variable outputs id: variables @@ -56,6 +57,7 @@ jobs: fi echo "os=$os_val" >> "$GITHUB_OUTPUT" echo "python-version=$pythonversion_val" >> "$GITHUB_OUTPUT" + echo "opa-version=$opaversion_val" >> "$GITHUB_OUTPUT" smoke-test: needs: configuration @@ -84,7 +86,7 @@ jobs: uses: ./.github/actions/setup-dependencies-windows with: os: "windows" - opa-version: ${{ inputs.opa-version }} + opa-version: ${{ needs.configuration.outputs.opa-version }} python-version: ${{ matrix.python-version }} - name: Setup Dependencies (macOS) @@ -92,7 +94,7 @@ jobs: uses: ./.github/actions/setup-dependencies-macos with: os: "macos" - opa-version: ${{ inputs.opa-version }} + opa-version: ${{ needs.configuration.outputs.opa-version }} python-version: ${{ matrix.python-version }} - name: Setup credentials for service account From 3519800b8b73c9c53a9c119bcef9799db09dd297 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Wed, 18 Sep 2024 10:17:18 -0700 Subject: [PATCH 18/37] Update input naming convention in windows dep action --- .github/actions/setup-dependencies-windows/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/setup-dependencies-windows/action.yml b/.github/actions/setup-dependencies-windows/action.yml index b279aa89..5025e459 100644 --- a/.github/actions/setup-dependencies-windows/action.yml +++ b/.github/actions/setup-dependencies-windows/action.yml @@ -1,6 +1,6 @@ name: Setup Dependencies (Windows) inputs: - os: + operating-system: required: true default: "windows" opa-version: @@ -29,4 +29,4 @@ runs: - name: Download OPA executable shell: powershell - run: python download_opa.py -v ${{ inputs.opa-version }} -os ${{ inputs.os }} + run: python download_opa.py -v ${{ inputs.opa-version }} -os ${{ inputs.operating-system }} From 24263421cb5d64738655cb67550852f06ab94a0e Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Wed, 18 Sep 2024 10:17:52 -0700 Subject: [PATCH 19/37] Update naming convention for os in macos dep action --- .github/actions/setup-dependencies-macos/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/setup-dependencies-macos/action.yml b/.github/actions/setup-dependencies-macos/action.yml index 435b4508..8562f49d 100644 --- a/.github/actions/setup-dependencies-macos/action.yml +++ b/.github/actions/setup-dependencies-macos/action.yml @@ -1,6 +1,6 @@ name: Setup Dependencies (macOS) inputs: - os: + operating-system: required: true default: "macos" opa-version: @@ -30,5 +30,5 @@ runs: - name: Download OPA executable shell: bash run: | - python download_opa.py -v ${{ inputs.opa-version }} -os ${{ inputs.os }} + python download_opa.py -v ${{ inputs.opa-version }} -os ${{ inputs.operating-system }} chmod +x opa_darwin_amd64 From 0fc2ab74797ce29efb75da370326a3f61d0453bd Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Wed, 18 Sep 2024 10:18:17 -0700 Subject: [PATCH 20/37] Update naming convention for os in smoke test workflow --- .github/workflows/run_smoke_test.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index 83c0b667..5f2d9bb2 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -16,7 +16,7 @@ on: workflow_call: workflow_dispatch: inputs: - os: + operating-system: description: "Choose operating system(s), format must be an array of strings:" required: true type: string @@ -36,7 +36,7 @@ jobs: configuration: runs-on: ubuntu-latest outputs: - os: ${{ steps.variables.outputs.os }} + operating-system: ${{ steps.variables.outputs.operating-system }} python-version: ${{ steps.variables.outputs.python-version }} opa-version: ${{ steps.variables.outputs.opa-version }} steps: @@ -45,17 +45,17 @@ jobs: run: | # For manual runs if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then - os_val="${{ inputs.os }}" + operatingsystem_val="${{ inputs.operating-system }}" pythonversion_val="${{ inputs.python-version }}" opaversion_val="${{ inputs.opa-version }}" # Default values for other events else - os_val="['windows-latest', 'macos-latest']" + operatingsystem_val="['windows-latest', 'macos-latest']" pythonversion_val="['3.10']" opaversion_val="0.60.0" fi - echo "os=$os_val" >> "$GITHUB_OUTPUT" + echo "operating-system=$operatingsystem_val" >> "$GITHUB_OUTPUT" echo "python-version=$pythonversion_val" >> "$GITHUB_OUTPUT" echo "opa-version=$opaversion_val" >> "$GITHUB_OUTPUT" @@ -64,11 +64,11 @@ jobs: strategy: fail-fast: false matrix: - os: ${{ fromJSON(needs.configuration.outputs.os) }} + operating-system: ${{ fromJSON(needs.configuration.outputs.operating-system) }} # See https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json, # ctrl + f and search "python-3..-" for supported versions python-version: ${{ fromJSON(needs.configuration.outputs.python-version) }} - runs-on: ${{ matrix.os }} + runs-on: ${{ matrix.operating-system }} environment: Development steps: - name: Checkout Repository @@ -82,18 +82,18 @@ jobs: cache-dependency-path: "requirements.txt" - name: Setup Dependencies (Windows) - if: ${{ matrix.os == 'windows-latest' }} + if: ${{ matrix.operating-system == 'windows-latest' }} uses: ./.github/actions/setup-dependencies-windows with: - os: "windows" + operating-system: "windows" opa-version: ${{ needs.configuration.outputs.opa-version }} python-version: ${{ matrix.python-version }} - name: Setup Dependencies (macOS) - if: ${{ matrix.os == 'macos-latest' }} + if: ${{ matrix.operating-system == 'macos-latest' }} uses: ./.github/actions/setup-dependencies-macos with: - os: "macos" + operating-system: "macos" opa-version: ${{ needs.configuration.outputs.opa-version }} python-version: ${{ matrix.python-version }} From 335b7caf91b2142d267c536be9b6af0a552117ca Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Wed, 18 Sep 2024 11:01:52 -0700 Subject: [PATCH 21/37] Create initial draft of README.md for smoke test documentation --- Testing/Functional/SmokeTests/README.md | 34 +++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 Testing/Functional/SmokeTests/README.md diff --git a/Testing/Functional/SmokeTests/README.md b/Testing/Functional/SmokeTests/README.md new file mode 100644 index 00000000..66e82b6f --- /dev/null +++ b/Testing/Functional/SmokeTests/README.md @@ -0,0 +1,34 @@ +# ScubaGoggles Functional Smoke Testing Automation +The ScubaGoggles repository consists of an automation suite to help test the functionality of the ScubaGoggles tool itself. The test automation is geared towards contributors who want to execute the functional smoke testing orchestrator as part of their development/testing activity. + +This README outlines the ScubaGoggles software test automation and its usage. The document also contains instructions for adding new functional tests to existing automation suite. + +## Table of Contents + +## Smoke Testing Prerequisites ## +Running the ScubaGoggles functional smoke tests requires a Windows, MacOS, or Linux computer or VM. The development environment should have Python v3.10.x installed at a minimum ([refer to our installing Python dependencies documentation if its not already installed](https://github.com/cisagov/ScubaGoggles/blob/main/docs/installation/DownloadAndInstall.md#installing-python-dependencies)), Pytest, and Selenium installed locally. + +### Pytest and Selenium ### +Pytest is a Python testing framework which is commonly used for unit, integration, and functional testing. [Pytest Get Started](https://docs.pytest.org/en/stable/getting-started.html) + +Selenium supports automation of all the major browsers in the market through the use of WebDriver. [Selenium Get Started](https://www.selenium.dev/documentation/webdriver/getting_started/) + +To install Pytest and Selenium on your development environment, open a new terminal session and run the following command: + +``` +pip install pytest selenium +``` + +> [!NOTE] +> The functional smoke tests use Chrome as its WebDriver when running Selenium tests. If you don't already have the Google Chrome web browser installed, [setup ChromeDriver here](https://developer.chrome.com/docs/chromedriver/get-started). + +## Functional Smoke Testing Structure ## +ScubaGoggles functional smoke testing has two main components: the smoke testing orchestrator and the automated workflow which is run via GitHub Actions. + +### Smoke testing orchestrator ### +The smoke testing orchestrator ([/Testing/Functional/SmokeTests/smoke_test.py](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/SmokeTests/smoke_test.py)) executes each test declared inside the `SmokeTest` class. The tests currently cover: +- if the `scubagoggles gws` command generates correct output for all baselines +- if ScubaResults.json contains API errors or exceptions +- if the generated baseline reports are correct, i.e. BaselineReports.html, CalendarReport.html, ChatReport.html + +### Automated workflow via GitHub Actions ### From 3a673520b935176ab046f59dd1075ac03ede7d9f Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Wed, 18 Sep 2024 13:34:19 -0700 Subject: [PATCH 22/37] Update README.md with prerequisite steps, directory structure, usage --- Testing/Functional/SmokeTests/README.md | 40 ++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/Testing/Functional/SmokeTests/README.md b/Testing/Functional/SmokeTests/README.md index 66e82b6f..34d3477c 100644 --- a/Testing/Functional/SmokeTests/README.md +++ b/Testing/Functional/SmokeTests/README.md @@ -22,13 +22,51 @@ pip install pytest selenium > [!NOTE] > The functional smoke tests use Chrome as its WebDriver when running Selenium tests. If you don't already have the Google Chrome web browser installed, [setup ChromeDriver here](https://developer.chrome.com/docs/chromedriver/get-started). +### Google Service Account ### +The ScubaGoggles functional smoke tests must be executed with a service account. [Refer to our documentation here on how to get setup.](https://github.com/cisagov/ScubaGoggles/blob/main/docs/authentication/ServiceAccount.md#using-a-service-account) + +A `credentials.json` file is required at the root directory of the ScubaGoggles project if running the functional smoke tests in a local development environment. + +Take note of the `subjectemail`, the email used to authenticate with GWS that has necessary administrator permissions, and the GWS `customerdomain` that ScubaGoggles is run against. Both credentials are required in a later step. + ## Functional Smoke Testing Structure ## ScubaGoggles functional smoke testing has two main components: the smoke testing orchestrator and the automated workflow which is run via GitHub Actions. -### Smoke testing orchestrator ### +### Smoke testing directory structure ### The smoke testing orchestrator ([/Testing/Functional/SmokeTests/smoke_test.py](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/SmokeTests/smoke_test.py)) executes each test declared inside the `SmokeTest` class. The tests currently cover: - if the `scubagoggles gws` command generates correct output for all baselines - if ScubaResults.json contains API errors or exceptions - if the generated baseline reports are correct, i.e. BaselineReports.html, CalendarReport.html, ChatReport.html +The smoke testing utils ([/Testing/Functional/SmokeTests/smoke_test_utils.py](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/SmokeTests/smoke_test_utils.py)) stores helper methods which perform various operations. + +The Selenium Browser class ([/Testing/Functional/SmokeTests/selenium_browser.py](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/SmokeTests/selenium_browser.py)) encapsulates the setup, usage, and teardown of Selenium WebDriver instances. + +The Pytest configuration methods ([/Testing/Functional/SmokeTests/conftest.py](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/conftest.py)) declare various Pytest fixtures, allowing for the use of CLI arguments when invoking the Pytest command. + ### Automated workflow via GitHub Actions ### +The automated workflow for running the functional smoke tests ([/.github/workflows/run_smoke_test.yml](https://github.com/cisagov/ScubaGoggles/blob/main/.github/workflows/run_smoke_test.yml)) is triggered on `push` events to the main branch, `pull_request` events when a pull request is opened/reopened, and manually with customer user input via workflow_dispatch. + +## Functional Smoke Testing Usage ## +After completing all of the prerequisite steps, the functional smoke tests can be run on a local development environment or remotely via GitHub Actions. + +### Running on a local development environment ### +Ensure that you have correctly setup a Google service account and that the `credentials.json` stored at the root directory of the ScubaGoggles project is up to date. If you haven't already, please refer back to the [prerequisite step](/Google-Service-Account) on how to get setup before proceeding. + +The following arguments are required when running the functional smoke tests: +- `subjectemail`: user@domain.com (the email used to authenticate with GWS, must have necessary administrator permissions) +- `customerdomain`: domain.com (the domain that ScubaGoggles is run against) + +Run the following command to execute the functional smoke tests: +``` +pytest -vvv ./Testing/Functional/SmokeTests/ --subjectemail="user@domain.com" --customerdomain="domain.com" +``` + +Common Pytest parameters and their use cases: +- `-v` or `--verbose` (shows individual test names and results) +- `-vv` (increases verbosity further, shows detailed output about each test) +- `-vvv` (shows even more detailed output and debug-level information) +- `-s` (disables output capturing allowing print() statements and logs to be shown in the console) + +### Running remotely via GitHub Actions ### + From c208006102d3e18711bcf5c795eb97bf63356b43 Mon Sep 17 00:00:00 2001 From: Mitchel Baker Date: Wed, 18 Sep 2024 20:42:16 +0000 Subject: [PATCH 23/37] update baseline report H1 to match secure configuration baseline reports update --- Testing/Functional/SmokeTests/smoke_test_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Testing/Functional/SmokeTests/smoke_test_utils.py b/Testing/Functional/SmokeTests/smoke_test_utils.py index 7073750c..bb899cf6 100644 --- a/Testing/Functional/SmokeTests/smoke_test_utils.py +++ b/Testing/Functional/SmokeTests/smoke_test_utils.py @@ -11,7 +11,7 @@ from scubagoggles.utils import get_package_version OUTPUT_DIRECTORY = "GWSBaselineConformance" -BASELINE_REPORT_H1 = "SCuBA GWS Security Baseline Conformance Reports" +BASELINE_REPORT_H1 = "SCuBA GWS Secure Configuration Baseline Reports" CISA_GOV_URL = "https://www.cisa.gov/scuba" SCUBAGOGGLES_BASELINES_URL = "https://github.com/cisagov/ScubaGoggles/tree/main/baselines" From 228ccb5e8a0e3f9035f6bc131824d29a7c19c575 Mon Sep 17 00:00:00 2001 From: Mitchel Baker Date: Wed, 18 Sep 2024 21:17:41 +0000 Subject: [PATCH 24/37] update smoke tests to use customerdomain instead of domain; add window-size argument to chrome_options to fix failing selenium test --- .github/workflows/run_smoke_test.yml | 2 +- .../Functional/SmokeTests/selenium_browser.py | 1 + Testing/Functional/SmokeTests/smoke_test.py | 4 ++-- .../Functional/SmokeTests/smoke_test_utils.py | 22 +++++++++---------- Testing/Functional/conftest.py | 8 +++---- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index 5f2d9bb2..0e742159 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -105,4 +105,4 @@ jobs: json: ${{ secrets.GWS_GITHUB_AUTOMATION_CREDS }} - name: Run ScubaGoggles and check for correct output - run: pytest -s -vvv ./Testing/Functional/SmokeTests/ --subjectemail="${{ secrets.GWS_SUBJECT_EMAIL }}" --domain="${{ secrets.GWS_DOMAIN }}" + run: pytest ./Testing/Functional/SmokeTests/ -s -vvv --subjectemail="${{ secrets.GWS_SUBJECT_EMAIL }}" --customerdomain="${{ secrets.GWS_DOMAIN }}" diff --git a/Testing/Functional/SmokeTests/selenium_browser.py b/Testing/Functional/SmokeTests/selenium_browser.py index 69bf9d9d..d3ffbc74 100644 --- a/Testing/Functional/SmokeTests/selenium_browser.py +++ b/Testing/Functional/SmokeTests/selenium_browser.py @@ -13,6 +13,7 @@ class Browser: def __init__(self): chrome_options = Options() chrome_options.add_argument("--headless") + chrome_options.add_argument("--window-size=1200,800") chrome_options.add_argument("--no-sandbox") chrome_options.add_argument("--disable-dev-shm-usage") diff --git a/Testing/Functional/SmokeTests/smoke_test.py b/Testing/Functional/SmokeTests/smoke_test.py index 8c9c6839..3774e20c 100644 --- a/Testing/Functional/SmokeTests/smoke_test.py +++ b/Testing/Functional/SmokeTests/smoke_test.py @@ -57,7 +57,7 @@ def test_scubaresults(self): except (ValueError, Exception) as e: pytest.fail(f"An error occurred, {e}") - def test_scubagoggles_report(self, browser, domain): + def test_scubagoggles_report(self, browser, customerdomain): """ Test if the generated baseline reports are correct, i.e. BaselineReports.html, CalendarReport.html, ChatReport.html @@ -66,7 +66,7 @@ def test_scubagoggles_report(self, browser, domain): output_path: str = get_output_path() report_path: str = prepend_file_protocol(os.path.join(output_path, BASELINE_REPORTS)) browser.get(report_path) - run_selenium(browser, domain) + run_selenium(browser, customerdomain) except (ValueError, AssertionError, Exception) as e: browser.quit() pytest.fail(f"An error occurred, {e}") diff --git a/Testing/Functional/SmokeTests/smoke_test_utils.py b/Testing/Functional/SmokeTests/smoke_test_utils.py index bb899cf6..f90ed528 100644 --- a/Testing/Functional/SmokeTests/smoke_test_utils.py +++ b/Testing/Functional/SmokeTests/smoke_test_utils.py @@ -125,13 +125,13 @@ def verify_scubaresults(jsonfile): if summary["Errors"] != 0: raise ValueError(f"{product} contains errors in the report") -def run_selenium(browser, domain): +def run_selenium(browser, customerdomain): """ Run Selenium tests against the generated reports. Args: browser: A Selenium WebDriver instance - domain: The user's domain + customerdomain: The customer domain """ verify_navigation_links(browser) h1 = browser.find_element(By.TAG_NAME, "h1").text @@ -149,9 +149,9 @@ def run_selenium(browser, domain): if len(reports_table) == 10: for i in range(len(reports_table)): - # Check if domain is present in agency table + # Check if customerdomain is present in agency table # Skip tool version if assessing the parent report - verify_tenant_table(browser, domain, True) + verify_tenant_table(browser, customerdomain, True) reports_table = get_reports_table(browser)[i] baseline_report = reports_table.find_elements(By.TAG_NAME, "td")[0] @@ -169,8 +169,8 @@ def run_selenium(browser, domain): h1 = browser.find_element(By.TAG_NAME, "h1").text assert h1 == products[product]["title"] - # Check if domain and tool version are present in individual report - verify_tenant_table(browser, domain, False) + # Check if customerdomain and tool version are present in individual report + verify_tenant_table(browser, customerdomain, False) policy_tables = browser.find_elements(By.TAG_NAME, "table") for table in policy_tables[1:]: @@ -239,14 +239,14 @@ def get_reports_table(browser): .find_elements(By.TAG_NAME, "tr") ) -def verify_tenant_table(browser, domain, parent): +def verify_tenant_table(browser, customerdomain, parent): """ Get the tenant table rows elements from the DOM. - (Table at the top of each report with user domain, baseline/tool version) + (Table at the top of each report with customer domain, baseline/tool version) Args: browser: A Selenium WebDriver instance - domain: The user's domain + customerdomain: The customer domain parent: boolean to determine parent/individual reports """ tenant_table_rows = ( @@ -255,8 +255,8 @@ def verify_tenant_table(browser, domain, parent): .find_elements(By.TAG_NAME, "tr") ) assert len(tenant_table_rows) == 2 - customer_domain = tenant_table_rows[1].find_elements(By.TAG_NAME, "td")[0].text - assert customer_domain == domain + domain = tenant_table_rows[1].find_elements(By.TAG_NAME, "td")[0].text + assert domain == customerdomain if not parent: # Check for correct tool version, e.g. 0.2.0 diff --git a/Testing/Functional/conftest.py b/Testing/Functional/conftest.py index 456f9be3..f84c2a62 100644 --- a/Testing/Functional/conftest.py +++ b/Testing/Functional/conftest.py @@ -13,7 +13,7 @@ def pytest_addoption(parser): parser: An instance of "argparse.ArgumentParser" """ parser.addoption("--subjectemail", action="store") - parser.addoption("--domain", action="store") + parser.addoption("--customerdomain", action="store") @pytest.fixture def subjectemail(pytestconfig): @@ -26,14 +26,14 @@ def subjectemail(pytestconfig): return pytestconfig.getoption("subjectemail") @pytest.fixture -def domain(pytestconfig): +def customerdomain(pytestconfig): """ - Setup code that shares the "domain" parameter across tests. + Setup code that shares the "customerdomain" parameter across tests. Args: pytestconfig: Provides access to the "Config" object for a current test session """ - return pytestconfig.getoption("domain") + return pytestconfig.getoption("customerdomain") @pytest.fixture def browser(): From 9c5880f3a677e6768100eb0753a17c470c4c4941 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:24:28 -0700 Subject: [PATCH 25/37] add toc, extend initial list of arguments for pytest, add additional documentation references --- Testing/Functional/SmokeTests/README.md | 51 ++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/Testing/Functional/SmokeTests/README.md b/Testing/Functional/SmokeTests/README.md index 34d3477c..0bf352d9 100644 --- a/Testing/Functional/SmokeTests/README.md +++ b/Testing/Functional/SmokeTests/README.md @@ -3,7 +3,16 @@ The ScubaGoggles repository consists of an automation suite to help test the fun This README outlines the ScubaGoggles software test automation and its usage. The document also contains instructions for adding new functional tests to existing automation suite. -## Table of Contents +## Table of Contents +- [Smoke Testing Prerequisites](#smoke-testing-prerequisites) + - [Pytest and Selenium](#pytest-and-selenium) + - [Google Service Account](#google-service-account) +- [Functional Smoke Testing Structure](#functional-smoke-testing-structure) + - [Smoke Testing Classes and Methods](#smoke-testing-classes-and-methods) + - [Automated workflow via GitHub Actions](#automated-workflow-via-github-actions) +- [Functional Smoke Testing Usage](#functional-smoke-testing-usage) + - [Running on a Local Development Environment](#running-on-a-local-development-environment) + - [Running Remotely via GitHub Actions](#running-remotely-via-github-actions) ## Smoke Testing Prerequisites ## Running the ScubaGoggles functional smoke tests requires a Windows, MacOS, or Linux computer or VM. The development environment should have Python v3.10.x installed at a minimum ([refer to our installing Python dependencies documentation if its not already installed](https://github.com/cisagov/ScubaGoggles/blob/main/docs/installation/DownloadAndInstall.md#installing-python-dependencies)), Pytest, and Selenium installed locally. @@ -32,7 +41,7 @@ Take note of the `subjectemail`, the email used to authenticate with GWS that ha ## Functional Smoke Testing Structure ## ScubaGoggles functional smoke testing has two main components: the smoke testing orchestrator and the automated workflow which is run via GitHub Actions. -### Smoke testing directory structure ### +### Smoke Testing Classes and Methods ### The smoke testing orchestrator ([/Testing/Functional/SmokeTests/smoke_test.py](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/SmokeTests/smoke_test.py)) executes each test declared inside the `SmokeTest` class. The tests currently cover: - if the `scubagoggles gws` command generates correct output for all baselines - if ScubaResults.json contains API errors or exceptions @@ -44,13 +53,13 @@ The Selenium Browser class ([/Testing/Functional/SmokeTests/selenium_browser.py] The Pytest configuration methods ([/Testing/Functional/SmokeTests/conftest.py](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/conftest.py)) declare various Pytest fixtures, allowing for the use of CLI arguments when invoking the Pytest command. -### Automated workflow via GitHub Actions ### +### Automated Workflow via GitHub Actions ### The automated workflow for running the functional smoke tests ([/.github/workflows/run_smoke_test.yml](https://github.com/cisagov/ScubaGoggles/blob/main/.github/workflows/run_smoke_test.yml)) is triggered on `push` events to the main branch, `pull_request` events when a pull request is opened/reopened, and manually with customer user input via workflow_dispatch. ## Functional Smoke Testing Usage ## After completing all of the prerequisite steps, the functional smoke tests can be run on a local development environment or remotely via GitHub Actions. -### Running on a local development environment ### +### Running on a Local Development Environment ### Ensure that you have correctly setup a Google service account and that the `credentials.json` stored at the root directory of the ScubaGoggles project is up to date. If you haven't already, please refer back to the [prerequisite step](/Google-Service-Account) on how to get setup before proceeding. The following arguments are required when running the functional smoke tests: @@ -59,7 +68,7 @@ The following arguments are required when running the functional smoke tests: Run the following command to execute the functional smoke tests: ``` -pytest -vvv ./Testing/Functional/SmokeTests/ --subjectemail="user@domain.com" --customerdomain="domain.com" +pytest ./Testing/Functional/SmokeTests/ -vvv --subjectemail="user@domain.com" --customerdomain="domain.com" ``` Common Pytest parameters and their use cases: @@ -67,6 +76,36 @@ Common Pytest parameters and their use cases: - `-vv` (increases verbosity further, shows detailed output about each test) - `-vvv` (shows even more detailed output and debug-level information) - `-s` (disables output capturing allowing print() statements and logs to be shown in the console) +- `-k` (run tests that match a keyword) -### Running remotely via GitHub Actions ### + Example: + ``` + pytest ./Testing/Functional/SmokeTests/ -vvv -k test_scubagoggles_output --subjectemail="user@domain.com" --customerdomain="domain.com" + ``` +- `--tb=short`, `tb=long`, or `tb=none` (provide either brief, full, or suppress the traceback output for failed tests) +- `-q` (reduces output to show only minimal information) + +Run `pytest -h` for a full list of CLI options, or [learn more about Pytest usage](https://docs.pytest.org/en/7.1.x/how-to/usage.html) + +### Running Remotely via GitHub Actions ### +Go to the [run_smoke_test.yml workflow](https://github.com/cisagov/ScubaGoggles/actions/workflows/run_smoke_test.yml) in the GitHub Actions tab. + +![Screenshot (216)](https://github.com/user-attachments/assets/adb1c656-7065-4031-850c-0dc1402e3bda) + +The default values are the following: +- operating system: `['windows-latest', 'macos-latest']` ([list of supported GitHub-hosted runners](https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories)) +- python version: `['3.10']` +- opa version: "0.60.0" + +![Screenshot (214)](https://github.com/user-attachments/assets/9ce1f00e-24e5-4e06-b3ad-aad7b7bc16c7) + +Feel free to play around with the inputs. The workflow will create a matrix strategy for each combination. For example, passing `['windows-latest', 'macos-latest']`, `['3.10', '3.11', 3.12']`, and OPA version `0.60.0` will create the following: + +![Screenshot (218)](https://github.com/user-attachments/assets/212b4e4b-d552-4dc9-a3f6-7f0e29accc4b) + +Some factors to consider: +- Each input is required so an empty string will fail validation. `[]`, `['']`, `['', ]` may also cause the workflow to error out, although this is expected behavior. +- `ubuntu-latest` has not been tested as a value for operating system. Support can be added for this, although its dependent on if this is something we want to test for ScubaGoggles as a whole. +- Python versions <3.10.x are not supported and will cause the smoke test workflow to fail. +- [Due to the lack of an array input type from GitHub](https://github.com/orgs/community/discussions/11692), the required format is an array of strings for the operating system and python version inputs. This is something to capture as a future todo once arrays are available. From 9cb6272f299beb341fc10bc092d0a0f7f4c96016 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:43:08 -0700 Subject: [PATCH 26/37] documentation improvements --- Testing/Functional/SmokeTests/README.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Testing/Functional/SmokeTests/README.md b/Testing/Functional/SmokeTests/README.md index 0bf352d9..e8edc663 100644 --- a/Testing/Functional/SmokeTests/README.md +++ b/Testing/Functional/SmokeTests/README.md @@ -11,16 +11,16 @@ This README outlines the ScubaGoggles software test automation and its usage. Th - [Smoke Testing Classes and Methods](#smoke-testing-classes-and-methods) - [Automated workflow via GitHub Actions](#automated-workflow-via-github-actions) - [Functional Smoke Testing Usage](#functional-smoke-testing-usage) - - [Running on a Local Development Environment](#running-on-a-local-development-environment) + - [Running in a Local Development Environment](#running-in-a-local-development-environment) - [Running Remotely via GitHub Actions](#running-remotely-via-github-actions) ## Smoke Testing Prerequisites ## Running the ScubaGoggles functional smoke tests requires a Windows, MacOS, or Linux computer or VM. The development environment should have Python v3.10.x installed at a minimum ([refer to our installing Python dependencies documentation if its not already installed](https://github.com/cisagov/ScubaGoggles/blob/main/docs/installation/DownloadAndInstall.md#installing-python-dependencies)), Pytest, and Selenium installed locally. ### Pytest and Selenium ### -Pytest is a Python testing framework which is commonly used for unit, integration, and functional testing. [Pytest Get Started](https://docs.pytest.org/en/stable/getting-started.html) +Pytest is a Python testing framework which is commonly used for unit, integration, and functional testing. ([Pytest Get Started](https://docs.pytest.org/en/stable/getting-started.html)) -Selenium supports automation of all the major browsers in the market through the use of WebDriver. [Selenium Get Started](https://www.selenium.dev/documentation/webdriver/getting_started/) +Selenium supports automation of all the major browsers in the market through the use of WebDriver. ([Selenium Get Started](https://www.selenium.dev/documentation/webdriver/getting_started/)) To install Pytest and Selenium on your development environment, open a new terminal session and run the following command: @@ -59,14 +59,15 @@ The automated workflow for running the functional smoke tests ([/.github/workflo ## Functional Smoke Testing Usage ## After completing all of the prerequisite steps, the functional smoke tests can be run on a local development environment or remotely via GitHub Actions. -### Running on a Local Development Environment ### -Ensure that you have correctly setup a Google service account and that the `credentials.json` stored at the root directory of the ScubaGoggles project is up to date. If you haven't already, please refer back to the [prerequisite step](/Google-Service-Account) on how to get setup before proceeding. +### Running in a Local Development Environment ### +> [!IMPORTANT] +> Ensure that you have correctly setup a Google service account and that the `credentials.json` stored at the root directory of the ScubaGoggles project is up to date. If you haven't already, please refer back to the [prerequisite step on Google Service Accounts](#google-service-account) for how to get setup before proceeding. The following arguments are required when running the functional smoke tests: -- `subjectemail`: user@domain.com (the email used to authenticate with GWS, must have necessary administrator permissions) -- `customerdomain`: domain.com (the domain that ScubaGoggles is run against) +- `--subjectemail="user@domain.com"` (the email used to authenticate with GWS, must have necessary administrator permissions) +- `--customerdomain="domain.com"` (the domain that ScubaGoggles is run against) -Run the following command to execute the functional smoke tests: +Replace `user@domain.com` with your email and `domain.com` with your domain, then run the following command to execute the functional smoke tests: ``` pytest ./Testing/Functional/SmokeTests/ -vvv --subjectemail="user@domain.com" --customerdomain="domain.com" ``` @@ -78,15 +79,15 @@ Common Pytest parameters and their use cases: - `-s` (disables output capturing allowing print() statements and logs to be shown in the console) - `-k` (run tests that match a keyword) - Example: + Example (only runs test_scubagoggles_output, deselects the rest): ``` pytest ./Testing/Functional/SmokeTests/ -vvv -k test_scubagoggles_output --subjectemail="user@domain.com" --customerdomain="domain.com" ``` -- `--tb=short`, `tb=long`, or `tb=none` (provide either brief, full, or suppress the traceback output for failed tests) +- `--tb=short`, `tb=long`, or `tb=no` (provide either brief, full, or suppress the traceback output for failed tests) - `-q` (reduces output to show only minimal information) -Run `pytest -h` for a full list of CLI options, or [learn more about Pytest usage](https://docs.pytest.org/en/7.1.x/how-to/usage.html) +Run `pytest -h` for a full list of CLI options, or [learn more about Pytest usage here.](https://docs.pytest.org/en/7.1.x/how-to/usage.html) ### Running Remotely via GitHub Actions ### Go to the [run_smoke_test.yml workflow](https://github.com/cisagov/ScubaGoggles/actions/workflows/run_smoke_test.yml) in the GitHub Actions tab. From 69a170bd371cdcf8494a6bb0bad2a0c6b37fca83 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Wed, 18 Sep 2024 15:03:18 -0700 Subject: [PATCH 27/37] update running via github actions section to reflect main branch instead of 340 --- Testing/Functional/SmokeTests/README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Testing/Functional/SmokeTests/README.md b/Testing/Functional/SmokeTests/README.md index e8edc663..9b1c400d 100644 --- a/Testing/Functional/SmokeTests/README.md +++ b/Testing/Functional/SmokeTests/README.md @@ -90,18 +90,17 @@ Common Pytest parameters and their use cases: Run `pytest -h` for a full list of CLI options, or [learn more about Pytest usage here.](https://docs.pytest.org/en/7.1.x/how-to/usage.html) ### Running Remotely via GitHub Actions ### -Go to the [run_smoke_test.yml workflow](https://github.com/cisagov/ScubaGoggles/actions/workflows/run_smoke_test.yml) in the GitHub Actions tab. +Go to the [run_smoke_test.yml workflow](https://github.com/cisagov/ScubaGoggles/actions/workflows/run_smoke_test.yml) in the GitHub Actions tab, then click the "Run workflow" dropdown button. -![Screenshot (216)](https://github.com/user-attachments/assets/adb1c656-7065-4031-850c-0dc1402e3bda) - -The default values are the following: +The default values are the following: +- ref branch: `main` but can be set to any branch - operating system: `['windows-latest', 'macos-latest']` ([list of supported GitHub-hosted runners](https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners#standard-github-hosted-runners-for-public-repositories)) - python version: `['3.10']` - opa version: "0.60.0" -![Screenshot (214)](https://github.com/user-attachments/assets/9ce1f00e-24e5-4e06-b3ad-aad7b7bc16c7) +![Screenshot (226)](https://github.com/user-attachments/assets/6f25b7a9-3981-4866-a413-93df4bae1130) -Feel free to play around with the inputs. The workflow will create a matrix strategy for each combination. For example, passing `['windows-latest', 'macos-latest']`, `['3.10', '3.11', 3.12']`, and OPA version `0.60.0` will create the following: +Feel free to play around with the inputs then click the "Run workflow" button when ready. The workflow will create a matrix strategy for each combination. For example, passing `['windows-latest', 'macos-latest']`, `['3.10', '3.11', 3.12']`, and OPA version `0.60.0` will create the following: ![Screenshot (218)](https://github.com/user-attachments/assets/212b4e4b-d552-4dc9-a3f6-7f0e29accc4b) From 65b9a04566125e73c83a0796982abc7d2e86d4a8 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Wed, 18 Sep 2024 15:10:03 -0700 Subject: [PATCH 28/37] try removing environment: Development and replacing with env key/value combo --- .github/workflows/run_smoke_test.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index 0e742159..7e65a4ed 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -69,7 +69,11 @@ jobs: # ctrl + f and search "python-3..-" for supported versions python-version: ${{ fromJSON(needs.configuration.outputs.python-version) }} runs-on: ${{ matrix.operating-system }} - environment: Development + env: + GWS_GITHUB_AUTOMATION_CREDS: ${{ secrets.GWS_GITHUB_AUTOMATION_CREDS }} + GWS_SUBJECT_EMAIL: ${{ secrets.GWS_SUBJECT_EMAIL }} + GWS_DOMAIN: ${{ secrets.GWS_DOMAIN }} + #environment: Development steps: - name: Checkout Repository uses: actions/checkout@v4 @@ -102,7 +106,7 @@ jobs: uses: jsdaniell/create-json@v1.2.3 with: name: "credentials.json" - json: ${{ secrets.GWS_GITHUB_AUTOMATION_CREDS }} + json: $env:GWS_GITHUB_AUTOMATION_CREDS - name: Run ScubaGoggles and check for correct output - run: pytest ./Testing/Functional/SmokeTests/ -s -vvv --subjectemail="${{ secrets.GWS_SUBJECT_EMAIL }}" --customerdomain="${{ secrets.GWS_DOMAIN }}" + run: pytest ./Testing/Functional/SmokeTests/ -s -vvv --subjectemail="$env:GWS_SUBJECT_EMAIL" --customerdomain="$env:GWS_DOMAIN" From f3de724e72571155eb97a035a521e3b0e0c30a40 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Wed, 18 Sep 2024 15:16:22 -0700 Subject: [PATCH 29/37] try updating permissions to workflow --- .github/workflows/run_smoke_test.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index 7e65a4ed..5465a553 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -32,6 +32,8 @@ on: type: string default: "0.60.0" +permissions: read-all + jobs: configuration: runs-on: ubuntu-latest @@ -73,6 +75,8 @@ jobs: GWS_GITHUB_AUTOMATION_CREDS: ${{ secrets.GWS_GITHUB_AUTOMATION_CREDS }} GWS_SUBJECT_EMAIL: ${{ secrets.GWS_SUBJECT_EMAIL }} GWS_DOMAIN: ${{ secrets.GWS_DOMAIN }} + permissions: + contents: read #environment: Development steps: - name: Checkout Repository From 5360b8a4633292fecbf11a138bf322413e9f2c4a Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Wed, 18 Sep 2024 15:34:39 -0700 Subject: [PATCH 30/37] Update run_smoke_test.yml --- .github/workflows/run_smoke_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index 5465a553..7880472f 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -113,4 +113,4 @@ jobs: json: $env:GWS_GITHUB_AUTOMATION_CREDS - name: Run ScubaGoggles and check for correct output - run: pytest ./Testing/Functional/SmokeTests/ -s -vvv --subjectemail="$env:GWS_SUBJECT_EMAIL" --customerdomain="$env:GWS_DOMAIN" + run: pytest ./Testing/Functional/SmokeTests/ -vvv --subjectemail="$env:GWS_SUBJECT_EMAIL" --customerdomain="$env:GWS_DOMAIN" From d690ce3fb55fc9eb7c1bd5c16ddbf219d699839d Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Wed, 18 Sep 2024 15:42:01 -0700 Subject: [PATCH 31/37] Update run_smoke_test.yml --- .github/workflows/run_smoke_test.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index 7880472f..ae2b0dd7 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -32,8 +32,6 @@ on: type: string default: "0.60.0" -permissions: read-all - jobs: configuration: runs-on: ubuntu-latest @@ -75,9 +73,6 @@ jobs: GWS_GITHUB_AUTOMATION_CREDS: ${{ secrets.GWS_GITHUB_AUTOMATION_CREDS }} GWS_SUBJECT_EMAIL: ${{ secrets.GWS_SUBJECT_EMAIL }} GWS_DOMAIN: ${{ secrets.GWS_DOMAIN }} - permissions: - contents: read - #environment: Development steps: - name: Checkout Repository uses: actions/checkout@v4 @@ -110,7 +105,7 @@ jobs: uses: jsdaniell/create-json@v1.2.3 with: name: "credentials.json" - json: $env:GWS_GITHUB_AUTOMATION_CREDS + json: ${{ secrets.GWS_GITHUB_AUTOMATION_CREDS }} - name: Run ScubaGoggles and check for correct output - run: pytest ./Testing/Functional/SmokeTests/ -vvv --subjectemail="$env:GWS_SUBJECT_EMAIL" --customerdomain="$env:GWS_DOMAIN" + run: pytest ./Testing/Functional/SmokeTests/ -vvv --subjectemail="${{ secrets.GWS_SUBJECT_EMAIL }}" --customerdomain="${{ secrets.GWS_DOMAIN }}" From f9ae0c37f2e8ae4effed2af32f73668ffdbfa182 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Wed, 18 Sep 2024 15:51:44 -0700 Subject: [PATCH 32/37] remove env key/value since its unneeded, call secrets vars directly; remove permissions: read-only since we have to write credentials.json to root of runner --- .github/workflows/run_smoke_test.yml | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index ae2b0dd7..7f301578 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -5,11 +5,10 @@ on: branches: - "main" push: - # Uncomment when testing locally paths: - ".github/workflows/run_smoke_test.yml" - # - ".github/actions/setup-dependencies-windows/action.yml" - # - ".github/actions/setup-dependencies-macos/action.yml" + - ".github/actions/setup-dependencies-windows/action.yml" + - ".github/actions/setup-dependencies-macos/action.yml" branches: - "main" - "*smoketest*" @@ -69,10 +68,6 @@ jobs: # ctrl + f and search "python-3..-" for supported versions python-version: ${{ fromJSON(needs.configuration.outputs.python-version) }} runs-on: ${{ matrix.operating-system }} - env: - GWS_GITHUB_AUTOMATION_CREDS: ${{ secrets.GWS_GITHUB_AUTOMATION_CREDS }} - GWS_SUBJECT_EMAIL: ${{ secrets.GWS_SUBJECT_EMAIL }} - GWS_DOMAIN: ${{ secrets.GWS_DOMAIN }} steps: - name: Checkout Repository uses: actions/checkout@v4 From 362b8d7e697da95d746be3e0f1990e19c6c94963 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:01:22 -0700 Subject: [PATCH 33/37] add pull_request_review on submit trigger back into workflow --- .github/workflows/run_smoke_test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/run_smoke_test.yml b/.github/workflows/run_smoke_test.yml index 7f301578..eee99664 100644 --- a/.github/workflows/run_smoke_test.yml +++ b/.github/workflows/run_smoke_test.yml @@ -4,7 +4,10 @@ on: types: [opened, reopened] branches: - "main" + pull_request_review: + types: [submitted] push: + # These paths are primarily for workflow testing purposes paths: - ".github/workflows/run_smoke_test.yml" - ".github/actions/setup-dependencies-windows/action.yml" From 80dd72aa968a4a2788502faa7ebd2b2ec51aacc3 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:35:58 -0700 Subject: [PATCH 34/37] add section on adding new functional tests with example --- Testing/Functional/SmokeTests/README.md | 36 +++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/Testing/Functional/SmokeTests/README.md b/Testing/Functional/SmokeTests/README.md index 9b1c400d..e7a8d465 100644 --- a/Testing/Functional/SmokeTests/README.md +++ b/Testing/Functional/SmokeTests/README.md @@ -1,7 +1,7 @@ # ScubaGoggles Functional Smoke Testing Automation The ScubaGoggles repository consists of an automation suite to help test the functionality of the ScubaGoggles tool itself. The test automation is geared towards contributors who want to execute the functional smoke testing orchestrator as part of their development/testing activity. -This README outlines the ScubaGoggles software test automation and its usage. The document also contains instructions for adding new functional tests to existing automation suite. +This README outlines the ScubaGoggles software test automation structure and its usage. The document also contains instructions for adding new tests to the existing automation suite if necessary. ## Table of Contents - [Smoke Testing Prerequisites](#smoke-testing-prerequisites) @@ -13,6 +13,7 @@ This README outlines the ScubaGoggles software test automation and its usage. Th - [Functional Smoke Testing Usage](#functional-smoke-testing-usage) - [Running in a Local Development Environment](#running-in-a-local-development-environment) - [Running Remotely via GitHub Actions](#running-remotely-via-github-actions) +- [Adding New Functional Tests](#adding-new-functional-tests) ## Smoke Testing Prerequisites ## Running the ScubaGoggles functional smoke tests requires a Windows, MacOS, or Linux computer or VM. The development environment should have Python v3.10.x installed at a minimum ([refer to our installing Python dependencies documentation if its not already installed](https://github.com/cisagov/ScubaGoggles/blob/main/docs/installation/DownloadAndInstall.md#installing-python-dependencies)), Pytest, and Selenium installed locally. @@ -108,4 +109,35 @@ Some factors to consider: - Each input is required so an empty string will fail validation. `[]`, `['']`, `['', ]` may also cause the workflow to error out, although this is expected behavior. - `ubuntu-latest` has not been tested as a value for operating system. Support can be added for this, although its dependent on if this is something we want to test for ScubaGoggles as a whole. - Python versions <3.10.x are not supported and will cause the smoke test workflow to fail. -- [Due to the lack of an array input type from GitHub](https://github.com/orgs/community/discussions/11692), the required format is an array of strings for the operating system and python version inputs. This is something to capture as a future todo once arrays are available. +- [Due to the lack of an array input type from GitHub](https://github.com/orgs/community/discussions/11692), the required format is an array of strings for the operating system and python version inputs. This is something to capture as a future todo once arrays are available. + +## Adding New Functional Tests ## +A new functional smoke test should be added as a method in the [SmokeTest class](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/SmokeTests/smoke_test.py). Helper methods should be stored in [smoke_test_utils.py](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/SmokeTests/smoke_test_utils.py). + +Below is an example that runs the `scubagoggles gws` command then performs some conditional check with Selenium: + +``` +class SmokeTest: + ... + + def test_scubagoggles_execution(self, browser, subjectemail): + """ + Test if the `scubagoggles gws` command succeeds or fails. + + Args: + browser: A Selenium WebDriver instance + subjectemail: The email address of an admin user who created the service account + """ + try: + command: str = f"scubagoggles gws --subjectemail {subjectemail} --quiet" + result = subprocess.run(command, shell=True, check=True, capture_output=True) + + if result.returncode != 0: + print(f"Scubagoggles execution failed with error:\n{result.stderr}") + assert False + else: + print("Scubagoggles execution succeeded") + print(f"Output:\n{result.stdout}") + except Exception as e: + pytest.fail(f"An error occurred, {e}") +``` From 8def1cbad84aecadb640bbdd2aa8849e345ea682 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:38:10 -0700 Subject: [PATCH 35/37] cleanup documentation --- Testing/Functional/SmokeTests/README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Testing/Functional/SmokeTests/README.md b/Testing/Functional/SmokeTests/README.md index e7a8d465..67c9a618 100644 --- a/Testing/Functional/SmokeTests/README.md +++ b/Testing/Functional/SmokeTests/README.md @@ -114,18 +114,17 @@ Some factors to consider: ## Adding New Functional Tests ## A new functional smoke test should be added as a method in the [SmokeTest class](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/SmokeTests/smoke_test.py). Helper methods should be stored in [smoke_test_utils.py](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/SmokeTests/smoke_test_utils.py). -Below is an example that runs the `scubagoggles gws` command then performs some conditional check with Selenium: +Below is an example that tests the `scubagoggles gws` command: ``` class SmokeTest: ... - def test_scubagoggles_execution(self, browser, subjectemail): + def test_scubagoggles_execution(self, subjectemail): """ Test if the `scubagoggles gws` command succeeds or fails. Args: - browser: A Selenium WebDriver instance subjectemail: The email address of an admin user who created the service account """ try: From bdd0e4aef4f6bbcf3f0b7bef8a422926cbe84a04 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:48:51 -0700 Subject: [PATCH 36/37] final proofreading --- Testing/Functional/SmokeTests/README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Testing/Functional/SmokeTests/README.md b/Testing/Functional/SmokeTests/README.md index 67c9a618..9ebf2663 100644 --- a/Testing/Functional/SmokeTests/README.md +++ b/Testing/Functional/SmokeTests/README.md @@ -13,7 +13,7 @@ This README outlines the ScubaGoggles software test automation structure and its - [Functional Smoke Testing Usage](#functional-smoke-testing-usage) - [Running in a Local Development Environment](#running-in-a-local-development-environment) - [Running Remotely via GitHub Actions](#running-remotely-via-github-actions) -- [Adding New Functional Tests](#adding-new-functional-tests) +- [Adding New Tests](#adding-new-tests) ## Smoke Testing Prerequisites ## Running the ScubaGoggles functional smoke tests requires a Windows, MacOS, or Linux computer or VM. The development environment should have Python v3.10.x installed at a minimum ([refer to our installing Python dependencies documentation if its not already installed](https://github.com/cisagov/ScubaGoggles/blob/main/docs/installation/DownloadAndInstall.md#installing-python-dependencies)), Pytest, and Selenium installed locally. @@ -30,17 +30,17 @@ pip install pytest selenium ``` > [!NOTE] -> The functional smoke tests use Chrome as its WebDriver when running Selenium tests. If you don't already have the Google Chrome web browser installed, [setup ChromeDriver here](https://developer.chrome.com/docs/chromedriver/get-started). +> The functional smoke tests use Chrome as its WebDriver when running Selenium tests. [Setup ChromeDriver](https://developer.chrome.com/docs/chromedriver/get-started) if you don't already have the Google Chrome web browser installed. ### Google Service Account ### -The ScubaGoggles functional smoke tests must be executed with a service account. [Refer to our documentation here on how to get setup.](https://github.com/cisagov/ScubaGoggles/blob/main/docs/authentication/ServiceAccount.md#using-a-service-account) +The ScubaGoggles functional smoke tests must be executed with a service account. [Refer to our service account documentation on how to get setup.](https://github.com/cisagov/ScubaGoggles/blob/main/docs/authentication/ServiceAccount.md#using-a-service-account) A `credentials.json` file is required at the root directory of the ScubaGoggles project if running the functional smoke tests in a local development environment. Take note of the `subjectemail`, the email used to authenticate with GWS that has necessary administrator permissions, and the GWS `customerdomain` that ScubaGoggles is run against. Both credentials are required in a later step. ## Functional Smoke Testing Structure ## -ScubaGoggles functional smoke testing has two main components: the smoke testing orchestrator and the automated workflow which is run via GitHub Actions. +ScubaGoggles functional smoke testing has two main components: the smoke testing orchestrator and the automated workflow run via GitHub Actions. ### Smoke Testing Classes and Methods ### The smoke testing orchestrator ([/Testing/Functional/SmokeTests/smoke_test.py](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/SmokeTests/smoke_test.py)) executes each test declared inside the `SmokeTest` class. The tests currently cover: @@ -55,14 +55,14 @@ The Selenium Browser class ([/Testing/Functional/SmokeTests/selenium_browser.py] The Pytest configuration methods ([/Testing/Functional/SmokeTests/conftest.py](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/conftest.py)) declare various Pytest fixtures, allowing for the use of CLI arguments when invoking the Pytest command. ### Automated Workflow via GitHub Actions ### -The automated workflow for running the functional smoke tests ([/.github/workflows/run_smoke_test.yml](https://github.com/cisagov/ScubaGoggles/blob/main/.github/workflows/run_smoke_test.yml)) is triggered on `push` events to the main branch, `pull_request` events when a pull request is opened/reopened, and manually with customer user input via workflow_dispatch. +The automated workflow for running the functional smoke tests ([/.github/workflows/run_smoke_test.yml](https://github.com/cisagov/ScubaGoggles/blob/main/.github/workflows/run_smoke_test.yml)) is triggered on `push` events to the main branch, `pull_request` events when a pull request is opened/reopened/reviewed, and manually with custom user input via workflow_dispatch. ## Functional Smoke Testing Usage ## -After completing all of the prerequisite steps, the functional smoke tests can be run on a local development environment or remotely via GitHub Actions. +After completing all of the prerequisite steps, the functional smoke tests can be run in a local development environment or remotely via GitHub Actions. ### Running in a Local Development Environment ### > [!IMPORTANT] -> Ensure that you have correctly setup a Google service account and that the `credentials.json` stored at the root directory of the ScubaGoggles project is up to date. If you haven't already, please refer back to the [prerequisite step on Google Service Accounts](#google-service-account) for how to get setup before proceeding. +> Ensure that you have correctly setup a Google service account and that the `credentials.json` stored at the root directory of the ScubaGoggles project is up to date. If you haven't already, please refer back to the [prerequisite step on Google Service Accounts](#google-service-account) for how to setup before proceeding. The following arguments are required when running the functional smoke tests: - `--subjectemail="user@domain.com"` (the email used to authenticate with GWS, must have necessary administrator permissions) @@ -88,7 +88,7 @@ Common Pytest parameters and their use cases: - `--tb=short`, `tb=long`, or `tb=no` (provide either brief, full, or suppress the traceback output for failed tests) - `-q` (reduces output to show only minimal information) -Run `pytest -h` for a full list of CLI options, or [learn more about Pytest usage here.](https://docs.pytest.org/en/7.1.x/how-to/usage.html) +Run `pytest -h` for a full list of CLI options or [learn more about Pytest usage here.](https://docs.pytest.org/en/7.1.x/how-to/usage.html) ### Running Remotely via GitHub Actions ### Go to the [run_smoke_test.yml workflow](https://github.com/cisagov/ScubaGoggles/actions/workflows/run_smoke_test.yml) in the GitHub Actions tab, then click the "Run workflow" dropdown button. @@ -111,8 +111,8 @@ Some factors to consider: - Python versions <3.10.x are not supported and will cause the smoke test workflow to fail. - [Due to the lack of an array input type from GitHub](https://github.com/orgs/community/discussions/11692), the required format is an array of strings for the operating system and python version inputs. This is something to capture as a future todo once arrays are available. -## Adding New Functional Tests ## -A new functional smoke test should be added as a method in the [SmokeTest class](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/SmokeTests/smoke_test.py). Helper methods should be stored in [smoke_test_utils.py](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/SmokeTests/smoke_test_utils.py). +## Adding New Tests ## +A new smoke test should be added as a method in the [SmokeTest class](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/SmokeTests/smoke_test.py). Helper methods should be added in [smoke_test_utils.py](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/SmokeTests/smoke_test_utils.py). Below is an example that tests the `scubagoggles gws` command: From 8cae42e3a14afcc579ad8a0d91336a3080954ad7 Mon Sep 17 00:00:00 2001 From: mitchelbaker-cisa <149098823+mitchelbaker-cisa@users.noreply.github.com> Date: Thu, 19 Sep 2024 10:14:39 -0700 Subject: [PATCH 37/37] remove correct wording and replace with valid --- Testing/Functional/SmokeTests/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Testing/Functional/SmokeTests/README.md b/Testing/Functional/SmokeTests/README.md index 9ebf2663..268b6179 100644 --- a/Testing/Functional/SmokeTests/README.md +++ b/Testing/Functional/SmokeTests/README.md @@ -44,9 +44,9 @@ ScubaGoggles functional smoke testing has two main components: the smoke testing ### Smoke Testing Classes and Methods ### The smoke testing orchestrator ([/Testing/Functional/SmokeTests/smoke_test.py](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/SmokeTests/smoke_test.py)) executes each test declared inside the `SmokeTest` class. The tests currently cover: -- if the `scubagoggles gws` command generates correct output for all baselines +- if the `scubagoggles gws` command generates valid output for all baselines - if ScubaResults.json contains API errors or exceptions -- if the generated baseline reports are correct, i.e. BaselineReports.html, CalendarReport.html, ChatReport.html +- if the generated baseline reports, i.e. BaselineReports.html, CalendarReport.html, ChatReport.html, etc., contain valid content and all links redirect accordingly The smoke testing utils ([/Testing/Functional/SmokeTests/smoke_test_utils.py](https://github.com/cisagov/ScubaGoggles/blob/main/Testing/Functional/SmokeTests/smoke_test_utils.py)) stores helper methods which perform various operations.