Skip to content

Commit 41f2cdc

Browse files
authored
Adding Secure Aggregation Test (#1419)
* Secure Aggregation Tests Signed-off-by: Chaurasiya, Payal <[email protected]> * Secure Aggregation Tests Signed-off-by: Chaurasiya, Payal <[email protected]> * Handle success and exception messages Signed-off-by: Chaurasiya, Payal <[email protected]> * Handle success and exception messages Signed-off-by: Chaurasiya, Payal <[email protected]> * Format issue Signed-off-by: Chaurasiya, Payal <[email protected]> * Put Secure Agg Signed-off-by: Chaurasiya, Payal <[email protected]> * Review comments Signed-off-by: Chaurasiya, Payal <[email protected]> --------- Signed-off-by: Chaurasiya, Payal <[email protected]>
1 parent d7c25e8 commit 41f2cdc

File tree

9 files changed

+83
-8
lines changed

9 files changed

+83
-8
lines changed

.github/workflows/pq_pipeline.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ jobs:
6565
needs: task_runner_e2e
6666
uses: ./.github/workflows/task_runner_fedeval_e2e.yml
6767

68+
task_runner_secure_agg_e2e:
69+
if: |
70+
(github.event_name == 'schedule' && github.repository_owner == 'securefederatedai') ||
71+
(github.event_name == 'workflow_dispatch')
72+
name: TaskRunner Secure Aggregation E2E
73+
uses: ./.github/workflows/task_runner_secure_agg_e2e.yml
74+
6875
task_runner_straggler_e2e:
6976
if: |
7077
(github.event_name == 'schedule' && github.repository_owner == 'securefederatedai') ||

.github/workflows/pr_pipeline.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,14 @@ jobs:
5959
name: TaskRunner E2E
6060
uses: ./.github/workflows/task_runner_basic_e2e.yml
6161

62-
task_runner_e2e_resiliency:
62+
task_runner_resiliency_e2e:
6363
name: TaskRunner Resiliency E2E
6464
uses: ./.github/workflows/task_runner_resiliency_e2e.yml
6565

66+
task_runner_secure_agg_e2e:
67+
name: TaskRunner Secure Aggregation E2E
68+
uses: ./.github/workflows/task_runner_secure_agg_e2e.yml
69+
6670
tr_docker_gramine_direct:
6771
name: TaskRunner (docker/gramine-direct)
6872
uses: ./.github/workflows/tr_docker_gramine_direct.yml
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
# Task Runner E2E tests with Secure aggregation with bare metal approach
3+
4+
name: Task_Runner_Secure_Agg_E2E # Please do not modify the name as it is used in the composite action
5+
6+
on:
7+
workflow_call:
8+
workflow_dispatch:
9+
10+
permissions:
11+
contents: read
12+
13+
jobs:
14+
test_secure_aggregation:
15+
name: Secure Aggregation (torch/mnist, 3.10)
16+
runs-on: ubuntu-22.04
17+
timeout-minutes: 30
18+
env:
19+
MODEL_NAME: 'torch/mnist'
20+
PYTHON_VERSION: '3.10'
21+
NUM_ROUNDS: 5
22+
NUM_COLLABORATORS: 2
23+
steps:
24+
- name: Checkout OpenFL repository
25+
id: checkout_openfl
26+
uses: actions/checkout@v4
27+
with:
28+
fetch-depth: 2 # needed for detecting changes
29+
submodules: "true"
30+
token: ${{ secrets.GITHUB_TOKEN }}
31+
32+
- name: Install Secure Aggregation dependies
33+
run: |
34+
python -m pip install pycryptodome
35+
36+
- name: Pre test run
37+
uses: ./.github/actions/tr_pre_test_run
38+
if: ${{ always() }}
39+
40+
- name: Run Task Runner with secure aggregation
41+
id: run_tests
42+
run: |
43+
python -m pytest -s tests/end_to_end/test_suites/task_runner_tests.py \
44+
-m task_runner_basic --model_name ${{ env.MODEL_NAME }} \
45+
--num_rounds ${{ env.NUM_ROUNDS }} --num_collaborators ${{ env.NUM_COLLABORATORS }} --secure_agg
46+
echo "Task runner end to end test run completed"
47+
48+
- name: Post test run
49+
uses: ./.github/actions/tr_post_test_run
50+
if: ${{ always() }}
51+
with:
52+
test_type: "With_Secure_Agg"

tests/end_to_end/conftest.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def pytest_addoption(parser):
2929
parser.addoption("--disable_client_auth", action="store_true")
3030
parser.addoption("--disable_tls", action="store_true")
3131
parser.addoption("--log_memory_usage", action="store_true")
32+
parser.addoption("--secure_agg", action="store_true")
3233

3334

3435
def pytest_configure(config):
@@ -46,6 +47,7 @@ def pytest_configure(config):
4647
config.require_client_auth = not args.disable_client_auth
4748
config.use_tls = not args.disable_tls
4849
config.log_memory_usage = args.log_memory_usage
50+
config.secure_agg = args.secure_agg
4951
config.results_dir = config.getini("results_dir")
5052

5153

tests/end_to_end/models/model_owner.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,8 @@ def modify_plan(self, param_config, plan_path):
159159
data["data_loader"]["settings"]["collaborator_count"] = int(self.num_collaborators)
160160
data["network"]["settings"]["require_client_auth"] = param_config.require_client_auth
161161
data["network"]["settings"]["use_tls"] = param_config.use_tls
162-
163-
162+
if param_config.secure_agg:
163+
data["aggregator"]["settings"]["secure_aggregation"] = True
164164
with open(plan_file, "w+") as write_file:
165165
yaml.dump(data, write_file)
166166
log.info(f"Modified the plan with provided parameters.")

tests/end_to_end/utils/conftest_helper.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def parse_arguments():
3333
parser.add_argument("--disable_client_auth", action="store_true", help="Disable client authentication. Default is False")
3434
parser.add_argument("--disable_tls", action="store_true", help="Disable TLS for communication. Default is False")
3535
parser.add_argument("--log_memory_usage", action="store_true", help="Enable Memory leak logs. Default is False")
36+
parser.add_argument("--secure_agg", action="store_true", help="Enable secure aggregation. Default is False")
3637
args = parser.parse_known_args()[0]
3738
return args
3839

tests/end_to_end/utils/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,4 @@ class ModelName(Enum):
5454

5555
COL_CERTIFY_CMD = "fx collaborator certify --import 'agg_to_col_{}_signed_cert.zip'"
5656
DFLT_DOCKERIZE_IMAGE_NAME = "workspace"
57+
EXCEPTION = "Exception"

tests/end_to_end/utils/federation_helper.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,11 @@ def _create_tarball(collaborator_name, data_file_path, local_bind_path, add_data
171171
return True
172172

173173

174-
def import_pki_for_collaborators(collaborators, local_bind_path):
174+
def import_pki_for_collaborators(collaborators):
175175
"""
176176
Import and certify the CSR for the collaborators
177177
"""
178178
executor = concurrent.futures.ThreadPoolExecutor()
179-
local_agg_ws_path = constants.AGG_WORKSPACE_PATH.format(local_bind_path)
180179
try:
181180
results = [
182181
executor.submit(
@@ -359,13 +358,21 @@ def _verify_completion_for_participant(
359358
):
360359
with open(participant.res_file, "r") as file:
361360
lines = [line.strip() for line in file.readlines()]
362-
content = list(filter(str.rstrip, lines))[-1:]
361+
# Below change is done to incorporate warnings coming in end of runs
362+
content = list(filter(str.rstrip, lines))[-7:] if len(lines) >= 7 else lines
363363

364364
# Print last line of the log file on screen to track the progress
365-
log.info(f"Last line in {participant.name} log: {content}")
365+
log.info(f"Last line in {participant.name} log: {lines[-1:]}")
366366
if constants.SUCCESS_MARKER in content:
367367
break
368368
log.info(f"Process is yet to complete for {participant.name}")
369+
# If in logs Exception is encountered, throw Exception and stop the process
370+
if constants.EXCEPTION in content:
371+
log.error(
372+
f"Process {participant.name} is throwing Exception. Check the logs for more details"
373+
)
374+
raise Exception(f"Process failed for {participant.name}")
375+
369376
time.sleep(45)
370377

371378
if constants.SUCCESS_MARKER not in content:
@@ -430,6 +437,7 @@ def federation_env_setup_and_validate(request, eval_scope=False):
430437
f"\tModel name: {request.config.model_name}\n"
431438
f"\tClient authentication: {request.config.require_client_auth}\n"
432439
f"\tTLS: {request.config.use_tls}\n"
440+
f"\tSecure Aggregation: {request.config.secure_agg}\n"
433441
f"\tMemory Logs: {request.config.log_memory_usage}\n"
434442
f"\tResults directory: {request.config.results_dir}\n"
435443
f"\tWorkspace path: {workspace_path}"

tests/end_to_end/utils/tr_workspace.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def create_tr_workspace(request, eval_scope=False):
145145

146146
if request.config.use_tls:
147147
fh.setup_pki_for_collaborators(collaborators, model_owner, local_bind_path)
148-
fh.import_pki_for_collaborators(collaborators, local_bind_path)
148+
fh.import_pki_for_collaborators(collaborators)
149149

150150
fh.remove_stale_processes(request.config.num_collaborators)
151151

0 commit comments

Comments
 (0)