/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.hive.hcatalog.streaming.mutate.client; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.junit.Assert.fail; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.metastore.IMetaStoreClient; import org.apache.hadoop.hive.metastore.api.StorageDescriptor; import org.apache.hadoop.hive.metastore.api.Table; import org.apache.hadoop.hive.ql.io.orc.OrcOutputFormat; import org.apache.hive.hcatalog.streaming.TransactionBatch.TxnState; import org.apache.hive.hcatalog.streaming.mutate.client.lock.Lock; import org.apache.hive.hcatalog.streaming.mutate.client.lock.LockFailureListener; import org.apache.thrift.TException; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; @RunWith(MockitoJUnitRunner.class) public class TestMutatorClient { private static final long TRANSACTION_ID = 42L; private static final String TABLE_NAME_1 = "TABLE_1"; private static final String TABLE_NAME_2 = "TABLE_2"; private static final String DB_NAME = "DB_1"; private static final String USER = "user"; private static final AcidTable TABLE_1 = new AcidTable(DB_NAME, TABLE_NAME_1, true, TableType.SINK); private static final AcidTable TABLE_2 = new AcidTable(DB_NAME, TABLE_NAME_2, true, TableType.SINK); @Mock private IMetaStoreClient mockMetaStoreClient; @Mock private Lock mockLock; @Mock private Table mockTable1, mockTable2; @Mock private StorageDescriptor mockSd; @Mock private Map<String, String> mockParameters; @Mock private HiveConf mockConfiguration; @Mock private LockFailureListener mockLockFailureListener; private MutatorClient client; @Before public void configureMocks() throws Exception { when(mockMetaStoreClient.getTable(DB_NAME, TABLE_NAME_1)).thenReturn(mockTable1); when(mockTable1.getDbName()).thenReturn(DB_NAME); when(mockTable1.getTableName()).thenReturn(TABLE_NAME_1); when(mockTable1.getSd()).thenReturn(mockSd); when(mockTable1.getParameters()).thenReturn(mockParameters); when(mockMetaStoreClient.getTable(DB_NAME, TABLE_NAME_2)).thenReturn(mockTable2); when(mockTable2.getDbName()).thenReturn(DB_NAME); when(mockTable2.getTableName()).thenReturn(TABLE_NAME_2); when(mockTable2.getSd()).thenReturn(mockSd); when(mockTable2.getParameters()).thenReturn(mockParameters); when(mockSd.getNumBuckets()).thenReturn(1, 2); when(mockSd.getOutputFormat()).thenReturn(OrcOutputFormat.class.getName()); when(mockParameters.get("transactional")).thenReturn(Boolean.TRUE.toString()); when(mockMetaStoreClient.openTxn(USER)).thenReturn(TRANSACTION_ID); client = new MutatorClient(mockMetaStoreClient, mockConfiguration, mockLockFailureListener, USER, Collections.singletonList(TABLE_1)); } @Test public void testCheckValidTableConnect() throws Exception { List<AcidTable> inTables = new ArrayList<>(); inTables.add(TABLE_1); inTables.add(TABLE_2); client = new MutatorClient(mockMetaStoreClient, mockConfiguration, mockLockFailureListener, USER, inTables); client.connect(); List<AcidTable> outTables = client.getTables(); assertThat(client.isConnected(), is(true)); assertThat(outTables.size(), is(2)); assertThat(outTables.get(0).getDatabaseName(), is(DB_NAME)); assertThat(outTables.get(0).getTableName(), is(TABLE_NAME_1)); assertThat(outTables.get(0).getTotalBuckets(), is(2)); assertThat(outTables.get(0).getOutputFormatName(), is(OrcOutputFormat.class.getName())); assertThat(outTables.get(0).getTransactionId(), is(0L)); assertThat(outTables.get(0).getTable(), is(mockTable1)); assertThat(outTables.get(1).getDatabaseName(), is(DB_NAME)); assertThat(outTables.get(1).getTableName(), is(TABLE_NAME_2)); assertThat(outTables.get(1).getTotalBuckets(), is(2)); assertThat(outTables.get(1).getOutputFormatName(), is(OrcOutputFormat.class.getName())); assertThat(outTables.get(1).getTransactionId(), is(0L)); assertThat(outTables.get(1).getTable(), is(mockTable2)); } @Test public void testCheckNonTransactionalTableConnect() throws Exception { when(mockParameters.get("transactional")).thenReturn(Boolean.FALSE.toString()); try { client.connect(); fail(); } catch (ConnectionException e) { } assertThat(client.isConnected(), is(false)); } @Test public void testCheckUnBucketedTableConnect() throws Exception { when(mockSd.getNumBuckets()).thenReturn(0); try { client.connect(); fail(); } catch (ConnectionException e) { } assertThat(client.isConnected(), is(false)); } @Test public void testMetaStoreFailsOnConnect() throws Exception { when(mockMetaStoreClient.getTable(anyString(), anyString())).thenThrow(new TException()); try { client.connect(); fail(); } catch (ConnectionException e) { } assertThat(client.isConnected(), is(false)); } @Test(expected = ConnectionException.class) public void testGetDestinationsFailsIfNotConnected() throws Exception { client.getTables(); } @Test public void testNewTransaction() throws Exception { List<AcidTable> inTables = new ArrayList<>(); inTables.add(TABLE_1); inTables.add(TABLE_2); client = new MutatorClient(mockMetaStoreClient, mockConfiguration, mockLockFailureListener, USER, inTables); client.connect(); Transaction transaction = client.newTransaction(); List<AcidTable> outTables = client.getTables(); assertThat(client.isConnected(), is(true)); assertThat(transaction.getTransactionId(), is(TRANSACTION_ID)); assertThat(transaction.getState(), is(TxnState.INACTIVE)); assertThat(outTables.get(0).getTransactionId(), is(TRANSACTION_ID)); assertThat(outTables.get(1).getTransactionId(), is(TRANSACTION_ID)); } @Test public void testCloseClosesClient() throws Exception { client.close(); assertThat(client.isConnected(), is(false)); verify(mockMetaStoreClient).close(); } }