From 48f135c8319c582f77ee5f4b7a34404f8ce34aa3 Mon Sep 17 00:00:00 2001 From: Abhimanyu Singh Gaur <12651351+abhimanyusinghgaur@users.noreply.github.com> Date: Thu, 8 Apr 2021 18:16:47 +0530 Subject: [PATCH] don't use dgraph binary in tests --- build.gradle | 3 + src/test/java/io/dgraph/AclTest.java | 156 +---------- .../java/io/dgraph/DgraphIntegrationTest.java | 3 +- src/test/java/io/dgraph/TestUtil.java | 256 ++++++++++++++++++ 4 files changed, 272 insertions(+), 146 deletions(-) create mode 100644 src/test/java/io/dgraph/TestUtil.java diff --git a/build.gradle b/build.gradle index c8743c0f..d4b68300 100644 --- a/build.gradle +++ b/build.gradle @@ -114,6 +114,9 @@ dependencies { testCompile "io.opencensus:opencensus-exporter-trace-jaeger:${openCensusVersion}" testRuntime "io.opencensus:opencensus-impl:${openCensusVersion}" + // Used for unmarshalling a JSON GraphQL response + testCompile "com.google.code.gson:gson:2.8.6" + // Declare the dependency for your favourite test framework you want to use in your tests. testCompile 'org.testng:testng:6.8.8' // javax.annotation is removed from the oracle java se 11, and requires explicit dependency diff --git a/src/test/java/io/dgraph/AclTest.java b/src/test/java/io/dgraph/AclTest.java index 456bf88b..a0535889 100644 --- a/src/test/java/io/dgraph/AclTest.java +++ b/src/test/java/io/dgraph/AclTest.java @@ -7,7 +7,6 @@ import io.grpc.StatusRuntimeException; import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; import java.util.stream.Collectors; import org.testng.annotations.BeforeClass; @@ -16,7 +15,6 @@ public class AclTest extends DgraphIntegrationTest { private static final String USER_ID = "alice"; private static final String USER_PASSWORD = "simplepassword"; - private static final String GUARDIAN_CREDS = "user=groot;password=password;namespace=0"; private static final String PREDICATE_TO_READ = "predicate_to_read"; private static final String PREDICATE_TO_WRITE = "predicate_to_write"; private static final String PREDICATE_TO_ALTER = "predicate_to_alter"; @@ -24,8 +22,6 @@ public class AclTest extends DgraphIntegrationTest { private static final String UNUSED_GROUP = "unusedGroup"; private static final String DEV_GROUP = "dev"; - private static final String DGRAPH_ENDPOINT = TEST_HOSTNAME + ":" + TEST_PORT; - @BeforeClass public void setSchema() { dgraphClient.alter( @@ -88,119 +84,28 @@ private void createAccountAndData() throws Exception { .build()); } - private void createGroupAndACLs(String group, boolean addUserToGroup) - throws IOException, InterruptedException { + private void createGroupAndACLs(String group, boolean addUserToGroup) throws Exception { // create a new group - checkCmd( - "unable to create the group " + group, - "dgraph", - "acl", - "add", - "-a", - DGRAPH_ENDPOINT, - "-g", - group, - "--guardian-creds", - GUARDIAN_CREDS); + TestUtil.addGroup(group); if (addUserToGroup) { - checkCmd( - "unable to add user " + USER_ID + " to the group " + group, - "dgraph", - "acl", - "mod", - "-a", - DGRAPH_ENDPOINT, - "-u", - USER_ID, - "--group_list", - group, - "--guardian-creds", - GUARDIAN_CREDS); + TestUtil.updateUser(USER_ID, group, true); } // add READ permission on the predicate_to_read to the group - checkCmd( - "unable to add READ permission on " + PREDICATE_TO_READ + " to the group " + group, - "dgraph", - "acl", - "mod", - "-a", - DGRAPH_ENDPOINT, - "-g", - group, - "-p", - PREDICATE_TO_READ, - "-m", - "4", - "--guardian-creds", - GUARDIAN_CREDS); + TestUtil.updateGroup(group, PREDICATE_TO_READ, 4); // also add READ permission on the attribute queryAttr, which is used inside the query block - checkCmd( - "unable to add READ permission on " + QUERY_ATTR + " to the group " + group, - "dgraph", - "acl", - "mod", - "-a", - DGRAPH_ENDPOINT, - "-g", - group, - "-p", - QUERY_ATTR, - "-m", - "4", - "--guardian-creds", - GUARDIAN_CREDS); + TestUtil.updateGroup(group, QUERY_ATTR, 4); - checkCmd( - "unable to add WRITE permission on " + PREDICATE_TO_WRITE + " to the group " + group, - "dgraph", - "acl", - "mod", - "-a", - DGRAPH_ENDPOINT, - "-g", - group, - "-p", - PREDICATE_TO_WRITE, - "-m", - "2", - "--guardian-creds", - GUARDIAN_CREDS); + TestUtil.updateGroup(group, PREDICATE_TO_WRITE, 2); - checkCmd( - "unable to add ALTER permission on " + PREDICATE_TO_ALTER + " to the group " + group, - "dgraph", - "acl", - "mod", - "-a", - DGRAPH_ENDPOINT, - "-g", - group, - "-p", - PREDICATE_TO_ALTER, - "-m", - "1", - "--guardian-creds", - GUARDIAN_CREDS); + TestUtil.updateGroup(group, PREDICATE_TO_ALTER, 1); } - private void removeUserFromAllGroups() throws IOException, InterruptedException { - checkCmd( - "unable to remove user " + USER_ID + " from all the groups", - "dgraph", - "acl", - "mod", - "-a", - DGRAPH_ENDPOINT, - "-u", - USER_ID, - "--group_list", - "", - "--guardian-creds", - GUARDIAN_CREDS); + private void removeUserFromAllGroups() throws Exception { + TestUtil.updateUser(USER_ID, DEV_GROUP, false); } private void queryPredicateWithUserAccount(boolean shouldFail) { @@ -278,47 +183,8 @@ private void verifyOperation(boolean shouldFail, String operation, Runnable runn } private void resetUser() throws Exception { - Process deleteUserCmd = - new ProcessBuilder( - "dgraph", - "acl", - "del", - "-a", - DGRAPH_ENDPOINT, - "-u", - USER_ID, - "--guardian-creds", - GUARDIAN_CREDS) - .start(); - deleteUserCmd.waitFor(); - - Process createUserCmd = - new ProcessBuilder( - "dgraph", - "acl", - "add", - "-a", - DGRAPH_ENDPOINT, - "-u", - USER_ID, - "-p", - USER_PASSWORD, - "--guardian-creds", - GUARDIAN_CREDS) - .redirectErrorStream(true) - .start(); - createUserCmd.waitFor(); - if (createUserCmd.exitValue() != 0) { - // print out the output from the command - InputStream inputStream = createUserCmd.getInputStream(); - BufferedReader br = new BufferedReader(new InputStreamReader(inputStream)); - String line; - while ((line = br.readLine()) != null) { - System.out.println(line); - } - - throw new Exception("unable to create user"); - } + TestUtil.deleteUser(USER_ID); + TestUtil.addUser(USER_ID, USER_PASSWORD); } private void checkCmd(String failureMsg, String... args) diff --git a/src/test/java/io/dgraph/DgraphIntegrationTest.java b/src/test/java/io/dgraph/DgraphIntegrationTest.java index 394cd644..2b516ae2 100644 --- a/src/test/java/io/dgraph/DgraphIntegrationTest.java +++ b/src/test/java/io/dgraph/DgraphIntegrationTest.java @@ -29,7 +29,8 @@ public abstract class DgraphIntegrationTest { static final Logger logger = LoggerFactory.getLogger(DgraphIntegrationTest.class); static final String TEST_HOSTNAME = "localhost"; - static final int TEST_PORT = 9180; + static final int TEST_gRPC_PORT = 9180; + static final int TEST_HTTP_PORT = 8180; protected static DgraphClient dgraphClient; private static ManagedChannel channel1, channel2, channel3; diff --git a/src/test/java/io/dgraph/TestUtil.java b/src/test/java/io/dgraph/TestUtil.java new file mode 100644 index 00000000..6a27b88f --- /dev/null +++ b/src/test/java/io/dgraph/TestUtil.java @@ -0,0 +1,256 @@ +package io.dgraph; + +import static io.dgraph.DgraphIntegrationTest.TEST_HOSTNAME; +import static io.dgraph.DgraphIntegrationTest.TEST_HTTP_PORT; + +import com.google.gson.Gson; +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class TestUtil { + private static final String GROOT_USERNAME = "groot"; + private static final String GROOT_PASSWORD = "password"; + private static final String ADMIN_HTTP_ENDPOINT = + "http://" + TEST_HOSTNAME + ":" + TEST_HTTP_PORT + "/admin"; + + private static class GraphQLRequest { + public String query; + public Map variables; + + // excluded from serialization/deserialization + public transient Map headers; + + public GraphQLResponse execute(String url) throws Exception { + Gson gson = new Gson(); + String response = executePost(url, gson.toJson(this), this.headers); + return gson.fromJson(response, GraphQLResponse.class); + } + + public GraphQLResponse executeAsGroot(String url) throws Exception { + if (this.headers == null) { + this.headers = new HashMap<>(); + } + this.headers.put("X-Dgraph-AccessToken", login(GROOT_USERNAME, GROOT_PASSWORD)); + return this.execute(url); + } + } + + private static class GraphQLResponse { + public List errors; + public Map data; + + public static class GqlError { + public String message; + } + + public void assertNoError() throws Exception { + if (this.errors != null && this.errors.size() > 0) { + throw new Exception(this.errors.toString()); + } + } + } + + /** @return the accessJWT of the logged-in user. */ + public static String login(String userId, String password) throws Exception { + GraphQLRequest req = new GraphQLRequest(); + req.query = + "" + + "mutation login($userId: String, $pass: String) {\n" + + " login(userId: $userId, password: $pass) {\n" + + " response {\n" + + " accessJWT\n" + + " }\n" + + " }\n" + + "}"; + req.variables = + new HashMap() { + { + put("userId", userId); + put("pass", password); + } + }; + + GraphQLResponse resp = req.execute(ADMIN_HTTP_ENDPOINT); + resp.assertNoError(); + + return (String) + ((Map) ((Map) resp.data.get("login")).get("response")) + .get("accessJWT"); + } + + public static void addUser(String username, String password) throws Exception { + GraphQLRequest req = new GraphQLRequest(); + req.query = + "" + + "mutation addUser($name: String!, $pass: String!) {\n" + + " addUser(input: [{name: $name, password: $pass}]) {\n" + + " user {\n" + + " name\n" + + " }\n" + + " }\n" + + "}"; + req.variables = + new HashMap() { + { + put("name", username); + put("pass", password); + } + }; + + GraphQLResponse resp = req.executeAsGroot(ADMIN_HTTP_ENDPOINT); + resp.assertNoError(); + } + + /** @param setOrRemove true if set, false if remove. */ + public static void updateUser(String username, String group, boolean setOrRemove) + throws Exception { + GraphQLRequest req = new GraphQLRequest(); + if (setOrRemove) { + req.query = + "" + + "mutation updateUser($name: String, $group: String!) {\n" + + " updateUser(input: {filter: {name: {eq: $name}}, set: {groups: [{name: $group}]}}) {\n" + + " user {\n" + + " name\n" + + " }\n" + + " }\n" + + "}"; + } else { + req.query = + "" + + "mutation updateUser($name: String, $group: String!) {\n" + + " updateUser(input: {filter: {name: {eq: $name}}, remove: {groups: [{name: $group}]}}) {\n" + + " user {\n" + + " name\n" + + " }\n" + + " }\n" + + "}"; + } + req.variables = + new HashMap() { + { + put("name", username); + put("group", group); + } + }; + + GraphQLResponse resp = req.executeAsGroot(ADMIN_HTTP_ENDPOINT); + resp.assertNoError(); + } + + public static void deleteUser(String username) throws Exception { + GraphQLRequest req = new GraphQLRequest(); + req.query = + "" + + "mutation ($name: String!) {\n" + + " deleteUser(filter: {name: { eq: $name } }) {\n" + + " msg\n" + + " numUids\n" + + " }\n" + + "}"; + req.variables = + new HashMap() { + { + put("name", username); + } + }; + + GraphQLResponse resp = req.executeAsGroot(ADMIN_HTTP_ENDPOINT); + resp.assertNoError(); + } + + public static void addGroup(String groupname) throws Exception { + GraphQLRequest req = new GraphQLRequest(); + req.query = + "" + + "mutation addGroup($name: String!) {\n" + + " addGroup(input: [{name: $name}]) {\n" + + " group {\n" + + " name\n" + + " }\n" + + " }\n" + + "}"; + req.variables = + new HashMap() { + { + put("name", groupname); + } + }; + + GraphQLResponse resp = req.executeAsGroot(ADMIN_HTTP_ENDPOINT); + resp.assertNoError(); + } + + public static void updateGroup(String group, String pred, int perm) throws Exception { + GraphQLRequest req = new GraphQLRequest(); + req.query = + "" + + "mutation updateGroup($gname: String!, $pred: String!, $perm: Int!) {\n" + + " updateGroup(input: {filter: {name: {eq: $gname}}, set: {rules: [{predicate: $pred, permission: $perm}]}}) {\n" + + " group {\n" + + " name\n" + + " }\n" + + " }\n" + + "}"; + req.variables = + new HashMap() { + { + put("gname", group); + put("pred", pred); + put("perm", perm); + } + }; + + GraphQLResponse resp = req.executeAsGroot(ADMIN_HTTP_ENDPOINT); + resp.assertNoError(); + } + + private static String executePost(String targetURL, String body, Map headers) + throws Exception { + HttpURLConnection connection = null; + + try { + // Create connection + URL url = new URL(targetURL); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + if (headers != null) { + for (Map.Entry entry : headers.entrySet()) { + connection.setRequestProperty(entry.getKey(), entry.getValue()); + } + } + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestProperty("Content-Length", Integer.toString(body.getBytes().length)); + + connection.setUseCaches(false); + connection.setDoOutput(true); + + // Send request + DataOutputStream wr = new DataOutputStream(connection.getOutputStream()); + wr.writeBytes(body); + wr.close(); + + // Get Response + InputStream is = connection.getInputStream(); + BufferedReader rd = new BufferedReader(new InputStreamReader(is)); + StringBuilder response = new StringBuilder(); + String line; + while ((line = rd.readLine()) != null) { + response.append(line); + } + rd.close(); + return response.toString(); + } finally { + if (connection != null) { + connection.disconnect(); + } + } + } +}