15d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin/* 25d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * Copyright (C) 2014 Google, Inc. 35d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * 45d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * Licensed under the Apache License, Version 2.0 (the "License"); 55d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * you may not use this file except in compliance with the License. 65d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * You may obtain a copy of the License at 75d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * 85d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * http://www.apache.org/licenses/LICENSE-2.0 95d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * 105d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * Unless required by applicable law or agreed to in writing, software 115d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * distributed under the License is distributed on an "AS IS" BASIS, 125d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * See the License for the specific language governing permissions and 145d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * limitations under the License. 155d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin */ 165d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinpackage dagger.producers.internal; 175d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 185d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport com.google.common.util.concurrent.Futures; 195d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport com.google.common.util.concurrent.ListenableFuture; 205d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport com.google.common.util.concurrent.SettableFuture; 215d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport dagger.producers.Producer; 225d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport dagger.producers.monitoring.ProducerMonitor; 2387182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffinimport dagger.producers.monitoring.ProducerToken; 2487182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffinimport dagger.producers.monitoring.ProductionComponentMonitor; 255d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport java.util.concurrent.ExecutionException; 2687182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffinimport javax.inject.Provider; 2787182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffinimport org.mockito.Mock; 2887182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffinimport org.mockito.Mockito; 2987182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffinimport org.mockito.MockitoAnnotations; 305d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport org.junit.Before; 315d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport org.junit.Test; 325d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport org.junit.runner.RunWith; 335d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport org.junit.runners.JUnit4; 345d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 355d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport static com.google.common.truth.Truth.assertThat; 365d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport static org.junit.Assert.fail; 3787182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffinimport static org.mockito.Mockito.any; 385d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport static org.mockito.Mockito.verify; 395d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinimport static org.mockito.Mockito.verifyNoMoreInteractions; 4087182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffinimport static org.mockito.Mockito.when; 415d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 425d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin/** 435d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin * Tests {@link AbstractProducer}. 445d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin */ 455d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin@RunWith(JUnit4.class) 465d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffinpublic class AbstractProducerTest { 4787182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin @Mock private ProductionComponentMonitor componentMonitor; 4887182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin private ProducerMonitor monitor; 4987182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin private Provider<ProductionComponentMonitor> componentMonitorProvider; 505d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 515d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Before 525d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin public void initMocks() { 535d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin MockitoAnnotations.initMocks(this); 5487182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin monitor = Mockito.mock(ProducerMonitor.class, Mockito.CALLS_REAL_METHODS); 5587182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin when(componentMonitor.producerMonitorFor(any(ProducerToken.class))).thenReturn(monitor); 5687182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin componentMonitorProvider = 5787182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin new Provider<ProductionComponentMonitor>() { 5887182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin @Override 5987182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin public ProductionComponentMonitor get() { 6087182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin return componentMonitor; 6187182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin } 6287182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin }; 635d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 645d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 655d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Test 665d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin public void get_nullPointerException() { 6787182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin Producer<Object> producer = new DelegateProducer<>(componentMonitorProvider, null); 685d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin try { 695d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin producer.get(); 705d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin fail(); 715d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } catch (NullPointerException expected) { 725d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 735d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 745d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 755d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Test public void get() throws Exception { 765d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin Producer<Integer> producer = 7787182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin new AbstractProducer<Integer>(componentMonitorProvider, null) { 785d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin int i = 0; 795d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 805d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Override 8187182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin public ListenableFuture<Integer> compute(ProducerMonitor unusedMonitor) { 825d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return Futures.immediateFuture(i++); 835d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 845d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin }; 855d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin assertThat(producer.get().get()).isEqualTo(0); 865d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin assertThat(producer.get().get()).isEqualTo(0); 875d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin assertThat(producer.get().get()).isEqualTo(0); 885d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 895d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 905d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Test 915d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin public void monitor_success() throws Exception { 925d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin SettableFuture<Integer> delegateFuture = SettableFuture.create(); 9387182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin Producer<Integer> producer = new DelegateProducer<>(componentMonitorProvider, delegateFuture); 945d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 955d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin ListenableFuture<Integer> future = producer.get(); 965d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin assertThat(future.isDone()).isFalse(); 9787182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin verify(monitor).addCallbackTo(any(ListenableFuture.class)); 985d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin delegateFuture.set(-42); 995d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin assertThat(future.get()).isEqualTo(-42); 1005d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin verify(monitor).succeeded(-42); 1015d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin verifyNoMoreInteractions(monitor); 1025d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1035d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 1045d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Test 1055d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin public void monitor_failure() throws Exception { 1065d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin SettableFuture<Integer> delegateFuture = SettableFuture.create(); 10787182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin Producer<Integer> producer = new DelegateProducer<>(componentMonitorProvider, delegateFuture); 1085d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 1095d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin ListenableFuture<Integer> future = producer.get(); 1105d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin assertThat(future.isDone()).isFalse(); 11187182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin verify(monitor).addCallbackTo(any(ListenableFuture.class)); 1125d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin Throwable t = new RuntimeException("monkey"); 1135d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin delegateFuture.setException(t); 1145d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin try { 1155d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin future.get(); 1165d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin fail(); 1175d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } catch (ExecutionException e) { 1185d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin assertThat(e.getCause()).isSameAs(t); 1195d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1205d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin verify(monitor).failed(t); 1215d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin verifyNoMoreInteractions(monitor); 1225d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1235d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 12487182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin @Test(expected = NullPointerException.class) 1255d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin public void monitor_null() throws Exception { 12687182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin new DelegateProducer<>(null, Futures.immediateFuture(42)); 1275d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1285d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 1295d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin static final class DelegateProducer<T> extends AbstractProducer<T> { 1305d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin private final ListenableFuture<T> delegate; 1315d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 13287182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin DelegateProducer( 13387182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin Provider<ProductionComponentMonitor> componentMonitorProvider, 13487182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin ListenableFuture<T> delegate) { 13587182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin super(componentMonitorProvider, null); 1365d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin this.delegate = delegate; 1375d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1385d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin 1395d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin @Override 14087182e06b8f6ec9a11ed6ebcaf74444e79b18ae2Paul Duffin public ListenableFuture<T> compute(ProducerMonitor unusedMonitor) { 1415d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin return delegate; 1425d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1435d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin } 1445d3207ac2713386ed61c6ca8f0356e8f093a62e1Paul Duffin} 145