From e398d100a717a16c48ce81adcbb2e0422fd24c22 Mon Sep 17 00:00:00 2001 From: Alan Malta Rodrigues Date: Fri, 4 Mar 2022 11:51:14 -0500 Subject: [PATCH] Enhancements to the GH issues and PRs workflows fix rst formatting and bulleted items apply more suggestions Merge standards/README into CONTRIBUTING.rst guidelines apply Kenyis suggestions --- CONTRIBUTING.rst | 235 +++++++++++++++++++++++++---- standards/README | 379 ----------------------------------------------- 2 files changed, 209 insertions(+), 405 deletions(-) delete mode 100644 standards/README diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 546cc3d619..a28962bc5a 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -3,18 +3,22 @@ How to contribute to WMCore =========================== Thank you for participating in WMCore! -* Please ensure that a GitHub `issue `_ exists before submitting your contribution through a pull request. - * There are two templates available to create a new Github issue, select the one matching your issue type. -* Pull request will only be merged if there is an associated issue (different solutions/implementations can be discussed on the issue). - * And at least one approval through the GitHub review process. +- Please ensure that a GitHub `issue `_ exists before submitting your contribution through a pull request. + + - There are two templates available to create a new Github issue, select the one matching your issue type. +- Pull request will only be merged if there is an associated issue (different solutions/implementations can be discussed on the issue). + + - And at least one approval through the GitHub review process. A contribution can be either a **patch** or a **feature**: - * **patch**: includes a bug-fixes or an outstanding enhancement; besides going to the **master** branch, we also backport the same contribution to the latest **wmagent** branch. - * **feature**: includes major developments or potentially disruptive changes and are included in feature releases following a monthly cycle. + +- **patch**: includes a bug-fixes or an outstanding enhancement; besides going to the **master** branch, we also backport the same contribution to the latest **wmagent** branch. +- **feature**: includes major developments or potentially disruptive changes and are included in feature releases following a monthly cycle. From the contribution types, we can also define at least two different branches: - * **master**: it includes both features and patches contributions and it only reaches production when there is a CMSWEB/WMAgent upgrade. - * **wmagent/crab/dbs**: it includes code and **patch** tags which are already deployed to production. Only patches/hotfixes make it to these branches. + +- **master**: it includes both features and patches contributions and it only reaches production when there is a CMSWEB/WMAgent upgrade. +- **wmagent/crab/dbs**: it includes code and **patch** tags which are already deployed to production. Only patches/hotfixes make it to these branches. In general, we always start developing against the **master** branch, such that we can profit of the CI Jenkins infrastructure to evaluate and test our pull request. In rare cases, we need to create a **temporary** fix that has to live only on the **wmagent** branch. If it's a temporary fix, it doesn't go to **master**. @@ -52,7 +56,8 @@ Contributing **Step 2**: Create a local branch to start working on a proposal for that issue, branching off the "master" branch:: - git checkout -b your-branch-name origin/master + git fetch upstream + git checkout -b your-branch-name upstream/master **Step 3**: implement your awesome feature/patch to fix the issue. @@ -63,8 +68,9 @@ Contributing **Step 5**: Now it's probably time to check the unit tests and: - * make sure unit tests for the modules you touched are still succeeding - * create new unit test(s) + +- make sure unit tests for the modules you touched are still succeeding +- create new unit test(s) **Step 6**: repeat the Step 4 to add and create a new commit. We **highly recommend** a separate commit for test-related changes like unit tests, emulation, json data,templates and so on. In addition to unit tests, we ask you that any code refactoring **not changing any logical blocks**, as pylint, pep8 convention, fixing typos, etc; to be added to the same test commit. @@ -75,15 +81,45 @@ Check the commits you have on your branch and then push them to your forked repo git log -10 --pretty=oneline --decorate git push origin your-branch-name -**Step 8**: then create a pull request either from your fork, or from the official github repository. There is a pull request template that you need to edit/update before confirming the pull request creation. -If you're proposing a **patch** that needs to be backported to a specific branch, please make sure to mention it in your pull request, such that the project responsible can properly label it. If your pull request requires further effort, please use the labels "Do not merge yet" and "Work in progress". -The pull request title has to be meaningful as well, even though it's not used for the release notes. You might want to describe your changes and the reason behind that, it's quite helpful when we need to check a module's history. +**Step 8**: then create a pull request either from your fork, or from the official github repository. There is a pull request template that you need to edit/update before actually creating your pull request: + +- please make sure to provide a meaningful and short PR title; +- also provide a short description of the changes provided in the PR (if useful, also provide a reason for that decision and implementation) +- provide any possible dependency and/or external changes that are required to go with your pull request (kubernetes, COMP packages, deployments, etc). + +If your pull request requires further effort and/or it's still a work in progress, please use one or both labels like: "Do not merge yet" and "Work in progress". If you're proposing a **patch** that needs to be backported to a specific branch and/or pushed to production right away, then please make sure to mention it in your pull request such that the proper actions and labelling are done. + +**Step 9**: before asking for a pull request review, please make sure to provide any other material that is necessary to go together with your WMCore contribution (deployment, configurations, kubernetes, etc). +Once your pull request is ready to be reviewed, use the `Reviewers` option to ask a specific person(s) to review it. Watch your pull request for comments and feedback. +If further changes are required in your pull request, you might want to provide them in a separate commit, making it easier to review only the latest differences. + +**Step 10**: when your pull request gets approved by at least one reviewer, you must squash your commits according to what has been explained above. In short: -**Step 9**: once your pull request is ready to be reviewed, use the `Reviewers` option to ask a specific person(s) to review it. Watch your pull request for comments and feedback. -If further changes are required to your pull request, you might want to provide them in a separate commit, making it easier to review only the latest difference. +- logical and algorithmical changes go in the first commit; +- while unit tests, pylint reformat, pep conventions, aesthetic minor improves go in the second commit. -**Step 10**: when your pull request gets approved by at least one reviewer, you must squash your commits accordingly in order to keep a clean commit history (remember, if you need to update both src/ and test/ files, then you need to squash them into the correct commits). -If you need further instructions for squashing your commits, please check `this `_ quick and simple document. +Make sure to provide meaningful, short and free of typos commit messages, since they are used in our software release notes. If you think the commit message could be better, please amend it. +If you need help squashing your commits, please have a look at this short and clear document `this `_. + +Timeframe expectations +----------------------- +People involved in the GH issues and pull requests should try commit to the following actions and their timeframes, such as: + +- GH issues: tickets inactive for more than 3 years will be candidates to be closed out without any development. +- PR review: reviewers have 3 business days to provide feedback. If changes are too deep and/or complex, even a partial review is better than no review. +- PR follow up: we ask the developer/contributor to follow up on any required changes and/or questions with a one month time period. Otherwise the team might consider it no longer relevant and it could become eligible to be closed out. + +Eventually we should integrate GH bots to start taking automated decisions based on some of these time period parameters. + +Useful pull request labels +-------------------------- + +The WMCore project has many labels, however, here is a list of the most important labels for pull request contributions: + +- ``Do not merge yet``: if changes are not fully read from your side, e.g. missing some extra validation, you might want to label your PR with this. +- ``Work in progress``: if you created a pull request for a development that you know it's still unfinished, please use this label. +- ``One approval required``: for somehow simple changes, or changes that are quite specific to a given WMCore service. +- ``Two approvals required``: for more complex changes; or changes that are more intrusive and need special attention. Automatic Tests ---------------- @@ -94,9 +130,10 @@ This infrastructure is thoroughly described in this `wiki_section `_ and you should always pass this file when running pylint locally. The project follows the conventions described in there. - * if you are proposing a brand new python module, then we expect it to have 0 pylint issues; if it's an older module - unless it's too much troublesome and dangerous - we always request to get the **E** and **W** pylint issues fixed (errors and warnings). Report type **C** and **R** are left for your consideration, if simple to fix in an IDE, then you should apply those changes and increase the code quality. If unsure, ask about it in the pull request. - * reminder: any pylint updates are supposed to go with your 2nd commit, such that code review becomes easier. + + - WMCore pylintrc is defined `here `_ and you should always pass this file when running pylint locally. The project follows the conventions described in there. + - if you are proposing a brand new python module, then we expect it to have 0 pylint issues; if it's an older module - unless it's too much troublesome and dangerous - we always request to get the **E** and **W** pylint issues fixed (errors and warnings). Report type **C** and **R** are left for your consideration, if simple to fix in an IDE, then you should apply those changes and increase the code quality. If unsure, ask about it in the pull request. + - reminder: any pylint updates are supposed to go with your 2nd commit, such that code review becomes easier. 3. **pycodestyle**: it corresponds to the pep8 checks and it should usually not report anything, these issues can be easily fixed by an IDE. @@ -105,15 +142,49 @@ This infrastructure is thoroughly described in this `wiki_section .log``. +So in case of the ``LumiList_t.py`` you would get a ``LumiList_t.log`` file. Coding Style and checks ----------------------- -We use pep8 and pylint (including pylint3) to sanitize our code. Please do the same before submitting a pull request. -WMCore defines its own pylintrc `here `_, thus you should always pass this file as an argument when running pylint locally. +We use pep8 and pylint to sanitize our code. Please do the same before submitting a pull request. +WMCore defines its own pylintrc `here `_ standards. +Thus, when evaluating your changes, please run pylint by passing this pylintrc file in the command line, your code should get scored 8 or above. +Unless there is a very good reason, we discourage the use of pylint disable statements. Extra documentation ------------------- @@ -121,3 +192,115 @@ Extra documentation In case you're having issues with git and working through a branch feature, you might want to have a look at this old'ish `wiki `_ in our WMCore wiki documentation. In addition to that, we've also compiled a long list of important git `commands `_. If none of those work for you, google and stackoverflow will be your best friend. + +Structural and in-depth documentation +============ + +WMCore structure +------------------- + +When developing utilitarian libraries that do **not** depend on any of the +WMCore libraries, create it under:: + + src/python/Utils/ + +this package can be easily shared with external projects, so please ensure +it's well covered by unit tests and that its documentation (docstrings) are +as clean and clear as possible. + +Core libraries, which can be shared among the several WMCore services, should +be implemented under:: + + src/python/WMCore/ + +some of those are also shared with external projects. + +When developing a new WMAgent component - which inherits from the ``Harness`` +module, please use the following structure:: + + src/python/WMComponent// + +and if it requires any specific config file, use:: + + src/python/WMComponent//DefaultConfig.py + +WMCore/bin/wmcore-new-config is a config file aggregator that takes +as input directories roots and aggregates the config files. This enables +operators to generate one config file and edit it as they see fit. Beware that +if you import a DefaultConfig.py file in your DefaultConfig.py file this +can give errors when generating this file as it would overwrite existing +values. + +If components contain parameters, those should be defined in the WMAgent default configuration/template file:: + + etc/WMAgentConfig.py + + +On what concerns the tests, the module:: + + src/python/WMQuality/TestInit.py + +contains a set of methods often used in testing for performing mundane tasks, +such as setting up database connections, deploying/cleaning database schema, etc. +It is recommended that you use them to facilitate maintainability. + +To facilitate using methods from the TestInit class for loading schemas, put +create statements in a ``.../Create.py`` method, following a similar +structure as can be found in the Create.py methods under ``./src/python/WMCore/Agent/Database/``. +Backend has either the value ``Oracle`` or ``MySQL``. + +If you are creating a new WMCore package, or making changes for an external +project, verify whether your package - or an upper package - is listed under +the list of packages for each service, in the file:: + + setup_dependencies.py + +If not, then please add it whenever it's necessary. This is used by the package +builder for new releases. + +Reserved words +------------------- + +To prevent having to pass (a potential growing) number of parameters to +classes, there will be several reserved attributes in the thread class +to facilitate ease of use of much used objects. Below a list and how +you can assign them. These attributes enable (on a thread level) to +change values of certain often used objects (e.g. switching database +access parameters). It is not obligatory to use them just do not use +them in any other way than described here:: + + import threading + myThread = threading.currentThread() + + # pointer to the logger used in the module + myThread.logger + + # pointer to current database interface object (WMCore.Database.DBInterface) + myThread.dbi + + # the current database transaction object used (WMCore.Database.Transaction) + myThread.transaction + + # A dictionary of factories. Factories are instantiated with a namespace + # (e.g. WMCore.BossAir.MySQL) and load the appropriate objects. This is especially + # useful if you work with multiple backends. + myThread.factory + + # A String representing the backend. Currently there are 2: "MySQL", "Oracle". + # These backends are used to define the proper namespace for importing data + # access objects (DAO) from factories. + # E.g. I can define a namespace: "WMCore.BossAir"+myThread.backend . + myThread.backend + + # pointer to current message service object being used + myThread.msgService + + # pointer to current trigger service object being used + myThread.trigger + + # pointer to arguments used by this component + myThread.args + + # dictionary of transactions. It is a - optional - possibility + # to synchronize commits to multiple databases (or the same database) + myThread.transactions diff --git a/standards/README b/standards/README deleted file mode 100644 index ee063317b7..0000000000 --- a/standards/README +++ /dev/null @@ -1,379 +0,0 @@ -TOC -=== --SETUP --CODE STANDARD --RESERVED WORDS --DEVELOPMENT --->DEVELOPMENT (DATABASES) --TESTING --OTHER PROJECTS: PRODAGENT, T0, CRAB - -Quality Officer: fvlingen@caltech.edu - -The following are guidelines for development in WMCORE. -If you are working for an external project you are advized to -follow these guidelines too for that project as it helps -to create a consistent structure for code development and testing -which minimizes maintenance and debugging. - -If you have any problem with using the instructions in -this document, please contact the -quality officer as he/she can assist you. The information in -this document perhaps not always completete but giving your -feedback will help improving it for all developers. - -SETUP -===== -To setup the library it is assumed the following conditions -hold: - --You have a recent version of the prodagent installed (this -is mainly used for dependency package compliance such as mysql, -etcs.. --Edit the WMCORE/standards/setup.sh file appropriately --If you are integrating this with an exterenal package make sure these -settings are set correctly too - -so typically you would have something like this: - -source your external package setup.sh -source the WMCORE setup.sh - -Also edit any other setup_* files as you see fit. - -If you want to run the tests. Read the section on Testing. - -Assuming you want to run a specific test with a sepcific backend you can -do the following: - -edit the 'test_code' file and comment out the backends you do not want to test -(e.g. oracle) - -edit the 'conf_test_mysql.py' and locate the test you want to test. (e.g. ProxyTest) - -Copy paste this code after the last test is loaded. It empties the tests array and only -inserts your speicific test: - -tests = [] - -try: - x=ProxyTest() - tests.append((x,"fvlingen")) -except Exception,ex: - if not errors.has_key("fvlingen"): - errors["fvlingen"] = [] - errors["fvlingen"].append(("ProxyTest",str(ex))) - -Save the file and execute test_code - -Note: when you first run the tests mysql will initialize things and for some -reason some tests fail for the first time. Running them again (after mysql -is initialized) makes them succeed. - -CODE STANDARD: -============= -Use pylint and the pylint test file located under: -WMCORE/standards/.pylintrc - -Test files need to be located under WMCORE/test/python/ and -need to mirror the structure you use for the packages under -WMCORE/src/python where every directory and test file is -augmented with a _t and the class should be augmented with 'TEST' -If you develop for an external package you mimic this structure -in the external package directory structure. - -E.g.: if you have a package: - -src/python/WMCORE/MsgService/MsgService.py - -you will have a test in the pacakge: - -test/python/WMCORE_t/MsgService_t/MsgService_t.py and in it -class: MsgserviceTest which inherits from: unittest.TestCase. - -In order to ensure the testsuite can pick up the test implement -the runTest method in your test class which describes the sequence -in which tests need to be run. - -When developing a component use the following structure: - -for component file that inherits from the harness: -....WMComponent// - -for config file: -....WMComponent//DefaultConfig.py - -WMCORE/bin/wmcore-new-config is a config file aggregator that takes -as input directories roots and aggregates the config files. This enables -operators to generate one config file and edit it as they see fit. Beware that -if you import a DefaultConfig.py file in your DefaultConfig.py file this -can give errors when generating this file as it would overwrite existing -values. - -for storing the message handlers: - -...WMComponent//Handler - -If you work on an external project you will work with a different -root than .../WMComponent - -All files should be tested against the .pylintrc format and need -to get a minimum score of 8 or higher. In case that is not possible -due to certain language constructs being used, the pylint style file -can be accomodated to reflect this. - -Potential log files for tests should have a name: .log -So in case of the MsgService_t.py you get a MsgService_t.log file - -If components contain parameters they should be defined in a file -'DefaultConfig.py' using the WMCORE/src/python/WMCore/Agent/Configuration -module. - -the WMCORE WMQuality.TestInit class contains a set of methods used often -in testing for doing mundane stuff such as setting up connections. It is -recommended that you use them to facilitate maintainability. - -The TestInit class is based on the WMCORE/src/python/WMCore/WMInit class. It -contains a set of often used methods for conveniently dealing with various -mundane things such as database setup or initialization. - -To facilitate using methods from the TestInit class for loading schemas put -create statements in a .../Create.py method following a similar -structure as can be found in the Create.py methods in the wmcore module -MsgService and Trigger. Backend has either the value Oracle or MySQL - -RESERVED WORDS: -============== -To prevent having to pass (a potential growing) number of parameters to -classes, there will be several reserved attributes in the thread class -to facilitate ease of use of much used objects. Below a list and how -you can assign them. These attributes enable (on a thread level) to -change values of certain often used objects (e.g. switching database -access parameters). It is not obligatory to use them just do not use -them in any other way than described here. - -import threading -myThread = threading.currentThread() -# pointer to the logger used in the module -myThread.logger -# pointer to current database interface object (WMCore.Database.DBInterface) -myThread.dbi -# the current database transaction object used (WMCore.Database.Transaction) -myThread.transaction -# A dictionary of factories. Factories are instantiated with a namespace (e.g. WMCore.MsgService.MySQL) and load the appropriate objects. This is especially useful if you work with multiple backends. -myThread.factory -# A String representing the backend. Currently there are 2: "MySQL", "Oracle" . These backends are used to define the proper namespace for importing data access objects (DAO) from factories. -# E.g. I can define a namespace: "WMCore.MsgService"+myThread.backend . -myThread.backend -# pointer to current message service object being used -myThread.msgService -# pointer to current trigger service object being used -myThread.trigger -# pointer to arguments used by this component -myThread.args -# dictionary of transactions. It is an (optional) possibility -# to synchronize commits to multiple databases (or the same database) -myThread.transactions - -DEVELOPMENT: -=========== - -Development follows typically the following (iterative) cycle: - -(1) Develop your module(s) in src/python/WMCore or src/python/WMComponent -or if you develop for a dependent project something like: src/python/Component - -(2) Use the WMCORE/standards/test_style.sh script to generate a style -report and improve your code until it (at least) reaches the rating threshold -(currently 8) - -(3) Check/edit the WMCORE/setup.py file to see if your package is listed. -If not add it to the packages list. This is used by the package builder -for new releases. If you develop for another project update that setup.py -file. - -(4) Develop your tests in .../test/python mirroring the structure in src/python -(4.1) Make sure that the database access parameters (and other relevant -parameters) are extracted from the environment variables of the setup* files. -Currently it assumes that there is one database per backend (except -for the proxy test case). If you need more databases than are currently defined -in the setup files, add these environment variables to the appropriate setup files -Unless: these variables will be specific to this one test , or these -test are for an external package (in which case you need to update the -setup files of that package). - -(5) (Optional as this can be autogenerated by package quality officer). -Add your module and/or files (including your tests) you develop to -the WMCore/standards/test_style file, with your unique identifier in the -packages list. This is used by the quality officer to find the responsible -person in case of quality audits (e.g. testing). Note that you can add either -individual files or whole subdirs. If your responsible for a whole subdir add -this whole subdir. External projects should create or generate their own -test_style file in their own project package. The test_style file can be generated -using the test_generate script (this is the task of the quality officer). -External projects need to create their own test_generate script (copy the -WMCORE one and modify it, is the easiest way). This scripts also generates -the test suite files. - -(6)Develop your tests in test/python mirroring the structure in src/python -(6.1) Make sure that the database access parameters (and other relevant -parameters) are extracted from the environment variables of the setup* files. -Currently it assumes that there is one database assume per backend (except -for the proxy test case). If you need more databases than are currently defined -in the setup files, add these environment variables to the appropriate setup files -Unless: these variables will be specific to this one test or if you develop -for an external package in which case you need to add them to the settings -files of that project. - -(7) (Optional as this can be autogenerated by quality officer). -When your test is finalized add it to the appropriate backend (some -test might need to be added to multiple backends) in the config_.py -file. You import the test module and add a tuple (test instance, and your unique -id) to the test array. Your id (e.g. name) is used by the quality officer in -case of anomalies during testing. If you work for an external project you -need to add it at the appropriate test suite for that project. - -DEVELOPMENT (DATABASES) -====================== - -Some components have their own database tables. In order to prevent name clashes -prefix your tables with something that easily associates it to the component. - -Some examples that are being used: - -ms_ MsgService -tp_ ThreadPool -err_ ErrorHandler -tr_ Trigger - - - -TESTING: -======= - -(it is assumed you use the setup described in the SETUP section). - - -This directory also contains several files. The following prefixes -are used: - -setup : files for setting your environment. These are the only -files you need to edit when running the tests on your machine. Different -backends (mysql and oracle) have there own setup files (setup_mysql.sh, -setup_oracle.sh) that are used in the various test files (to prevent -having to hardcode these variables in the tests themselves. - -clean : cleans generated log files, pyc files, etc... Separate files -are available for the different backends. - -start : startup scripts for the various backends. - -config_test : enables you to config the different tests for different backends - before running - -test : actually test scripts. Currently there are 4 scripts. Two -for the code style, one for the code itself and a script (test_generate) -which generates the actual test_style, test_code, config_test_mysql.py -and config_test_oracle.py files by analyzing the cvs repository log -(requires access to the cvs repository to generate log) - -NOTE: if you test ensure you are testing using the environment that is packaged -with wmcore applications (e.g. you can install for example the latest prodagent -rpms and source this environment (minus the prodagent and prodcommon python libraries). - -test_generate -------------- - -This script generates various files to prepare for testing. -During generation it also provides a report for test files that -do not use the proper convention for importing tests (level 1 failure) -it writes these to failures1.log - -Note: the test_generate script should be used mainly to generate -the initial test configurations. After that these configuration -can be tweeked manually and committed incrementally. - -The test_generate script generates various test configurations. -Before running them edit them (e.g. you might want to remove -some tests for certain backends). - -When you run the actual tests using the test_code script -it will again generate a report which highlights the tests that could -not be instantiated (level 2 failure). By default these failures -are written to failures2.log, however since we test with multiple -backends it it desirable to edit this filename in the -multiple generated conf_test*.py files (e.g. failure2_mysql.log -and failures2_oracle.log) - -Finally the tests that are run can generate errors (level 3 failure). -By default these errors and failures are written to failures3.log. -Edit the name of this file so the different backends write to -unique files. - -Note: that some tests require an empty database. If tests preceding -a this test do not empty the database this might result in errors -for this test. The test framework cleans the default database -but this might not be sufficient. - -Note: when generating the tests and style checks the mapping from -developer to module might not be correct. For example if user 'fvlingen' -has moved files to a new directory for better organization he -might be associated to modules he did not develop. - -After generation check the generated files and adapt them appropriately -also check what tests you want to run for mysql, oracle or both. - -Once all files are configured appropriately you typically do: - -(1) source setup.sh -(2) (optional and usually only done by the quality officer) ./test_generate.sh -(3) (optional) edit the mapping in the generated files -(4) ./test_style -(5) ./test_code - -(repeat 4 and 5 if necessary) - -The test scripts generate a summary when anomalies occur. - - -a set of .sh files to setup and run tests - --edit the setup*.sh scripts to reflect your settings (it assumes you use the cms packages -for running the tests (e.g. mysql, sqlalchemy). --source the setup.sh file (once) - -(optional) edit the test.sh file to disable some tests. -run test.sh (repeat as necessary) - -After sourcing setup.sh you can also test your code quality -using the quality.sh command. Either invoke -quality.sh with a file or directory, or edit -the myfiles.sh script to run quality tests on several -dirs. If you name your output files quality*.txt, -cleanup.sh will automatically remove them when invoked. - -OTHER PROJECTS -============== - -To facilitate uniformity and reuse of code we strongly advise that you follow the structure -outlined in this document for your project where possible. In particular following the same -code style standards and layout. - -E.g. for the ProdAgent project components will be sub directories in: -PRODAGENT/src/python/PA/PAComponent - -And tests for these components will be sub directories in: - -PRODAGENT/test/python/PA_t/PAComponent_t - -If components contain parameters they should be defined in a file 'DefaultConfig.py' -using the WMCORE/src/python/WMCore/Agent/Configuration module. - -the WMCORE WMQuality.TestInit class contains a set of methods used often -in testing for doing mundane stuff such as setting up connections. It is recommended -that you use them to facilitate maintainability. - -To facilitate using methods from the TestInit class for loading schemas put create -statements in a .../Create.py method following a similar structure as can -be found in the Create.py methods in the wmcore module MsgService and Trigger. Backend -has either the value Oracle or MySQL