squad 1.74__tar.gz → 1.75__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {squad-1.74 → squad-1.75}/CHANGELOG.md +23 -0
- {squad-1.74/squad.egg-info → squad-1.75}/PKG-INFO +1 -1
- {squad-1.74 → squad-1.75}/squad/api/rest.py +0 -1
- {squad-1.74 → squad-1.75}/squad/ci/backend/tuxsuite.py +33 -3
- {squad-1.74 → squad-1.75}/squad/ci/models.py +30 -1
- {squad-1.74 → squad-1.75}/squad/core/models.py +5 -4
- {squad-1.74 → squad-1.75}/squad/frontend/views.py +29 -10
- {squad-1.74 → squad-1.75}/squad/settings.py +9 -0
- squad-1.75/squad/version.py +1 -0
- {squad-1.74 → squad-1.75/squad.egg-info}/PKG-INFO +1 -1
- {squad-1.74 → squad-1.75}/test/ci/backend/test_tuxsuite.py +88 -0
- {squad-1.74 → squad-1.75}/test/ci/test_tasks.py +80 -0
- {squad-1.74 → squad-1.75}/test/core/test_build.py +9 -0
- {squad-1.74 → squad-1.75}/test/frontend/test_basics.py +63 -0
- squad-1.74/squad/version.py +0 -1
- {squad-1.74 → squad-1.75}/.ackrc +0 -0
- {squad-1.74 → squad-1.75}/.coveragerc +0 -0
- {squad-1.74 → squad-1.75}/.ctags +0 -0
- {squad-1.74 → squad-1.75}/.dockerignore +0 -0
- {squad-1.74 → squad-1.75}/.github/workflows/release.yml +0 -0
- {squad-1.74 → squad-1.75}/.github/workflows/test.yml +0 -0
- {squad-1.74 → squad-1.75}/.gitignore +0 -0
- {squad-1.74 → squad-1.75}/.mailmap +0 -0
- {squad-1.74 → squad-1.75}/.readthedocs.yml +0 -0
- {squad-1.74 → squad-1.75}/.reuse/dep5 +0 -0
- {squad-1.74 → squad-1.75}/COPYING +0 -0
- {squad-1.74 → squad-1.75}/COPYRIGHTS +0 -0
- {squad-1.74 → squad-1.75}/Dockerfile +0 -0
- {squad-1.74 → squad-1.75}/LICENSES/GPL-3.0-or-later.txt +0 -0
- {squad-1.74 → squad-1.75}/LICENSES/MIT.txt +0 -0
- {squad-1.74 → squad-1.75}/LICENSES/OFL-1.1.txt +0 -0
- {squad-1.74 → squad-1.75}/MANIFEST.in +0 -0
- {squad-1.74 → squad-1.75}/Procfile +0 -0
- {squad-1.74 → squad-1.75}/README.rst +0 -0
- {squad-1.74 → squad-1.75}/babel.cfg +0 -0
- {squad-1.74 → squad-1.75}/dev-docker +0 -0
- {squad-1.74 → squad-1.75}/doc/.gitignore +0 -0
- {squad-1.74 → squad-1.75}/doc/Makefile +0 -0
- {squad-1.74 → squad-1.75}/doc/api.rst +0 -0
- {squad-1.74 → squad-1.75}/doc/ci.rst +0 -0
- {squad-1.74 → squad-1.75}/doc/conf.py +0 -0
- {squad-1.74 → squad-1.75}/doc/hacking.rst +0 -0
- {squad-1.74 → squad-1.75}/doc/index.rst +0 -0
- {squad-1.74 → squad-1.75}/doc/install.rst +0 -0
- {squad-1.74 → squad-1.75}/doc/intro.rst +0 -0
- {squad-1.74 → squad-1.75}/doc/lava_usecase.rst +0 -0
- {squad-1.74 → squad-1.75}/doc/plugins.rst +0 -0
- {squad-1.74 → squad-1.75}/doc/quickstart.rst +0 -0
- {squad-1.74 → squad-1.75}/doc/translating.rst +0 -0
- {squad-1.74 → squad-1.75}/doc/tuxsuite_usecase.rst +0 -0
- {squad-1.74 → squad-1.75}/docker-compose.yaml +0 -0
- {squad-1.74 → squad-1.75}/manage.py +0 -0
- {squad-1.74 → squad-1.75}/package-lock.json +0 -0
- {squad-1.74 → squad-1.75}/package.json +0 -0
- {squad-1.74 → squad-1.75}/pytest.ini +0 -0
- {squad-1.74 → squad-1.75}/requirements-dev.txt +0 -0
- {squad-1.74 → squad-1.75}/requirements.txt +0 -0
- {squad-1.74 → squad-1.75}/scripts/build +0 -0
- {squad-1.74 → squad-1.75}/scripts/check-ci +0 -0
- {squad-1.74 → squad-1.75}/scripts/check-ignore +0 -0
- {squad-1.74 → squad-1.75}/scripts/community_connector/main.js +0 -0
- {squad-1.74 → squad-1.75}/scripts/community_connector/manifest.json +0 -0
- {squad-1.74 → squad-1.75}/scripts/dogfood +0 -0
- {squad-1.74 → squad-1.75}/scripts/get-metrics +0 -0
- {squad-1.74 → squad-1.75}/scripts/get-tests +0 -0
- {squad-1.74 → squad-1.75}/scripts/git-build +0 -0
- {squad-1.74 → squad-1.75}/scripts/pytest +0 -0
- {squad-1.74 → squad-1.75}/scripts/rabbitmq-server +0 -0
- {squad-1.74 → squad-1.75}/scripts/release +0 -0
- {squad-1.74 → squad-1.75}/scripts/release-docker +0 -0
- {squad-1.74 → squad-1.75}/scripts/squad-config +0 -0
- {squad-1.74 → squad-1.75}/scripts/test-ci +0 -0
- {squad-1.74 → squad-1.75}/scripts/test-docker +0 -0
- {squad-1.74 → squad-1.75}/scripts/testdata/gen-ci-jobs +0 -0
- {squad-1.74 → squad-1.75}/scripts/testdata/gen-metrics +0 -0
- {squad-1.74 → squad-1.75}/scripts/testdata/gen-test-data +0 -0
- {squad-1.74 → squad-1.75}/scripts/testdata/gen-tests +0 -0
- {squad-1.74 → squad-1.75}/scripts/testdata/setup-dev +0 -0
- {squad-1.74 → squad-1.75}/scripts/testdata/submit-ci-jobs +0 -0
- {squad-1.74 → squad-1.75}/scripts/testdata/submit-test-data +0 -0
- {squad-1.74 → squad-1.75}/scripts/translate +0 -0
- {squad-1.74 → squad-1.75}/scripts/travis-lava +0 -0
- {squad-1.74 → squad-1.75}/scripts/update-translation-files +0 -0
- {squad-1.74 → squad-1.75}/scripts/upload +0 -0
- {squad-1.74 → squad-1.75}/setup.cfg +0 -0
- {squad-1.74 → squad-1.75}/setup.py +0 -0
- {squad-1.74 → squad-1.75}/squad/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/admin.py +0 -0
- {squad-1.74 → squad-1.75}/squad/api/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/api/apps.py +0 -0
- {squad-1.74 → squad-1.75}/squad/api/ci.py +0 -0
- {squad-1.74 → squad-1.75}/squad/api/data.py +0 -0
- {squad-1.74 → squad-1.75}/squad/api/filters.py +0 -0
- {squad-1.74 → squad-1.75}/squad/api/urls.py +0 -0
- {squad-1.74 → squad-1.75}/squad/api/utils.py +0 -0
- {squad-1.74 → squad-1.75}/squad/api/views.py +0 -0
- {squad-1.74 → squad-1.75}/squad/celery.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/admin.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/apps.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/backend/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/backend/fake.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/backend/lava.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/backend/null.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/exceptions.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/management/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/management/commands/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/management/commands/create_tuxsuite_boot_tests.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/management/commands/listen.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/management/commands/testfetch.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0001_initial.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0002_auto_20170406_1252.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0003_backend_name.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0004_testjob_failure.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0005_remove_listener_data.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0006_simplify_backend_loading.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0007_auto_20170517_1736.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0008_testjob_testrun.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0009_slug_pattern.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0010_testjob_can_resubmit.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0011_testjob_resubmitted_count.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0012_testjob_build.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0013_testjob_name.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0014_testjob_target_build.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0015_testjob_populate_target_build.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0016_backend_max_fetch_attempts.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0017_testjob_fetch_attempts.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0018_testjob_dates.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0019_add_fake_backend.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0020_backend_settings_field.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0021_testjob_parent_job.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0022_backend_poll_enabled.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0023_remove_testjob_build.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0024_fix_testjob_environment_validation.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0025_backend_listen_enabled.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0026_job_start_end_time.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0027_add_tuxsuite_implementation_type.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0028_create_testjob_indexes.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/0029_create_testjob_results_input.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/migrations/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/tasks.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/templates/squad/ci/testjob_resubmit.html.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/templates/squad/ci/testjob_resubmit.txt.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/templatetags/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/templatetags/filter_jobs.py +0 -0
- {squad-1.74 → squad-1.75}/squad/ci/utils.py +0 -0
- {squad-1.74 → squad-1.75}/squad/compat.py +0 -0
- {squad-1.74 → squad-1.75}/squad/container_settings.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/admin.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/apps.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/callback.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/comparison.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/data.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/failures.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/history.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/locale/django.pot +0 -0
- {squad-1.74 → squad-1.75}/squad/core/locale/es_MX/LC_MESSAGES/django.po +0 -0
- {squad-1.74 → squad-1.75}/squad/core/locale/pl/LC_MESSAGES/django.po +0 -0
- {squad-1.74 → squad-1.75}/squad/core/locale/pt/LC_MESSAGES/django.po +0 -0
- {squad-1.74 → squad-1.75}/squad/core/locale/pt_BR/LC_MESSAGES/django.po +0 -0
- {squad-1.74 → squad-1.75}/squad/core/management/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/management/commands/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/management/commands/compute_build_summaries.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/management/commands/compute_project_statuses.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/management/commands/fill_test_metadata.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/management/commands/fix_squadplugin_data.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/management/commands/import_data.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/management/commands/import_data.rst +0 -0
- {squad-1.74 → squad-1.75}/squad/core/management/commands/migrate_test_runs.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/management/commands/populate_metric_build_and_environment.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/management/commands/populate_test_build_and_environment.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/management/commands/prepdump.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/management/commands/send-email.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/management/commands/update_project_statuses.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/management/commands/users.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0001_initial.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0002_auto_20160525_1403.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0003_testrun_log_file.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0004_group_user_groups.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0005_token.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0006_auto_20160826_2242.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0007_testrun_data_processed.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0008_status.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0009_testrun_status_recorded.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0010_testrun_datetime.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0011_testrun_metadata_fields.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0012_build_datetime.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0013_testrun_resubmit_url.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0014_testrun_metadata_file.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0015_attachment.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0016_project_is_public.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0017_slug_validator.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0018_build_name.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0019_build_version.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0020_build_ordering.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0021_global_tokens.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0022_projectstatus.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0023_subscription.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0024_project_build_completion_threshold.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0025_unique_testrun_job_id.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0026_testrun_result_accept_null.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0027_project_notification_strategy.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0028_suite_and_test_name_length.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0029_subscription_email_formats.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0030_remove_project_build_completion_threshold.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0031_environment_expected_test_runs.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0032_testrun_completed.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0033_drop_debversion.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0034_prepare_to_remove_build_name.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0035_remove_build_name.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0036_status_tests_skip.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0037_project_status_test_summary_fields.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0038_populate_project_status_cache.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0039_orderings.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0040_remove_subscription_html.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0041_projectstatus_notified.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0042_set_projectstatus_notified.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0043_project_status_build.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0044_project_html_mail.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0045_adminsubscription.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0046_projectstatus_last_updated.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0047_populate_projectstatus_last_updated.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0048_moderate_notifications.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0049_projectstatus_plural.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0050_projectstatus_finished.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0051_build_status.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0052_recreate_projectstatus_data.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0053_remove_projectstatus_previous.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0054_custom_email_template.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0055_emailtemplate_subject.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0056_project_description.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0057_projectstatus_has_metrics.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0058_populate_projectstatus_has_metrics.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0059_project_important_metadata_keys.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0060_test_log.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0061_project_enabled_plugins_list.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0062_project_allow_empty_enabled_plugin_list.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0063_project_wait_before_notification.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0064_project_notification_timeout.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0065_projectstatus_notified_on_timeout.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0066_environment_description.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0067_accept_blank_suite_name.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0068_suite_version.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0069_suite_metadata.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0070_create_suite_test_and_metric_metadata.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0071_migrate_old_tokens.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0072_group_description.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0073_auto_20180420_1643.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0074_add_indexes.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0075_update_project_enabled_plugin_list.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0076_patch_builds.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0077_knownissue.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0078_cache_test_run_counts.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0079_init_cache_test_run_counts.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0080_auto_20180810_0047.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0081_status_has_metrics.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0082_populate_status_has_metrics.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0083_rename_knownissue_environments.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0084_projectstatus_regressions_fixes.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0085_projectstatus_defaults.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0086_xfail.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0087_test_known_issues.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0088_user_subscriptions.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0089_test_has_known_issues.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0090_populate_test_has_known_issues.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0091_notification_delivery_remove_unique_status.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0092_annotation.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0093_historicalemailtemplate.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0094_populatehistoricalemailtemplate.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0095_project_data_retention_days.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0096_build_keep_data.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0097_build_placeholder.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0098_blank_annotation.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0099_metricthreshold.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0100_metric_is_outlier.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0101_project_project_settings.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0102_projectstatus_null_metric_summary.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0103_populate_project_status.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0104_delayedreport.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0105_delayed_report_error_message.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0106_delayedreport_output_subject.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0107_move_notification_strategy.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0108_add_email_template_validator.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0109_group_member.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0110_move_users_from_django_groups_to_squad_groups.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0111_remove_group_user_groups.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0112_user_namespaces.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0113_group_project_blank_name_and_description.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0114_project_enabled_plugin_list_can_be_blank.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0115_fix_slug_validation.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0116_make_group_membership_unique.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0117_drop_obsolete_token_model.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0118_project_is_archived.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0119_i18n.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0120_buildsummary.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0121_add_password_patchsource.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0122_fix_patchsource_url_and_token.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0123_django_upgrade_missing_migrations.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0124_set_default_expected_test_runs_to_zero.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0125_fix_missing_status_has_metrics_for_testruns.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0126_metricthreshold_environment.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0127_metric_thresholds_migrate_data.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0128_metric_thresholds_remove_proj_col.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0129_projectstatus_nullable_notified_on_timeout.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0130_project_status_baseline_next.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0131_create_squad_auth_group_and_add_users.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0132_attachment_mimetype.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0133_append_project_permissions_to_squad_auth_group.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0134_longer_metric_name.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0135_add_privileged_access_level.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0136_migrate_submitters_to_privileged.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0137_patchsource_token_null.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0138_metric_unit.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0139_nullable_test_name.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0140_increase_gerrit_password_length.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0141_remove_test_name.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0142_add_testrun_file_storage.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0143_attachment_storage.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0144_attachment_data_null.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0145_pluginscratch.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0146_deprecate_testrun_and_attachment_data_fields.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0147_add_build_and_environment_to_test.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0148_remove_legacy_storage_fields.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0149_build_patch_url.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0150_add_new_notification_strategy.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0151_callback.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0152_add_build_patch_notified.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0153_callback_make_response_content_blob.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0154_project_add_force_finishing_builds_field.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0155_add_build_and_environment_to_metric.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0156_nullable_metric_name.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0157_remove_metric_name.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0158_add_metric_comparison_to_projectstatus.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0159_nullable_metricthreshold_value.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0160_add_project_to_metricthreshold.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0161_add_metricthreshold_perm_to_squad_group.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0162_project_add_build_confidence_settings.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0163_hirtoricalemailtemplate_update.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0164_django_update.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0165_buildsummary_uniqueness.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0166_build_is_release.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0167_add_project_datetime.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/0168_add_group_settings.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/migrations/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/notification.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/plugins.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/queries.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/statistics.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/tasks/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/tasks/exceptions.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/tasks/notification.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/templates/squad/notification/base.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/core/templates/squad/notification/diff.html.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/core/templates/squad/notification/diff.txt.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/core/templates/squad/notification/failed_test_jobs.html.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/core/templates/squad/notification/failed_test_jobs.txt.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/core/templates/squad/notification/moderation.html.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/core/templates/squad/notification/moderation.txt.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/core/templatetags/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/templatetags/squad_notification.py +0 -0
- {squad-1.74 → squad-1.75}/squad/core/utils.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/__main__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/admin.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/apps.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/badges.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/build_settings.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/ci.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/comparison.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/extract.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/forms.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/group_settings.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/locale/django.pot +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/locale/pl/LC_MESSAGES/django.po +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/locale/pt/LC_MESSAGES/django.po +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/locale/pt_BR/LC_MESSAGES/django.po +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/management/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/management/commands/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/management/commands/get_token.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/metrics.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/project_settings.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/queries.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/setup.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/compare.css +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/download +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/download.conf +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/favicon.ico +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/main.css +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/attach_select2.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/build.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/build_compare.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/build_list.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/charts.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/common.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/compare.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/config.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/controllers/annotation.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/controllers/build_compare.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/controllers/build_list_compare.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/controllers/build_release.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/controllers/cancel.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/controllers/charts.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/controllers/compare.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/controllers/fetch.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/controllers/filter.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/controllers/metricThreshold.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/controllers/project_compare.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/controllers/resubmit.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/controllers/testjobs_progress.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/metric.threshold.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/project_compare.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/showHide.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad/table.js +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/static/squad_sign.svg +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/401.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/404.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/django/rest_framework/api.html +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/django/squad/_user_menu.html +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_builds_table.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_env_suite_data.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_metadata.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_pagination.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_permissions.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_project_list.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_regressions_and_fixes.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_results_table.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_results_transitions_filter.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_subscribe.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_test_results_envbox.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_test_results_suitebox.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_test_results_summary.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_test_results_table.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_test_run_metric.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_test_run_test.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_unfinished_build.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/_user_menu.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/base.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/build-nav.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/build.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/build_callbacks.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/build_metadata.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/build_metrics.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/build_settings.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/builds.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/compare.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/compare_builds.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/compare_projects.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/group-nav.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/group.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/group_settings/advanced.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/group_settings/base.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/group_settings/delete.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/group_settings/index.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/group_settings/members.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/group_settings/new_group.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/group_settings/new_project.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/index.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/knownissues.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/login.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/metrics.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/project-nav.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/project.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/project_settings/_threshold_table.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/project_settings/advanced.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/project_settings/base.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/project_settings/build_confidence.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/project_settings/delete.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/project_settings/environments.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/project_settings/index.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/project_settings/thresholds.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/test_history.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/test_run.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/test_run_suite_metrics.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/test_run_suite_test_details.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/test_run_suite_tests.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/testjob.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/testjobs.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/testjobs_progress.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/tests-details-nav.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/tests.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/user_settings/api_token.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/user_settings/base.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/user_settings/profile.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/user_settings/projects.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templates/squad/user_settings/subscriptions.jinja2 +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templatetags/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/templatetags/squad.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/tests.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/urls.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/user_settings.py +0 -0
- {squad-1.74 → squad-1.75}/squad/frontend/utils.py +0 -0
- {squad-1.74 → squad-1.75}/squad/http.py +0 -0
- {squad-1.74 → squad-1.75}/squad/jinja2.py +0 -0
- {squad-1.74 → squad-1.75}/squad/mail.py +0 -0
- {squad-1.74 → squad-1.75}/squad/manage.py +0 -0
- {squad-1.74 → squad-1.75}/squad/plugins/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/plugins/example.py +0 -0
- {squad-1.74 → squad-1.75}/squad/plugins/gerrit.py +0 -0
- {squad-1.74 → squad-1.75}/squad/plugins/github.py +0 -0
- {squad-1.74 → squad-1.75}/squad/plugins/linux_log_parser.py +0 -0
- {squad-1.74 → squad-1.75}/squad/run/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/run/__main__.py +0 -0
- {squad-1.74 → squad-1.75}/squad/run/listener.py +0 -0
- {squad-1.74 → squad-1.75}/squad/run/scheduler.py +0 -0
- {squad-1.74 → squad-1.75}/squad/run/worker.py +0 -0
- {squad-1.74 → squad-1.75}/squad/socialaccount.py +0 -0
- {squad-1.74 → squad-1.75}/squad/urls.py +0 -0
- {squad-1.74 → squad-1.75}/squad/wsgi.py +0 -0
- {squad-1.74 → squad-1.75}/squad.egg-info/SOURCES.txt +0 -0
- {squad-1.74 → squad-1.75}/squad.egg-info/dependency_links.txt +0 -0
- {squad-1.74 → squad-1.75}/squad.egg-info/entry_points.txt +0 -0
- {squad-1.74 → squad-1.75}/squad.egg-info/requires.txt +0 -0
- {squad-1.74 → squad-1.75}/squad.egg-info/top_level.txt +0 -0
- {squad-1.74 → squad-1.75}/squad.svg +0 -0
- {squad-1.74 → squad-1.75}/test/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/test/api/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/test/api/benchmarks.csv +0 -0
- {squad-1.74 → squad-1.75}/test/api/benchmarks.json +0 -0
- {squad-1.74 → squad-1.75}/test/api/definition.yaml +0 -0
- {squad-1.74 → squad-1.75}/test/api/metadata.json +0 -0
- {squad-1.74 → squad-1.75}/test/api/test_ci.py +0 -0
- {squad-1.74 → squad-1.75}/test/api/test_data.py +0 -0
- {squad-1.74 → squad-1.75}/test/api/test_rest.py +0 -0
- {squad-1.74 → squad-1.75}/test/api/test_run.log +0 -0
- {squad-1.74 → squad-1.75}/test/api/tests.csv +0 -0
- {squad-1.74 → squad-1.75}/test/api/tests.json +0 -0
- {squad-1.74 → squad-1.75}/test/api/tests.py +0 -0
- {squad-1.74 → squad-1.75}/test/api/tests_log.json +0 -0
- {squad-1.74 → squad-1.75}/test/api/tests_two.json +0 -0
- {squad-1.74 → squad-1.75}/test/api/twoline_definition.yaml +0 -0
- {squad-1.74 → squad-1.75}/test/ci/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/test/ci/backend/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/test/ci/backend/example-broken-log.yaml +0 -0
- {squad-1.74 → squad-1.75}/test/ci/backend/example-lava-log.yaml +0 -0
- {squad-1.74 → squad-1.75}/test/ci/backend/lava.json +0 -0
- {squad-1.74 → squad-1.75}/test/ci/backend/test_fake.py +0 -0
- {squad-1.74 → squad-1.75}/test/ci/backend/test_lava.py +0 -0
- {squad-1.74 → squad-1.75}/test/ci/backend/test_real_lava.py +0 -0
- {squad-1.74 → squad-1.75}/test/ci/backend/tuxsuite_test_failed_result_sample.json +0 -0
- {squad-1.74 → squad-1.75}/test/ci/backend/tuxsuite_test_result_sample.json +0 -0
- {squad-1.74 → squad-1.75}/test/ci/test_listen.py +0 -0
- {squad-1.74 → squad-1.75}/test/ci/test_models.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_attachment.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_build_summary.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_callback.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_emailtemplate.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_failures.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_group.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_historical_emailtemplate.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_history.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_import_data.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_import_data_input/1/default/1/metadata.json +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_import_data_input/1/default/1/metrics.json +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_import_data_input/2/default/2/metadata.json +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_import_data_input/2/default/2/metrics.json +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_import_data_input/2/default/2/screenshot.png +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_import_data_input/2/default/2/tests.json +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_import_data_missing_metadata/1/1/tests.json +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_known_issues.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_metric.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_metric_comparison.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_metric_threshold.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_metrics_data.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_metrics_summary.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_notification.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_notification_delivery.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_patch_source.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_project.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_project_status.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_statistics.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_tasks.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_tasks_notification.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_test.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_test_comparison.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_test_data.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_test_run.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_test_summary.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_update_project_statuses.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_user_namespace.py +0 -0
- {squad-1.74 → squad-1.75}/test/core/test_utils.py +0 -0
- {squad-1.74 → squad-1.75}/test/frontend/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/test/frontend/test_comparison.py +0 -0
- {squad-1.74 → squad-1.75}/test/frontend/test_get_token_command.py +0 -0
- {squad-1.74 → squad-1.75}/test/frontend/test_group_settings.py +0 -0
- {squad-1.74 → squad-1.75}/test/frontend/test_history.py +0 -0
- {squad-1.74 → squad-1.75}/test/frontend/test_template_tags.py +0 -0
- {squad-1.74 → squad-1.75}/test/frontend/test_test_job.py +0 -0
- {squad-1.74 → squad-1.75}/test/frontend/test_tests.py +0 -0
- {squad-1.74 → squad-1.75}/test/frontend/test_utils.py +0 -0
- {squad-1.74 → squad-1.75}/test/integration/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/test/integration/plugins/test_tradefed.py +0 -0
- {squad-1.74 → squad-1.75}/test/integration/plugins/tradefed-output-20220608105250.tar.xz +0 -0
- {squad-1.74 → squad-1.75}/test/integration/test_build_notification_from_ci.py +0 -0
- {squad-1.74 → squad-1.75}/test/javascript.py +0 -0
- {squad-1.74 → squad-1.75}/test/karma.conf.js +0 -0
- {squad-1.74 → squad-1.75}/test/mock.py +0 -0
- {squad-1.74 → squad-1.75}/test/performance.py +0 -0
- {squad-1.74 → squad-1.75}/test/plugins/__init__.py +0 -0
- {squad-1.74 → squad-1.75}/test/plugins/linux_log_parser/kasan.log +0 -0
- {squad-1.74 → squad-1.75}/test/plugins/linux_log_parser/kernel_bug_and_invalid_opcode.log +0 -0
- {squad-1.74 → squad-1.75}/test/plugins/linux_log_parser/kernelexceptiontrace.log +0 -0
- {squad-1.74 → squad-1.75}/test/plugins/linux_log_parser/kernelpanic.log +0 -0
- {squad-1.74 → squad-1.75}/test/plugins/linux_log_parser/kfence.log +0 -0
- {squad-1.74 → squad-1.75}/test/plugins/linux_log_parser/multiple_issues_dmesg.log +0 -0
- {squad-1.74 → squad-1.75}/test/plugins/linux_log_parser/oops.log +0 -0
- {squad-1.74 → squad-1.75}/test/plugins/linux_log_parser/rcu_warning.log +0 -0
- {squad-1.74 → squad-1.75}/test/plugins/test_gerrit.py +0 -0
- {squad-1.74 → squad-1.75}/test/plugins/test_github.py +0 -0
- {squad-1.74 → squad-1.75}/test/plugins/test_linux_log_parser.py +0 -0
- {squad-1.74 → squad-1.75}/test/plugins/test_plugin.py +0 -0
- {squad-1.74 → squad-1.75}/test/settings.py +0 -0
- {squad-1.74 → squad-1.75}/test/test_architecture.py +0 -0
- {squad-1.74 → squad-1.75}/test/test_code_quality.py +0 -0
- {squad-1.74 → squad-1.75}/test/test_cors.py +0 -0
- {squad-1.74 → squad-1.75}/test/test_i18n.py +0 -0
- {squad-1.74 → squad-1.75}/test/test_mail.py +0 -0
- {squad-1.74 → squad-1.75}/test/test_pending_migrations.py +0 -0
- {squad-1.74 → squad-1.75}/test/unit/test_annotation.js +0 -0
- {squad-1.74 → squad-1.75}/test/unit/test_cancel.js +0 -0
- {squad-1.74 → squad-1.75}/test/unit/test_charts.js +0 -0
- {squad-1.74 → squad-1.75}/test/unit/test_compare.js +0 -0
- {squad-1.74 → squad-1.75}/test/unit/test_filter.js +0 -0
- {squad-1.74 → squad-1.75}/test/unit/test_resubmit.js +0 -0
@@ -1,3 +1,26 @@
|
|
1
|
+
# 1.75
|
2
|
+
|
3
|
+
This 1.75 release fixes an important bug that has been around unnoticed for quite some time.
|
4
|
+
|
5
|
+
The bug is basically a race condition when a build is marked as finished too early, before
|
6
|
+
all testjobs results are actually done processing. The fix should address that issue.
|
7
|
+
|
8
|
+
The release also allows listing projects in group's home page by active in last N days. Within
|
9
|
+
project settings one can determine N.
|
10
|
+
|
11
|
+
There has been added support for accepting OE builds from Tuxsuite and support for squad-client
|
12
|
+
will come soon.
|
13
|
+
|
14
|
+
Complete list of changes going in:
|
15
|
+
|
16
|
+
* api/rest.py: re-add suite to failures with confidence endpoint
|
17
|
+
* ci/backend/tuxsuite.py: support oe builds
|
18
|
+
* ci/models.py: bring pending function to TestJob
|
19
|
+
* settings.py: support newer versions of django-allauth
|
20
|
+
* squad/core/models.py: Change important metadata to support custom order
|
21
|
+
* squad/frontend/views.py,squad/core/models.py: move sorting of metadata
|
22
|
+
* squad/frontend/views.py: Add support for filtering project list by age
|
23
|
+
|
1
24
|
# 1.74
|
2
25
|
|
3
26
|
This 1.74 release patches a couple of pages improving overall performance.
|
@@ -100,9 +100,14 @@ class Backend(BaseBackend):
|
|
100
100
|
|
101
101
|
('BUILD', 'linaro@anders', '1yPYGaOEPNwr2pCqBgONY43zORq')
|
102
102
|
|
103
|
+
The leading string determines the type of the tuxsuite object:
|
104
|
+
- BUILD
|
105
|
+
- OEBUILD
|
106
|
+
- TEST
|
107
|
+
|
103
108
|
"""
|
104
109
|
|
105
|
-
regex = r'^(BUILD|TEST):([0-9a-z_\-]+@[0-9a-z_\-]+)#([a-zA-Z0-9]+)$'
|
110
|
+
regex = r'^(OEBUILD|BUILD|TEST):([0-9a-z_\-]+@[0-9a-z_\-]+)#([a-zA-Z0-9]+)$'
|
106
111
|
matches = re.findall(regex, job_id)
|
107
112
|
if len(matches) == 0:
|
108
113
|
raise FetchIssue(f'Job id "{job_id}" does not match "{regex}"')
|
@@ -113,18 +118,19 @@ class Backend(BaseBackend):
|
|
113
118
|
def generate_job_id(self, result_type, result):
|
114
119
|
"""
|
115
120
|
The job id for TuxSuite results is generated using 3 pieces of info:
|
116
|
-
1. If it's either "BUILD" or "TEST" result;
|
121
|
+
1. If it's either "BUILD", "OEBUILD" or "TEST" result;
|
117
122
|
2. The TuxSuite project. Ex: "linaro/anders"
|
118
123
|
3. The ksuid of the object. Ex: "1yPYGaOEPNwr2pfqBgONY43zORp"
|
119
124
|
|
120
125
|
A couple examples for job_id are:
|
121
126
|
- BUILD:linaro@anders#1yPYGaOEPNwr2pCqBgONY43zORq
|
127
|
+
- OEBUILD:linaro@lkft#2Wetiz7Qs0TbtfPgPT7hUObWqDK
|
122
128
|
- TEST:arm@bob#1yPYGaOEPNwr2pCqBgONY43zORp
|
123
129
|
|
124
130
|
Then it's up to SQUAD's TuxSuite backend to parse the job_id
|
125
131
|
and fetch results properly.
|
126
132
|
"""
|
127
|
-
_type =
|
133
|
+
_type = result_type.upper()
|
128
134
|
project = result["project"].replace("/", "@")
|
129
135
|
uid = result["uid"]
|
130
136
|
return f"{_type}:{project}#{uid}"
|
@@ -257,6 +263,30 @@ class Backend(BaseBackend):
|
|
257
263
|
|
258
264
|
return status, completed, metadata, tests, metrics, logs
|
259
265
|
|
266
|
+
def parse_oebuild_results(self, test_job, job_url, results, settings):
|
267
|
+
required_keys = ['download_url', 'result']
|
268
|
+
self.__check_required_keys__(required_keys, results)
|
269
|
+
|
270
|
+
# Make metadata
|
271
|
+
metadata_keys = settings.get('OEBUILD_METADATA_KEYS', [])
|
272
|
+
metadata = {k: results.get(k) for k in metadata_keys}
|
273
|
+
metadata['job_url'] = job_url
|
274
|
+
metadata['job_id'] = test_job.job_id
|
275
|
+
|
276
|
+
sources = results.get('sources')
|
277
|
+
if sources:
|
278
|
+
metadata['sources'] = sources
|
279
|
+
|
280
|
+
# Create tests and metrics
|
281
|
+
tests = {}
|
282
|
+
metrics = {}
|
283
|
+
completed = True
|
284
|
+
status = 'Complete'
|
285
|
+
tests['build/build'] = 'pass' if results['result'] == 'pass' else 'fail'
|
286
|
+
logs = self.fetch_url(results['download_url'], 'build.log').text
|
287
|
+
|
288
|
+
return status, completed, metadata, tests, metrics, logs
|
289
|
+
|
260
290
|
def parse_test_results(self, test_job, job_url, results, settings):
|
261
291
|
status = 'Complete'
|
262
292
|
completed = True
|
@@ -4,6 +4,7 @@ import traceback
|
|
4
4
|
import yaml
|
5
5
|
from io import StringIO
|
6
6
|
from django.db import models, transaction, DatabaseError
|
7
|
+
from django.db.models import Q
|
7
8
|
from django.utils import timezone
|
8
9
|
from dateutil.relativedelta import relativedelta
|
9
10
|
|
@@ -66,6 +67,19 @@ class Backend(models.Model):
|
|
66
67
|
yield test_job
|
67
68
|
|
68
69
|
def fetch(self, job_id):
|
70
|
+
# Job statuses can be one of:
|
71
|
+
# * None
|
72
|
+
# * Submitted
|
73
|
+
# * Scheduling
|
74
|
+
# * Scheduled
|
75
|
+
# * Running
|
76
|
+
# * Complete
|
77
|
+
# * Incomplete
|
78
|
+
# * Canceled
|
79
|
+
# * Fetching
|
80
|
+
# Only jobs in 'Complete', 'Canceled' and 'Incomplete' are eligible for fetching
|
81
|
+
|
82
|
+
job_status = None
|
69
83
|
with transaction.atomic():
|
70
84
|
try:
|
71
85
|
test_job = TestJob.objects.select_for_update(nowait=True).get(pk=job_id)
|
@@ -91,6 +105,8 @@ class Backend(models.Model):
|
|
91
105
|
test_job.save()
|
92
106
|
return
|
93
107
|
|
108
|
+
job_status = test_job.job_status
|
109
|
+
test_job.job_status = 'Fetching'
|
94
110
|
test_job.fetched = True
|
95
111
|
test_job.fetched_at = timezone.now()
|
96
112
|
test_job.save()
|
@@ -130,10 +146,16 @@ class Backend(models.Model):
|
|
130
146
|
except DuplicatedTestJob as exception:
|
131
147
|
logger.error('Failed to fetch test_job(%d): "%s"' % (test_job.id, str(exception)))
|
132
148
|
|
149
|
+
if test_job.testrun:
|
150
|
+
self.__postprocess_testjob__(test_job)
|
151
|
+
|
152
|
+
# Removed the 'Fetching' job_status only after eventual plugins
|
153
|
+
# are finished, this garantees extra tests and metadata to
|
154
|
+
# be in SQUAD before the build is considered finished
|
155
|
+
test_job.job_status = job_status
|
133
156
|
test_job.save()
|
134
157
|
|
135
158
|
if test_job.testrun:
|
136
|
-
self.__postprocess_testjob__(test_job)
|
137
159
|
UpdateProjectStatus()(test_job.testrun)
|
138
160
|
|
139
161
|
def __postprocess_testjob__(self, test_job):
|
@@ -177,9 +199,16 @@ class Backend(models.Model):
|
|
177
199
|
return '%s (%s)' % (self.name, self.implementation_type)
|
178
200
|
|
179
201
|
|
202
|
+
class TestJobManager(models.Manager):
|
203
|
+
|
204
|
+
def pending(self):
|
205
|
+
return self.filter(Q(fetched=False) | Q(job_status='Fetching'))
|
206
|
+
|
207
|
+
|
180
208
|
class TestJob(models.Model):
|
181
209
|
|
182
210
|
__test__ = False
|
211
|
+
objects = TestJobManager()
|
183
212
|
|
184
213
|
# input - internal
|
185
214
|
backend = models.ForeignKey(Backend, related_name='test_jobs', on_delete=models.CASCADE)
|
@@ -584,10 +584,11 @@ class Build(models.Model):
|
|
584
584
|
def important_metadata(self):
|
585
585
|
wanted = (self.project.important_metadata_keys or '').splitlines()
|
586
586
|
m = self.metadata
|
587
|
+
metadata = self.metadata
|
587
588
|
if len(wanted):
|
588
|
-
|
589
|
-
|
590
|
-
|
589
|
+
metadata = {k: m[k] for k in wanted if k in m}
|
590
|
+
|
591
|
+
return metadata
|
591
592
|
|
592
593
|
@property
|
593
594
|
def has_extra_metadata(self):
|
@@ -619,7 +620,7 @@ class Build(models.Model):
|
|
619
620
|
# dependency on squad.ci, what in theory violates our architecture.
|
620
621
|
testjobs = self.test_jobs
|
621
622
|
if testjobs.count() > 0:
|
622
|
-
if testjobs.
|
623
|
+
if testjobs.pending().count() > 0:
|
623
624
|
# a build that has pending CI jobs is NOT finished
|
624
625
|
reasons.append("There are unfinished CI jobs")
|
625
626
|
else:
|
@@ -6,6 +6,9 @@ from django.core.paginator import Paginator, EmptyPage
|
|
6
6
|
from django.contrib.auth.decorators import login_required
|
7
7
|
from django.http import HttpResponse, Http404
|
8
8
|
from django.shortcuts import render, get_object_or_404, redirect, reverse
|
9
|
+
from django.utils import timezone
|
10
|
+
|
11
|
+
from dateutil.relativedelta import relativedelta
|
9
12
|
|
10
13
|
from squad.ci.models import TestJob
|
11
14
|
from squad.core.models import Group, Metric, ProjectStatus, Status, MetricThreshold, KnownIssue, Test
|
@@ -83,24 +86,30 @@ def home(request):
|
|
83
86
|
return render(request, 'squad/index.jinja2', context)
|
84
87
|
|
85
88
|
|
86
|
-
def
|
87
|
-
|
88
|
-
|
89
|
-
projects_queryset = group.projects.accessible_to(request.user)
|
89
|
+
def get_project_list(group, user, order_by, display_all_projects):
|
90
|
+
projects_queryset = group.projects.accessible_to(user)
|
90
91
|
projects_queryset = projects_queryset.annotate(latest_build_id=Max('builds__id'))
|
91
92
|
|
92
|
-
if
|
93
|
-
projects_queryset = projects_queryset.prefetch_related(Prefetch('subscriptions', queryset=Subscription.objects.filter(user=
|
93
|
+
if user.is_authenticated:
|
94
|
+
projects_queryset = projects_queryset.prefetch_related(Prefetch('subscriptions', queryset=Subscription.objects.filter(user=user), to_attr='user_subscriptions'))
|
94
95
|
|
95
|
-
order_by = request.GET.get('order', 'last_updated')
|
96
96
|
if group.get_setting('SORT_PROJECTS_BY_NAME'):
|
97
97
|
order_by = 'by_name'
|
98
98
|
|
99
99
|
elif order_by == 'last_updated':
|
100
100
|
projects_queryset = projects_queryset.order_by('-datetime')
|
101
101
|
|
102
|
-
display_all_projects = request.GET.get('all_projects') is not None
|
103
102
|
num_projects = group.get_setting('DEFAULT_PROJECT_COUNT')
|
103
|
+
|
104
|
+
show_projects_active_n_days_ago = group.get_setting('SHOW_PROJECTS_ACTIVE_N_DAYS_AGO')
|
105
|
+
if show_projects_active_n_days_ago:
|
106
|
+
earilest_timestamp = timezone.now() - relativedelta(days=show_projects_active_n_days_ago)
|
107
|
+
latest_project_count = projects_queryset.filter(datetime__gte=earilest_timestamp).count()
|
108
|
+
if latest_project_count > 0:
|
109
|
+
projects_queryset = projects_queryset.filter(datetime__gte=earilest_timestamp)
|
110
|
+
# Ignore DEFAULT_PROJECT_COUNT if we are using age of project
|
111
|
+
num_projects = None
|
112
|
+
|
104
113
|
if display_all_projects or num_projects is None:
|
105
114
|
display_all_projects = True
|
106
115
|
projects = projects_queryset.all()
|
@@ -108,6 +117,16 @@ def group_home(request, group_slug):
|
|
108
117
|
display_all_projects = projects_queryset.count() <= num_projects
|
109
118
|
projects = projects_queryset.all()[:num_projects]
|
110
119
|
|
120
|
+
return projects
|
121
|
+
|
122
|
+
|
123
|
+
def group_home(request, group_slug):
|
124
|
+
group = get_object_or_404(Group, slug=group_slug)
|
125
|
+
|
126
|
+
order_by = request.GET.get('order', 'last_updated')
|
127
|
+
display_all_projects = request.GET.get('all_projects') is not None
|
128
|
+
projects = get_project_list(group, request.user, order_by, display_all_projects)
|
129
|
+
|
111
130
|
has_archived_projects = False
|
112
131
|
latest_build_ids = {}
|
113
132
|
projects_count = 0
|
@@ -157,7 +176,7 @@ def project_home(request, group_slug, project_slug):
|
|
157
176
|
builds = [b for b in __get_builds_with_status__(project, 11)]
|
158
177
|
last_build = len(builds) and builds[0] or None
|
159
178
|
|
160
|
-
metadata = last_build and
|
179
|
+
metadata = last_build and last_build.important_metadata.items() or ()
|
161
180
|
context = {
|
162
181
|
'project': project,
|
163
182
|
'builds': builds,
|
@@ -379,7 +398,7 @@ def build(request, group_slug, project_slug, version):
|
|
379
398
|
'build': build,
|
380
399
|
'test_results': test_results,
|
381
400
|
'results_layout': results_layout,
|
382
|
-
'metadata':
|
401
|
+
'metadata': build.important_metadata.items(),
|
383
402
|
'has_extra_metadata': build.has_extra_metadata,
|
384
403
|
'failures_only': failures_only,
|
385
404
|
'testjobs_progress': testjobs_progress,
|
@@ -81,6 +81,14 @@ except ImportError:
|
|
81
81
|
pass
|
82
82
|
|
83
83
|
|
84
|
+
django_allauth_middleware = None
|
85
|
+
try:
|
86
|
+
import allauth.account.middleware # noqa: F401
|
87
|
+
django_allauth_middleware = 'allauth.account.middleware.AccountMiddleware'
|
88
|
+
except ImportError:
|
89
|
+
pass
|
90
|
+
|
91
|
+
|
84
92
|
__apps__ = [
|
85
93
|
'django.contrib.admin',
|
86
94
|
'django.contrib.auth',
|
@@ -146,6 +154,7 @@ __middlewares__ = [
|
|
146
154
|
'django.contrib.messages.middleware.MessageMiddleware',
|
147
155
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
148
156
|
django_toolbar_middleware, # OPTIONAL
|
157
|
+
django_allauth_middleware,
|
149
158
|
]
|
150
159
|
|
151
160
|
MIDDLEWARE = [middleware for middleware in __middlewares__ if middleware]
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = '1.75'
|
@@ -52,6 +52,10 @@ class TuxSuiteTest(TestCase):
|
|
52
52
|
"toolchain",
|
53
53
|
"does_not_exist"
|
54
54
|
],
|
55
|
+
"OEBUILD_METADATA_KEYS": [
|
56
|
+
"download_url",
|
57
|
+
"sources",
|
58
|
+
],
|
55
59
|
"TEST_METADATA_KEYS": [
|
56
60
|
"does_not_exist"
|
57
61
|
],
|
@@ -1041,3 +1045,87 @@ class TuxSuiteTest(TestCase):
|
|
1041
1045
|
returned_testjob = self.tuxsuite.process_callback(json.dumps(payload), self.build, self.environment.slug, self.backend)
|
1042
1046
|
self.assertEqual(testjob.id, returned_testjob.id)
|
1043
1047
|
self.assertEqual(json.dumps(payload["status"]), returned_testjob.input)
|
1048
|
+
|
1049
|
+
@patch("squad.ci.backend.tuxsuite.Backend.fetch_from_results_input")
|
1050
|
+
def test_fetch_oe_build_results(self, mock_fetch_from_results_input):
|
1051
|
+
job_id = 'OEBUILD:tuxgroup@tuxproject#123'
|
1052
|
+
testjob = self.build.test_jobs.create(target=self.project, backend=self.backend, job_id=job_id)
|
1053
|
+
build_url = urljoin(TUXSUITE_URL, '/groups/tuxgroup/projects/tuxproject/oebuilds/123')
|
1054
|
+
build_download_url = 'http://builds.tuxbuild.com/123'
|
1055
|
+
|
1056
|
+
# Only fetch when finished
|
1057
|
+
with requests_mock.Mocker() as fake_request:
|
1058
|
+
fake_request.get(build_url, json={'state': 'running'})
|
1059
|
+
results = self.tuxsuite.fetch(testjob)
|
1060
|
+
self.assertEqual(None, results)
|
1061
|
+
|
1062
|
+
build_logs = 'dummy build log'
|
1063
|
+
build_results = {
|
1064
|
+
"artifacts": [],
|
1065
|
+
"bblayers_conf": [],
|
1066
|
+
"container": "ubuntu-20.04",
|
1067
|
+
"download_url": build_download_url,
|
1068
|
+
"environment": {},
|
1069
|
+
"errors_count": 0,
|
1070
|
+
"extraconfigs": [],
|
1071
|
+
"is_canceling": False,
|
1072
|
+
"is_public": True,
|
1073
|
+
"local_conf": [],
|
1074
|
+
"name": "",
|
1075
|
+
"no_cache": False,
|
1076
|
+
"plan": "2UyDaiGYNeHEYPD7hGjuuqmgZIn",
|
1077
|
+
"project": "linaro/lkft",
|
1078
|
+
"provisioning_time": "2023-09-05T08:36:32.853409",
|
1079
|
+
"result": "pass",
|
1080
|
+
"sources": {
|
1081
|
+
"android": {
|
1082
|
+
"bazel": True,
|
1083
|
+
"branch": "common-android-mainline",
|
1084
|
+
"build_config": "//common:kernel_aarch64_dist",
|
1085
|
+
"manifest": "default.xml",
|
1086
|
+
"url": "https://android.googlesource.com/kernel/manifest"
|
1087
|
+
}
|
1088
|
+
},
|
1089
|
+
"state": "finished",
|
1090
|
+
"token_name": "lkft-android-bot",
|
1091
|
+
"uid": "2UyDaslU6koW0a85VVEh3Pc2LNW",
|
1092
|
+
"user": "lkft@linaro.org",
|
1093
|
+
"user_agent": "tuxsuite/1.25.1",
|
1094
|
+
"waited_by": [],
|
1095
|
+
"warnings_count": 0
|
1096
|
+
}
|
1097
|
+
|
1098
|
+
expected_metadata = {
|
1099
|
+
'download_url': build_download_url,
|
1100
|
+
'sources': {
|
1101
|
+
'android': {
|
1102
|
+
'bazel': True,
|
1103
|
+
'branch': 'common-android-mainline',
|
1104
|
+
'build_config': '//common:kernel_aarch64_dist',
|
1105
|
+
'manifest': 'default.xml',
|
1106
|
+
'url': 'https://android.googlesource.com/kernel/manifest'
|
1107
|
+
}
|
1108
|
+
},
|
1109
|
+
'job_url': build_url,
|
1110
|
+
'job_id': job_id,
|
1111
|
+
}
|
1112
|
+
|
1113
|
+
expected_tests = {
|
1114
|
+
'build/build': 'pass',
|
1115
|
+
}
|
1116
|
+
|
1117
|
+
expected_metrics = {}
|
1118
|
+
|
1119
|
+
with requests_mock.Mocker() as fake_request:
|
1120
|
+
fake_request.get(build_url, json=build_results)
|
1121
|
+
fake_request.get(urljoin(build_download_url, 'build.log'), text=build_logs)
|
1122
|
+
|
1123
|
+
status, completed, metadata, tests, metrics, logs = self.tuxsuite.fetch(testjob)
|
1124
|
+
self.assertEqual('Complete', status)
|
1125
|
+
self.assertTrue(completed)
|
1126
|
+
self.assertEqual(sorted(expected_metadata.items()), sorted(metadata.items()))
|
1127
|
+
self.assertEqual(sorted(expected_tests.items()), sorted(tests.items()))
|
1128
|
+
self.assertEqual(sorted(expected_metrics.items()), sorted(metrics.items()))
|
1129
|
+
self.assertEqual(build_logs, logs)
|
1130
|
+
|
1131
|
+
mock_fetch_from_results_input.assert_not_called()
|
@@ -10,6 +10,7 @@ from celery.exceptions import Retry
|
|
10
10
|
|
11
11
|
from squad.ci import models
|
12
12
|
from squad.core import models as core_models
|
13
|
+
from squad.core.tasks import ReceiveTestRun
|
13
14
|
from squad.ci.tasks import poll, fetch, submit
|
14
15
|
from squad.ci.utils import task_id
|
15
16
|
from squad.ci.exceptions import SubmissionIssue, TemporarySubmissionIssue
|
@@ -164,6 +165,85 @@ class FetchTestRaceCondition(TransactionTestCase):
|
|
164
165
|
self.assertEqual(1, fetch_method.call_count)
|
165
166
|
|
166
167
|
|
168
|
+
__sleeping__ = False
|
169
|
+
|
170
|
+
|
171
|
+
class FetchTestRaceConditionWaitAllJobsToBeFetched(TransactionTestCase):
|
172
|
+
"""
|
173
|
+
If another testjob for this build is finished, it'll trigger UpdateProjectStatus
|
174
|
+
which will invoke Build.finished and will see that all testjobs for this build
|
175
|
+
are finished. Except that if this current test job is still running plugins, like
|
176
|
+
VTS/CTS which take long time, the build will be considered to be finished
|
177
|
+
and finishing events will be triggered such as email reports and callbacks
|
178
|
+
"""
|
179
|
+
|
180
|
+
def setUp(self):
|
181
|
+
group = core_models.Group.objects.create(slug='test')
|
182
|
+
project = group.projects.create(slug='test')
|
183
|
+
self.build = project.builds.create(version='test-build')
|
184
|
+
backend = models.Backend.objects.create()
|
185
|
+
self.testjob1 = models.TestJob.objects.create(
|
186
|
+
backend=backend,
|
187
|
+
target=project,
|
188
|
+
target_build=self.build,
|
189
|
+
job_id='job-1',
|
190
|
+
)
|
191
|
+
self.testjob2 = models.TestJob.objects.create(
|
192
|
+
backend=backend,
|
193
|
+
target=project,
|
194
|
+
target_build=self.build,
|
195
|
+
job_id='job-2',
|
196
|
+
)
|
197
|
+
|
198
|
+
def mock_backend_fetch(test_job):
|
199
|
+
status = ''
|
200
|
+
completed = True
|
201
|
+
metadata = {}
|
202
|
+
tests = {}
|
203
|
+
metrics = {}
|
204
|
+
logs = ''
|
205
|
+
return status, completed, metadata, tests, metrics, logs
|
206
|
+
|
207
|
+
def mock_receive_testrun(target, update_project_status):
|
208
|
+
global __sleeping__
|
209
|
+
# Let's present job1 takes a bit longer
|
210
|
+
if __sleeping__ is False:
|
211
|
+
time.sleep(2)
|
212
|
+
__sleeping__ = True
|
213
|
+
return ReceiveTestRun(target, update_project_status=update_project_status)
|
214
|
+
|
215
|
+
@tag('skip_sqlite')
|
216
|
+
@patch('squad.ci.backend.null.Backend.job_url')
|
217
|
+
@patch('squad.ci.models.ReceiveTestRun', side_effect=mock_receive_testrun)
|
218
|
+
@patch('squad.ci.backend.null.Backend.fetch', side_effect=mock_backend_fetch)
|
219
|
+
def test_race_condition_on_fetch(self, fetch_method, mock_receive, mock_url):
|
220
|
+
mock_url.return_value = "job-url"
|
221
|
+
|
222
|
+
def thread(testjob_id):
|
223
|
+
fetch(testjob_id)
|
224
|
+
connection.close()
|
225
|
+
|
226
|
+
parallel_task_1 = threading.Thread(target=thread, args=(self.testjob1.id,))
|
227
|
+
parallel_task_2 = threading.Thread(target=thread, args=(self.testjob2.id,))
|
228
|
+
|
229
|
+
parallel_task_1.start()
|
230
|
+
parallel_task_2.start()
|
231
|
+
|
232
|
+
time.sleep(1)
|
233
|
+
|
234
|
+
self.testjob1.refresh_from_db()
|
235
|
+
self.testjob2.refresh_from_db()
|
236
|
+
|
237
|
+
finished, _ = self.build.finished
|
238
|
+
self.assertFalse(finished)
|
239
|
+
|
240
|
+
parallel_task_1.join()
|
241
|
+
parallel_task_2.join()
|
242
|
+
|
243
|
+
finished, _ = self.build.finished
|
244
|
+
self.assertTrue(finished)
|
245
|
+
|
246
|
+
|
167
247
|
class SubmitTest(TestCase):
|
168
248
|
|
169
249
|
def setUp(self):
|
@@ -293,6 +293,15 @@ class BuildTest(TestCase):
|
|
293
293
|
with patch('squad.core.models.Build.metadata', m):
|
294
294
|
self.assertEqual({'my key': 'my value'}, build.important_metadata)
|
295
295
|
|
296
|
+
def test_important_metadata_order(self):
|
297
|
+
project = Project(important_metadata_keys='key2\nkey1\nkey3\n')
|
298
|
+
build = Build(project=project)
|
299
|
+
|
300
|
+
m = {'key3': 'val3', 'key1': 'val1', 'key2': 'val2'}
|
301
|
+
with patch('squad.core.models.Build.metadata', m):
|
302
|
+
self.assertEqual({'key1': 'val1', 'key2': 'val2', 'key3': 'val3'}, build.important_metadata)
|
303
|
+
self.assertEqual(['key2', 'key1', 'key3'], list(build.important_metadata.keys()))
|
304
|
+
|
296
305
|
def test_metadata(self):
|
297
306
|
build = Build.objects.create(project=self.project, version='build-metadata')
|
298
307
|
env1 = self.project.environments.create(slug='env1')
|
@@ -2,12 +2,15 @@ import re
|
|
2
2
|
from django.test import TestCase
|
3
3
|
from django.test import Client
|
4
4
|
from django.contrib.auth.models import User
|
5
|
+
from django.utils import timezone
|
5
6
|
|
7
|
+
from dateutil.relativedelta import relativedelta
|
6
8
|
|
7
9
|
from squad.ci.models import Backend
|
8
10
|
from squad.core import models
|
9
11
|
from squad.core.tasks import ReceiveTestRun
|
10
12
|
from squad.core.tasks import cleanup_build
|
13
|
+
from squad.frontend.views import get_project_list
|
11
14
|
from test.performance import count_queries
|
12
15
|
|
13
16
|
|
@@ -281,6 +284,66 @@ class FrontendTest(TestCase):
|
|
281
284
|
self.assertEqual(404, response.status_code)
|
282
285
|
|
283
286
|
|
287
|
+
class FrontendTestProjectList(TestCase):
|
288
|
+
|
289
|
+
def setUp(self):
|
290
|
+
|
291
|
+
self.group = models.Group.objects.create(slug='mygroup')
|
292
|
+
self.two_day_old_project = self.group.projects.create(slug='two_day_old_project', datetime=timezone.now() - relativedelta(days=2))
|
293
|
+
self.ten_day_old_project = self.group.projects.create(slug='ten_day_old_project', datetime=timezone.now() - relativedelta(days=10))
|
294
|
+
self.thirty_day_old_project = self.group.projects.create(slug='thirty_day_old_project', datetime=timezone.now() - relativedelta(days=30))
|
295
|
+
self.user = User.objects.create(username='theuser')
|
296
|
+
self.group.add_admin(self.user)
|
297
|
+
|
298
|
+
self.client = Client()
|
299
|
+
self.client.force_login(self.user)
|
300
|
+
|
301
|
+
def test_get_project_list_show_projects_active_n_days_ago_some_projects(self):
|
302
|
+
# test that only the projects that are new enough are returned when
|
303
|
+
# SHOW_PROJECTS_ACTIVE_N_DAYS_AGO is provided
|
304
|
+
self.group.settings = "SHOW_PROJECTS_ACTIVE_N_DAYS_AGO: 3\nDEFAULT_PROJECT_COUNT: 2"
|
305
|
+
order_by = 'last_updated'
|
306
|
+
display_all_projects = False
|
307
|
+
|
308
|
+
projects = get_project_list(self.group, self.user, order_by, display_all_projects)
|
309
|
+
|
310
|
+
self.assertEqual(len(projects), 1)
|
311
|
+
|
312
|
+
def test_get_project_list_show_projects_active_n_days_ago_no_projects(self):
|
313
|
+
# test if there are no projects new enough when
|
314
|
+
# SHOW_PROJECTS_ACTIVE_N_DAYS_AGO is provided that
|
315
|
+
# DEFAULT_PROJECT_COUNT is used instead
|
316
|
+
self.group.settings = "SHOW_PROJECTS_ACTIVE_N_DAYS_AGO: 1\nDEFAULT_PROJECT_COUNT: 2"
|
317
|
+
order_by = 'last_updated'
|
318
|
+
display_all_projects = False
|
319
|
+
|
320
|
+
projects = get_project_list(self.group, self.user, order_by, display_all_projects)
|
321
|
+
|
322
|
+
self.assertEqual(len(projects), 2)
|
323
|
+
|
324
|
+
def test_get_project_list_show_projects_active_n_days_ago_only_no_projects(self):
|
325
|
+
# test case where SHOW_PROJECTS_ACTIVE_N_DAYS_AGO but no projects are
|
326
|
+
# new enough and DEFAULT_PROJECT_COUNT is not provided that all
|
327
|
+
# projects will be shown
|
328
|
+
self.group.settings = "SHOW_PROJECTS_ACTIVE_N_DAYS_AGO: 1"
|
329
|
+
order_by = 'last_updated'
|
330
|
+
display_all_projects = False
|
331
|
+
|
332
|
+
projects = get_project_list(self.group, self.user, order_by, display_all_projects)
|
333
|
+
|
334
|
+
self.assertEqual(len(projects), 3)
|
335
|
+
|
336
|
+
def test_get_project_list_no_parameters(self):
|
337
|
+
# test case where SHOW_PROJECTS_ACTIVE_N_DAYS_AGO and
|
338
|
+
# DEFAULT_PROJECT_COUNT are not provided - all projects should be shown
|
339
|
+
order_by = 'last_updated'
|
340
|
+
display_all_projects = False
|
341
|
+
|
342
|
+
projects = get_project_list(self.group, self.user, order_by, display_all_projects)
|
343
|
+
|
344
|
+
self.assertEqual(len(projects), 3)
|
345
|
+
|
346
|
+
|
284
347
|
class FrontendTestAnonymousUser(TestCase):
|
285
348
|
|
286
349
|
def setUp(self):
|
squad-1.74/squad/version.py
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
__version__ = '1.74'
|
{squad-1.74 → squad-1.75}/.ackrc
RENAMED
File without changes
|
File without changes
|
{squad-1.74 → squad-1.75}/.ctags
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|