From 08132f75bd17faf9d504bc3a676f48510dbce148 Mon Sep 17 00:00:00 2001 From: Belen Bustamante Date: Tue, 25 Aug 2020 10:45:50 -0700 Subject: [PATCH] Add healthcheck endpoint, spec testing --- Gemfile | 2 +- lib/vmpooler/api.rb | 6 ++- lib/vmpooler/api/healthcheck.rb | 14 ++++++ spec/integration/api/healthcheck_spec.rb | 56 ++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 lib/vmpooler/api/healthcheck.rb create mode 100644 spec/integration/api/healthcheck_spec.rb diff --git a/Gemfile b/Gemfile index 26eef16f6..8e9f4b989 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ gem 'puma', '~> 4.3' gem 'rack', '~> 2.2' gem 'rake', '~> 13.0' gem 'redis', '~> 4.1' -gem 'rbvmomi', '~> 2.1' +gem 'rbvmomi', '~> 2.4', '>= 2.4.1' gem 'sinatra', '~> 2.0' gem 'prometheus-client', '~> 2.0' gem 'net-ldap', '~> 0.16' diff --git a/lib/vmpooler/api.rb b/lib/vmpooler/api.rb index 7d72ec6d6..eb856fc3d 100644 --- a/lib/vmpooler/api.rb +++ b/lib/vmpooler/api.rb @@ -3,7 +3,7 @@ module Vmpooler class API < Sinatra::Base # Load API components - %w[helpers dashboard reroute v1 request_logger].each do |lib| + %w[helpers dashboard reroute v1 request_logger healthcheck].each do |lib| require "vmpooler/api/#{lib}" end # Load dashboard components @@ -40,6 +40,10 @@ def self.execute(torun, config, redis, metrics, logger) require 'prometheus/middleware/exporter' use Vmpooler::Metrics::Promstats::CollectorMiddleware, metrics_prefix: "#{metrics.prometheus_prefix}_http" use Prometheus::Middleware::Exporter, path: metrics.prometheus_endpoint + # Note that a user may want to use this check without prometheus + # However, prometheus setup includes the web server which is required for this check + # At this time prometheus is a requirement of using the health check on manager + use Vmpooler::API::Healthcheck end if torun.include? :api diff --git a/lib/vmpooler/api/healthcheck.rb b/lib/vmpooler/api/healthcheck.rb new file mode 100644 index 000000000..50da734c5 --- /dev/null +++ b/lib/vmpooler/api/healthcheck.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Vmpooler + class API + class Healthcheck < Sinatra::Base + get '/healthcheck/?' do + content_type :json + + status 200 + JSON.pretty_generate({ 'ok' => true }) + end + end + end +end diff --git a/spec/integration/api/healthcheck_spec.rb b/spec/integration/api/healthcheck_spec.rb new file mode 100644 index 000000000..ecce07ec2 --- /dev/null +++ b/spec/integration/api/healthcheck_spec.rb @@ -0,0 +1,56 @@ +require 'spec_helper' +require 'rack/test' + +describe Vmpooler::API::Healthcheck do + include Rack::Test::Methods + + def app() + Vmpooler::API + end + + # Added to ensure no leakage in rack state from previous tests. + # Removes all routes, filters, middleware and extension hooks from the current class + # https://rubydoc.info/gems/sinatra/Sinatra/Base#reset!-class_method + before(:each) do + app.reset! + end + + let(:config) { + { + config: { + 'site_name' => 'test pooler', + 'vm_lifetime_auth' => 2, + }, + pools: [ + {'name' => 'pool1', 'size' => 5, 'alias' => ['poolone', 'poolun']}, + {'name' => 'pool2', 'size' => 10}, + {'name' => 'pool3', 'size' => 10, 'alias' => 'NotArray'} + ] + } + } + + let(:current_time) { Time.now } + + let(:metrics) { + double("metrics") + } + + before(:each) do + expect(app).to receive(:run!).once + expect(metrics).to receive(:setup_prometheus_metrics) + expect(metrics).to receive(:prometheus_prefix) + expect(metrics).to receive(:prometheus_endpoint) + app.execute([:api], config, redis, metrics, nil) + app.settings.set :config, auth: false + end + + describe '/healthcheck' do + it 'returns OK' do + get "/healthcheck" + expect(last_response.header['Content-Type']).to eq('application/json') + expect(last_response.status).to eq(200) + result = JSON.parse(last_response.body) + expect(result).to eq({'ok' => true}) + end + end +end