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

ArrayComparisonFailure serialization incompatibility fix: #1315

Merged
merged 2 commits into from
Jul 17, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions src/main/java/org/junit/internal/ArrayComparisonFailure.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ public class ArrayComparisonFailure extends AssertionError {

/*
* We have to use the f prefix until the next major release to ensure
* serialization compatibility.
* serialization compatibility.
* See https://github.com/junit-team/junit4/issues/976
*/
private final List<Integer> fIndices = new ArrayList<Integer>();
private final String fMessage;
private final AssertionError fCause;

/**
* Construct a new <code>ArrayComparisonFailure</code> with an error text and the array's
Expand All @@ -32,14 +33,20 @@ public class ArrayComparisonFailure extends AssertionError {
*/
public ArrayComparisonFailure(String message, AssertionError cause, int index) {
this.fMessage = message;
initCause(cause);
this.fCause = cause;
initCause(fCause);
addDimension(index);
}

public void addDimension(int index) {
fIndices.add(0, index);
}

@Override
public synchronized Throwable getCause() {
return super.getCause() == null ? fCause : super.getCause();
}

@Override
public String getMessage() {
StringBuilder sb = new StringBuilder();
Expand Down
3 changes: 2 additions & 1 deletion src/test/java/org/junit/internal/AllInternalTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
FailOnTimeoutTest.class,
MethodSorterTest.class,
StacktracePrintingMatcherTest.class,
ThrowableCauseMatcherTest.class
ThrowableCauseMatcherTest.class,
ArrayComparisonFailureTest.class
})
public class AllInternalTests {
}
68 changes: 68 additions & 0 deletions src/test/java/org/junit/internal/ArrayComparisonFailureTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package org.junit.internal;

import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

public class ArrayComparisonFailureTest {

private static final String ARRAY_COMPARISON_FAILURE_411 = "arrayComparisonFailure_411";
private static final String ARRAY_COMPARISON_FAILURE_412 = "arrayComparisonFailure_412";

/*
Test compatibility of older versions of ArrayComparisonFailure
Setup:
- checkout prior versions of the codebase (r4.11, r4.12 in this case)
- catch the exception resulting from:
assertArrayEquals(new int[]{0, 1}, new int[]{0, 5});
- serialize the resulting exception to a file, moving into the test/resources path
Ex., for v4.11's resulting exception {@link org/junit/internal/arrayComparisonFailure_411}
Current unit test:
- deserialize the above files casting it to the current version of the class
(catches any forward incompatibility with missing fields)
- assert the results from existing methods: getCause(), toString() -> getMessage()
(catches incompatible usages of fields)

This does not test if an instance of the current version of the class is able to deserialize to a previous ver.
*/

@Test
public void classShouldAccept411Version() throws Exception {
assertFailureSerializableFromOthers(ARRAY_COMPARISON_FAILURE_411);
}

@Test
public void classShouldAccept412Version() throws Exception {
assertFailureSerializableFromOthers(ARRAY_COMPARISON_FAILURE_412);
}

private void assertFailureSerializableFromOthers(String failureFileName) throws IOException,
ClassNotFoundException {
try {
assertArrayEquals(new int[]{0, 1}, new int[]{0, 5});
fail();
} catch (ArrayComparisonFailure e) {
ArrayComparisonFailure arrayComparisonFailureFromFile = deserializeFailureFromFile(failureFileName);
assertNotNull("ArrayComparisonFailure.getCause() should fallback to the deprecated fCause field"
+ " for compatibility with older versions of junit4 that didn't use Throwable.initCause().",
arrayComparisonFailureFromFile.getCause());
assertEquals(e.getCause().toString(), arrayComparisonFailureFromFile.getCause().toString());
assertEquals(e.toString(), arrayComparisonFailureFromFile.toString());
}
}

private ArrayComparisonFailure deserializeFailureFromFile(String fileName) throws IOException,
ClassNotFoundException {
InputStream resource = getClass().getResourceAsStream(fileName);
ObjectInputStream objectInputStream = new ObjectInputStream(resource);
return (ArrayComparisonFailure) objectInputStream.readObject();
}

}
Binary file not shown.
Binary file not shown.