blob: 94fa7f08c032e20b7ab9b651a752c9fe60bbf784 [file] [log] [blame]
// 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.doris.http;
import org.apache.doris.alter.MaterializedViewHandler;
import org.apache.doris.alter.SchemaChangeHandler;
import org.apache.doris.catalog.Catalog;
import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.DataProperty;
import org.apache.doris.catalog.Database;
import org.apache.doris.catalog.EsTable;
import org.apache.doris.catalog.KeysType;
import org.apache.doris.catalog.MaterializedIndex;
import org.apache.doris.catalog.OlapTable;
import org.apache.doris.catalog.Partition;
import org.apache.doris.catalog.PartitionInfo;
import org.apache.doris.catalog.PrimitiveType;
import org.apache.doris.catalog.RandomDistributionInfo;
import org.apache.doris.catalog.Replica;
import org.apache.doris.catalog.SinglePartitionInfo;
import org.apache.doris.catalog.Tablet;
import org.apache.doris.catalog.TabletInvertedIndex;
import org.apache.doris.catalog.TabletMeta;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.ExceptionChecker.ThrowingRunnable;
import org.apache.doris.common.jmockit.Deencapsulation;
import org.apache.doris.load.Load;
import org.apache.doris.mysql.privilege.PaloAuth;
import org.apache.doris.persist.EditLog;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.system.Backend;
import org.apache.doris.system.SystemInfoService;
import org.apache.doris.thrift.TStorageMedium;
import org.apache.doris.thrift.TStorageType;
import com.google.common.collect.Lists;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import junit.framework.AssertionFailedError;
import mockit.Expectations;
import mockit.Mock;
import mockit.MockUp;
import mockit.Mocked;
import okhttp3.Credentials;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
abstract public class DorisHttpTestCase {
public OkHttpClient networkClient = new OkHttpClient.Builder()
.readTimeout(100, TimeUnit.SECONDS)
.build();
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private static HttpServer httpServer;
public static final String CLUSTER_NAME = "default_cluster";
public static final String DB_NAME = "testDb";
public static final String TABLE_NAME = "testTbl";
private static long testBackendId1 = 1000;
private static long testBackendId2 = 1001;
private static long testBackendId3 = 1002;
private static long testReplicaId1 = 2000;
private static long testReplicaId2 = 2001;
private static long testReplicaId3 = 2002;
private static long testDbId = 100L;
private static long testTableId = 200L;
private static long testPartitionId = 201L;
public static long testIndexId = testTableId; // the base indexid == tableid
private static long tabletId = 400L;
public static long testStartVersion = 12;
public static long testStartVersionHash = 12312;
public static int testSchemaHash = 93423942;
public static long testPartitionCurrentVersionHash = 12312;
public static long testPartitionNextVersionHash = 123123123;
public static int HTTP_PORT;
protected static String URI;
protected String rootAuth = Credentials.basic("root", "");
@Mocked
private static EditLog editLog;
public static OlapTable newTable(String name) {
Catalog.getCurrentInvertedIndex().clear();
Column k1 = new Column("k1", PrimitiveType.BIGINT);
Column k2 = new Column("k2", PrimitiveType.DOUBLE);
List<Column> columns = new ArrayList<>();
columns.add(k1);
columns.add(k2);
Replica replica1 = new Replica(testReplicaId1, testBackendId1, testStartVersion, testStartVersionHash, testSchemaHash, 1024000L, 2000L,
Replica.ReplicaState.NORMAL, -1, 0, 0, 0);
Replica replica2 = new Replica(testReplicaId2, testBackendId2, testStartVersion, testStartVersionHash, testSchemaHash, 1024000L, 2000L,
Replica.ReplicaState.NORMAL, -1, 0, 0, 0);
Replica replica3 = new Replica(testReplicaId3, testBackendId3, testStartVersion, testStartVersionHash, testSchemaHash, 1024000L, 2000L,
Replica.ReplicaState.NORMAL, -1, 0, 0, 0);
// tablet
Tablet tablet = new Tablet(tabletId);
// index
MaterializedIndex baseIndex = new MaterializedIndex(testIndexId, MaterializedIndex.IndexState.NORMAL);
TabletMeta tabletMeta = new TabletMeta(testDbId, testTableId, testPartitionId, testIndexId, testSchemaHash, TStorageMedium.HDD);
baseIndex.addTablet(tablet, tabletMeta);
tablet.addReplica(replica1);
tablet.addReplica(replica2);
tablet.addReplica(replica3);
// partition
RandomDistributionInfo distributionInfo = new RandomDistributionInfo(2);
Partition partition = new Partition(testPartitionId, "testPartition", baseIndex, distributionInfo);
partition.updateVisibleVersionAndVersionHash(testStartVersion, testStartVersionHash);
partition.setNextVersion(testStartVersion + 1);
partition.setNextVersionHash(testPartitionNextVersionHash, testPartitionCurrentVersionHash);
// table
PartitionInfo partitionInfo = new SinglePartitionInfo();
partitionInfo.setDataProperty(testPartitionId, DataProperty.DEFAULT_DATA_PROPERTY);
partitionInfo.setReplicationNum(testPartitionId, (short) 3);
OlapTable table = new OlapTable(testTableId, name, columns, KeysType.AGG_KEYS, partitionInfo,
distributionInfo);
table.addPartition(partition);
table.setIndexMeta(testIndexId, "testIndex", columns, 0, testSchemaHash, (short) 1, TStorageType.COLUMN,
KeysType.AGG_KEYS);
table.setBaseIndexId(testIndexId);
return table;
}
private static EsTable newEsTable(String name) {
Column k1 = new Column("k1", PrimitiveType.BIGINT);
Column k2 = new Column("k2", PrimitiveType.DOUBLE);
List<Column> columns = new ArrayList<>();
columns.add(k1);
columns.add(k2);
PartitionInfo partitionInfo = new SinglePartitionInfo();
partitionInfo.setDataProperty(testPartitionId + 100, DataProperty.DEFAULT_DATA_PROPERTY);
partitionInfo.setReplicationNum(testPartitionId + 100, (short) 3);
EsTable table = null;
Map<String, String> props = new HashMap<>();
props.put(EsTable.HOSTS, "http://node-1:8080");
props.put(EsTable.USER, "root");
props.put(EsTable.PASSWORD, "root");
props.put(EsTable.INDEX, "test");
props.put(EsTable.TYPE, "doc");
try {
table = new EsTable(testTableId + 1, name, columns, props, partitionInfo);
} catch (DdlException e) {
e.printStackTrace();
}
return table;
}
private static Catalog newDelegateCatalog() {
try {
Catalog catalog = Deencapsulation.newInstance(Catalog.class);
PaloAuth paloAuth = new PaloAuth();
//EasyMock.expect(catalog.getAuth()).andReturn(paloAuth).anyTimes();
Database db = new Database(testDbId, "default_cluster:testDb");
OlapTable table = newTable(TABLE_NAME);
db.createTable(table);
OlapTable table1 = newTable(TABLE_NAME + 1);
db.createTable(table1);
EsTable esTable = newEsTable("es_table");
db.createTable(esTable);
new Expectations(catalog) {
{
catalog.getAuth();
minTimes = 0;
result = paloAuth;
catalog.getDb(db.getId());
minTimes = 0;
result = db;
catalog.getDb("default_cluster:" + DB_NAME);
minTimes = 0;
result = db;
catalog.isMaster();
minTimes = 0;
result = true;
catalog.getDb("default_cluster:emptyDb");
minTimes = 0;
result = null;
catalog.getDb(anyString);
minTimes = 0;
result = new Database();
catalog.getDbNames();
minTimes = 0;
result = Lists.newArrayList("default_cluster:testDb");
catalog.getLoadInstance();
minTimes = 0;
result = new Load();
catalog.getEditLog();
minTimes = 0;
result = editLog;
catalog.getClusterDbNames("default_cluster");
minTimes = 0;
result = Lists.newArrayList("default_cluster:testDb");
catalog.changeDb((ConnectContext) any, "blockDb");
minTimes = 0;
catalog.changeDb((ConnectContext) any, anyString);
minTimes = 0;
catalog.initDefaultCluster();
minTimes = 0;
}
};
return catalog;
} catch (DdlException e) {
return null;
} catch (AnalysisException e) {
return null;
}
}
private static void assignBackends() {
Backend backend1 = new Backend(testBackendId1, "node-1", 9308);
backend1.setBePort(9300);
Backend backend2 = new Backend(testBackendId2, "node-2", 9308);
backend2.setBePort(9300);
Backend backend3 = new Backend(testBackendId3, "node-3", 9308);
backend3.setBePort(9300);
Catalog.getCurrentSystemInfo().addBackend(backend1);
Catalog.getCurrentSystemInfo().addBackend(backend2);
Catalog.getCurrentSystemInfo().addBackend(backend3);
}
@BeforeClass
public static void initHttpServer() throws IllegalArgException, InterruptedException {
ServerSocket socket = null;
try {
socket = new ServerSocket(0);
socket.setReuseAddress(true);
HTTP_PORT = socket.getLocalPort();
URI = "http://localhost:" + HTTP_PORT + "/api/" + DB_NAME + "/" + TABLE_NAME;
} catch (Exception e) {
throw new IllegalStateException("Could not find a free TCP/IP port to start HTTP Server on");
} finally {
if (socket != null) {
try {
socket.close();
} catch (Exception e) {
}
}
}
httpServer = new HttpServer(HTTP_PORT);
httpServer.setup();
httpServer.start();
// must ensure the http server started before any unit test
while (!httpServer.isStarted()) {
Thread.sleep(500);
}
}
@Before
public void setUp() {
Catalog catalog = newDelegateCatalog();
SystemInfoService systemInfoService = new SystemInfoService();
TabletInvertedIndex tabletInvertedIndex = new TabletInvertedIndex();
new MockUp<Catalog>() {
@Mock
SchemaChangeHandler getSchemaChangeHandler() {
return new SchemaChangeHandler();
}
@Mock
MaterializedViewHandler getRollupHandler() {
return new MaterializedViewHandler();
}
@Mock
Catalog getCurrentCatalog() {
return catalog;
}
@Mock
SystemInfoService getCurrentSystemInfo() {
return systemInfoService;
}
@Mock
TabletInvertedIndex getCurrentInvertedIndex() {
return tabletInvertedIndex;
}
};
assignBackends();
doSetUp();
}
@After
public void tearDown() {
}
@AfterClass
public static void closeHttpServer() {
httpServer.shutDown();
}
public void doSetUp() {
}
public void expectThrowsNoException(ThrowingRunnable runnable) {
try {
runnable.run();
} catch (Throwable e) {
throw new AssertionFailedError(e.getMessage());
}
}
/**
* Checks a specific exception class is thrown by the given runnable, and returns it.
*/
public static <T extends Throwable> T expectThrows(Class<T> expectedType, ThrowingRunnable runnable) {
return expectThrows(expectedType, "Expected exception " + expectedType.getSimpleName() + " but no exception was thrown", runnable);
}
/**
* Checks a specific exception class is thrown by the given runnable, and returns it.
*/
public static <T extends Throwable> T expectThrows(Class<T> expectedType, String noExceptionMessage, ThrowingRunnable runnable) {
try {
runnable.run();
} catch (Throwable e) {
if (expectedType.isInstance(e)) {
return expectedType.cast(e);
}
AssertionFailedError assertion = new AssertionFailedError("Unexpected exception type, expected " + expectedType.getSimpleName() + " but got " + e);
assertion.initCause(e);
throw assertion;
}
throw new AssertionFailedError(noExceptionMessage);
}
}