Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure code that accesses resources is efficient #1740

Merged
merged 15 commits into from
Nov 10, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ public final class Version extends BaseProductVersion {

static {
try (final BufferedReader reader =
new BufferedReader(
new ClasspathInputResource("/help/SchemaCrawler.txt").openNewInputReader(UTF_8))) {
new ClasspathInputResource("/help/SchemaCrawler.txt").openNewInputReader(UTF_8)) {

final List<String> lines = reader.lines().collect(toList());
lines.add("");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ public static IdentifiersBuilder builder() {
private static Collection<String> loadSql2003ReservedWords() {
final Set<String> reservedWords = new HashSet<>();
try (final BufferedReader reader =
new BufferedReader(
new ClasspathInputResource("/sql2003_reserved_words.txt").openNewInputReader(UTF_8))) {
new ClasspathInputResource("/sql2003_reserved_words.txt").openNewInputReader(UTF_8)) {
String line;
while ((line = reader.readLine()) != null) {
reservedWords.add(line);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import java.sql.Connection;
import java.util.Map;
import java.util.Properties;

import schemacrawler.crawl.SchemaCrawler;
import schemacrawler.schema.Catalog;
import schemacrawler.schemacrawler.LoadOptionsBuilder;
Expand All @@ -45,7 +44,6 @@
import us.fatehi.utility.PropertiesUtility;
import us.fatehi.utility.datasource.DatabaseConnectionSource;
import us.fatehi.utility.datasource.DatabaseConnectionSourceUtility;
import us.fatehi.utility.ioresource.ClasspathInputResource;

public final class DatabaseTestUtility {

Expand Down Expand Up @@ -75,15 +73,13 @@ public static Catalog getCatalog(

public static Map<String, String> loadHsqldbConfig() throws IOException {
final Properties properties =
TestUtility.loadProperties(
new ClasspathInputResource("/hsqldb.INFORMATION_SCHEMA.config.properties"));
TestUtility.loadPropertiesFromClasspath("/hsqldb.INFORMATION_SCHEMA.config.properties");
return PropertiesUtility.propertiesMap(properties);
}

public static Path tempHsqldbConfig() throws IOException {
final Properties properties =
TestUtility.loadProperties(
new ClasspathInputResource("/hsqldb.INFORMATION_SCHEMA.config.properties"));
TestUtility.loadPropertiesFromClasspath("/hsqldb.INFORMATION_SCHEMA.config.properties");
return TestUtility.savePropertiesToTempFile(properties);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public boolean matches(final Object actualValue) {
} else {
// Check file contents
final String outputFormatValue = getNonNullOutputFormatValue();
failures = compareOutput(referenceFile, file, outputFormatValue, false);
failures = compareOutput(referenceFile, file, outputFormatValue);
return failures != null && failures.isEmpty();
}
} catch (final Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,7 @@
import static java.nio.file.Files.deleteIfExists;
import static java.nio.file.Files.exists;
import static java.nio.file.Files.move;
import static java.nio.file.Files.newBufferedReader;
import static java.nio.file.Files.newBufferedWriter;
import static java.nio.file.Files.newInputStream;
import static java.nio.file.Files.newOutputStream;
import static java.nio.file.Files.size;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static java.nio.file.StandardOpenOption.CREATE;
Expand All @@ -58,24 +55,16 @@
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.Reader;
import java.io.Writer;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
Expand All @@ -89,7 +78,6 @@
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import java.util.zip.ZipInputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.commons.io.FileUtils;
Expand All @@ -100,13 +88,14 @@
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import static java.util.Objects.requireNonNull;
import static us.fatehi.utility.Utility.isBlank;
import schemacrawler.schemacrawler.InformationSchemaKey;
import schemacrawler.schemacrawler.InformationSchemaViews;
import schemacrawler.schemacrawler.InformationSchemaViewsBuilder;
import schemacrawler.schemacrawler.SchemaRetrievalOptions;
import schemacrawler.schemacrawler.SchemaRetrievalOptionsBuilder;
import us.fatehi.utility.IOUtility;
import us.fatehi.utility.ioresource.ClasspathInputResource;
import us.fatehi.utility.ioresource.FileInputResource;
import us.fatehi.utility.ioresource.InputResource;

public final class TestUtility {
Expand All @@ -116,24 +105,9 @@ public static void clean(final String dirname) throws Exception {
buildDirectory().resolve("unit_tests_results_output").resolve(dirname).toFile());
}

public static List<String> compareCompressedOutput(
final String referenceFile, final Path testOutputTempFile, final String outputFormat)
throws Exception {
return compareOutput(referenceFile, testOutputTempFile, outputFormat, true);
}

public static List<String> compareOutput(
final String referenceFile, final Path testOutputTempFile, final String outputFormat)
throws Exception {
return compareOutput(referenceFile, testOutputTempFile, outputFormat, false);
}

public static List<String> compareOutput(
final String referenceFile,
final Path testOutputTempFile,
final String outputFormat,
final boolean isCompressed)
throws Exception {

requireNonNull(referenceFile, "Reference file is not defined");
requireNonNull(testOutputTempFile, "Output file is not defined");
Expand All @@ -146,14 +120,15 @@ public static List<String> compareOutput(
final List<String> failures = new ArrayList<>();

final boolean contentEquals;
final Reader referenceReader = readerForResource(referenceFile, isCompressed);
final Reader referenceReader =
readerForInputResource(new ClasspathInputResource(referenceFile));
if (referenceReader == null) {
failures.add("Reference file not available, " + referenceFile);
contentEquals = false;
} else if ("png".equals(outputFormat)) {
contentEquals = true;
} else {
final Reader fileReader = readerForFile(testOutputTempFile, isCompressed);
final Reader fileReader = readerForInputResource(new FileInputResource(testOutputTempFile));
final Predicate<String> linesFilter = new SvgElementFilter().and(new NeuteredLinesFilter());
final Function<String, String> neuterMap = new NeuteredExpressionsFilter();
contentEquals = contentEquals(referenceReader, fileReader, failures, linesFilter, neuterMap);
Expand Down Expand Up @@ -189,14 +164,12 @@ public static List<String> compareOutput(
}

public static Path copyResourceToTempFile(final String resource) throws IOException {
if (isBlank(resource)) {
throw new IOException("Cannot read empty resource");
}
final InputResource inputResource = new ClasspathInputResource(resource);
final Path tempFile =
IOUtility.createTempFilePath("resource", "data").normalize().toAbsolutePath();
Files.copy(inputResource.openNewInputStream(), tempFile);

try (final InputStream resourceStream = TestUtility.class.getResourceAsStream(resource)) {
requireNonNull(resourceStream, "Resource not found, " + resource);
return writeToTempFile(resourceStream);
}
return tempFile;
}

public static ResultSet createMockResultSet(final String[] columnNames, final Object[][] data)
Expand Down Expand Up @@ -238,11 +211,6 @@ public static void deleteIfPossible(final Path testOutputTargetFilePath) {
}
}

public static <V> V failTestSetup(final String message) {
testAborted(message, null);
return null;
}

public static <V> V failTestSetup(final String message, final Exception e) {
testAborted(message, e);
return null;
Expand Down Expand Up @@ -285,16 +253,14 @@ public static String javaVersion() {
*
* @param inputResource Properties resource.
* @return Properties
* @throws IOException
*/
public static Properties loadProperties(final InputResource inputResource) {
requireNonNull(inputResource, "No input resource provided");

public static Properties loadPropertiesFromClasspath(final String resource) throws IOException {
final InputResource inputResource = new ClasspathInputResource(resource);
try (final Reader reader = inputResource.openNewInputReader(UTF_8); ) {
final Properties properties = new Properties();
properties.load(reader);
return properties;
} catch (final IOException e) {
return new Properties();
}
}

Expand Down Expand Up @@ -322,6 +288,11 @@ public static SchemaRetrievalOptions newSchemaRetrievalOptions() throws IOExcept
.toOptions();
}

public static String readFileFully(final Path filePath) throws IOException {
final byte[] bytes = Files.readAllBytes(filePath);
return new String(bytes, UTF_8);
}

public static Path savePropertiesToTempFile(final Properties properties) throws IOException {
requireNonNull(properties, "No properties provided");
final Path propertiesFile = Files.createTempFile("schemacrawler", ".properties");
Expand Down Expand Up @@ -424,26 +395,6 @@ private static StackTraceElement currentMethodStackTraceElement() {
return null;
}

private static void fastChannelCopy(final ReadableByteChannel src, final WritableByteChannel dest)
throws IOException {
final ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024);
while (src.read(buffer) != -1) {
// prepare the buffer to be drained
buffer.flip();
// write to the channel, may block
dest.write(buffer);
// If partial transfer, shift remainder down
// If buffer is empty, same as doing clear()
buffer.compact();
}
// EOF will leave buffer in fill state
buffer.flip();
// make sure the buffer is fully drained.
while (buffer.hasRemaining()) {
dest.write(buffer);
}
}

private static String lineMiscompare(final String expectedline, final String actualLine) {
final StringBuilder buffer = new StringBuilder();
buffer.append(">> expected followed by actual:").append("\n");
Expand All @@ -454,48 +405,12 @@ private static String lineMiscompare(final String expectedline, final String act
return lineMiscompare;
}

private static Reader openNewCompressedInputReader(
final InputStream inputStream, final Charset charset) throws IOException {
final ZipInputStream zipInputStream = new ZipInputStream(inputStream);
zipInputStream.getNextEntry();
return new InputStreamReader(zipInputStream, charset);
}

private static Reader readerForFile(final Path testOutputTempFile) throws IOException {
return readerForFile(testOutputTempFile, false);
}

private static Reader readerForFile(final Path testOutputTempFile, final boolean isCompressed)
throws IOException {

final BufferedReader bufferedReader;
if (isCompressed) {
final ZipInputStream inputStream =
new ZipInputStream(newInputStream(testOutputTempFile, StandardOpenOption.READ));
inputStream.getNextEntry();

bufferedReader = new BufferedReader(new InputStreamReader(inputStream, UTF_8));
} else {
bufferedReader = newBufferedReader(testOutputTempFile, UTF_8);
}
return bufferedReader;
}

private static Reader readerForResource(final String resource, final boolean isCompressed)
throws IOException {
final InputStream inputStream = TestUtility.class.getResourceAsStream("/" + resource);
final Reader reader;
if (inputStream != null) {
final Charset charset = UTF_8;
if (isCompressed) {
reader = openNewCompressedInputReader(inputStream, charset);
} else {
reader = new InputStreamReader(inputStream, charset);
}
} else {
reader = null;
private static Reader readerForInputResource(final InputResource inputResource) {
try {
return inputResource.openNewInputReader(UTF_8);
} catch (final IOException e) {
return null;
}
return reader;
}

private static void testAborted(final String message, final Exception e) {
Expand Down Expand Up @@ -526,19 +441,9 @@ public void warning(final SAXParseException e) throws SAXException {
failures.add(e.getMessage());
}
});
builder.parse(new InputSource(readerForFile(testOutputFile)));
}

private static Path writeToTempFile(final InputStream resourceStream) throws IOException {
final Path tempFile =
IOUtility.createTempFilePath("resource", "data").normalize().toAbsolutePath();

try (final OutputStream tempFileStream =
newOutputStream(tempFile, WRITE, TRUNCATE_EXISTING, CREATE)) {
fastChannelCopy(Channels.newChannel(resourceStream), Channels.newChannel(tempFileStream));
try (final Reader reader = new FileInputResource(testOutputFile).openNewInputReader(UTF_8); ) {
builder.parse(new InputSource(reader));
}

return tempFile;
}

private TestUtility() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
import schemacrawler.tools.commandline.utility.SchemaCrawlerOptionsConfig;
import schemacrawler.tools.options.Config;
import us.fatehi.utility.PropertiesUtility;
import us.fatehi.utility.ioresource.ClasspathInputResource;

public class SchemaCrawlerOptionsConfigTest {

Expand Down Expand Up @@ -121,8 +120,7 @@ public void nullBuilders() {

private Map<String, String> loadConfig(final String configResource) {
try {
final Properties properties =
TestUtility.loadProperties(new ClasspathInputResource(configResource));
final Properties properties = TestUtility.loadPropertiesFromClasspath(configResource);
return PropertiesUtility.propertiesMap(properties);
} catch (final IOException e) {
fail("Could not load " + configResource, e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,10 @@

package schemacrawler.tools.lint;

import static us.fatehi.utility.IOUtility.readFully;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import static us.fatehi.utility.IOUtility.readResourceFully;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import us.fatehi.utility.UtilityMarker;
import us.fatehi.utility.ioresource.ClasspathInputResource;
import us.fatehi.utility.ioresource.InputResource;
import us.fatehi.utility.string.StringFormat;

@UtilityMarker
public final class LintUtility {
Expand Down Expand Up @@ -65,16 +59,7 @@ private LintUtility() {}
*/
public static String readDescription(final String linterId) {
final String descriptionResource = String.format("/help/%s.txt", linterId);
try {
final InputResource inputResource = new ClasspathInputResource(descriptionResource);
final String descriptionText =
readFully(inputResource.openNewInputReader(StandardCharsets.UTF_8));
return descriptionText;
} catch (final IOException e) {
LOGGER.log(
Level.FINE,
new StringFormat("Could not find description resource for linter {0}, at {1}", linterId));
return "";
}
final String descriptionText = readResourceFully(descriptionResource);
return descriptionText;
}
}
Loading
Loading