| /* |
| * 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.zeppelin.kylin; |
| |
| import static org.junit.Assert.assertEquals; |
| |
| import org.apache.http.Header; |
| import org.apache.http.HttpEntity; |
| import org.apache.http.HttpResponse; |
| import org.apache.http.ProtocolVersion; |
| import org.apache.http.StatusLine; |
| import org.apache.http.client.methods.HttpPost; |
| import org.apache.http.message.AbstractHttpMessage; |
| import org.junit.Assert; |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.util.Locale; |
| import java.util.Properties; |
| |
| import org.apache.zeppelin.interpreter.InterpreterResult; |
| |
| public class KylinInterpreterTest { |
| static final Properties KYLIN_PROPERTIES = new Properties(); |
| |
| @BeforeClass |
| public static void setUpClass() { |
| KYLIN_PROPERTIES.put("kylin.api.url", "http://localhost:7070/kylin/api/query"); |
| KYLIN_PROPERTIES.put("kylin.api.user", "ADMIN"); |
| KYLIN_PROPERTIES.put("kylin.api.password", "KYLIN"); |
| KYLIN_PROPERTIES.put("kylin.query.project", "default"); |
| KYLIN_PROPERTIES.put("kylin.query.offset", "0"); |
| KYLIN_PROPERTIES.put("kylin.query.limit", "5000"); |
| KYLIN_PROPERTIES.put("kylin.query.ispartial", "true"); |
| } |
| |
| @Test |
| public void testWithDefault() { |
| KylinInterpreter t = new MockKylinInterpreter(getDefaultProperties()); |
| InterpreterResult result = t.interpret( |
| "select a.date,sum(b.measure) as measure from kylin_fact_table a " + |
| "inner join kylin_lookup_table b on a.date=b.date group by a.date", null); |
| assertEquals("default", t.getProject("select a.date,sum(b.measure) as measure " |
| + "from kylin_fact_table a inner join kylin_lookup_table b on a.date=b.date " |
| + "group by a.date")); |
| assertEquals(InterpreterResult.Type.TABLE, result.message().get(0).getType()); |
| } |
| |
| @Test |
| public void testWithProject() { |
| KylinInterpreter t = new MockKylinInterpreter(getDefaultProperties()); |
| assertEquals("project2", t.getProject("(project2)\n select a.date,sum(b.measure) " |
| + "as measure from kylin_fact_table a inner join kylin_lookup_table b on " |
| + "a.date=b.date group by a.date")); |
| assertEquals("", t.getProject("()\n select a.date,sum(b.measure) as measure " |
| + "from kylin_fact_table a inner join kylin_lookup_table b on a.date=b.date " |
| + "group by a.date")); |
| assertEquals("\n select a.date,sum(b.measure) as measure from kylin_fact_table a " |
| + "inner join kylin_lookup_table b on a.date=b.date group by a.date", |
| t.getSQL("(project2)\n select a.date,sum(b.measure) as measure " |
| + "from kylin_fact_table a inner join kylin_lookup_table b on a.date=b.date " |
| + "group by a.date")); |
| assertEquals("\n select a.date,sum(b.measure) as measure from kylin_fact_table a " |
| + "inner join kylin_lookup_table b on a.date=b.date group by a.date", |
| t.getSQL("()\n select a.date,sum(b.measure) as measure from kylin_fact_table a " |
| + "inner join kylin_lookup_table b on a.date=b.date group by a.date")); |
| } |
| |
| @Test |
| public void testParseResult() { |
| String msg = "{\"columnMetas\":[{\"isNullable\":1,\"displaySize\":256,\"label\":\"COUNTRY\"," |
| + "\"name\":\"COUNTRY\",\"schemaName\":\"DEFAULT\",\"catelogName\":null," |
| + "\"tableName\":\"SALES_TABLE\",\"precision\":256,\"scale\":0,\"columnType\":12," |
| + "\"columnTypeName\":\"VARCHAR\",\"writable\":false,\"readOnly\":true," |
| + "\"definitelyWritable\":false,\"autoIncrement\":false,\"caseSensitive\":true," |
| + "\"searchable\":false,\"currency\":false,\"signed\":true},{\"isNullable\":1," |
| + "\"displaySize\":256,\"label\":\"CURRENCY\",\"name\":\"CURRENCY\"," |
| + "\"schemaName\":\"DEFAULT\",\"catelogName\":null,\"tableName\":\"SALES_TABLE\"," |
| + "\"precision\":256,\"scale\":0,\"columnType\":12,\"columnTypeName\":\"VARCHAR\"," |
| + "\"writable\":false,\"readOnly\":true,\"definitelyWritable\":false," |
| + "\"autoIncrement\":false,\"caseSensitive\":true,\"searchable\":false," |
| + "\"currency\":false,\"signed\":true},{\"isNullable\":0,\"displaySize\":19," |
| + "\"label\":\"COUNT__\",\"name\":\"COUNT__\",\"schemaName\":\"DEFAULT\"," |
| + "\"catelogName\":null,\"tableName\":\"SALES_TABLE\",\"precision\":19,\"scale\":0," |
| + "\"columnType\":-5,\"columnTypeName\":\"BIGINT\",\"writable\":false," |
| + "\"readOnly\":true,\"definitelyWritable\":false,\"autoIncrement\":false," |
| + "\"caseSensitive\":true,\"searchable\":false,\"currency\":false,\"signed\":true}]," |
| + "\"results\":[[\"AMERICA\",\"USD\",null],[null,\"RMB\",0],[\"KOR\",null,100]," |
| + "[\"\\\"abc\\\"\",\"a,b,c\",-1]],\"cube\":\"Sample_Cube\",\"affectedRowCount\":0," |
| + "\"isException\":false,\"exceptionMessage\":null,\"duration\":134," |
| + "\"totalScanCount\":1,\"hitExceptionCache\":false,\"storageCacheUsed\":false," |
| + "\"partial\":false}"; |
| String expected = "%table COUNTRY \tCURRENCY \tCOUNT__ \t \n" + |
| "AMERICA \tUSD \tnull \t \n" + |
| "null \tRMB \t0 \t \n" + |
| "KOR \tnull \t100 \t \n" + |
| "\\\"abc\\\" \ta,b,c \t-1 \t \n"; |
| KylinInterpreter t = new MockKylinInterpreter(getDefaultProperties()); |
| String actual = t.formatResult(msg); |
| Assert.assertEquals(expected, actual); |
| } |
| |
| @Test |
| public void testParseEmptyResult() { |
| String msg = "{\"columnMetas\":[{\"isNullable\":1,\"displaySize\":256,\"label\":\"COUNTRY\"," |
| + "\"name\":\"COUNTRY\",\"schemaName\":\"DEFAULT\",\"catelogName\":null," |
| + "\"tableName\":\"SALES_TABLE\",\"precision\":256,\"scale\":0,\"columnType\":12," |
| + "\"columnTypeName\":\"VARCHAR\",\"writable\":false,\"readOnly\":true," |
| + "\"definitelyWritable\":false,\"autoIncrement\":false,\"caseSensitive\":true," |
| + "\"searchable\":false,\"currency\":false,\"signed\":true},{\"isNullable\":1," |
| + "\"displaySize\":256,\"label\":\"CURRENCY\",\"name\":\"CURRENCY\"," |
| + "\"schemaName\":\"DEFAULT\",\"catelogName\":null,\"tableName\":\"SALES_TABLE\"," |
| + "\"precision\":256,\"scale\":0,\"columnType\":12,\"columnTypeName\":\"VARCHAR\"," |
| + "\"writable\":false,\"readOnly\":true,\"definitelyWritable\":false," |
| + "\"autoIncrement\":false,\"caseSensitive\":true,\"searchable\":false," |
| + "\"currency\":false,\"signed\":true},{\"isNullable\":0,\"displaySize\":19," |
| + "\"label\":\"COUNT__\",\"name\":\"COUNT__\",\"schemaName\":\"DEFAULT\"," |
| + "\"catelogName\":null,\"tableName\":\"SALES_TABLE\",\"precision\":19,\"scale\":0," |
| + "\"columnType\":-5,\"columnTypeName\":\"BIGINT\",\"writable\":false," |
| + "\"readOnly\":true,\"definitelyWritable\":false,\"autoIncrement\":false," |
| + "\"caseSensitive\":true,\"searchable\":false,\"currency\":false,\"signed\":true}]," |
| + "\"results\":[]," + "\"cube\":\"Sample_Cube\",\"affectedRowCount\":0," |
| + "\"isException\":false,\"exceptionMessage\":null,\"duration\":134," |
| + "\"totalScanCount\":1,\"hitExceptionCache\":false,\"storageCacheUsed\":false," |
| + "\"partial\":false}"; |
| String expected = "%table COUNTRY \tCURRENCY \tCOUNT__ \t \n"; |
| KylinInterpreter t = new MockKylinInterpreter(getDefaultProperties()); |
| String actual = t.formatResult(msg); |
| Assert.assertEquals(expected, actual); |
| } |
| |
| private Properties getDefaultProperties() { |
| Properties prop = new Properties(); |
| prop.put("kylin.api.username", "ADMIN"); |
| prop.put("kylin.api.password", "KYLIN"); |
| prop.put("kylin.api.url", "http://<host>:<port>/kylin/api/query"); |
| prop.put("kylin.query.project", "default"); |
| prop.put("kylin.query.offset", "0"); |
| prop.put("kylin.query.limit", "5000"); |
| prop.put("kylin.query.ispartial", "true"); |
| return prop; |
| } |
| } |
| |
| class MockKylinInterpreter extends KylinInterpreter { |
| MockKylinInterpreter(Properties property) { |
| super(property); |
| } |
| |
| @Override |
| public HttpResponse prepareRequest(String sql) throws IOException { |
| MockHttpClient client = new MockHttpClient(); |
| return client.execute(new HttpPost()); |
| } |
| } |
| |
| class MockHttpClient{ |
| public MockHttpResponse execute(HttpPost post){ |
| return new MockHttpResponse(); |
| } |
| } |
| |
| class MockHttpResponse extends AbstractHttpMessage implements HttpResponse{ |
| @Override |
| public StatusLine getStatusLine() { |
| return new MockStatusLine(); |
| } |
| |
| @Override |
| public void setStatusLine(StatusLine statusLine) { |
| } |
| |
| @Override |
| public void setStatusLine(ProtocolVersion protocolVersion, int i) { |
| } |
| |
| @Override |
| public void setStatusLine(ProtocolVersion protocolVersion, int i, String s) { |
| } |
| |
| @Override |
| public void setStatusCode(int i) throws IllegalStateException { |
| } |
| |
| @Override |
| public void setReasonPhrase(String s) throws IllegalStateException { |
| } |
| |
| @Override |
| public HttpEntity getEntity() { |
| return new MockEntity(); |
| } |
| |
| @Override |
| public void setEntity(HttpEntity httpEntity) { |
| } |
| |
| @Override |
| public Locale getLocale() { |
| return null; |
| } |
| |
| @Override |
| public void setLocale(Locale locale) { |
| } |
| |
| @Override |
| public ProtocolVersion getProtocolVersion() { |
| return null; |
| } |
| } |
| |
| class MockStatusLine implements StatusLine{ |
| @Override |
| public ProtocolVersion getProtocolVersion() { |
| return null; |
| } |
| |
| @Override |
| public int getStatusCode() { |
| return 200; |
| } |
| |
| @Override |
| public String getReasonPhrase() { |
| return null; |
| } |
| } |
| |
| class MockEntity implements HttpEntity{ |
| @Override |
| public boolean isRepeatable() { |
| return false; |
| } |
| |
| @Override |
| public boolean isChunked() { |
| return false; |
| } |
| |
| @Override |
| public long getContentLength() { |
| return 0; |
| } |
| |
| @Override |
| public Header getContentType() { |
| return null; |
| } |
| |
| @Override |
| public Header getContentEncoding() { |
| return null; |
| } |
| |
| @Override |
| public InputStream getContent() throws IOException, IllegalStateException { |
| return new ByteArrayInputStream(("{\"columnMetas\":" + |
| "[{\"label\":\"PART_DT\"},{\"label\":\"measure\"}]," + |
| "\"results\":[[\"2012-01-03\",\"917.4138\"]," + |
| "[\"2012-05-06\",\"592.4823\"]]}").getBytes()); |
| } |
| |
| @Override |
| public void writeTo(OutputStream outputStream) throws IOException { |
| } |
| |
| @Override |
| public boolean isStreaming() { |
| return false; |
| } |
| |
| @Override |
| public void consumeContent() throws IOException { |
| } |
| } |