Skip to content

Commit

Permalink
Setup dummy test server
Browse files Browse the repository at this point in the history
  • Loading branch information
bf4 committed Jan 5, 2016
1 parent 7d4f0c5 commit 411d613
Show file tree
Hide file tree
Showing 5 changed files with 278 additions and 0 deletions.
39 changes: 39 additions & 0 deletions bin/serve_dummy
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bash
set -e

case "$1" in

start)
config="${CONFIG_RU:-test/dummy/config.ru}"
bundle exec ruby -Ilib -S rackup "$config" --daemonize --pid tmp/dummy_app.pid --warn --server webrick
until [ -f 'tmp/dummy_app.pid' ]; do
sleep 0.1 # give it time to start.. I don't know a better way
done
cat tmp/dummy_app.pid
true
;;

stop)
if [ -f 'tmp/dummy_app.pid' ]; then
kill -TERM $(cat tmp/dummy_app.pid)
else
echo 'No pidfile'
false
fi
;;

status)
if [ -f 'tmp/dummy_app.pid' ]; then
kill -0 $(cat tmp/dummy_app.pid)
[ "$?" -eq 0 ]
else
echo 'No pidfile'
false
fi
;;

*)
echo "Usage: $0 [start|stop|status]"
;;

esac
88 changes: 88 additions & 0 deletions test/dummy/app.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# https://github.com/rails-api/active_model_serializers/pull/872
# approx ref 792fb8a9053f8db3c562dae4f40907a582dd1720 to test against
require 'bundler/setup'

require 'rails'
require 'active_model'
require 'active_support'
require 'active_support/json'
require 'action_controller'
require 'action_controller/test_case'
require 'action_controller/railtie'
abort "Rails application already defined: #{Rails.application.class}" if Rails.application

# ref: https://gist.github.com/bf4/8744473
class DummyApp < Rails::Application
config.action_controller.perform_caching = ENV['CACHE_ON'] != 'off'
config.action_controller.cache_store = :memory_store

# Set up production configuration
config.eager_load = true
config.cache_classes = true

config.active_support.test_order = :random
config.secret_token = '1234'
config.secret_key_base = 'abc123'
config.logger = Logger.new(IO::NULL)

class DummyLogger < ActiveSupport::Logger
def initialize
@file = StringIO.new
super(@file)
end

def messages
@file.rewind
@file.read
end
end
end

require 'active_model_serializers'

# Initialize app before any serializers are defined, for sanity's sake.
# Otherwise, you have to manually set perform caching.
#
# Details:
#
# 1. Upon load, when AMS.config.perform_caching is true,
# serializers inherit the cache store from ActiveModelSerializers.config.cache_store
# 1. If the serializers are loaded before Rails is initialized (`Rails.application.initialize!`),
# these values are nil, and are not applied to the already loaded serializers
# 1. If Rails is initialized before any serializers are loaded, then the configs are set,
# and are used when serializers are loaded
# 1. In either case, `ActiveModelSerializers.config.cache_store`, and
# `ActiveModelSerializers.config.perform_caching` can be set at any time before the serializers
# are loaded,
# e.g. `ActiveModel::Serializer.config.cache_store ||=
# ActiveSupport::Cache.lookup_store(ActionController::Base.cache_store ||
# Rails.cache || :memory_store)`
# and `ActiveModelSerializers.config.perform_caching = true`
# 1. If the serializers are loaded before Rails is initialized, then,
# you can set the `_cache` store directly on the serializers.
# `ActiveModel::Serializer._cache ||=
# ActiveSupport::Cache.lookup_store(ActionController::Base.cache_store ||
# Rails.cache || :memory_store`
# is sufficient.
# Setting `_cache` to a truthy value will cause the CachedSerializer
# to consider it cached, which will apply to all serializers (bug? :bug: )
#
# This happens, in part, because the cache store is set for a serializer
# when `cache` is called, and cache is usually called when the serializer is defined.
#
# So, there's now a 'workaround', something to debug, and a starting point.
Rails.application.initialize!

require_relative 'fixtures'
require_relative 'controllers'

# Clear cache
ActionController::Base.cache_store.clear

