Isolation test is aimed to test MVCC(Multiversion Concurrency Control). We can write an isolation test case to simulate the multi-user operations and control its execution order.
To perform the isolation test, we need to install CTP first.
You can get the latest version of CTP from https://github.com/CUBRID/cubrid-testtools/tree/develop/CTP.
- Checkout from git repository
cd ~ git clone https://github.com/CUBRID/cubrid-testtools.git cd ~/cubrid-testtools git checkout develop cp -rf CTP ~/
- Configurations
- touch and configure
~/CTP/conf/common.conf
grepo_service_url=rmi://192.168.1.91:11099
- Add below settings to
~/.bash_profile
and source it.export CTP_HOME=~/CTP export init_path=$CTP_HOME/shell/init_path # CTP_SKIP_UPDATE 0:update 1:skip export CTP_SKIP_UPDATE=0 export CTP_BRANCH_NAME=develop export PATH=$CTP_HOME/bin:$CTP_HOME/common/script:$PATH:$HOME/.local/bin:$HOME/bin . ~/.cubrid.sh
- touch and configure
- Make sure that CTP is installed successfully.
For more instructions to CTP, please see https://github.com/CUBRID/cubrid-testtools/blob/develop/CTP/README.md.
$ ctp.sh -h Welcome to use CUBRID Test Program (CTP) usage: ctp.sh <sql|medium|shell|ha_repl|isolation|jdbc|unittest> -c <config_file> -c,--config <arg> provide a configuration file -h,--help show help --interactive interactive mode to run single test case or cases in a folder -v,--version show version utility: ctp.sh webconsole <start|stop> For example: ctp.sh sql -c conf/sql.conf ctp.sh medium -c conf/medium.conf ctp.sh shell -c conf/shell.conf ctp.sh ha_repl -c conf/ha_repl.conf ctp.sh isolation -c conf/isolation.conf ctp.sh jdbc -c conf/jdbc.conf ctp.sh sql #use default configuration file: /home/memory1/CTP/conf/sql.conf ctp.sh medium #use default configuration file: /home/memory1/CTP/conf/medium.conf ctp.sh shell #use default configuration file: /home/memory1/CTP/conf/shell.conf ctp.sh ha_repl #use default configuration file: /home/memory1/CTP/conf/ha_repl.conf ctp.sh isolation #use default configuration file: /home/memory1/CTP/conf/isolation.conf ctp.sh jdbc #use default configuration file: /home/memory1/CTP/conf/jdbc.conf ctp.sh unittest #use default configuration file: /home/memory1/CTP/conf/unittest.conf ctp.sh sql medium #run both sql and medium with default configuration ctp.sh medium medium #execute medium twice ctp.sh webconsole start #start web console to view sql test results
You can checkout isolation test cases from https://github.com/CUBRID/cubrid-testcases/tree/develop/isolation.
$ git clone https://github.com/CUBRID/cubrid-testcases.git
$ cd cubrid-testcases/isolation
$ ls
_01_ReadCommitted _02_RepeatableRead _04_RepeatableRead_ReadCommitted _05_ReadCommitted_RepeatableRead config
- Install CUBRID
run_cubrid_install http://192.168.1.91:8080/REPO_ROOT/store_01/10.2.0.8368-b85a234/drop/CUBRID-10.2.0.8368-b85a234-Linux.x86_64-debug.sh
- Configure a config file
Touch an empty fileisolation_quick_start.conf
, setscenario
path.scenario
should be a path to a folder but not a file.scenario=${HOME}/cubrid-testcases/isolation/_01_ReadCommitted/authorization/method/
- Run
Screen output: Druing the test, CTP prints testing information like test configs, deploy status, test results, execution time and so on.
ctp.sh isolation -c ./isolation_quick_start.conf
$ ctp.sh isolation -c ./isolation_quick_start.conf ====================================== ISOLATION ========================================== [ISOLATION] TEST STARTED (Tue Jun 25 16:47:00 KST 2019) [ISOLATION] CONFIG FILE: /home/may/isolation_quick_start.conf scenario=${HOME}/cubrid-testcases/isolation/_01_ReadCommitted/authorization/method/ ----------END OF FILE---------- Available Env: [local] Build Id: 10.2.0.8368-b85a234 Build Bits: 64bits java.runtime.name=Java(TM) SE Runtime Environment ... ... ============= FETCH TEST CASES ================== The category:isolation The Number of Test Cases: 10 (macro skipped: 0, bug skipped: 0) The Number of Test Case : 10 ============= DEPLOY ================== DONE ============= TEST ================== STARTED [ENV START] local [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/method/add_user_01.ctl EnvId=local [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/method/add_user_02.ctl EnvId=local [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/method/changing_owner_01.ctl EnvId=local [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/method/changing_owner_02.ctl EnvId=local [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/method/changing_owner_03.ctl EnvId=local [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/method/drop_user_01.ctl EnvId=local [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/method/drop_user_02.ctl EnvId=local [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/method/find_user_01.ctl EnvId=local [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/method/find_user_02.ctl EnvId=local [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/method/login_01.ctl EnvId=local [OK] [ENV STOP] local ============= PRINT SUMMARY ================== Test Category:isolation Total Case:10 Total Execution Case:10 Total Success Case:10 Total Fail Case:0 Total Skip Case:0 TEST COMPLETE [ISOLATION] TEST END (Tue Jun 25 16:47:24 KST 2019) [ISOLATION] ELAPSE TIME: 24 seconds
- Test logs
During the test, the test logs are generated toCTP/result/isolation/current_runtime_logs
, after test finish, current_runtime_logs will be backuped as a.tar.gz
file.$ cd ~/CTP/result/isolation/ $ ls current_runtime_logs isolation_result_10.2.0.8368-b85a234_64bits_0_2019.6.25_6.32.56.tar.gz $ ls -l current_runtime_logs/ total 108 -rw-rw-r--. 1 may may 571 Jun 25 18:32 check_local.log -rw-rw-r--. 1 may may 839 Jun 25 18:32 dispatch_tc_ALL.txt -rw-rw-r--. 1 may may 839 Jun 25 18:32 dispatch_tc_FIN_local.txt -rw-rw-r--. 1 may may 1537 Jun 25 18:32 feedback.log -rw-rw-r--. 1 may may 2479 Jun 25 18:32 main_snapshot.properties -rw-rw-r--. 1 may may 83236 Jun 25 18:32 test_local.log -rw-rw-r--. 1 may may 157 Jun 25 18:32 test_status.data $ tar tvf isolation_result_10.2.0.8368-b85a234_64bits_0_2019.6.25_6.32.56.tar.gz drwxrwxr-x may/may 0 2019-06-25 18:32 ./ -rw-rw-r-- may/may 2479 2019-06-25 18:32 ./main_snapshot.properties -rw-rw-r-- may/may 571 2019-06-25 18:32 ./check_local.log -rw-rw-r-- may/may 1537 2019-06-25 18:32 ./feedback.log -rw-rw-r-- may/may 839 2019-06-25 18:32 ./dispatch_tc_ALL.txt -rw-rw-r-- may/may 839 2019-06-25 18:32 ./dispatch_tc_FIN_local.txt -rw-rw-r-- may/may 157 2019-06-25 18:32 ./test_status.data -rw-rw-r-- may/may 83236 2019-06-25 18:32 ./test_local.log
- Test Result
The results of each test case are generated to the same path with test cases.$ cd cubrid-testcases/isolation/_01_ReadCommitted/authorization/method/ $ ll total 88 -rw-rw-r--. 1 may may 1830 Jun 19 12:31 add_user_01.ctl -rw-rw-r--. 1 may may 16 Jun 26 17:12 add_user_01.result -rw-rw-r--. 1 may may 1733 Jun 19 12:31 add_user_02.ctl -rw-rw-r--. 1 may may 16 Jun 25 18:32 add_user_02.result drwxrwxr-x. 2 may may 4096 Jun 26 17:12 answer -rw-rw-r--. 1 may may 2067 Jun 19 12:31 changing_owner_01.ctl -rw-rw-r--. 1 may may 22 Jun 25 18:32 changing_owner_01.result -rw-rw-r--. 1 may may 2210 Jun 19 12:31 changing_owner_02.ctl -rw-rw-r--. 1 may may 22 Jun 25 18:32 changing_owner_02.result -rw-rw-r--. 1 may may 2209 Jun 19 12:31 changing_owner_03.ctl -rw-rw-r--. 1 may may 22 Jun 25 18:32 changing_owner_03.result -rw-rw-r--. 1 may may 1851 Jun 19 12:31 drop_user_01.ctl -rw-rw-r--. 1 may may 17 Jun 25 18:32 drop_user_01.result -rw-rw-r--. 1 may may 1834 Jun 19 12:31 drop_user_02.ctl -rw-rw-r--. 1 may may 17 Jun 25 18:32 drop_user_02.result -rw-rw-r--. 1 may may 1897 Jun 19 12:31 find_user_01.ctl -rw-rw-r--. 1 may may 17 Jun 25 18:32 find_user_01.result -rw-rw-r--. 1 may may 1755 Jun 19 12:31 find_user_02.ctl -rw-rw-r--. 1 may may 17 Jun 25 18:32 find_user_02.result -rw-rw-r--. 1 may may 1645 Jun 19 12:31 login_01.ctl -rw-rw-r--. 1 may may 13 Jun 25 18:32 login_01.result drwxrwxr-x. 2 may may 4096 Jun 26 17:12 result $ ll answer/ total 40 -rw-rw-r--. 1 may may 844 Jun 26 17:12 add_user_01.answer -rw-rw-r--. 1 may may 708 Jun 19 12:31 add_user_02.answer -rw-rw-r--. 1 may may 637 Jun 19 12:31 changing_owner_01.answer -rw-rw-r--. 1 may may 556 Jun 19 12:31 changing_owner_02.answer -rw-rw-r--. 1 may may 556 Jun 19 12:31 changing_owner_03.answer -rw-rw-r--. 1 may may 694 Jun 19 12:31 drop_user_01.answer -rw-rw-r--. 1 may may 725 Jun 19 12:31 drop_user_02.answer -rw-rw-r--. 1 may may 947 Jun 19 12:31 find_user_01.answer -rw-rw-r--. 1 may may 672 Jun 19 12:31 find_user_02.answer -rw-rw-r--. 1 may may 927 Jun 19 12:31 login_01.answer $ ll result/ total 160 -rw-rw-r--. 1 may may 844 Jun 26 17:12 add_user_01.log -rw-rw-r--. 1 may may 9251 Jun 26 17:12 add_user_01.result -rw-rw-r--. 1 may may 708 Jun 25 18:32 add_user_02.log -rw-rw-r--. 1 may may 8523 Jun 25 18:32 add_user_02.result -rw-rw-r--. 1 may may 637 Jun 25 18:32 changing_owner_01.log -rw-rw-r--. 1 may may 10666 Jun 25 18:32 changing_owner_01.result -rw-rw-r--. 1 may may 556 Jun 25 18:32 changing_owner_02.log -rw-rw-r--. 1 may may 11333 Jun 25 18:32 changing_owner_02.result -rw-rw-r--. 1 may may 556 Jun 25 18:32 changing_owner_03.log -rw-rw-r--. 1 may may 11333 Jun 25 18:32 changing_owner_03.result -rw-rw-r--. 1 may may 694 Jun 25 18:32 drop_user_01.log -rw-rw-r--. 1 may may 9081 Jun 25 18:32 drop_user_01.result -rw-rw-r--. 1 may may 725 Jun 25 18:32 drop_user_02.log -rw-rw-r--. 1 may may 9039 Jun 25 18:32 drop_user_02.result -rw-rw-r--. 1 may may 947 Jun 25 18:32 find_user_01.log -rw-rw-r--. 1 may may 9643 Jun 25 18:32 find_user_01.result -rw-rw-r--. 1 may may 672 Jun 25 18:32 find_user_02.log -rw-rw-r--. 1 may may 8266 Jun 25 18:32 find_user_02.result -rw-rw-r--. 1 may may 927 Jun 25 18:32 login_01.log -rw-rw-r--. 1 may may 8237 Jun 25 18:32 login_01.result $
- The files end with
.result
in the same directory as test case record the success or failure of the test cases.$ cat add_user_01.result add_user_01:OK.
- The files end with
.result
in theresult
directory are the detailed log of the test cases execution.$ cat result/add_user_01.result MC: Attempting to restart master client. INFO! Setting up 3 clients. C1 output (Transaction index = 2): | Client 1 (Transaction index = 2) is ready. C2 output (Transaction index = 3): | Client 2 (Transaction index = 3) is ready. C3 output (Transaction index = 4): | Client 3 (Transaction index = 4) is ready. QACTL 0 line: 25 statement: (MC: setup NUM_CLIENTS = 3;) MC to C1: login as 'dba'; C1 output (Transaction index = 2): | Ope_no = 1, Client_no = 1 | login as 'dba'; ... QACTL 0 line: 75 statement: (MC: wait until C3 ready;) C3 output (Transaction index = 4): | Client 3 (Transaction index = 4) is ready. MC to C3: quit; C3 output (Transaction index = 4): | Ope_no = 8, Client_no = 3 | quit; C3 output (Transaction index = 4): | This client shutting down as commanded.
- The files end with
.log
in theresult
directory are the actual result of test case.$ cat result/add_user_01.log | ERROR RETURNED: Operation "add_user" can only be performed by the DBA or a DBA group member. | on statement number: 10 | ================= Q U E R Y R E S U L T S ================= | | | 'COMPANY' | 'DBA' | 'DESIGN' | 'PUBLIC' | 4 rows selected | ================= Q U E R Y R E S U L T S ================= | | | 'COMPANY' | 'DBA' | 'DESIGN' | 'JONES' | 'PUBLIC' | 5 rows selected | ================= Q U E R Y R E S U L T S ================= | | | NULL | 1 row affected | ================= Q U E R Y R E S U L T S ================= | | | 'COMPANY' | 'DBA' | 'DESIGN' | 'JONES' | 'PUBLIC' | 5 rows selected | ERROR RETURNED: Semantic: SELECT is not authorized on t1. select t1.id, t1.phone from t1 t1 | on statement number: 10
- The success or failure of the test case is obtained by comparing the
.answer
file in theanswer
directory with the.log
file in theresult
directory.If the$ diff answer/add_user_01.answer result/add_user_01.log -y | ERROR RETURNED: Operation "add_user" can only be performed | ERROR RETURNED: Operation "add_user" can only be performed | on statement number: 10 | on statement number: 10 | ================= Q U E R Y R E S U L T S =========== | ================= Q U E R Y R E S U L T S =========== | | | | | 'COMPANY' | 'COMPANY' | 'DBA' | 'DBA' | 'DESIGN' | 'DESIGN' | 'PUBLIC' | 'PUBLIC' | 4 rows selected | 4 rows selected | ================= Q U E R Y R E S U L T S =========== | ================= Q U E R Y R E S U L T S =========== | | | | | 'COMPANY' | 'COMPANY' | 'DBA' | 'DBA' | 'DESIGN' | 'DESIGN' | 'JONES' | 'JONES' | 'PUBLIC' | 'PUBLIC' | 5 rows selected | 5 rows selected | ================= Q U E R Y R E S U L T S =========== | ================= Q U E R Y R E S U L T S =========== | | | | | NULL | NULL | 1 row affected | 1 row affected | ================= Q U E R Y R E S U L T S =========== | ================= Q U E R Y R E S U L T S =========== | | | | | 'COMPANY' | 'COMPANY' | 'DBA' | 'DBA' | 'DESIGN' | 'DESIGN' | 'JONES' | 'JONES' | 'PUBLIC' | 'PUBLIC' | 5 rows selected | 5 rows selected | ERROR RETURNED: Semantic: SELECT is not authorized on t1. s | ERROR RETURNED: Semantic: SELECT is not authorized on t1. s | on statement number: 10 | on statement number: 10 $ echo $? 0
.log
file is different from.answer
file, the result turns outNOK
.
- The files end with
Since we have thousands of isolation test cases, it takes a long time to finish. So we need to execute the test cases in parallel. CTP supports multi-node execution of test cases.
- CTP and CUBRID should be installed and cubrid-testcases should be checked out on each test node.
- Configure a config file
Touch an empty fileisolation_multi_node.conf
, then define test nodes.To know more about the configurations, see https://github.com/CUBRID/cubrid-testtools/blob/develop/CTP/conf/isolation.conf.scenario=${HOME}/cubrid-testcases/isolation/_01_ReadCommitted/authorization/managing_user/ env.instance1.ssh.host=192.168.1.118 env.instance1.ssh.port=22 env.instance1.ssh.user=may env.instance1.ssh.pwd=PASSWORD env.instance2.ssh.host=192.168.1.124 env.instance2.ssh.port=22 env.instance2.ssh.user=may env.instance2.ssh.pwd=PASSWORD
- Run
Screen output:
ctp.sh isolation -c isolation_multi_node.conf
$ ctp.sh isolation -c isolation_multi_node.conf ====================================== ISOLATION ========================================== [ISOLATION] TEST STARTED (Tue Jun 25 18:51:03 KST 2019) [ISOLATION] CONFIG FILE: /home/may/isolation_multi_node.conf scenario=${HOME}/cubrid-testcases/isolation/_01_ReadCommitted/authorization/managing_user env.instance2.ssh.user=may env.instance1.ssh.pwd=PASSWORD env.instance2.ssh.pwd=PASSWORD env.instance1.ssh.user=may env.instance1.ssh.host=192.168.1.118 env.instance2.ssh.port=22 env.instance2.ssh.host=192.168.1.124 env.instance1.ssh.port=22 ----------END OF FILE---------- Available Env: [instance1, instance2] Build Id: 10.2.0.8368-b85a234 Build Bits: 64bits ... BEGIN TO CHECK: =================== Check may@192.168.1.118:22============================ ==> Check ssh connection ...... PASS ==> Check variable 'JAVA_HOME' ...... PASS ==> Check variable 'CTP_HOME' ...... PASS ==> Check variable 'CUBRID' ...... PASS ==> Check command 'java' ...... PASS ==> Check command 'diff' ...... PASS ==> Check command 'wget' ...... PASS ==> Check command 'find' ...... PASS ==> Check command 'cat' ...... PASS ==> Check directory 'cubrid-testcases/isolation/_01_ReadCommitted/authorization/managing_user' ...... PASS ==> Check directory '${CTP_HOME}/isolation/ctltool' ...... PASS =================== Check may@192.168.1.124:22============================ ==> Check ssh connection ...... PASS ==> Check variable 'JAVA_HOME' ...... PASS ==> Check variable 'CTP_HOME' ...... PASS ==> Check variable 'CUBRID' ...... PASS ==> Check command 'java' ...... PASS ==> Check command 'diff' ...... PASS ==> Check command 'wget' ...... PASS ==> Check command 'find' ...... PASS ==> Check command 'cat' ...... PASS ==> Check directory 'cubrid-testcases/isolation/_01_ReadCommitted/authorization/managing_user' ...... PASS ==> Check directory '${CTP_HOME}/isolation/ctltool' ...... PASS CHECK RESULT: PASS ============= UPDATE TEST CASES ================== [INFO] START (Tue Jun 25 18:51:09 KST 2019) grepo_service_url: rmi://192.168.1.91:11099/repoService [INFO] begin to fetch ... REPO: cubrid-testtools BRANCH: develop PATH: CTP CLIENT SHA1: 55c34777593040342116dc769a3c16e40f058eee [INFO] fetch done: NO CHANGE [INFO] got package file: /home/may/CTP/.dailyqa/cubrid-testtools_develop_CTP.zip [INFO] begin to expand files ... [INFO] expand done [INFO] DONE Tue Jun 25 18:51:09 KST 2019 DONE Above EnvId is instance1 SKIP TEST CASE UPDATE! [INFO] START (Tue Jun 25 18:51:10 KST 2019) grepo_service_url: rmi://192.168.1.91:11099/repoService [INFO] begin to fetch ... REPO: cubrid-testtools BRANCH: develop PATH: CTP CLIENT SHA1: 55c34777593040342116dc769a3c16e40f058eee [INFO] fetch done: NO CHANGE [INFO] got package file: /home/may/CTP/.dailyqa/cubrid-testtools_develop_CTP.zip [INFO] begin to expand files ... [INFO] expand done [INFO] DONE Tue Jun 25 18:51:14 KST 2019 DONE Above EnvId is instance2 SKIP TEST CASE UPDATE! DONE ============= FETCH TEST CASES ================== The category:isolation The Number of Test Cases: 12 (macro skipped: 0, bug skipped: 0) The Number of Test Case : 12 ============= DEPLOY ================== DONE ============= TEST ================== [ENV START] instance1 STARTED [ENV START] instance2 [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/managing_user/bug_bts_13384.ctl EnvId=instance1 [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/managing_user/create_create_01.ctl EnvId=instance1 [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/managing_user/create_create_02.ctl EnvId=instance1 [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/managing_user/create_create_03.ctl EnvId=instance1 [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/managing_user/create_create_04.ctl EnvId=instance1 [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/managing_user/group_member_01.ctl EnvId=instance1 [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/managing_user/group_member_02.ctl EnvId=instance1 [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/managing_user/group_member_03.ctl EnvId=instance1 [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/managing_user/bug_bts_13467.ctl EnvId=instance2 [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/managing_user/group_member_04.ctl EnvId=instance1 [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/managing_user/group_member_06.ctl EnvId=instance1 [OK] [ENV STOP] instance1 [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/managing_user/group_member_05.ctl EnvId=instance2 [OK] [ENV STOP] instance2 ============= PRINT SUMMARY ================== Test Category:isolation Total Case:12 Total Execution Case:12 Total Success Case:12 Total Fail Case:0 Total Skip Case:0 TEST COMPLETE [ISOLATION] TEST END (Tue Jun 25 18:51:51 KST 2019) [ISOLATION] ELAPSE TIME: 47 seconds
- Test logs
Test logs on each test nodes saved with a suffix which are named by instance name.$ cd ~/CTP/result/isolation/current_runtime_logs $ ll total 144 -rw-rw-r--. 1 may may 593 Jun 25 18:51 check_instance1.log -rw-rw-r--. 1 may may 593 Jun 25 18:51 check_instance2.log -rw-rw-r--. 1 may may 1116 Jun 25 18:51 dispatch_tc_ALL.txt -rw-rw-r--. 1 may may 932 Jun 25 18:51 dispatch_tc_FIN_instance1.txt -rw-rw-r--. 1 may may 184 Jun 25 18:51 dispatch_tc_FIN_instance2.txt -rw-rw-r--. 1 may may 2106 Jun 25 18:51 feedback.log -rw-rw-r--. 1 may may 2730 Jun 25 18:51 main_snapshot.properties -rw-rw-r--. 1 may may 87025 Jun 25 18:51 test_instance1.log -rw-rw-r--. 1 may may 24240 Jun 25 18:51 test_instance2.log -rw-rw-r--. 1 may may 157 Jun 25 18:51 test_status.data
If you want to execute only one test case but not a test cases folder, you can use CTP/isolation/ctltool/runone.sh
.
Usage: sh runone.sh <case path> <timeout time>
For example,
$ cd CTP/isolation/ctltool/
$ sh CTP/isolation/ctltool/runone.sh ~/cubrid-testcases/isolation/_01_ReadCommitted/authorization/method/add_user_01.ctl 300
Testing cubrid-testcases/isolation/_01_ReadCommitted/authorization/method/add_user_01.ctl (retry count: 0)
flag: OK
By this way, the result will be generated in the test case directory, CTP will not generate logs under CTP/result/isolation/current_runtime_logs
.
You can define an alias to use this script easily.
alias runone="sh $CTP_HOME/isolation/ctltool/runone.sh "
Then you can execute test as
$ cd ~/cubrid-testcases/isolation/_01_ReadCommitted/authorization/method/
$ runone add_user_01.ctl 300
In the current daily regression test, we are using one controller node and twelve test nodes.
No. | Role | User Name | IP | Hostname |
---|---|---|---|---|
0 | Controller node | controller | 192.168.1.83 | func08 |
1 | Test node | isolation | 192.168.1.83 | func08 |
2 | Test node | isolation | 192.168.1.84 | func09 |
3 | Test node | isolation | 192.168.1.85 | func10 |
4 | Test node | isolation | 192.168.1.87 | func12 |
5 | Test node | isolation | 192.168.1.88 | func13 |
6 | Test node | isolation | 192.168.1.89 | func14 |
7 | Test node | isolation | 192.168.1.92 | func17 |
8 | Test node | isolation | 192.168.1.93 | func18 |
9 | Test node | isolation | 192.168.1.94 | func19 |
10 | Test node | isolation | 192.168.1.95 | func20 |
11 | Test node | isolation | 192.168.1.96 | func21 |
12 | Test node | isolation | 192.168.1.97 | func22 |
Controller node listens to test messages and starts a test when there is a test message. It will distribute test cases to each test node for execution.
Test nodes execute test cases in parallel.
- Install CTP
Follow the guide to install CTP first, then configureCTP/conf/common.conf
as below.# git user information, used to checkout the latest test cases. git_user=cubridqa git_pwd=PASSWORD git_email=<DL email address> # default values of ssh connection. default_ssh_pwd=PASSWORD default_ssh_port=22 # this service provides the latest test tool. grepo_service_url=rmi://192.168.1.91:11099 coverage_controller_pwd=PASSWORD # QA hompeage server and db information, used to update testing info and test results. qahome_db_driver=cubrid.jdbc.driver.CUBRIDDriver qahome_db_url=jdbc:cubrid:192.168.1.86:33080:qaresu:dba:: qahome_db_user=dba qahome_db_pwd= qahome_server_host=192.168.1.86 qahome_server_port=22 qahome_server_user=qahome qahome_server_pwd=PASSWORD # activemq information, used to managing test messages. activemq_user=admin activemq_pwd=admin activemq_url=failover:tcp://192.168.1.91:61616?wireFormat.maxInactivityDurationInitalDelay=30000 # email address to recieve notification. mail_from_nickname=CUBRIDQA_BJ mail_from_address=<DL email address>
- Configure test settings
Create a config file named$CTP_HOME/conf/isolation_template.conf
to configure daily regression test.
Here is the config file that we use for current daily regression test.$ cat $CTP_HOME/conf/isolation_template.conf #setup test nodes env.mvcc83.ssh.host=192.168.1.83 env.mvcc84.ssh.host=192.168.1.84 env.mvcc85.ssh.host=192.168.1.85 env.mvcc87.ssh.host=192.168.1.87 env.mvcc88.ssh.host=192.168.1.88 env.mvcc89.ssh.host=192.168.1.89 env.mvcc92.ssh.host=192.168.1.92 env.mvcc93.ssh.host=192.168.1.93 env.mvcc94.ssh.host=192.168.1.94 env.mvcc95.ssh.host=192.168.1.95 env.mvcc96.ssh.host=192.168.1.96 env.mvcc97.ssh.host=192.168.1.97 #default value of ssh connection default.ssh.port=22 default.ssh.user=isolation default.ssh.pwd=PASSWORD #set $CUBRID/conf/cubrid.conf default.cubrid.cubrid_port_id = 1570 #set $CUBRID/conf/cubrid_broker.conf default.broker1.BROKER_PORT = 30070 default.broker1.APPL_SERVER_SHM_ID=30070 default.broker2.BROKER_PORT = 33071 default.broker2.APPL_SERVER_SHM_ID=33071 #set $CUBRID/conf/cubrid_ha.conf default.ha.ha_port_id = 59900 #The test case path, the test cases must be located in the same path on all test nodes. scenario=$HOME/cubrid-testcases/isolation/ testcase_git_branch=develop testcase_exclude_from_file=$HOME/cubrid-testcases/isolation/config/daily_regression_test_excluded_list_linux.conf #timeout seconds.If a test case has been executed for more than 300 seconds, stop it and proceed to the next test case. Prevent the test hangs on. testcase_timeout_in_secs=300 #update test case from git repository testcase_update_yn=true testcase_retry_num=3 #qa homepage database info to update test result. feedback_type=database feedback_db_host=192.168.1.86 feedback_db_port=33080 feedback_db_name=qaresu feedback_db_user=dba feedback_db_pwd= feedback_notice_qahome_url=http://192.168.1.86:8080/qaresult/shellImportAction.nhn?main_id=<MAINID>
- Create and Start Consumer
A consumer is used to listening to a test message. It requires a queue name and a script name to run.- Create a script file
~/start_test.sh
as below.QUEUE_CUBRID_QA_CC_BASIC is the queue name$ cat ~/start_test.sh nohup start_consumer.sh -q QUEUE_CUBRID_QA_CC_BASIC -exec run_isolation &
run_isolation is the script name, it will execute the scriptrun_isolation.sh
inCTP/common/ext/
- Start consumer
It will check if there is a test message every five seconds.
$ sh start_test.sh $ tail -f nohup.out ... No build + let count=count+1 + '[' -f /home/controller/CTP/common/sched/status/STATUS.TXT ']' + sleep 5 ...
- Create a script file
- Stop Consumer
When you're investigating a problem, you may need to stop consumer to avoid it starts a new test. You can execute thestop_consumer.sh
to stop it.- Check the process
$ ps -u $USER f|tee PID TTY STAT TIME COMMAND 32464 ? S 0:00 sshd: controller@pts/1 32465 pts/1 Ss 0:00 \_ -bash 21192 pts/1 R+ 0:00 \_ ps -u controller f 21193 pts/1 S+ 0:00 \_ tee 19130 pts/1 S 0:00 /bin/bash /home/controller/CTP/common/script/start_consumer.sh -q QUEUE_CUBRID_QA_CC_BASIC,QUEUE_CUBRID_QA_SHELL_HA_LINUX -exec run_isolation,run_shell 21152 pts/1 S 0:00 \_ sleep 5
- Stop Consumer
There is no start_consumer.sh process anymore.
$ stop_consumer.sh /home/controller/CTP/common/script/stop_consumer.sh: line 34: kill: (27873) - No such process
$ ps -u $USER f|tee PID TTY STAT TIME COMMAND 32464 ? S 0:00 sshd: controller@pts/1 32465 pts/1 Ss 0:00 \_ -bash 27950 pts/1 R+ 0:00 \_ ps -u controller f 27951 pts/1 S+ 0:00 \_ tee
- Check the process
- Install CTP
Install CTP as it on controller node. - Checkout test cases
Checkout test cases as 2.2 Checkout Isolation Test Cases on each test node. Thecubrid-testcases
should be at the same path on each test node. - Install CUBRID on each test node
run_cubrid_install http://192.168.1.91:8080/REPO_ROOT/store_01/10.2.0.8368-b85a234/drop/CUBRID-10.2.0.8368-b85a234-Linux.x86_64-debug.sh
We perform isolation/isolation_debug for daily (actually is for each build) and perform code coverage test of isolation for monthly. isolation_debug
is executing isolation test cases with a debug build.
To execute the isolation/isolation_debug test, you only need to send a testing message.
-
Login to the message server:
message@192.168.1.91
-
Send test message
- To execute an isolation test with release build
sender.sh QUEUE_CUBRID_QA_CC_BASIC http://192.168.1.91:8080/REPO_ROOT/store_01/10.2.0.8369-5a75e41/drop/CUBRID-10.2.0.8369-5a75e41-Linux.x86_64.sh isolation default
- To execute an isolation_debug test with debug build
sender.sh QUEUE_CUBRID_QA_CC_BASIC http://192.168.1.91:8080/REPO_ROOT/store_01/10.2.0.8369-5a75e41/drop/CUBRID-10.2.0.8369-5a75e41-Linux.x86_64-debug.sh isolation_debug default
For example, run an isolation test on 10.2.0.8369-5a75e41 build, you need to send a message like below.
$ sender.sh QUEUE_CUBRID_QA_CC_BASIC http://192.168.1.91:8080/REPO_ROOT/store_01/10.2.0.8369-5a75e41/drop/CUBRID-10.2.0.8369-5a75e41-Linux.x86_64.sh isolation default Message: Message Content: Test for build 10.2.0.8369-5a75e41 by CUBRID QA Team, China MSG_ID = 190627-195624-685-000001 MSG_PRIORITY = 4 BUILD_ABSOLUTE_PATH=/home/ci_build/REPO_ROOT/store_01/10.2.0.8369-5a75e41/drop BUILD_BIT=0 BUILD_CREATE_TIME=1561143743000 BUILD_GENERATE_MSG_WAY=MANUAL BUILD_ID=10.2.0.8369-5a75e41 BUILD_IS_FROM_GIT=1 BUILD_PACKAGE_PATTERN=CUBRID-{1}-Linux.x86_64.sh BUILD_SCENARIOS=isolation BUILD_SCENARIO_BRANCH_GIT=develop BUILD_SEND_DELAY=489241 BUILD_SEND_TIME=1561632984684 BUILD_STORE_ID=store_01 BUILD_SVN_BRANCH=RB-10.2.0 BUILD_SVN_BRANCH_NEW=RB-10.2.0 BUILD_TYPE=general BUILD_URLS=http://192.168.1.91:8080/REPO_ROOT/store_01/10.2.0.8369-5a75e41/drop/CUBRID-10.2.0.8369-5a75e41-Linux.x86_64.sh BUILD_URLS_CNT=1 BUILD_URLS_KR=http://192.168.1.91:8080/REPO_ROOT/store_01/10.2.0.8369-5a75e41/drop/CUBRID-10.2.0.8369-5a75e41-Linux.x86_64.sh Do you accept above message [Y/N]: Y log4j:WARN No appenders could be found for logger (org.apache.activemq.thread.TaskRunnerFactory). log4j:WARN Please initialize the log4j system properly. log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
-
Monitoring the execution log
When you sent a test message, the consumer will catch the test massage and starts the test. You can go to thecontroller node
to see the execution log.$ tail -f nohup.out ... + consumerTimer 190627-195624-685-000001 start + msgId=190627-195624-685-000001 + typeName=start ++ getTimeStamp +++ date '+%Y-%m-%d %H:%M:%S %Z' ++ timeStamp='2019-06-27 19:56:26 KST' ++ echo 2019-06-27 19:56:26 KST + timeStamp='2019-06-27 19:56:26 KST' + echo '++++++++ Message-190627-195624-685-000001 start at 2019-06-27 19:56:26 KST ++++++++' ++++++++ Message-190627-195624-685-000001 start at 2019-06-27 19:56:26 KST ++++++++ + cd /home/controller/CTP/common/sched + /usr/local/cubridqa/jdk1.8.0_201/bin/java -cp ./lib/cubridqa-scheduler.jar com.navercorp.cubridqa.scheduler.consumer.ConsumerTimer 190627-195624-685-000001 start + cd /home/controller/CTP + source /home/controller/CTP/common/sched/init.sh china ... The Number of Test Case : 6297 ============= DEPLOY ================== DEPLAY START: EnvId=mvcc96[isolation@192.168.1.96:22] DEPLAY START: EnvId=mvcc92[isolation@192.168.1.92:22] DEPLAY START: EnvId=mvcc94[isolation@192.168.1.94:22] ... DEPLAY STOP: EnvId=mvcc94[isolation@192.168.1.94:22] DEPLAY STOP: EnvId=mvcc97[isolation@192.168.1.97:22] DEPLAY STOP: EnvId=mvcc87[isolation@192.168.1.87:22] DONE ============= TEST ================== [ENV START] mvcc92 [ENV START] mvcc94 [ENV START] mvcc96 ... [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/granting_authorization/granting_authorization_02.ctl EnvId=mvcc88 [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/granting_authorization/granting_authorization_03.ctl EnvId=mvcc88 [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/granting_authorization/granting_authorization_01.ctl EnvId=mvcc84 [OK] [TESTCASE] cubrid-testcases/isolation/_01_ReadCommitted/authorization/changing_owner/changing_owner_05.ctl EnvId=mvcc85 [OK] ...
You can find the detailed logs of each node in the
$CTP_HOME/result/isolation/current_runtime_logs
.$ cd CTP/result/isolation/current_runtime_logs $ ls check_mvcc83.log check_mvcc92.log current_task_id dispatch_tc_FIN_mvcc88.txt dispatch_tc_FIN_mvcc96.txt test_mvcc87.log test_mvcc95.log check_mvcc84.log check_mvcc93.log dispatch_tc_ALL.txt dispatch_tc_FIN_mvcc89.txt dispatch_tc_FIN_mvcc97.txt test_mvcc88.log test_mvcc96.log check_mvcc85.log check_mvcc94.log dispatch_tc_FIN_mvcc83.txt dispatch_tc_FIN_mvcc92.txt main_snapshot.properties test_mvcc89.log test_mvcc97.log check_mvcc87.log check_mvcc95.log dispatch_tc_FIN_mvcc84.txt dispatch_tc_FIN_mvcc93.txt test_mvcc83.log test_mvcc92.log check_mvcc88.log check_mvcc96.log dispatch_tc_FIN_mvcc85.txt dispatch_tc_FIN_mvcc94.txt test_mvcc84.log test_mvcc93.log check_mvcc89.log check_mvcc97.log dispatch_tc_FIN_mvcc87.txt dispatch_tc_FIN_mvcc95.txt test_mvcc85.log test_mvcc94.log $
-
See the testing progress in the QA homepage.
Click the build number, find the isolation/isolation_debug category, you can see the related information from the table.
In this picture, current test rate is 21.5%, no failied test case yet.
When the test finished, you can see the test rate is 100%.
To execute code coverage test of isolation, you also need to send a testing message.
-
Login to the message server:
message@192.168.1.91
. -
Send code coverage test message
cd manual/ sh sender_code_coverage_testing_message.sh QUEUE_CUBRID_QA_CC_BASIC http://192.168.1.91:8080/REPO_ROOT/store_01/10.2.0.8362-fbf9d84/drop/CUBRID-10.2.0.8362-fbf9d84-gcov-Linux.x86_64.tar.gz http://192.168.1.91:8080/REPO_ROOT/store_01/10.2.0.8362-fbf9d84/drop/cubrid-10.2.0.8362-fbf9d84-gcov-src-Linux.x86_64.tar.gz isolation
- the first url is a build for testing code coverage.
- the second url is the source code of the build.
For example, to execute the isolation code coverage test on 10.2.0.8362-fbf9d84 build, you need to send a test message like below.
$ cd ~/manual/ $ sh sender_code_coverage_testing_message.sh QUEUE_CUBRID_QA_CC_BASIC http://192.168.1.91:8080/REPO_ROOT/store_01/10.2.0.8362-fbf9d84/drop/CUBRID-10.2.0.8362-fbf9d84-gcov-Linux.x86_64.tar.gz http://192.168.1.91:8080/REPO_ROOT/store_01/10.2.0.8362-fbf9d84/drop/cubrid-10.2.0.8362-fbf9d84-gcov-src-Linux.x86_64.tar.gz isolation Queue:QUEUE_CUBRID_QA_CC_BASIC Build URL:http://192.168.1.91:8080/REPO_ROOT/store_01/10.2.0.8362-fbf9d84/drop/CUBRID-10.2.0.8362-fbf9d84-gcov-Linux.x86_64.tar.gz Source URL:http://192.168.1.91:8080/REPO_ROOT/store_01/10.2.0.8362-fbf9d84/drop/cubrid-10.2.0.8362-fbf9d84-gcov-src-Linux.x86_64.tar.gz Category:isolation Message: Message Content: Test for build 10.2.0.8362-fbf9d84 by CUBRID QA Team, China MSG_ID = 190627-201922-425-000001 MSG_PRIORITY = 4 BUILD_ABSOLUTE_PATH=/home/ci_build/REPO_ROOT/store_01/10.2.0.8362-fbf9d84/drop BUILD_BIT=0 BUILD_CREATE_TIME=1558747605000 BUILD_GENERATE_MSG_WAY=MANUAL BUILD_ID=10.2.0.8362-fbf9d84 BUILD_IS_FROM_GIT=1 BUILD_PACKAGE_PATTERN=CUBRID-{1}-gcov-Linux.x86_64.tar.gz BUILD_SCENARIOS=isolation BUILD_SCENARIO_BRANCH_GIT=develop BUILD_SEND_DELAY=2886757 BUILD_SEND_TIME=1561634362424 BUILD_STORE_ID=store_01 BUILD_SVN_BRANCH=RB-10.2.0 BUILD_SVN_BRANCH_NEW=RB-10.2.0 BUILD_TYPE=coverage BUILD_URLS=http://192.168.1.91:8080/REPO_ROOT/store_01/10.2.0.8362-fbf9d84/drop/CUBRID-10.2.0.8362-fbf9d84-gcov-Linux.x86_64.tar.gz BUILD_URLS_1=http://192.168.1.91:8080/REPO_ROOT/store_01/10.2.0.8362-fbf9d84/drop/cubrid-10.2.0.8362-fbf9d84-gcov-src-Linux.x86_64.tar.gz BUILD_URLS_CNT=2 BUILD_URLS_KR=http://192.168.1.91:8080/REPO_ROOT/store_01/10.2.0.8362-fbf9d84/drop/CUBRID-10.2.0.8362-fbf9d84-gcov-Linux.x86_64.tar.gz BUILD_URLS_KR_1=http://192.168.1.91:8080/REPO_ROOT/store_01/10.2.0.8362-fbf9d84/drop/cubrid-10.2.0.8362-fbf9d84-gcov-src-Linux.x86_64.tar.gz MKEY_COVERAGE_UPLOAD_DIR=/home/codecov/cc4c/result MKEY_COVERAGE_UPLOAD_IP=192.168.1.98 MKEY_COVERAGE_UPLOAD_PWD=PASSWORD MKEY_COVERAGE_UPLOAD_USER=codecov Do you accept above message [Y/N]:
For code coverage test, it doesn't show the progress in the QA homepage. You can log in to the controller node to see the execution log and the detailed logs of each node in the
$CTP_HOME/result/isolation/current_runtime_logs
. After the test finished, you can find the result in thecode coverage
node. See 4.2 verify code coverage testing result for detail.
Go to QA homepage and click the CI build, wait for the Function
page loading, then check if there are isolation
and isolation_debug
results.
Total column: The number of test cases, it counts all the .ctl
files in the scenario
path.
Testing column: The number of test cases that should be executed. It excepts the test cases that defined in ~/cubrid-testcases/isolation/config/daily_regression_test_excluded_list_linux.conf
.
If there shows 'NO RESULT (OR RUNNING)'as bellow, you need to find the reason.
Sometimes the CI build comes late, so that the test started late; or there is another test like manual build or ha_shell tests executed before the CI build. In this case, just wait for the test finish and then verify the results.
It means the Testing
is equal to the sum of Success
and Fail(Total)
.
If there is a failed test case, you need to verify it.
Click the failed number 1
, it shows the list of failed test cases.
Click the test case, it shows the test case, answer, and result.
Analyze the failure, then fix/revise the test case and verify it.
If you want to reproduce the failure by csql, you can refer to Execute isolation test case by csql.
You can refer to the test case modification history for changes to the unstable test case and revise required.
https://github.com/CUBRID/cubrid-testcases/commits/develop/isolation
If there is a test case always failed because of a bug, but due to some reason, the bug can't be fixed within a period of time, we can add test cases to the exclusion list. So that we don't need to test and verify the test case until the bug is fixed.
- You can find the exclude list from https://github.com/CUBRID/cubrid-testcases/blob/develop/isolation/config/daily_regression_test_excluded_list_linux.conf.
- If you want to add a test case to exclude list, you need to follow these rules:
- Comment the issue number before the test case.
- Approved by developer.
- Delete from list when the issue fixed.
Here are the issues that you can refer to.
- Regression issue: http://jira.cubrid.org/browse/CBRD-22630
- Compile issue: http://jira.cubrid.org/browse/CBRD-22717
Go to QA homepage and find the 'code coverage' node in the left area, click the link of latest result.
Click the isolation link.
There is a coverage rate of lines. Its coverage rate of lines is usually in 38%~39%. You can see the expected rate from http://jira.cubrid.org/browse/CUBRIDQA-851.
If the coverage does not meet expectation, you need to determine the cause and re-execute the test.
- The current isolation test case is located in the https://github.com/CUBRID/cubrid-testcases repository.
- In the isolation directory, test cases are stored in four different combination of isolation levels.
$ cd cubrid-testcases/isolation $ ls _01_ReadCommitted _02_RepeatableRead _04_RepeatableRead_ReadCommitted _05_ReadCommitted_RepeatableRead config $
- Each isolation level directory is further divided into multiple catalogs according to the purpose of the test.
$ ls cubrid-testcases/isolation/* _01_ReadCommitted: authorization cbrd_21506 dml_ddl function issues not_null primary_key_column template view catalog cbrd_22202_invisible_indexes foreign_key_column index_column no_index_column partition_table serial trigger _02_RepeatableRead: catalog dml_ddl foreign_key_column function index_column issues no_index_column partition_table primary_key_column serial trigger _04_RepeatableRead_ReadCommitted: dml_ddl index_column no_index_column not_null partition_table primary_key_column serial trigger _05_ReadCommitted_RepeatableRead: dml_ddl function index_column issues no_index_column partition_table primary_key_column serial trigger config: daily_regression_test_excluded_list_linux.conf
- The suffix of an isolation test case is
.ctl
. The expected answer file has the same name as the test case and the suffix is.answer[id]
. The answer files should be in theanswer
folder, and theanswer
folder and test cases are in the same path.$ cd _01_ReadCommitted/authorization/method $ ls add_user_01.ctl add_user_02.ctl answer changing_owner_01.ctl changing_owner_02.ctl changing_owner_03.ctl drop_user_01.ctl drop_user_02.ctl find_user_01.ctl find_user_02.ctl login_01.ctl $ ls answer/ add_user_01.answer changing_owner_01.answer changing_owner_03.answer drop_user_02.answer find_user_02.answer add_user_02.answer changing_owner_02.answer drop_user_01.answer find_user_01.answer login_01.answer
- A test case can have multiple answer files, distinguished by
id
of.answer[id]
like insert_update_07_1.answer and insert_update_07_1.answer1. Because in some cases, we don't know which transaction gets the lock first so we save both results as answer if they are expected.
An isolation test case usually consist of four parts: initialization, preparation, testing, and exit. We still take cbrd_21900.ctl as an example.
- Initialization
Define the number of clients and set isolation level and lock timeout for each client.MC: setup NUM_CLIENTS = 2; C1: set transaction lock timeout INFINITE; C1: set transaction isolation level read committed; C2: set transaction lock timeout 5; C2: set transaction isolation level read committed;
MC: setup NUM_CLIENTS = 2;
means there are 2 clients used. You can define up to ten clients.C1
andC2
represent each client. The query is executed on the corresponding client.
- Preparation
Create table, insert data, create indexes and so on.commit
is required to save the transaction in this part./* preparation */ C1: DROP TABLE IF EXISTS xoo; C1: create table xoo (a int primary key); C1: insert into xoo values(5); C1: commit;
- Testing
Perform the transaction mix scenario.TheC1: update xoo set a=a where a=5; MC: wait until C1 ready; C2: select * from xoo where a=5; MC: wait until C2 ready; C2: update xoo set a=a where a=5; MC: wait until C2 blocked; /* * C1 does not commit. C2 will be timed out. C1: commit; MC: wait until C1 ready; */ C2: select * from xoo where a=5; C2: COMMIT; MC: wait until C2 ready;
MC
actions here can verify the behavior and also can control the execution order.MC
action generally follows a client, it can verify the behavior of the client.MC: wait until C1 ready;
, It means you expect C1 processed normally. If C1 is blocked, the test case will fail. Other clients will be executed after C1 ready. In above test case,C1: update xoo set a=a where a=5;
andC2: select * from xoo where a=5;
, if there is noMC: wait until C1 ready;
, the 'C2 select' may executed before 'C1 update', that's not our expectation.MC: wait until C2 blocked;
, It means you expected C2 is blocked. If C2 didn't blocked, then the test case will fail.- Isolation test cases are executed in no-auto-commit mode. So you need to execute
commit;
orrollback;
to end a transaction. - The annotations in the isolation test are a pair of
/*
and*'/
. The content between/*
and*'/
doesn't executed.
- Exit
Quit all clients at the end of test case.C1: quit; C2: quit;
Suppose we are adding a test case for http://jira.cubrid.org/browse/CBRD-21900?focusedCommentId=4748985&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-4748985.
- Go to
_01_ReadCommitted/issues/_18_1h/
directory, create a test case file namedcbrd_21900.ctl
and an empty answer file./answer/cbrd_21900.answer
.$ cd ~/cubrid-testcases/isolation/_01_ReadCommitted/issues/_18_1h $ tree -f . +-- ./answer ¦ +-- ./answer/cbrd_21900.answer +-- ./cbrd_21900.ctl 1 directory, 2 files
- Save reproduce scenario to
cbrd_21900.ctl
.When writing a test case please note to make it stable. Such as drop table before create, add$ cat cbrd_21900.ctl MC: setup NUM_CLIENTS = 2; C1: set transaction lock timeout INFINITE; C1: set transaction isolation level read committed; C2: set transaction lock timeout 5; C2: set transaction isolation level read committed; /* preparation */ C1: DROP TABLE IF EXISTS xoo; C1: create table xoo (a int primary key); C1: insert into xoo values(5); C1: commit; C1: update xoo set a=a where a=5; MC: wait until C1 ready; C2: select * from xoo where a=5; MC: wait until C2 ready; C2: update xoo set a=a where a=5; MC: wait until C2 blocked; /* * C1 does not commit. C2 will be timed out. C1: commit; MC: wait until C1 ready; */ C2: select * from xoo where a=5; C2: COMMIT; MC: wait until C2 ready; C1: quit; C2: quit;
order by
caulse when select. - Execute test case
After execute a test case, there will generate
$ runone cbrd_21900.ctl 300 Testing cbrd_21900.ctl (retry count: 0) Testing cbrd_21900.ctl (retry count: 0) elapse: 5533 0a1,14 > | 1 row affected > | 1 row affected > | ================= Q U E R Y R E S U L T S ================= > | > | > | 5 > | 1 row selected > | ERROR RETURNED: Your transaction (index ?, PUBLIC@localhost|?) timed out waiting on X_LOCK lock on instance ?|?|? of class xoo. You are waiting for user(s) PUBLIC@localhost|qacsql(?) to finish. > | on statement number: 4 > | ================= Q U E R Y R E S U L T S ================= > | > | > | 5 > | 1 row selected flag: NOK dbtype: qacsql
result
folder which has a.log
file and.result
file.$ runone cbrd_21900.ctl 300 flag: OK $ tree -f . +-- ./answer ¦ +-- ./answer/cbrd_21900.answer // Expected answer +-- ./cbrd_21900.ctl // Test case +-- ./cbrd_21900.result // Executin result, log 'OK' or 'NOK' +-- ./csql.err // csql error log +-- ./result // Result folder ¦ +-- ./result/cbrd_21900.log // Actural result of test case ¦ +-- ./result/cbrd_21900.result // Detailed execution log of each client and MC actions +-- ./runone.log // Execution time in milliseconds 2 directories, 7 files
- Check the
./result/cbrd_21900.log
to see if the result is correct.$ cat result/cbrd_21900.log | 1 row affected | 1 row affected | ================= Q U E R Y R E S U L T S ================= | | | 5 | 1 row selected | ERROR RETURNED: Your transaction (index ?, PUBLIC@localhost|?) timed out waiting on X_LOCK lock on instance ?|?|? of class xoo. You are waiting for user(s) PUBLIC@localhost|qacsql(?) to finish. | on statement number: 4 | ================= Q U E R Y R E S U L T S ================= | | | 5 | 1 row selected
- If result is correct then save
result/cbrd_21900.log
asanswer/cbrd_21900.answer
.If result is not correct, then you need to investigate the reason. DO NOT save incorrect result as answer.$ cp result/cbrd_21900.log answer/cbrd_21900.answer
- Execute the test again, confirm test case executed successfully.
$ runone cbrd_21900.ctl 300 Testing cbrd_21900.ctl (retry count: 0) flag: OK
- Add and commit
cbrd_21900.ctl
andanswer/cbrd_21900.answer
to repository.$ git add cbrd_21900.ctl answer/cbrd_21900.answer $ git commit -m "[CBRD-21900] add test case for deadlock detection." 8. Then open a pull request to merge the test case.
Sometimes, to understand the test case, you may need to reproduce it by csql manually.
Take cbrd_21900.ctl(the answer file is cbrd_21900.answer) as an example.
-
Create and start a database.
cubrid createdb ctldb1 en_US cubrid server start ctldb1
-
Login csql public user on no-auto-commit mode. One csql session is one client.
In cbrd_21900.ctl,MC: setup NUM_CLIENTS = 2;
, so open two csql.MC: setup NUM_CLIENTS = 2;
on client 1
csql ctldb1 --no-auto-commit
on client 2
csql ctldb1 --no-auto-commit
-
Execute each command on each consoel.
C1: set transaction lock timeout INFINITE;
C1: set transaction isolation level read committed;on client 1
csql> set transaction lock timeout INFINITE; Execute OK. (0.001374 sec) 1 command(s) successfully processed. csql> set transaction isolation level read committed; Execute OK. (0.000045 sec) 1 command(s) successfully processed. csql>
C2: set transaction lock timeout 5;
C2: set transaction isolation level read committed;on client 2
csql> set transaction lock timeout 5; Execute OK. (0.000739 sec) 1 command(s) successfully processed. csql> set transaction isolation level read committed; Execute OK. (0.000037 sec) 1 command(s) successfully processed. csql>
/* preparation */
C1: DROP TABLE IF EXISTS xoo;
C1: create table xoo (a int primary key);
C1: insert into xoo values(5);
C1: commit;on client 1
csql> DROP TABLE IF EXISTS xoo; Execute OK. (0.001576 sec) 1 command(s) successfully processed. csql> create table xoo (a int primary key); Execute OK. (0.015276 sec) 1 command(s) successfully processed. csql> insert into xoo values(5); 1 row affected. (0.005699 sec) 1 command(s) successfully processed. csql> commit; Execute OK. (0.001922 sec) 1 command(s) successfully processed. csql>
C1: update xoo set a=a where a=5;
MC: wait until C1 ready;on client 1
csql> update xoo set a=a where a=5; 1 row affected. (0.006018 sec) 1 command(s) successfully processed. csql>
When execute test case by csql, the MC actions are confirmed by you. The
MC: wait until C1 ready;
means check the query has been processed here.C2: select * from xoo where a=5;
MC: wait until C2 ready;on client 2
csql> select * from xoo where a=5; === <Result of SELECT Command in Line 1> === a ============= 5 1 row selected. (0.013211 sec) 1 command(s) successfully processed. csql>
C2: update xoo set a=a where a=5;
MC: wait until C2 blocked;on client 2
csql> update xoo set a=a where a=5; -- The query will block at here, and after 5 seconds it will return following error. In the command from line 1, ERROR: Your transaction (index 2, PUBLIC@func43|7401) timed out waiting on X_LOCK lock on instance 0|3585|1 of class xoo. You are waiting for user(s) PUBLIC@func43|csql(7373) to finish. 0 command(s) successfully processed. csql>
MC: wait until C2 blocked;
means it expectes C2 is blocked here, so the console doesn't print a result. But since we setC2: set transaction lock timeout 5;
, after 5 seconds it returns thetransaction timed out
error./*
* C1 does not commit. C2 will be timedout.
C1: commit;
MC: wait until C1 ready;
*/Thess are comments, we don't need to execute them.
C2: select * from xoo where a=5;
C2: COMMIT;
MC: wait until C2 ready;on client 2
csql> select * from xoo where a=5; === <Result of SELECT Command in Line 1> === a ============= 5 1 row selected. (0.010001 sec) 1 command(s) successfully processed. csql> COMMIT; Execute OK. (0.001018 sec) 1 command(s) successfully processed. csql>
Test has finished here.
-
Exit clients.
C1: quit; C2: quit;
on client 1
csql> ;ex There have been updates. Do you want to commit ? (`Y' or `N') Y
on client 2
csql> ;ex
You can see the cbrd_21900.answer to check if the result is same as expectaion.
When a change of CUBRID leads the answer changed, we may need to modify the format_ctl_result
function to sabilize the test result.
See https://github.com/CUBRID/cubrid-testtools/blob/develop/CTP/isolation/ctltool/runone.sh#L48
If there is a crash during the isolation test, the tool can backup the core and CUBRID to $HOME/error_backup
folder. If you don't want to backup them, you can add backup_core_file_yn=no
(default value is yes) to the config file. For runone.sh
, you can use -n
option. Please see CUBRIDQA-950 for detail.