Commit c4c00b25 authored by Carlos Galindo's avatar Carlos Galindo
Browse files

Merge branch 'ci-tests-on-merge' into 'develop'

Add CI tests on merge

See merge request !44
parents 55e88421 f293d418
Loading
Loading
Loading
Loading
Loading

.gitlab-ci.yml

0 → 100644
+55 −0
Original line number Diff line number Diff line
# This file is a template, and might need editing before it works on your project.
# Build JAVA applications using Apache Maven (http://maven.apache.org)
# For docker image tags see https://hub.docker.com/_/maven/
#
# For general lifecycle information see https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html

# This template will build and test your projects
# * Caches downloaded dependencies and plugins between invocation.
# * Verify but don't deploy merge requests.
# * Deploy built artifacts from master branch only.

variables:
  # This will suppress any download for dependencies and plugins or upload messages which would clutter the console log.
  # `showDateTime` will show the passed time in milliseconds. You need to specify `--batch-mode` to make this work.
  MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true"
  # As of Maven 3.3.0 instead of this you may define these options in `.mvn/maven.config` so the same config is used
  # when running from the command line.
  # `installAtEnd` and `deployAtEnd` are only effective with recent version of the corresponding plugins.
  MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true"

# This template uses jdk8 for verifying and deploying images
image: maven:3-jdk-11

# Cache downloaded dependencies and plugins between builds.
# To keep cache across branches add 'key: "$CI_JOB_NAME"'
cache:
  paths:
    - .m2/repository

# For merge requests do not `deploy` but only run `verify`.
# See https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
.verify: &verify
  stage: test
  script:
    - 'mvn $MAVEN_CLI_OPTS verify'
  except:
    - master

# Verify merge requests using JDK8
verify:jdk11:
  <<: *verify

# To deploy packages from CI, create a ci_settings.xml file
# For deploying packages to GitLab's Maven Repository: See https://docs.gitlab.com/ee/user/project/packages/maven_repository.html#creating-maven-packages-with-gitlab-cicd for more details.
# Please note: The GitLab Maven Repository is currently only available in GitLab Premium / Ultimate.
# For `master` branch run `mvn deploy` automatically.
deploy:jdk11:
  stage: deploy
  script:
    - if [ ! -f ci_settings.xml ];
        then echo "CI settings missing\! If deploying to GitLab Maven Repository, please see https://docs.gitlab.com/ee/user/project/packages/maven_repository.html#creating-maven-packages-with-gitlab-cicd for instructions.";
      fi
    - 'mvn $MAVEN_CLI_OPTS deploy -s ci_settings.xml'
  only:
    - master
+6 −0
Original line number Diff line number Diff line
@@ -21,6 +21,12 @@
                        <target>11</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <!-- JUnit 5 requires Surefire version 2.22.0 or higher -->
                    <version>3.0.0-M5</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
+13 −0
Original line number Diff line number Diff line
@@ -17,6 +17,19 @@
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <build>
        <testResources>
            <testResource>
                <directory>src/test/res</directory>
                <includes>
                    <include>**/*.java</include>
                    <include>**/*.java.*.criterion</include>
                    <include>**/*.java.*.sliced</include>
                </includes>
            </testResource>
        </testResources>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.github.javaparser</groupId>
+115 −42
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 {
@@ -32,63 +32,136 @@ public class SlicerTest {
        StaticJavaParser.getConfiguration().setAttributeComments(false);
    }

    private static final String TEST_FILES = "./sdg-core/src/test/res/dinsa-tests";
    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.getName().endsWith(suffix))
                res.add(Arguments.of(f, getSliceFile(f), getCriterionLine(f)));
            if (f.isDirectory())
                res.addAll(findFiles(f, suffix));
                findFiles(f, suffix, consumer);
            else if (f.getName().endsWith(suffix))
                consumer.accept(f);
        }
        return res;
    }

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

    private static File getSliceFile(File file) {
        return new File(file.getParent(), file.getName() + ".sdg.sliced");
    }

    private static int getCriterionLine(File file) throws FileNotFoundException {
        return new Scanner(new File(file.getParent(), file.getName() + ".sdg.criterion")).nextInt();
    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 changed, please fix the error or update the reference slice.";
    }

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

    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();
        }
    }

    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));
    }
        String targetSlice;
        {

    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;
        });
    }
}
+3 −1
Original line number Diff line number Diff line
import java.util.Scanner;

public class Classic {
    public static void main(String[] args) {
        int sum = 0;
@@ -18,7 +20,7 @@ public class Classic {
        int chars = 1;
        String subtext = "";
        int i = 0;
        while (i < text.size()) {
        while (i < text.length()) {
            char c = text.charAt(i);
            if (c == '\n') {
                lines += 1;
Loading