Skip to content

Ensure Bisect::Channel is able to send data successfully when UTF-8 encoding is set

gitlab-qa-bot requested to merge github/fork/mikejarema/main into main

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.

Merge request reports