From 1074c4fa0ae632faf0a1c9816544d6f3ea63c1b7 Mon Sep 17 00:00:00 2001 From: Thomas Walker Lynch Date: Wed, 18 Dec 2024 16:14:18 +0000 Subject: [PATCH] misc --- .../Mosaic_Dispatcher.java" | 251 ++++++++++-------- .../Mosaic_TestClasses_0.java" | 50 ---- release/Mosaic.jar | Bin 964684 -> 960692 bytes tester/idea/0 | 2 - tester/idea/Access_0 | 2 - tester/idea/IO | 2 - tester/idea/IsPrimitive | 2 - tester/idea/Logger | 2 - tester/idea/MockClass_0 | 2 - tester/idea/Test0 | 2 - tester/idea/Test_Access_0 | 2 - tester/idea/Test_IO | 2 - tester/idea/Test_IsPrimitive | 2 - tester/idea/Test_Logger | 2 - tester/idea/Test_MockClass_0 | 2 - tester/idea/Test_Testbench | 2 - tester/idea/Test_Util | 2 - tester/idea/Testbench | 2 - tester/idea/Util | 2 - tester/idea/smoke | 2 - "tester/javac\360\237\226\211/Access_0.java" | 94 ------- .../AllMethodsPublicProxy_0.java" | 2 +- .../javac\360\237\226\211/Dispatch_0.java" | 134 ++++++++++ .../javac\360\237\226\211/Dispatch_1.java" | 211 +++++++++++++++ .../javac\360\237\226\211/TestClasses_0.java" | 61 +++++ .../javac\360\237\226\211/TestClasses_1.java" | 10 +- tester/jdwp_server/.gitignore | 2 + tester/jdwp_server/Access_0 | 2 - tester/jdwp_server/IO | 2 - tester/jdwp_server/IsPrimitive | 2 - tester/jdwp_server/Logger | 2 - tester/jdwp_server/MockClass_0 | 2 - tester/jdwp_server/Testbench | 2 - tester/jdwp_server/Util | 2 - tester/jdwp_server/smoke | 2 - "tester/tool\360\237\226\211/list" | 4 +- "tester/tool\360\237\226\211/make" | 5 + "tester/tool\360\237\226\211/run" | 6 +- 38 files changed, 566 insertions(+), 314 deletions(-) delete mode 100644 "developer/javac\360\237\226\211/Mosaic_TestClasses_0.java" delete mode 100755 tester/idea/0 delete mode 100755 tester/idea/Access_0 delete mode 100755 tester/idea/IO delete mode 100755 tester/idea/IsPrimitive delete mode 100755 tester/idea/Logger delete mode 100755 tester/idea/MockClass_0 delete mode 100755 tester/idea/Test0 delete mode 100755 tester/idea/Test_Access_0 delete mode 100755 tester/idea/Test_IO delete mode 100755 tester/idea/Test_IsPrimitive delete mode 100755 tester/idea/Test_Logger delete mode 100755 tester/idea/Test_MockClass_0 delete mode 100755 tester/idea/Test_Testbench delete mode 100755 tester/idea/Test_Util delete mode 100755 tester/idea/Testbench delete mode 100755 tester/idea/Util delete mode 100755 tester/idea/smoke delete mode 100644 "tester/javac\360\237\226\211/Access_0.java" create mode 100644 "tester/javac\360\237\226\211/Dispatch_0.java" create mode 100644 "tester/javac\360\237\226\211/Dispatch_1.java" create mode 100644 "tester/javac\360\237\226\211/TestClasses_0.java" rename "developer/javac\360\237\226\211/Mosaic_TestClasses_1.java" => "tester/javac\360\237\226\211/TestClasses_1.java" (69%) create mode 100644 tester/jdwp_server/.gitignore delete mode 100755 tester/jdwp_server/Access_0 delete mode 100755 tester/jdwp_server/IO delete mode 100755 tester/jdwp_server/IsPrimitive delete mode 100755 tester/jdwp_server/Logger delete mode 100755 tester/jdwp_server/MockClass_0 delete mode 100755 tester/jdwp_server/Testbench delete mode 100755 tester/jdwp_server/Util delete mode 100755 tester/jdwp_server/smoke diff --git "a/developer/javac\360\237\226\211/Mosaic_Dispatcher.java" "b/developer/javac\360\237\226\211/Mosaic_Dispatcher.java" index e2b9a86..530b5b7 100644 --- "a/developer/javac\360\237\226\211/Mosaic_Dispatcher.java" +++ "b/developer/javac\360\237\226\211/Mosaic_Dispatcher.java" @@ -169,27 +169,29 @@ Dispatcher instance. */ class MethodSignature_To_Handle_Map{ - private Map map; - // test facilities + // Static test messaging // - private boolean test = false; - public void test_switch(boolean test){ - if(this.test && !test){ - test_print("test messages off"); - this.test = test; + private static boolean test = false; + public static void test_switch(boolean test){ + if (MethodSignature_To_Handle_Map.test && !test){ + test_print("MethodSignature_To_Handle_Map:: test messages off"); } - if( !this.test && test){ - this.test = test; - test_print("test messages on"); + if (!MethodSignature_To_Handle_Map.test && test){ + test_print("MethodSignature_To_Handle_Map:: test messages on"); } + MethodSignature_To_Handle_Map.test = test; } - private void test_print(String message){ - if(test){ - System.out.println("MethodSignature_To_Handle_Map::" + message); + private static void test_print(String message){ + if (test){ + System.out.println(message); } } + // instance data + // + private Map map; + // field access and strings // @@ -204,22 +206,29 @@ class MethodSignature_To_Handle_Map{ private void add_entry(MethodSignature key ,MethodHandle value){ test_print ( - "add_entry::" - + "(" - + key - + "," - +value + "(add_entry:: " + "(key " + key + ") " + "(value " + value + ")" + ")" ); map.put(key ,value); } public void add_class(Class class_metadata){ try{ + test_print("adding public methods"); add_methods_public(class_metadata); + + test_print("adding private methods"); add_methods_private(class_metadata); + + test_print("adding constructors"); add_constructors(class_metadata); + + /* + test_print("adding static methods"); + add_methods_static(class_metadata); + */ + }catch(Throwable t){ - System.out.println("MethodSignature_To_Handle_Map::add_class exception:"); + System.out.println("MethodSignature_To_Handle_Map::add_class exception: "); t.printStackTrace(); } } @@ -310,6 +319,35 @@ class MethodSignature_To_Handle_Map{ } } + public void add_methods_static(Class class_metadata) { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + + for (Method method : class_metadata.getDeclaredMethods()) { + try { + if (Modifier.isStatic(method.getModifiers())) { // Only static methods + Class[] parameter_type_list = method.getParameterTypes(); + MethodType method_type = MethodType.methodType(method.getReturnType(), parameter_type_list); + MethodHandle method_handle = lookup.findStatic(class_metadata, method.getName(), method_type); + + MethodSignature signature = new MethodSignature( + method.getReturnType(), + class_metadata.getName(), + method.getName(), + parameter_type_list + ); + + add_entry(signature, method_handle); + } + } catch (NoSuchMethodException e) { + System.err.println("Skipping static method: " + method); + e.printStackTrace(); + } catch (Throwable t) { + t.printStackTrace(); + } + } + } + + // methods for looking up handles // public MethodHandle lookup(MethodSignature s){ @@ -321,7 +359,7 @@ class MethodSignature_To_Handle_Map{ @Override public String toString(){ StringBuilder sb = new StringBuilder(); - sb.append("MethodSignature_To_Handle_Map: {").append(System.lineSeparator()); + sb.append("MethodSignature_To_Handle_Map:{").append(System.lineSeparator()); for (Map.Entry entry : map.entrySet()){ sb.append(" ") @@ -342,29 +380,32 @@ class MethodSignature_To_Handle_Map{ */ public class Mosaic_Dispatcher{ - private MethodSignature_To_Handle_Map map; - private Class target; - // test facilities + // Static test messaging // - private boolean test = false; - public void test_switch(boolean test){ - if(this.test && !test){ + private static boolean test = false; + public static void test_switch(boolean test){ + if (Mosaic_Dispatcher.test && !test){ test_print("Mosaic_Dispatcher:: test messages off"); - this.test = test; } - if(!this.test && test){ - this.test = test; + if (!Mosaic_Dispatcher.test && test){ test_print("Mosaic_Dispatcher:: test messages on"); - map.test_switch(true); + MethodSignature_To_Handle_Map.test_switch(true); } + Mosaic_Dispatcher.test = test; } - private void test_print(String message){ - if(test){ - System.out.println("Mosaic_Dispatcher::" + message); + private static void test_print(String message){ + if (test){ + System.out.println(message); } } + // instance data + // + private MethodSignature_To_Handle_Map map; + private Class target; + + // field access and strings // public Class get_target(){ @@ -385,19 +426,17 @@ public class Mosaic_Dispatcher{ // construct given the class metadata for the target class public Mosaic_Dispatcher(Class target){ this.map = new MethodSignature_To_Handle_Map(); - test_switch(true); this.target = target; - test_print("Mosaic_Dispatcher:: mapping class from metadata:" + to_string_target()); + test_print("Mosaic_Dispatcher:: mapping methods given class_metadata object: " + to_string_target()); this.map.add_class(target); } // Constructor accepting a fully qualified class name of the target class public Mosaic_Dispatcher(String fully_qualified_class_name) throws ClassNotFoundException{ this.map = new MethodSignature_To_Handle_Map(); - test_switch(true); try{ this.target = Class.forName(fully_qualified_class_name); - test_print("Mosaic_Dispatcher:: mapping class from name string:" + to_string_target()); + test_print("Mosaic_Dispatcher:: mapping methods from class specified by string:" + to_string_target()); this.map.add_class(target); }catch(ClassNotFoundException e){ throw new ClassNotFoundException("Class not found: " + fully_qualified_class_name ,e); @@ -409,6 +448,7 @@ public class Mosaic_Dispatcher{ // Factory method to create an instance (dispatch a constructor) public Object make(Object... arg_list){ + test_print("Call to Mosaic_Dispatcher::make"); return dispatch_1 ( null // there is no instance passed in when calling a constructor @@ -418,91 +458,64 @@ public class Mosaic_Dispatcher{ ); } - @SuppressWarnings("unchecked") + // dispatch static methods public T dispatch + ( + Class return_type + ,String method_name + ,Object... arg_list + ){ + test_print("Call to Mosaic_Dispatcher::dispatch for a static method."); + return dispatch_1 ( - Object instance - ,Class return_type - ,String method_name - ,Object... arg_list - ){ - if(instance == null || !target.isInstance(instance)){ - throw new IllegalArgumentException - ( - "Provided instance is not of target type: " - + target.getName() - + ", but received: " - + (instance == null ? "null" : instance.getClass().getName()) - ); - } - - Object result = dispatch_1( - instance - ,return_type - ,method_name - ,arg_list - ); - - // Handle primitive return types explicitly - if(return_type.isPrimitive()){ - if(return_type == boolean.class) return (T) (Boolean) result; - if(return_type == int.class) return (T) (Integer) result; - if(return_type == double.class) return (T) (Double) result; - if(return_type == float.class) return (T) (Float) result; - if(return_type == long.class) return (T) (Long) result; - if(return_type == short.class) return (T) (Short) result; - if(return_type == byte.class) return (T) (Byte) result; - if(return_type == char.class) return (T) (Character) result; - } - - // For non-primitives, cast normally - return return_type.cast(result); + null // No instance for static methods + ,return_type // Return type + ,method_name // Method name + ,arg_list // Argument list + ); } - - /* + // dispatch instance binded methods + @SuppressWarnings("unchecked") public T dispatch - ( - Object instance - ,Class return_type - ,String method_name - ,Object... arg_list - ){ - + ( + Object instance, + Class return_type, + String method_name, + Object... arg_list + ){ + test_print("Call to Mosaic_Dispatcher::dispatch for a method bound to an instance."); if(instance == null || !target.isInstance(instance)){ throw new IllegalArgumentException ( - "Provided instance is not of target type: " - + target.getName() - + ", but received: " + "Provided instance is not of target type: " + + target.getName() + + ", but received: " + (instance == null ? "null" : instance.getClass().getName()) ); } - - return return_type.cast(dispatch_1( - instance - ,return_type - ,method_name - ,arg_list - )); + return dispatch_1(instance, return_type, method_name, arg_list); } - */ - private Object dispatch_1( - Object instance - ,Class return_type - ,String method_name - ,Object... arg_list + private T dispatch_1( + Object instance, + Class return_type, + String method_name, + Object... arg_list ){ try{ + if(arg_list == null){ + arg_list = new Object[0]; // Treat null as an empty argument list + } + // Resolve method/constructor signature MethodSignature signature = new MethodSignature( - return_type - ,to_string_target() - ,method_name - ,arg_list + return_type, + to_string_target(), + method_name, + arg_list ); - test_print("dispatch_1:: signature is:" + signature.toString()); + test_print("dispatch_1:: signature key:" + signature.toString()); MethodHandle handle = map.lookup(signature); @@ -513,20 +526,38 @@ public class Mosaic_Dispatcher{ // Unwrap Mosaic_IsPrimitive arguments Object[] unwrapped_arg_list = new Object[arg_list.length]; for(int i = 0; i < arg_list.length; i++){ - if (arg_list[i] instanceof Mosaic_IsPrimitive){ + if(arg_list[i] instanceof Mosaic_IsPrimitive){ unwrapped_arg_list[i] = ((Mosaic_IsPrimitive) arg_list[i]).get_value(); - } else { + }else{ unwrapped_arg_list[i] = arg_list[i]; } } - // Handle constructor vs method + // Handle method invocation + Object result; if("".equals(method_name)){ - return handle.invokeWithArguments(unwrapped_arg_list); // Constructor: no binding needed + result = handle.invokeWithArguments(unwrapped_arg_list); // Constructor: no binding needed + }else if(instance == null){ + result = handle.invokeWithArguments(unwrapped_arg_list); // Static method }else{ - return handle.bindTo(instance).invokeWithArguments(unwrapped_arg_list); // Method: bind instance + result = handle.bindTo(instance).invokeWithArguments(unwrapped_arg_list); // Instance method } + // Handle primitive return types explicitly + if(return_type.isPrimitive()){ + if(return_type == boolean.class) return(T)(Boolean) result; + if(return_type == int.class) return(T)(Integer) result; + if(return_type == double.class) return(T)(Double) result; + if(return_type == float.class) return(T)(Float) result; + if(return_type == long.class) return(T)(Long) result; + if(return_type == short.class) return(T)(Short) result; + if(return_type == byte.class) return(T)(Byte) result; + if(return_type == char.class) return(T)(Character) result; + } + + // For non-primitives, cast normally + return return_type.cast(result); + }catch(Throwable t){ System.out.println("Mosaic_Dispatcher::dispatch exception:"); t.printStackTrace(); @@ -539,7 +570,7 @@ public class Mosaic_Dispatcher{ @Override public String toString(){ return - "Mosaic_Dispatcher {" + "Mosaic_Dispatcher{" + "target=" + to_string_target() + " ,map=" diff --git "a/developer/javac\360\237\226\211/Mosaic_TestClasses_0.java" "b/developer/javac\360\237\226\211/Mosaic_TestClasses_0.java" deleted file mode 100644 index 7c09e36..0000000 --- "a/developer/javac\360\237\226\211/Mosaic_TestClasses_0.java" +++ /dev/null @@ -1,50 +0,0 @@ -package com.ReasoningTechnology.Mosaic; - -/* - These are used for testing that Mosaic can be used for white box - testing. Mosaic tests for Mosaic itself access each of these as - part of regression. Users are welcome to also check accessing these - when debugging any access problems that might arise. -*/ - -// Public class with public and private methods -public class Mosaic_TestClasses_0 { - public boolean a_public_method_1() { - return true; - } - - private boolean a_private_method_2() { - return true; - } - - public class PublicClass { - public boolean a_public_method_3() { - return true; - } - - private boolean a_private_method_4() { - return true; - } - } - - private class PrivateClass { - public boolean a_public_method_5() { - return true; - } - - private boolean a_private_method_6() { - return true; - } - } -} - -// Default (package-private) class with public and private methods -class DefaultClass { - public boolean a_public_method_7() { - return true; - } - - private boolean a_private_method_8() { - return true; - } -} diff --git a/release/Mosaic.jar b/release/Mosaic.jar index d1937e2b077a799554c026732afd35408f3a782a..4acbf18f9065234356c55191c7d3910884404ba1 100644 GIT binary patch delta 11777 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 Ky%9gyNdFH#b&nSS delta 15054 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 private_class_metadata = Mosaic_Dispatch.resolve_class( + TestClasses_0.class ,"tester.TestClasses_0$APrivateClass_02" + ); + + // Create a dispatcher for the private class + Mosaic_Dispatcher nested_dispatcher = new Mosaic_Dispatcher(private_class_metadata); + + // Instance of the private class is created via the dispatcher + Object nested_instance = nested_dispatcher.make(); + + boolean result = nested_dispatcher.dispatch( + nested_instance + ,boolean.class + ,"a_public_method_5" + ); + + return result; + } + + + // Test public method in the nested private class + public static boolean test_privateClassPublicMethod_5(){ + + // Create a dispatcher for the nested public class + Mosaic_Dispatcher nested_dispatcher = new Mosaic_Dispatcher(TestClasses_0.APrivateClass_02.class); + + // Instance of the private class is created via the dispatcher + Object nested_instance = nested_dispatcher.make(); + boolean result = nested_dispatcher.dispatch( + nested_instance, // target instance + boolean.class, // return type + "a_public_method_5" // method name + ); + return result; + } + + // Test private method in the nested private class + public static boolean test_privateClassPrivateMethod_6(){ + Object nested_instance = dispatcher.make( + TestClasses_0.class, + "APrivateClass_02", + null + ); + boolean result = dispatcher.dispatch( + nested_instance, + boolean.class, + "a_private_method_6" + ); + return result; + } + + // Run method to execute all tests + public static boolean run(){ + try{ + boolean result = true; + + /* + System.out.println("\nRunning test: publicMethod_1"); + if (Boolean.TRUE.equals(test_publicMethod_1())){ + System.out.println("PASSED"); + } else{ + System.out.println("FAILED"); + result = false; + } + + System.out.println("\nRunning test: privateMethod_2"); + if (Boolean.TRUE.equals(test_privateMethod_2())){ + System.out.println("PASSED"); + } else{ + System.out.println("FAILED"); + result = false; + } + + System.out.println("\nRunning test: nestedPublicMethod_3"); + if (Boolean.TRUE.equals(test_nestedPublicMethod_3())){ + System.out.println("PASSED"); + } else{ + System.out.println("FAILED"); + result = false; + } + + System.out.println("\nRunning test: nestedPrivateMethod_4"); + if (Boolean.TRUE.equals(test_nestedPrivateMethod_4())){ + System.out.println("PASSED"); + } else{ + System.out.println("FAILED"); + result = false; + } + */ + + System.out.println("\nRunning test: privateClassPublicMethod_5"); + if (Boolean.TRUE.equals(test_privateClassPublicMethod_5())){ + System.out.println("PASSED"); + } else{ + System.out.println("FAILED"); + result = false; + } + + System.out.println("\nRunning test: privateClassPrivateMethod_6"); + if (Boolean.TRUE.equals(test_privateClassPrivateMethod_6())){ + System.out.println("PASSED"); + } else{ + System.out.println("FAILED"); + result = false; + } + + return result; + } catch (Exception e){ + System.out.println("Exception in Dispatch_1 test:"); + e.printStackTrace(); + return false; + } + } + + public static void main(String[] args){ + if (run()){ + System.exit(0); + } else{ + System.exit(1); + } + } +} diff --git "a/tester/javac\360\237\226\211/TestClasses_0.java" "b/tester/javac\360\237\226\211/TestClasses_0.java" new file mode 100644 index 0000000..edf975f --- /dev/null +++ "b/tester/javac\360\237\226\211/TestClasses_0.java" @@ -0,0 +1,61 @@ +package tester; + +/* + These are used for testing that Mosaic can be used for white box + testing. Mosaic tests for Mosaic itself access each of these as + part of regression. Users are welcome to also check accessing these + when debugging any access problems that might arise. +*/ + +// Public class with public and private methods +public class TestClasses_0{ + public boolean a_public_method_1(){ + return true; + } + + private boolean a_private_method_2(){ + return true; + } + + public class APublicClass_01{ + public boolean a_public_method_3(){ + return true; + } + + private boolean a_private_method_4(){ + return true; + } + } + + private class APrivateClass_02{ + public boolean a_public_method_5(){ + return true; + } + + private boolean a_private_method_6(){ + return true; + } + } + + /* + public static boolean a_public_static_method_7(){ + return true; + } + + private static boolean a_private_static_method_9(){ + return true; + } + */ + +} + +// Default (package-private) class with public and private methods +class DefaultTestClass{ + public boolean a_public_method_7(){ + return true; + } + + private boolean a_private_method_8(){ + return true; + } +} diff --git "a/developer/javac\360\237\226\211/Mosaic_TestClasses_1.java" "b/tester/javac\360\237\226\211/TestClasses_1.java" similarity index 69% rename from "developer/javac\360\237\226\211/Mosaic_TestClasses_1.java" rename to "tester/javac\360\237\226\211/TestClasses_1.java" index 7c3f2db..7c425ce 100644 --- "a/developer/javac\360\237\226\211/Mosaic_TestClasses_1.java" +++ "b/tester/javac\360\237\226\211/TestClasses_1.java" @@ -1,4 +1,4 @@ -package com.ReasoningTechnology.Mosaic; +package tester; /* These are used for testing that Mosaic can be used for white box @@ -8,19 +8,19 @@ package com.ReasoningTechnology.Mosaic; */ // Public class with public and private methods -public class Mosaic_TestClasses_1 { +public class TestClasses_1 { private int i; - public Mosaic_TestClasses_1(){ + public TestClasses_1(){ i = 0; } - public Mosaic_TestClasses_1(int a){ + public TestClasses_1(int a){ i = a; } - public Mosaic_TestClasses_1(int a ,int b){ + public TestClasses_1(int a ,int b){ i = a + b; } diff --git a/tester/jdwp_server/.gitignore b/tester/jdwp_server/.gitignore new file mode 100644 index 0000000..120f485 --- /dev/null +++ b/tester/jdwp_server/.gitignore @@ -0,0 +1,2 @@ +* +!/.gitignore diff --git a/tester/jdwp_server/Access_0 b/tester/jdwp_server/Access_0 deleted file mode 100755 index f25e6f8..0000000 --- a/tester/jdwp_server/Access_0 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/env bash -java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005 Access_0 diff --git a/tester/jdwp_server/IO b/tester/jdwp_server/IO deleted file mode 100755 index 235da3f..0000000 --- a/tester/jdwp_server/IO +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/env bash -java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005 IO diff --git a/tester/jdwp_server/IsPrimitive b/tester/jdwp_server/IsPrimitive deleted file mode 100755 index f835393..0000000 --- a/tester/jdwp_server/IsPrimitive +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/env bash -java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005 IsPrimitive diff --git a/tester/jdwp_server/Logger b/tester/jdwp_server/Logger deleted file mode 100755 index f127e85..0000000 --- a/tester/jdwp_server/Logger +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/env bash -java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005 Logger diff --git a/tester/jdwp_server/MockClass_0 b/tester/jdwp_server/MockClass_0 deleted file mode 100755 index b047e64..0000000 --- a/tester/jdwp_server/MockClass_0 +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/env bash -java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005 MockClass_0 diff --git a/tester/jdwp_server/Testbench b/tester/jdwp_server/Testbench deleted file mode 100755 index e1fed4e..0000000 --- a/tester/jdwp_server/Testbench +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/env bash -java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005 Testbench diff --git a/tester/jdwp_server/Util b/tester/jdwp_server/Util deleted file mode 100755 index bc24d32..0000000 --- a/tester/jdwp_server/Util +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/env bash -java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005 Util diff --git a/tester/jdwp_server/smoke b/tester/jdwp_server/smoke deleted file mode 100755 index c7aa8e4..0000000 --- a/tester/jdwp_server/smoke +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/env bash -java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005 smoke diff --git "a/tester/tool\360\237\226\211/list" "b/tester/tool\360\237\226\211/list" index b5bef5c..9e538ca 100755 --- "a/tester/tool\360\237\226\211/list" +++ "b/tester/tool\360\237\226\211/list" @@ -20,5 +20,7 @@ echo\ Testbench\ MockClass_0\ IsPrimitive\ - Access_0\ + Dispatch_0\ "" + +# Dispatch_1\ diff --git "a/tester/tool\360\237\226\211/make" "b/tester/tool\360\237\226\211/make" index 947d919..1d2f173 100755 --- "a/tester/tool\360\237\226\211/make" +++ "b/tester/tool\360\237\226\211/make" @@ -15,6 +15,11 @@ echo "Compiling files..." set -x cd $REPO_HOME/tester +# setup a couple of test classes + +javac -g -d scratchpad javac🖉/TestClasses* + + # Get the list of tests to compile # wrapper is a space-separated list list=$(list) diff --git "a/tester/tool\360\237\226\211/run" "b/tester/tool\360\237\226\211/run" index da69708..a3bcf3a 100755 --- "a/tester/tool\360\237\226\211/run" +++ "b/tester/tool\360\237\226\211/run" @@ -10,11 +10,11 @@ fi cd "$REPO_HOME/tester/jvm" || exit # Get the list of test scripts in the specific order from bash_wrapper_list -test_list=$(test_list) -echo test_list: $test_list +list=$(list) +echo list: $list # Execute each test in the specified order -for file in $test_list; do +for file in $list; do echo if [[ -x "$file" && ! -d "$file" ]]; then echo "... Running $file" -- 2.20.1