File: test_fork_safety.rb

package info (click to toggle)
ruby-dalli 5.0.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 992 kB
  • sloc: ruby: 9,447; sh: 19; makefile: 4
file content (60 lines) | stat: -rw-r--r-- 1,889 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# frozen_string_literal: true

require_relative '../helper'

describe 'Fork safety' do
  # Skip tests if fork is not supported (e.g., JRuby)
  next unless Process.respond_to?(:fork)

  MemcachedManager.supported_protocols.each do |protocol|
    describe "using the #{protocol} protocol" do
      it 'automatically reconnects after fork' do
        memcached_persistent(protocol) do |dc, _port|
          # Set a value before forking
          dc.set('fork_test_key', 'parent_value')

          assert_equal 'parent_value', dc.get('fork_test_key')

          # Fork a child process
          read_pipe, write_pipe = IO.pipe
          pid = fork do
            read_pipe.close

            # In the child process, we should detect the fork and reconnect
            begin
              # Simple test - set a value after fork
              dc.set('child_key', 'child_value')
              value = dc.get('child_key')

              # Write success to the pipe
              write_pipe.write("success:#{value}")
            rescue StandardError => e
              # Write error to the pipe if reconnection fails
              write_pipe.write("error:#{e.class.name}:#{e.message}")
            ensure
              write_pipe.close
              exit!(0)
            end
          end

          # In the parent process
          write_pipe.close

          # Wait for child process to finish
          Process.wait(pid)

          # Read result from pipe
          result = read_pipe.read
          read_pipe.close

          # Verify the child successfully reconnected and performed operations
          assert_match(/^success:/, result, "Child process encountered an error: #{result}")
          assert_equal 'success:child_value', result

          # Parent should still be able to work
          assert_equal 'parent_value', dc.get('fork_test_key')
        end
      end
    end
  end
end