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.transaction;
19  
20  import org.apache.omid.tso.client.TSOClient;
21  import org.apache.hadoop.hbase.client.Get;
22  import org.apache.hadoop.hbase.client.Put;
23  import org.apache.hadoop.hbase.client.Result;
24  import org.apache.hadoop.hbase.util.Bytes;
25  import org.testng.ITestContext;
26  import org.testng.annotations.Test;
27  
28  import static org.mockito.Matchers.anyLong;
29  import static org.mockito.Matchers.anySetOf;
30  import static org.mockito.Mockito.doReturn;
31  import static org.mockito.Mockito.spy;
32  import static org.mockito.Mockito.timeout;
33  import static org.mockito.Mockito.times;
34  import static org.mockito.Mockito.verify;
35  import static org.testng.Assert.assertEquals;
36  import static org.testng.Assert.assertTrue;
37  
38  // TODO These tests should be adapted to a future test for AbstractTransactionManager as they should be DB independent
39  @Test(groups = "sharedHBase")
40  public class TestHBaseTransactionManager extends OmidTestBase {
41  
42      private static final int FAKE_EPOCH_INCREMENT = 100;
43  
44      private final byte[] row1 = Bytes.toBytes(TestHBaseTransactionManager.class.getCanonicalName());
45      private final byte[] testFamily = Bytes.toBytes(TEST_FAMILY);
46      private final byte[] qualifier = Bytes.toBytes("TEST_Q");
47      private final byte[] data1 = Bytes.toBytes("test_data1");
48  
49  
50      @Test(timeOut = 20_000)
51      public void testTxManagerGetsTimestampsInTheRightEpoch(ITestContext context) throws Exception {
52  
53          TSOClient tsoClient = spy(getClient(context));
54  
55          long fakeEpoch = tsoClient.getNewStartTimestamp().get() + FAKE_EPOCH_INCREMENT;
56  
57          // Modify the epoch before testing the begin method
58          doReturn(fakeEpoch).when(tsoClient).getEpoch();
59  
60          AbstractTransactionManager tm = spy((AbstractTransactionManager) newTransactionManager(context, tsoClient));
61  
62          // Create a transaction with the initial setup and check that the TX id matches the fake epoch created
63          Transaction tx1 = tm.begin();
64          assertEquals(tx1.getTransactionId(), fakeEpoch);
65          verify(tsoClient, timeout(100).times(FAKE_EPOCH_INCREMENT)).getEpoch();
66  
67      }
68  
69      @Test(timeOut = 20_000)
70      public void testReadOnlyTransactionsDoNotContactTSOServer(ITestContext context) throws Exception {
71  
72          final int EXPECTED_INVOCATIONS_FOR_COMMIT = 1; // Test specific checks
73  
74          TSOClient tsoClient = spy(getClient(context));
75          TransactionManager tm = newTransactionManager(context, tsoClient);
76  
77          try (TTable txTable = new TTable(hbaseConf, TEST_TABLE)) {
78  
79              // Add initial data in a transactional context
80              Transaction tx1 = tm.begin();
81              Put put = new Put(row1);
82              put.add(testFamily, qualifier, data1);
83              txTable.put(tx1, put);
84              tm.commit(tx1);
85  
86              verify(tsoClient, times(EXPECTED_INVOCATIONS_FOR_COMMIT)).commit(anyLong(), anySetOf(HBaseCellId.class));
87  
88              // Create a read-only tx and verify that commit has not been invoked again in the TSOClient
89              AbstractTransaction readOnlyTx = (AbstractTransaction) tm.begin();
90              Get get = new Get(row1);
91              Result r = txTable.get(readOnlyTx, get);
92              assertTrue(Bytes.equals(r.getValue(testFamily, qualifier), data1), "Wrong value for RO-TX " + readOnlyTx);
93              assertTrue(readOnlyTx.getWriteSet().isEmpty());
94              tm.commit(readOnlyTx);
95  
96              verify(tsoClient, times(EXPECTED_INVOCATIONS_FOR_COMMIT)).commit(anyLong(), anySetOf(HBaseCellId.class));
97              assertEquals(readOnlyTx.getStatus(), Transaction.Status.COMMITTED_RO);
98          }
99  
100     }
101 
102 }