Skip to content

Commit e083889

Browse files
[AC-240] SPIKE: Initial approach for implementing e2e tests. (#46)
1 parent eaef9db commit e083889

File tree

11 files changed

+642
-0
lines changed

11 files changed

+642
-0
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# Ed-Fi Admin Console Instance Management Worker Process Diagram
2+
3+
This document contains a Mermaid diagram visualizing the architecture and workflow of the Instance Management Worker Process.
4+
5+
## Instance Management Worker Process Diagram
6+
7+
```mermaid
8+
flowchart TD
9+
B(CreateInstance)
10+
C(DeleteInstance)
11+
B --> D(GetInstances)
12+
B --> E(CheckDatabaseExists && !OverrideExistingDatabase)
13+
B --> F(AddDBInstance)
14+
F --> G(CompleteInstance)
15+
C --> H(GetTenants)
16+
C --> I(GetInstances)
17+
C --> J(DeleteDBInstance)
18+
J --> K(SetDeleteFailedStatus)
19+
20+
subgraph "External Dependencies (Mocked by Docker)"
21+
DB[(Database)]
22+
AdminAPI[AdminAPI]
23+
end
24+
25+
D --> AdminAPI
26+
E --> |skip creation if database exists and override is disabled / create database even if it exists when override is enabled|DB
27+
F --> |process instance successfully| DB
28+
G --> |Complete the instance successfully| AdminAPI
29+
H --> AdminAPI
30+
I --> AdminAPI
31+
J --> |Delete Instance successfully| DB
32+
K --> |Fail delete process / set as failed delete| AdminAPI
33+
```
34+
35+
## End-to-End Testing Approach
36+
37+
The Instance Management Worker Process is tested using an end-to-end (E2E) testing approach that validates the complete workflow from API interactions through database operations.
38+
39+
### E2E Test Framework
40+
41+
The E2E tests are implemented using PowerShell scripts with Pester, a testing framework for PowerShell. The tests are located in the `/tests/E2E/` directory.
42+
43+
### Testing Process
44+
45+
1. **Environment Setup**:
46+
- Tests use environment variables defined in a `.env.example` (changing its name to `.env`) file
47+
- The `Read-EnvVariables` function loads these settings for test execution
48+
49+
2. **Test Execution Flow**:
50+
1. **Client Registration**: Register a new client with the Admin API
51+
2. **Authentication**: Obtain an access token for API operations
52+
3. **Instance Creation**: Create a new ODS instance with "Pending" status
53+
4. **Worker Process Execution**: Invoke the Instance Management Worker Process via Docker
54+
5. **Status Verification**: Check if the instance status has changed to "completed"
55+
6. **Assertions**: Use Pester to verify expected outcomes
56+
57+
### Docker Integration
58+
59+
Tests use Docker to run the Instance Management Worker Process:
60+
- The worker process is containerized using a Dockerfile in the `/docker` directory
61+
- The Docker image must be built before running the tests:
62+
```powershell
63+
docker build -t edfi.adminconsole.instancemanagementworker -f docker/Dockerfile .
64+
```
65+
- The test script invokes the container with appropriate parameters:
66+
```powershell
67+
docker run --rm edfi.adminconsole.instancemanagementworker dotnet EdFi.AdminConsole.InstanceManagementWorker.dll --isMultiTenant=true --tenant="$env:DEFAULTTENANT" --ClientId="$env:clientId" --ClientSecret="$env:clientSecret"
68+
```
69+
70+
### Test Validation
71+
72+
The tests validate that:
73+
1. The worker process correctly connects to the Admin API
74+
2. Instances with "Pending" status are processed
75+
3. Database operations are performed correctly
76+
4. Instance status is updated to "completed" when successful
77+
78+
### Running the Tests
79+
80+
To run the E2E tests:
81+
1. Ensure Docker is running
82+
2. Build the worker process Docker image
83+
3. Configure the `.env` file with appropriate values
84+
4. Execute the test script:
85+
```powershell
86+
cd tests/E2E
87+
./e2eTest.ps1
88+
```
89+
90+
### Test Dependencies
91+
92+
The E2E tests require:
93+
- PowerShell 7 with Pester module
94+
- Docker
95+
- Access to Admin API services
96+
- Valid client credentials
97+
98+
## Current State and Next Steps
99+
100+
### Current State
101+
102+
The environment is set up using Docker to run Admin API along with their databases. The Admin API was updated to use the latest endpoints, and corresponding payloads were adjusted to match the new schema.
103+
104+
This setup enables running the Instance Management Worker. However, the E2E test currently fails because the Instance Management service attempts to authenticate using a Keycloak-generated token. Since the Admin API now uses self-contained authorization (Keycloak has been removed), this causes a token mismatch and results in authentication failure.
105+
106+
### Next Steps
107+
108+
- **Update Instance Management Worker** to support Admin API’s new self-contained authorization
109+
- **Remove dependency on Keycloak** for Instance Management authentication
110+
- **Create a new ticket** to track the work required for the auth update

tests/E2E/.env.example

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
MULTITENANCY=true
2+
DEFAULTTENANT=tenant1
3+
POSTGRES_PASSWORD=P@ssw0rd
4+
5+
ADMIN_API = http://localhost:8003
6+
CLIENT_SECRET = abcdeFGHIJkmnopQRSTuvWxyz1234567890*abcdeFGHIJkmnopQRSTuvWxyz1234567890*

tests/E2E/README.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# E2E Tests for Instance Management Worker Process
2+
3+
This folder contains scripts to test the Instance Management Worker Process in an end-to-end scenario using Docker containers.
4+
5+
## How it Works
6+
7+
The E2E tests verify that the Instance Management Worker Process correctly:
8+
1. Processes instance creation requests, creating new ODS databases
9+
2. Updates instance statuses from "Pending" to "Complete"
10+
3. Processes instance deletion requests
11+
4. Updates instance statuses from "Pending_Delete" to "Deleted" or removes them
12+
13+
## Prerequisites
14+
15+
- Docker and Docker Compose
16+
- PowerShell 7.0 or later
17+
18+
## Steps to Run
19+
20+
1. Create your `.env` file using the `.env.example` as a reference:
21+
```
22+
ADMIN_API_URL=http://localhost:8003
23+
ADMIN_USERNAME=test@ed-fi.org
24+
ADMIN_PASSWORD=Password123!
25+
CONNECTION_STRING=Host=localhost;Port=5401;Username=postgres;Password=postgres;Database=EdFi_Admin;
26+
```
27+
28+
2. Execute the `e2eTest.ps1` script, which will:
29+
- Start the Docker environment (using the `../docker/start.ps1` script)
30+
- Wait for Admin API to be ready
31+
- Create a test instance with "Pending" status
32+
- Run the worker process to create the instance
33+
- Verify the instance was created successfully
34+
- Test instance deletion (unless `-SkipDeleteTest` is specified)
35+
- Stop and clean up the Docker environment (unless `-SkipTearDown` is specified)
36+
37+
## Command-Line Options
38+
39+
You can run the script with the following options:
40+
41+
- `-SkipTearDown`: Skip tearing down the Docker environment after the test (useful for debugging)
42+
- `-SkipDeleteTest`: Skip testing the instance deletion functionality
43+
44+
```powershell
45+
./e2eTest.ps1
46+
./e2eTest.ps1 -SkipTearDown
47+
./e2eTest.ps1 -SkipDeleteTest
48+
./e2eTest.ps1 -SkipTearDown -SkipDeleteTest
49+
```
50+
51+
## Files in this Directory
52+
53+
- `e2eTest.ps1` - The main test script
54+
- `e2eTest-helpers.psm1` - PowerShell module with helper functions
55+
- `.env.example` - Example environment variables file
56+
- `README.md` - This documentation file
57+
58+
## Troubleshooting
59+
60+
If the tests fail:
61+
62+
1. Check if the Docker containers are running:
63+
```powershell
64+
docker ps
65+
```
66+
67+
2. Check the Admin API logs:
68+
```powershell
69+
docker logs ed-fi-adminapi
70+
```
71+
72+
3. Verify the environment variables in `.env` are correct
73+
74+
4. Try running with `-SkipTearDown` to keep the environment running for manual inspection

tests/E2E/appsettings.e2etest.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"AppSettings": {
3+
"DatabaseEngine": "PostgreSQL",
4+
"OverrideExistingDatabase": false,
5+
"RunDeleteInstance": false,
6+
"RunCreateInstance": true
7+
},
8+
"AdminApiSettings": {
9+
"Url": "http://localhost:8003",
10+
"Key": "testKey",
11+
"Secret": "testSecret",
12+
"Username": "test@ed-fi.org",
13+
"Password": "Password123!"
14+
},
15+
"ConnectionStrings": {
16+
"MsSqlServerConnectionString": "Server=localhost,1433;Database=EdFi_Admin;User Id=sa;Password=Your_Password1234;TrustServerCertificate=True;",
17+
"PostgresConnectionString": "Host=localhost;Port=5401;Username=postgres;Password=postgres;Database=EdFi_Admin;"
18+
},
19+
"Logging": {
20+
"LogLevel": {
21+
"Default": "Information",
22+
"Microsoft": "Warning",
23+
"Microsoft.Hosting.Lifetime": "Information"
24+
}
25+
}
26+
}

