/* * 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.flink.graph.test.operations; import org.apache.flink.api.common.functions.FilterFunction; import org.apache.flink.api.java.DataSet; import org.apache.flink.api.java.ExecutionEnvironment; import org.apache.flink.api.java.io.LocalCollectionOutputFormat; import org.apache.flink.api.java.tuple.Tuple2; import org.apache.flink.graph.Edge; import org.apache.flink.graph.Graph; import org.apache.flink.graph.Triplet; import org.apache.flink.graph.Vertex; import org.apache.flink.graph.test.TestGraphUtils; import org.apache.flink.test.util.MultipleProgramsTestBase; import org.apache.flink.types.NullValue; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.util.ArrayList; import java.util.List; @RunWith(Parameterized.class) public class GraphOperationsITCase extends MultipleProgramsTestBase { public GraphOperationsITCase(TestExecutionMode mode) { super(mode); } private String expectedResult; @Test public void testUndirected() throws Exception { /* * Test getUndirected() */ final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); Graph<Long, Long, Long> graph = Graph.fromDataSet(TestGraphUtils.getLongLongVertexData(env), TestGraphUtils.getLongLongEdgeData(env), env); DataSet<Edge<Long, Long>> data = graph.getUndirected().getEdges(); List<Edge<Long, Long>> result = data.collect(); expectedResult = "1,2,12\n" + "2,1,12\n" + "1,3,13\n" + "3,1,13\n" + "2,3,23\n" + "3,2,23\n" + "3,4,34\n" + "4,3,34\n" + "3,5,35\n" + "5,3,35\n" + "4,5,45\n" + "5,4,45\n" + "5,1,51\n" + "1,5,51\n"; compareResultAsTuples(result, expectedResult); } @Test public void testReverse() throws Exception { /* * Test reverse() */ final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); Graph<Long, Long, Long> graph = Graph.fromDataSet(TestGraphUtils.getLongLongVertexData(env), TestGraphUtils.getLongLongEdgeData(env), env); DataSet<Edge<Long, Long>> data = graph.reverse().getEdges(); List<Edge<Long, Long>> result = data.collect(); expectedResult = "2,1,12\n" + "3,1,13\n" + "3,2,23\n" + "4,3,34\n" + "5,3,35\n" + "5,4,45\n" + "1,5,51\n"; compareResultAsTuples(result, expectedResult); } @SuppressWarnings("serial") @Test public void testSubGraph() throws Exception { /* * Test subgraph: */ final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); Graph<Long, Long, Long> graph = Graph.fromDataSet(TestGraphUtils.getLongLongVertexData(env), TestGraphUtils.getLongLongEdgeData(env), env); DataSet<Edge<Long, Long>> data = graph.subgraph( new FilterFunction<Vertex<Long, Long>>() { public boolean filter(Vertex<Long, Long> vertex) throws Exception { return (vertex.getValue() > 2); } }, new FilterFunction<Edge<Long, Long>>() { public boolean filter(Edge<Long, Long> edge) throws Exception { return (edge.getValue() > 34); } }).getEdges(); List<Edge<Long, Long>> result = data.collect(); expectedResult = "3,5,35\n" + "4,5,45\n"; compareResultAsTuples(result, expectedResult); } @SuppressWarnings("serial") @Test public void testFilterVertices() throws Exception { /* * Test filterOnVertices: */ final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); Graph<Long, Long, Long> graph = Graph.fromDataSet(TestGraphUtils.getLongLongVertexData(env), TestGraphUtils.getLongLongEdgeData(env), env); DataSet<Edge<Long, Long>> data = graph.filterOnVertices(new FilterFunction<Vertex<Long, Long>>() { public boolean filter(Vertex<Long, Long> vertex) throws Exception { return (vertex.getValue() > 2); } }).getEdges(); List<Edge<Long, Long>> result = data.collect(); expectedResult = "3,4,34\n" + "3,5,35\n" + "4,5,45\n"; compareResultAsTuples(result, expectedResult); } @SuppressWarnings("serial") @Test public void testFilterEdges() throws Exception { /* * Test filterOnEdges: */ final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); Graph<Long, Long, Long> graph = Graph.fromDataSet(TestGraphUtils.getLongLongVertexData(env), TestGraphUtils.getLongLongEdgeData(env), env); DataSet<Edge<Long, Long>> data = graph.filterOnEdges(new FilterFunction<Edge<Long, Long>>() { public boolean filter(Edge<Long, Long> edge) throws Exception { return (edge.getValue() > 34); } }).getEdges(); List<Edge<Long, Long>> result = data.collect(); expectedResult = "3,5,35\n" + "4,5,45\n" + "5,1,51\n"; compareResultAsTuples(result, expectedResult); } @Test public void testNumberOfVertices() throws Exception { /* * Test numberOfVertices() */ final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); Graph<Long, Long, Long> graph = Graph.fromDataSet(TestGraphUtils.getLongLongVertexData(env), TestGraphUtils.getLongLongEdgeData(env), env); DataSet<Long> data = env.fromElements(graph.numberOfVertices()); List<Long> result = data.collect(); expectedResult = "5"; compareResultAsText(result, expectedResult); } @Test public void testNumberOfEdges() throws Exception { /* * Test numberOfEdges() */ final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); Graph<Long, Long, Long> graph = Graph.fromDataSet(TestGraphUtils.getLongLongVertexData(env), TestGraphUtils.getLongLongEdgeData(env), env); DataSet<Long> data = env.fromElements(graph.numberOfEdges()); List<Long> result = data.collect(); expectedResult = "7"; compareResultAsText(result, expectedResult); } @Test public void testVertexIds() throws Exception { /* * Test getVertexIds() */ final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); Graph<Long, Long, Long> graph = Graph.fromDataSet(TestGraphUtils.getLongLongVertexData(env), TestGraphUtils.getLongLongEdgeData(env), env); DataSet<Long> data = graph.getVertexIds(); List<Long> result = data.collect(); expectedResult = "1\n2\n3\n4\n5\n"; compareResultAsText(result, expectedResult); } @Test public void testEdgesIds() throws Exception { /* * Test getEdgeIds() */ final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); Graph<Long, Long, Long> graph = Graph.fromDataSet(TestGraphUtils.getLongLongVertexData(env), TestGraphUtils.getLongLongEdgeData(env), env); DataSet<Tuple2<Long, Long>> data = graph.getEdgeIds(); List<Tuple2<Long, Long>> result = data.collect(); expectedResult = "1,2\n" + "1,3\n" + "2,3\n" + "3,4\n" + "3,5\n" + "4,5\n" + "5,1\n"; compareResultAsTuples(result, expectedResult); } @Test public void testUnion() throws Exception { /* * Test union() */ final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); Graph<Long, Long, Long> graph = Graph.fromDataSet(TestGraphUtils.getLongLongVertexData(env), TestGraphUtils.getLongLongEdgeData(env), env); List<Vertex<Long, Long>> vertices = new ArrayList<>(); List<Edge<Long, Long>> edges = new ArrayList<>(); vertices.add(new Vertex<>(6L, 6L)); edges.add(new Edge<>(6L, 1L, 61L)); graph = graph.union(Graph.fromCollection(vertices, edges, env)); DataSet<Edge<Long, Long>> data = graph.getEdges(); List<Edge<Long, Long>> result = data.collect(); expectedResult = "1,2,12\n" + "1,3,13\n" + "2,3,23\n" + "3,4,34\n" + "3,5,35\n" + "4,5,45\n" + "5,1,51\n" + "6,1,61\n"; compareResultAsTuples(result, expectedResult); } @Test public void testDifference() throws Exception { /*Test difference() method by checking the output for getEdges() on the resultant graph */ final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); Graph<Long, Long, Long> graph = Graph.fromDataSet(TestGraphUtils.getLongLongVertexData(env), TestGraphUtils.getLongLongEdgeData(env), env); Graph<Long, Long, Long> graph2 = Graph.fromDataSet(TestGraphUtils.getLongLongVertexDataDifference(env), TestGraphUtils.getLongLongEdgeDataDifference(env), env); graph = graph.difference(graph2); List<Edge<Long, Long>> result = graph.getEdges().collect(); expectedResult = "4,5,45\n"; compareResultAsTuples(result, expectedResult); } @Test public void testDifferenceVertices() throws Exception { /*Test difference() method by checking the output for getVertices() on the resultant graph */ final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); Graph<Long, Long, Long> graph = Graph.fromDataSet(TestGraphUtils.getLongLongVertexData(env), TestGraphUtils.getLongLongEdgeData(env), env); Graph<Long, Long, Long> graph2 = Graph.fromDataSet(TestGraphUtils.getLongLongVertexDataDifference(env), TestGraphUtils.getLongLongEdgeDataDifference(env), env); graph = graph.difference(graph2); List<Vertex<Long, Long>> result = graph.getVertices().collect(); expectedResult = "2,2\n" + "4,4\n" + "5,5\n"; compareResultAsTuples(result, expectedResult); } @Test public void testDifference2() throws Exception { /* * Test difference() such that no common vertices are there */ final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); Graph<Long, Long, Long> graph = Graph.fromDataSet(TestGraphUtils.getLongLongVertexData(env), TestGraphUtils.getLongLongEdgeData(env), env); DataSet<Vertex<Long, Long>> vertex = env.fromElements(new Vertex<>(6L, 6L)); Graph<Long, Long, Long> graph2 = Graph.fromDataSet(vertex, TestGraphUtils.getLongLongEdgeDataDifference2(env), env); graph = graph.difference(graph2); List<Edge<Long, Long>> result = graph.getEdges().collect(); expectedResult = "1,2,12\n" + "1,3,13\n" + "2,3,23\n" + "3,4,34\n" + "3,5,35\n" + "4,5,45\n" + "5,1,51\n"; compareResultAsTuples(result, expectedResult); } @Test public final void testIntersect() throws Exception { final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); @SuppressWarnings("unchecked") List<Edge<Long, Long>> edges1 = new ArrayList<>(); edges1.add(new Edge<>(1L, 3L, 12L)); edges1.add(new Edge<>(1L, 3L, 13L)); // needs to be in the output edges1.add(new Edge<>(1L, 3L, 14L)); @SuppressWarnings("unchecked") List<Edge<Long, Long>> edges2 = new ArrayList<>(); edges2.add(new Edge<>(1L, 3L, 13L)); Graph<Long, NullValue, Long> graph1 = Graph.fromCollection(edges1, env); Graph<Long, NullValue, Long> graph2 = Graph.fromCollection(edges2, env); Graph<Long, NullValue, Long> intersect = graph1.intersect(graph2, true); List<Vertex<Long, NullValue>> vertices = new ArrayList<>(); List<Edge<Long, Long>> edges = new ArrayList<>(); intersect.getVertices().output(new LocalCollectionOutputFormat<>(vertices)); intersect.getEdges().output(new LocalCollectionOutputFormat<>(edges)); env.execute(); String expectedVertices = "1,(null)\n" + "3,(null)\n"; String expectedEdges = "1,3,13\n"; compareResultAsTuples(vertices, expectedVertices); compareResultAsTuples(edges, expectedEdges); } @Test public final void testIntersectWithPairs() throws Exception { final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); @SuppressWarnings("unchecked") List<Edge<Long, Long>> edges1 = new ArrayList<>(); edges1.add(new Edge<>(1L, 3L, 12L)); edges1.add(new Edge<>(1L, 3L, 13L)); edges1.add(new Edge<>(1L, 3L, 13L)); // output edges1.add(new Edge<>(1L, 3L, 13L)); // output edges1.add(new Edge<>(1L, 3L, 14L)); // output @SuppressWarnings("unchecked") List<Edge<Long, Long>> edges2 = new ArrayList<>(); edges2.add(new Edge<>(1L, 3L, 13L)); // output edges2.add(new Edge<>(1L, 3L, 13L)); // output edges2.add(new Edge<>(1L, 3L, 14L)); // output Graph<Long, NullValue, Long> graph1 = Graph.fromCollection(edges1, env); Graph<Long, NullValue, Long> graph2 = Graph.fromCollection(edges2, env); Graph<Long, NullValue, Long> intersect = graph1.intersect(graph2, false); List<Vertex<Long, NullValue>> vertices = new ArrayList<>(); List<Edge<Long, Long>> edges = new ArrayList<>(); intersect.getVertices().output(new LocalCollectionOutputFormat<>(vertices)); intersect.getEdges().output(new LocalCollectionOutputFormat<>(edges)); env.execute(); String expectedVertices = "1,(null)\n" + "3,(null)\n"; String expectedEdges = "1,3,13\n" + "1,3,13\n" + "1,3,13\n" + "1,3,13\n" + "1,3,14\n" + "1,3,14"; compareResultAsTuples(vertices, expectedVertices); compareResultAsTuples(edges, expectedEdges); } @Test public void testTriplets() throws Exception { /* * Test getTriplets() */ final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment(); Graph<Long, Long, Long> graph = Graph.fromDataSet(TestGraphUtils.getLongLongVertexData(env), TestGraphUtils.getLongLongEdgeData(env), env); DataSet<Triplet<Long, Long, Long>> data = graph.getTriplets(); List<Triplet<Long, Long, Long>> result = data.collect(); expectedResult = "1,2,1,2,12\n" + "1,3,1,3,13\n" + "2,3,2,3,23\n" + "3,4,3,4,34\n" + "3,5,3,5,35\n" + "4,5,4,5,45\n" + "5,1,5,1,51\n"; compareResultAsTuples(result, expectedResult); } }