514946b4a42604d427a15ca1c3a75ff9673ed803
[appc.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * APPC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * Copyright (C) 2017 Amdocs
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  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
21  */
22
23 package org.openecomp.appc.lockmanager.impl.sql.pessimistic;
24
25 import org.junit.Assert;
26 import org.junit.Test;
27 import org.openecomp.appc.lockmanager.api.LockException;
28 import org.openecomp.appc.lockmanager.api.LockRuntimeException;
29 import org.openecomp.appc.lockmanager.impl.sql.JdbcLockManager;
30 import org.openecomp.appc.lockmanager.impl.sql.MySqlLockManagerBaseTests;
31 import org.openecomp.appc.lockmanager.impl.sql.Synchronizer;
32 import org.openecomp.appc.lockmanager.impl.sql.pessimistic.MySqlLockManager;
33
34 import java.util.concurrent.*;
35
36 public class TestMySqlLockManager extends MySqlLockManagerBaseTests {
37
38     private static int CRITICAL_SECTION_WAIT_TIMEOUT = 1; // in secs
39
40         @Override
41         protected JdbcLockManager createJdbcLockManager(boolean useReal) {
42                 return new MySqlLockManagerMock(useReal);
43         }
44
45         @Test
46         public void testConcurrentLock() throws LockException, InterruptedException, ExecutionException, TimeoutException {
47         try {
48             callConcurrentTest(new Callable<Boolean>() {
49                 @Override
50                 public Boolean call() throws Exception {
51                     try {
52                         Assert.assertTrue(lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name()));
53                         return true;
54                     } catch(LockRuntimeException e) {
55                         Assert.assertEquals("Cannot obtain critical section lock for resource [" + Resource.Resource1.name() + "].", e.getMessage());
56                         return false;
57                     }
58                 }
59             });
60         } finally {
61             lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name());
62                 }
63         }
64
65         @Test
66     public void testConcurrentUnlock() throws LockException, InterruptedException, ExecutionException, TimeoutException {
67         lockManager.acquireLock(Resource.Resource1.name(), Owner.A.name());
68         callConcurrentTest(new Callable<Boolean>() {
69             @Override
70             public Boolean call() throws Exception {
71                 try {
72                     lockManager.releaseLock(Resource.Resource1.name(), Owner.A.name());
73                     return true;
74                 } catch(LockRuntimeException e) {
75                     Assert.assertEquals("Cannot obtain critical section lock for resource [" + Resource.Resource1.name() + "].", e.getMessage());
76                     return false;
77                 }
78             }
79         });
80     }
81
82     private void callConcurrentTest(Callable<Boolean> callable) throws LockException, InterruptedException, ExecutionException, TimeoutException {
83         final int participantsNo = 2;
84         Synchronizer synchronizer = new Synchronizer(participantsNo) {
85
86             @Override
87             protected void waitForAllParticipants(Object waitObj, int totalParticipantsNo, int currentParticipantsNo) {
88                 waitOn(this, TimeUnit.MILLISECONDS.convert(1 + CRITICAL_SECTION_WAIT_TIMEOUT, TimeUnit.SECONDS)); // add 1 sec to make sure timeout occured
89             }
90         };
91         if(!setSynchronizer(synchronizer)) {
92             return;
93         }
94         ((MySqlLockManager)lockManager).setCriticalSectionWaitTimeoutSecs(CRITICAL_SECTION_WAIT_TIMEOUT);
95         ExecutorService executor = Executors.newFixedThreadPool(participantsNo);
96         Future<Boolean> future1 = executor.submit(callable);
97         try {
98             for(int i = 0; i < 10; i++) {
99                 Thread.sleep(100);
100                 if(synchronizer.getParticipantCount() > 0) {
101                     break;
102                 }
103             }
104             // make sure 1st thread gets inside critical section
105             if(synchronizer.getParticipantCount() < 1) {
106                 Assert.fail(getClass().getName() + " first thread failed to acquireLock()");
107             }
108             Future<Boolean> future2 = executor.submit(callable);
109             try {
110                 // 1st thread should acquire the lock
111                 Assert.assertTrue(future1.get(3 + CRITICAL_SECTION_WAIT_TIMEOUT, TimeUnit.SECONDS));
112                 // 2nd thread should fail waiting for critical section
113                 Assert.assertFalse(future2.get(2 + CRITICAL_SECTION_WAIT_TIMEOUT, TimeUnit.SECONDS));
114             } finally {
115                 future2.cancel(true);
116             }
117         } finally {
118             future1.cancel(true);
119             setSynchronizer(null);
120         }
121     }
122 }