| /* |
| * Copyright 2017 HugeGraph Authors |
| * |
| * 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 com.baidu.hugegraph.loader.test.functional; |
| |
| import java.nio.charset.Charset; |
| import java.nio.file.Paths; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| |
| import org.apache.commons.lang3.StringUtils; |
| import org.junit.After; |
| import org.junit.AfterClass; |
| import org.junit.Before; |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| |
| import com.baidu.hugegraph.driver.GraphManager; |
| import com.baidu.hugegraph.driver.HugeClient; |
| import com.baidu.hugegraph.driver.SchemaManager; |
| import com.baidu.hugegraph.driver.TaskManager; |
| import com.baidu.hugegraph.loader.HugeGraphLoader; |
| import com.baidu.hugegraph.loader.exception.ParseException; |
| import com.baidu.hugegraph.structure.constant.DataType; |
| import com.baidu.hugegraph.structure.graph.Edge; |
| import com.baidu.hugegraph.structure.graph.Vertex; |
| import com.baidu.hugegraph.structure.schema.PropertyKey; |
| import com.baidu.hugegraph.testutil.Assert; |
| import com.google.common.collect.ImmutableList; |
| |
| public class LoaderTest { |
| |
| private static final Charset GBK = Charset.forName("GBK"); |
| |
| private static final String PATH_PREFIX = "src/test/resources"; |
| private static final String url = "http://127.0.0.1:8080"; |
| private static final String graph = "hugegraph"; |
| private static final HugeClient client = new HugeClient(url, graph); |
| |
| @BeforeClass |
| public static void setUp() { |
| clearFileData(); |
| clearServerData(); |
| } |
| |
| @Before |
| public void init() { |
| FileUtil.append(path("vertex_person.csv"), "name,age,city"); |
| FileUtil.append(path("vertex_software.csv"), GBK, "name,lang,price"); |
| FileUtil.append(path("edge_knows.csv"), |
| "source_name,target_name,date,weight"); |
| FileUtil.append(path("edge_created.csv"), |
| "source_name,target_name,date,weight"); |
| } |
| |
| @After |
| public void clear() { |
| clearFileData(); |
| clearServerData(); |
| } |
| |
| @AfterClass |
| public static void tearDown() { |
| FileUtil.delete(path("vertex_person.csv")); |
| FileUtil.delete(path("vertex_software.csv")); |
| FileUtil.delete(path("edge_knows.csv")); |
| FileUtil.delete(path("edge_created.csv")); |
| } |
| |
| private static void clearFileData() { |
| FileUtil.clear(path("vertex_person.csv")); |
| FileUtil.clear(path("vertex_software.csv")); |
| FileUtil.clear(path("edge_knows.csv")); |
| FileUtil.clear(path("edge_created.csv")); |
| } |
| |
| private static void clearServerData() { |
| SchemaManager schema = client.schema(); |
| GraphManager graph = client.graph(); |
| TaskManager task = client.task(); |
| // Clear edge |
| graph.listEdges().forEach(e -> graph.removeEdge(e.id())); |
| // Clear vertex |
| graph.listVertices().forEach(v -> graph.removeVertex(v.id())); |
| |
| // Clear schema |
| List<Long> taskIds = new ArrayList<>(); |
| schema.getIndexLabels().forEach(il -> { |
| taskIds.add(schema.removeIndexLabelAsync(il.name())); |
| }); |
| taskIds.forEach(id -> task.waitUntilTaskCompleted(id, 5L)); |
| taskIds.clear(); |
| schema.getEdgeLabels().forEach(el -> { |
| taskIds.add(schema.removeEdgeLabelAsync(el.name())); |
| }); |
| taskIds.forEach(id -> task.waitUntilTaskCompleted(id, 5L)); |
| taskIds.clear(); |
| schema.getVertexLabels().forEach(vl -> { |
| taskIds.add(schema.removeVertexLabelAsync(vl.name())); |
| }); |
| taskIds.forEach(id -> task.waitUntilTaskCompleted(id, 5L)); |
| taskIds.clear(); |
| schema.getPropertyKeys().forEach(pk -> { |
| schema.removePropertyKey(pk.name()); |
| }); |
| } |
| |
| /** |
| * NOTE: Unsupport auto create schema |
| */ |
| //@Test |
| public void testLoadWithAutoCreateSchema() { |
| String[] args = new String[]{"-f", "example/struct.json", |
| "-g", "hugegraph", |
| "--num-threads", "2"}; |
| try { |
| HugeGraphLoader.main(args); |
| } catch (Exception e) { |
| Assert.fail("Should not throw exception, but throw " + e); |
| } |
| |
| List<PropertyKey> propertyKeys = client.schema().getPropertyKeys(); |
| propertyKeys.forEach(pkey -> { |
| Assert.assertEquals(DataType.TEXT, pkey.dataType()); |
| }); |
| |
| List<Vertex> vertices = client.graph().listVertices(); |
| List<Edge> edges = client.graph().listEdges(); |
| |
| Assert.assertEquals(7, vertices.size()); |
| Assert.assertEquals(6, edges.size()); |
| |
| boolean interestedVertex = false; |
| for (Vertex vertex : vertices) { |
| Assert.assertEquals(String.class, vertex.id().getClass()); |
| if (((String) vertex.id()).contains("li,nary")) { |
| interestedVertex = true; |
| Assert.assertEquals("26", vertex.property("age")); |
| Assert.assertEquals("Wu,han", vertex.property("city")); |
| } |
| } |
| Assert.assertTrue(interestedVertex); |
| |
| boolean interestedEdge = false; |
| for (Edge edge : edges) { |
| Assert.assertEquals(String.class, edge.source().getClass()); |
| Assert.assertEquals(String.class, edge.target().getClass()); |
| if (((String) edge.source()).contains("marko") && |
| ((String) edge.target()).contains("vadas")) { |
| interestedEdge = true; |
| Assert.assertEquals("20160110", edge.property("date")); |
| Assert.assertEquals("0.5", edge.property("weight")); |
| } |
| } |
| Assert.assertTrue(interestedEdge); |
| } |
| |
| @Test |
| public void testLoadWithCustomizedSchema() { |
| FileUtil.append(path("vertex_person.csv"), |
| "marko,29,Beijing", |
| "vadas,27,Hongkong", |
| "josh,32,Beijing", |
| "peter,35,Shanghai", |
| "\"li,nary\",26,\"Wu,han\""); |
| |
| FileUtil.append(path("vertex_software.csv"), |
| "lop,java,328", |
| "ripple,java,199"); |
| |
| FileUtil.append(path("edge_knows.csv"), |
| "marko,vadas,20160110,0.5", |
| "marko,josh,20130220,1.0"); |
| |
| FileUtil.append(path("edge_created.csv"), |
| "marko,lop,20171210,0.4", |
| "josh,lop,20091111,0.4", |
| "josh,ripple,20171210,1.0", |
| "peter,lop,20170324,0.2"); |
| |
| String[] args = new String[]{"-f", path("struct.json"), |
| "-s", path("schema.groovy"), |
| "-g", "hugegraph", |
| "--num-threads", "2", |
| "--test-mode", "true"}; |
| try { |
| HugeGraphLoader.main(args); |
| } catch (Exception e) { |
| Assert.fail("Should not throw exception, but throw " + e); |
| } |
| |
| List<Vertex> vertices = client.graph().listVertices(); |
| List<Edge> edges = client.graph().listEdges(); |
| |
| Assert.assertEquals(7, vertices.size()); |
| Assert.assertEquals(6, edges.size()); |
| |
| boolean interestedVertex = false; |
| for (Vertex vertex : vertices) { |
| Assert.assertEquals(String.class, vertex.id().getClass()); |
| if (((String) vertex.id()).contains("li,nary")) { |
| interestedVertex = true; |
| Assert.assertEquals(26, vertex.property("age")); |
| Assert.assertEquals("Wu,han", vertex.property("city")); |
| } |
| } |
| Assert.assertTrue(interestedVertex); |
| |
| boolean interestedEdge = false; |
| for (Edge edge : edges) { |
| Assert.assertEquals(String.class, edge.source().getClass()); |
| Assert.assertEquals(String.class, edge.target().getClass()); |
| if (((String) edge.source()).contains("marko") && |
| ((String) edge.target()).contains("vadas")) { |
| interestedEdge = true; |
| Assert.assertEquals("20160110", edge.property("date")); |
| Assert.assertEquals(0.5, edge.property("weight")); |
| } |
| } |
| Assert.assertTrue(interestedEdge); |
| } |
| |
| @Test |
| public void testVertexIdExceedLimit() { |
| Integer[] array = new Integer[129]; |
| Arrays.fill(array, 1); |
| String tooLongId = StringUtils.join(array); |
| String line = FileUtil.newCSVLine(tooLongId, 29, "Beijing"); |
| FileUtil.append(path("vertex_person.csv"), line); |
| |
| String[] args = new String[]{"-f", path("struct.json"), |
| "-s", path("schema.groovy"), |
| "-g", "hugegraph", |
| "--num-threads", "2", |
| "--test-mode", "true"}; |
| |
| Assert.assertThrows(ParseException.class, () -> { |
| HugeGraphLoader.main(args); |
| }); |
| } |
| |
| @Test |
| public void testLoadWithIdExceedLimitLengthInBytes() { |
| String pk = "ecommerce__color__极光银翻盖上盖+" + |
| "琥珀啡翻盖下盖+咖啡金翻盖上盖装饰片+" + |
| "香槟金主镜片+深咖啡色副镜片+琥珀>" + |
| "啡前壳+极光银后壳+浅灰电池扣+极光银电池组件+深灰天线"; |
| assert pk.length() < 128; |
| String line = FileUtil.newCSVLine(pk, "中文", 328); |
| FileUtil.append(path("vertex_software.csv"), GBK, line); |
| |
| String[] args = new String[]{"-f", path("struct.json"), |
| "-s", path("schema.groovy"), |
| "-g", "hugegraph", |
| "--num-threads", "2", |
| "--test-mode", "true"}; |
| // Bytes encoded in utf-8 exceed 128 |
| Assert.assertThrows(ParseException.class, () -> { |
| HugeGraphLoader.main(args); |
| }); |
| } |
| |
| @Test |
| public void testVertexTooManyColumns() { |
| String line = FileUtil.newCSVLine("marko", 29, "Beijing", "Extra"); |
| FileUtil.append(path("vertex_person.csv"), line); |
| |
| String[] args = new String[]{"-f", path("struct.json"), |
| "-s", path("schema.groovy"), |
| "-g", "hugegraph", |
| "--num-threads", "2", |
| "--test-mode", "true"}; |
| |
| Assert.assertThrows(ParseException.class, () -> { |
| HugeGraphLoader.main(args); |
| }); |
| } |
| |
| @Test |
| public void testVertexTooFewColumns() { |
| String line = FileUtil.newCSVLine("marko", 29); |
| FileUtil.append(path("vertex_person.csv"), line); |
| |
| String[] args = new String[]{"-f", path("struct.json"), |
| "-s", path("schema.groovy"), |
| "-g", "hugegraph", |
| "--num-threads", "2", |
| "--test-mode", "true"}; |
| |
| Assert.assertThrows(ParseException.class, () -> { |
| HugeGraphLoader.main(args); |
| }); |
| } |
| |
| @Test |
| public void testUnmatchedPropertyDataType() { |
| String line = FileUtil.newCSVLine("marko", "Should be number", |
| "Beijing"); |
| FileUtil.append(path("vertex_person.csv"), line); |
| |
| String[] args = new String[]{"-f", path("struct.json"), |
| "-s", path("schema.groovy"), |
| "-g", "hugegraph", |
| "--num-threads", "2", |
| "--test-mode", "true"}; |
| |
| Assert.assertThrows(ParseException.class, () -> { |
| HugeGraphLoader.main(args); |
| }); |
| } |
| |
| @Test |
| public void testVertexPkContainsSpecicalSymbol() { |
| String line = FileUtil.newCSVLine("mar:ko!", 29, "Beijing"); |
| FileUtil.append(path("vertex_person.csv"), line); |
| |
| String[] args = new String[]{"-f", path("struct.json"), |
| "-s", path("schema.groovy"), |
| "-g", "hugegraph", |
| "--num-threads", "2", |
| "--test-mode", "true"}; |
| |
| try { |
| HugeGraphLoader.main(args); |
| } catch (Exception e) { |
| Assert.fail("Should not throw exception, but throw " + e); |
| } |
| |
| List<Vertex> vertices = client.graph().listVertices(); |
| Assert.assertEquals(1, vertices.size()); |
| Vertex vertex = vertices.get(0); |
| Assert.assertEquals(String.class, vertex.id().getClass()); |
| Assert.assertTrue(((String) vertex.id()).contains(":mar`:ko`!")); |
| Assert.assertEquals(29, vertex.property("age")); |
| Assert.assertEquals("Beijing", vertex.property("city")); |
| } |
| |
| @Test |
| public void testLoadWithUnmatchedEncodingCharset() { |
| String line = FileUtil.newCSVLine("lop", "中文", 328); |
| FileUtil.append(path("vertex_software.csv"), GBK, line); |
| |
| String[] args = new String[]{"-f", path("struct.json"), |
| "-g", "hugegraph", |
| "-s", path("schema.groovy"), |
| "--num-threads", "2", |
| "--test-mode", "true"}; |
| try { |
| HugeGraphLoader.main(args); |
| } catch (Exception e) { |
| Assert.fail("Should not throw exception, but throw " + e); |
| } |
| |
| List<Vertex> vertices = client.graph().listVertices(); |
| Assert.assertEquals(1, vertices.size()); |
| Vertex vertex = vertices.get(0); |
| Assert.assertEquals("lop", vertex.property("name")); |
| Assert.assertNotEquals("中文", vertex.property("lang")); |
| Assert.assertEquals(328.0, vertex.property("price")); |
| } |
| |
| @Test |
| public void testLoadWithMatchedEncodingCharset() { |
| String line = FileUtil.newCSVLine("lop", "中文", 328); |
| FileUtil.append(path("vertex_software.csv"), GBK, line); |
| |
| String[] args = new String[]{"-f", path("struct_gbk.json"), |
| "-g", "hugegraph", |
| "-s", path("schema.groovy"), |
| "--num-threads", "2", |
| "--test-mode", "true"}; |
| |
| try { |
| HugeGraphLoader.main(args); |
| } catch (Exception e) { |
| Assert.fail("Should not throw exception, but throw " + e); |
| } |
| |
| List<Vertex> vertices = client.graph().listVertices(); |
| Assert.assertEquals(1, vertices.size()); |
| Vertex vertex = vertices.get(0); |
| Assert.assertEquals("lop", vertex.property("name")); |
| Assert.assertEquals("中文", vertex.property("lang")); |
| Assert.assertEquals(328.0, vertex.property("price")); |
| } |
| |
| @Test |
| public void testLoadWithValueListPorpertyInJsonFile() { |
| String line = FileUtil.newCSVLine("marko", 29, "Beijing"); |
| FileUtil.append(path("vertex_person.csv"), line); |
| |
| line = FileUtil.newCSVLine("lop", "中文", 328); |
| FileUtil.append(path("vertex_software.csv"), GBK, line); |
| |
| line = "{\"person_name\": \"marko\", \"software_name\": \"lop\", " + |
| "\"feel\": [\"so so\", \"good\", \"good\"]}"; |
| FileUtil.append(path("edge_use.json"), line); |
| |
| String[] args = new String[]{"-f", path("struct_edge_use.json"), |
| "-g", "hugegraph", |
| "-s", path("schema.groovy"), |
| "--num-threads", "2", |
| "--test-mode", "true"}; |
| |
| try { |
| HugeGraphLoader.main(args); |
| } catch (Exception e) { |
| FileUtil.delete(path("edge_use.json")); |
| Assert.fail("Should not throw exception, but throw " + e); |
| } |
| |
| List<Edge> edges = client.graph().listEdges(); |
| Assert.assertEquals(1, edges.size()); |
| Edge edge = edges.get(0); |
| |
| Assert.assertEquals("person", edge.sourceLabel()); |
| Assert.assertEquals("software", edge.targetLabel()); |
| Assert.assertEquals(ImmutableList.of("so so", "good", "good"), |
| edge.property("feel")); |
| |
| FileUtil.delete(path("edge_use.json")); |
| } |
| |
| @Test |
| public void testLoadWithValueSetPorpertyInJsonFile() { |
| String line = FileUtil.newCSVLine("marko", 29, "Beijing"); |
| FileUtil.append(path("vertex_person.csv"), line); |
| |
| line = FileUtil.newCSVLine("lop", "中文", 328); |
| FileUtil.append(path("vertex_software.csv"), GBK, line); |
| |
| line = "{\"person_name\": \"marko\", \"software_name\": \"lop\", " + |
| "\"time\": [\"20171210\", \"20180101\"]}"; |
| FileUtil.append(path("edge_use.json"), line); |
| |
| String[] args = new String[]{"-f", path("struct_edge_use.json"), |
| "-g", "hugegraph", |
| "-s", path("schema.groovy"), |
| "--num-threads", "2", |
| "--test-mode", "true"}; |
| |
| try { |
| HugeGraphLoader.main(args); |
| } catch (Exception e) { |
| FileUtil.delete(path("edge_use.json")); |
| Assert.fail("Should not throw exception, but throw " + e); |
| } |
| |
| List<Edge> edges = client.graph().listEdges(); |
| Assert.assertEquals(1, edges.size()); |
| Edge edge = edges.get(0); |
| |
| Assert.assertEquals("person", edge.sourceLabel()); |
| Assert.assertEquals("software", edge.targetLabel()); |
| /* |
| * NOTE: Although the cardinality of the property is set in schema |
| * declaration, client will deserialize it to list type in default. |
| */ |
| Assert.assertEquals(ImmutableList.of("20171210", "20180101"), |
| edge.property("time")); |
| |
| FileUtil.delete(path("edge_use.json")); |
| } |
| |
| @Test |
| public void testLoadVerticesWithCustomizedNumberId() { |
| String line = FileUtil.newCSVLine(1, "marko", 29, "Beijing"); |
| FileUtil.append(path("vertex_person_number_id.csv"), line); |
| |
| String[] args = new String[]{"-f", path("struct_number_id.json"), |
| "-g", "hugegraph", |
| "-s", path("schema_number_id.groovy"), |
| "--test-mode", "true"}; |
| |
| try { |
| HugeGraphLoader.main(args); |
| } catch (Exception e) { |
| FileUtil.delete(path("vertex_person_number_id.csv")); |
| Assert.fail("Should not throw exception, but throw " + e); |
| } |
| |
| List<Vertex> vertices = client.graph().listVertices(); |
| Assert.assertEquals(1, vertices.size()); |
| Vertex vertex = vertices.get(0); |
| |
| Assert.assertEquals(1, vertex.id()); |
| Assert.assertEquals("person", vertex.label()); |
| Assert.assertEquals("marko", vertex.property("name")); |
| Assert.assertEquals(29, vertex.property("age")); |
| Assert.assertEquals("Beijing", vertex.property("city")); |
| |
| FileUtil.delete(path("vertex_person_number_id.csv")); |
| } |
| |
| @Test |
| public void testLoadVerticesWithJointPrimaryKeys() { |
| String line = FileUtil.newCSVLine("marko", 29, "Beijing"); |
| FileUtil.append(path("vertex_person.csv"), line); |
| |
| String[] args = new String[]{"-f", path("struct_joint_pk.json"), |
| "-s", path("schema_joint_pk.groovy"), |
| "-g", "hugegraph", |
| "--test-mode", "true"}; |
| try { |
| HugeGraphLoader.main(args); |
| } catch (Exception e) { |
| Assert.fail("Should not throw exception, but throw " + e); |
| } |
| |
| List<Vertex> vertices = client.graph().listVertices(); |
| |
| Assert.assertEquals(1, vertices.size()); |
| Vertex vertex = vertices.get(0); |
| |
| Assert.assertTrue(vertex.id().toString().contains("marko!Beijing")); |
| Assert.assertEquals("person", vertex.label()); |
| Assert.assertEquals("marko", vertex.property("name")); |
| Assert.assertEquals(29, vertex.property("age")); |
| Assert.assertEquals("Beijing", vertex.property("city")); |
| } |
| |
| private static String path(String fileName) { |
| return Paths.get(PATH_PREFIX, fileName).toString(); |
| } |
| } |