0

I'm instrumenting test code for a research project. We start with test cases such as

@Test
public void test025() throws Throwable {
    if (debug)
        System.out.format("%n%s%n", "RegressionTest1.test025");
    java.lang.Double[] d_array2 = new java.lang.Double[] { 1.0d, (-1.0d) };
    org.apache.commons.math.linear.ArrayRealVector arrayRealVector3 = new org.apache.commons.math.linear.ArrayRealVector(d_array2);
    org.apache.commons.math.linear.ArrayRealVector arrayRealVector4 = new org.apache.commons.math.linear.ArrayRealVector(d_array2);
    try {
        org.apache.commons.math.linear.ArrayRealVector arrayRealVector7 = new org.apache.commons.math.linear.ArrayRealVector(d_array2, (int) '4', (int) ' ');
        org.junit.Assert.fail("Expected exception of type org.apache.commons.math.exception.NumberIsTooLargeException");
    } catch (org.apache.commons.math.exception.NumberIsTooLargeException e) {
    }
    org.junit.Assert.assertNotNull(d_array2);
}

The assert statements are commented out of the .java files with:

original = original.replace("org.junit.Assert.", "//org.junit.Assert.");
original = original.replace("assert", "//assert");

Then, they are instrumented with javassist to log any exceptions (to be sure they happen in all runs of the test cases):

    for (CtMethod testmethod : methods) {
        if (testmethod.getName().startsWith("test")) {
            try {
                testmethod.insertBefore("semanticrt.statedump.dumpObjectState.setDumpTestCase(\""+testClassName+ "." + testmethod.getName()+"\");");
                CtClass etype = null;
                try {
                    etype = pool.get("java.lang.Exception");
                } catch (NotFoundException e) {
                    e.printStackTrace();
                }

                String exceptionCode = "{ semanticrt.statedump.dumpObjectState.dumpExceptionToFile($e, " +
                        "\"" + outputFileRoot + "."+ testmethod.getName() + ".exception\", false); throw $e; }\n";
                testmethod.addCatch(exceptionCode, etype);
            } catch (CannotCompileException e) {
                System.out.println(testmethod);
                e.printStackTrace();
            }

        }
    }

Which yields:

@Test
public void test025() throws Throwable {
    try {
        dumpObjectState.setDumpTestCase("RegressionTest1.test025");
        if(debug) {
            System.out.format("%n%s%n", new Object[]{"RegressionTest1.test025"});
        }

        Double[] var1 = new Double[]{Double.valueOf(1.0D), Double.valueOf(-1.0D)};
        new ArrayRealVector(var1);
        new ArrayRealVector(var1);

        try {
            new ArrayRealVector(var1, 52, 32);
        } catch (NumberIsTooLargeException var6) {
            ;
        }

    } catch (Exception var7) {
        dumpObjectState.dumpExceptionToFile(var7, "/home/loren/repos/d4jBugs/Math_45/version/XMLOut//out-RegressionTest1.test025.exception", false);
    }
}

My problem is the NumberIsTooLargeException is swallowed by the try/catch block left in the code. (Note: The Exception class could be any class, this is just an example of one problematic case.) So I need a way to get rid of any try/catch blocks in the generate test cases before I wrap them in mine.

Does anyone know how to do this with javassist or perhaps a good regular-expression that I could run on the .java file before instrumentation to remove them?

I'd like to end up with:

@Test
public void test025() throws Throwable {
    try {
        dumpObjectState.setDumpTestCase("RegressionTest1.test025");
        if(debug) {
            System.out.format("%n%s%n", new Object[]{"RegressionTest1.test025"});
        }

        Double[] var1 = new Double[]{Double.valueOf(1.0D), Double.valueOf(-1.0D)};
        new ArrayRealVector(var1);
        new ArrayRealVector(var1);

        new ArrayRealVector(var1, 52, 32);

    } catch (Exception var7) {
        dumpObjectState.dumpExceptionToFile(var7, "/home/loren/repos/d4jBugs/Math_45/version/XMLOut//out-RegressionTest1.test025.exception", false);
    }
}
Loren
  • 9,783
  • 4
  • 39
  • 49
  • 1
    Using `--no-regression-assertions` with Randoop should eliminate the need to remove the assertions. – vinegarbin Dec 14 '17 at 06:35
  • True, our script is also able to handle pre-written test cases in which case we'd need to comment them manually. Also, it's nice to test things by running the original tests with assertions to make sure the instrumentation works as expected. – Loren Dec 14 '17 at 13:23

1 Answers1

0

I found a solution which works. It doesn't remove the try/catch block, but it does add a throw to the beginning of the catch so it provides the needed functionality.

testmethod.instrument(
    new ExprEditor() {
        public void edit(Handler m)
                throws CannotCompileException
        {
            m.insertBefore("throw $1;");
        }
    }
);

Which makes the whole loop:

    for (CtMethod testmethod : methods) {
        if (testmethod.getName().startsWith("test")) {
            try {
                testmethod.instrument(
                    new ExprEditor() {
                        public void edit(Handler m)
                                throws CannotCompileException
                        {
                            m.insertBefore("throw $1;");
                        }
                    }
                );
                testmethod.insertBefore("semanticrt.statedump.dumpObjectState.setDumpTestCase(\""+testClassName+ "." + testmethod.getName()+"\");");
                CtClass etype = null;
                try {
                    etype = pool.get("java.lang.Exception");
                } catch (NotFoundException e) {
                    e.printStackTrace();
                }
                // See addCatch() https://jboss-javassist.github.io/javassist/tutorial/tutorial2.html
                String exceptionCode = "{ semanticrt.statedump.dumpObjectState.dumpExceptionToFile($e, " +
                        "\"" + outputFileRoot + "."+ testmethod.getName() + ".exception\", false); return; }\n";
                testmethod.addCatch(exceptionCode, etype);
            } catch (CannotCompileException e) {
                System.out.println(testmethod);
                e.printStackTrace();
            }
        }
    }
Loren
  • 9,783
  • 4
  • 39
  • 49