View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.omid.tso;
19  
20  import org.apache.commons.pool2.ObjectPool;
21  import org.apache.omid.committable.CommitTable;
22  import org.apache.omid.metrics.MetricsRegistry;
23  import org.apache.omid.timestamp.storage.TimestampStorage;
24  import org.mockito.Mock;
25  import org.mockito.Mockito;
26  import org.mockito.MockitoAnnotations;
27  import org.slf4j.Logger;
28  import org.slf4j.LoggerFactory;
29  import org.testng.annotations.AfterMethod;
30  import org.testng.annotations.BeforeMethod;
31  import org.testng.annotations.Test;
32  
33  import java.io.IOException;
34  
35  import static org.mockito.Matchers.any;
36  import static org.mockito.Matchers.anyLong;
37  import static org.mockito.Matchers.anyString;
38  import static org.mockito.Mockito.doReturn;
39  import static org.mockito.Mockito.doThrow;
40  import static org.mockito.Mockito.mock;
41  import static org.mockito.Mockito.spy;
42  import static org.mockito.Mockito.timeout;
43  import static org.mockito.Mockito.verify;
44  
45  public class TestPanicker {
46  
47      private static final Logger LOG = LoggerFactory.getLogger(TestPanicker.class);
48  
49      @Mock
50      private CommitTable.Writer mockWriter;
51      @Mock
52      private MetricsRegistry metrics;
53  
54      @BeforeMethod
55      public void initMocksAndComponents() {
56          MockitoAnnotations.initMocks(this);
57      }
58  
59      @AfterMethod
60      void afterMethod() {
61          Mockito.reset(mockWriter);
62      }
63  
64      // Note this test has been moved and refactored to TestTimestampOracle because
65      // it tests the behaviour of the TimestampOracle.
66      // Please, remove me in a future commit
67      @Test
68      public void testTimestampOraclePanic() throws Exception {
69  
70          TimestampStorage storage = spy(new TimestampOracleImpl.InMemoryTimestampStorage());
71          Panicker panicker = spy(new MockPanicker());
72  
73          doThrow(new RuntimeException("Out of memory")).when(storage).updateMaxTimestamp(anyLong(), anyLong());
74  
75          final TimestampOracleImpl tso = new TimestampOracleImpl(metrics, storage, panicker);
76          tso.initialize();
77          Thread allocThread = new Thread("AllocThread") {
78              @Override
79              public void run() {
80                  try {
81                      while (true) {
82                          tso.next();
83                      }
84                  } catch (IOException ioe) {
85                      LOG.error("Shouldn't occur");
86                  }
87              }
88          };
89          allocThread.start();
90  
91          verify(panicker, timeout(1000).atLeastOnce()).panic(anyString(), any(Throwable.class));
92  
93      }
94  
95      // Note this test has been moved and refactored to TestPersistenceProcessor because
96      // it tests the behaviour of the PersistenceProcessor.
97      // Please, remove me in a future commit
98      @Test
99      public void testCommitTablePanic() throws Exception {
100 
101         Panicker panicker = spy(new MockPanicker());
102 
103         doThrow(new IOException("Unable to write@TestPanicker")).when(mockWriter).flush();
104 
105         final CommitTable.Client mockClient = mock(CommitTable.Client.class);
106         CommitTable commitTable = new CommitTable() {
107             @Override
108             public Writer getWriter() {
109                 return mockWriter;
110             }
111 
112             @Override
113             public Client getClient() {
114                 return mockClient;
115             }
116         };
117 
118         LeaseManager leaseManager = mock(LeaseManager.class);
119         doReturn(true).when(leaseManager).stillInLeasePeriod();
120         TSOServerConfig config = new TSOServerConfig();
121         ObjectPool<Batch> batchPool = new BatchPoolModule(config).getBatchPool();
122 
123         PersistenceProcessorHandler[] handlers = new PersistenceProcessorHandler[config.getNumConcurrentCTWriters()];
124         for (int i = 0; i < config.getNumConcurrentCTWriters(); i++) {
125             handlers[i] = new PersistenceProcessorHandler(metrics,
126                                                           "localhost:1234",
127                                                           leaseManager,
128                                                           commitTable,
129                                                           mock(ReplyProcessor.class),
130                                                           mock(RetryProcessor.class),
131                                                           panicker);
132         }
133 
134         PersistenceProcessor proc = new PersistenceProcessorImpl(config,
135                                                                  commitTable,
136                                                                  batchPool,
137                                                                  panicker,
138                                                                  handlers,
139                                                                  metrics);
140 
141         proc.addCommitToBatch(1, 2, null, new MonitoringContext(metrics));
142 
143         new RequestProcessorImpl(metrics, mock(TimestampOracle.class), proc, panicker, mock(TSOServerConfig.class));
144 
145         verify(panicker, timeout(1000).atLeastOnce()).panic(anyString(), any(Throwable.class));
146 
147     }
148 
149     // Note this test has been moved and refactored to TestPersistenceProcessor because
150     // it tests the behaviour of the PersistenceProcessor.
151     // Please, remove me in a future commit
152     @Test
153     public void testRuntimeExceptionTakesDownDaemon() throws Exception {
154 
155         Panicker panicker = spy(new MockPanicker());
156 
157         final CommitTable.Writer mockWriter = mock(CommitTable.Writer.class);
158         doThrow(new RuntimeException("Kaboom!")).when(mockWriter).addCommittedTransaction(anyLong(), anyLong());
159 
160         final CommitTable.Client mockClient = mock(CommitTable.Client.class);
161         CommitTable commitTable = new CommitTable() {
162             @Override
163             public Writer getWriter() {
164                 return mockWriter;
165             }
166 
167             @Override
168             public Client getClient() {
169                 return mockClient;
170             }
171         };
172         TSOServerConfig config = new TSOServerConfig();
173         ObjectPool<Batch> batchPool = new BatchPoolModule(config).getBatchPool();
174 
175         PersistenceProcessorHandler[] handlers = new PersistenceProcessorHandler[config.getNumConcurrentCTWriters()];
176         for (int i = 0; i < config.getNumConcurrentCTWriters(); i++) {
177             handlers[i] = new PersistenceProcessorHandler(metrics,
178                                                           "localhost:1234",
179                                                           mock(LeaseManager.class),
180                                                           commitTable,
181                                                           mock(ReplyProcessor.class),
182                                                           mock(RetryProcessor.class),
183                                                           panicker);
184         }
185 
186         PersistenceProcessor proc = new PersistenceProcessorImpl(config,
187                                                                  commitTable,
188                                                                  batchPool,
189                                                                  panicker,
190                                                                  handlers,
191                                                                  metrics);
192         proc.addCommitToBatch(1, 2, null, new MonitoringContext(metrics));
193 
194         new RequestProcessorImpl(metrics, mock(TimestampOracle.class), proc, panicker, mock(TSOServerConfig.class));
195 
196         verify(panicker, timeout(1000).atLeastOnce()).panic(anyString(), any(Throwable.class));
197 
198     }
199 
200 }