Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for Fed EVal #1296

Merged
merged 24 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 181 additions & 0 deletions .github/workflows/task_runner_fedeval_dws_e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
---
# Task Runner E2E Evaluation tests for dockerized approach

name: Task_Runner_FedEval_DWS_E2E # Please do not modify the name as it is used in the composite action

on:
workflow_dispatch:
inputs:
num_rounds:
description: "Number of rounds to train"
required: false
default: "5"
type: string
num_collaborators:
description: "Number of collaborators"
required: false
default: "2"
type: string
job_to_run:
description: "Job to run (tls, non_tls, no_client_auth, all)"
required: true
default: "all"
type: choice
options:
- tls
- non_tls
- no_client_auth
- all

permissions:
contents: read

# Environment variables common for all the jobs
env:
NUM_ROUNDS: ${{ inputs.num_rounds || '5' }}
NUM_COLLABORATORS: ${{ inputs.num_collaborators || '2' }}
JOB_TO_RUN: ${{ inputs.job_to_run || 'all' }}

jobs:
input_selection:
if: |
(github.event_name == 'schedule' && github.repository_owner == 'securefederatedai') ||
(github.event_name == 'workflow_dispatch')
name: Input value selection
runs-on: ubuntu-22.04
outputs:
selected_jobs: ${{ env.JOB_TO_RUN }}
steps:
- name: Job to select input values
id: input_selection
run: |
echo "jobs_to_run=${{ env.JOBS_TO_RUN }}"

test_with_tls_dockerized_ws:
name: tr_tls_dockerized_ws
needs: input_selection
runs-on: ubuntu-22.04
timeout-minutes: 15
if: needs.input_selection.outputs.selected_jobs == 'tls' || needs.input_selection.outputs.selected_jobs == 'all'
strategy:
matrix:
model_name: ["keras_cnn_mnist"]
python_version: ["3.10"]
fail-fast: false # do not immediately fail if one of the combinations fail

env:
MODEL_NAME: ${{ matrix.model_name }}
PYTHON_VERSION: ${{ matrix.python_version }}

steps:
- name: Checkout OpenFL repository
id: checkout_openfl
uses: actions/[email protected]
with:
fetch-depth: 2 # needed for detecting changes
submodules: "true"
token: ${{ secrets.GITHUB_TOKEN }}

- name: Pre test run
uses: ./.github/actions/tr_pre_test_run
if: ${{ always() }}

- name: Run Task Runner E2E tests with TLS
id: run_tests
run: |
python -m pytest -s tests/end_to_end/test_suites/tr_with_fedeval_tests.py \
-m task_runner_dockerized_ws --model_name ${{ env.MODEL_NAME }} \
--num_rounds ${{ env.NUM_ROUNDS }} --num_collaborators ${{ env.NUM_COLLABORATORS }}
echo "Task runner end to end test run completed"

- name: Post test run
uses: ./.github/actions/tr_post_test_run
if: ${{ always() }}
with:
test_type: "tr_tls_dockerized_ws"

test_with_non_tls_dockerized_ws:
name: tr_non_tls_dockerized_ws
needs: input_selection
runs-on: ubuntu-22.04
timeout-minutes: 15
if: needs.input_selection.outputs.selected_jobs == 'non_tls' || needs.input_selection.outputs.selected_jobs == 'all'
strategy:
matrix:
model_name: ["keras_cnn_mnist"]
python_version: ["3.10"]
fail-fast: false # do not immediately fail if one of the combinations fail

env:
MODEL_NAME: ${{ matrix.model_name }}
PYTHON_VERSION: ${{ matrix.python_version }}

steps:
- name: Checkout OpenFL repository
id: checkout_openfl
uses: actions/[email protected]
with:
fetch-depth: 2 # needed for detecting changes
submodules: "true"
token: ${{ secrets.GITHUB_TOKEN }}

- name: Pre test run
uses: ./.github/actions/tr_pre_test_run
if: ${{ always() }}

- name: Run Task Runner E2E tests without TLS
id: run_tests
run: |
python -m pytest -s tests/end_to_end/test_suites/tr_with_fedeval_tests.py \
-m task_runner_dockerized_ws --model_name ${{ env.MODEL_NAME }} \
--num_rounds ${{ env.NUM_ROUNDS }} --num_collaborators ${{ env.NUM_COLLABORATORS }} --disable_tls
echo "Task runner end to end test run completed"

