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.PooledObject;
21  import org.jboss.netty.channel.Channel;
22  import org.mockito.Mock;
23  import org.slf4j.Logger;
24  import org.slf4j.LoggerFactory;
25  import org.testng.annotations.BeforeMethod;
26  import org.testng.annotations.Test;
27  
28  import static org.mockito.MockitoAnnotations.initMocks;
29  import static org.testng.Assert.assertEquals;
30  import static org.testng.Assert.assertFalse;
31  import static org.testng.Assert.assertTrue;
32  import static org.testng.Assert.fail;
33  
34  public class TestBatch {
35  
36      private static final Logger LOG = LoggerFactory.getLogger(TestBatch.class);
37  
38      private static final int BATCH_SIZE = 1000;
39  
40      private static final long ANY_ST = 1231;
41      private static final long ANY_CT = 2241;
42  
43      @Mock
44      private Channel channel;
45      @Mock
46      private MonitoringContext monCtx;
47  
48      @BeforeMethod
49      void setup() {
50          initMocks(this);
51      }
52  
53      @Test(timeOut = 10_000)
54      public void testBatchFunctionality() {
55  
56          // Component to test
57          Batch batch = new Batch(0, BATCH_SIZE);
58  
59          // Test initial state is OK
60          assertTrue(batch.isEmpty(), "Batch should be empty");
61          assertFalse(batch.isFull(), "Batch shouldn't be full");
62          assertEquals(batch.getNumEvents(), 0, "Num events should be 0");
63  
64          // Test getting or setting an element in the batch greater than the current number of events is illegal
65          try {
66              batch.get(1);
67              fail();
68          } catch (IllegalStateException ex) {
69              // Expected, as we can not access elements in the batch greater than the current number of events
70          }
71          try {
72              batch.set(1, new PersistEvent());
73              fail();
74          } catch (IllegalStateException ex) {
75              // Expected, as we can not access elements in the batch greater than the current number of events
76          }
77  
78          // Test when filling the batch with different types of events, that becomes full
79          for (int i = 0; i < BATCH_SIZE; i++) {
80              if (i % 4 == 0) {
81                  batch.addTimestamp(ANY_ST, channel, monCtx);
82              } else if (i % 4 == 1) {
83                  batch.addCommit(ANY_ST, ANY_CT, channel, monCtx);
84              } else if (i % 4 == 2) {
85                  batch.addCommitRetry(ANY_ST, channel, monCtx);
86              } else {
87                  batch.addAbort(ANY_ST, channel, monCtx);
88              }
89          }
90          assertFalse(batch.isEmpty(), "Batch should contain elements");
91          assertTrue(batch.isFull(), "Batch should be full");
92          assertEquals(batch.getNumEvents(), BATCH_SIZE, "Num events should be " + BATCH_SIZE);
93  
94          // Test an exception is thrown when batch is full and a new element is going to be added
95          try {
96              batch.addCommit(ANY_ST, ANY_CT, channel, monCtx);
97              fail("Should throw an IllegalStateException");
98          } catch (IllegalStateException e) {
99              assertEquals(e.getMessage(), "batch is full", "message returned doesn't match");
100             LOG.debug("IllegalStateException catch properly");
101         }
102         assertTrue(batch.isFull(), "Batch shouldn't be empty");
103 
104         // Check the first 3 events and the last one correspond to the filling done above
105         assertTrue(batch.get(0).getType().equals(PersistEvent.Type.TIMESTAMP));
106         assertTrue(batch.get(1).getType().equals(PersistEvent.Type.COMMIT));
107         assertTrue(batch.get(2).getType().equals(PersistEvent.Type.COMMIT_RETRY));
108         assertTrue(batch.get(3).getType().equals(PersistEvent.Type.ABORT));
109 
110         // Set a new value for last element in Batch and check we obtain the right result
111         batch.decreaseNumEvents();
112         assertEquals(batch.getNumEvents(), BATCH_SIZE - 1, "Num events should be " + (BATCH_SIZE - 1));
113         try {
114             batch.get(BATCH_SIZE - 1);
115             fail();
116         } catch (IllegalStateException ex) {
117             // Expected, as we can not access elements in the batch greater than the current number of events
118         }
119 
120         // Re-check that batch is NOT full
121         assertFalse(batch.isFull(), "Batch shouldn't be full");
122 
123         // Clear the batch and goes back to its initial state
124         batch.clear();
125         assertTrue(batch.isEmpty(), "Batch should be empty");
126         assertFalse(batch.isFull(), "Batch shouldn't be full");
127         assertEquals(batch.getNumEvents(), 0, "Num events should be 0");
128 
129     }
130 
131     @Test(timeOut = 10_000)
132     public void testBatchFactoryFunctionality() throws Exception {
133 
134         // Component to test
135         Batch.BatchFactory factory = new Batch.BatchFactory(BATCH_SIZE);
136 
137         // Check the factory creates a new batch properly...
138         Batch batch = factory.create();
139         assertTrue(batch.isEmpty(), "Batch should be empty");
140         assertFalse(batch.isFull(), "Batch shouldn't be full");
141         assertEquals(batch.getNumEvents(), 0, "Num events should be 0");
142 
143         // ...and is wrapped in to a pooled object
144         PooledObject<Batch> pooledBatch = factory.wrap(batch);
145         assertEquals(pooledBatch.getObject(), batch);
146 
147         // Put some elements in the batch...
148         batch.addTimestamp(ANY_ST, channel, monCtx);
149         batch.addCommit(ANY_ST, ANY_CT, channel, monCtx);
150         batch.addCommitRetry(ANY_ST, channel, monCtx);
151         batch.addAbort(ANY_ST, channel, monCtx);
152         assertFalse(batch.isEmpty(), "Batch should contain elements");
153         assertFalse(batch.isFull(), "Batch should NOT be full");
154         assertEquals(batch.getNumEvents(), 4, "Num events should be 4");
155 
156         // ... and passivate the object through the factory. It should reset the state of the batch
157         factory.passivateObject(pooledBatch);
158         assertTrue(batch.isEmpty(), "Batch should NOT contain elements");
159         assertFalse(batch.isFull(), "Batch should NOT be full");
160         assertEquals(batch.getNumEvents(), 0, "Num events should be 0");
161 
162     }
163 
164 }