Skip to content
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
285 changes: 273 additions & 12 deletions .github/workflows/unit-test-shards.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,275 @@
{
"lms-1": "lms/djangoapps/badges/ lms/djangoapps/branding/ lms/djangoapps/bulk_email/ lms/djangoapps/bulk_enroll/ lms/djangoapps/bulk_user_retirement/ lms/djangoapps/ccx/ lms/djangoapps/certificates/ lms/djangoapps/commerce/",
"lms-2": "lms/djangoapps/course_api/ lms/djangoapps/course_blocks/ lms/djangoapps/course_goals/ lms/djangoapps/course_home_api/ lms/djangoapps/course_wiki/ lms/djangoapps/coursewarehistoryextended/ lms/djangoapps/debug/",
"lms-3": "lms/djangoapps/courseware/",
"lms-4": "lms/djangoapps/discussion/ lms/djangoapps/edxnotes/ lms/djangoapps/email_marketing/ lms/djangoapps/experiments/",
"lms-5": "lms/djangoapps/gating/ lms/djangoapps/grades/ lms/djangoapps/instructor/ lms/djangoapps/instructor_analytics/",
"lms-6": "lms/djangoapps/instructor_task/ lms/djangoapps/learner_dashboard/ lms/djangoapps/lms_initialization/ lms/djangoapps/lms_xblock/ lms/djangoapps/lti_provider/ lms/djangoapps/mailing/ lms/djangoapps/mobile_api/ lms/djangoapps/monitoring/ lms/djangoapps/program_enrollments/ lms/djangoapps/rss_proxy/ lms/djangoapps/save_for_later/ lms/djangoapps/static_template_view/ lms/djangoapps/staticbook/ lms/djangoapps/support/ lms/djangoapps/survey/ lms/djangoapps/teams/ lms/djangoapps/tests/ lms/djangoapps/user_tours/ lms/djangoapps/verify_student/ lms/envs/ lms/lib/ lms/tests.py",
"openedx-1": "openedx/core/djangoapps/ace_common/ openedx/core/djangoapps/cors_csrf/ openedx/core/djangoapps/agreements/ openedx/core/djangoapps/api_admin/ openedx/core/djangoapps/auth_exchange/ openedx/core/djangoapps/bookmarks/ openedx/core/djangoapps/cache_toolbox/ openedx/core/djangoapps/catalog/ openedx/core/djangoapps/ccxcon/ openedx/core/djangoapps/commerce/ openedx/core/djangoapps/common_initialization/ openedx/core/djangoapps/common_views/ openedx/core/djangoapps/config_model_utils/ openedx/core/djangoapps/content/ openedx/core/djangoapps/content_libraries/ openedx/core/djangoapps/contentserver/ openedx/core/djangoapps/cookie_metadata/ openedx/core/djangoapps/course_apps/ openedx/core/djangoapps/course_date_signals/ openedx/core/djangoapps/course_groups/ openedx/core/djangoapps/coursegraph/ openedx/core/djangoapps/courseware_api/ openedx/core/djangoapps/crawlers/ openedx/core/djangoapps/credentials/ openedx/core/djangoapps/credit/ openedx/core/djangoapps/dark_lang/ openedx/core/djangoapps/debug/ openedx/core/djangoapps/demographics/ openedx/core/djangoapps/discussions/ openedx/core/djangoapps/django_comment_common/ openedx/core/djangoapps/embargo/ openedx/core/djangoapps/enrollments/ openedx/core/djangoapps/external_user_ids/",
"openedx-2": "openedx/core/djangoapps/geoinfo/ openedx/core/djangoapps/header_control/ openedx/core/djangoapps/heartbeat/ openedx/core/djangoapps/lang_pref/ openedx/core/djangoapps/models/ openedx/core/djangoapps/monkey_patch/ openedx/core/djangoapps/oauth_dispatch/ openedx/core/djangoapps/olx_rest_api/ openedx/core/djangoapps/password_policy/ openedx/core/djangoapps/plugin_api/ openedx/core/djangoapps/plugins/ openedx/core/djangoapps/profile_images/ openedx/core/djangoapps/programs/ openedx/core/djangoapps/safe_sessions/ openedx/core/djangoapps/schedules/ openedx/core/djangoapps/self_paced/ openedx/core/djangoapps/service_status/ openedx/core/djangoapps/session_inactivity_timeout/ openedx/core/djangoapps/signals/ openedx/core/djangoapps/site_configuration/ openedx/core/djangoapps/system_wide_roles/ openedx/core/djangoapps/theming/ openedx/core/djangoapps/user_api/ openedx/core/djangoapps/user_authn/ openedx/core/djangoapps/util/ openedx/core/djangoapps/verified_track_content/ openedx/core/djangoapps/video_config/ openedx/core/djangoapps/video_pipeline/ openedx/core/djangoapps/waffle_utils/ openedx/core/djangoapps/xblock/ openedx/core/djangoapps/xmodule_django/ openedx/core/djangoapps/zendesk_proxy/ openedx/core/djangolib/ openedx/core/lib/ openedx/core/tests/ openedx/core/tests/ openedx/features/ openedx/testing/ openedx/tests/",
"cms-1": "cms/djangoapps/api/ cms/djangoapps/cms_user_tasks/ cms/djangoapps/course_creators/ cms/djangoapps/export_course_metadata/ cms/djangoapps/maintenance/ cms/djangoapps/models/ cms/djangoapps/pipeline_js/ cms/djangoapps/xblock_config/ cms/envs/ cms/lib/",
"cms-2": "cms/djangoapps/contentstore/",
"common-1": "common/djangoapps/",
"common-2": "common/lib/"
"lms-1": {
"settings": "lms.envs.test",
"paths": [
"lms/djangoapps/badges/",
"lms/djangoapps/branding/",
"lms/djangoapps/bulk_email/",
"lms/djangoapps/bulk_enroll/",
"lms/djangoapps/bulk_user_retirement/",
"lms/djangoapps/ccx/",
"lms/djangoapps/certificates/",
"lms/djangoapps/commerce/"
]
},
"lms-2": {
"settings": "lms.envs.test",
"paths": [
"lms/djangoapps/course_api/",
"lms/djangoapps/course_blocks/",
"lms/djangoapps/course_goals/",
"lms/djangoapps/course_home_api/",
"lms/djangoapps/course_wiki/",
"lms/djangoapps/coursewarehistoryextended/",
"lms/djangoapps/debug/"
]
},
"lms-3": {
"settings": "lms.envs.test",
"paths": [
"lms/djangoapps/courseware/"
]
},
"lms-4": {
"settings": "lms.envs.test",
"paths": [
"lms/djangoapps/discussion/",
"lms/djangoapps/edxnotes/",
"lms/djangoapps/email_marketing/",
"lms/djangoapps/experiments/"
]
},
"lms-5": {
"settings": "lms.envs.test",
"paths": [
"lms/djangoapps/gating/",
"lms/djangoapps/grades/",
"lms/djangoapps/instructor/",
"lms/djangoapps/instructor_analytics/"
]
},
"lms-6": {
"settings": "lms.envs.test",
"paths": [
"lms/djangoapps/instructor_task/",
"lms/djangoapps/learner_dashboard/",
"lms/djangoapps/lms_initialization/",
"lms/djangoapps/lms_xblock/",
"lms/djangoapps/lti_provider/",
"lms/djangoapps/mailing/",
"lms/djangoapps/mobile_api/",
"lms/djangoapps/monitoring/",
"lms/djangoapps/program_enrollments/",
"lms/djangoapps/rss_proxy/",
"lms/djangoapps/save_for_later/",
"lms/djangoapps/static_template_view/",
"lms/djangoapps/staticbook/",
"lms/djangoapps/support/",
"lms/djangoapps/survey/",
"lms/djangoapps/teams/",
"lms/djangoapps/tests/",
"lms/djangoapps/user_tours/",
"lms/djangoapps/verify_student/",
"lms/envs/",
"lms/lib/",
"lms/tests.py"
]
},
"openedx-1": {
"settings": "lms.envs.test",
"paths": [
"openedx/core/djangoapps/ace_common/",
"openedx/core/djangoapps/cors_csrf/",
"openedx/core/djangoapps/agreements/",
"openedx/core/djangoapps/api_admin/",
"openedx/core/djangoapps/auth_exchange/",
"openedx/core/djangoapps/bookmarks/",
"openedx/core/djangoapps/cache_toolbox/",
"openedx/core/djangoapps/catalog/",
"openedx/core/djangoapps/ccxcon/",
"openedx/core/djangoapps/commerce/",
"openedx/core/djangoapps/common_initialization/",
"openedx/core/djangoapps/common_views/",
"openedx/core/djangoapps/config_model_utils/",
"openedx/core/djangoapps/content/",
"openedx/core/djangoapps/content_libraries/",
"openedx/core/djangoapps/contentserver/",
"openedx/core/djangoapps/cookie_metadata/",
"openedx/core/djangoapps/course_apps/",
"openedx/core/djangoapps/course_date_signals/",
"openedx/core/djangoapps/course_groups/",
"openedx/core/djangoapps/coursegraph/",
"openedx/core/djangoapps/courseware_api/",
"openedx/core/djangoapps/crawlers/",
"openedx/core/djangoapps/credentials/",
"openedx/core/djangoapps/credit/",
"openedx/core/djangoapps/dark_lang/",
"openedx/core/djangoapps/debug/",
"openedx/core/djangoapps/demographics/",
"openedx/core/djangoapps/discussions/",
"openedx/core/djangoapps/django_comment_common/",
"openedx/core/djangoapps/embargo/",
"openedx/core/djangoapps/enrollments/",
"openedx/core/djangoapps/external_user_ids/"
]
},
"openedx-2": {
"settings": "lms.envs.test",
"paths": [
"openedx/core/djangoapps/geoinfo/",
"openedx/core/djangoapps/header_control/",
"openedx/core/djangoapps/heartbeat/",
"openedx/core/djangoapps/lang_pref/",
"openedx/core/djangoapps/models/",
"openedx/core/djangoapps/monkey_patch/",
"openedx/core/djangoapps/oauth_dispatch/",
"openedx/core/djangoapps/olx_rest_api/",
"openedx/core/djangoapps/password_policy/",
"openedx/core/djangoapps/plugin_api/",
"openedx/core/djangoapps/plugins/",
"openedx/core/djangoapps/profile_images/",
"openedx/core/djangoapps/programs/",
"openedx/core/djangoapps/safe_sessions/",
"openedx/core/djangoapps/schedules/",
"openedx/core/djangoapps/self_paced/",
"openedx/core/djangoapps/service_status/",
"openedx/core/djangoapps/session_inactivity_timeout/",
"openedx/core/djangoapps/signals/",
"openedx/core/djangoapps/site_configuration/",
"openedx/core/djangoapps/system_wide_roles/",
"openedx/core/djangoapps/theming/",
"openedx/core/djangoapps/user_api/",
"openedx/core/djangoapps/user_authn/",
"openedx/core/djangoapps/util/",
"openedx/core/djangoapps/verified_track_content/",
"openedx/core/djangoapps/video_config/",
"openedx/core/djangoapps/video_pipeline/",
"openedx/core/djangoapps/waffle_utils/",
"openedx/core/djangoapps/xblock/",
"openedx/core/djangoapps/xmodule_django/",
"openedx/core/djangoapps/zendesk_proxy/",
"openedx/core/djangolib/",
"openedx/core/lib/",
"openedx/core/tests/",
"openedx/features/",
"openedx/testing/",
"openedx/tests/"
]
},
"openedx-3": {
"settings": "cms.envs.test",
"paths": [
"openedx/core/djangoapps/ace_common/",
"openedx/core/djangoapps/cors_csrf/",
"openedx/core/djangoapps/agreements/",
"openedx/core/djangoapps/api_admin/",
"openedx/core/djangoapps/auth_exchange/",
"openedx/core/djangoapps/bookmarks/",
"openedx/core/djangoapps/cache_toolbox/",
"openedx/core/djangoapps/catalog/",
"openedx/core/djangoapps/ccxcon/",
"openedx/core/djangoapps/commerce/",
"openedx/core/djangoapps/common_initialization/",
"openedx/core/djangoapps/common_views/",
"openedx/core/djangoapps/config_model_utils/",
"openedx/core/djangoapps/content/",
"openedx/core/djangoapps/content_libraries/",
"openedx/core/djangoapps/contentserver/",
"openedx/core/djangoapps/cookie_metadata/",
"openedx/core/djangoapps/course_apps/",
"openedx/core/djangoapps/course_date_signals/",
"openedx/core/djangoapps/course_groups/",
"openedx/core/djangoapps/coursegraph/",
"openedx/core/djangoapps/courseware_api/",
"openedx/core/djangoapps/crawlers/",
"openedx/core/djangoapps/credentials/",
"openedx/core/djangoapps/credit/",
"openedx/core/djangoapps/dark_lang/",
"openedx/core/djangoapps/debug/",
"openedx/core/djangoapps/demographics/",
"openedx/core/djangoapps/discussions/",
"openedx/core/djangoapps/django_comment_common/",
"openedx/core/djangoapps/embargo/",
"openedx/core/djangoapps/enrollments/",
"openedx/core/djangoapps/external_user_ids/"
]
},
"openedx-4": {
"settings": "cms.envs.test",
"paths": [
"openedx/core/djangoapps/geoinfo/",
"openedx/core/djangoapps/header_control/",
"openedx/core/djangoapps/heartbeat/",
"openedx/core/djangoapps/lang_pref/",
"openedx/core/djangoapps/models/",
"openedx/core/djangoapps/monkey_patch/",
"openedx/core/djangoapps/oauth_dispatch/",
"openedx/core/djangoapps/olx_rest_api/",
"openedx/core/djangoapps/password_policy/",
"openedx/core/djangoapps/plugin_api/",
"openedx/core/djangoapps/plugins/",
"openedx/core/djangoapps/profile_images/",
"openedx/core/djangoapps/programs/",
"openedx/core/djangoapps/safe_sessions/",
"openedx/core/djangoapps/schedules/",
"openedx/core/djangoapps/self_paced/",
"openedx/core/djangoapps/service_status/",
"openedx/core/djangoapps/session_inactivity_timeout/",
"openedx/core/djangoapps/signals/",
"openedx/core/djangoapps/site_configuration/",
"openedx/core/djangoapps/system_wide_roles/",
"openedx/core/djangoapps/theming/",
"openedx/core/djangoapps/user_api/",
"openedx/core/djangoapps/user_authn/",
"openedx/core/djangoapps/util/",
"openedx/core/djangoapps/verified_track_content/",
"openedx/core/djangoapps/video_config/",
"openedx/core/djangoapps/video_pipeline/",
"openedx/core/djangoapps/waffle_utils/",
"openedx/core/djangoapps/xblock/",
"openedx/core/djangoapps/xmodule_django/",
"openedx/core/djangoapps/zendesk_proxy/",
"openedx/core/lib/",
"openedx/tests/"
]
},
"cms-1": {
"settings": "cms.envs.test",
"paths": [
"cms/djangoapps/api/",
"cms/djangoapps/cms_user_tasks/",
"cms/djangoapps/course_creators/",
"cms/djangoapps/export_course_metadata/",
"cms/djangoapps/maintenance/",
"cms/djangoapps/models/",
"cms/djangoapps/pipeline_js/",
"cms/djangoapps/xblock_config/",
"cms/envs/",
"cms/lib/"
]
},
"cms-2": {
"settings": "cms.envs.test",
"paths": [
"cms/djangoapps/contentstore/"
]
},
"common-1": {
"settings": "lms.envs.test",
"paths": [
"common/djangoapps/"
]
},
"common-2": {
"settings": "lms.envs.test",
"paths": [
"common/lib/"
]
},
"common-3": {
"settings": "cms.envs.test",
"paths": [
"common/djangoapps/"
]
}
}
9 changes: 4 additions & 5 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@ jobs:
"lms-6",
"openedx-1",
"openedx-2",
"openedx-3",
"openedx-4",
"cms-1",
"cms-2",
"common-1",
"common-2",
"common-3",
]


