diff --git a/Gemfile b/Gemfile index b4eede485d3..fd91efb1071 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,6 @@ gem 'clockwork', require: false gem 'cloudfront-signer' gem 'concurrent-ruby' gem 'digest-xxhash' -gem 'eventmachine', '~> 1.2.7' gem 'fluent-logger' gem 'googleapis-common-protos', '>= 1.8.0' gem 'hashdiff' @@ -38,7 +37,6 @@ gem 'sinatra-contrib' gem 'statsd-ruby', '~> 1.5.0' gem 'steno' gem 'talentbox-delayed_job_sequel', '~> 4.3.0' -gem 'thin' gem 'uri', '~> 1.1' gem 'vmstat', '~> 2.3' diff --git a/Gemfile.lock b/Gemfile.lock index 89796d205ba..e31ae39ffe6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -129,7 +129,6 @@ GEM bigdecimal rexml crass (1.0.6) - daemons (1.4.1) date (3.5.0) debug (1.11.0) irb (~> 1.10) @@ -144,7 +143,6 @@ GEM drb (2.2.3) erb (5.1.3) erubi (1.13.1) - eventmachine (1.2.7) excon (1.3.0) logger faraday (0.17.6) @@ -568,11 +566,6 @@ GEM delayed_job (~> 4.1.0) sequel (>= 3.38, < 6.0) tzinfo - thin (2.0.1) - daemons (~> 1.0, >= 1.0.9) - eventmachine (~> 1.0, >= 1.0.4) - logger - rack (>= 1, < 4) thor (1.4.0) tilt (2.6.1) timecop (0.9.10) @@ -625,7 +618,6 @@ DEPENDENCIES concurrent-ruby debug (~> 1.11) digest-xxhash - eventmachine (~> 1.2.7) fluent-logger fog-aliyun fog-aws @@ -692,7 +684,6 @@ DEPENDENCIES statsd-ruby (~> 1.5.0) steno talentbox-delayed_job_sequel (~> 4.3.0) - thin timecop uri (~> 1.1) vmstat (~> 2.3) diff --git a/app/controllers/internal/metrics_controller.rb b/app/controllers/internal/metrics_controller.rb deleted file mode 100644 index 3d4aa75845e..00000000000 --- a/app/controllers/internal/metrics_controller.rb +++ /dev/null @@ -1,18 +0,0 @@ -require 'prometheus/client' -require 'prometheus/client/formats/text' - -module VCAP::CloudController - module Internal - # This controller is only used when the webserver is not Puma - # When using Puma, the metrics are served by a separate webserver in the main process - class MetricsController < RestController::BaseController - allow_unauthenticated_access - get '/internal/v4/metrics', :index - - def index - CloudController::DependencyLocator.instance.periodic_updater.update! unless VCAP::CloudController::Config.config.get(:webserver) == 'puma' - [200, Prometheus::Client::Formats::Text.marshal(Prometheus::Client.registry)] - end - end - end -end diff --git a/config/cloud_controller.yml b/config/cloud_controller.yml index 3fea034bc6a..a0549a3534d 100644 --- a/config/cloud_controller.yml +++ b/config/cloud_controller.yml @@ -395,7 +395,7 @@ locket: key_file: 'spec/fixtures/certs/bbs_client.key' threadpool_size: 20 -webserver: thin +webserver: puma default_app_lifecycle: buildpack custom_metric_tag_prefix_list: ["metric.tag.cloudfoundry.org"] diff --git a/lib/cloud_controller.rb b/lib/cloud_controller.rb index 4a3faffffd7..5875c33462a 100644 --- a/lib/cloud_controller.rb +++ b/lib/cloud_controller.rb @@ -1,6 +1,5 @@ require 'sinatra' require 'sequel' -require 'thin' require 'oj' require 'delayed_job' diff --git a/lib/cloud_controller/config_schemas/api_schema.rb b/lib/cloud_controller/config_schemas/api_schema.rb index ad399a1f19d..0cb25f7f5d3 100644 --- a/lib/cloud_controller/config_schemas/api_schema.rb +++ b/lib/cloud_controller/config_schemas/api_schema.rb @@ -318,7 +318,7 @@ class ApiSchema < VCAP::Config threadpool_size: Integer, skip_cert_verify: bool, - webserver: String, # thin or puma + webserver: String, # currently only puma optional(:puma) => { automatic_worker_count: bool, workers: Integer, diff --git a/lib/cloud_controller/metrics_webserver.rb b/lib/cloud_controller/metrics_webserver.rb index b2c4f4672b7..447f5d569ab 100644 --- a/lib/cloud_controller/metrics_webserver.rb +++ b/lib/cloud_controller/metrics_webserver.rb @@ -11,15 +11,19 @@ def initialize end def start(config) - server = Puma::Server.new(@app) + @server = Puma::Server.new(@app) if config.get(:nginx, :metrics_socket).nil? || config.get(:nginx, :metrics_socket).empty? - server.add_tcp_listener('127.0.0.1', 9395) + @server.add_tcp_listener('127.0.0.1', 9395) else - server.add_unix_listener(config.get(:nginx, :metrics_socket)) + @server.add_unix_listener(config.get(:nginx, :metrics_socket)) end - server.run + @server.run + end + + def stop + @server.stop(true) end private diff --git a/lib/cloud_controller/runner.rb b/lib/cloud_controller/runner.rb index 0adf9741ed1..001528fb466 100644 --- a/lib/cloud_controller/runner.rb +++ b/lib/cloud_controller/runner.rb @@ -11,7 +11,6 @@ require 'cloud_controller/logs/request_logs' require 'cloud_controller/telemetry_logger' require 'cloud_controller/secrets_fetcher' -require 'cloud_controller/runners/thin_runner' require 'cloud_controller/runners/puma_runner' require 'cloud_controller/metrics_webserver' require 'prometheus/client/data_stores/direct_file_store' @@ -33,7 +32,7 @@ def initialize(argv) # DB connection metrics have a label to determine whether the process accessing the connection is the # main or a worker process. We need to set this env variable before `setup_db` otherwise the main process - # will show up twice in the metrics as main and worker. Thin metrics will be labeled with main as well. + # will show up twice in the metrics as main and worker. ENV['PROCESS_TYPE'] = 'main' setup_cloud_controller @@ -45,11 +44,7 @@ def initialize(argv) builder = RackAppBuilder.new app = builder.build(@config, request_metrics, request_logs) - @server = if @config.get(:webserver) == 'puma' - VCAP::CloudController::PumaRunner.new(@config, app, logger, periodic_updater, request_logs) - else - VCAP::CloudController::ThinRunner.new(@config, app, logger, periodic_updater, request_logs) - end + @server = VCAP::CloudController::PumaRunner.new(@config, app, logger, periodic_updater, request_logs) end def logger diff --git a/lib/cloud_controller/runners/thin_runner.rb b/lib/cloud_controller/runners/thin_runner.rb deleted file mode 100644 index 1d00f620b64..00000000000 --- a/lib/cloud_controller/runners/thin_runner.rb +++ /dev/null @@ -1,73 +0,0 @@ -module VCAP::CloudController - class ThinRunner - attr_reader :logger - - def initialize(config, app, logger, periodic_updater, request_logs) - @config = config - @logger = logger - @thin_server = if @config.get(:nginx, :use_nginx) - Thin::Server.new(@config.get(:nginx, :instance_socket), signals: false) - else - Thin::Server.new(@config.get(:external_host), @config.get(:external_port), signals: false) - end - - @thin_server.app = app - - # The routers proxying to us handle killing inactive connections. - # Set an upper limit just to be safe. - @thin_server.timeout = @config.get(:request_timeout_in_seconds) - @thin_server.threaded = true - @thin_server.threadpool_size = @config.get(:threadpool_size) - @periodic_updater = periodic_updater - @request_logs = request_logs - end - - def start! - EM.run do - logger.info('starting periodic metrics updater') - @periodic_updater.setup_updates - trap_signals - logger.info("Starting thin server with #{EventMachine.threadpool_size} threads") - @thin_server.start! - rescue StandardError => e - logger.error "Encountered error: #{e}\n#{e.backtrace.join("\n")}" - raise e - end - end - - def stop! - logger.info('Stopping Thin Server.') - @thin_server.stop if @thin_server - logger.info('Stopping EventMachine') - EM.stop - @request_logs.log_incomplete_requests if @request_logs - end - - def trap_signals - %w[TERM INT QUIT].each do |signal| - trap(signal) do - EM.add_timer(0) do - logger.warn("Caught signal #{signal}") - stop! - end - end - end - - trap('USR1') do - EM.add_timer(0) do - logger.warn('Collecting diagnostics') - collect_diagnostics - end - end - end - - def collect_diagnostics - @diagnostics_dir ||= @config.get(:directories, :diagnostics) - - file = VCAP::CloudController::Diagnostics.new.collect(@diagnostics_dir) - logger.warn("Diagnostics written to #{file}") - rescue StandardError => e - logger.warn("Failed to capture diagnostics: #{e}") - end - end -end diff --git a/middleware/cors.rb b/middleware/cors.rb index f37bbed7348..ee3125f292d 100644 --- a/middleware/cors.rb +++ b/middleware/cors.rb @@ -33,7 +33,8 @@ def call(env) }) end - return [200, preflight_headers, ''] if env['REQUEST_METHOD'] == 'OPTIONS' + # NOTE: The response body must be an enumerable for Puma. Returning an empty string does not work. + return [200, preflight_headers, ['']] if env['REQUEST_METHOD'] == 'OPTIONS' status, headers, body = call_app(env) diff --git a/spec/request/internal/metrics_spec.rb b/spec/request/internal/metrics_spec.rb index fdc553094a8..62284d6b43d 100644 --- a/spec/request/internal/metrics_spec.rb +++ b/spec/request/internal/metrics_spec.rb @@ -3,22 +3,17 @@ RSpec.describe 'Metrics' do let(:user) { VCAP::CloudController::User.make } let(:user_header) { headers_for(user) } - let(:threadqueue) { double(EventMachine::Queue, size: 20, num_waiting: 0) } - let(:resultqueue) { double(EventMachine::Queue, size: 0, num_waiting: 1) } + let(:metrics_webserver) { VCAP::CloudController::MetricsWebserver.new } + + delegate :app, to: :metrics_webserver before do - allow(EventMachine).to receive(:connection_count).and_return(123) - - allow(EventMachine).to receive(:instance_variable_get) do |instance_var| - case instance_var - when :@threadqueue - threadqueue - when :@resultqueue - resultqueue - else - raise "Unexpected call: #{instance_var}" - end - end + allow_any_instance_of(VCAP::CloudController::Metrics::PeriodicUpdater).to receive(:update_webserver_stats) + metrics_webserver.start(TestConfig.config_instance) + end + + after do + metrics_webserver.stop end it 'can be called several times' do @@ -41,6 +36,7 @@ 10.times do VCAP::CloudController::User.make end + CloudController::DependencyLocator.instance.periodic_updater.update! end it 'reports the total number of users' do @@ -54,6 +50,7 @@ context 'cc_vitals' do it 'reports vitals' do + CloudController::DependencyLocator.instance.periodic_updater.update! get '/internal/v4/metrics', nil expect(last_response.body).to match(/cc_vitals_num_cores [1-9][0-9]*\.\d+/) @@ -69,6 +66,8 @@ before do Delayed::Job.enqueue(VCAP::CloudController::Jobs::Runtime::EventsCleanup.new(1), { queue: 'cc_api_0', run_at: Time.now + 1.day }) Delayed::Job.enqueue(VCAP::CloudController::Jobs::Runtime::EventsCleanup.new(1), { queue: 'cc_generic', run_at: Time.now + 1.day }) + + CloudController::DependencyLocator.instance.periodic_updater.update! end after do @@ -87,6 +86,8 @@ before do Delayed::Job.enqueue(VCAP::CloudController::Jobs::Runtime::EventsCleanup.new(1), { queue: 'cc_api_0', run_at: Time.now }) Delayed::Job.enqueue(VCAP::CloudController::Jobs::Runtime::EventsCleanup.new(1), { queue: 'cc_generic', run_at: Time.now }) + + CloudController::DependencyLocator.instance.periodic_updater.update! end after do @@ -105,6 +106,8 @@ before do Delayed::Job.enqueue(VCAP::CloudController::Jobs::Runtime::EventsCleanup.new(1), { queue: 'cc_api_0', run_at: Time.now + 1.minute }) Delayed::Job.enqueue(VCAP::CloudController::Jobs::Runtime::EventsCleanup.new(1), { queue: 'cc_generic', run_at: Time.now + 1.minute }) + + CloudController::DependencyLocator.instance.periodic_updater.update! end after do @@ -123,8 +126,9 @@ before do Delayed::Job.enqueue(VCAP::CloudController::Jobs::Runtime::EventsCleanup.new(1), { queue: 'cc_api_0', run_at: Time.now + 1.day }) Delayed::Job.enqueue(VCAP::CloudController::Jobs::Runtime::EventsCleanup.new(1), { queue: 'cc_generic', run_at: Time.now + 1.day }) - Delayed::Job.dataset.update(failed_at: Time.now.utc) + + CloudController::DependencyLocator.instance.periodic_updater.update! end after do diff --git a/spec/unit/controllers/internal/metric_controller_spec.rb b/spec/unit/controllers/internal/metric_controller_spec.rb deleted file mode 100644 index b31e4db1ddc..00000000000 --- a/spec/unit/controllers/internal/metric_controller_spec.rb +++ /dev/null @@ -1,34 +0,0 @@ -require 'spec_helper' - -module VCAP::CloudController - module Internal - RSpec.describe MetricsController do - let(:threadqueue) { double(EventMachine::Queue, size: 20, num_waiting: 0) } - let(:resultqueue) { double(EventMachine::Queue, size: 0, num_waiting: 1) } - - before do - allow(EventMachine).to receive(:connection_count).and_return(123) - - allow(EventMachine).to receive(:instance_variable_get) do |instance_var| - case instance_var - when :@threadqueue - threadqueue - when :@resultqueue - resultqueue - else - raise "Unexpected call: #{instance_var}" - end - end - end - - describe '#index' do - it 'returns a 200' do - get '/internal/v4/metrics' - - expect(last_response.status).to eq 200 - expect(last_response.body).to match(/cc_vitals_num_cores [1-9][0-9]*.\d+/) - end - end - end - end -end diff --git a/spec/unit/lib/background_job_environment_spec.rb b/spec/unit/lib/background_job_environment_spec.rb index 1f3950100de..4127de8560c 100644 --- a/spec/unit/lib/background_job_environment_spec.rb +++ b/spec/unit/lib/background_job_environment_spec.rb @@ -16,7 +16,6 @@ describe '#setup_environment' do before do allow(VCAP::CloudController::DB).to receive(:load_models) - allow(EM).to receive(:run).and_yield allow(VCAP::CloudController::ResourcePool).to receive(:new) end diff --git a/spec/unit/lib/cloud_controller/diagnostics_spec.rb b/spec/unit/lib/cloud_controller/diagnostics_spec.rb index 6aad33669fd..fdafad027d7 100644 --- a/spec/unit/lib/cloud_controller/diagnostics_spec.rb +++ b/spec/unit/lib/cloud_controller/diagnostics_spec.rb @@ -17,10 +17,6 @@ module VCAP::CloudController subject(:diagnostics) { Diagnostics.new } - before do - allow(EventMachine).to receive(:connection_count).and_return(17) - end - after do VCAP::Request.current_id = nil end diff --git a/spec/unit/lib/cloud_controller/diego/buildpack_entry_generator_spec.rb b/spec/unit/lib/cloud_controller/diego/buildpack_entry_generator_spec.rb index fa869e91e55..27861fe2645 100644 --- a/spec/unit/lib/cloud_controller/diego/buildpack_entry_generator_spec.rb +++ b/spec/unit/lib/cloud_controller/diego/buildpack_entry_generator_spec.rb @@ -27,9 +27,6 @@ module Diego before do allow(blobstore_url_generator).to receive_messages(app_package_download_url: app_package_download_url, admin_buildpack_download_url: admin_buildpack_download_url, buildpack_cache_download_url: build_artifacts_cache_download_uri) - - allow(EM).to receive(:add_timer) - allow(EM).to receive(:defer).and_yield end describe '#buildpack_entries' do diff --git a/spec/unit/lib/cloud_controller/metrics/periodic_updater_spec.rb b/spec/unit/lib/cloud_controller/metrics/periodic_updater_spec.rb index 53aaf4dd651..c90893c845d 100644 --- a/spec/unit/lib/cloud_controller/metrics/periodic_updater_spec.rb +++ b/spec/unit/lib/cloud_controller/metrics/periodic_updater_spec.rb @@ -70,6 +70,16 @@ module VCAP::CloudController::Metrics allow(prometheus_updater).to receive(:update_log_counts) allow(prometheus_updater).to receive(:update_task_stats) allow(prometheus_updater).to receive(:update_deploying_count) + + stats_hash = { + booted_workers: 2, + worker_status: [ + { started_at: '2023-11-29T13:15:05Z', index: 0, pid: 123, last_status: { running: 1, backlog: 0, busy_threads: 0, pool_capacity: 1, requests_count: 9 } }, + { started_at: '2023-11-29T13:15:10Z', index: 1, pid: 234, last_status: { running: 2, backlog: 1, busy_threads: 1, pool_capacity: 2, requests_count: 10 } } + ] + } + allow(Puma).to receive(:stats_hash).and_return(stats_hash) + allow(prometheus_updater).to receive(:update_webserver_stats_puma) end it 'bumps the number of users and sets periodic timer' do @@ -594,38 +604,24 @@ module VCAP::CloudController::Metrics allow(prometheus_updater).to receive(:update_webserver_stats_puma) end - context 'when Puma is configured as webserver' do - before do - TestConfig.override(webserver: 'puma') - end - - it 'sends stats to the prometheus updater' do - stats_hash = { - booted_workers: 2, - worker_status: [ - { started_at: '2023-11-29T13:15:05Z', index: 0, pid: 123, last_status: { running: 1, backlog: 0, busy_threads: 0, pool_capacity: 1, requests_count: 9 } }, - { started_at: '2023-11-29T13:15:10Z', index: 1, pid: 234, last_status: { running: 2, backlog: 1, busy_threads: 1, pool_capacity: 2, requests_count: 10 } } - ] - } - allow(Puma).to receive(:stats_hash).and_return(stats_hash) - - periodic_updater.update_webserver_stats - - expected_worker_count = 2 - expected_worker_stats = [ - { started_at: 1_701_263_705, index: 0, pid: 123, thread_count: 1, backlog: 0, busy_threads: 0, pool_capacity: 1, requests_count: 9 }, - { started_at: 1_701_263_710, index: 1, pid: 234, thread_count: 2, backlog: 1, busy_threads: 1, pool_capacity: 2, requests_count: 10 } + it 'sends stats to the prometheus updater' do + stats_hash = { + booted_workers: 2, + worker_status: [ + { started_at: '2023-11-29T13:15:05Z', index: 0, pid: 123, last_status: { running: 1, backlog: 0, busy_threads: 0, pool_capacity: 1, requests_count: 9 } }, + { started_at: '2023-11-29T13:15:10Z', index: 1, pid: 234, last_status: { running: 2, backlog: 1, busy_threads: 1, pool_capacity: 2, requests_count: 10 } } ] - expect(prometheus_updater).to have_received(:update_webserver_stats_puma).with(expected_worker_count, expected_worker_stats) - end - end + } + allow(Puma).to receive(:stats_hash).and_return(stats_hash) - context 'when Thin is configured as webserver' do - it 'does not send stats to the prometheus updater' do - periodic_updater.update_webserver_stats + periodic_updater.update_webserver_stats - expect(prometheus_updater).not_to have_received(:update_webserver_stats_puma) - end + expected_worker_count = 2 + expected_worker_stats = [ + { started_at: 1_701_263_705, index: 0, pid: 123, thread_count: 1, backlog: 0, busy_threads: 0, pool_capacity: 1, requests_count: 9 }, + { started_at: 1_701_263_710, index: 1, pid: 234, thread_count: 2, backlog: 1, busy_threads: 1, pool_capacity: 2, requests_count: 10 } + ] + expect(prometheus_updater).to have_received(:update_webserver_stats_puma).with(expected_worker_count, expected_worker_stats) end end diff --git a/spec/unit/lib/cloud_controller/metrics/prometheus_updater_spec.rb b/spec/unit/lib/cloud_controller/metrics/prometheus_updater_spec.rb index 274fbbbcae1..eb6b2603af3 100644 --- a/spec/unit/lib/cloud_controller/metrics/prometheus_updater_spec.rb +++ b/spec/unit/lib/cloud_controller/metrics/prometheus_updater_spec.rb @@ -160,10 +160,6 @@ module VCAP::CloudController::Metrics end describe '#update_webserver_stats_puma' do - before do - TestConfig.override(webserver: 'puma') - end - it 'contains Puma stats' do worker_count = 2 worker_stats = [ diff --git a/spec/unit/lib/cloud_controller/metrics_webserver_spec.rb b/spec/unit/lib/cloud_controller/metrics_webserver_spec.rb index e924f54b361..47b6c6e7e48 100644 --- a/spec/unit/lib/cloud_controller/metrics_webserver_spec.rb +++ b/spec/unit/lib/cloud_controller/metrics_webserver_spec.rb @@ -5,6 +5,10 @@ module VCAP::CloudController let(:metrics_webserver) { described_class.new } let(:config) { double('config', get: nil) } + after do + metrics_webserver.stop + end + describe '#start' do it 'configures and starts a Puma server' do allow(Puma::Server).to receive(:new).and_call_original diff --git a/spec/unit/lib/cloud_controller/runner_spec.rb b/spec/unit/lib/cloud_controller/runner_spec.rb index 4d8b051ba57..30edc77cc4d 100644 --- a/spec/unit/lib/cloud_controller/runner_spec.rb +++ b/spec/unit/lib/cloud_controller/runner_spec.rb @@ -14,12 +14,10 @@ module VCAP::CloudController before do allow(Steno).to receive(:init) allow(CloudController::DependencyLocator.instance).to receive(:routing_api_client).and_return(routing_api_client) - allow(EM).to receive(:run).and_yield allow(VCAP::CloudController::Metrics::PeriodicUpdater).to receive(:new).and_return(periodic_updater) allow(VCAP::CloudController::Metrics::RequestMetrics).to receive(:new).and_return(request_metrics) allow(periodic_updater).to receive(:setup_updates) allow(VCAP::PidFile).to receive(:new) { double(:pidfile, unlink_at_exit: nil) } - allow_any_instance_of(VCAP::CloudController::ThinRunner).to receive(:start!) allow(Puma::Server).to receive(:new).and_return(puma_server_double) end @@ -31,13 +29,17 @@ module VCAP::CloudController it 'creates a pidfile' do expect(VCAP::PidFile).to receive(:new).with('/tmp/cloud_controller.pid') + server = double(:server) + allow(server).to receive(:start!) + expect(VCAP::CloudController::PumaRunner).to receive(:new).and_return(server) + subject.run! end it 'starts the web server' do server = double(:server) allow(server).to receive(:start!) - expect(VCAP::CloudController::ThinRunner).to receive(:new).and_return(server) + expect(VCAP::CloudController::PumaRunner).to receive(:new).and_return(server) subject.run! expect(server).to have_received(:start!).once @@ -45,25 +47,6 @@ module VCAP::CloudController end describe '#initialize' do - describe 'web server selection' do - context 'when thin is specifed' do - it 'chooses ThinRunner as the web server' do - expect(subject.instance_variable_get(:@server)).to be_an_instance_of(ThinRunner) - end - end - - context 'when puma is specified' do - before do - TestConfig.override(webserver: 'puma') - allow(Config).to receive(:load_from_file).and_return(TestConfig.config_instance) - end - - it 'chooses puma as the web server' do - expect(subject.instance_variable_get(:@server)).to be_an_instance_of(PumaRunner) - end - end - end - it 'sets environment variable `PROCESS_TYPE` to `main`' do subject @@ -149,6 +132,7 @@ module VCAP::CloudController it 'builds a rack app with request metrics and request logs handlers' do builder = instance_double(RackAppBuilder) + allow(builder).to receive(:build).and_return(double(:app)) allow(RackAppBuilder).to receive(:new).and_return(builder) request_logs = double(:request_logs) allow(VCAP::CloudController::Logs::RequestLogs).to receive(:new).and_return(request_logs) @@ -297,16 +281,6 @@ module VCAP::CloudController subject end end - - context 'when the webserver is not puma' do - let(:test_config_overrides) { super().merge(webserver: 'thin') } - - it 'does not start the MetricsWebserver' do - expect(MetricsWebserver).not_to receive(:new) - - subject - end - end end end end diff --git a/spec/unit/lib/cloud_controller/runners/thin_runner_spec.rb b/spec/unit/lib/cloud_controller/runners/thin_runner_spec.rb deleted file mode 100644 index 70e5fa9ee9e..00000000000 --- a/spec/unit/lib/cloud_controller/runners/thin_runner_spec.rb +++ /dev/null @@ -1,159 +0,0 @@ -require 'spec_helper' - -module VCAP::CloudController - RSpec.describe ThinRunner do - let(:valid_config_file_path) { File.join(Paths::CONFIG, 'cloud_controller.yml') } - let(:config_file) { File.new(valid_config_file_path) } - let(:app) { double(:app) } - let(:logger) { double(:logger) } - let(:argv) { [] } - let(:periodic_updater) { double(:periodic_updater) } - let(:diagnostics) { instance_double(VCAP::CloudController::Diagnostics) } - let(:request_logs) { double(:request_logs) } - - before do - allow(logger).to receive :info - allow(logger).to receive :warn - allow(periodic_updater).to receive :setup_updates - allow(EM).to receive(:run).and_yield - allow(EM).to receive(:add_timer).and_yield - allow(VCAP::CloudController::Diagnostics).to receive(:new).and_return(diagnostics) - allow(diagnostics).to receive(:collect) - end - - subject do - config = Config.load_from_file(config_file.path, context: :api, secrets_hash: {}) - config.set(:external_host, 'some_local_ip') - ThinRunner.new(config, app, logger, periodic_updater, request_logs) - end - - it 'starts thin server on set up bind address' do - thin_server = double(:thin_server).as_null_object - expect(Thin::Server).to receive(:new).with('some_local_ip', 8181, { signals: false }).and_return(thin_server) - subject.start! - expect(subject.instance_variable_get(:@thin_server)).to eq(thin_server) - end - - describe 'start!' do - let(:app) { double(:app) } - let(:thin_server) { OpenStruct.new(start!: nil) } - - before do - allow(Thin::Server).to receive(:new).and_return(thin_server) - allow(thin_server).to receive(:start!) - subject.start! - end - - it 'gets the timeout from the config' do - expect(thin_server.timeout).to eq(600) - end - - it "uses thin's experimental threaded mode intentionally" do - expect(thin_server.threaded).to be(true) - end - - it 'starts the thin server' do - expect(thin_server).to have_received(:start!) - end - - it 'starts EventMachine' do - expect(EM).to have_received(:run) - end - - it 'sets up periodic updater updates' do - expect(periodic_updater).to receive(:setup_updates) - subject.start! - end - - it 'logs an error if an exception is raised' do - allow(thin_server).to receive(:start!).and_raise('we have a problem') - expect(subject.logger).to receive(:error) - expect { subject.start! }.to raise_exception('we have a problem') - end - end - - describe '#stop!' do - let(:thin_server) { double(:thin_server) } - - before do - subject.instance_variable_set(:@thin_server, thin_server) - end - - it 'stops thin and EM, logs incomplete requests' do - expect(thin_server).to receive(:stop) - expect(request_logs).to receive(:log_incomplete_requests) - expect(EM).to receive(:stop) - subject.stop! - end - end - - describe '#trap_signals' do - it 'registers TERM, INT, QUIT and USR1 handlers' do - expect(subject).to receive(:trap).with('TERM') - expect(subject).to receive(:trap).with('INT') - expect(subject).to receive(:trap).with('QUIT') - expect(subject).to receive(:trap).with('USR1') - subject.trap_signals - end - - it 'calls #stop! when the handlers are triggered' do - callbacks = [] - - expect(subject).to receive(:trap).with('TERM') do |_, &blk| - callbacks << blk - end - - expect(subject).to receive(:trap).with('INT') do |_, &blk| - callbacks << blk - end - - expect(subject).to receive(:trap).with('QUIT') do |_, &blk| - callbacks << blk - end - - expect(subject).to receive(:trap).with('USR1') do |_, &blk| - callbacks << blk - end - - subject.trap_signals - - expect(subject).to receive(:stop!).exactly(3).times - - callbacks.each(&:call) - end - end - - describe '#collect_diagnostics' do - callback = nil - - before do - callback = nil - expect(subject).to receive(:trap).with('TERM') - expect(subject).to receive(:trap).with('INT') - expect(subject).to receive(:trap).with('QUIT') - expect(subject).to receive(:trap).with('USR1') do |_, &blk| - callback = blk - end - subject.trap_signals - end - - let(:config_file) do - config = YAMLConfig.safe_load_file(valid_config_file_path) - config['directories'] ||= { 'tmpdir' => 'tmpdir' } - config['directories']['diagnostics'] = 'diagnostics/dir' - file = Tempfile.new('config') - file.write(YAML.dump(config)) - file.rewind - file - end - - it 'uses the configured directory' do - expect(Dir).not_to receive(:mktmpdir) - expect(subject).to receive(:collect_diagnostics).and_call_original - expect(diagnostics).to receive(:collect).with('diagnostics/dir') - - callback.call - end - end - end -end diff --git a/spec/unit/lib/vcap/stats_spec.rb b/spec/unit/lib/vcap/stats_spec.rb index bf6b78de5e7..c397bf14c3d 100644 --- a/spec/unit/lib/vcap/stats_spec.rb +++ b/spec/unit/lib/vcap/stats_spec.rb @@ -6,24 +6,11 @@ allow(VCAP::Stats).to receive_messages(ps_pid: "123456 7.8\n", ps_ppid: "121212 3.4\n343434 5.6\n") end - it 'returns the memory bytes and cpu for the process' do + it 'returns the summed up memory bytes and cpu for the process and its subprocesses' do rss_bytes, pcpu = VCAP::Stats.process_memory_bytes_and_cpu - expect(rss_bytes).to eq(126_418_944) - expect(pcpu).to eq(8) - end - - context 'when Puma is configured as webserver' do - before do - TestConfig.override(webserver: 'puma') - end - - it 'returns the summed up memory bytes and cpu for the process and its subprocesses' do - rss_bytes, pcpu = VCAP::Stats.process_memory_bytes_and_cpu - - expect(rss_bytes).to eq(602_216_448) - expect(pcpu).to eq(17) - end + expect(rss_bytes).to eq(602_216_448) + expect(pcpu).to eq(17) end end end diff --git a/spec/unit/middleware/cors_spec.rb b/spec/unit/middleware/cors_spec.rb index a75bb67e403..e9c9271c410 100644 --- a/spec/unit/middleware/cors_spec.rb +++ b/spec/unit/middleware/cors_spec.rb @@ -116,7 +116,7 @@ module Middleware status, _, body = middleware.call(request_headers) expect(status).to eq(200) - expect(body).to eq('') + expect(body).to eq(['']) end it 'sets the Content-Type: text/plain header' do