Commit a4d7b25d authored by Sonia Zorba's avatar Sonia Zorba
Browse files

DAO testing: replaced Spring ScriptUtils with custom method

parent 70c8222b
Loading
Loading
Loading
Loading
+55 −12
Original line number Original line Diff line number Diff line
@@ -12,9 +12,12 @@ import java.io.File;
import java.io.IOException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.Connection;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.Pattern;
import javax.sql.DataSource;
import javax.sql.DataSource;
@@ -24,9 +27,7 @@ import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.Scope;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.init.ScriptUtils;


/**
/**
 * Generates a DataSource that can be used for testing DAO classes. It loads an
 * Generates a DataSource that can be used for testing DAO classes. It loads an
@@ -82,15 +83,59 @@ public class DataSourceConfig {
            assertTrue(scriptDir.exists(), "DAO tests require " + scriptDir.getAbsolutePath() + " to exists.\n"
            assertTrue(scriptDir.exists(), "DAO tests require " + scriptDir.getAbsolutePath() + " to exists.\n"
                    + "Please clone the repository from https://www.ict.inaf.it/gitlab/vospace/vospace-file-catalog.git");
                    + "Please clone the repository from https://www.ict.inaf.it/gitlab/vospace/vospace-file-catalog.git");


            File[] scripts = scriptDir.listFiles(f -> f.getName().endsWith(".sql"));
            // load all sql files in vospace-file-catalog repo
            Arrays.sort(scripts); // sort alphabetically
            File[] repoScripts = scriptDir.listFiles(f -> f.getName().endsWith(".sql"));
            Arrays.sort(repoScripts); // sort alphabetically

            // add test-data.sql
            List<File> scripts = new ArrayList<>(Arrays.asList(repoScripts));
            scripts.add(new ClassPathResource("test-data.sql").getFile());


            for (File script : scripts) {
            for (File script : scripts) {
                ByteArrayResource scriptResource = replaceDollarQuoting(script.toPath());
                String scriptContent = Files.readString(script.toPath());
                ScriptUtils.executeSqlScript(conn, scriptResource);
                for (String sql : splitScript(scriptContent)) {
                    executeSql(conn, replaceDollarQuoting(sql));
                }
            }
        }
    }

    /**
     * Spring ScriptUtils is not able to correctly split the SQL statements if a
     * function definition contains semicolon characters, so this method is used
     * instead of it.
     */
    private List<String> splitScript(String script) {

        List<String> parts = new ArrayList<>();

        StringBuilder sb = new StringBuilder();

        boolean insideFunc = false;
        for (int i = 0; i < script.length(); i++) {
            char c = script.charAt(i);
            sb.append(c);

            if (insideFunc) {
                if (i > 6 && "$func$".equals(script.substring(i - 6, i))) {
                    insideFunc = false;
                }
            } else {
                if (i > 6 && "$func$".equals(script.substring(i - 6, i))) {
                    insideFunc = true;
                } else if (c == ';') {
                    parts.add(sb.toString());
                    sb = new StringBuilder();
                }
            }
        }

        return parts;
    }
    }


            ScriptUtils.executeSqlScript(conn, new ClassPathResource("test-data.sql"));
    private void executeSql(Connection conn, String sqlStatement) throws SQLException {
        try ( Statement stat = conn.createStatement()) {
            stat.execute(sqlStatement);
        }
        }
    }
    }


@@ -100,9 +145,7 @@ public class DataSourceConfig {
     * instead of inside the original files because dollar quoting provides a
     * instead of inside the original files because dollar quoting provides a
     * better visibility.
     * better visibility.
     */
     */
    private ByteArrayResource replaceDollarQuoting(Path sqlScriptPath) throws Exception {
    private String replaceDollarQuoting(String scriptContent) {

        String scriptContent = Files.readString(sqlScriptPath);


        if (scriptContent.contains("$func$")) {
        if (scriptContent.contains("$func$")) {


@@ -114,7 +157,7 @@ public class DataSourceConfig {
            scriptContent = scriptContent.replace(originalFunction, newFunction);
            scriptContent = scriptContent.replace(originalFunction, newFunction);
        }
        }


        return new ByteArrayResource(scriptContent.getBytes());
        return scriptContent;
    }
    }


    private String extractFunctionDefinition(String scriptContent) {
    private String extractFunctionDefinition(String scriptContent) {