-
Notifications
You must be signed in to change notification settings - Fork 107
setup wmcore unittest
- Initial node setup and/or creation
- Set up for WMCore Unittest
- Executing WMCore Unittest
-
Miscellaneous
- 4 Recovering from a corrupt database
- 5 Authenticate yourself when running unittests
- 6. Checking code quality
- 7. Shutdown mysql and couch server
- 8. Update the current code base.
- 9. In case your unittests need to access central services:
- 10. Using git bisect to find which commit breaks a particular test
- Set up for Python2 WMCore Unittest with docker (DEPRECATED)
- Set up for WMCore Unittest with Oracle (outdated)
- Troubleshooting
- Useful scripts
Brief Summary (for Linux)
- WMCore unittests requires setting up a RDBMS (MariaDB or Oracle) and CouchDB, in addition to many python libraries. The easiest way to get the full stack is through the deployment of the WMAgent RPM from the
cmsrep
repository. - This tutorial assumes you have the proper grid certificates available (for external service communication)
- This tutorial assumes you also have the
git
client installed. - It also assumes you have Condor installed on the same node, even though it's not mandatory to have it. Some unit tests require Condor to run properly, e.g. BossAir_t module
- Deployment of wmagentpy3-dev rpm is only used for setting up external sources (including nose). Actual WMCore code will be checked out from git and linked with symbolic link.
-
deploy_unittest_py3.sh
will do all the work for you. There is no need to deploy anything in advance.
You can choose between two different resources/hardware:
- create an openstack VM on CERN OpenStack, or
- deploying docker on your local (or a remote machine). See section 1.1 for further details.
If you create an openstack VM, mind the following recommended settings:
- flavor: m2.medium
- boot source: from the latest
CC7 Base - x86_64
image.
Prerequisite: Download docker https://www.docker.com/products/overview/
Run the docker container which contains a CC7 distribution, all our software, and some extras. First you need to pull the WMAgent image from the CERN Gitlab Registry:
## you might have to first login to the registry (your CLI password is available under User Profile --> CLI Secret
docker login gitlab-registry.cern.ch
## then you can pull the latest image
docker pull gitlab-registry.cern.ch/cmsdocks/dmwm:wmcorepy3_tests
Now that you have the image in your local machine, you can run it with the command below. But notice that you will need to mount your grid user credentials (usercert/userkey pem files) and your WMCore remote clone, for a seamless integration with your development environment.
export LOCAL_DIR=blah
cd $LOCAL_DIR
git clone https://github.com/dmwm/WMCore.git
## note that the command below assumes that your grid certificate is available under $LOCAL_DIR/certs
docker run -v $LOCAL_DIR/certs:/home/dmwm/certs -v $LOCAL_DIR/WMCore:/home/dmwm/wmcore_unittest/WMCore -it --entrypoint /bin/bash gitlab-registry.cern.ch/cmsdocks/dmwm:wmcorepy3_tests
This will download the container image from Docker Hub and start it. You don't have to "get" the image yourself if you don't want to, but without the docker pull
command it will not be kept up to date.
The first -v option maps a directory on the local host (~/DMWM/certs) to a certs/ directory in the container which is presumed to contain the servicekey.pem and servicecert.pem from step 6 below.
While the container comes with a version of our code (current at the time of creation), the 2nd -v
option above mounts code from your host machine into the container making it easy to use your editor.
Setup the environment, start couch and MySQL:
source env_unittest_py3.sh
$manage start-services
Carry on. You will find some useful scripts in ContainerScripts/
including one to run a slice of the unit tests. There is also an update git script that is used to update the code inside the container to the very latest master (this assumes you omitted the 2nd -v option above).
See https://github.com/dmwm/WMCore/wiki/Docker-and-WMCore for a discussion on how these containers were created.
PS.: If your docker container run out of space, you might have to run the following command in order to make
some space by deleting old containers:
docker system prune -a -f
First we need to download the script to set up unittests (in your current working directory).
$ curl https://raw.githubusercontent.com/dmwm/WMCore/master/test/deploy/deploy_unittest_py3.sh > deploy_unittest_py3.sh
The command below will deploy the latest wmagentpy3-dev
version available in cmsrep
comp repository. It will also update the source code to master
HEAD.
You can also change the WMA_TAG inside the script to the WMAgent version you want to deploy.
$ sh deploy_unittest_py3.sh -r dmwm -b master
Alternatively, you can specify a wmagentpy3-dev
version (-v), the git organization (-r) and the branch to pull the source code from (-b)
$ sh deploy_unittest_py3.sh -v 1.0.16.pre2 -r dmwm -b master
If everything goes well, both MariaDB and CouchDB should be up and running. You can check it with:
source env_unittest_py3.sh
$manage status
PS.: In case the WMAgent deployment fails in the installation step (sw), you might need to manually install one RPM dependency:
bzip2 tk perl-ExtUtils-Embed compat-libstdc++-33 libXmu libXcursor libXrandr libXft mesa-libGLU libXi libXinerama libXft-devel libXpm perl-Test-Harness libX11-devel libXpm-devel libXext-devel mesa-libGLU-devel perl-Switch perl-Env perl-Thread-Queue
Just a FYI, the "unittestdeploy" directory will contain the RPM content while "wmcore_unittest" directory contains the content as checked out from git.
This example test spec which doesn't use db.
$ cd $TEST_DIR/WMCore/test/python/WMCore_t/WMSpec_t
$ python3 WMStep_t.py
For more info about nose, see http://nose.readthedocs.org/en/latest/usage.html
$ cd $TEST_DIR/WMCore/test/python/WMCore_t
$ nosetests WMSpec_t
Like above, but say you just want to run the one test you are trying to fix:
$ cd $TEST_DIR/WMCore/test/python/WMCore_t/WMSpec_t/StdSpecs_t
$ nosetests TaskChain_t.py:TaskChainTests.testMultithreadedTasksTaskChain
where before the : you have the file name, after the : the class and function names.
You can also select all the unit tests under the patch to run.
$ cd $TEST_DIR/WMCore/
$ python3 setup.py test --buildBotMode=true --reallyDeleteMyDatabaseAfterEveryTest=true --testCertainPath=test/python/WMCore_t/WMSpec_t/StdSpecs_t/
code is the directory where the checkout was done. SLICES is the number of slices you want create for all the unittests (jenkins use 10). SLICE is the slice number you want to run, usually it's the same SLICE that failed in Jenkins.
$ python3 $TEST_DIR/WMCore/setup.py test --buildBotMode=true --reallyDeleteMyDatabaseAfterEveryTest=true --testCertainPath=$TEST_DIR/WMCore/test/python/ --testTotalSlices=$SLICES --testCurrentSlice=$SLICE
If you screw up the underlying MySQL/MariaDB database, you may need to drop and recreate it:
$ mysql -u unittestagent -p --sock $INSTALL_DIR/current/install/mysql/logs/mysql.sock
and at the DB prompt type
drop database wmcore_unittest; create database wmcore_unittest;
Some unittests check the inetraction between WMCore code and external existing services. In order to run such tests, it is necessary that the user authenticates himself. There are two ways of authenticating. You can either use a proxy file, or you can use certificates files. Some unittests will work with either, while some require to have certificate files (such as DQMUpload_t
).
BEWARE: The files you will deal with in the following commands can be used to impersonate you if they fall into the wrong hands! handle them with caution.
Start by setting up the environment in the container or VM with:
[@dockercontainer ~]$ source env_unittest_py3.sh`
[@dockercontainer ~]$ $manage start-services # this is not compulsory, but if you need it, you can do it now
Make sure that host/user certificates are ok (i.e. if have been loaded when sourcing env_unittest_py3.sh
), checking that the following env variables point to existing files:
[@dockercontainer ~]$ ls $X509_HOST_CERT
[@dockercontainer ~]$ ls $X509_HOST_KEY
[@dockercontainer ~]$ ls $X509_USER_CERT
[@dockercontainer ~]$ ls $X509_USER_KEY
If not, you can manually source the new locations of your certificates:
- I assume that you run the docker container with
docker run -v ${CERT_DIR}:/home/dmwm/certs-mount
, where${CERT_DIR}
is the directory that you keep you certificates in your laptop. The same steps applies in a VM, you just have to adjust the paths. - get a
.p12
Grid certificate file from cern account service, save it to${CERT_DIR}
on your laptop. -[@dockercontainer ~]$ openssl pkcs12 -in ~/certs-mount/2021_myCertificate.p12 -clcerts -nokeys -out ~/certs/usercert.pem
: (enter your grid certificate pwd) -
[@dockercontainer ~]$ openssl pkcs12 -in ~/certs-mount/2021_myCertificate.p12 -nocerts -out ~/certs/userkey.pem
: unlock the grid certificate inserting your grid certificate pwd, enter two times a new pwd for protecting your private keyuserkey.pem
. [@dockercontainer ~]$ chmod 400 ~/certs/userkey.pem
-
[@dockercontainer ~]$ openssl rsa -in ~/certs/userkey.pem -out ~/certs/userkey_nopwd.pem
: enter the pwd of your private keyuserkey.pem
to get a passwordless private key. This allows you to run unittests without inserting the password protecting the certificate key every time that it is used by a unittest. Beware: this file can be used to impersonate you! [@dockercontainer ~]$ chmod 400 ~/certs/userkey_nopwd.pem
[@dockercontainer ~]$ export X509_HOST_CERT=/home/dmwm/certs/usercert.pem
[@dockercontainer ~]$ export X509_HOST_KEY=/home/dmwm/certs/userkey_nopwd.pem
[@dockercontainer ~]$ export X509_USER_CERT=/home/dmwm/certs/usercert.pem
[@dockercontainer ~]$ export X509_USER_KEY=/home/dmwm/certs/userkey_nopwd.pem
- annotation: I export the grid certificate into a directory that lives only in the docker filesystem, not in a dicrectory that is mounted into the host. this way i am sure that when i exit the container the
--rm
parameter above will remove the passwordless private key from my system
Instead of dealing with certificates, a faster way of authenticating yourself is using a proxy file, but this does not work for every unittest. I suggest trying this out first, then if the unittest fail try using the certificates.
Using a proxy file means providing into the docker container at the path /tmp/x509up_u1000
(similar statements apply in the case of a VM) the proxy file you get in lxplus
when you run voms-proxy-init -voms cms
with (the proxy expires after ~1day, so you may need to repeat this procedure even if you do not exit the docker container)
[@laptop ~]$ ssh -XY lxplus.cern.ch
[@lxplus ~]$ voms-proxy-init -voms cms
-
[@laptop ~]$ scp lxplus.cern.ch:/tmp/x509up_u${UID} ${CERT_DIR}
use the same${CERT_DIR}
as above, set${UID}
to your lxplus user id. Anyway,voms-proxy
should tell you the path where it created the proxy file. [@dockercontainer ~]$ cp ~/certs-mount/x509up_u99307 /tmp/x509up_u1000
- This is it. This line will load your proxy file without requiring any env variable.
We use pylint to automatically analyze our code for errors and bad coding practice. We keep our own standards file which allows us to use camel case for variables, etc. To run a report, execute a command like this:
$ pylint --rcfile=$TEST_DIR/WMCore/standards/.pylintrc some_python_file_or_directory/
Most of the codes are self explanatory, but there is more help available for some at http://pylint-messages.wikidot.com/all-codes
$ $manage stop-services
Once unittest is set you don't have go through the first step for new update. Assume everything was set up before, go to the directory where the initial setup was made. (-u for update, -r for git repository name, -b for branch name)
$ sh deploy_unittest_py3.sh -u -r dmwm -b master
In order to contact central services (DBS, PhEDEx, etc), we need to also create a proxy and copy this file into (example):
$ cp myproxy.pem $TEST_DIR../certs/servicecert.pem
$ cp myproxy.pem $TEST_DIR../certs/servicekey.pem
Alternatively you can use your certificate and key directly (however, the key needs to be unencrypted so above option is recommended although you need to renew the proxy often).
To create the cert and unencrypted key (with -nodes option) from p12 file.
$ openssl pkcs12 -in myCert.p12 -clcerts -out $TEST_DIR../certs/servicecert.pem -nokeys
$ openssl pkcs12 -in myCert.p12 -out $TEST_DIR../certs/servicekey.pem -nocerts -nodes
and change the cert, key file permission
$ chmod 600 $TEST_DIR../certs/servicecert.pem
$ chmod 400 $TEST_DIR../certs/servicekey.pem
First, take a look at https://www.kernel.org/pub/software/scm/git/docs/git-bisect.html which is full documentation for git bisect. Strangely, git bisect has to be run from the root directory of the git tree, so you will see all my commands have (cd blah
prepended to them.
Verify a patch is broken in master:
$ git checkout master
$ nosetests MonteCarlo_t:MonteCarloTestCase.testLHEProductionWorkload
Ok, it's broken. Let's try to find a place it's still working. Because the testing infrastructure may have changed, it doesn't make sense to go as far back as possible, so let's try going back in 1-year steps:
$ git checkout `git rev-list -n 1 --before="2015-01-01 00:00" master
Here the test is OK, so let's tell git bisect this:
$ git checkout master
$ (cd /storage/local/data1/ewv/wmcore_unittest/WMCore; git bisect start)
$ (cd /storage/local/data1/ewv/wmcore_unittest/WMCore; git bisect bad)
$ git checkout `git rev-list -n 1 --before="2015-01-01 00:00" master`
Note: checking out '267b8164a534ea3bf7b649ac122f0bc4f5e86961'.
$ (cd /storage/local/data1/ewv/wmcore_unittest/WMCore; git bisect good)
Bisecting: 400 revisions left to test after this (roughly 9 steps)
error: You have local changes to 'src/couchapps/AlertsCollector/vendor/couchapp/_attachments/jquery.js'; cannot switch branches.
Ok, now the checkout failed to switch because of local changes. This is probably because git is changing end-of-line characters on me. Change your config settings with git config core.autocrlf false
, do a force checkout of the last commit mentioned in git bisect log
, and carry on.
This section explains how to get the Docker image for a Python2 WMCore stack, which is very similar to the instructions_above.
Pull and run the Python2-based WMCore container with:
docker pull gitlab-registry.cern.ch/cmsdocks/dmwm:wmcore_tests
docker run -v $LOCAL_DIR/certs:/home/dmwm/certs -v $LOCAL_DIR/WMCore:/home/dmwm/wmcore_unittest/WMCore -it --entrypoint /bin/bash gitlab-registry.cern.ch/cmsdocks/dmwm:wmcore_tests
Next, you need to source the python3 WMCore environment with:
source env_unittest.sh
now you can start services (CouchDB and MySQL):
$manage start-services
and you are ready to run the unit tests - with python2 - for a single module, e.g.:
cd $TEST_DIR/WMCore/
nosetests test/python/Utils_t/FileTools_t.py
....
----------------------------------------------------------------------
Ran 4 tests in 0.061s
OK
alternatively, you can run those unit tests as they are executed in Jenkins. So, running a full slice out of 10, e.g.:
cd $TEST_DIR/WMCore/
python setup.py test --buildBotMode=true --reallyDeleteMyDatabaseAfterEveryTest=true --testCertainPath=test/python --testTotalSlices=10 --testCurrentSlice=2
It follows basically the same procedure as above. However, we need to make a few local changes to 3 files before we run the deployment.
-
create a new oracle account NewOracleAccount
-
WMAgent_unittest.secrets file: replace MYSQL by the ORACLE credentials, for instance:
ORACLE_USER=(write your oracle user name)
ORACLE_PASS=(write your oracle password)
ORACLE_TNS=(write your tns name, e.g. INT2R_NOLB)
- env_unittest_py3.sh file: remove the DBSOCK line; update the DATABASE (you need to provide the actual values, it does not get automatically filled from the secrets file) and the DIALECT (Oracle) variables. Diff would be something like:
amaltaro@alan-wmacloud:/data/amaltaro/WMAgent $ diff -rup env_unittest_py3.sh.ori env_unittest_py3.sh | colordiff
-export DBSOCK=$INSTALL_DIR/current/install/mysql/logs/mysql.sock
-export DATABASE=mysql://unittestagent:passwd@localhost/wmcore_unittest
+export DATABASE=oracle://ORACLE_USER:ORACLE_PASS@ORACLE_TNS
-export DIALECT=MySQL
+export DIALECT=Oracle
- deploy_unittest_py3.sh: before you run this script, make sure to first comment out the
mysql
database creation line; als comment out the line downloading theenv_unittest_py3.sh
andWMAgent_unittest.secrets
files, since you do not want them to get overwritten. Diff would be something like:
amaltaro@alan-wmacloud:/data/amaltaro/WMAgent $ diff -rup deploy_unittest_py3.sh.ori deploy_unittest_py3.sh | colordiff
- curl -s https://raw.githubusercontent.com/dmwm/WMCore/master/test/deploy/env_unittest_py3.sh > env_unittest_py3.sh
- curl -s https://raw.githubusercontent.com/dmwm/WMCore/master/test/deploy/WMAgent_unittest.secrets > WMAgent_unittest.secrets
+ #curl -s https://raw.githubusercontent.com/dmwm/WMCore/master/test/deploy/env_unittest_py3.sh > env_unittest_py3.sh
+ #curl -s https://raw.githubusercontent.com/dmwm/WMCore/master/test/deploy/WMAgent_unittest.secrets > WMAgent_unittest.secrets
- mysql -u unittestagent --password=passwd --sock $INSTALL_DIR/current/install/mysql/logs/mysql.sock --exec "create database wmcore_unittest"
+# echo "--- when prompted type 'passwd' (without ')"
+# mysql -u unittestagent -p --sock $INSTALL_DIR/current/install/mysql/logs/mysql.sock --exec "create database wmcore_unittest"
- No space left on device
If you get following error in Mac
[dmwm@486dbd7e0a4e ~]$ $manage start-services
Starting Services...
starting couch...
/home/dmwm/unittestdeploy/wmagent/1.1.10.pre7/sw/slc7_amd64_gcc630/external/couchdb15/1.6.1-comp/bin/couchdb: line 131: cannot create temp file for here-document: No space left on device
It can be resolved with the following command (as suggested in this link):
rm ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/Docker.qcow2
- docker.sock permission denied
If you fail to run docker login
or docker pull
with the following error:
dial unix /var/run/docker.sock: connect: permission denied
it can be resolved by changing the file permission such as:
sudo chmod 666 /var/run/docker.sock
Convert the unittest identifier that Jenkins provide, such as WMCore_t.JobSplitting_t.RunBased_t.RunBasedTest:testMultipleRunsCombine
, to a path that can be passed to nosetests
, such as test/python/WMCore_t/JobSplitting_t/RunBased_t.py:RunBasedTest.testMultipleRunsCombine
with the script
#!/usr/bin/python3
# add ~/.local/bin to $PATH
# cd ~/.local/bin
# ln -s path/to/convert_unittest_to_path.py convert_unittest_to_path.py
import sys
import os
ut = sys.argv[1]
ut = ut.split(".")
ut[-2] = ut[-2] + ".py"
tmp = ut[-1].replace(":", ".")
ut.pop(-1)
ut[-1] = ut[-1] + ":" + tmp
ut = "/".join(ut)
ut = os.path.join("test/python", ut)
print(ut)