- name: Post test run
uses: ./.github/actions/tr_post_test_run
if: ${{ always() }}
with:
test_type: "tr_non_tls_dockerized_ws"

test_with_no_client_auth_dockerized_ws:
name: tr_no_client_auth_dockerized_ws
needs: input_selection
runs-on: ubuntu-22.04
timeout-minutes: 15
if: needs.input_selection.outputs.selected_jobs == 'no_client_auth' || needs.input_selection.outputs.selected_jobs == 'all'
strategy:
matrix:
model_name: ["keras_cnn_mnist"]
python_version: ["3.10"]
fail-fast: false # do not immediately fail if one of the combinations fail

env:
MODEL_NAME: ${{ matrix.model_name }}
PYTHON_VERSION: ${{ matrix.python_version }}

steps:
- name: Checkout OpenFL repository
id: checkout_openfl
uses: actions/[email protected]
with:
fetch-depth: 2 # needed for detecting changes
submodules: "true"
token: ${{ secrets.GITHUB_TOKEN }}

- name: Pre test run
uses: ./.github/actions/tr_pre_test_run
if: ${{ always() }}

- name: Run Task Runner E2E tests without TLS
id: run_tests
run: |
python -m pytest -s tests/end_to_end/test_suites/tr_with_fedeval_tests.py \
-m task_runner_dockerized_ws --model_name ${{ env.MODEL_NAME }} \
--num_rounds ${{ env.NUM_ROUNDS }} --num_collaborators ${{ env.NUM_COLLABORATORS }} --disable_client_auth
echo "Task runner end to end test run completed"

- name: Post test run
uses: ./.github/actions/tr_post_test_run
if: ${{ always() }}
with:
test_type: "tr_no_client_auth_dockerized_ws"
158 changes: 158 additions & 0 deletions .github/workflows/task_runner_fedeval_e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
---
# Task Runner E2E tests with evaluation with bare metal approach

name: Task_Runner_FedEval_E2E # Please do not modify the name as it is used in the composite action

on:
schedule:
- cron: "0 0 * * *" # Run every day at midnight
workflow_dispatch:
inputs:
num_rounds:
description: "Number of rounds to train"
required: false
default: "5"
type: string
num_collaborators:
description: "Number of collaborators"
required: false
default: "2"
type: string

permissions:
contents: read

# Environment variables common for all the jobs
env:
NUM_ROUNDS: ${{ inputs.num_rounds || '5' }}
NUM_COLLABORATORS: ${{ inputs.num_collaborators || '2' }}

jobs:
test_with_tls:
name: tr_tls
runs-on: ubuntu-22.04
timeout-minutes: 30
strategy:
matrix:
# Models like XGBoost (xgb_higgs) and torch_cnn_histology require runners with higher memory and CPU to run.
# Thus these models are excluded from the matrix for now.
model_name: ["torch_cnn_mnist", "keras_cnn_mnist"]
python_version: ["3.10"]
fail-fast: false # do not immediately fail if one of the combinations fail

env:
MODEL_NAME: ${{ matrix.model_name }}
PYTHON_VERSION: ${{ matrix.python_version }}

steps:
- name: Checkout OpenFL repository
id: checkout_openfl
uses: actions/[email protected]
with:
fetch-depth: 2 # needed for detecting changes
submodules: "true"
token: ${{ secrets.GITHUB_TOKEN }}

- name: Pre test run
uses: ./.github/actions/tr_pre_test_run
if: ${{ always() }}

- name: Run Task Runner E2E tests with TLS
id: run_tests
run: |
python -m pytest -s tests/end_to_end/test_suites/tr_with_fedeval_tests.py \
-m task_runner_basic --model_name ${{ env.MODEL_NAME }} \
--num_rounds ${{ env.NUM_ROUNDS }} --num_collaborators ${{ env.NUM_COLLABORATORS }}
echo "Task runner end to end test run completed"

- name: Post test run
uses: ./.github/actions/tr_post_test_run
if: ${{ always() }}
with:
test_type: "tr_tls"

