1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.omid.tso;
19
20 import org.apache.omid.committable.CommitTable;
21 import org.apache.omid.metrics.MetricsRegistry;
22 import org.apache.omid.timestamp.storage.TimestampStorage;
23 import org.mockito.InjectMocks;
24 import org.mockito.Mock;
25 import org.mockito.MockitoAnnotations;
26 import org.mockito.invocation.InvocationOnMock;
27 import org.mockito.stubbing.Answer;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30 import org.testng.annotations.BeforeMethod;
31 import org.testng.annotations.Test;
32
33 import java.util.concurrent.CountDownLatch;
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.atLeastOnce;
39 import static org.mockito.Mockito.doAnswer;
40 import static org.mockito.Mockito.verify;
41 import static org.testng.Assert.assertEquals;
42 import static org.testng.Assert.assertTrue;
43
44 public class TestTimestampOracle {
45
46 private static final Logger LOG = LoggerFactory.getLogger(TestTimestampOracle.class);
47
48 @Mock
49 private MetricsRegistry metrics;
50 @Mock
51 private Panicker panicker;
52 @Mock
53 private TimestampStorage timestampStorage;
54 @Mock
55 TSOServerConfig config;
56
57
58 @InjectMocks
59 private TimestampOracleImpl timestampOracle;
60
61 @BeforeMethod(alwaysRun = true, timeOut = 30_000)
62 public void initMocksAndComponents() {
63 MockitoAnnotations.initMocks(this);
64 }
65
66 @Test(timeOut = 60_000)
67 public void testMonotonicTimestampGrowth() throws Exception {
68
69
70 timestampOracle.initialize();
71
72 long last = timestampOracle.next();
73 for (int i = 0; i < (3 * TimestampOracleImpl.TIMESTAMP_BATCH); i++) {
74 long current = timestampOracle.next();
75 assertEquals(current, last + CommitTable.MAX_CHECKPOINTS_PER_TXN, "Not monotonic growth");
76 last = current;
77 }
78 assertTrue(timestampOracle.getLast() == last);
79 LOG.info("Last timestamp: {}", last);
80 }
81
82 @Test(timeOut = 10_000)
83 public void testTimestampOraclePanicsWhenTheStorageHasProblems() throws Exception {
84
85
86 timestampOracle.initialize();
87
88
89 final CountDownLatch updateMaxTimestampMethodCalled = new CountDownLatch(1);
90 doAnswer(new Answer() {
91 @Override
92 public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
93 updateMaxTimestampMethodCalled.countDown();
94 throw new RuntimeException("Out of memory or something");
95 }
96 }).when(timestampStorage).updateMaxTimestamp(anyLong(), anyLong());
97
98
99 Thread allocThread = new Thread("AllocThread") {
100 @Override
101 public void run() {
102 while (true) {
103 timestampOracle.next();
104 }
105 }
106 };
107 allocThread.start();
108
109 updateMaxTimestampMethodCalled.await();
110
111
112 verify(panicker, atLeastOnce()).panic(anyString(), any(Throwable.class));
113 }
114
115 }