tests/E2E/e2eTest-helpers.psm1

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
# Licensed to the Ed-Fi Alliance under one or more agreements.
3+
# The Ed-Fi Alliance licenses this file to you under the Apache License, Version 2.0.
4+
# See the LICENSE and NOTICES files in the project root for more information.
5+
6+
<#
7+
.DESCRIPTION
8+
Reads values from the .env file.
9+
#>
10+
function Read-EnvVariables {
11+
$envFilePath = "$PSScriptRoot/.env"
12+
$envFileContent = Get-Content -Path $envFilePath
13+
14+
foreach ($line in $envFileContent) {
15+
if ($line -match "^\s*([^#][^=]+)=(.*)$") {
16+
$name = $matches[1].Trim()
17+
$value = $matches[2].Trim()
18+
[System.Environment]::SetEnvironmentVariable($name, $value)
19+
}
20+
}
21+
}
22+
23+
<#
24+
.DESCRIPTION
25+
Creates a new user on Admin API
26+
#>
27+
function Register-AdminApiClient {
28+
$headers = @{
29+
"Content-Type" = "application/x-www-form-urlencoded"
30+
"tenant" = $env:DEFAULTTENANT
31+
}
32+
33+
$body = @{
34+
"ClientId" = $env:clientId
35+
"ClientSecret" = $env:clientSecret
36+
"DisplayName" = $env:clientId
37+
}
38+
39+
try {
40+
$response = Invoke-RestMethod -SkipCertificateCheck -Uri "$env:ADMIN_API/connect/register" -Method Post -Headers $headers -Body $body -StatusCodeVariable statusCode
41+
42+
$output = [PSCustomObject]@{
43+
Body = $response
44+
StatusCode = $statusCode
45+
}
46+
47+
return $output
48+
}
49+
catch {
50+
Write-Error "Failed to send request to $RegisterUrl. Error: $_" -ErrorAction Stop
51+
}
52+
}
53+
54+
<#
55+
.DESCRIPTION
56+
Returns token from Admin API
57+
#>
58+
function Get-Token {
59+
$headers = @{
60+
"Content-Type" = "application/x-www-form-urlencoded"
61+
"tenant" = "$env:DEFAULTTENANT"
62+
}
63+
64+
$body = @{
65+
"client_id" = $env:clientId
66+
"client_secret" = $env:clientSecret
67+
"grant_type" = "client_credentials"
68+
"scope" = "edfi_admin_api/full_access"
69+
}
70+
71+
try {
72+
$response = Invoke-RestMethod -SkipCertificateCheck -Uri "$env:ADMIN_API/connect/token" -Method Post -Headers $headers -Body $body -StatusCodeVariable statusCode
73+
74+
$output = [PSCustomObject]@{
75+
Body = $response
76+
StatusCode = $statusCode
77+
}
78+
79+
return $output
80+
}
81+
catch {
82+
Write-Error "Failed to send request to $TokenUrl. Error: $_" -ErrorAction Stop
83+
}
84+
}
85+
86+
<#
87+
.DESCRIPTION
88+
Makes an authenticated request to Admin Api
89+
#>
90+
function Invoke-AdminApi {
91+
param (
92+
[Parameter(Mandatory = $true)]
93+
[string]
94+
$access_token,
95+
96+
[Parameter(Mandatory = $true)]
97+
[string]
98+
$endpoint,
99+
100+
[Parameter(Mandatory = $false)]
101+
[bool]
102+
$adminConsoleApi = $false,
103+
104+
[Parameter(Mandatory = $false)]
105+
[string]
106+
$method = "POST",
107+
108+
[Parameter(Mandatory = $false)]
109+
[string]
110+
$filePath
111+
)
112+
113+
$headers = @{
114+
"Authorization" = "Bearer $access_token"
115+
"Content-Type" = "application/json"
116+
"tenant" = $env:DEFAULTTENANT
117+
}
118+
119+
$uri = "$env:ADMIN_API/v2/$endpoint"
120+
121+
if ($adminConsoleApi -eq $true) {
122+
123+
124+
$uri = "$env:ADMIN_API/adminconsole/$endpoint"
125+
}
126+
127+
try {
128+
if ($method -eq "POST") {
129+
$response = Invoke-RestMethod -SkipCertificateCheck -Uri $uri -Method Post -Headers $headers -InFile $filePath -StatusCodeVariable statusCode -ResponseHeadersVariable responseHeaders
130+
}
131+
else{
132+
$response = Invoke-RestMethod -SkipCertificateCheck -Uri $uri -Method Get -Headers $headers -StatusCodeVariable statusCode
133+
}
134+
135+
return @{
136+
Body = $response
137+
StatusCode = $statusCode
138+
ResponseHeaders = $responseHeaders
139+
}
140+
}
141+
catch {
142+
Write-Error "Failed to send request to $env:ADMIN_API. Error: $_" -ErrorAction Stop
143+
}
144+
}
145+
146+
Export-ModuleMember -Function Read-EnvVariables, Register-AdminApiClient, Get-Token, Invoke-AdminApi

0 commit comments

Comments
 (0)