Open Alexander-- opened 6 years ago
Overriding printStackTrace
is an interesting idea, but I worry that would lead to a very confusing user-experience for any code that doesn't happen to enter that path. It'd also be good to implement such a change Truth-wide, rather than in the array classes alone.
In general I'm not sure how compelling the OOM case really is - it's always possible for an object's .toString()
to end up constructing a massive string, there's nothing special about arrays in this regard.
@dimo414 well, by the same logic, the possibility of OOM is always around the corner, so there is no need to care about memory usage, is there?
The real problem is the extent of issue: by concatenating array members into a two-byte Java string, the storage space for storing each element of byte[]
is multiplied x4 to x12 times. So an array, that took 512Mb of heap memory ends up producing a Throwable message of ~3Gb. That's nothing to sneer at, especially on Android.
OOM is not even the biggest concern. It is really about readability: by placing a huge blob in front of error message you are obfuscating the actually useful information. Because Truth currently puts the array contents before the diff, I wasn't even aware, that change №4 has already been implemented since 0.32 release, — all my arrays are so long, that small difference report at the end of message was completely lost (IntelliJ truncated messages; console printout was too long to manually inspect all of it).
I do expect us to do (1) and (4), hopefully this quarter. Possibly we'll do (2), as well; I'm a little worried that it might be noisy for IterableSubject
, but of course you're only asking for it for the array subjects (though doing it only for arrays runs somewhat counter to (4), which would make IterableSubject
and the array subjects more similar -- I've never been sure how similar it makes sense to make them). It's also possible that we'll do something in between (2) and (4) that includes a count of the missing and unexpected elements, which implicitly mentions the difference in length. But a direct mention would be more useful in some cases....
RE: (3), I'm hoping that we'll eventually abbreviate messages better than we do now. That may help. Then again, in the course of doing all the bookkeeping needed, we might well use up a bunch of extra space.... But hopefully we can do at least a little better:
getMessage
(and override printStackTrace
to avoid calling getMessage
)@cpovirk
I'm a little worried that it might be noisy for IterableSubject, but of course you're only asking for it for the array subjects
Why do you think, that message like the one I provided would be noisy? In my opinion, it only makes developer's life easier by highlighting most important information first. If the array lengths do not differ, it might make sense to skip byte[99] and byte[99]
part and make it
Arrays differ at position 4 (5 more differences) *details about differences* [optional array contents]
hopefully we can do at least a little better:...
I don't think, that adding full array contents to Throwable message should be done at all for huge arrays. The main reason why I sometimes use huge arrays in tests is to test robustness of memory management or to enable discovery of issues, that can not be highlighted by existing test cases, when full-blown fuzzing solution is an overkill. As such, those arrays are either filled with zeroes or contain some randomly generated/meaningless data. It is rather inconvenient to visually compare two randomly generated byte arrays with >200 elements each.
When the contents of huge array are omitted, the resulting message can be made to look like this:
Arrays byte[5] and byte[1024] differ at position 4 *details about differences*; array contents: <1, -68, 110, 6, 0>, <array is too long, full contents are added to exception stack trace>
If omitting array contents may be undesirable (for compatibility reasons, or because a developer might not always have access to stack trace), that behavior can be made configurable via system property or environment variable.
The current code of
PrimitiveByteArraySubject
(as well as other primitive array subjects) has several major flaws:hasLength
. I believe, thatisEqualTo
on AbstractArraySubject should automatically perform that check;These are the changes I'd like to see:
printStackTrace
so that information is printed to stream (you can even keep the same format while doing so). This improvement might also be relevant for ListSubjectThe resulting error message woukd like like this: