Ensure Bisect::Channel is able to send data successfully when UTF-8 encoding is set
Created by: mikejarema
This PR is the outcome of debugging an issue that arose when running rspec --bisect
on a Rails project.
My environment: Ubuntu 20.04 running under Windows WSL RSpec 3.10.1 Rails 5.2.4.4 Ruby 2.6.6
One of our specs fails sporadically so I tried using rspec --bisect
to find the source of the failure.
$ bundle exec rspec --seed 1638 --bisect
Bisect started using options: "--seed 1638"
Running suite to find failures...
Rspec would hang like this indefinitely. By inspecting ps aux | grep rspec
I confirmed that the forked spec runner did complete, but did not report back its results to the parent process.
The problem was in RSpec::Core::Bisect::Channel.
Namely, RSpec::Core::Bisect::Channel#send was silently failing in the forked process with the following error on @write_io.write
.
Encoding::UndefinedConversionError: "\xF8" from ASCII-8BIT to UTF-8
The results from the spec run (latest_run_results
) would contain a non-UTF-8 character after being sent through Marshal.dump.
Since I'm running these specs in the context of Rails, and Rails by default sets UTF-8 encoding, the IO::pipe itself was set to use UTF-8 encoding. Since the output of Marshal.dump contained binary characters, the @write_io
pipe couldn't accept the data.
My PR addresses this by proactively setting the encoding on the @write_io
pipe to use the same encoding as the data dumped by Marshal.dump
. I've added specs which reproduce, in isolation, the preconditions which caused the failure I saw and ensure that 1) the data is sent to @write_io
pipe successfully and 2) that the parent process receives it successfully.