You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@systemds.apache.org by ba...@apache.org on 2020/09/10 13:06:43 UTC

[systemds] branch master updated: [MINOR] Cleanup in exception handling

This is an automated email from the ASF dual-hosted git repository.

baunsgaard pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/systemds.git


The following commit(s) were added to refs/heads/master by this push:
     new 69c015f  [MINOR] Cleanup in exception handling
69c015f is described below

commit 69c015f4e2ef5d435bc0f470e7012bd01fe4e200
Author: baunsgaard <ba...@tugraz.at>
AuthorDate: Thu Sep 10 15:01:16 2020 +0200

    [MINOR] Cleanup in exception handling
    
    Cleanup in the DMLScript execution, by reverting to printing stacktrace
    in the bottom of output if --debug flag is set.
    
    Also the error messages colour code is moved to a line above and bellow
    output, to separate the colour code from the output, in case the terminal
    does not support color coding.
    
    New test type that verifies the user experience when experiencing
    errors while running systemds.
---
 src/main/java/org/apache/sysds/api/DMLScript.java  |  48 ++++++----
 .../java/org/apache/sysds/test/usertest/Base.java  | 106 +++++++++++++++++++++
 .../sysds/test/usertest/UserInterfaceTest.java     |  55 +++++++++++
 src/test/scripts/usertest/Stop.dml                 |  22 +++++
 src/test/scripts/usertest/SyntaxError.dml          |  22 +++++
 src/test/scripts/usertest/helloWorld.dml           |  22 +++++
 6 files changed, 255 insertions(+), 20 deletions(-)

diff --git a/src/main/java/org/apache/sysds/api/DMLScript.java b/src/main/java/org/apache/sysds/api/DMLScript.java
index 2f01647..758fde6 100644
--- a/src/main/java/org/apache/sysds/api/DMLScript.java
+++ b/src/main/java/org/apache/sysds/api/DMLScript.java
@@ -161,32 +161,13 @@ public class DMLScript
 			String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
 			DMLScript.executeScript(conf, otherArgs);
 		} catch(Exception e){
+			errorPrint(e);
 			for(String s: args){
 				if(s.trim().contains("-debug")){
 					e.printStackTrace();
 				}
 			}
-			final String ANSI_RED = "\u001B[31m";
-			final String ANSI_RESET = "\u001B[0m";
-			StringBuilder sb = new StringBuilder();
-			sb.append(ANSI_RED);
-			sb.append("An Error Occured : ");
-			sb.append("\n" );
-			sb.append(StringUtils.leftPad(e.getClass().getSimpleName(),25));
-			sb.append(" -- ");
-			sb.append(e.getMessage());
-			Throwable s =  e.getCause();
-			while(s != null){
-				sb.append("\n" );
-				sb.append(StringUtils.leftPad(s.getClass().getSimpleName(),25));
-				sb.append(" -- ");
-				sb.append(s.getMessage());
-				s = s.getCause();
-			}
-			sb.append(ANSI_RESET);
-			System.out.println(sb.toString());
 		}
-
 	}
 
 	/**
@@ -576,4 +557,31 @@ public class DMLScript
 	public static void setGlobalExecMode(ExecMode mode) {
 		EXEC_MODE = mode;
 	}
+
+	/**
+	 * Print the error in a user friendly manner.
+	 * 
+	 * @param e The exception thrown.
+	 */
+	public static void errorPrint(Exception e){
+		final String ANSI_RED = "\u001B[31m";
+		final String ANSI_RESET = "\u001B[0m";
+		StringBuilder sb = new StringBuilder();
+		sb.append(ANSI_RED + "\n");
+		sb.append("An Error Occured : ");
+		sb.append("\n" );
+		sb.append(StringUtils.leftPad(e.getClass().getSimpleName(),25));
+		sb.append(" -- ");
+		sb.append(e.getMessage());
+		Throwable s =  e.getCause();
+		while(s != null){
+			sb.append("\n" );
+			sb.append(StringUtils.leftPad(s.getClass().getSimpleName(),25));
+			sb.append(" -- ");
+			sb.append(s.getMessage());
+			s = s.getCause();
+		}
+		sb.append("\n" + ANSI_RESET);
+		System.out.println(sb.toString());
+	}
 }
