github.com/nycdavid/zeus@v0.0.0-20201208104106-9ba439429e03/rubygem/spec/zeus_spec.rb (about)

     1  require 'zeus'
     2  
     3  describe Zeus do
     4    class MyTestPlan < Zeus::Plan
     5      def self.mutex
     6        @mutex ||= Mutex.new
     7      end
     8  
     9      def self.boot
    10        require_relative 'assets/boot'
    11        Thread.new do
    12          mutex.synchronize do
    13            Zeus::LoadTracking.add_feature(File.join(__dir__, 'assets', 'boot_delayed.rb'))
    14          end
    15        end
    16      end
    17    end
    18  
    19    Zeus.plan = MyTestPlan
    20  
    21    before do
    22      MyTestPlan.mutex.lock
    23    end
    24  
    25    after do
    26      MyTestPlan.mutex.unlock if MyTestPlan.mutex.locked?
    27    end
    28  
    29    context 'booting' do
    30      before do
    31        # Don't reopen STDOUT
    32        Zeus.dummy_tty = true
    33      end
    34  
    35      it 'boots and tracks features' do
    36        master_r, master_w = UNIXSocket.pair(Socket::SOCK_STREAM)
    37        ENV['ZEUS_MASTER_FD'] = master_w.to_i.to_s
    38  
    39        thr = Thread.new do
    40          begin
    41            Zeus.go
    42          rescue Interrupt
    43            return
    44          rescue => e
    45            STDERR.puts "Zeus terminated with exception: #{e.message}"
    46            STDERR.puts e.backtrace.map {|line| " #{line}"}
    47          end
    48        end
    49  
    50        begin
    51          # Receive the control IO and start message
    52          ctrl_io = master_r.recv_io(UNIXSocket)
    53          begin
    54            # We use recv instead of readline on the UNIXSocket to avoid
    55            # converting it to a buffered reader. That seems to interact
    56            # badly with passing file descriptors around on Linux.
    57            proc_msg = "P:#{Process.pid}:0:boot\0"
    58            expect(ctrl_io.recv(proc_msg.length)).to eq(proc_msg)
    59  
    60            feature_io = ctrl_io.recv_io
    61  
    62            ready_msg = "R:OK\0"
    63            expect(ctrl_io.recv(ready_msg.length)).to eq(ready_msg)
    64            begin
    65              # We should receive the synchronously required feature immediately
    66              expect(feature_io.readline).to eq(File.join(__dir__, 'assets', 'boot.rb') + "\n")
    67  
    68              # We should receive the delayed feature after unlocking its mutex
    69              MyTestPlan.mutex.unlock
    70              expect(feature_io.readline).to eq(File.join(__dir__, 'assets', 'boot_delayed.rb') + "\n")
    71            ensure
    72              feature_io.close
    73            end
    74          ensure
    75            ctrl_io.close
    76          end
    77        ensure
    78          thr.raise(Interrupt.new)
    79        end
    80      end
    81  
    82      it 'tracks features after booting has completed' do
    83      end
    84    end
    85  end