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