diff --git a/src/test/java/org/apache/sysds/test/usertest/Base.java b/src/test/java/org/apache/sysds/test/usertest/Base.java
new file mode 100644
index 0000000..52e284d
--- /dev/null
+++ b/src/test/java/org/apache/sysds/test/usertest/Base.java
@@ -0,0 +1,106 @@
+/*
+ * 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.sysds.test.usertest;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.sysds.api.DMLScript;
+
+public class Base {
+    public final static String BASE_FOLDER = "src/test/scripts/usertest/";
+
+    /**
+     * Run the system in a different JVM
+     * 
+     * @param script a path to the script to execute.
+     * @return A pair of standard out and standard error.
+     */
+    public static Pair<String, String> runProcess(String script) {
+        String fullDMLScriptName = BASE_FOLDER + script;
+
+        String separator = System.getProperty("file.separator");
+        String classpath = System.getProperty("java.class.path");
+        String path = System.getProperty("java.home") + separator + "bin" + separator + "java";
+        ProcessBuilder processBuilder = new ProcessBuilder(path, "-cp", classpath, DMLScript.class.getName(), "-f",
+            fullDMLScriptName);
+
+        StringBuilder stdout = new StringBuilder();
+        StringBuilder stderr = new StringBuilder();
+        try {
+            Process process = processBuilder.start();
+
+            BufferedReader output = new BufferedReader(new InputStreamReader(process.getInputStream()));
+            BufferedReader error = new BufferedReader(new InputStreamReader(process.getErrorStream()));
+
+            Thread t = new Thread(() -> {
+                output.lines().forEach(s -> stdout.append("\n" + s));
+            });
+
+            Thread te = new Thread(() -> {
+                error.lines().forEach(s -> stderr.append("\n" + s));
+            });
+
+            t.start();
+            te.start();
+
+            process.waitFor();
+            t.join();
+            te.join();
+        }
+        catch(IOException | InterruptedException e) {
+            e.printStackTrace();
+        }
+        return new ImmutablePair<>(stdout.toString(), stderr.toString());
+    }
+
+    public static Pair<String, String> runThread(String script) {
+        String fullDMLScriptName = BASE_FOLDER + script;
+
+        Thread t = new Thread(() -> {
+            DMLScript.main(new String[] {"-f", fullDMLScriptName});
+        });
+        
+        ByteArrayOutputStream buff = new ByteArrayOutputStream();
+        ByteArrayOutputStream buffErr = new ByteArrayOutputStream();
+        PrintStream old = System.out;
+        PrintStream oldErr = System.err;
+        System.setOut(new PrintStream(buff));
+        System.setErr(new PrintStream(buffErr));
+        
+        t.start();
+        try {
+            t.join();
+        }
+        catch(InterruptedException e) {
+            e.printStackTrace();
+        }
+
+        System.setOut(old);
+        System.setErr(oldErr);
+        
+        return new ImmutablePair<>(buff.toString(), buffErr.toString());
+    }
+}
diff --git a/src/test/java/org/apache/sysds/test/usertest/UserInterfaceTest.java b/src/test/java/org/apache/sysds/test/usertest/UserInterfaceTest.java
new file mode 100644
index 0000000..67ebca2
--- /dev/null
+++ b/src/test/java/org/apache/sysds/test/usertest/UserInterfaceTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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.sysds.test.usertest;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.junit.Test;
+
+public class UserInterfaceTest extends Base {
+
+	@Test
+	public void testHelloWorld(){
+		Pair<String,String> res = runThread("helloWorld.dml");
+		assertEquals("", res.getRight());
+		assertTrue(res.getLeft().contains("Hello, World!"));
+	}
+
+	@Test
+	public void testStop(){
+		Pair<String,String> res = runThread("Stop.dml");
+		assertEquals("",res.getRight());
+		assertTrue(res.getLeft().contains("An Error Occured :"));
+		assertTrue(res.getLeft().contains("DMLScriptException -- Stop Message!"));
+	}
+
+	@Test
+	public void SyntaxError(){
+		Pair<String,String> res = runThread("SyntaxError.dml");
+		assertEquals("",res.getRight());
+		System.out.println(res.getLeft());
+		System.out.println(res.getRight());
+		assertTrue(res.getLeft().contains("An Error Occured :"));
+		assertTrue(res.getLeft().contains("[Syntax error]"));
+		assertTrue(res.getLeft().contains("ParseException --"));
+	}
+}
diff --git a/src/test/scripts/usertest/Stop.dml b/src/test/scripts/usertest/Stop.dml
new file mode 100644
index 0000000..6e080dd
--- /dev/null
+++ b/src/test/scripts/usertest/Stop.dml
@@ -0,0 +1,22 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+stop("Stop Message!")
diff --git a/src/test/scripts/usertest/SyntaxError.dml b/src/test/scripts/usertest/SyntaxError.dml
new file mode 100644
index 0000000..be860bb
--- /dev/null
+++ b/src/test/scripts/usertest/SyntaxError.dml
@@ -0,0 +1,22 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+stop("Stop Message!"))
diff --git a/src/test/scripts/usertest/helloWorld.dml b/src/test/scripts/usertest/helloWorld.dml
new file mode 100644
index 0000000..d68f4c8
--- /dev/null
+++ b/src/test/scripts/usertest/helloWorld.dml
@@ -0,0 +1,22 @@
+#-------------------------------------------------------------
+#
+# 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.
+#
+#-------------------------------------------------------------
+
+print("Hello, World!")