Verified Commit af492b3f authored by Carlos Galindo's avatar Carlos Galindo
Browse files

improve test generation

parent 132316c8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <!-- JUnit 5 requires Surefire version 2.22.0 or higher -->
                    <version>2.22.0</version>
                    <version>3.0.0-M5</version>
                </plugin>
            </plugins>
        </pluginManagement>
+116 −46
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ import es.upv.mist.slicing.graphs.sdg.SDG;
import es.upv.mist.slicing.slicing.FileLineSlicingCriterion;
import es.upv.mist.slicing.slicing.Slice;
import es.upv.mist.slicing.slicing.SlicingCriterion;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@@ -18,10 +19,9 @@ import org.junit.jupiter.params.provider.MethodSource;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Supplier;

public class SlicerTest {
    static {
@@ -34,64 +34,134 @@ public class SlicerTest {

    private static final String TEST_PKG = "regression";
    private static final String DOT_JAVA = ".java";
    private static final String SDG_CRITERION = ".sdg.criterion";
    private static final String SDG_SLICE = ".sdg.sliced";

    public static Collection<Arguments> findFiles(File directory, String suffix) throws FileNotFoundException {
        Collection<Arguments> res = new LinkedList<>();
    public static void findFiles(File directory, String suffix, Consumer<File> consumer) {
        File[] files = directory.listFiles();
        if (files == null) return Collections.emptyList();
        if (files == null)
            return;
        for (File f : files) {
            if (f.isDirectory()) {
                res.addAll(findFiles(f, suffix));
            } else if (f.getName().endsWith(suffix)) {
                File slice = new File(f.getParent(), f.getName() + ".sdg.sliced");
                if (!slice.isFile() || !slice.canRead())
                    continue;
                int criterionLine;
                try (Scanner in = new Scanner(new File(f.getParent(), f.getName() + "sdg.criterion"))) {
                    criterionLine = in.nextInt();
                } catch (FileNotFoundException e) {
                    continue;
                }
                res.add(Arguments.of(f, slice, criterionLine));
            }
            if (f.isDirectory())
                findFiles(f, suffix, consumer);
            else if (f.getName().endsWith(suffix))
                consumer.accept(f);
        }
        return res;
    }

    public static Arguments[] findAllFiles() throws FileNotFoundException {
    public static Arguments[] findAllFiles() {
        Collection<Arguments> args = new LinkedList<>();
        File testFolder = new File(Thread.currentThread().getContextClassLoader().getResource(TEST_PKG).getPath());
        Collection<Arguments> args = findFiles(testFolder, DOT_JAVA);
        findFiles(testFolder, DOT_JAVA, f -> createArgumentForTest(f).ifPresent(args::add));
        return args.toArray(Arguments[]::new);
    }

    private static Optional<Arguments> createArgumentForTest(File javaFile) {
        File slice = new File(javaFile.getParent(), javaFile.getName() + SDG_SLICE);
        Optional<SlicingCriterion> criterion = findSDGCriterion(javaFile);
        if (!slice.isFile() || !slice.canRead() || criterion.isEmpty())
            return Optional.empty();
        return Optional.of(Arguments.of(javaFile, slice, criterion.get()));
    }

    @ParameterizedTest(name = "[{index}] {0}")
    @MethodSource("findAllFiles")
    public void sdgCompare(File source, File target, int criterionLine) throws FileNotFoundException {
        // Build the SDG
        SDG sdg = new ESSDG();
        sdg.build(new NodeList<>(StaticJavaParser.parse(source)));
        SlicingCriterion sc = new FileLineSlicingCriterion(source, criterionLine);
        Slice slice = sdg.slice(sc);
    public void slicerRegressionTest(File source, File target, SlicingCriterion sc) throws FileNotFoundException {
        if (!target.exists())
            return;
        Slice slice = slice(source ,sc);
        boolean equal = slicesMatch(slice, target);
        assert equal: "The slice for " + source.toString() + " has change, please fix the error or update the reference slice.";
    }

    @Test
    public void generateDefaultSlices() {
        File testFolder = new File("./sdg-core/src/test/res/", TEST_PKG);
        findFiles(testFolder, DOT_JAVA, SlicerTest::createAndSaveSlice);
    }

        // Convert the slice to code and output the result to `outputDir`
        NodeList<CompilationUnit> slicedUnits = slice.toAst();
        assert slicedUnits.size() == 1;
        if (!target.exists()) {
            try (PrintWriter pw = new PrintWriter(target)) {
                pw.print(slicedUnits.get(0).toString());
    private static Optional<SlicingCriterion> findSDGCriterion(File javaFile) {
        File criterionFile = new File(javaFile.getParentFile(), javaFile.getName() + SDG_CRITERION);
        try (Scanner in = new Scanner(criterionFile)) {
            return Optional.of(new FileLineSlicingCriterion(javaFile, in.nextInt()));
        } catch (FileNotFoundException | NoSuchElementException e) {
            return Optional.empty();
        }
    }

    private static void createAndSaveSlice(File javaFile) {
        try {
            File sliceFile = new File(javaFile.getParent(), javaFile.getName() + SDG_SLICE);
            Optional<SlicingCriterion> sc = findSDGCriterion(javaFile);
            if (sc.isEmpty() || sliceFile.exists())
                return;
            Slice slice = slice(javaFile, sc.get());
            var cus = slice.toAst();
            assert cus.size() == 1;
            try (PrintWriter pw = new PrintWriter(sliceFile)) {
                pw.write(cus.getFirst().get().toString());
            }
        } catch (FileNotFoundException e) {
            System.err.println("Could not save slice due to missing file or permissions");
        } catch (Exception e) {
            System.err.println("Error generating slice for " + javaFile.toString());
            System.err.println(e.getMessage());
            e.printStackTrace();
        }
    }
        String targetSlice;
        {

    private static boolean slicesMatch(Slice slice, File referenceSlice) {
        NodeList<CompilationUnit> cus = slice.toAst();
        assert cus.size() == 1;
        return Objects.equals(cus.getFirst().get().toString(), readFile(referenceSlice));
    }

    private static String readFile(File file, Supplier<String> separator) {
        try (Scanner in = new Scanner(file)) {
            StringBuilder builder = new StringBuilder();
            Scanner in = new Scanner(target);
            while (in.hasNextLine())
                builder.append(in.nextLine()).append('\n');
            targetSlice = builder.toString();
                builder.append(in.nextLine()).append(separator.get());
            return builder.toString();
        } catch (FileNotFoundException e) {
            return "";
        }
    }

    private static String readFile(File file) {
        return readFile(file, () -> "\n");
    }

    private static Slice slice(File javaFile, SlicingCriterion sc) throws FileNotFoundException {
        SDG sdg = new ESSDG();
        sdg.build(new NodeList<>(StaticJavaParser.parse(javaFile)));
        return sdg.slice(sc);
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        File testFolder = new File("./sdg-core/src/test/res/", TEST_PKG);
        findFiles(testFolder, DOT_JAVA, file -> {
           File sliceFile = new File(file.getParent(), file.getName() + SDG_CRITERION);
           if (!sliceFile.exists()) {
               int[] counter = new int[] { 1 };
               System.out.printf("%3d", counter[0]++);
               System.out.print(readFile(file, () -> String.format("\n%3d", counter[0]++)));
               System.out.printf("No criterion found for this program (%s), please input one (-1 to skip)\nCriterion: ", file);
               int line = in.nextInt();
               if (line == -1)
                   return;
               while (line <= 0 || line >= counter[0] - 2) {
                   System.out.printf("Your input is out-of-bounds, please try again [1-%d]: ", counter[0] - 2);
                   line = in.nextInt();
               }
               System.out.printf("Saving line %d as slicing criterion for %s... ", line, file);
               try (PrintWriter pw = new PrintWriter(sliceFile)) {
                   pw.write(line + "");
                   System.out.println("DONE");
               } catch (FileNotFoundException e) {
                   System.out.println("ERROR");
               }
           }
        String ourSlice = slicedUnits.get(0).toString();
        boolean equal = targetSlice.equals(ourSlice);
        assert equal;
        });
    }
}
+0 −8
Original line number Diff line number Diff line
public class Test {
    public static void main(String[] args) {
        switch (X) {
            case e1:

        }
    }
}
 No newline at end of file