Skip to content
This repository has been archived by the owner on Jan 27, 2025. It is now read-only.

Commit

Permalink
Merge pull request #210 from metafacture/192-implementStrictMode
Browse files Browse the repository at this point in the history
Implement "strict" mode.
  • Loading branch information
blackwinter authored Mar 31, 2022
2 parents b491cbb + e167bbe commit dd514f7
Show file tree
Hide file tree
Showing 28 changed files with 375 additions and 54 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ package-lock.json
/metafix/src/test/resources/org/metafacture/metafix/integration/**/*.err
/metafix/src/test/resources/org/metafacture/metafix/integration/**/*.out
/metafix/src/test/resources/org/metafacture/metafix/integration/**/output-*
!/metafix/src/test/resources/org/metafacture/metafix/integration/**/expected.err
2 changes: 1 addition & 1 deletion metafix/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ dependencies {
implementation "org.metafacture:metamorph:${versions.metafacture}"

testImplementation "nl.jqno.equalsverifier:equalsverifier:${versions.equalsverifier}"
testImplementation "org.mockito:mockito-core:${versions.mockito}"
testImplementation "org.mockito:mockito-inline:${versions.mockito}"
testImplementation "org.mockito:mockito-junit-jupiter:${versions.mockito}"
}

Expand Down
96 changes: 61 additions & 35 deletions metafix/integrationTest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ todo_file=todo.txt

input_glob=input.*
expected_glob=expected.*
expected_errors_extension=err

