Skip to content
Browse files

fix: implemented precompilation/preloading of erlang modules for sing…

…le tests
  • Loading branch information...
1 parent 619d8f5 commit c43344bc12ea59a7d875d92bfdac87dce5e71b35 @pavlobaron committed
View
8 build.xml
@@ -127,17 +127,13 @@
<classpath>
<pathelement location="target/test-classes" />
<pathelement location="target/test-classes/generated/classes" />
- <path id="beam-compiled">
- <fileset dir="${user.home}/.erjang">
- <include name="*.jar"/>
- </fileset>
- </path>
</classpath>
<classpath refid="erjang.classpath" />
<assertions><enable /></assertions>
<jvmarg value="-Derjang.configfile=erjang_cfg.properties" />
<batchtest>
- <fileset dir="target/test-classes" includes="**/*_TEST.class" />
+ <!--<fileset dir="target/test-classes" includes="**/*_TEST.class" />-->
+ <fileset dir="target/test-classes" includes="**/sizes_tests_erl_TEST.class" />
</batchtest>
</junit>
</target>
View
29 src/main/java/erjang/OTPMain.java
@@ -48,14 +48,8 @@
new erjang.driver.js.EJSDriver()
};
- public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException {
-
- Handler fh = new FileHandler("erjang.log");
- Logger.getLogger("").addHandler(fh);
- // Logger.getLogger("erjang").setLevel(Level.FINE);
- // Logger.getLogger("kilim.Task").setLevel(Level.FINEST);
-
- for (String m : MODULES) {
+ public static void load_modules_and_drivers() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException {
+ for (String m : MODULES) {
ERT.load_module(EAtom.intern(m));
}
for (EDriver d : DRIVERS) {
@@ -64,20 +58,33 @@ public static void main(String[] args) throws ClassNotFoundException, Instantiat
for (EDriver d : extra_drivers) {
erjang.driver.Drivers.register(d);
}
+ }
- EAtom am_otp_ring0 = EAtom.intern("otp_ring0");
+ public static void start_otp_ring0(String[] args) {
+ EAtom am_otp_ring0 = EAtom.intern("otp_ring0");
EAtom am_start = EAtom.intern("start");
ESeq env = ERT.NIL;
ESeq argv = ERT.NIL;
-
+
for (int i = args.length-1; i >= 0; i--) {
argv = argv.cons(EBinary.fromString(args[i]));
}
-
+
EProc proc = new EProc(null, am_otp_ring0, am_start, ERT.NIL.cons(argv).cons(env));
ERT.run(proc);
proc.joinb();
+ }
+
+ public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException {
+
+ Handler fh = new FileHandler("erjang.log");
+ Logger.getLogger("").addHandler(fh);
+ // Logger.getLogger("erjang").setLevel(Level.FINE);
+ // Logger.getLogger("kilim.Task").setLevel(Level.FINEST);
+
+ load_modules_and_drivers();
+ start_otp_ring0(args);
System.out.println("done.");
}
View
22 src/main/java/erjang/driver/EExecDriverTask.java
@@ -116,16 +116,18 @@ public EExecDriverTask(EProc owner, ETuple2 name, EObject command, EObject portS
} else {
String cmd_path = env.get("PATH");
- for (String elm : cmd_path.split(File.pathSeparator)) {
- File dir = new File(elm);
- f = new File(dir, cmd[0]);
- if (f.exists()) {
- cmd[0] = f.getAbsolutePath();
- break;
- } else {
- f = null;
- }
- }
+ if (cmd_path != null) {
+ for (String elm : cmd_path.split(File.pathSeparator)) {
+ File dir = new File(elm);
+ f = new File(dir, cmd[0]);
+ if (f.exists()) {
+ cmd[0] = f.getAbsolutePath();
+ break;
+ } else {
+ f = null;
+ }
+ }
+ }
}
// System.err.println("lauching "+cmd[0]+" "+(f==null?"(not found)":""));
View
81 src/test/java/erjang/TestRunFile.java
@@ -23,28 +23,26 @@
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
+import java.util.*;
import erjang.beam.Compiler;
-import erjang.EObject;
-import erjang.EAtom;
-import erjang.EList;
-import erjang.ETuple;
-import erjang.EBinary;
import erjang.beam.DirClassRepo;
import erjang.beam.BeamLoader;
import erjang.beam.loader.ErjangBeamDisLoader;
import erjang.m.erlang.ErlConvert;
-import junit.framework.TestCase;
import junit.framework.TestResult;
import junit.framework.Assert;
import junit.framework.AssertionFailedError;
import kilim.ExitMsg;
import kilim.Mailbox;
+import erjang.OTPMain;
+
/**
- *
+ * @author <? who wrote the original version>
+ * @author Pavlo Baron <pb@pbit.org>
*/
public class TestRunFile extends AbstractErjangTestCase {
@@ -107,6 +105,17 @@ public int countTestCases() {
return 1;
}
+ static void find_files(List<File> otp, File dir) {
+ if (! dir.isDirectory()) throw new IllegalArgumentException("not a directory: " + dir);
+ for (File file : dir.listFiles()) {
+ if (file.isDirectory()) {
+ find_files(otp, file);
+ } else if (file.getName().endsWith(".beam")) {
+ otp.add(file);
+ }
+ }
+ }
+
/* (non-Javadoc)
* @see junit.framework.Test#run(junit.framework.TestResult)
*/
@@ -122,7 +131,51 @@ public void run(TestResult result) {
File beamFile = new File(BEAM_DIR,
trimExtension(file.getName())+".beam");
- if (! EModuleManager.module_loaded(ERLANG_ATOM)) load("erlang");
+ /*
+ * This is how this method previously tried to load the modules. It is absolutely not sufficient since
+ * only "erlang" module gets loaded in this case. We need all further modules which the test depends on.
+ * The problem is that these modules need to be preloaded. If we put the compiled beam modules on the
+ * classpath for the test, they get loaded, but in the wrong class loader - they have to be loaded using
+ * EModuleLoader -> EModuleClassLoader
+ *
+ * ORIGINAL CODE:
+ *
+ * if (! EModuleManager.module_loaded(ERLANG_ATOM)) load("erlang");
+ *
+ * :ORIGINAL CODE END
+ *
+ * The following implementation solves the problem by loading (with compilation if necessary) _all_ modules
+ * it finds. First of all, the main modules get loaded including drivers. Then, all the rest gets loaded.
+ * This code simulates what happens in otp_ring0:start/2 / init/boot/1.
+ *
+ * It should be considered to replace all this code by the usage of the ej-shell taking -s arguments. One
+ * reason for this is that init:boot only loads a subset of modules which are really necessary. By
+ * deleting the .erjang cache one can see which modules these are. This subset is _much_ smaller than what is
+ * getting loaded here. The MaxPermSizes necessary to run one single test is > 512m! (have it @ 1024m to
+ * be sure)
+ *
+ * This piece of code did just right but
+ * started the interactive shell (replace the placeholders with your local paths):
+ *
+ * String[] args = {"-root", "<ERL_ROOT>", "-home", "<USR_HOME>"};
+ * OTPMain.start_otp_ring0(args);
+ *
+ */
+
+ OTPMain.load_modules_and_drivers();
+
+ List<File> otp = new ArrayList<File>();
+ find_files(otp, new File(OTP_HOME));
+ for (File beam : otp) {
+ try {
+ EModuleLoader.load_module(trimExtension(beam.getName()), beam);
+ }
+ catch (Throwable e) {
+ //ignore and go on loading
+ }
+ }
+
+ //load run_wrapper
if (! EModuleManager.module_loaded(RUN_WRAPPER_ATOM)) load(wrapperBeamFile);
load(beamFile);
@@ -138,7 +191,14 @@ public void run(TestResult result) {
Assert.assertNotNull("process timed out?", exit);
EObject actual = (EObject) p.exit_reason;
+
+ /* FIXME:
+ * TODO:
+ * this code is unreachable in some cases - it seems that run_wrapper's throw leeds to an Exception here,
+ * so we have no chance to compare results
+ */
Assert.assertEquals(expected, actual);
+
} catch (AssertionFailedError e) {
result.addFailure(this, e);
} catch (Throwable e) {
@@ -167,6 +227,7 @@ private EObject erl_run(File file) throws Exception {
"-s", "erlang", "halt"};
byte[] bin = execGetBinaryOutput(cmd);
+
return ErlConvert.binary_to_term(new EBinary(bin));
}
@@ -197,7 +258,9 @@ private String execGetOutput(String[] cmd) throws Exception {
}
assert(exitCode == 0);
- return outThread.getResult();
+ //return outThread.getResult();
+
+ return Arrays.copyOf(outThread.getResult(), outThread.getResult().length);
}
static class OutputCollectorThread extends Thread {

0 comments on commit c43344b

Please sign in to comment.
Something went wrong with that request. Please try again.