Merge of new rebased code
[appc.git] / appc-dispatcher / appc-dispatcher-common / lock-manager-lib / lock-manager-impl / src / test / java / org / openecomp / appc / lockmanager / impl / sql / pessimistic / TestMySqlLockManager.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * openECOMP : APP-C
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                                              reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.openecomp.appc.lockmanager.impl.sql.pessimistic;
23
24 import org.junit.Assert;
25 import org.junit.Test;
26 import org.openecomp.appc.lockmanager.api.LockException;
27 import org.openecomp.appc.lockmanager.api.LockRuntimeException;
28 import org.openecomp.appc.lockmanager.impl.sql.JdbcLockManager;
29 import org.openecomp.appc.lockmanager.impl.sql.MySqlLockManagerBaseTests;
30 import org.openecomp.appc.lockmanager.impl.sql.Synchronizer;
31 import org.openecomp.appc.lockmanager.impl.sql.pessimistic.MySqlLockManager;
32
33 import java.util.concurrent.*;
34
35 public class TestMySqlLockManager extends MySqlLockManagerBaseTests {
36
37     private static int CRITICAL_SECTION_WAIT_TIMEOUT = 1; // in secs
38
39         @Override
40         protected JdbcLockManager createJdbcLockManager(boolean useReal) {
41                 return new MySqlLockManagerMock(useReal);
42         }
43
44         @Test
45         public void testConcurrentLock() throws LockException, InterruptedException, ExecutionException, TimeoutException {
46         try {
47             callConcurrentTest(new Callable<Boolean>() {
48                 @Override
49                 public Boolean call() throws Exception {
50                     try {
51                         Assert.assertTrue(lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()));
52                         return true;
53                     } catch(LockRuntimeException e) {
54                         Assert.assertEquals("Cannot obtain critical section lock for resource [" + Resource.Resource1.name() + "].", e.getMessage());
55                         return false;
56                     }
57                 }
58             });
59         } finally {
60             lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name());
61                 }
62         }
63
64         @Test
65     public void testConcurrentUnlock() throws LockException, InterruptedException, ExecutionException, TimeoutException {
66         lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name());
67         callConcurrentTest(new Callable<Boolean>() {
68             @Override
69             public Boolean call() throws Exception {
70                 try {
71                     lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name());
72                     return true;
73                 } catch(LockRuntimeException e) {
74                     Assert.assertEquals("Cannot obtain critical section lock for resource [" + Resource.Resource1.name() + "].", e.getMessage());
75                     return false;
76                 }
77             }
78         });
79     }
80
81     private void callConcurrentTest(Callable<Boolean> callable) throws LockException, InterruptedException, ExecutionException, TimeoutException {
82         final int participantsNo = 2;
83         Synchronizer synchronizer = new Synchronizer(participantsNo) {
84
85             @Override
86             protected void waitForAllParticipants(Object waitObj, int totalParticipantsNo, int currentParticipantsNo) {
87                 waitOn(this, TimeUnit.MILLISECONDS.convert(1 + CRITICAL_SECTION_WAIT_TIMEOUT, TimeUnit.SECONDS)); // add 1 sec to make sure timeout occured
88             }
89         };
90         if(!setSynchronizer(synchronizer)) {
91             return;
92         }
93         ((MySqlLockManager)lockManager).setCriticalSectionWaitTimeoutSecs(CRITICAL_SECTION_WAIT_TIMEOUT);
94         ExecutorService executor = Executors.newFixedThreadPool(participantsNo);
95         Future<Boolean> future1 = executor.submit(callable);
96         try {
97             for(int i = 0; i < 10; i++) {
98                 Thread.sleep(100);
99                 if(synchronizer.getParticipantCount() > 0) {
100                     break;
101                 }
102             }
103             // make sure 1st thread gets inside critical section
104             if(synchronizer.getParticipantCount() < 1) {
105                 Assert.fail(getClass().getName() + " first thread failed to acquireLock()");
106             }
107             Future<Boolean> future2 = executor.submit(callable);
108             try {
109                 // 1st thread should acquire the lock
110                 Assert.assertTrue(future1.get(3 + CRITICAL_SECTION_WAIT_TIMEOUT, TimeUnit.SECONDS));
111                 // 2nd thread should fail waiting for critical section
112                 Assert.assertFalse(future2.get(2 + CRITICAL_SECTION_WAIT_TIMEOUT, TimeUnit.SECONDS));
113             } finally {
114                 future2.cancel(true);
115             }
116         } finally {
117             future1.cancel(true);
118             setSynchronizer(null);
119         }
120     }
121 }