File: integration_helper.rb

package info (click to toggle)
ruby-sinatra 4.2.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,932 kB
  • sloc: ruby: 17,700; sh: 25; makefile: 8
file content (146 lines) | stat: -rw-r--r-- 3,330 bytes parent folder | download | duplicates (2)
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
require 'sinatra/base'
require 'rbconfig'
require 'open-uri'
require 'sinatra/runner'

module IntegrationHelper
  class BaseServer < Sinatra::Runner
    extend Enumerable
    attr_accessor :server, :port
    alias name server

    def self.all
      @all ||= []
    end

    def self.all_async
      @all_async ||= []
    end

    def self.each(&block)
      all.each(&block)
    end

    def self.run(server, port, async: false)
      new(server, port, async).run
    end

    def app_file
      File.expand_path('integration/app.rb', __dir__)
    end

    def environment
      "development"
    end

    def initialize(server, port, async)
      @installed, @pipe, @server, @port = nil, nil, server, port
      ENV['PUMA_MIN_THREADS'] = '1' if server == 'puma'
      if async
        Server.all_async << self
      else
        Server.all << self
      end
    end

    def run
      return unless installed?
      kill
      @log     = +""
      super
      at_exit { kill }
    end

    def installed?
      return @installed unless @installed.nil?
      s = server == 'HTTP' ? 'net/http/server' : server
      require s
      @installed = true
    rescue LoadError
      warn "#{server} is not installed, skipping integration tests"
      @installed = false
    end

    def command
      @command ||= begin
        cmd = ["APP_ENV=#{environment}", "exec"]
        if RbConfig.respond_to? :ruby
          cmd << RbConfig.ruby.inspect
        else
          file, dir = RbConfig::CONFIG.values_at('ruby_install_name', 'bindir')
          cmd << File.expand_path(file, dir).inspect
        end
        cmd << "-w" unless net_http_server?
        cmd << "-I" << File.expand_path('../lib', __dir__).inspect
        cmd << app_file.inspect << '-s' << server << '-o' << '127.0.0.1' << '-p' << port
        cmd << "-e" << environment.to_s << '2>&1'
        cmd.join " "
      end
    end

    def webrick?
      name.to_s == "webrick"
    end

    def puma?
      name.to_s == "puma"
    end

    def falcon?
      name.to_s == "falcon"
    end

    def trinidad?
      name.to_s == "trinidad"
    end

    def net_http_server?
      name.to_s == 'HTTP'
    end

    def warnings
      log.scan(%r[(?:\(eval|lib/sinatra).*warning:.*$])
    end

    def run_test(target, &block)
      retries ||= 3
      target.server = self
      run unless alive?
      target.instance_eval(&block)
    rescue Exception => error
      retries -= 1
      kill
      retries < 0 ? retry : raise(error)
    end
  end

  Server = BaseServer

  def it(message, &block)
    Server.each do |server|
      next unless server.installed?
      super("with #{server.name}: #{message}") { server.run_test(self, &block) }
    end
  end

  def self.extend_object(obj)
    super

    base_port = 5000 + Process.pid % 100
    servers = Sinatra::Base.server.dup

    # TruffleRuby doesn't support `Fiber.set_scheduler` yet
    unsupported_truffleruby = RUBY_ENGINE == "truffleruby" && !Fiber.respond_to?(:set_scheduler)
    # Ruby 2.7 uses falcon 0.42.3 which isn't working with rackup 2.2.0+
    too_old_ruby = RUBY_VERSION <= "3.0.0"

    if unsupported_truffleruby || too_old_ruby
      warn "skip falcon server"
      servers.delete('falcon')
    end

    servers.each_with_index do |server, index|
      Server.run(server, base_port+index)
    end
  end
end