View Javadoc

1   package org.apache.onami.scopes;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  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,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import static org.junit.Assert.assertEquals;
23  import static org.junit.Assert.assertSame;
24  
25  import java.util.concurrent.Callable;
26  import java.util.concurrent.CountDownLatch;
27  import java.util.concurrent.ExecutorService;
28  import java.util.concurrent.Executors;
29  
30  import org.apache.onami.lifecycle.standard.AfterInjectionModule;
31  import org.apache.onami.test.OnamiRunner;
32  import org.junit.Before;
33  import org.junit.Test;
34  import org.junit.runner.RunWith;
35  
36  import com.google.inject.Guice;
37  import com.google.inject.Inject;
38  import com.google.inject.Injector;
39  import com.google.inject.Provider;
40  
41  @RunWith(OnamiRunner.class)
42  public class TestConcurrentLazySingleton
43  {
44      public static class InjectedAnnotatedProvider
45      {
46          public final Provider<AnnotatedConcurrentLazySingletonObject> provider;
47  
48          @Inject
49          public InjectedAnnotatedProvider( Provider<AnnotatedConcurrentLazySingletonObject> provider )
50          {
51              this.provider = provider;
52          }
53      }
54  
55      @Before
56      public void setup()
57      {
58          AnnotatedConcurrentLazySingletonObject.constructorCount.set( 0 );
59          AnnotatedConcurrentLazySingletonObject.postConstructCount.set( 0 );
60          LazySingletonObject.constructorCount.set( 0 );
61          LazySingletonObject.postConstructCount.set( 0 );
62      }
63  
64      @ConcurrentLazySingleton
65      public static class DeadLockTester
66      {
67          @Inject
68          public DeadLockTester( final Injector injector )
69              throws InterruptedException
70          {
71              final CountDownLatch latch = new CountDownLatch( 1 );
72              ExecutorService executorService = Executors.newSingleThreadExecutor();
73              try
74              {
75                  executorService.submit( new Callable<Object>()
76                  {
77                      public Object call()
78                          throws Exception
79                      {
80                          injector.getInstance( AnnotatedConcurrentLazySingletonObject.class );
81                          latch.countDown();
82                          return null;
83                      }
84                  } );
85                  latch.await();
86              }
87              finally
88              {
89                  executorService.shutdownNow();
90              }
91          }
92      }
93  
94      @Test
95      public void testDeadLock()
96          throws InterruptedException
97      {
98          Injector injector = Guice.createInjector( new ScopesModule() );
99          injector.getInstance( DeadLockTester.class ); // if ConcurrentLazySingleton is not used, this line will deadlock
100         assertEquals( AnnotatedConcurrentLazySingletonObject.constructorCount.get(), 1 );
101     }
102 
103     @Test
104     public void testUsingAnnotation()
105     {
106         Injector injector = Guice.createInjector( new AfterInjectionModule(), new ScopesModule() );
107 
108         assertEquals( AnnotatedConcurrentLazySingletonObject.constructorCount.get(), 0 );
109         assertEquals( AnnotatedConcurrentLazySingletonObject.postConstructCount.get(), 0 );
110 
111         AnnotatedConcurrentLazySingletonObject instance =
112             injector.getInstance( AnnotatedConcurrentLazySingletonObject.class );
113         assertEquals( AnnotatedConcurrentLazySingletonObject.constructorCount.get(), 1 );
114         assertEquals( AnnotatedConcurrentLazySingletonObject.postConstructCount.get(), 1 );
115 
116         AnnotatedConcurrentLazySingletonObject instance2 =
117             injector.getInstance( AnnotatedConcurrentLazySingletonObject.class );
118         assertEquals( AnnotatedConcurrentLazySingletonObject.constructorCount.get(), 1 );
119         assertEquals( AnnotatedConcurrentLazySingletonObject.postConstructCount.get(), 1 );
120 
121         assertSame( instance, instance2 );
122     }
123 
124     @Test
125     public void testUsingInWithProviderAndAnnotation()
126     {
127         Injector injector = Guice.createInjector( new AfterInjectionModule(), new ScopesModule() );
128 
129         assertEquals( AnnotatedConcurrentLazySingletonObject.constructorCount.get(), 0 );
130         assertEquals( AnnotatedConcurrentLazySingletonObject.postConstructCount.get(), 0 );
131 
132         InjectedAnnotatedProvider injectedProvider = injector.getInstance( InjectedAnnotatedProvider.class );
133         assertEquals( AnnotatedConcurrentLazySingletonObject.constructorCount.get(), 0 );
134         assertEquals( AnnotatedConcurrentLazySingletonObject.postConstructCount.get(), 0 );
135 
136         AnnotatedConcurrentLazySingletonObject instance = injectedProvider.provider.get();
137         assertEquals( AnnotatedConcurrentLazySingletonObject.constructorCount.get(), 1 );
138         assertEquals( AnnotatedConcurrentLazySingletonObject.postConstructCount.get(), 1 );
139 
140         AnnotatedConcurrentLazySingletonObject instance2 = injectedProvider.provider.get();
141         assertEquals( AnnotatedConcurrentLazySingletonObject.constructorCount.get(), 1 );
142         assertEquals( AnnotatedConcurrentLazySingletonObject.postConstructCount.get(), 1 );
143 
144         assertSame( instance, instance2 );
145     }
146 }