metafix_output_glob=output-metafix.*
catmandu_output_glob=output-catmandu.*
Expand Down Expand Up @@ -102,6 +103,8 @@ function get_file() {
reason="Ambiguous $type files: $*"
elif [ ! -r "$1" ]; then
reason="No $type file: $1"
elif [ "$type" != "output" ] && [ ! -s "$1" ]; then
reason="Empty $type file: $1"
else
current_file=$1
return 0
Expand Down Expand Up @@ -138,6 +141,40 @@ function skip_test() {
fi
}

function test_passed() {
if [ -r "$2" ]; then
log "$color_test$1$color_reset: ${color_failed}FAILED$color_reset (Marked as \"to do\", but passed.)"

((failed++)) || true
else
if parse_boolean "$METAFIX_LOG_PASSED"; then
log "$color_test$1$color_reset: ${color_passed}PASSED$color_reset$3"
fi

((passed++)) || true
fi
}

function test_failed() {
if ! skip_test "$1" "$2"; then
log "$color_test$1$color_reset: $color_failed$4$color_reset$3"

if [ $# -ge 13 ]; then
log " Fix: $9"
log " Input: ${10}"
log " Expected: ${11}"
log " Output: ${12}"
log " Diff: ${13}"

[ -s "${13}" ] && $colordiff <"${13}" || rm -f "${13}"
fi

command_info "$5" "$6" "$7" "$8"

((failed++)) || true
fi
}

function run_tests() {
local test matched=1\
test_directory test_fix test_input test_expected test_todo\
Expand Down Expand Up @@ -165,62 +202,51 @@ function run_tests() {
test_todo="$test_directory/$todo_file"

if [ -z "$disable_todo" ] || ! skip_test "$test" "$test_todo"; then
# TODO: catmandu (optional)

metafix_command_output="$test_directory/metafix.out"
metafix_command_error="$test_directory/metafix.err"

metafix_start_time=$(current_time)

# TODO: catmandu (optional)
run_metafix "$test_directory/$metafix_file" >"$metafix_command_output" 2>"$metafix_command_error"
metafix_exit_status=$?

if run_metafix "$test_directory/$metafix_file" >"$metafix_command_output" 2>"$metafix_command_error"; then
metafix_exit_status=$?
metafix_elapsed_time=$(elapsed_time "$metafix_start_time")

if [ "$metafix_exit_status" -eq 0 ]; then
if get_file "$test" output "$test_directory"/$metafix_output_glob; then
metafix_output=$current_file
metafix_diff="$test_directory/metafix.diff"

metafix_elapsed_time=$(elapsed_time "$metafix_start_time")

if diff -u "$test_expected" "$metafix_output" >"$metafix_diff"; then
if [ -r "$test_todo" ]; then
log "$color_test$test$color_reset: ${color_failed}FAILED$color_reset (Marked as \"to do\", but passed.)"

((failed++)) || true
else
if parse_boolean "$METAFIX_LOG_PASSED"; then
log "$color_test$test$color_reset: ${color_passed}PASSED$color_reset$metafix_elapsed_time"
fi

((passed++)) || true
fi
test_passed "$test" "$test_todo" "$metafix_elapsed_time"

rm -f "$metafix_diff" "$metafix_command_output" "$metafix_command_error"
elif ! skip_test "$test" "$test_todo"; then
log "$color_test$test$color_reset: ${color_failed}FAILED$color_reset$metafix_elapsed_time"

log " Fix: $test_fix"
log " Input: $test_input"
log " Expected: $test_expected"
log " Output: $metafix_output"
log " Diff: $metafix_diff"

[ -s "$metafix_diff" ] && $colordiff <"$metafix_diff" || rm -f "$metafix_diff"

command_info metafix "$metafix_exit_status" "$metafix_command_output" "$metafix_command_error"

((failed++)) || true
else
test_failed "$test" "$test_todo" "$metafix_elapsed_time" FAILED\
metafix "$metafix_exit_status" "$metafix_command_output" "$metafix_command_error"\
"$test_fix" "$test_input" "$test_expected" "$metafix_output" "$metafix_diff"
fi
else
command_info metafix "$metafix_exit_status" "$metafix_command_output" "$metafix_command_error"
fi
elif ! skip_test "$test" "$test_todo"; then
metafix_exit_status=$?
elif [ "${test_expected##*.}" == "$expected_errors_extension" ]; then
get_file "$test" error "$metafix_command_error" || { log; continue; }

log "$color_test$test$color_reset: ${color_error}ERROR$color_reset"
while read -r pattern; do
if ! grep -qE "$pattern" "$metafix_command_error"; then
test_failed "$test" "$test_todo" " (Pattern not found: $pattern)" FAILED\
metafix "$metafix_exit_status" "$metafix_command_output" "$metafix_command_error"

command_info metafix "$metafix_exit_status" "$metafix_command_output" "$metafix_command_error"
continue 2
fi
done <"$test_expected"

((failed++)) || true
test_passed "$test" "$test_todo" "$metafix_elapsed_time"
else
test_failed "$test" "$test_todo" "$metafix_elapsed_time" ERROR\
metafix "$metafix_exit_status" "$metafix_command_output" "$metafix_command_error"
fi
fi
done
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@

import org.metafacture.framework.MetafactureException;

/**
* Indicates dynamic (i.e., data-dependent) issues during Fix execution that
* should be subject to {@link Metafix.Strictness strictness} handling.
*
* @see FixProcessException
*/
public class FixExecutionException extends MetafactureException {

public FixExecutionException(final String message) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2022 hbz NRW
*
* Licensed under the Apache License, Version 2.0 the "License";
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.metafacture.metafix;

import org.metafacture.framework.MetafactureException;

/**
* Indicates static (i.e., data-independent) issues with the usage of Fix
* expressions.
*
* @see FixExecutionException
*/
public class FixProcessException extends MetafactureException {

public FixProcessException(final String message) {
super(message);
}

public FixProcessException(final String message, final Throwable cause) {
super(message, cause);
}

}
58 changes: 58 additions & 0 deletions metafix/src/main/java/org/metafacture/metafix/Metafix.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;

/**
* Transforms a data stream sent via the {@link StreamReceiver} interface. Use
Expand All @@ -61,6 +62,8 @@ public class Metafix implements StreamPipe<StreamReceiver>, Maps { // checkstyle
public static final String VAR_END = "]";
public static final String VAR_START = "$[";

public static final Strictness DEFAULT_STRICTNESS = Strictness.PROCESS;

public static final Map<String, String> NO_VARS = Collections.emptyMap();

private static final Logger LOG = LoggerFactory.getLogger(Metafix.class);
Expand All @@ -79,6 +82,7 @@ public class Metafix implements StreamPipe<StreamReceiver>, Maps { // checkstyle
private List<Value> entities = new ArrayList<>();
private Record currentRecord = new Record();
private StreamReceiver outputStreamReceiver;
private Strictness strictness = DEFAULT_STRICTNESS;
private String fixFile;
private String recordIdentifier;
private int entityCount;
Expand Down Expand Up @@ -325,4 +329,58 @@ public String putValue(final String mapName, final String key, final String valu
return maps.computeIfAbsent(mapName, k -> new HashMap<>()).put(key, value);
}

public void setStrictness(final Strictness strictness) {
this.strictness = strictness != null ? strictness : DEFAULT_STRICTNESS;
}

public Strictness getStrictness() {
return strictness;
}

public enum Strictness {

/**
* Aborts process by throwing an exception.
*/
PROCESS {
@Override
protected void handleInternal(final FixExecutionException exception, final Record record) {
throw exception;
}
},

/**
* Ignores (skips) record and logs an error.
*/
RECORD {
@Override
protected void handleInternal(final FixExecutionException exception, final Record record) {
log(exception, LOG::error);
record.setReject(true); // TODO: Skip remaining expressions?
}
},

/**
* Ignores (skips) expression and logs a warning.
*/
EXPRESSION {
@Override
protected void handleInternal(final FixExecutionException exception, final Record record) {
log(exception, LOG::warn);
}
};

public void handle(final FixExecutionException exception, final Record record) {
LOG.debug("Current record: {}", record);
handleInternal(exception, record);
}

protected abstract void handleInternal(FixExecutionException exception, Record record);

protected void log(final FixExecutionException exception, final BiConsumer<String, Throwable> logger) {
logger.accept(exception.getMessage(), exception.getCause());
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ else if (e instanceof MethodCall) {
processFunction((MethodCall) e, params);
}
else {
throw new FixExecutionException(executionExceptionMessage(e));
throw new FixProcessException(executionExceptionMessage(e));
}
});
}
Expand Down Expand Up @@ -173,15 +173,26 @@ private void processExpression(final Expression expression, final Consumer<Strin
}

private void processFix(final Supplier<String> messageSupplier, final Runnable runnable) {
final FixExecutionException exception;

try {
runnable.run();
return;
}
catch (final FixExecutionException e) {
catch (final FixProcessException e) {
throw e; // TODO: Add nesting information?
}
catch (final FixExecutionException e) {
exception = e; // TODO: Add nesting information?
}
catch (final IllegalStateException | NumberFormatException e) {
exception = new FixExecutionException(messageSupplier.get(), e);
}
catch (final RuntimeException e) { // checkstyle-disable-line IllegalCatch
throw new FixExecutionException(messageSupplier.get(), e);
throw new FixProcessException(messageSupplier.get(), e);
}

metafix.getStrictness().handle(exception, record);
}

private String executionExceptionMessage(final Expression expression) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ public void shouldLookupInSeparateExternalFileMap() {
public void shouldNotLookupInRelativeExternalFileMapFromInlineScript() {
final String mapFile = "../maps/test.csv";

MetafixTestHelpers.assertThrowsCause(IllegalArgumentException.class, "Cannot resolve relative path: " + mapFile, () ->
MetafixTestHelpers.assertProcessException(IllegalArgumentException.class, "Cannot resolve relative path: " + mapFile, () ->
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
LOOKUP + " '" + mapFile + "')"
),
Expand Down Expand Up @@ -299,7 +299,7 @@ public void shouldNotLookupInUnknownInternalMap() {

@Test
public void shouldFailLookupInUnknownExternalMap() {
MetafixTestHelpers.assertThrowsCause(MorphExecutionException.class, "File not found: testMap.csv", () ->
MetafixTestHelpers.assertProcessException(MorphExecutionException.class, "File not found: testMap.csv", () ->
MetafixTestHelpers.assertFix(streamReceiver, Arrays.asList(
LOOKUP + " 'testMap.csv')"
),
Expand Down
Loading

0 comments on commit dd514f7

Please sign in to comment.