percy-common
Server-side common library for Percy.
Installation
Add this line to your application's Gemfile:
gem 'percy-common'
Or, for a Ruby library, add this to your gemspec:
spec.add_development_dependency 'percy-common'
And then run:
$ bundle install
Setup in a Rails app
If including in a Rails app, add the following to your application.rb
:
require 'percy/common/engine'
This enables Rails to autoload the constants from this library without more require
lines.
Usage
Percy::KeywordStruct
A simple struct that can be used when you need to return a simple value object.
require 'percy/keyword_struct'
class Foo < Percy::KeywordStruct.new(:bar, :baz, :qux)
end
foo = Foo.new(bar: 123, baz: true)
foo. # --> 123
foo.baz # --> true
foo.qux # --> nil
foo.fake # --> raises NoMethodError
Percy.logger
require 'percy/logger'
Percy.logger.debug { 'debug log' }
Percy.logger.info { 'info log' }
Percy.logger.warn { 'warning log' }
Percy.logger.error { 'error message' }
Prefer the block form usage Percy.logger.debug { 'message' }
over Percy.logger.debug('message')
because it is slightly more efficient when the log will be excluded by the current logging level. For example, if the log level is currently info
, then a debug
log in block form will never evaluate or allocate the message string itself.
Percy::ProcessHelpers
gracefully_kill(pid[, grace_period_seconds: 10])
Returns true
if the process was successfully killed, or false
if the process did not exist or its exit status was already collected.
require 'percy/process_helpers'
Percy::ProcessHelpers.gracefully_kill(pid)
This will send SIGTERM
to the process, wait up to 10 seconds, then send SIGKILL
if it has not already shut down.
Percy::NetworkHelpers
random_open_port
Returns a random open port. This is guaranteed by the OS to be currently an unbound open port, but users must still handle race conditions where the port is bound by the time it is actually used.
require 'percy/network_helpers'
Percy::NetworkHelpers.random_open_port
verify_healthcheck(url:[, expected_body: 'ok', retry_wait_seconds: 0.5])
Verify that a URL returns a specific body. Raises Percy::NetworkHelpers::ServerDown
if the server is down or does not respond with the expected body.
require 'percy/network_helpers'
Percy::NetworkHelpers.verify_healthcheck('http://localhost/healthz')
verify_http_server_up(hostname[, port: nil, path: nil, retry_wait_seconds: 0.25])
Verifies that a simple HTTP GET / request works against a hostname. Raises Percy::NetworkHelpers::ServerDown
if the server is down or if the request times out.
require 'percy/network_helpers'
Percy::NetworkHelpers.verify_http_server_up('example.com')
Percy::NetworkHelpers.verify_http_server_up('localhost', port: 8080)
serve_static_directory(dir[, hostname: 'localhost', port: nil])
Starts a simple local WEBrick server to serve a directory of static assets. This is a testing helper and should not be used in production.
require 'percy/network_helpers'
Percy::NetworkHelpers.serve_static_directory(File.('../test_data/', __FILE__))
Percy::Stats
Client for recording Datadog metrics and automatically setting up Percy-specific environment tags.
This class is a wrapper for Datadog::Statsd, an extended client for DogStatsD, which extends the StatsD metric server for Datadog.
Basic usage includes:
require 'percy/stats'
stats = Percy::Stats.new
# Increment a counter.
stats.increment('page.views')
# Record a gauge 50% of the time.
stats.gauge('users.online', 123, sample_rate: 0.5)
# Sample a histogram.
stats.histogram('file.upload.size', 1234)
# Time a block of code.
stats.time('page.render') do
render_page('home.html')
end
# Send several metrics at the same time.
# All metrics will be buffered and sent in one packet when the block completes.
stats.batch do |s|
s.increment('page.views')
s.gauge('users.online', 123)
end
# Tag a metric.
stats.histogram('query.time', 10, tags: ['version:1'])
See the Datadog::Statsd docs for more usage.
Our wrapper adds support for a non-block based start_timing
and stop_timing
methods:
require 'percy/stats'
stats = Percy::Stats.new
stats.start_timing
account.activate!
stats.stop_timing('account.activate')