# Handling Unexpected Closure of Testing Executions

In case, your **testing execution is aborted** because of any failure, it is **important to close all the executions left open** because the Testing framework was not able to perform a graceful shutdown for example.

Below is a sample code that checks the list of remaining open executions and closes them one by one as part of a post-build section in a Jenkins pipeline script used to execute the tests.

Details on the *Get Executions Status List API* can be found in our dedicated documentation page [#get-executions-status-list](https://docs.sealights.io/knowledgebase/setup-and-configuration/integrations/rest-apis/test-sessions-api-a.k.a-tia-api#get-executions-status-list "mention").\
For example, you have the ability to query the list of executions with a filter based on the Test Stage name or the LabId in addition to the execution status “created”.

{% tabs fullWidth="true" %}
{% tab title="GitHub Actions/Python" %}
GitHub Action Yaml executing the Sealights Cleanup step on UIT failure (or cancellation)

{% code overflow="wrap" lineNumbers="true" fullWidth="true" %}

```yaml
  unit-tests:
    needs: build
    runs-on: ubuntu-latest
    env:
      SEALIGHTS_TEST_STAGE: "Unit Tests"
    steps:
      ## ...
      - name: Run Unit Tests
        id: unittest
        env:
          SEALIGHTS_TEST_STAGE: "Unit Tests"
        continue-on-error: true
        run: ##Unit test command
      - name: Sealights - Cleanup Open Executions
        if: (cancelled() || steps.unittest.outcome == 'failure') && env.SEALIGHTS_ENABLED == 'true'
        run: |
          pip install requests
          python -u scripts/sealights-utils.py --cleanup \
            "${{ needs.build.outputs.build_session_id }}" \
            "${{ secrets.SL_AGENT_TOKEN }}" \
            "${{ env.SEALIGHTS_TEST_STAGE }}"
```

{% endcode %}

Python script

{% code overflow="wrap" lineNumbers="true" fullWidth="true" %}

```python
def cleanup_open_executions(build_session_id, sealights_agent_token, test_stage=None):
    url = f"{SEALIGHTS_BASE_URL}/v1/executions"
    headers = {
        "Authorization": f"Bearer {sealights_agent_token}",
        "Content-Type": "application/json",
    }
    params = {"bsid": build_session_id, "status": "created"}
    if test_stage:
        params["testStage"] = test_stage
    print(f"[Sealights] Cleanup executions left open for build session {build_session_id} and test stage '{test_stage}'")

    try:
        response = requests.get(url, headers=headers, params=params, timeout=30)
        response.raise_for_status()
    except Exception as e:
        print(f"Failed to query executions: {e}")
        return 0

    data = response.json()
    execution_ids = [
        item["executionId"]
        for item in data.get("data", {}).get("list", [])
    ]
    print(f"Found {len(execution_ids)} open execution(s)")

    closed = 0
    for execution_id in execution_ids:
        delete_url = f"{SEALIGHTS_BASE_URL}/v1/test-sessions/{execution_id}"
        try:
            resp = requests.delete(delete_url, headers=headers, timeout=30)
            print(f"Closing test session {execution_id}: HTTP {resp.status_code}")
            closed += 1
        except Exception as e:
            print(f"Error closing session {execution_id}: {e}")

    return closed
```

{% endcode %}
{% endtab %}

{% tab title="Jenkins/Bash" %}
{% code overflow="wrap" lineNumbers="true" fullWidth="true" %}

```groovy
    post {
        aborted{
            echo '[Sealights] Cleanup executions left open.'
            withCredentials([string(credentialsId: 'sl.agent.token', variable: 'SL_TOKEN')]) {
                sh '''
                    set +x
                    SL_SESSION_IDs=(`curl -sX GET "https://$DOMAIN/sl-api/v1/executions?bsid=$BSID&status=created" \
                                              -H "Authorization: Bearer $SL_TOKEN" -H "Content-Type: application/json" \
                    						  | jq -r '.data.list | map(.executionId) | join(" ")'`)
                    #Optional: filter based on the Test Stage name and/or labId (especially relevant in case of parallel testing)
                    
                    echo "Found ${#SL_SESSION_IDs[@]} executions"
                    
                    for id in ${SL_SESSION_IDs[@]}
                    do 
                    	echo -n "Closing Test Session ID $id: "
                    	curl -isX DELETE "https://$DOMAIN/sl-api/v1/test-sessions/$id" \
                    	  -H "Authorization: Bearer $SL_TOKEN" -H "Content-Type: application/json" | grep HTTP
                    done
                '''
            }
        }
    }
```

{% endcode %}
{% endtab %}

{% tab title="ADO/Powershell" %}
{% code fullWidth="true" %}

```yaml
steps:
- task: Bash@3
  name: RunTests
  displayName: "Run my tests"
  inputs:
    targetType: inline
    script: |
      ./run-tests.sh
# ========================================================================
# 2. Sealights cleanup ONLY if RunTests failed or cancelled
# ========================================================================
- task: PowerShell@2
  displayName: "Sealights cleanup for this specific task (PowerShell)"
  condition: or(failed('RunTests'), canceled('RunTests'))
  env:
    SL_TOKEN: $(sl.agent.token)
    DOMAIN: $(DOMAIN)
    BSID: $(BSID)
  inputs:
    targetType: inline
    script: |
      Write-Host "[Sealights] Cleanup executions left open."

      # Build API URL
      $url = "https://$env:DOMAIN/sl-api/v1/executions?bsid=$env:BSID&status=created"

      # Prepare headers
      $headers = @{
        "Authorization" = "Bearer $env:SL_TOKEN"
        "Content-Type"  = "application/json"
      }

      # Get execution IDs
      try {
        $response = Invoke-RestMethod -Method GET -Uri $url -Headers $headers -ErrorAction Stop
        $sessionIds = $response.data.list | ForEach-Object { $_.executionId }
      }
      catch {
        Write-Host "Failed to fetch execution list: $($_.Exception.Message)"
        exit 0   # do not fail pipeline
      }

      if (!$sessionIds) {
        Write-Host "No executions found."
        exit 0
      }

      Write-Host "Found $($sessionIds.Count) executions"

      # Close each Sealights test session
      foreach ($id in $sessionIds) {
        Write-Host ("Closing Test Session ID {0}: " -f $id) -NoNewline

        $deleteUrl = "https://$env:DOMAIN/sl-api/v1/test-sessions/$id"

        try {
          $deleteResponse = Invoke-RestMethod -Method DELETE -Uri $deleteUrl -Headers $headers -ErrorAction Stop
          Write-Host "OK"
        }
        catch {
          # Still print HTTP response if possible
          Write-Host "Failed: $($_.Exception.Message)"
        }
      }
```

{% endcode %}
{% endtab %}
{% endtabs %}
