ruby-concurrency / concurrent-ruby

Modern concurrency tools including agents, futures, promises, thread pools, supervisors, and more. Inspired by Erlang, Clojure, Scala, Go, Java, JavaScript, and classic concurrency patterns.
https://ruby-concurrency.github.io/concurrent-ruby/
Other
5.68k stars 418 forks source link

test failure due to "uninitialized constant Concurrent::CAtomicReference" #979

Closed Apteryks closed 1 year ago

Apteryks commented 1 year ago
* Operating system:                GNU/Linux (Guix System)
* Ruby implementation:             Ruby
* `concurrent-ruby` version:       1.1.10
* `concurrent-ruby-ext` installed: no
* `concurrent-ruby-edge` used:     yes

Hi, running the test suite of concurrent-ruby-edge using rake ci`, I get the following failure, which is reproducible on each re-run:

[...]

Failures:

  1) Concurrent::AtomicReference inherits from CAtomicReference
     Failure/Error: expect(described_class.ancestors).to include(Concurrent::CAtomicReference)

     NameError:
       uninitialized constant Concurrent::CAtomicReference
     # ./spec/concurrent/atomic/atomic_reference_spec.rb:192:in `block (2 levels) in <module:Concurrent>'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/example.rb:254:in `instance_exec'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/example.rb:254:in `block in run'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/example.rb:500:in `block in with_around_and_singleton_context_hooks'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/example.rb:457:in `block in with_around_example_hooks'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/hooks.rb:464:in `block in run'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/hooks.rb:602:in `run_around_example_hooks_for'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/hooks.rb:464:in `run'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/example.rb:457:in `with_around_example_hooks'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/example.rb:500:in `with_around_and_singleton_context_hooks'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/example.rb:251:in `run'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/example_group.rb:629:in `block in run_examples'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/example_group.rb:625:in `map'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/example_group.rb:625:in `run_examples'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/example_group.rb:591:in `run'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/runner.rb:116:in `block (3 levels) in run_specs'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/runner.rb:116:in `map'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/runner.rb:116:in `block (2 levels) in run_specs'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/configuration.rb:1989:in `with_suite_hooks'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/runner.rb:111:in `block in run_specs'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/reporter.rb:74:in `report'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/runner.rb:110:in `run_specs'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/runner.rb:87:in `run'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/runner.rb:71:in `run'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib/rspec/core/runner.rb:45:in `invoke'
     # /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/exe/rspec:4:in `<main>'

Finished in 3 minutes 3.6 seconds (files took 1.6 seconds to load)
2639 examples, 1 failure, 7 pending

Failed examples:

rspec ./spec/concurrent/atomic/atomic_reference_spec.rb:191 # Concurrent::AtomicReference inherits from CAtomicReference

/gnu/store/j4z07lyi1ykk8bc68h1p4bpj1il9dn3f-ruby-2.7.4/bin/ruby -I/gnu/store/kgbqsnj1ng2rannxpj5fkc8kxc2sxdma-ruby-rspec-support-3.8.0/lib/ruby/vendor_ruby/gems/rspec-support-3.8.0/lib:/gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/lib /gnu/store/aiw0xksjcx9krjmm66xx2ih30mi3z277-ruby-rspec-core-3.8.0/lib/ruby/vendor_ruby/gems/rspec-core-3.8.0/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb --color --backtrace --order defined --format documentation failed
error: in phase 'check': uncaught exception:
%exception #<&invoke-error program: "rake" arguments: ("ci") exit-status: 1 term-signal: #f stop-signal: #963 
phase `check' failed after 189.8 seconds
command "rake" "ci" failed with status 1

Ruby 2.7.4 is used in a clean environment with the following dependencies: `ruby-concurrent-ruby@1.1.10 ruby-rake-compiler-dock@1.2.2 ruby-rake-compiler@1.1.1

Thanks!

eregon commented 1 year ago

The error you see is either because the C extension was not compiled or could not be loaded.

rake ci is task :ci => [:compile, 'spec:ci']. So it should be compiled, and you should have a lib/concurrent-ruby/concurrent/concurrent_ruby_ext.so.

You can debug using RUBYOPT=-d or printing manually the error in try_load_c_extension.

eregon commented 1 year ago

As you can see the CI here doesn't have this problem, so it must be something specific to your environment.

eregon commented 1 year ago

Also this is expected if on purpose you don't use concurrent-ruby-ext: https://github.com/ruby-concurrency/concurrent-ruby#c-extensions-for-mri

But if you run bundle exec rake ci it should compile it for you anyway.

Apteryks commented 1 year ago

I confirm the test suite passes when the C extensions are installed. I often do not use bundle because it has a tendency to inflate the dependencies needed to build the package and run the test suite or sometimes outright fail in the containerized environment for some reason.

eregon commented 1 year ago

rake without bundle exec is pretty risky, it's likely it picks the wrong version of something and e.g. doesn't add the correct gems on $LOAD_PATH.

The test suite expects the C extension to be built and on $LOAD_PATH (via bundle exec, or in installed gems). That's good to ensure the C ext classes are used if the C ext is there.

Apteryks commented 1 year ago

GNU Guix builds things in a clean environment; it exposes only the dependencies specified for the package it builds in a Linux networkless namespace (container); so not using bundle in this context is not much risk.

eregon commented 1 year ago

so not using bundle in this context is not much risk.

Right, but it indeed misses some $LOAD_PATH entries for this case: https://github.com/ruby-concurrency/concurrent-ruby/blob/5406c1c81d54042e4f1877e85f9fb1d9b5ab5d8c/Gemfile#L10-L12