-
-
Notifications
You must be signed in to change notification settings - Fork 753
Ensure Bisect::Channel is able to send data successfully when UTF-8 encoding is set #2852
Conversation
After applying this patch locally to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very interesting issue. Thanks for the report.
I tested locally your patch and it works as expected.
Can you rebase this please |
lib/rspec/core/bisect/utilities.rb
Outdated
@@ -32,8 +32,13 @@ def publish(event, *args) | |||
# parent process. | |||
# @private | |||
class Channel | |||
MARSHAL_DUMP_ENCODING = Marshal.dump("").encoding |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah so, of course, encoding
is not a method for 1.8.7, our usual work around would be to wrap it in a check, I'm about 80% certain 1.8.7s default encoding as just :ascii
and in fact IO might not even have set_encoding
which would mean you'd need to do a similar check there.
MARSHAL_DUMP_ENCODING = Marshal.dump("").encoding | |
if String.method_defined?(:encoding) | |
MARSHAL_DUMP_ENCODING = Marshal.dump("").encoding | |
else | |
MARSHAL_DUMP_ENCODING = :ascii | |
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, thanks for the suggestion. I've confirmed that IO#set_encoding
doesn't exist in 1.8.7, nor does the global Encoding
object.
I've adjusted the code and specs to skip unsupported method calls, relying on whatever encoding is implicit to 1.8.7.
Hopefully this gets the PR across the line. I had trouble building MRI 1.8.7 on my end for testing so I'm relying on CI to reveal any issues. I'll address them as necessary.
The legacy ruby issues seem to have been addressed, however a few of the CI environments are failing for odd reasons (timing-sensitivity or "Resource temporarily unavailable"). I can't determine whether they're related to this PR. |
b997774
to
58430ba
Compare
The last CI failure (jruby-9.1.17.0) seems unrelated to this PR. Any guidance?
|
My hot tip is to rebase when #2858 is merged 😂 |
Fix should be merged so if you rebase it should pass. |
…:Bisect::Channel can send and receive binary data (encoded by Marshal.dump)
All green, great! Thank you for the fix @JonRowe, and helping with my first RSpec contribution. @benoittgt thank you for reviewing. |
Thanks! |
Ensure Bisect::Channel is able to send data successfully when UTF-8 encoding is set
Ensure Bisect::Channel is able to send data successfully when UTF-8 encoding is set
Ensure Bisect::Channel is able to send data successfully when UTF-8 encoding is set --- This commit was imported from rspec/rspec-core@83eb95c.
This commit was imported from rspec/rspec-core@ecb65d2.
Ensure Bisect::Channel is able to send data successfully when UTF-8 encoding is set --- This commit was imported from rspec/rspec-core@0211a2c.
This commit was imported from rspec/rspec-core@d9976b1.
Ensure Bisect::Channel is able to send data successfully when UTF-8 encoding is set --- This commit was imported from rspec/rspec-core@f9d04bf.
This commit was imported from rspec/rspec-core@0e9f42c.
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.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
.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 byMarshal.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.