cumulusci-plus 5.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cumulusci-plus might be problematic. Click here for more details.
- cumulusci/__about__.py +1 -0
- cumulusci/__init__.py +22 -0
- cumulusci/__main__.py +3 -0
- cumulusci/cli/__init__.py +0 -0
- cumulusci/cli/cci.py +244 -0
- cumulusci/cli/error.py +125 -0
- cumulusci/cli/flow.py +185 -0
- cumulusci/cli/logger.py +72 -0
- cumulusci/cli/org.py +692 -0
- cumulusci/cli/plan.py +181 -0
- cumulusci/cli/project.py +391 -0
- cumulusci/cli/robot.py +116 -0
- cumulusci/cli/runtime.py +190 -0
- cumulusci/cli/service.py +521 -0
- cumulusci/cli/task.py +295 -0
- cumulusci/cli/tests/__init__.py +0 -0
- cumulusci/cli/tests/test_cci.py +545 -0
- cumulusci/cli/tests/test_error.py +170 -0
- cumulusci/cli/tests/test_flow.py +276 -0
- cumulusci/cli/tests/test_logger.py +25 -0
- cumulusci/cli/tests/test_org.py +1438 -0
- cumulusci/cli/tests/test_plan.py +245 -0
- cumulusci/cli/tests/test_project.py +235 -0
- cumulusci/cli/tests/test_robot.py +177 -0
- cumulusci/cli/tests/test_runtime.py +197 -0
- cumulusci/cli/tests/test_service.py +853 -0
- cumulusci/cli/tests/test_task.py +266 -0
- cumulusci/cli/tests/test_ui.py +310 -0
- cumulusci/cli/tests/test_utils.py +122 -0
- cumulusci/cli/tests/utils.py +52 -0
- cumulusci/cli/ui.py +234 -0
- cumulusci/cli/utils.py +150 -0
- cumulusci/conftest.py +181 -0
- cumulusci/core/__init__.py +0 -0
- cumulusci/core/config/BaseConfig.py +5 -0
- cumulusci/core/config/BaseTaskFlowConfig.py +5 -0
- cumulusci/core/config/OrgConfig.py +5 -0
- cumulusci/core/config/ScratchOrgConfig.py +5 -0
- cumulusci/core/config/__init__.py +125 -0
- cumulusci/core/config/base_config.py +111 -0
- cumulusci/core/config/base_task_flow_config.py +82 -0
- cumulusci/core/config/marketing_cloud_service_config.py +83 -0
- cumulusci/core/config/oauth2_service_config.py +17 -0
- cumulusci/core/config/org_config.py +604 -0
- cumulusci/core/config/project_config.py +782 -0
- cumulusci/core/config/scratch_org_config.py +251 -0
- cumulusci/core/config/sfdx_org_config.py +220 -0
- cumulusci/core/config/tests/_test_config_backwards_compatibility.py +33 -0
- cumulusci/core/config/tests/test_config.py +1895 -0
- cumulusci/core/config/tests/test_config_expensive.py +839 -0
- cumulusci/core/config/tests/test_config_util.py +91 -0
- cumulusci/core/config/universal_config.py +88 -0
- cumulusci/core/config/util.py +18 -0
- cumulusci/core/datasets.py +303 -0
- cumulusci/core/debug.py +33 -0
- cumulusci/core/dependencies/__init__.py +55 -0
- cumulusci/core/dependencies/base.py +561 -0
- cumulusci/core/dependencies/dependencies.py +273 -0
- cumulusci/core/dependencies/github.py +177 -0
- cumulusci/core/dependencies/github_resolvers.py +244 -0
- cumulusci/core/dependencies/resolvers.py +580 -0
- cumulusci/core/dependencies/tests/__init__.py +0 -0
- cumulusci/core/dependencies/tests/conftest.py +385 -0
- cumulusci/core/dependencies/tests/test_dependencies.py +950 -0
- cumulusci/core/dependencies/tests/test_github.py +83 -0
- cumulusci/core/dependencies/tests/test_resolvers.py +1027 -0
- cumulusci/core/dependencies/utils.py +13 -0
- cumulusci/core/enums.py +11 -0
- cumulusci/core/exceptions.py +311 -0
- cumulusci/core/flowrunner.py +888 -0
- cumulusci/core/github.py +665 -0
- cumulusci/core/keychain/__init__.py +24 -0
- cumulusci/core/keychain/base_project_keychain.py +441 -0
- cumulusci/core/keychain/encrypted_file_project_keychain.py +945 -0
- cumulusci/core/keychain/environment_project_keychain.py +7 -0
- cumulusci/core/keychain/serialization.py +152 -0
- cumulusci/core/keychain/subprocess_keychain.py +24 -0
- cumulusci/core/keychain/tests/conftest.py +50 -0
- cumulusci/core/keychain/tests/test_base_project_keychain.py +299 -0
- cumulusci/core/keychain/tests/test_encrypted_file_project_keychain.py +1228 -0
- cumulusci/core/metadeploy/__init__.py +0 -0
- cumulusci/core/metadeploy/api.py +88 -0
- cumulusci/core/metadeploy/plans.py +25 -0
- cumulusci/core/metadeploy/tests/test_api.py +276 -0
- cumulusci/core/runtime.py +115 -0
- cumulusci/core/sfdx.py +162 -0
- cumulusci/core/source/__init__.py +16 -0
- cumulusci/core/source/github.py +50 -0
- cumulusci/core/source/local_folder.py +35 -0
- cumulusci/core/source_transforms/__init__.py +0 -0
- cumulusci/core/source_transforms/tests/test_transforms.py +1091 -0
- cumulusci/core/source_transforms/transforms.py +532 -0
- cumulusci/core/tasks.py +404 -0
- cumulusci/core/template_utils.py +59 -0
- cumulusci/core/tests/__init__.py +0 -0
- cumulusci/core/tests/cassettes/TestDatasetsE2E.test_datasets_e2e.yaml +215 -0
- cumulusci/core/tests/cassettes/TestDatasetsE2E.test_datasets_extract_standard_objects.yaml +199 -0
- cumulusci/core/tests/cassettes/TestDatasetsE2E.test_datasets_read_explicit_extract_declaration.yaml +3 -0
- cumulusci/core/tests/fake_remote_repo/cumulusci.yml +32 -0
- cumulusci/core/tests/fake_remote_repo/tasks/directory/example_2.py +6 -0
- cumulusci/core/tests/fake_remote_repo/tasks/example.py +43 -0
- cumulusci/core/tests/fake_remote_repo_2/cumulusci.yml +11 -0
- cumulusci/core/tests/fake_remote_repo_2/tasks/example_3.py +6 -0
- cumulusci/core/tests/test_datasets_e2e.py +386 -0
- cumulusci/core/tests/test_exceptions.py +11 -0
- cumulusci/core/tests/test_flowrunner.py +836 -0
- cumulusci/core/tests/test_github.py +942 -0
- cumulusci/core/tests/test_sfdx.py +138 -0
- cumulusci/core/tests/test_source.py +678 -0
- cumulusci/core/tests/test_tasks.py +262 -0
- cumulusci/core/tests/test_utils.py +141 -0
- cumulusci/core/tests/test_utils_merge_config.py +276 -0
- cumulusci/core/tests/test_versions.py +76 -0
- cumulusci/core/tests/untrusted_repo_child/cumulusci.yml +7 -0
- cumulusci/core/tests/untrusted_repo_child/tasks/untrusted_child.py +6 -0
- cumulusci/core/tests/untrusted_repo_parent/cumulusci.yml +26 -0
- cumulusci/core/tests/untrusted_repo_parent/tasks/untrusted_parent.py +6 -0
- cumulusci/core/tests/utils.py +116 -0
- cumulusci/core/tests/yaml/global.yaml +0 -0
- cumulusci/core/utils.py +402 -0
- cumulusci/core/versions.py +149 -0
- cumulusci/cumulusci.yml +1621 -0
- cumulusci/files/admin_profile.xml +20 -0
- cumulusci/files/delete_excludes.txt +424 -0
- cumulusci/files/templates/project/README.md +12 -0
- cumulusci/files/templates/project/cumulusci.yml +63 -0
- cumulusci/files/templates/project/dot-gitignore +60 -0
- cumulusci/files/templates/project/mapping.yml +45 -0
- cumulusci/files/templates/project/scratch_def.json +25 -0
- cumulusci/oauth/__init__.py +0 -0
- cumulusci/oauth/client.py +400 -0
- cumulusci/oauth/exceptions.py +9 -0
- cumulusci/oauth/salesforce.py +95 -0
- cumulusci/oauth/tests/__init__.py +0 -0
- cumulusci/oauth/tests/cassettes/test_get_device_code.yaml +22 -0
- cumulusci/oauth/tests/cassettes/test_get_device_oauth_token.yaml +74 -0
- cumulusci/oauth/tests/test_client.py +308 -0
- cumulusci/oauth/tests/test_salesforce.py +46 -0
- cumulusci/plugins/__init__.py +3 -0
- cumulusci/plugins/plugin_base.py +93 -0
- cumulusci/plugins/plugin_loader.py +59 -0
- cumulusci/robotframework/CumulusCI.py +340 -0
- cumulusci/robotframework/CumulusCI.robot +7 -0
- cumulusci/robotframework/Performance.py +165 -0
- cumulusci/robotframework/Salesforce.py +936 -0
- cumulusci/robotframework/Salesforce.robot +192 -0
- cumulusci/robotframework/SalesforceAPI.py +416 -0
- cumulusci/robotframework/SalesforcePlaywright.py +220 -0
- cumulusci/robotframework/SalesforcePlaywright.robot +40 -0
- cumulusci/robotframework/__init__.py +2 -0
- cumulusci/robotframework/base_library.py +39 -0
- cumulusci/robotframework/faker_mixin.py +89 -0
- cumulusci/robotframework/form_handlers.py +222 -0
- cumulusci/robotframework/javascript/cci_init.js +34 -0
- cumulusci/robotframework/javascript/cumulusci.js +4 -0
- cumulusci/robotframework/locator_manager.py +197 -0
- cumulusci/robotframework/locators_56.py +88 -0
- cumulusci/robotframework/locators_57.py +5 -0
- cumulusci/robotframework/pageobjects/BasePageObjects.py +433 -0
- cumulusci/robotframework/pageobjects/ObjectManagerPageObject.py +246 -0
- cumulusci/robotframework/pageobjects/PageObjectLibrary.py +45 -0
- cumulusci/robotframework/pageobjects/PageObjects.py +351 -0
- cumulusci/robotframework/pageobjects/__init__.py +12 -0
- cumulusci/robotframework/pageobjects/baseobjects.py +120 -0
- cumulusci/robotframework/perftests/short/collection_perf.robot +105 -0
- cumulusci/robotframework/tests/CustomObjectTestPage.py +10 -0
- cumulusci/robotframework/tests/FooTestPage.py +8 -0
- cumulusci/robotframework/tests/cumulusci/base.robot +40 -0
- cumulusci/robotframework/tests/cumulusci/bulkdata.robot +38 -0
- cumulusci/robotframework/tests/cumulusci/communities.robot +57 -0
- cumulusci/robotframework/tests/cumulusci/datagen.robot +84 -0
- cumulusci/robotframework/tests/salesforce/TestLibraryA.py +24 -0
- cumulusci/robotframework/tests/salesforce/TestLibraryB.py +20 -0
- cumulusci/robotframework/tests/salesforce/TestListener.py +93 -0
- cumulusci/robotframework/tests/salesforce/api.robot +178 -0
- cumulusci/robotframework/tests/salesforce/browsers.robot +143 -0
- cumulusci/robotframework/tests/salesforce/classic.robot +51 -0
- cumulusci/robotframework/tests/salesforce/create_contact.robot +59 -0
- cumulusci/robotframework/tests/salesforce/faker.robot +68 -0
- cumulusci/robotframework/tests/salesforce/forms.robot +172 -0
- cumulusci/robotframework/tests/salesforce/label_locator.robot +244 -0
- cumulusci/robotframework/tests/salesforce/labels.html +33 -0
- cumulusci/robotframework/tests/salesforce/locators.robot +149 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/base_pageobjects.robot +100 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/example_page_object.py +25 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/listing_page.robot +115 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/objectmanager.robot +74 -0
- cumulusci/robotframework/tests/salesforce/pageobjects/pageobjects.robot +171 -0
- cumulusci/robotframework/tests/salesforce/performance.robot +109 -0
- cumulusci/robotframework/tests/salesforce/playwright/javascript_keywords.robot +33 -0
- cumulusci/robotframework/tests/salesforce/playwright/open_test_browser.robot +48 -0
- cumulusci/robotframework/tests/salesforce/playwright/playwright.robot +24 -0
- cumulusci/robotframework/tests/salesforce/playwright/ui.robot +32 -0
- cumulusci/robotframework/tests/salesforce/populate.robot +89 -0
- cumulusci/robotframework/tests/salesforce/test_testlistener.py +37 -0
- cumulusci/robotframework/tests/salesforce/ui.robot +361 -0
- cumulusci/robotframework/tests/test_cumulusci_library.py +304 -0
- cumulusci/robotframework/tests/test_locator_manager.py +158 -0
- cumulusci/robotframework/tests/test_pageobjects.py +291 -0
- cumulusci/robotframework/tests/test_performance.py +38 -0
- cumulusci/robotframework/tests/test_salesforce.py +79 -0
- cumulusci/robotframework/tests/test_salesforce_locators.py +73 -0
- cumulusci/robotframework/tests/test_template_util.py +53 -0
- cumulusci/robotframework/tests/test_utils.py +106 -0
- cumulusci/robotframework/utils.py +283 -0
- cumulusci/salesforce_api/__init__.py +0 -0
- cumulusci/salesforce_api/exceptions.py +23 -0
- cumulusci/salesforce_api/filterable_objects.py +96 -0
- cumulusci/salesforce_api/mc_soap_envelopes.py +89 -0
- cumulusci/salesforce_api/metadata.py +721 -0
- cumulusci/salesforce_api/org_schema.py +571 -0
- cumulusci/salesforce_api/org_schema_models.py +226 -0
- cumulusci/salesforce_api/package_install.py +265 -0
- cumulusci/salesforce_api/package_zip.py +301 -0
- cumulusci/salesforce_api/rest_deploy.py +148 -0
- cumulusci/salesforce_api/retrieve_profile_api.py +301 -0
- cumulusci/salesforce_api/soap_envelopes.py +177 -0
- cumulusci/salesforce_api/tests/__init__.py +0 -0
- cumulusci/salesforce_api/tests/metadata_test_strings.py +24 -0
- cumulusci/salesforce_api/tests/test_metadata.py +1015 -0
- cumulusci/salesforce_api/tests/test_package_install.py +219 -0
- cumulusci/salesforce_api/tests/test_package_zip.py +380 -0
- cumulusci/salesforce_api/tests/test_rest_deploy.py +264 -0
- cumulusci/salesforce_api/tests/test_retrieve_profile_api.py +337 -0
- cumulusci/salesforce_api/tests/test_utils.py +124 -0
- cumulusci/salesforce_api/utils.py +51 -0
- cumulusci/schema/cumulusci.jsonschema.json +782 -0
- cumulusci/tasks/__init__.py +0 -0
- cumulusci/tasks/apex/__init__.py +0 -0
- cumulusci/tasks/apex/anon.py +157 -0
- cumulusci/tasks/apex/batch.py +180 -0
- cumulusci/tasks/apex/testrunner.py +835 -0
- cumulusci/tasks/apex/tests/cassettes/ManualEditTestApexIntegrationTests.test_run_tests__integration_test.yaml +703 -0
- cumulusci/tasks/apex/tests/test_apex_tasks.py +1558 -0
- cumulusci/tasks/base_source_control_task.py +17 -0
- cumulusci/tasks/bulkdata/__init__.py +15 -0
- cumulusci/tasks/bulkdata/base_generate_data_task.py +96 -0
- cumulusci/tasks/bulkdata/dates.py +97 -0
- cumulusci/tasks/bulkdata/delete.py +156 -0
- cumulusci/tasks/bulkdata/extract.py +441 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/calculate_dependencies.py +117 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/extract_yml.py +123 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/hardcoded_default_declarations.py +49 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/synthesize_extract_declarations.py +283 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/tests/test_extract_yml.py +142 -0
- cumulusci/tasks/bulkdata/extract_dataset_utils/tests/test_synthesize_extract_declarations.py +575 -0
- cumulusci/tasks/bulkdata/factory_utils.py +134 -0
- cumulusci/tasks/bulkdata/generate.py +4 -0
- cumulusci/tasks/bulkdata/generate_and_load_data.py +232 -0
- cumulusci/tasks/bulkdata/generate_and_load_data_from_yaml.py +19 -0
- cumulusci/tasks/bulkdata/generate_from_yaml.py +183 -0
- cumulusci/tasks/bulkdata/generate_mapping.py +434 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/dependency_map.py +169 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/extract_mapping_file_generator.py +45 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/generate_mapping_from_declarations.py +121 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/load_mapping_file_generator.py +127 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/mapping_generator_post_processes.py +53 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/mapping_transforms.py +139 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_generate_extract_mapping_from_declarations.py +135 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_generate_load_mapping_from_declarations.py +330 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_mapping_generator_post_processes.py +60 -0
- cumulusci/tasks/bulkdata/generate_mapping_utils/tests/test_mapping_transforms.py +188 -0
- cumulusci/tasks/bulkdata/load.py +1196 -0
- cumulusci/tasks/bulkdata/mapping_parser.py +811 -0
- cumulusci/tasks/bulkdata/query_transformers.py +264 -0
- cumulusci/tasks/bulkdata/select_utils.py +792 -0
- cumulusci/tasks/bulkdata/snowfakery.py +753 -0
- cumulusci/tasks/bulkdata/snowfakery_utils/queue_manager.py +478 -0
- cumulusci/tasks/bulkdata/snowfakery_utils/snowfakery_run_until.py +141 -0
- cumulusci/tasks/bulkdata/snowfakery_utils/snowfakery_working_directory.py +53 -0
- cumulusci/tasks/bulkdata/snowfakery_utils/subtask_configurator.py +64 -0
- cumulusci/tasks/bulkdata/step.py +1242 -0
- cumulusci/tasks/bulkdata/tests/__init__.py +0 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_random_strategy.yaml +147 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_annoy_strategy.yaml +123 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_select_and_insert_strategy.yaml +313 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_select_and_insert_strategy_bulk.yaml +550 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_similarity_strategy.yaml +175 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSelect.test_select_standard_strategy.yaml +147 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_run_until_records_in_org__multiple_needed.yaml +69 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_run_until_records_in_org__none_needed.yaml +22 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_run_until_records_in_org__one_needed.yaml +24 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestSnowfakery.test_snowfakery_query_salesforce.yaml +25 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpdatesIntegrationTests.test_updates_task.yaml +80 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_simple_upsert__rest.yaml +270 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert__rest.yaml +267 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert_complex_external_id_field__rest.yaml +369 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert_complex_external_id_field_rest__duplicate_error.yaml +204 -0
- cumulusci/tasks/bulkdata/tests/cassettes/TestUpsert.test_upsert_complex_fields__bulk.yaml +675 -0
- cumulusci/tasks/bulkdata/tests/dummy_data_factory.py +36 -0
- cumulusci/tasks/bulkdata/tests/integration_test_utils.py +49 -0
- cumulusci/tasks/bulkdata/tests/mapping-oid.yml +87 -0
- cumulusci/tasks/bulkdata/tests/mapping_after.yml +38 -0
- cumulusci/tasks/bulkdata/tests/mapping_poly.yml +34 -0
- cumulusci/tasks/bulkdata/tests/mapping_poly_incomplete.yml +20 -0
- cumulusci/tasks/bulkdata/tests/mapping_poly_wrong.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_select.yml +20 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_invalid_strategy.yml +20 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_invalid_threshold__invalid_number.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_invalid_threshold__invalid_strategy.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_invalid_threshold__non_float.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_missing_priority_fields.yml +22 -0
- cumulusci/tasks/bulkdata/tests/mapping_select_no_priority_fields.yml +18 -0
- cumulusci/tasks/bulkdata/tests/mapping_simple.yml +27 -0
- cumulusci/tasks/bulkdata/tests/mapping_v1.yml +28 -0
- cumulusci/tasks/bulkdata/tests/mapping_v2.yml +21 -0
- cumulusci/tasks/bulkdata/tests/mapping_v3.yml +32 -0
- cumulusci/tasks/bulkdata/tests/mapping_vanilla_sf.yml +69 -0
- cumulusci/tasks/bulkdata/tests/mock_data_factory_without_mapping.py +12 -0
- cumulusci/tasks/bulkdata/tests/person_accounts.yml +23 -0
- cumulusci/tasks/bulkdata/tests/person_accounts_minimal.yml +15 -0
- cumulusci/tasks/bulkdata/tests/recordtypes.yml +8 -0
- cumulusci/tasks/bulkdata/tests/recordtypes_2.yml +6 -0
- cumulusci/tasks/bulkdata/tests/recordtypes_with_ispersontype.yml +8 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/child/child2.yml +3 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/child.yml +4 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/gen_npsp_standard_objects.recipe.yml +89 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/include_parent.yml +3 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/npsp_standard_objects_macros.yml +34 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/options.recipe.yml +6 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/query_snowfakery.recipe.yml +16 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/sf_standard_object_macros.yml +83 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery.load.yml +2 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery.recipe.yml +13 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_2.load.yml +5 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_channels.load.yml +13 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_channels.recipe.yml +12 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/simple_snowfakery_channels_2.load.yml +13 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/unique_values.recipe.yml +4 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/upsert.recipe.yml +23 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/upsert_2.recipe.yml +29 -0
- cumulusci/tasks/bulkdata/tests/snowfakery/upsert_before.yml +10 -0
- cumulusci/tasks/bulkdata/tests/test_base_generate_data_tasks.py +61 -0
- cumulusci/tasks/bulkdata/tests/test_dates.py +99 -0
- cumulusci/tasks/bulkdata/tests/test_delete.py +404 -0
- cumulusci/tasks/bulkdata/tests/test_extract.py +1311 -0
- cumulusci/tasks/bulkdata/tests/test_factory_utils.py +55 -0
- cumulusci/tasks/bulkdata/tests/test_generate_and_load.py +252 -0
- cumulusci/tasks/bulkdata/tests/test_generate_from_snowfakery_task.py +343 -0
- cumulusci/tasks/bulkdata/tests/test_generatemapping.py +1039 -0
- cumulusci/tasks/bulkdata/tests/test_load.py +3175 -0
- cumulusci/tasks/bulkdata/tests/test_mapping_parser.py +1658 -0
- cumulusci/tasks/bulkdata/tests/test_query_db__joins_self_lookups.yml +12 -0
- cumulusci/tasks/bulkdata/tests/test_query_db_joins_lookups.yml +26 -0
- cumulusci/tasks/bulkdata/tests/test_query_db_joins_lookups_select.yml +48 -0
- cumulusci/tasks/bulkdata/tests/test_select.py +171 -0
- cumulusci/tasks/bulkdata/tests/test_select_utils.py +1057 -0
- cumulusci/tasks/bulkdata/tests/test_snowfakery.py +1153 -0
- cumulusci/tasks/bulkdata/tests/test_step.py +3957 -0
- cumulusci/tasks/bulkdata/tests/test_updates.py +513 -0
- cumulusci/tasks/bulkdata/tests/test_upsert.py +1015 -0
- cumulusci/tasks/bulkdata/tests/test_utils.py +158 -0
- cumulusci/tasks/bulkdata/tests/testdata.db +0 -0
- cumulusci/tasks/bulkdata/tests/update_describe.py +50 -0
- cumulusci/tasks/bulkdata/tests/update_person_accounts.yml +23 -0
- cumulusci/tasks/bulkdata/tests/utils.py +114 -0
- cumulusci/tasks/bulkdata/update_data.py +260 -0
- cumulusci/tasks/bulkdata/upsert_utils.py +130 -0
- cumulusci/tasks/bulkdata/utils.py +249 -0
- cumulusci/tasks/command.py +178 -0
- cumulusci/tasks/connectedapp.py +186 -0
- cumulusci/tasks/create_package_version.py +778 -0
- cumulusci/tasks/datadictionary.py +745 -0
- cumulusci/tasks/dx_convert_from.py +26 -0
- cumulusci/tasks/github/__init__.py +17 -0
- cumulusci/tasks/github/base.py +16 -0
- cumulusci/tasks/github/commit_status.py +13 -0
- cumulusci/tasks/github/merge.py +11 -0
- cumulusci/tasks/github/publish.py +11 -0
- cumulusci/tasks/github/pull_request.py +11 -0
- cumulusci/tasks/github/release.py +11 -0
- cumulusci/tasks/github/release_report.py +11 -0
- cumulusci/tasks/github/tag.py +11 -0
- cumulusci/tasks/github/tests/__init__.py +0 -0
- cumulusci/tasks/github/tests/test_util.py +202 -0
- cumulusci/tasks/github/tests/test_vcs_migration.py +44 -0
- cumulusci/tasks/github/tests/util_github_api.py +666 -0
- cumulusci/tasks/github/util.py +252 -0
- cumulusci/tasks/marketing_cloud/__init__.py +0 -0
- cumulusci/tasks/marketing_cloud/api.py +188 -0
- cumulusci/tasks/marketing_cloud/base.py +38 -0
- cumulusci/tasks/marketing_cloud/deploy.py +345 -0
- cumulusci/tasks/marketing_cloud/get_user_info.py +40 -0
- cumulusci/tasks/marketing_cloud/mc_constants.py +1 -0
- cumulusci/tasks/marketing_cloud/tests/__init__.py +0 -0
- cumulusci/tasks/marketing_cloud/tests/conftest.py +46 -0
- cumulusci/tasks/marketing_cloud/tests/expected-payload.json +110 -0
- cumulusci/tasks/marketing_cloud/tests/test_api.py +97 -0
- cumulusci/tasks/marketing_cloud/tests/test_api_soap_envelopes.py +145 -0
- cumulusci/tasks/marketing_cloud/tests/test_base.py +14 -0
- cumulusci/tasks/marketing_cloud/tests/test_deploy.py +400 -0
- cumulusci/tasks/marketing_cloud/tests/test_get_user_info.py +141 -0
- cumulusci/tasks/marketing_cloud/tests/validation-response.json +39 -0
- cumulusci/tasks/metadata/__init__.py +0 -0
- cumulusci/tasks/metadata/ee_src.py +94 -0
- cumulusci/tasks/metadata/managed_src.py +100 -0
- cumulusci/tasks/metadata/metadata_map.yml +868 -0
- cumulusci/tasks/metadata/modify.py +99 -0
- cumulusci/tasks/metadata/package.py +684 -0
- cumulusci/tasks/metadata/tests/__init__.py +0 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/.hidden/.keep +0 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/destructiveChanges.xml +9 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/package.xml +9 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/package_install_uninstall.xml +11 -0
- cumulusci/tasks/metadata/tests/package_metadata/namespaced_report_folder/reports/namespace__TestFolder/TestReport.report +3 -0
- cumulusci/tasks/metadata/tests/sample_package.xml +9 -0
- cumulusci/tasks/metadata/tests/test_ee_src.py +112 -0
- cumulusci/tasks/metadata/tests/test_managed_src.py +111 -0
- cumulusci/tasks/metadata/tests/test_modify.py +123 -0
- cumulusci/tasks/metadata/tests/test_package.py +476 -0
- cumulusci/tasks/metadata_etl/__init__.py +29 -0
- cumulusci/tasks/metadata_etl/base.py +436 -0
- cumulusci/tasks/metadata_etl/duplicate_rules.py +24 -0
- cumulusci/tasks/metadata_etl/field_sets.py +70 -0
- cumulusci/tasks/metadata_etl/help_text.py +92 -0
- cumulusci/tasks/metadata_etl/layouts.py +550 -0
- cumulusci/tasks/metadata_etl/objects.py +68 -0
- cumulusci/tasks/metadata_etl/permissions.py +167 -0
- cumulusci/tasks/metadata_etl/picklists.py +221 -0
- cumulusci/tasks/metadata_etl/remote_site_settings.py +99 -0
- cumulusci/tasks/metadata_etl/sharing.py +138 -0
- cumulusci/tasks/metadata_etl/tests/test_base.py +512 -0
- cumulusci/tasks/metadata_etl/tests/test_duplicate_rules.py +22 -0
- cumulusci/tasks/metadata_etl/tests/test_field_sets.py +156 -0
- cumulusci/tasks/metadata_etl/tests/test_help_text.py +387 -0
- cumulusci/tasks/metadata_etl/tests/test_ip_ranges.py +85 -0
- cumulusci/tasks/metadata_etl/tests/test_layouts.py +858 -0
- cumulusci/tasks/metadata_etl/tests/test_objects.py +236 -0
- cumulusci/tasks/metadata_etl/tests/test_permissions.py +223 -0
- cumulusci/tasks/metadata_etl/tests/test_picklists.py +547 -0
- cumulusci/tasks/metadata_etl/tests/test_remote_site_settings.py +46 -0
- cumulusci/tasks/metadata_etl/tests/test_sharing.py +333 -0
- cumulusci/tasks/metadata_etl/tests/test_value_sets.py +298 -0
- cumulusci/tasks/metadata_etl/value_sets.py +106 -0
- cumulusci/tasks/metadeploy.py +393 -0
- cumulusci/tasks/metaxml.py +88 -0
- cumulusci/tasks/preflight/__init__.py +0 -0
- cumulusci/tasks/preflight/dataset_load.py +49 -0
- cumulusci/tasks/preflight/licenses.py +86 -0
- cumulusci/tasks/preflight/packages.py +14 -0
- cumulusci/tasks/preflight/permsets.py +23 -0
- cumulusci/tasks/preflight/recordtypes.py +16 -0
- cumulusci/tasks/preflight/retrieve_tasks.py +30 -0
- cumulusci/tasks/preflight/settings.py +77 -0
- cumulusci/tasks/preflight/sobjects.py +202 -0
- cumulusci/tasks/preflight/tests/test_dataset_load.py +85 -0
- cumulusci/tasks/preflight/tests/test_licenses.py +174 -0
- cumulusci/tasks/preflight/tests/test_packages.py +14 -0
- cumulusci/tasks/preflight/tests/test_permset_preflights.py +51 -0
- cumulusci/tasks/preflight/tests/test_recordtypes.py +30 -0
- cumulusci/tasks/preflight/tests/test_retrieve_tasks.py +62 -0
- cumulusci/tasks/preflight/tests/test_settings.py +130 -0
- cumulusci/tasks/preflight/tests/test_sobjects.py +231 -0
- cumulusci/tasks/push/README.md +59 -0
- cumulusci/tasks/push/__init__.py +0 -0
- cumulusci/tasks/push/push_api.py +659 -0
- cumulusci/tasks/push/pushfails.py +136 -0
- cumulusci/tasks/push/tasks.py +476 -0
- cumulusci/tasks/push/tests/conftest.py +263 -0
- cumulusci/tasks/push/tests/test_push_api.py +951 -0
- cumulusci/tasks/push/tests/test_push_tasks.py +659 -0
- cumulusci/tasks/release_notes/README.md +63 -0
- cumulusci/tasks/release_notes/__init__.py +0 -0
- cumulusci/tasks/release_notes/exceptions.py +5 -0
- cumulusci/tasks/release_notes/generator.py +137 -0
- cumulusci/tasks/release_notes/parser.py +232 -0
- cumulusci/tasks/release_notes/provider.py +44 -0
- cumulusci/tasks/release_notes/task.py +300 -0
- cumulusci/tasks/release_notes/tests/__init__.py +0 -0
- cumulusci/tasks/release_notes/tests/change_notes/full/example1.md +17 -0
- cumulusci/tasks/release_notes/tests/change_notes/multi/1.txt +1 -0
- cumulusci/tasks/release_notes/tests/change_notes/multi/2.txt +1 -0
- cumulusci/tasks/release_notes/tests/change_notes/multi/3.txt +1 -0
- cumulusci/tasks/release_notes/tests/change_notes/single/1.txt +1 -0
- cumulusci/tasks/release_notes/tests/test_generator.py +582 -0
- cumulusci/tasks/release_notes/tests/test_parser.py +867 -0
- cumulusci/tasks/release_notes/tests/test_provider.py +512 -0
- cumulusci/tasks/release_notes/tests/test_task.py +461 -0
- cumulusci/tasks/release_notes/tests/utils.py +153 -0
- cumulusci/tasks/robotframework/__init__.py +3 -0
- cumulusci/tasks/robotframework/debugger/DebugListener.py +100 -0
- cumulusci/tasks/robotframework/debugger/__init__.py +10 -0
- cumulusci/tasks/robotframework/debugger/model.py +87 -0
- cumulusci/tasks/robotframework/debugger/ui.py +259 -0
- cumulusci/tasks/robotframework/libdoc.py +269 -0
- cumulusci/tasks/robotframework/robotframework.py +392 -0
- cumulusci/tasks/robotframework/stylesheet.css +130 -0
- cumulusci/tasks/robotframework/template.html +109 -0
- cumulusci/tasks/robotframework/tests/TestLibrary.py +18 -0
- cumulusci/tasks/robotframework/tests/TestPageObjects.py +31 -0
- cumulusci/tasks/robotframework/tests/TestResource.robot +8 -0
- cumulusci/tasks/robotframework/tests/failing_tests.robot +16 -0
- cumulusci/tasks/robotframework/tests/performance.robot +23 -0
- cumulusci/tasks/robotframework/tests/test_browser_proxies.py +137 -0
- cumulusci/tasks/robotframework/tests/test_debugger.py +360 -0
- cumulusci/tasks/robotframework/tests/test_robot_parallel.py +141 -0
- cumulusci/tasks/robotframework/tests/test_robotframework.py +860 -0
- cumulusci/tasks/salesforce/BaseRetrieveMetadata.py +58 -0
- cumulusci/tasks/salesforce/BaseSalesforceApiTask.py +45 -0
- cumulusci/tasks/salesforce/BaseSalesforceMetadataApiTask.py +18 -0
- cumulusci/tasks/salesforce/BaseSalesforceTask.py +4 -0
- cumulusci/tasks/salesforce/BaseUninstallMetadata.py +41 -0
- cumulusci/tasks/salesforce/CreateCommunity.py +124 -0
- cumulusci/tasks/salesforce/CreatePackage.py +29 -0
- cumulusci/tasks/salesforce/Deploy.py +240 -0
- cumulusci/tasks/salesforce/DeployBundles.py +88 -0
- cumulusci/tasks/salesforce/DescribeMetadataTypes.py +26 -0
- cumulusci/tasks/salesforce/EnsureRecordTypes.py +202 -0
- cumulusci/tasks/salesforce/GetInstalledPackages.py +8 -0
- cumulusci/tasks/salesforce/ListCommunities.py +40 -0
- cumulusci/tasks/salesforce/ListCommunityTemplates.py +19 -0
- cumulusci/tasks/salesforce/PublishCommunity.py +62 -0
- cumulusci/tasks/salesforce/RetrievePackaged.py +41 -0
- cumulusci/tasks/salesforce/RetrieveReportsAndDashboards.py +82 -0
- cumulusci/tasks/salesforce/RetrieveUnpackaged.py +36 -0
- cumulusci/tasks/salesforce/SOQLQuery.py +39 -0
- cumulusci/tasks/salesforce/UninstallLocal.py +15 -0
- cumulusci/tasks/salesforce/UninstallLocalBundles.py +28 -0
- cumulusci/tasks/salesforce/UninstallLocalNamespacedBundles.py +58 -0
- cumulusci/tasks/salesforce/UninstallPackage.py +32 -0
- cumulusci/tasks/salesforce/UninstallPackaged.py +56 -0
- cumulusci/tasks/salesforce/UpdateAdminProfile.py +8 -0
- cumulusci/tasks/salesforce/__init__.py +79 -0
- cumulusci/tasks/salesforce/activate_flow.py +74 -0
- cumulusci/tasks/salesforce/check_components.py +324 -0
- cumulusci/tasks/salesforce/composite.py +142 -0
- cumulusci/tasks/salesforce/create_permission_sets.py +35 -0
- cumulusci/tasks/salesforce/custom_settings.py +134 -0
- cumulusci/tasks/salesforce/custom_settings_wait.py +132 -0
- cumulusci/tasks/salesforce/enable_prediction.py +107 -0
- cumulusci/tasks/salesforce/insert_record.py +40 -0
- cumulusci/tasks/salesforce/install_package_version.py +242 -0
- cumulusci/tasks/salesforce/license_preflights.py +8 -0
- cumulusci/tasks/salesforce/network_member_group.py +178 -0
- cumulusci/tasks/salesforce/nonsourcetracking.py +228 -0
- cumulusci/tasks/salesforce/org_settings.py +193 -0
- cumulusci/tasks/salesforce/package_upload.py +328 -0
- cumulusci/tasks/salesforce/profiles.py +74 -0
- cumulusci/tasks/salesforce/promote_package_version.py +376 -0
- cumulusci/tasks/salesforce/retrieve_profile.py +195 -0
- cumulusci/tasks/salesforce/salesforce_files.py +244 -0
- cumulusci/tasks/salesforce/sourcetracking.py +507 -0
- cumulusci/tasks/salesforce/tests/__init__.py +3 -0
- cumulusci/tasks/salesforce/tests/test_CreateCommunity.py +278 -0
- cumulusci/tasks/salesforce/tests/test_CreatePackage.py +22 -0
- cumulusci/tasks/salesforce/tests/test_Deploy.py +470 -0
- cumulusci/tasks/salesforce/tests/test_DeployBundles.py +76 -0
- cumulusci/tasks/salesforce/tests/test_EnsureRecordTypes.py +345 -0
- cumulusci/tasks/salesforce/tests/test_ListCommunities.py +84 -0
- cumulusci/tasks/salesforce/tests/test_ListCommunityTemplates.py +49 -0
- cumulusci/tasks/salesforce/tests/test_PackageUpload.py +547 -0
- cumulusci/tasks/salesforce/tests/test_ProfileGrantAllAccess.py +699 -0
- cumulusci/tasks/salesforce/tests/test_PublishCommunity.py +181 -0
- cumulusci/tasks/salesforce/tests/test_RetrievePackaged.py +24 -0
- cumulusci/tasks/salesforce/tests/test_RetrieveReportsAndDashboards.py +56 -0
- cumulusci/tasks/salesforce/tests/test_RetrieveUnpackaged.py +21 -0
- cumulusci/tasks/salesforce/tests/test_SOQLQuery.py +30 -0
- cumulusci/tasks/salesforce/tests/test_UninstallLocal.py +15 -0
- cumulusci/tasks/salesforce/tests/test_UninstallLocalBundles.py +19 -0
- cumulusci/tasks/salesforce/tests/test_UninstallLocalNamespacedBundles.py +22 -0
- cumulusci/tasks/salesforce/tests/test_UninstallPackage.py +19 -0
- cumulusci/tasks/salesforce/tests/test_UninstallPackaged.py +66 -0
- cumulusci/tasks/salesforce/tests/test_UninstallPackagedIncremental.py +127 -0
- cumulusci/tasks/salesforce/tests/test_activate_flow.py +132 -0
- cumulusci/tasks/salesforce/tests/test_base_tasks.py +110 -0
- cumulusci/tasks/salesforce/tests/test_check_components.py +445 -0
- cumulusci/tasks/salesforce/tests/test_composite.py +250 -0
- cumulusci/tasks/salesforce/tests/test_create_permission_sets.py +41 -0
- cumulusci/tasks/salesforce/tests/test_custom_settings.py +227 -0
- cumulusci/tasks/salesforce/tests/test_custom_settings_wait.py +174 -0
- cumulusci/tasks/salesforce/tests/test_describemetadatatypes.py +18 -0
- cumulusci/tasks/salesforce/tests/test_enable_prediction.py +240 -0
- cumulusci/tasks/salesforce/tests/test_insert_record.py +110 -0
- cumulusci/tasks/salesforce/tests/test_install_package_version.py +464 -0
- cumulusci/tasks/salesforce/tests/test_network_member_group.py +444 -0
- cumulusci/tasks/salesforce/tests/test_nonsourcetracking.py +235 -0
- cumulusci/tasks/salesforce/tests/test_org_settings.py +407 -0
- cumulusci/tasks/salesforce/tests/test_profiles.py +202 -0
- cumulusci/tasks/salesforce/tests/test_retrieve_profile.py +287 -0
- cumulusci/tasks/salesforce/tests/test_salesforce_files.py +228 -0
- cumulusci/tasks/salesforce/tests/test_sourcetracking.py +350 -0
- cumulusci/tasks/salesforce/tests/test_trigger_handlers.py +300 -0
- cumulusci/tasks/salesforce/tests/test_update_dependencies.py +509 -0
- cumulusci/tasks/salesforce/tests/util.py +79 -0
- cumulusci/tasks/salesforce/trigger_handlers.py +119 -0
- cumulusci/tasks/salesforce/uninstall_packaged_incremental.py +136 -0
- cumulusci/tasks/salesforce/update_dependencies.py +290 -0
- cumulusci/tasks/salesforce/update_profile.py +339 -0
- cumulusci/tasks/salesforce/users/permsets.py +227 -0
- cumulusci/tasks/salesforce/users/photos.py +162 -0
- cumulusci/tasks/salesforce/users/tests/photo.mock.txt +1 -0
- cumulusci/tasks/salesforce/users/tests/test_permsets.py +950 -0
- cumulusci/tasks/salesforce/users/tests/test_photos.py +373 -0
- cumulusci/tasks/sample_data/capture_sample_data.py +77 -0
- cumulusci/tasks/sample_data/load_sample_data.py +85 -0
- cumulusci/tasks/sample_data/test_capture_sample_data.py +117 -0
- cumulusci/tasks/sample_data/test_load_sample_data.py +121 -0
- cumulusci/tasks/sfdx.py +83 -0
- cumulusci/tasks/tests/__init__.py +1 -0
- cumulusci/tasks/tests/conftest.py +30 -0
- cumulusci/tasks/tests/test_command.py +129 -0
- cumulusci/tasks/tests/test_connectedapp.py +236 -0
- cumulusci/tasks/tests/test_create_package_version.py +847 -0
- cumulusci/tasks/tests/test_datadictionary.py +1575 -0
- cumulusci/tasks/tests/test_dx_convert_from.py +60 -0
- cumulusci/tasks/tests/test_metadeploy.py +624 -0
- cumulusci/tasks/tests/test_metaxml.py +99 -0
- cumulusci/tasks/tests/test_promote_package_version.py +488 -0
- cumulusci/tasks/tests/test_pushfails.py +96 -0
- cumulusci/tasks/tests/test_salesforce.py +72 -0
- cumulusci/tasks/tests/test_sfdx.py +105 -0
- cumulusci/tasks/tests/test_util.py +207 -0
- cumulusci/tasks/util.py +261 -0
- cumulusci/tasks/vcs/__init__.py +19 -0
- cumulusci/tasks/vcs/commit_status.py +58 -0
- cumulusci/tasks/vcs/create_commit_status.py +37 -0
- cumulusci/tasks/vcs/download_extract.py +199 -0
- cumulusci/tasks/vcs/merge.py +298 -0
- cumulusci/tasks/vcs/publish.py +207 -0
- cumulusci/tasks/vcs/pull_request.py +9 -0
- cumulusci/tasks/vcs/release.py +134 -0
- cumulusci/tasks/vcs/release_report.py +105 -0
- cumulusci/tasks/vcs/tag.py +31 -0
- cumulusci/tasks/vcs/tests/github/test_commit_status.py +196 -0
- cumulusci/tasks/vcs/tests/github/test_download_extract.py +896 -0
- cumulusci/tasks/vcs/tests/github/test_merge.py +1118 -0
- cumulusci/tasks/vcs/tests/github/test_publish.py +823 -0
- cumulusci/tasks/vcs/tests/github/test_pull_request.py +29 -0
- cumulusci/tasks/vcs/tests/github/test_release.py +390 -0
- cumulusci/tasks/vcs/tests/github/test_release_report.py +109 -0
- cumulusci/tasks/vcs/tests/github/test_tag.py +90 -0
- cumulusci/tasks/vlocity/exceptions.py +2 -0
- cumulusci/tasks/vlocity/tests/test_vlocity.py +283 -0
- cumulusci/tasks/vlocity/vlocity.py +342 -0
- cumulusci/tests/__init__.py +1 -0
- cumulusci/tests/cassettes/GET_sobjects_Account_PersonAccount_describe.yaml +18 -0
- cumulusci/tests/cassettes/TestIntegrationInfrastructure.test_integration_tests.yaml +19 -0
- cumulusci/tests/pytest_plugins/pytest_sf_orgconnect.py +307 -0
- cumulusci/tests/pytest_plugins/pytest_sf_vcr.py +275 -0
- cumulusci/tests/pytest_plugins/pytest_sf_vcr_serializer.py +160 -0
- cumulusci/tests/pytest_plugins/pytest_typeguard.py +5 -0
- cumulusci/tests/pytest_plugins/test_vcr_string_compressor.py +49 -0
- cumulusci/tests/pytest_plugins/vcr_string_compressor.py +97 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Account_describe.yaml +18 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Case_describe.yaml +18 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Contact_describe.yaml +4838 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Custom__c_describe.yaml +242 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Event_describe.yaml +19 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Global_describe.yaml +1338 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Lead_describe.yaml +18 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_OpportunityContactRole_describe.yaml +34 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Opportunity_describe.yaml +1261 -0
- cumulusci/tests/shared_cassettes/GET_sobjects_Organization.yaml +49 -0
- cumulusci/tests/shared_cassettes/vcr_string_templates/batchInfoList_xml.tpl +15 -0
- cumulusci/tests/shared_cassettes/vcr_string_templates/batchInfo_xml.tpl +13 -0
- cumulusci/tests/shared_cassettes/vcr_string_templates/jobInfo_insert_xml.tpl +24 -0
- cumulusci/tests/shared_cassettes/vcr_string_templates/jobInfo_upsert_xml.tpl +25 -0
- cumulusci/tests/test_entry_points.py +20 -0
- cumulusci/tests/test_integration_infrastructure.py +131 -0
- cumulusci/tests/test_main.py +9 -0
- cumulusci/tests/test_schema.py +32 -0
- cumulusci/tests/test_utils.py +657 -0
- cumulusci/tests/test_vcr_serializer.py +134 -0
- cumulusci/tests/uncompressed_cassette.yaml +83 -0
- cumulusci/tests/util.py +344 -0
- cumulusci/utils/__init__.py +731 -0
- cumulusci/utils/classutils.py +9 -0
- cumulusci/utils/collections.py +32 -0
- cumulusci/utils/deprecation.py +11 -0
- cumulusci/utils/encryption.py +31 -0
- cumulusci/utils/fileutils.py +295 -0
- cumulusci/utils/git.py +142 -0
- cumulusci/utils/http/multi_request.py +214 -0
- cumulusci/utils/http/requests_utils.py +103 -0
- cumulusci/utils/http/tests/cassettes/ManualEditTestCompositeParallelSalesforce.test_http_headers.yaml +32 -0
- cumulusci/utils/http/tests/cassettes/TestCompositeParallelSalesforce.test_composite_parallel_salesforce.yaml +65 -0
- cumulusci/utils/http/tests/cassettes/TestCompositeParallelSalesforce.test_errors.yaml +24 -0
- cumulusci/utils/http/tests/cassettes/TestCompositeParallelSalesforce.test_reference_ids.yaml +49 -0
- cumulusci/utils/http/tests/test_multi_request.py +255 -0
- cumulusci/utils/iterators.py +21 -0
- cumulusci/utils/logging.py +128 -0
- cumulusci/utils/metaprogramming.py +10 -0
- cumulusci/utils/options.py +138 -0
- cumulusci/utils/parallel/queries_in_parallel/run_queries_in_parallel.py +29 -0
- cumulusci/utils/parallel/queries_in_parallel/tests/test_run_queries_in_parallel.py +50 -0
- cumulusci/utils/parallel/task_worker_queues/parallel_worker.py +238 -0
- cumulusci/utils/parallel/task_worker_queues/parallel_worker_queue.py +243 -0
- cumulusci/utils/parallel/task_worker_queues/tests/test_parallel_worker.py +353 -0
- cumulusci/utils/salesforce/count_sobjects.py +46 -0
- cumulusci/utils/salesforce/soql.py +17 -0
- cumulusci/utils/salesforce/tests/cassettes/ManualEdit_TestCountSObjects.test_count_sobjects__network_errors.yaml +23 -0
- cumulusci/utils/salesforce/tests/cassettes/TestCountSObjects.test_count_sobjects__errors.yaml +33 -0
- cumulusci/utils/salesforce/tests/cassettes/TestCountSObjects.test_count_sobjects_simple.yaml +29 -0
- cumulusci/utils/salesforce/tests/test_count_sobjects.py +29 -0
- cumulusci/utils/salesforce/tests/test_soql.py +30 -0
- cumulusci/utils/tests/cassettes/ManualEditTestDescribeOrg.test_minimal_schema.yaml +36 -0
- cumulusci/utils/tests/cassettes/ManualEdit_test_describe_to_sql.yaml +191 -0
- cumulusci/utils/tests/test_fileutils.py +284 -0
- cumulusci/utils/tests/test_git.py +85 -0
- cumulusci/utils/tests/test_logging.py +70 -0
- cumulusci/utils/tests/test_option_parsing.py +188 -0
- cumulusci/utils/tests/test_org_schema.py +691 -0
- cumulusci/utils/tests/test_org_schema_models.py +79 -0
- cumulusci/utils/tests/test_waiting.py +25 -0
- cumulusci/utils/version_strings.py +391 -0
- cumulusci/utils/waiting.py +42 -0
- cumulusci/utils/xml/__init__.py +91 -0
- cumulusci/utils/xml/metadata_tree.py +299 -0
- cumulusci/utils/xml/robot_xml.py +114 -0
- cumulusci/utils/xml/salesforce_encoding.py +100 -0
- cumulusci/utils/xml/test/test_metadata_tree.py +251 -0
- cumulusci/utils/xml/test/test_salesforce_encoding.py +173 -0
- cumulusci/utils/yaml/cumulusci_yml.py +401 -0
- cumulusci/utils/yaml/model_parser.py +156 -0
- cumulusci/utils/yaml/safer_loader.py +74 -0
- cumulusci/utils/yaml/tests/bad_cci.yml +5 -0
- cumulusci/utils/yaml/tests/cassettes/TestCumulusciYml.test_validate_url__with_errors.yaml +20 -0
- cumulusci/utils/yaml/tests/test_cumulusci_yml.py +286 -0
- cumulusci/utils/yaml/tests/test_model_parser.py +175 -0
- cumulusci/utils/yaml/tests/test_safer_loader.py +88 -0
- cumulusci/utils/ziputils.py +61 -0
- cumulusci/vcs/base.py +143 -0
- cumulusci/vcs/bootstrap.py +272 -0
- cumulusci/vcs/github/__init__.py +24 -0
- cumulusci/vcs/github/adapter.py +689 -0
- cumulusci/vcs/github/release_notes/generator.py +219 -0
- cumulusci/vcs/github/release_notes/parser.py +151 -0
- cumulusci/vcs/github/release_notes/provider.py +143 -0
- cumulusci/vcs/github/service.py +569 -0
- cumulusci/vcs/github/tests/test_adapter.py +138 -0
- cumulusci/vcs/github/tests/test_service.py +408 -0
- cumulusci/vcs/models.py +586 -0
- cumulusci/vcs/tests/conftest.py +41 -0
- cumulusci/vcs/tests/dummy_service.py +241 -0
- cumulusci/vcs/tests/test_vcs_base.py +687 -0
- cumulusci/vcs/tests/test_vcs_bootstrap.py +727 -0
- cumulusci/vcs/utils/__init__.py +31 -0
- cumulusci/vcs/vcs_source.py +287 -0
- cumulusci_plus-5.0.0.dist-info/METADATA +145 -0
- cumulusci_plus-5.0.0.dist-info/RECORD +744 -0
- cumulusci_plus-5.0.0.dist-info/WHEEL +4 -0
- cumulusci_plus-5.0.0.dist-info/entry_points.txt +3 -0
- cumulusci_plus-5.0.0.dist-info/licenses/AUTHORS.rst +41 -0
- cumulusci_plus-5.0.0.dist-info/licenses/LICENSE +30 -0
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
import robot.api.logger
|
|
4
|
+
from robot.libraries.BuiltIn import BuiltIn
|
|
5
|
+
|
|
6
|
+
from cumulusci.cli.runtime import CliRuntime
|
|
7
|
+
from cumulusci.core.config import ScratchOrgConfig, TaskConfig
|
|
8
|
+
from cumulusci.core.exceptions import TaskOptionsError
|
|
9
|
+
from cumulusci.core.tasks import CURRENT_TASK
|
|
10
|
+
from cumulusci.core.utils import import_global
|
|
11
|
+
from cumulusci.robotframework.utils import set_pdb_trace
|
|
12
|
+
from cumulusci.salesforce_api.utils import get_simple_salesforce_connection
|
|
13
|
+
from cumulusci.tasks.robotframework.robotframework import Robot
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class CumulusCI(object):
|
|
17
|
+
"""Library for accessing CumulusCI for the local git project
|
|
18
|
+
|
|
19
|
+
This library allows Robot Framework tests to access credentials to a
|
|
20
|
+
Salesforce org created by CumulusCI, including Scratch Orgs. It also
|
|
21
|
+
exposes the core logic of CumulusCI including interactions with the
|
|
22
|
+
Salesforce API's and project specific configuration including custom
|
|
23
|
+
and customized tasks and flows.
|
|
24
|
+
|
|
25
|
+
Initialization requires a single argument, the org name for the target
|
|
26
|
+
CumulusCI org. If running your tests via cci's robot task (recommended),
|
|
27
|
+
you can initialize the library in your tests taking advantage of the
|
|
28
|
+
variable set by the robot task:
|
|
29
|
+
| ``*** Settings ***``
|
|
30
|
+
|
|
|
31
|
+
| Library cumulusci.robotframework.CumulusCI ${ORG}
|
|
32
|
+
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
ROBOT_LIBRARY_SCOPE = "GLOBAL"
|
|
36
|
+
|
|
37
|
+
def __init__(self, org_name=None):
|
|
38
|
+
if not org_name:
|
|
39
|
+
org_name = "dev"
|
|
40
|
+
self.org_name = org_name
|
|
41
|
+
self._project_config = None
|
|
42
|
+
self._org = None
|
|
43
|
+
|
|
44
|
+
# Turn off info logging of all http requests
|
|
45
|
+
logging.getLogger("requests.packages.urllib3.connectionpool").setLevel(
|
|
46
|
+
logging.WARN
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def project_config(self):
|
|
51
|
+
if self._project_config is None:
|
|
52
|
+
if getattr(CURRENT_TASK, "stack", None) and isinstance(
|
|
53
|
+
CURRENT_TASK.stack[0], Robot
|
|
54
|
+
):
|
|
55
|
+
# If CumulusCI is running a task, use that task's config
|
|
56
|
+
return CURRENT_TASK.stack[0].project_config
|
|
57
|
+
else:
|
|
58
|
+
robot.api.logger.console("Initializing CumulusCI config\n")
|
|
59
|
+
self._project_config = CliRuntime().project_config
|
|
60
|
+
return self._project_config
|
|
61
|
+
|
|
62
|
+
def set_project_config(self, project_config):
|
|
63
|
+
self._project_config = project_config
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def keychain(self):
|
|
67
|
+
return self.project_config.keychain
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def org(self):
|
|
71
|
+
if self._org is None:
|
|
72
|
+
if getattr(CURRENT_TASK, "stack", None) and isinstance(
|
|
73
|
+
CURRENT_TASK.stack[0], Robot
|
|
74
|
+
):
|
|
75
|
+
# If CumulusCI is running a task, use that task's org
|
|
76
|
+
return CURRENT_TASK.stack[0].org_config
|
|
77
|
+
else:
|
|
78
|
+
self._org = self.keychain.get_org(self.org_name)
|
|
79
|
+
return self._org
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def sf(self):
|
|
83
|
+
return self._init_api()
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def tooling(self):
|
|
87
|
+
return self._init_api("tooling/")
|
|
88
|
+
|
|
89
|
+
def set_login_url(self):
|
|
90
|
+
"""Sets the LOGIN_URL variable in the suite scope which will
|
|
91
|
+
automatically log into the target Salesforce org.
|
|
92
|
+
|
|
93
|
+
Typically, this is run during Suite Setup
|
|
94
|
+
"""
|
|
95
|
+
BuiltIn().set_suite_variable("${LOGIN_URL}", self.org.start_url)
|
|
96
|
+
|
|
97
|
+
def get_org_info(self):
|
|
98
|
+
"""Returns a dictionary of the org information for the current target
|
|
99
|
+
Salesforce org
|
|
100
|
+
"""
|
|
101
|
+
return self.org.config
|
|
102
|
+
|
|
103
|
+
def login_url(self, org=None, **userfields):
|
|
104
|
+
"""Returns the login url which will automatically log into the target
|
|
105
|
+
Salesforce org. By default, the org_name passed to the library
|
|
106
|
+
constructor is used but this can be overridden with the org option
|
|
107
|
+
to log into a different org.
|
|
108
|
+
|
|
109
|
+
If userfields are provided, the username and access token
|
|
110
|
+
for the given user will be used. If not provided, the access token
|
|
111
|
+
for the org's default user will be used.
|
|
112
|
+
|
|
113
|
+
The userfields argument is largely useful for scratch orgs, but can
|
|
114
|
+
also work with connected persistent orgs if you've connected the org
|
|
115
|
+
with the given username.
|
|
116
|
+
|
|
117
|
+
Example:
|
|
118
|
+
|
|
119
|
+
| ${login url}= Login URL alias=dadvisor
|
|
120
|
+
|
|
121
|
+
"""
|
|
122
|
+
org = self.org if org is None else self.keychain.get_org(org)
|
|
123
|
+
|
|
124
|
+
if userfields:
|
|
125
|
+
if org.get_access_token is not None:
|
|
126
|
+
# connected persistent org configs won't have the get_access_token method
|
|
127
|
+
access_token = org.get_access_token(**userfields)
|
|
128
|
+
else:
|
|
129
|
+
access_token = self._find_access_token(org, **userfields)
|
|
130
|
+
login_url = f"{org.instance_url}/secur/frontdoor.jsp?sid={access_token}"
|
|
131
|
+
return login_url
|
|
132
|
+
else:
|
|
133
|
+
return org.start_url
|
|
134
|
+
|
|
135
|
+
def get_community_info(self, community_name, key=None, force_refresh=False):
|
|
136
|
+
"""This keyword uses the Salesforce API to get information about a community.
|
|
137
|
+
|
|
138
|
+
This keyword requires the exact community name as its first argumment.
|
|
139
|
+
|
|
140
|
+
- If no key is given, all of the information returned by the API will be
|
|
141
|
+
returned by this keyword in the form of a dictionary
|
|
142
|
+
- If a key is given, only the value for that key will be returned.
|
|
143
|
+
|
|
144
|
+
Some of the supported keys include name, siteUrl, and
|
|
145
|
+
loginUrl. For a comprehensive list see the
|
|
146
|
+
[https://developer.salesforce.com/docs/atlas.en-us.chatterapi.meta/chatterapi/connect_responses_community.htm|API documentation],
|
|
147
|
+
or call this keyword without the key argument and examine the
|
|
148
|
+
results.
|
|
149
|
+
|
|
150
|
+
An API call will be made the first time this keyword is used, and
|
|
151
|
+
the return values will be cached. Subsequent calls will not call
|
|
152
|
+
the API unless the requested community name is not in the cached
|
|
153
|
+
results, or unless the force_refresh parameter is set to True.
|
|
154
|
+
"""
|
|
155
|
+
community_info = self.org.get_community_info(
|
|
156
|
+
community_name, force_refresh=force_refresh
|
|
157
|
+
)
|
|
158
|
+
if key is None:
|
|
159
|
+
return community_info
|
|
160
|
+
else:
|
|
161
|
+
if key not in community_info:
|
|
162
|
+
raise Exception("Invalid key '{}'".format(key))
|
|
163
|
+
return community_info[key]
|
|
164
|
+
|
|
165
|
+
def get_namespace_prefix(self, package=None):
|
|
166
|
+
"""Returns the namespace prefix (including __) for the specified package name.
|
|
167
|
+
(Defaults to project__package__name_managed from the current project config.)
|
|
168
|
+
|
|
169
|
+
Returns an empty string if the package is not installed as a managed package.
|
|
170
|
+
"""
|
|
171
|
+
result = ""
|
|
172
|
+
if package is None:
|
|
173
|
+
package = self.project_config.project__package__name_managed
|
|
174
|
+
packages = self.tooling.query(
|
|
175
|
+
"SELECT SubscriberPackage.NamespacePrefix, SubscriberPackage.Name "
|
|
176
|
+
"FROM InstalledSubscriberPackage"
|
|
177
|
+
)
|
|
178
|
+
match = [
|
|
179
|
+
p for p in packages["records"] if p["SubscriberPackage"]["Name"] == package
|
|
180
|
+
]
|
|
181
|
+
if match:
|
|
182
|
+
result = match[0]["SubscriberPackage"]["NamespacePrefix"] + "__"
|
|
183
|
+
return result
|
|
184
|
+
|
|
185
|
+
def run_task(self, task_name, **options):
|
|
186
|
+
"""Runs a named CumulusCI task for the current project with optional
|
|
187
|
+
support for overriding task options via kwargs.
|
|
188
|
+
|
|
189
|
+
Note: task_name can be prefixed with the name of another project,
|
|
190
|
+
just the same as when running the task from the command line. The other
|
|
191
|
+
project needs to have been defined in the 'sources' section of cumulusci.yml.
|
|
192
|
+
|
|
193
|
+
The task output will appear in the robot log.
|
|
194
|
+
|
|
195
|
+
Examples:
|
|
196
|
+
| =Keyword= | =task_name= | =task_options= | =comment= |
|
|
197
|
+
| Run Task | deploy | | Run deploy with standard options |
|
|
198
|
+
| Run Task | deploy | path=path/to/some/metadata | Run deploy with custom path |
|
|
199
|
+
| Run task | npsp:deploy_rd2_config | | Run the deploy_rd2_config task from the NPSP project |
|
|
200
|
+
"""
|
|
201
|
+
task_config = self.project_config.get_task(task_name)
|
|
202
|
+
class_path = task_config.class_path
|
|
203
|
+
task = self._init_task(class_path, options, task_config)
|
|
204
|
+
return self._run_task(task)
|
|
205
|
+
|
|
206
|
+
def run_task_class(self, class_path, **options):
|
|
207
|
+
"""Runs a CumulusCI task class with task options via kwargs.
|
|
208
|
+
|
|
209
|
+
Use this keyword to run logic from CumulusCI tasks which have not
|
|
210
|
+
been configured in the project's cumulusci.yml file. This is
|
|
211
|
+
most useful in cases where a test needs to use task logic for
|
|
212
|
+
logic unique to the test and thus not worth making into a named
|
|
213
|
+
task for the project
|
|
214
|
+
|
|
215
|
+
The task output will appear in the robot log.
|
|
216
|
+
|
|
217
|
+
Examples:
|
|
218
|
+
| =Keyword= | =task_class= | =task_options= |
|
|
219
|
+
| Run Task Class | cumulusci.task.utils.DownloadZip | url=http://test.com/test.zip dir=test_zip |
|
|
220
|
+
"""
|
|
221
|
+
task = self._init_task(class_path, options, TaskConfig())
|
|
222
|
+
return self._run_task(task)
|
|
223
|
+
|
|
224
|
+
def _init_api(self, base_url=None):
|
|
225
|
+
client = get_simple_salesforce_connection(self.project_config, self.org)
|
|
226
|
+
if base_url is not None:
|
|
227
|
+
client.base_url += base_url
|
|
228
|
+
return client
|
|
229
|
+
|
|
230
|
+
def _init_task(self, class_path, options, task_config):
|
|
231
|
+
task_class = import_global(class_path)
|
|
232
|
+
task_config = self._parse_task_options(options, task_class, task_config)
|
|
233
|
+
# Python deprecated the logger method "warn" in favor of
|
|
234
|
+
# "warning". Robot didn't get the memo and only has a "warn"
|
|
235
|
+
# method. Some tasks use "warning", so this makes sure the
|
|
236
|
+
# robot logger can handle that.
|
|
237
|
+
if not hasattr(robot.api.logger, "warning"):
|
|
238
|
+
robot.api.logger.warning = robot.api.logger.warn
|
|
239
|
+
|
|
240
|
+
# robot's logger doesn't have the 'log' method, and there's at least one
|
|
241
|
+
# piece of code that depends on this method. So, if we haven't already
|
|
242
|
+
# monkeypatched it in, do so now. See W-10503175
|
|
243
|
+
if not hasattr(robot.api.logger, "log"):
|
|
244
|
+
robot.api.logger.log = _logger_log
|
|
245
|
+
|
|
246
|
+
task = task_class(
|
|
247
|
+
task_config.project_config or self.project_config,
|
|
248
|
+
task_config,
|
|
249
|
+
org_config=self.org,
|
|
250
|
+
logger=robot.api.logger,
|
|
251
|
+
)
|
|
252
|
+
return task
|
|
253
|
+
|
|
254
|
+
def _parse_task_options(self, options, task_class, task_config):
|
|
255
|
+
if "options" not in task_config.config:
|
|
256
|
+
task_config.config["options"] = {}
|
|
257
|
+
# Parse options and add to task config
|
|
258
|
+
if options:
|
|
259
|
+
for name, value in options.items():
|
|
260
|
+
# Validate the option
|
|
261
|
+
if name not in task_class.task_options:
|
|
262
|
+
raise TaskOptionsError(
|
|
263
|
+
'Option "{}" is not available for task {}'.format(
|
|
264
|
+
name, task_class
|
|
265
|
+
)
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
# Override the option in the task config
|
|
269
|
+
task_config.config["options"][name] = value
|
|
270
|
+
|
|
271
|
+
return task_config
|
|
272
|
+
|
|
273
|
+
def _run_task(self, task):
|
|
274
|
+
task()
|
|
275
|
+
return task.return_values
|
|
276
|
+
|
|
277
|
+
def _find_access_token(self, base_org, **userfields):
|
|
278
|
+
"""Search connected orgs for a user and return the access token
|
|
279
|
+
|
|
280
|
+
The org config for connected orgs doesn't have an access token
|
|
281
|
+
for each user. Instead, we have an access token for the org as
|
|
282
|
+
a whole. This searches all connected org configs for an org
|
|
283
|
+
with the given user (either by username or alias) and returns
|
|
284
|
+
the access token for the org.
|
|
285
|
+
|
|
286
|
+
It is expected that userfields contains either a 'username'
|
|
287
|
+
or 'alias' field. If a username is provided, that's what will
|
|
288
|
+
be used. If not, this function will do a query to find a username
|
|
289
|
+
that matches the given parameters.
|
|
290
|
+
|
|
291
|
+
"""
|
|
292
|
+
|
|
293
|
+
username = userfields.get("username", None)
|
|
294
|
+
if username is None:
|
|
295
|
+
where = [f"{key}='{value}'" for key, value in userfields.items()]
|
|
296
|
+
query = f"SELECT Username FROM User WHERE {' AND '.join(where)}"
|
|
297
|
+
result = base_org.salesforce_client.query(query).get("records", [])
|
|
298
|
+
if len(result) == 0:
|
|
299
|
+
query = ", ".join(where)
|
|
300
|
+
raise Exception(
|
|
301
|
+
f"Couldn't find a username in org {base_org.name} for the specified user ({query})."
|
|
302
|
+
)
|
|
303
|
+
elif len(result) > 1:
|
|
304
|
+
results = ", ".join([user["Username"] for user in result])
|
|
305
|
+
raise Exception(
|
|
306
|
+
f"More than one user matched the search critiera for org {base_org.name} ({results})."
|
|
307
|
+
)
|
|
308
|
+
else:
|
|
309
|
+
username = result[0]["Username"]
|
|
310
|
+
|
|
311
|
+
for org_name in self.keychain.list_orgs():
|
|
312
|
+
org = self.keychain.get_org(org_name)
|
|
313
|
+
if not isinstance(org, ScratchOrgConfig):
|
|
314
|
+
if "userinfo" in org.config:
|
|
315
|
+
if org.config["userinfo"]["preferred_username"] == username:
|
|
316
|
+
return org.access_token
|
|
317
|
+
return None
|
|
318
|
+
|
|
319
|
+
def debug(self):
|
|
320
|
+
"""Pauses execution and enters the Python debugger."""
|
|
321
|
+
set_pdb_trace()
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
def _logger_log(level, msg):
|
|
325
|
+
"""Implements the 'log' method for robot.api.logger
|
|
326
|
+
|
|
327
|
+
This takes a normal python log level, converts it to one of
|
|
328
|
+
the supported robot log levels, then calls the write method
|
|
329
|
+
of the logger.
|
|
330
|
+
"""
|
|
331
|
+
level = (
|
|
332
|
+
"ERROR"
|
|
333
|
+
if level >= logging.ERROR
|
|
334
|
+
else "WARN"
|
|
335
|
+
if level >= logging.WARN
|
|
336
|
+
else "INFO"
|
|
337
|
+
if level >= logging.INFO
|
|
338
|
+
else "DEBUG"
|
|
339
|
+
)
|
|
340
|
+
robot.api.logger.write(msg, level)
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
|
|
3
|
+
from dateutil.parser import ParserError
|
|
4
|
+
from dateutil.parser import parse as parse_date
|
|
5
|
+
from robot.libraries.BuiltIn import BuiltIn
|
|
6
|
+
from robot.utils import timestr_to_secs
|
|
7
|
+
|
|
8
|
+
from cumulusci.robotframework.base_library import BaseLibrary
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Performance(BaseLibrary):
|
|
12
|
+
"""
|
|
13
|
+
Keywords for performance testing.
|
|
14
|
+
|
|
15
|
+
For more information on how to use these keywords, see
|
|
16
|
+
the "Performance Testing" section of the CumulusCI documentation.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def elapsed_time_for_last_record(
|
|
20
|
+
self, obj_name, start_field, end_field, order_by, **kwargs
|
|
21
|
+
):
|
|
22
|
+
"""For records representing jobs or processes, compare the record's start-time to its end-time to see how long a process took.
|
|
23
|
+
|
|
24
|
+
Arguments:
|
|
25
|
+
obj_name: SObject to look for last record
|
|
26
|
+
start_field: Name of the datetime field that represents the process start
|
|
27
|
+
end_field: Name of the datetime field that represents the process end
|
|
28
|
+
order_by: Field name to order by. Should be a datetime field, and usually is just the same as end_field.
|
|
29
|
+
where: Optional Where-clause to use for filtering
|
|
30
|
+
Other keywords are used for filtering as in the Salesforce Query keywordf
|
|
31
|
+
|
|
32
|
+
The last matching record queried and summarized.
|
|
33
|
+
|
|
34
|
+
Example:
|
|
35
|
+
|
|
36
|
+
| ${time_in_seconds} = Elapsed Time For Last Record
|
|
37
|
+
| ... obj_name=AsyncApexJob
|
|
38
|
+
| ... where=ApexClass.Name='BlahBlah'
|
|
39
|
+
| ... start_field=CreatedDate
|
|
40
|
+
| ... end_field=CompletedDate
|
|
41
|
+
| ... order_by=CompletedDate
|
|
42
|
+
"""
|
|
43
|
+
if len(order_by.split()) != 1:
|
|
44
|
+
raise Exception("order_by should be a simple field name")
|
|
45
|
+
query = self.salesforce_api._soql_query_builder(
|
|
46
|
+
obj_name,
|
|
47
|
+
select=f"{start_field}, {end_field}",
|
|
48
|
+
order_by=order_by + " DESC NULLS LAST",
|
|
49
|
+
limit=1,
|
|
50
|
+
**kwargs,
|
|
51
|
+
)
|
|
52
|
+
response = self.salesforce_api.soql_query(query)
|
|
53
|
+
results = response["records"]
|
|
54
|
+
|
|
55
|
+
if results:
|
|
56
|
+
record = results[0]
|
|
57
|
+
return _duration(record[start_field], record[end_field], record)
|
|
58
|
+
else:
|
|
59
|
+
raise Exception(f"Matching record not found: {query}")
|
|
60
|
+
|
|
61
|
+
def start_performance_timer(self):
|
|
62
|
+
"""Start an elapsed time stopwatch for performance tests.
|
|
63
|
+
|
|
64
|
+
See the docummentation for **Stop Performance Timer** for more
|
|
65
|
+
information.
|
|
66
|
+
|
|
67
|
+
Example:
|
|
68
|
+
|
|
69
|
+
| Start Performance Timer
|
|
70
|
+
| Do Something
|
|
71
|
+
| Stop Performance Timer
|
|
72
|
+
"""
|
|
73
|
+
BuiltIn().set_test_variable("${__start_time}", datetime.now())
|
|
74
|
+
|
|
75
|
+
def stop_performance_timer(self):
|
|
76
|
+
"""Record the results of a stopwatch. For perf testing.
|
|
77
|
+
|
|
78
|
+
This keyword uses Set Test Elapsed Time internally and therefore
|
|
79
|
+
outputs in all of the ways described there.
|
|
80
|
+
|
|
81
|
+
Example:
|
|
82
|
+
|
|
83
|
+
| Start Performance Timer
|
|
84
|
+
| Do Something
|
|
85
|
+
| Stop Performance Timer
|
|
86
|
+
|
|
87
|
+
"""
|
|
88
|
+
start_time = self.builtin.get_variable_value("${__start_time}")
|
|
89
|
+
if start_time:
|
|
90
|
+
seconds = (datetime.now() - start_time).seconds
|
|
91
|
+
assert seconds is not None
|
|
92
|
+
self.set_test_elapsed_time(seconds)
|
|
93
|
+
else:
|
|
94
|
+
raise Exception(
|
|
95
|
+
"Elapsed time clock was not started. "
|
|
96
|
+
"Use the Start Elapsed Time keyword to do so."
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
def set_test_elapsed_time(self, elapsedtime):
|
|
100
|
+
"""This keyword captures a computed rather than measured elapsed time for performance tests.
|
|
101
|
+
|
|
102
|
+
For example, if you were performance testing a Salesforce batch process, you might want to
|
|
103
|
+
store the Salesforce-measured elapsed time of the batch process instead of the time measured
|
|
104
|
+
in the CCI client process.
|
|
105
|
+
|
|
106
|
+
The keyword takes a single argument which is either a number of seconds or a Robot time string
|
|
107
|
+
(https://robotframework.org/robotframework/latest/libraries/DateTime.html#Time%20formats).
|
|
108
|
+
|
|
109
|
+
Using this keyword will automatically add the tag cci_metric_elapsed_time to the test case
|
|
110
|
+
and ${cci_metric_elapsed_time} to the test's variables. cci_metric_elapsed_time is not
|
|
111
|
+
included in Robot's html statistical roll-ups.
|
|
112
|
+
|
|
113
|
+
Example:
|
|
114
|
+
|
|
115
|
+
| Set Test Elapsed Time 11655.9
|
|
116
|
+
|
|
117
|
+
Performance test times are output in the CCI logs and are captured in MetaCI instead of the
|
|
118
|
+
"total elapsed time" measured by Robot Framework. The Robot "test message" is also updated."""
|
|
119
|
+
|
|
120
|
+
try:
|
|
121
|
+
seconds = float(elapsedtime)
|
|
122
|
+
except ValueError:
|
|
123
|
+
seconds = timestr_to_secs(elapsedtime)
|
|
124
|
+
assert seconds is not None
|
|
125
|
+
|
|
126
|
+
self.builtin.set_test_message(f"Elapsed time set by test : {seconds}")
|
|
127
|
+
self.builtin.set_tags("cci_metric_elapsed_time")
|
|
128
|
+
self.builtin.set_test_variable("${cci_metric_elapsed_time}", seconds)
|
|
129
|
+
|
|
130
|
+
def set_test_metric(self, metric: str, value=None):
|
|
131
|
+
"""This keyword captures any metric for performance monitoring.
|
|
132
|
+
|
|
133
|
+
For example: number of queries, rows processed, CPU usage, etc.
|
|
134
|
+
|
|
135
|
+
The keyword takes a metric name, which can be any string, and a value, which
|
|
136
|
+
can be any number.
|
|
137
|
+
|
|
138
|
+
Using this keyword will automatically add the tag cci_metric to the test case
|
|
139
|
+
and ${cci_metric_<metric_name>} to the test's variables. These permit downstream
|
|
140
|
+
processing in tools like CCI and MetaCI.
|
|
141
|
+
|
|
142
|
+
cci_metric is not included in Robot's html statistical roll-ups.
|
|
143
|
+
|
|
144
|
+
Example:
|
|
145
|
+
|
|
146
|
+
| Set Test Metric Max_CPU_Percent 30
|
|
147
|
+
|
|
148
|
+
Performance test metrics are output in the CCI logs, log.html and output.xml.
|
|
149
|
+
MetaCI captures them but does not currently have a user interface for displaying
|
|
150
|
+
them."""
|
|
151
|
+
|
|
152
|
+
value = float(value)
|
|
153
|
+
|
|
154
|
+
self.builtin.set_tags("cci_metric")
|
|
155
|
+
self.builtin.set_test_variable("${cci_metric_%s}" % metric, value)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def _duration(start_date: str, end_date: str, record: dict):
|
|
159
|
+
try:
|
|
160
|
+
start_date = parse_date(start_date)
|
|
161
|
+
end_date = parse_date(end_date)
|
|
162
|
+
except (ParserError, TypeError) as e:
|
|
163
|
+
raise Exception(f"Date parse error: {e} in record {record}")
|
|
164
|
+
duration = end_date - start_date
|
|
165
|
+
return duration.total_seconds()
|