View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.pool2.pool407;
19  
20  import java.time.Duration;
21  import java.util.concurrent.ExecutorService;
22  import java.util.concurrent.Executors;
23  import java.util.concurrent.TimeUnit;
24  
25  import org.apache.commons.pool2.PooledObject;
26  import org.junit.jupiter.api.Disabled;
27  import org.junit.jupiter.api.Test;
28  
29  /**
30   * Tests POOL-407.
31   */
32  public class KeyedPool407Test extends AbstractPool407Test {
33  
34      /**
35       * Borrows from a pool and then immediately returns to that a pool.
36       */
37      private static class KeyedPool407RoundtripRunnable implements Runnable {
38          private final KeyedPool407 pool;
39  
40          public KeyedPool407RoundtripRunnable(final KeyedPool407 pool) {
41              this.pool = pool;
42          }
43  
44          @Override
45          public void run() {
46              try {
47                  final KeyedPool407Fixture object = pool.borrowObject(KEY);
48                  if (object != null) {
49                      pool.returnObject(KEY, object);
50                  }
51              } catch (final Exception e) {
52                  throw new RuntimeException(e);
53              }
54          }
55      }
56  
57      private static final String KEY = "key";
58  
59      protected void assertShutdown(final ExecutorService executor, final Duration poolConfigMaxWait, final AbstractKeyedPool407Factory factory) throws Exception {
60          // Old note: This never finishes when the factory makes nulls because two threads are stuck forever
61          // If a factory always returns a null object or a null poolable object, then we will wait forever.
62          // This would also be true is object validation always fails.
63          executor.shutdown();
64          final boolean termination = executor.awaitTermination(Pool407Constants.AWAIT_TERMINATION_SECONDS, TimeUnit.SECONDS);
65          // Order matters: test create() before makeObject()
66          // Calling create() here in this test should not have side-effects
67          final KeyedPool407Fixture obj = factory.create(KEY);
68          // Calling makeObject() here in this test should not have side-effects
69          final PooledObject<KeyedPool407Fixture> pooledObject = obj != null ? factory.makeObject(KEY) : null;
70          assertShutdown(termination, poolConfigMaxWait, obj, pooledObject);
71      }
72  
73  
74      private void test(final AbstractKeyedPool407Factory factory, final int poolSize, final Duration poolConfigMaxWait) throws Exception {
75          final ExecutorService executor = Executors.newFixedThreadPool(poolSize);
76          try (final KeyedPool407 pool = new KeyedPool407(factory, poolConfigMaxWait)) {
77              // Start 'poolSize' threads that try to borrow a Pool407Fixture with the same key
78              for (int i = 0; i < poolSize; i++) {
79                  executor.execute(new KeyedPool407RoundtripRunnable(pool));
80              }
81              assertShutdown(executor, poolConfigMaxWait, factory);
82          }
83      }
84  
85      @Test
86      public void testNormalFactoryNonNullFixtureWaitMax() throws Exception {
87          test(new KeyedPool407NormalFactory(new KeyedPool407Fixture()), Pool407Constants.POOL_SIZE, Pool407Constants.WAIT_FOREVER);
88      }
89  
90      @Disabled
91      @Test
92      public void testNormalFactoryNullFixtureWaitMax() throws Exception {
93          test(new KeyedPool407NormalFactory(null), Pool407Constants.POOL_SIZE, Pool407Constants.WAIT_FOREVER);
94      }
95  
96      @Disabled
97      @Test
98      public void testNullObjectFactoryWaitMax() throws Exception {
99          test(new KeyedPool407NullObjectFactory(), Pool407Constants.POOL_SIZE, Pool407Constants.WAIT_FOREVER);
100     }
101 
102     @Disabled
103     @Test
104     public void testNullObjectFactoryWaitShort() throws Exception {
105         test(new KeyedPool407NullObjectFactory(), Pool407Constants.POOL_SIZE, Pool407Constants.WAIT_SHORT);
106     }
107 
108     @Disabled
109     @Test
110     public void testNullPoolableFactoryWaitMax() throws Exception {
111         test(new KeyedPool407NullPoolableObjectFactory(), Pool407Constants.POOL_SIZE, Pool407Constants.WAIT_FOREVER);
112     }
113 
114     @Disabled
115     @Test
116     public void testNullPoolableFactoryWaitShort() throws Exception {
117         test(new KeyedPool407NullPoolableObjectFactory(), Pool407Constants.POOL_SIZE, Pool407Constants.WAIT_SHORT);
118     }
119 }