Browse Source

Initial commit

master
Christian Aust 1 year ago
commit
fc8ba7deae
  1. 1
      .gitignore
  2. 1
      .ruby-gemset
  3. 1
      .ruby-version
  4. 7
      Gemfile
  5. 13
      Gemfile.lock
  6. 21
      LICENSE
  7. 25
      lib/sanity.rb
  8. 35
      lib/sanity/assertions.rb
  9. 26
      lib/sanity/runner.rb
  10. 31
      lib/sanity/suite.rb
  11. 25
      lib/sanity/tests/ssl.rb
  12. 35
      lib/sanity/tests/static_web.rb
  13. 7
      lib/string_ext.rb
  14. 11
      run.rb

1
.gitignore

@ -0,0 +1 @@
/*.json

1
.ruby-gemset

@ -0,0 +1 @@
sanity

1
.ruby-version

@ -0,0 +1 @@
ruby-2.6.5

7
Gemfile

@ -0,0 +1,7 @@
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem 'ssl-test'

13
Gemfile.lock

@ -0,0 +1,13 @@
GEM
remote: https://rubygems.org/
specs:
ssl-test (1.3.1)
PLATFORMS
ruby
DEPENDENCIES
ssl-test
BUNDLED WITH
2.1.4

21
LICENSE

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Christian Aust
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

25
lib/sanity.rb

@ -0,0 +1,25 @@
require 'string_ext'
module Sanity
autoload :Assertions, 'sanity/assertions'
autoload :Runner, 'sanity/runner'
autoload :Suite, 'sanity/suite'
module Tests
autoload :StaticWeb, 'sanity/tests/static_web'
autoload :Ssl, 'sanity/tests/ssl'
end
class AssertionError < Exception
##
# Where was this run before an assertion was raised?
def location
last_before_assertion = ""
self.backtrace.reverse_each do |s|
break if s =~ /in .(assert)/
last_before_assertion = s
end
last_before_assertion.sub(/:in .*$/, "")
end
end
end

35
lib/sanity/assertions.rb

@ -0,0 +1,35 @@
module Sanity
module Assertions
def assert(test, msg=nil)
return true if test
msg ||= "Expected value to be truthy"
raise AssertionError.new(msg)
end
def assert_blank(val, msg=nil)
result = case val
when String then val == ''
when Array then val.empty?
else val.nil?
end
assert(result, "Expected value to be blank")
end
def assert_equals(a, b, msg=nil)
assert(a==b, "Expected #{a} to equal #{b}")
end
def assert_present(val, msg=nil)
result = case val
when String then val != ''
when Array then !val.empty?
else !val.nil?
end
assert(result, "Expected value to be present")
end
def assert_true(val, msg=nil)
assert(val===true, "Expected #{val} to be true")
end
end
end

26
lib/sanity/runner.rb

@ -0,0 +1,26 @@
require 'json'
module Sanity
class Runner
attr_reader :path, :specs
def initialize(path)
@path = path
File.open(@path) do |f|
@specs = JSON.load f
end
end
def check!
specs.each do |name, roles|
suite = Suite.new(name)
roles.each do |role_name, targets|
klass = "Sanity::Tests::#{role_name}".to_class
targets.each { |target| suite << klass.new(target) }
end
suite.run
end
end
end
end

31
lib/sanity/suite.rb

@ -0,0 +1,31 @@
module Sanity
class Suite
attr_accessor :tests
def initialize(name)
@tests = []
end
def <<(val)
@tests << val
end
def run
@tests.each do |test|
test.send(:setup) if test.respond_to?(:setup)
test.methods
.filter{ |m| /\Atest./ =~ m.to_s }
.sort
.each do |m|
begin
test.send(m)
rescue Sanity::AssertionError => ex
puts "#{ex} in #{ex.location}"
rescue Exception => ex
puts ex
end
end
end
end
end
end

25
lib/sanity/tests/ssl.rb

@ -0,0 +1,25 @@
require 'ssl-test'
module Sanity::Tests
class Ssl
include Sanity::Assertions
attr_reader :target
def initialize(target)
@target = target
end
def setup
@valid, @error, @cert = SSLTest.test target
end
def test_if_valid
assert_true @valid, "SSL cert isn't valid"
end
def test_no_error
assert_blank @error, "SSL test has errors: #{@error}"
end
end
end

35
lib/sanity/tests/static_web.rb

@ -0,0 +1,35 @@
require 'date'
require 'uri'
require 'net/http'
module Sanity::Tests
class StaticWeb
include Sanity::Assertions
attr_reader :response, :target
def initialize(target)
@target = URI.parse(target)
end
def setup
http = Net::HTTP.new(@target.host, @target.port)
http.use_ssl = @target.scheme == 'https'
@response = http.request(Net::HTTP::Get.new(@target.request_uri))
end
def test_successful_request
assert response.is_a?(Net::HTTPSuccess), "Request does not succeed: #{response.code} #{response.message}"
end
def test_server_clock
server_date = DateTime.parse(response['date'])
diff = ((DateTime.now - server_date) * 24 * 60 * 60).to_i
assert diff<60, "Server clock off by #{diff} seconds"
end
def test_etag
assert_present response['etag'], 'Etag is not set'
end
end
end

7
lib/string_ext.rb

@ -0,0 +1,7 @@
class String
def to_class
split('::').inject(Kernel) do |scope, const_name|
scope.const_get(const_name)
end
end
end

11
run.rb

@ -0,0 +1,11 @@
#!/usr/bin/env ruby
require 'rubygems'
require 'bundler/setup'
lib = File.expand_path("../lib", __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'sanity'
Sanity::Runner.new('targets.json').check!
Loading…
Cancel
Save