Shopify / android-testify

Add screenshots to your Android tests
https://testify.dev
MIT License
231 stars 23 forks source link

Fix Issue #228: Fix IndexOutOfBoundsException when processing uneven image buffer chunks #239

Closed DanielJette closed 3 years ago

DanielJette commented 3 years ago

What does this change accomplish?

Resolves #228 Resolves #215

How have you achieved it?

While adding additional unit tests, I uncovered additional ways to trigger an IndexOutOfBoundsException error.

The solution is to account for uneven processing chunk sizes.

As Testify processes, it divides the images into chunks for faster, parallel processing. A bug in the original code assumed that each processing chunk would be equally sized. This caused an out-of-bounds exception in any case where the number of pixels in the image could not be evenly divided.

In most cases, Testify will be used to capture a bitmap that is something like 1080x1920 (2,073,600 pixels) and will run on a 2 or 4-core CPU. In either case, this is evenly divisible and means that each processor core will be able to process an equal number of pixels.

However, in the case where the bitmap is not evenly divisible by the number of CPU cores, the remainder will be processed separately. For example, if you have a 3x3 bitmap (9 total pixels) running on a 2-core device, Testify will divide the image buffer into three parts: two 4-pixel chunks and one 1-pixel chunk. The bug in Testify was that it was assumed that each chunk was of equal size, and so an index-out-of-bounds error would occur when trying to process non-existent pixels in the final image buffer chunk.

The solution is to accurately use the correct size for each chunk via the new method, getSizeOfChunk(). The rest of this PR is additional testing and testing improvements.

Tophat instructions

It can be difficult to reproduce this error on a normal device setup.

The most straightforward way to reproduce this seems to be to create an emulator based off the recommended Testify settings found here but then edit the Advanced Settings and set the Multi-Core CPU setting to 7. This generates an emulator with unequally divisible pixel buffer sizes.

Once configured, run the tests found in the Sample application. You should find that the exclusions and generatedDiffs tests will fail on master and pass on this branch.