Expand All @@ -38,13 +41,9 @@ jobs:
run: |
sudo /etc/init.d/mongodb start

- name: set top-level module name
run: |
echo "module_name=$(echo '${{ matrix.shard_name }}' | awk -F '-' '{print $1}')" >> $GITHUB_ENV

- name: set settings path
run: |
echo "settings_path=$(if [ '${{ env.module_name }}' = 'cms' ]; then echo 'cms.envs.test'; else echo 'lms.envs.test' ; fi)" >> $GITHUB_ENV
echo "settings_path=$(python scripts/unit_test_shards_parser.py --shard-name=${{ matrix.shard_name }} --output settings )" >> $GITHUB_ENV

# - name: set pytest randomly option
# run: |
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/verify-gha-unit-tests-count.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,10 @@ jobs:
echo All root unit tests count: ${{ env.root_all_unit_tests_count }}
echo All shards unit tests count: ${{ env.shards_all_unit_tests_count }}

- name: verify unit tests count
- name: fail the check
Comment thread
nedbat marked this conversation as resolved.
if: ${{ env.root_all_unit_tests_count != env.shards_all_unit_tests_count }}
run: |
echo "::error title='Unit test modules in unit-test-shards.json (unit-tests.yml workflow) are outdated'::unit tests running in unit-tests workflow don't match the count for unit tests for entire edx-platform suite, please update the unit-test-shards.json under .github/workflows to add any missing apps and match the count"
echo "::error title='Unit test modules in unit-test-shards.json (unit-tests.yml workflow) are outdated'::unit tests running in unit-tests
workflow don't match the count for unit tests for entire edx-platform suite, please update the unit-test-shards.json under .github/workflows
to add any missing apps and match the count. for more details please take a look at scripts/gha-shards-readme.md"
exit 1
35 changes: 35 additions & 0 deletions scripts/gha-shards-readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Unit tests sharding strategy

#### background
Unit tests are run in parallel (in GitHub Actions matrices) using the sharding strategy specified in unit-test-shards.json
We've divided the top level modules into multiple shards to achieve better parallelism.
The configuration in unit-test-shards.json specifies the shard name as key for each shard and the value contains an object
with django settings for each module and paths for submodules to test for example:
```json
{
"lms-1": {
"paths": ["lms/djangoapps/course_api", ...],
"settings": "lms.envs.test",
}
.
.
.
}
```
The `common` and `openedx` modules are tested with both `lms` and `cms` settings; that's why there are shards with the same `openedx`
submodules but with different Django settings.
For more details on sharding strategy please refer to this section on [sharding](https://openedx.atlassian.net/wiki/spaces/AT/pages/3235971586/edx-platfrom+unit+tests+migration+from+Jenkins+to+Github+Actions#Motivation-for-sharding-manually)

#### Unit tests count check is failing
There's a check in place that makes sure that all the unit tests under edx-platform modules are specified in `unit-test-shards.json`
If there's a mismatch between the number of unit tests collected from `unit-test-shards.json` and the number of unit tests collected
against the entire codebase the check will fail.
You'd have to update the `unit-test-shards.json` file manually to fix this.

##### How to fix
- If you've added a new django app to the codebase, and you want to add it to the unit tests you need to add it to the `unit-test-shards.json`, details on where (in which shard) to place your Django app please refer to the [sharding](https://openedx.atlassian.net/wiki/spaces/AT/pages/3235971586/edx-platfrom+unit+tests+migration+from+Jenkins+to+Github+Actions#Where-should-I-place-my-new-Django-app) section in this document.
- If you haven't added any new django app to the codebase, you can debug / verify this by collecting unit tests against a submodule by running `pytest` for example:
```
pytest --collect-only --ds=cms.envs.test cms/
```
For more details on how this check collects and compares the unit tests count please take a look at [verify unit tests count](../.github/workflows/verify-gha-unit-tests-count.yml)
Loading