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