test_with_non_tls:
name: tr_non_tls
runs-on: ubuntu-22.04
timeout-minutes: 30
strategy:
matrix:
# Testing this scenario only for torch_cnn_mnist model and python 3.10
# If required, this can be extended to other models and python versions
model_name: ["torch_cnn_mnist"]
python_version: ["3.10"]
fail-fast: false # do not immediately fail if one of the combinations fail

env:
MODEL_NAME: ${{ matrix.model_name }}
PYTHON_VERSION: ${{ matrix.python_version }}

steps:
- name: Checkout OpenFL repository
id: checkout_openfl
uses: actions/[email protected]
with:
fetch-depth: 2 # needed for detecting changes
submodules: "true"
token: ${{ secrets.GITHUB_TOKEN }}

- name: Pre test run
uses: ./.github/actions/tr_pre_test_run
if: ${{ always() }}

- name: Run Task Runner E2E tests without TLS
id: run_tests
run: |
python -m pytest -s tests/end_to_end/test_suites/tr_with_fedeval_tests.py \
-m task_runner_basic --model_name ${{ env.MODEL_NAME }} \
--num_rounds ${{ env.NUM_ROUNDS }} --num_collaborators ${{ env.NUM_COLLABORATORS }} --disable_tls
echo "Task runner end to end test run completed"

- name: Post test run
uses: ./.github/actions/tr_post_test_run
if: ${{ always() }}
with:
test_type: "tr_non_tls"

test_with_no_client_auth:
name: tr_no_client_auth
runs-on: ubuntu-22.04
timeout-minutes: 30
strategy:
matrix:
# Testing this scenario for keras_cnn_mnist model and python 3.10
# If required, this can be extended to other models and python versions
model_name: ["keras_cnn_mnist"]
python_version: ["3.10"]
fail-fast: false # do not immediately fail if one of the combinations fail

env:
MODEL_NAME: ${{ matrix.model_name }}
PYTHON_VERSION: ${{ matrix.python_version }}

steps:
- name: Checkout OpenFL repository
id: checkout_openfl
uses: actions/[email protected]
with:
fetch-depth: 2 # needed for detecting changes
submodules: "true"
token: ${{ secrets.GITHUB_TOKEN }}

- name: Pre test run
uses: ./.github/actions/tr_pre_test_run
if: ${{ always() }}

- name: Run Task Runner E2E tests without TLS
id: run_tests
run: |
python -m pytest -s tests/end_to_end/test_suites/tr_with_fedeval_tests.py \
-m task_runner_basic --model_name ${{ env.MODEL_NAME }} \
--num_rounds ${{ env.NUM_ROUNDS }} --num_collaborators ${{ env.NUM_COLLABORATORS }} --disable_client_auth
echo "Task runner end to end test run completed"

- name: Post test run
uses: ./.github/actions/tr_post_test_run
if: ${{ always() }}
with:
test_type: "tr_no_client_auth"
9 changes: 7 additions & 2 deletions tests/end_to_end/models/aggregator.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,20 @@ class Aggregator():
2. Starting the aggregator
"""

def __init__(self, agg_domain_name=None, workspace_path=None, container_id=None):
def __init__(self, agg_domain_name=None, workspace_path=None, container_id=None, eval_scope=False):
"""
Initialize the Aggregator class
Args:
payalcha marked this conversation as resolved.
Show resolved Hide resolved
agg_domain_name (str): Aggregator domain name
workspace_path (str): Workspace path
container_id (str): Container ID
eval_scope (bool, optional): Scope of aggregator is evaluation. Default is False.
"""
self.name = "aggregator"
self.agg_domain_name = agg_domain_name
self.workspace_path = workspace_path
self.container_id = container_id
self.eval_scope = eval_scope

def generate_sign_request(self):
"""
Expand Down Expand Up @@ -63,8 +65,11 @@ def start(self, res_file, with_docker=False):
log.info(f"Starting {self.name}")
res_file = res_file if not with_docker else os.path.basename(res_file)
error_msg = "Failed to start the aggregator"
command = "fx aggregator start"
if self.eval_scope:
command = f"{command} --task_group evaluation"
fh.run_command(
"fx aggregator start",
command=command,
error_msg=error_msg,
container_id=self.container_id,
workspace_path=self.workspace_path if not with_docker else "",
Expand Down
Loading
Loading