# Test caching is on
ActiveSupport::Cache::Store.logger = Logger.new(IO::NULL) # seems to be the best way
# the below is used in some rails tests but isn't available/working in all versions, so far as I can tell
# https://github.com/rails/rails/pull/15943
# ActiveSupport::Notifications.subscribe(/^cache_(.*)\.active_support$/) do |*args|
# p ActiveSupport::Notifications::Event.new(*args)
# end
3 changes: 3 additions & 0 deletions test/dummy/config.ru
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
require File.expand_path(['..','app'].join(File::SEPARATOR), __FILE__)

run Rails.application
42 changes: 42 additions & 0 deletions test/dummy/controllers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
class PostController < ActionController::Base
POST =
begin
comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
author = Author.new(id: 1, name: 'Joao Moura.')
Post.new(id: 1, title: 'New Post', blog: nil, body: 'Body', comments: [comment], author: author)
end

def render_with_caching_serializer
toggle_cache_status
render json: POST, adapter: :json
end

def render_with_non_caching_serializer
toggle_cache_status
render json: POST, serializer: CachingPostSerializer, adapter: :json
end

def render_cache_status
toggle_cache_status
# Uncomment to debug
# STDERR.puts cache_store.class
# STDERR.puts cache_dependencies
render json: {caching: perform_caching}.to_json
end

private

def toggle_cache_status
case params[:on]
when 'on'.freeze then self.perform_caching = true
when 'off'.freeze then self.perform_caching = false
else # no-op
end
end
end

Rails.application.routes.draw do
get '/status(/:on)' => 'post#render_cache_status'
get '/caching(/:on)' => 'post#render_with_caching_serializer'
get '/non_caching(/:on)' => 'post#render_with_non_caching_serializer'
end
106 changes: 106 additions & 0 deletions test/dummy/fixtures.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
class AuthorSerializer < ActiveModel::Serializer
attributes :id, :name

has_many :posts, embed: :ids
has_one :bio
end

class BlogSerializer < ActiveModel::Serializer
attributes :id, :name
end

class CommentSerializer < ActiveModel::Serializer
attributes :id, :body

belongs_to :post
belongs_to :author
end

class PostSerializer < ActiveModel::Serializer
attributes :id, :title, :body

has_many :comments, serializer: CommentSerializer
belongs_to :blog, serializer: BlogSerializer
belongs_to :author, serializer: AuthorSerializer

def blog
Blog.new(id: 999, name: 'Custom blog')
end
end

class CachingAuthorSerializer < AuthorSerializer
cache key: 'writer', skip_digest: true
end

class CachingCommentSerializer < CommentSerializer
cache expires_in: 1.day, skip_digest: true
end

class CachingPostSerializer < PostSerializer
cache key: 'post', expires_in: 0.1, skip_digest: true
belongs_to :blog, serializer: BlogSerializer
belongs_to :author, serializer: CachingAuthorSerializer
has_many :comments, serializer: CachingCommentSerializer
end

# ActiveModelSerializers::Model is a convenient
# serializable class to inherit from when making
# serializable non-activerecord objects.
class BenchmarkModel
include ActiveModel::Model
include ActiveModel::Serializers::JSON

attr_reader :attributes

def initialize(attributes = {})
@attributes = attributes
super
end

# Defaults to the downcased model name.
def id
attributes.fetch(:id) { self.class.name.downcase }
end

# Defaults to the downcased model name and updated_at
def cache_key
attributes.fetch(:cache_key) { "#{self.class.name.downcase}/#{id}-#{updated_at.strftime("%Y%m%d%H%M%S%9N")}" }
end

# Defaults to the time the serializer file was modified.
def updated_at
attributes.fetch(:updated_at) { File.mtime(__FILE__) }
end

def read_attribute_for_serialization(key)
if key == :id || key == 'id'
attributes.fetch(key) { id }
else
attributes[key]
end
end
end

class Comment < BenchmarkModel
attr_accessor :id, :body

def cache_key
"#{self.class.name.downcase}/#{id}"
end
end

class Author < BenchmarkModel
attr_accessor :id, :name, :posts
end

class Post < BenchmarkModel
attr_accessor :id, :title, :body, :comments, :blog, :author

def cache_key
'benchmarking::post/1-20151215212620000000000'
end
end

class Blog < BenchmarkModel
attr_accessor :id, :name
end

0 comments on commit 411d613

Please sign in to comment.