diff --git a/server-base/src/test/java/org/apache/kylin/rest/response/SQLResponseTest.java b/server-base/src/test/java/org/apache/kylin/rest/response/SQLResponseTest.java new file mode 100644 index 00000000000..4055a2779db --- /dev/null +++ b/server-base/src/test/java/org/apache/kylin/rest/response/SQLResponseTest.java @@ -0,0 +1,49 @@ +/* + * 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.kylin.rest.response; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.apache.kylin.common.util.JsonUtil; +import org.junit.Assert; +import org.junit.Test; + +import com.fasterxml.jackson.databind.JsonNode; + +public class SQLResponseTest { + + @Test + public void testInterfaceConsistency() throws IOException { + String[] attrArray = new String[] { "columnMetas", "results", "cube", "affectedRowCount", "isException", + "exceptionMessage", "duration", "partial", "totalScanCount", "hitExceptionCache", "storageCacheUsed", + "pushDown", "traceUrl", "totalScanBytes" }; + + SQLResponse sqlResponse = new SQLResponse(null, null, "learn_cube", 100, false, null, false, false); + String jsonStr = JsonUtil.writeValueAsString(sqlResponse); + System.out.println(jsonStr); + + JsonNode jnode = JsonUtil.readValueAsTree(jsonStr); + assertEquals(jnode.size(), attrArray.length); + for (String attr : attrArray) { + Assert.assertTrue(attr + " doesn't exist", jnode.has(attr)); + } + } +} diff --git a/server-base/src/test/java/org/apache/kylin/rest/signature/RealizationSignatureTest.java b/server-base/src/test/java/org/apache/kylin/rest/signature/RealizationSignatureTest.java new file mode 100644 index 00000000000..1b857c5eec6 --- /dev/null +++ b/server-base/src/test/java/org/apache/kylin/rest/signature/RealizationSignatureTest.java @@ -0,0 +1,46 @@ +/* + * 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.kylin.rest.signature; + +import org.apache.kylin.common.KylinConfig; +import org.apache.kylin.common.util.LocalFileMetadataTestCase; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class RealizationSignatureTest extends LocalFileMetadataTestCase { + + private KylinConfig kylinConfig; + + @Before + public void setUp() { + this.createTestMetadata(); + kylinConfig = getTestConfig(); + } + @Test + public void testEquals() { + RealizationSignature rs = RealizationSignature.CubeSignature.getCubeSignature(kylinConfig, "ssb_cube1"); + RealizationSignature rs1 = RealizationSignature.CubeSignature.getCubeSignature(kylinConfig, "ssb_cube1"); + RealizationSignature rs2 = RealizationSignature.CubeSignature.getCubeSignature(kylinConfig, "ssb_cube2"); + Assert.assertTrue(rs.equals(rs)); + Assert.assertTrue(rs.equals(rs1)); + Assert.assertFalse(rs.equals(null)); + Assert.assertFalse(rs.equals(rs2)); + } +} diff --git a/server-base/src/test/java/org/apache/kylin/rest/signature/SegmentSignatureTest.java b/server-base/src/test/java/org/apache/kylin/rest/signature/SegmentSignatureTest.java new file mode 100644 index 00000000000..36f74cb12ef --- /dev/null +++ b/server-base/src/test/java/org/apache/kylin/rest/signature/SegmentSignatureTest.java @@ -0,0 +1,39 @@ +/* + * 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.kylin.rest.signature; + +import org.junit.Assert; +import org.junit.Test; + +public class SegmentSignatureTest { + + @Test + public void testEquals() { + SegmentSignature ss = new SegmentSignature("segmentName", 999L); + Assert.assertTrue(ss.equals(ss)); + Assert.assertFalse(ss.equals(null)); + SegmentSignature ss1 = new SegmentSignature("segmentName", 0L); + Assert.assertFalse(ss.equals(ss1)); + SegmentSignature ss2 = new SegmentSignature(null, 999L); + Assert.assertFalse(ss.equals(ss2)); + Assert.assertFalse(ss2.equals(ss)); + SegmentSignature ss3 = new SegmentSignature("segmentName2", 999L); + Assert.assertFalse(ss.equals(ss3)); + } +} diff --git a/server-base/src/test/java/org/apache/kylin/rest/signature/SignatureCalculatorTest.java b/server-base/src/test/java/org/apache/kylin/rest/signature/SignatureCalculatorTest.java new file mode 100644 index 00000000000..55ac5b6515e --- /dev/null +++ b/server-base/src/test/java/org/apache/kylin/rest/signature/SignatureCalculatorTest.java @@ -0,0 +1,184 @@ +/* + * 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.kylin.rest.signature; + +import java.io.IOException; +import java.util.Map; + +import org.apache.kylin.common.KylinConfig; +import org.apache.kylin.common.KylinConfigExt; +import org.apache.kylin.common.util.LocalFileMetadataTestCase; +import org.apache.kylin.cube.CubeInstance; +import org.apache.kylin.cube.CubeManager; +import org.apache.kylin.cube.CubeSegment; +import org.apache.kylin.cube.CubeUpdate; +import org.apache.kylin.metadata.project.ProjectInstance; +import org.apache.kylin.metadata.project.ProjectManager; +import org.apache.kylin.metadata.realization.RealizationStatusEnum; +import org.apache.kylin.rest.response.SQLResponse; +import org.apache.kylin.rest.signature.RealizationSignature.CubeSignature; +import org.apache.kylin.rest.util.SQLResponseSignatureUtil; +import org.apache.kylin.storage.hybrid.HybridInstance; +import org.apache.kylin.storage.hybrid.HybridManager; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.google.common.collect.Maps; + +public class SignatureCalculatorTest extends LocalFileMetadataTestCase { + + private final String projectName = "default"; + private KylinConfig config; + + @Before + public void setup() throws Exception { + this.createTestMetadata(); + this.config = getTestConfig(); + } + + @After + public void after() throws Exception { + this.cleanupTestMetadata(); + } + + @Test + public void testGetRealizationSignature() { + RealizationSignature signature1 = RealizationSetCalculator.getRealizationSignature(this.config, + "Test" + System.currentTimeMillis()); + Assert.assertNull(signature1); + + CubeSignature signature2 = (CubeSignature) RealizationSetCalculator.getRealizationSignature(this.config, "ssb"); + Assert.assertEquals(RealizationStatusEnum.DISABLED, signature2.status); + Assert.assertNull(signature2.segmentSignatureSet); + + CubeSignature signature3 = (CubeSignature) RealizationSetCalculator.getRealizationSignature(this.config, + "test_kylin_cube_with_slr_left_join_ready"); + Assert.assertNotNull(signature3.segmentSignatureSet); + } + + @Test + public void testRealizationSetCalculator() throws IOException { + KylinConfig config = KylinConfig.createKylinConfig(getTestConfig()); + Map overrides = Maps.newHashMap(); + overrides.put("kylin.query.signature-class", "org.apache.kylin.rest.signature.RealizationSetCalculator"); + + ProjectInstance projectInstance = ProjectManager.getInstance(config).getProject(projectName); + projectInstance.setConfig(KylinConfigExt.createInstance(config, overrides)); + + HybridManager hybridManager = HybridManager.getInstance(config); + HybridInstance hybrid1 = hybridManager.getHybridInstance("test_kylin_hybrid_ready"); + + CubeManager cubeManager = CubeManager.getInstance(config); + CubeInstance cube1 = cubeManager.getCube("test_kylin_cube_with_slr_ready_2_segments"); + CubeInstance cube2 = cubeManager.getCube("test_kylin_cube_without_slr_ready"); + CubeInstance cube2Clone = cloneCubeInstance(cubeManager, cube2, cube2.getName() + "_clone"); + + //Related cubes: + // - test_kylin_cube_with_slr_ready + // - test_kylin_cube_with_slr_ready_2_segments + // - test_kylin_cube_without_slr_ready + String cubes = hybrid1.getCanonicalName() + "," + cube2Clone.getCanonicalName(); + + SQLResponse sqlResponse = new SQLResponse(); + sqlResponse.setCube(cubes); + + String signature = SQLResponseSignatureUtil.createSignature(config, sqlResponse, projectName); + sqlResponse.setSignature(signature); + + Assert.assertTrue(SQLResponseSignatureUtil.checkSignature(config, sqlResponse, projectName)); + + {//Test the influence of related cubes status change + cube1 = cubeManager.updateCubeStatus(cube1, RealizationStatusEnum.DISABLED); + Assert.assertFalse(SQLResponseSignatureUtil.checkSignature(config, sqlResponse, projectName)); + + cube1 = cubeManager.updateCubeStatus(cube1, RealizationStatusEnum.READY); + Assert.assertTrue(SQLResponseSignatureUtil.checkSignature(config, sqlResponse, projectName)); + } + + {//Test the influence of segment changes + cube2Clone = cubeManager.updateCubeDropSegments(cube2Clone, cube2Clone.getSegments().get(0)); + Assert.assertFalse(SQLResponseSignatureUtil.checkSignature(config, sqlResponse, projectName)); + } + } + + @Test + public void testFactTableRealizationSetCalculator() throws IOException { + KylinConfig config = KylinConfig.createKylinConfig(getTestConfig()); + Map overrides = Maps.newHashMap(); + overrides.put("kylin.query.signature-class", + "org.apache.kylin.rest.signature.FactTableRealizationSetCalculator"); + + ProjectInstance projectInstance = ProjectManager.getInstance(config).getProject(projectName); + projectInstance.setConfig(KylinConfigExt.createInstance(config, overrides)); + + HybridManager hybridManager = HybridManager.getInstance(config); + HybridInstance hybrid1 = hybridManager.getHybridInstance("test_kylin_hybrid_ready"); + + CubeManager cubeManager = CubeManager.getInstance(config); + CubeInstance cube1 = cubeManager.getCube("test_kylin_cube_with_slr_ready_2_segments"); + CubeInstance cube2 = cubeManager.getCube("test_kylin_cube_without_slr_ready"); + CubeInstance cube2Clone = cloneCubeInstance(cubeManager, cube2, cube2.getName() + "_clone"); + CubeInstance cube3 = cloneCubeInstance(cubeManager, cube2, cube2.getDescName()); + + //Related cubes: + // - test_kylin_cube_with_slr_ready + // - test_kylin_cube_with_slr_ready_2_segments + // - test_kylin_cube_without_slr_ready + String cubes = hybrid1.getCanonicalName() + "," + cube2Clone.getCanonicalName(); + + SQLResponse sqlResponse = new SQLResponse(); + sqlResponse.setCube(cubes); + + String signature = SQLResponseSignatureUtil.createSignature(config, sqlResponse, projectName); + sqlResponse.setSignature(signature); + + Assert.assertTrue(SQLResponseSignatureUtil.checkSignature(config, sqlResponse, projectName)); + + {//Test the influence of related cubes status change + cube1 = cubeManager.updateCubeStatus(cube1, RealizationStatusEnum.DISABLED); + Assert.assertFalse(SQLResponseSignatureUtil.checkSignature(config, sqlResponse, projectName)); + + cube1 = cubeManager.updateCubeStatus(cube1, RealizationStatusEnum.READY); + Assert.assertTrue(SQLResponseSignatureUtil.checkSignature(config, sqlResponse, projectName)); + } + + {//Test the influence of cubes not in ${cubes} while share the same fact tables + cube3 = cubeManager.updateCubeStatus(cube3, RealizationStatusEnum.DISABLED); + Assert.assertFalse(SQLResponseSignatureUtil.checkSignature(config, sqlResponse, projectName)); + + cube3 = cubeManager.updateCubeStatus(cube3, RealizationStatusEnum.READY); + Assert.assertTrue(SQLResponseSignatureUtil.checkSignature(config, sqlResponse, projectName)); + } + + {//Test the influence of segment changes + cube2Clone = cubeManager.updateCubeDropSegments(cube2Clone, cube2Clone.getSegments().get(0)); + Assert.assertFalse(SQLResponseSignatureUtil.checkSignature(config, sqlResponse, projectName)); + } + } + + private CubeInstance cloneCubeInstance(CubeManager cubeManager, CubeInstance cube, String name) throws IOException { + CubeInstance cubeClone = cubeManager.createCube(name, projectName, cube.getDescriptor(), cube.getOwner()); + CubeUpdate cubeUpdate = new CubeUpdate(cubeClone.latestCopyForWrite()); + cubeUpdate.setToAddSegs(cube.getSegments().toArray(new CubeSegment[cube.getSegments().size()])); + cubeUpdate.setStatus(RealizationStatusEnum.READY); + return cubeManager.updateCube(cubeUpdate); + } +}