cumuli 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5e3ea3081971fb3671f1b98e50f1d7140bb23587
4
- data.tar.gz: 9eb5f33068ba05c2dfc927d8b0e0b320acbe28e9
3
+ metadata.gz: 58e619931f7a11f25a4f514ec52b1a3e400c5b45
4
+ data.tar.gz: a2c6821ee16d9cef7f3cc7ce336244252977db7c
5
5
  SHA512:
6
- metadata.gz: 570630e93591b54fdb115244de8969f3b2a739f470c74133f8e4b72bfe7ca14892a6b060ea3a316a704b2b9502c179aced952c5e0d04ff0fd02259eca57adf42
7
- data.tar.gz: 556f8513559a6d74c80a46813c13d27b15b17b4a23c631082d140d5132ffa73517270840c60496f716d42209b0159c19adc10d925a57cf6f4286cf9359d378f0
6
+ metadata.gz: dcbf82ac48e8fc4ddf82e9242e1f2756f7fe8cfe015421a762be40f11f28b099acab29fa973f46545695496b337721f4041da2ffcd0488bf9513a87962606c82
7
+ data.tar.gz: 275079f9f57e77f16f32ae7509f25927a7324485cd895bc2469df00753c7493118cc100ff3452480ef591a48037e9ac6b24491eec47a5554807dca49c8dbbc3c
data/.gitignore CHANGED
@@ -16,3 +16,5 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  Procfile
19
+ log/*.log
20
+ spec/fixtures/log/*.log
data/.rvmrc CHANGED
@@ -2,5 +2,5 @@ rvm_install_on_use_flag=1
2
2
  rvm_trust_rvmrcs_flag=1
3
3
  rvm_gemset_create_on_use_flag=1
4
4
 
5
- rvm use 2.0.0@strawboss --create
5
+ rvm use 2.0.0@cumuli --create
6
6
 
data/README.md CHANGED
@@ -69,6 +69,12 @@ framework.
69
69
 
70
70
  app.stop # gracefully kills all the related processes
71
71
 
72
+ ## Known Issues
73
+
74
+ If you start the Cumuli app and stop it the first time, it will successfully start and stop all processes. However, if you use the same Cumuli app class to
75
+ start and stop the processes again, it will fail to stop any of the
76
+ processes.
77
+
72
78
  ## Contributing
73
79
 
74
80
  1. Fork it
data/Rakefile CHANGED
@@ -1,15 +1,2 @@
1
1
  require "bundler/gem_tasks"
2
-
3
- desc "kill the ruby stuff, debugging script"
4
- task :kill_rubies do
5
- ps_list = `ps axo pid,comm | grep ruby`
6
- pids = ps_list.lines.map(&:split).map(&:first).map(&:to_i) - [Process.pid]
7
- pids.each do |pid|
8
- Process.kill("SIGINT", pid)
9
- end
10
- end
11
-
12
- task :ps do
13
- ps = `ps axo pid,ppid,comm,args,user`
14
- puts ps.lines.select{|l| l.match(/ruby|resque|foreman|rvm/)}
15
- end
2
+ require "#{File.dirname(__FILE__)}/lib/cumuli/tasks.rb"
data/bin/cumuli CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "cumuli"
3
+ require_relative "../lib/cumuli"
4
4
 
5
5
  Cumuli::CLI.new.run
data/cumuli.gemspec CHANGED
@@ -6,7 +6,7 @@ require 'cumuli/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "cumuli"
8
8
  spec.version = Cumuli::VERSION
9
- spec.authors = ["SocialChorus", "Kane Baccigalupi", "Fito von Zastrow"]
9
+ spec.authors = ["SocialChorus", "Kane Baccigalupi", "Fito von Zastrow", "Roy Pfaffman"]
10
10
  spec.email = ["developers@socialchorus.com"]
11
11
  spec.description = %q{Cumuli runs several foreman processes in different directories}
12
12
  spec.summary = %q{Cumuli makes SOA on Heroku easier by delegating to Foreman in a Procfile}
@@ -18,8 +18,9 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
+ spec.add_dependency "foreman"
22
+
21
23
  spec.add_development_dependency "rspec"
22
- spec.add_development_dependency "foreman"
23
24
  spec.add_development_dependency "bundler", "~> 1.3"
24
25
  spec.add_development_dependency "rake"
25
26
  end
@@ -0,0 +1,92 @@
1
+ module Cumuli
2
+ class App
3
+ DEFAULT_WAIT_TIME = 5 #120
4
+ SIGNALS = ['TERM', 'INT', 'HUP']
5
+
6
+ attr_accessor :env, :wait_time, :app_dir, :log_dir
7
+
8
+ def initialize(options={})
9
+ @env = options[:env]
10
+ @wait_time = options[:wait_time]
11
+ @log_dir = options[:log_dir] || "#{Dir.pwd}/log"
12
+ @app_dir = options[:app_dir] || Dir.pwd
13
+ end
14
+
15
+ def start
16
+ return if foreman_process.started?
17
+
18
+ Dir.chdir(app_dir) do
19
+ listen_for_signals
20
+ logger.print "Starting ..."
21
+ foreman_process.start
22
+ wait_for_apps if wait?
23
+ end
24
+ end
25
+
26
+ def logger
27
+ @logger = StdoutLogger.new
28
+ end
29
+
30
+ def foreman_process
31
+ @termial ||= ForemanProcess.new(env, log_dir)
32
+ end
33
+
34
+ def apps
35
+ @apps ||= Procs.new(app_dir)
36
+ end
37
+
38
+ def pid
39
+ foreman_process.pid
40
+ end
41
+
42
+ def wait?
43
+ wait_time && wait_time > 0
44
+ end
45
+
46
+ def listen_for_signals
47
+ SIGNALS.each do |signal|
48
+ trap(signal) do
49
+ stop
50
+ end
51
+ end
52
+ end
53
+
54
+ def app_ports
55
+ @apps.map.values.compact
56
+ end
57
+
58
+ def wait_for_apps
59
+ app_ports.each do |port|
60
+ wait_for_app(port)
61
+ end
62
+
63
+ logger.add_space
64
+ end
65
+
66
+ def wait_for_app(port)
67
+ logger.print "waiting for apps on port: #{port}"
68
+
69
+ timeout = wait_time || DEFAULT_WAIT_TIME
70
+ Waiter.new("Application on port #{port} unavailable after #{timeout} seconds")
71
+ .wait_until(timeout) { open_socket(port) }
72
+ logger.print "Application on #{port} available"
73
+ rescue Exception => e
74
+ stop
75
+ raise e
76
+ end
77
+
78
+ def open_socket(port)
79
+ TCPSocket.new('localhost', port)
80
+ true
81
+ rescue Errno::ECONNREFUSED
82
+ false
83
+ end
84
+
85
+ def stop
86
+ if foreman_process.started?
87
+ foreman_process.stop
88
+ @foreman_process = nil
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,54 @@
1
+ module Cumuli
2
+ class App
3
+ class ForemanProcess
4
+ attr_reader :pid, :env, :log_dir
5
+
6
+ def initialize(env, log_dir)
7
+ @env = env
8
+ @log_dir = log_dir
9
+ ensure_log_dir_and_file
10
+ end
11
+
12
+ def ensure_log_dir_and_file
13
+ FileUtils.mkdir_p(log_dir)
14
+ FileUtils.touch(log_file)
15
+ end
16
+
17
+ def command
18
+ "HEROKU_ENV=#{env} RAILS_ENV=#{env} foreman start"
19
+ end
20
+
21
+ def log_file
22
+ "#{log_dir}/#{env}.log"
23
+ end
24
+
25
+ def start
26
+ @pid = fork do
27
+ listen_for_signals
28
+ $stdout.reopen(log_file)
29
+ exec(command)
30
+ end
31
+ end
32
+
33
+ def listen_for_signals
34
+ Cumuli::App::SIGNALS.each do |signal|
35
+ trap(signal) do
36
+ puts "#{self.class}: trapped signal #{signal} in #{Process.pid} ... stopping"
37
+ stop
38
+ end
39
+ end
40
+ end
41
+
42
+ def started?
43
+ !!pid
44
+ end
45
+
46
+ def stop
47
+ return if @killed_it
48
+ Process.kill('INT', 0) # kills all processes in the group
49
+ @killed_it = true
50
+ @pid = nil
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,51 @@
1
+ module Cumuli
2
+ class App
3
+ class Procs
4
+ attr_reader :port_map, :path, :apps
5
+
6
+ def initialize(path=nil)
7
+ @path = (path || Dir.pwd) + "/Procfile"
8
+ parse_procfile
9
+ end
10
+
11
+ def map
12
+ @map ||= apps.inject({}) do |hash, app|
13
+ hash[app.name] = app.port
14
+ hash
15
+ end
16
+ end
17
+
18
+ def file
19
+ @file ||= File.read(path)
20
+ end
21
+
22
+ def parse_procfile
23
+ @apps = file.lines.map do |line|
24
+ SubApp.new(line)
25
+ end
26
+ end
27
+
28
+ def names
29
+ map.keys
30
+ end
31
+
32
+ class SubApp
33
+ attr_reader :parts
34
+
35
+ def initialize(line)
36
+ @parts = line.split
37
+ end
38
+
39
+ def name
40
+ parts.first.gsub(':', '')
41
+ end
42
+
43
+ def port
44
+ if index = parts.find_index('-p')
45
+ parts[index + 1] && parts[index + 1].to_i
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,16 @@
1
+ module Cumuli
2
+ class App
3
+ class StdoutLogger
4
+ GRAY = "\033[0;37m"
5
+ RESET = "\033[0m"
6
+
7
+ def print(message)
8
+ puts "Nimbus: #{GRAY}#{message}#{RESET}"
9
+ end
10
+
11
+ def add_space
12
+ puts ''
13
+ end
14
+ end
15
+ end
16
+ end
data/lib/cumuli/app.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "cumuli/app/app"
2
+ require "cumuli/app/foreman_process"
3
+ require "cumuli/app/stdout_logger"
4
+ require "cumuli/app/procs"
5
+
@@ -1,18 +1,20 @@
1
1
  module Cumuli
2
- class Args
3
- attr_reader :argv, :dir
2
+ class CLI
3
+ class Args
4
+ attr_reader :argv, :dir
4
5
 
5
- def initialize(argv)
6
- @argv = argv
7
- @dir ||= argv.shift
8
- end
6
+ def initialize(argv)
7
+ @argv = argv
8
+ @dir ||= argv.shift
9
+ end
9
10
 
10
- def name
11
- @name ||= dir.match(/([a-z_]+)$/i)[0]
12
- end
11
+ def name
12
+ @name ||= dir.match(/([a-z_]+)$/i)[0]
13
+ end
13
14
 
14
- def foreman_options
15
- argv.join(' ')
15
+ def foreman_options
16
+ argv.join(' ')
17
+ end
16
18
  end
17
19
  end
18
20
  end
@@ -1,29 +1,31 @@
1
1
  module Cumuli
2
- class Commander
3
- attr_reader :args
2
+ class CLI
3
+ class Commander
4
+ attr_reader :args
4
5
 
5
- def initialize(args)
6
- @args = args
7
- end
6
+ def initialize(args)
7
+ @args = args
8
+ end
8
9
 
9
- def build
10
- "#{rvm_preface} foreman start #{args.foreman_options}"
11
- end
10
+ def build
11
+ "#{rvm_preface} foreman start #{args.foreman_options}"
12
+ end
12
13
 
13
- def rvm_preface
14
- "rvm ruby-#{rvm_version} exec" if rvmrc?
15
- end
14
+ def rvm_preface
15
+ "rvm ruby-#{rvm_version} exec" if rvmrc?
16
+ end
16
17
 
17
- def rvmrc_descriptor
18
- './.rvmrc'
19
- end
18
+ def rvmrc_descriptor
19
+ './.rvmrc'
20
+ end
20
21
 
21
- def rvmrc?
22
- File.exist?(rvmrc_descriptor)
23
- end
22
+ def rvmrc?
23
+ File.exist?(rvmrc_descriptor)
24
+ end
24
25
 
25
- def rvm_version
26
- File.read(rvmrc_descriptor).match(/(\d\.\d\.\d@\w+)/)[0]
26
+ def rvm_version
27
+ File.read(rvmrc_descriptor).match(/(\d\.\d\.\d@\w+)/)[0]
28
+ end
27
29
  end
28
30
  end
29
31
  end
@@ -1,34 +1,36 @@
1
1
  module Cumuli
2
- class Terminal
3
- VARS = ['GEM_HOME', 'GEM_PATH', 'RUBYOPT', 'RBENV_DIR']
2
+ class CLI
3
+ class Terminal
4
+ VARS = ['GEM_HOME', 'GEM_PATH', 'RUBYOPT', 'RBENV_DIR']
4
5
 
5
- attr_reader :command
6
+ attr_reader :command
6
7
 
7
- def initialize(command)
8
- @command = command
9
- end
8
+ def initialize(command)
9
+ @command = command
10
+ end
10
11
 
11
- def bundled?
12
- Object.const_defined?('Bundler')
13
- end
12
+ def bundled?
13
+ Object.const_defined?('Bundler')
14
+ end
14
15
 
15
- def spawn
16
- bundled? ? call_bundled : execute_command
17
- end
16
+ def spawn
17
+ bundled? ? call_bundled : execute_command
18
+ end
18
19
 
19
- def call_bundled
20
- Bundler.with_clean_env do
21
- clear_env
22
- execute_command
20
+ def call_bundled
21
+ Bundler.with_clean_env do
22
+ clear_env
23
+ execute_command
24
+ end
23
25
  end
24
- end
25
26
 
26
- def execute_command
27
- exec(command)
28
- end
27
+ def execute_command
28
+ exec(command)
29
+ end
29
30
 
30
- def clear_env
31
- VARS.each { |e| ENV.delete(e) }
31
+ def clear_env
32
+ VARS.each { |e| ENV.delete(e) }
33
+ end
32
34
  end
33
35
  end
34
36
  end
@@ -0,0 +1,19 @@
1
+ module Cumuli
2
+ def self.start(env='test')
3
+ @app ||= App.new({
4
+ env: env,
5
+ log_dir: log_dir,
6
+ app_dir: app_dir,
7
+ wait_time: wait_time || App::DEFAULT_WAIT_TIME
8
+ })
9
+ @app.start
10
+ end
11
+
12
+ def self.stop
13
+ @app.stop
14
+ end
15
+
16
+ class << self
17
+ attr_accessor :env, :log_dir, :app_dir, :wait_time
18
+ end
19
+ end
data/lib/cumuli/ps.rb ADDED
@@ -0,0 +1,63 @@
1
+ module Cumuli
2
+ class PS
3
+ REGEX = /ruby|resque|foreman|rvm|node/
4
+
5
+ attr_reader :lines
6
+
7
+ def initialize(list=self.class.list)
8
+ @lines = list.lines
9
+ @lines.shift # to remove header line
10
+ end
11
+
12
+ def matching(regex = REGEX)
13
+ @matching ||= lines
14
+ .select{|l| l.match(regex)}
15
+ .select{|l| !l.match(/^#{Process.pid} /) }
16
+ end
17
+
18
+ def kill
19
+ pids.each do |pid|
20
+ Process.kill("SIGINT", pid)
21
+ end
22
+ end
23
+
24
+ def pids(regex = REGEX)
25
+ matching(regex)
26
+ .map(&:split)
27
+ .map(&:first)
28
+ .map(&:to_i)
29
+ end
30
+
31
+ def ppid_hash
32
+ lines
33
+ .map(&:split)
34
+ .inject({}) do |hash, line_values|
35
+ pid = line_values[0].to_i
36
+ ppid = line_values[1].to_i
37
+ hash[ppid] ||= []
38
+ hash[ppid] << pid
39
+ hash
40
+ end
41
+ end
42
+
43
+ def line(pid)
44
+ lines.detect{|l| l.match(/^#{pid} /)}
45
+ end
46
+
47
+ def tree(pid)
48
+ child_pids = ppid_hash[pid]
49
+ puts "#{pid} => #{child_pids}"
50
+ child_pids.map{|cpid| tree(cpid) } if child_pids
51
+ end
52
+
53
+ def report(pid)
54
+ tree(pid)
55
+ puts "\n"
56
+ puts matching
57
+ end
58
+
59
+ def self.list
60
+ `ps axo pid,ppid,comm,args,user`
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,13 @@
1
+ namespace :cumuli do
2
+ require_relative "../ps"
3
+
4
+ desc "kill the processes showing up in the nimbus:ps task"
5
+ task :kill do
6
+ Cumuli::PS.new.kill
7
+ end
8
+
9
+ desc "look at processes likely related to cumuli"
10
+ task :ps do
11
+ puts Cumuli::PS.new.matching
12
+ end
13
+ end
@@ -0,0 +1 @@
1
+ load "#{File.dirname(__FILE__)}/tasks/cumuli.rake"
@@ -1,3 +1,3 @@
1
1
  module Cumuli
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,23 @@
1
+ module Cumuli
2
+ class Waiter
3
+ TIMEOUT = 30
4
+ MESSAGE = "#wait_until did not resolve after #{TIMEOUT} seconds"
5
+
6
+ attr_reader :message
7
+
8
+ def initialize(message=MESSAGE)
9
+ @message = message
10
+ end
11
+
12
+ def wait_until(timeout=TIMEOUT, &block)
13
+ begin
14
+ Timeout.timeout(timeout) do
15
+ sleep(0.1) until value = block.call
16
+ value
17
+ end
18
+ rescue Timeout::Error
19
+ raise message
20
+ end
21
+ end
22
+ end
23
+ end
data/lib/cumuli.rb CHANGED
@@ -3,5 +3,13 @@ $stdout.sync = true
3
3
  lib = File.expand_path(File.dirname(__FILE__))
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
+ require 'logger'
7
+ require 'timeout'
8
+ require 'fileutils'
9
+
10
+ require "cumuli/facade"
11
+ require "cumuli/ps"
12
+ require "cumuli/waiter"
6
13
  require "cumuli/cli"
14
+ require "cumuli/app"
7
15
  require "cumuli/version"
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cumuli::App do
4
+ describe '#start' do
5
+ let(:opts) {
6
+ {
7
+ env: 'test',
8
+ wait: false,
9
+ log_dir: log_dir,
10
+ app_dir: app_set_dir
11
+ }
12
+ }
13
+ let(:app) { Cumuli::App.new(opts) }
14
+ let(:logs) { File.readlines("#{log_dir}/test.log") }
15
+
16
+ before do
17
+ clear_logs
18
+ app.start
19
+ app.wait_for_app(2323)
20
+ end
21
+
22
+ after do
23
+ app.stop
24
+ end
25
+
26
+ it "launches subprocesses with the foreman command" do
27
+ ps_line = Cumuli::PS.new.matching.detect{|line| line.match(/foreman: master/) }
28
+ ps_line.should_not be_nil
29
+ end
30
+
31
+ it "redirects subprocess output to the logs" do
32
+ logs.detect {|line| line.match(/started with pid/) }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cumuli::App::Procs do
4
+ let(:procs) { Cumuli::App::Procs.new(app_set_dir) }
5
+
6
+ it "#names includes all the app names listed in the Procfile" do
7
+ procs.names.should =~ [
8
+ 'loopy', 'nodified'
9
+ ]
10
+ end
11
+
12
+ describe '#map' do
13
+ it "maps names to ports" do
14
+ procs.map['nodified'].should == 2323
15
+ end
16
+
17
+ it "return a nil port when the app has no port" do
18
+ procs.map['loopy'].should == nil
19
+ end
20
+ end
21
+ end
@@ -1,8 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Cumuli::Args do
3
+ describe Cumuli::CLI::Args do
4
4
  let(:argv) { ["../mactivator", "-p", "4000"] }
5
- let(:args) { Cumuli::Args.new(argv) }
5
+ let(:args) { Cumuli::CLI::Args.new(argv) }
6
6
 
7
7
  it "#dir will return the first element passed in" do
8
8
  args.dir.should == "../mactivator"
@@ -1,9 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Cumuli::Commander do
3
+ describe Cumuli::CLI::Commander do
4
4
  describe "#build" do
5
5
  let(:args) { mock({foreman_options: 'foreman-options-here'}) }
6
- let(:commander) { Cumuli::Commander.new(args) }
6
+ let(:commander) { Cumuli::CLI::Commander.new(args) }
7
7
 
8
8
  context "application directory has no .rvmrc" do
9
9
  before do
@@ -32,7 +32,7 @@ describe Cumuli::Commander do
32
32
 
33
33
  describe "reading from the file system" do
34
34
  it "prefaces with the right rvm information" do
35
- Dir.chdir(File.dirname(__FILE__) + "/fixtures/app_set/loopy") do
35
+ Dir.chdir(File.dirname(__FILE__) + "/../fixtures/app_set/loopy") do
36
36
  commander.build.should include('rvm ruby-2.0.0')
37
37
  end
38
38
  end
@@ -1,11 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Cumuli::Terminal do
3
+ describe Cumuli::CLI::Terminal do
4
4
  it "clears environmental variables" do
5
5
  preserving_env do
6
6
  ENV['GEM_HOME'] = 'somewhere-over-the-rainbow'
7
7
 
8
- terminal = Cumuli::Terminal.new('$GEM_HOME')
8
+ terminal = Cumuli::CLI::Terminal.new('$GEM_HOME')
9
9
  terminal.clear_env
10
10
 
11
11
  ENV['GEM_HOME'].should == nil
@@ -15,9 +15,10 @@ describe Cumuli::Terminal do
15
15
  it "spawns a new thread that runs the command" do
16
16
  preserving_env do
17
17
  pid = fork do
18
- Cumuli::Terminal.new('STRAWBOSSED=true').spawn
18
+ Cumuli::CLI::Terminal.new('STRAWBOSSED=true').spawn
19
19
  ENV['STRAWBOSSED'].should == true
20
20
  end
21
+
21
22
  Process.kill('INT', pid)
22
23
  end
23
24
  end
@@ -1 +1,2 @@
1
- loopy: ../../bin/strawboss ./loopy
1
+ loopy: ../../../bin/cumuli ./loopy
2
+ nodified: ../../../bin/cumuli ./noded -p 2323
@@ -2,4 +2,4 @@ rvm_install_on_use_flag=1
2
2
  rvm_trust_rvmrcs_flag=1
3
3
  rvm_gemset_create_on_use_flag=1
4
4
 
5
- rvm use 2.0.0@strawboss --create
5
+ rvm use 2.0.0@cumuli --create
@@ -2,4 +2,4 @@ rvm_install_on_use_flag=1
2
2
  rvm_trust_rvmrcs_flag=1
3
3
  rvm_gemset_create_on_use_flag=1
4
4
 
5
- rvm use 1.9.3@strawboss --create
5
+ rvm use 2.0.0@nimbus --create
@@ -0,0 +1,7 @@
1
+ var http = require('http');
2
+
3
+ var port = process.env.PORT;
4
+
5
+ http.createServer(function(request, response) {
6
+ console.log('Looping in node:', request.method, request.url, '\n');
7
+ }).listen(port);
@@ -0,0 +1,7 @@
1
+ def log_dir
2
+ File.dirname(__FILE__) + "/../fixtures/log"
3
+ end
4
+
5
+ def clear_logs
6
+ FileUtils.rm_rf(log_dir) if File.exist?(log_dir)
7
+ end
@@ -0,0 +1,7 @@
1
+ def app_set_dir
2
+ File.expand_path(File.dirname(__FILE__)) + "/../fixtures/app_set"
3
+ end
4
+
5
+ def fail_set_dir
6
+ File.expand_path(File.dirname(__FILE__)) + "/../fixtures/fail_set"
7
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cumuli::Waiter do
4
+ let(:timeout) { 0.1 }
5
+
6
+ context "default message" do
7
+ let(:waiter) { Cumuli::Waiter.new }
8
+
9
+ it "will raise a default message if the block never resolves to a non-falsey value" do
10
+ expect {
11
+ waiter.wait_until(timeout){ false }
12
+ }.to raise_error(Cumuli::Waiter::MESSAGE)
13
+ end
14
+
15
+ it "will return the truthy value that it gets from the block" do
16
+ waiter.wait_until{ 'truthy' }.should == 'truthy'
17
+ end
18
+ end
19
+
20
+ context "initialization with a message" do
21
+ let(:message) { "Something went unexpected" }
22
+ let(:waiter) { Cumuli::Waiter.new(message) }
23
+
24
+ it "raises the message if the block does not resolve" do
25
+ expect {
26
+ waiter.wait_until(timeout){ false }
27
+ }.to raise_error(message)
28
+ end
29
+ end
30
+
31
+ context "intitialization with an exception" do
32
+ let(:exception) { RuntimeError.new("Something went unexpected") }
33
+ let(:waiter) { Cumuli::Waiter.new(exception) }
34
+
35
+ it "raises the message if the block does not resolve" do
36
+ # Rspec is having issues with the normal expect block ...
37
+ # so let's do this the long way
38
+ raised = false
39
+ begin
40
+ waiter.wait_until(timeout){ false }
41
+ rescue Exception => e
42
+ raised = true
43
+ e.should == exception
44
+ end
45
+ raised.should == true
46
+ end
47
+ end
48
+ end
metadata CHANGED
@@ -1,25 +1,26 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cumuli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - SocialChorus
8
8
  - Kane Baccigalupi
9
9
  - Fito von Zastrow
10
+ - Roy Pfaffman
10
11
  autorequire:
11
12
  bindir: bin
12
13
  cert_chain: []
13
14
  date: 2013-07-09 00:00:00.000000000 Z
14
15
  dependencies:
15
16
  - !ruby/object:Gem::Dependency
16
- name: rspec
17
+ name: foreman
17
18
  requirement: !ruby/object:Gem::Requirement
18
19
  requirements:
19
20
  - - '>='
20
21
  - !ruby/object:Gem::Version
21
22
  version: '0'
22
- type: :development
23
+ type: :runtime
23
24
  prerelease: false
24
25
  version_requirements: !ruby/object:Gem::Requirement
25
26
  requirements:
@@ -27,7 +28,7 @@ dependencies:
27
28
  - !ruby/object:Gem::Version
28
29
  version: '0'
29
30
  - !ruby/object:Gem::Dependency
30
- name: foreman
31
+ name: rspec
31
32
  requirement: !ruby/object:Gem::Requirement
32
33
  requirements:
33
34
  - - '>='
@@ -86,25 +87,39 @@ files:
86
87
  - bin/cumuli
87
88
  - cumuli.gemspec
88
89
  - lib/cumuli.rb
90
+ - lib/cumuli/app.rb
91
+ - lib/cumuli/app/app.rb
92
+ - lib/cumuli/app/foreman_process.rb
93
+ - lib/cumuli/app/procs.rb
94
+ - lib/cumuli/app/stdout_logger.rb
89
95
  - lib/cumuli/cli.rb
90
96
  - lib/cumuli/cli/args.rb
91
97
  - lib/cumuli/cli/cli.rb
92
98
  - lib/cumuli/cli/commander.rb
93
99
  - lib/cumuli/cli/terminal.rb
100
+ - lib/cumuli/facade.rb
101
+ - lib/cumuli/ps.rb
102
+ - lib/cumuli/tasks.rb
103
+ - lib/cumuli/tasks/cumuli.rake
94
104
  - lib/cumuli/version.rb
95
- - spec/args_spec.rb
96
- - spec/commander_spec.rb
105
+ - lib/cumuli/waiter.rb
106
+ - spec/app/app_spec.rb
107
+ - spec/app/procs_spec.rb
108
+ - spec/cli/args_spec.rb
109
+ - spec/cli/commander_spec.rb
110
+ - spec/cli/terminal_spec.rb
97
111
  - spec/fixtures/app_set/Procfile
98
- - spec/fixtures/app_set/legacied/.rvmrc
99
- - spec/fixtures/app_set/legacied/half_loop.rb
100
- - spec/fixtures/app_set/legacied/quarter_loop.rb
101
112
  - spec/fixtures/app_set/loopy/.rvmrc
102
113
  - spec/fixtures/app_set/loopy/Procfile
103
114
  - spec/fixtures/app_set/loopy/half_loop.rb
104
115
  - spec/fixtures/app_set/loopy/loop.rb
116
+ - spec/fixtures/app_set/noded/.rvmrc
117
+ - spec/fixtures/app_set/noded/nodified.js
105
118
  - spec/spec_helper.rb
106
119
  - spec/support/functional_helpers.rb
107
- - spec/terminal_spec.rb
120
+ - spec/support/log_helpers.rb
121
+ - spec/support/mock_apps.rb
122
+ - spec/waiter_spec.rb
108
123
  homepage: http://github.com/socialchorus/cumuli
109
124
  licenses:
110
125
  - MIT
@@ -130,16 +145,20 @@ signing_key:
130
145
  specification_version: 4
131
146
  summary: Cumuli makes SOA on Heroku easier by delegating to Foreman in a Procfile
132
147
  test_files:
133
- - spec/args_spec.rb
134
- - spec/commander_spec.rb
148
+ - spec/app/app_spec.rb
149
+ - spec/app/procs_spec.rb
150
+ - spec/cli/args_spec.rb
151
+ - spec/cli/commander_spec.rb
152
+ - spec/cli/terminal_spec.rb
135
153
  - spec/fixtures/app_set/Procfile
136
- - spec/fixtures/app_set/legacied/.rvmrc
137
- - spec/fixtures/app_set/legacied/half_loop.rb
138
- - spec/fixtures/app_set/legacied/quarter_loop.rb
139
154
  - spec/fixtures/app_set/loopy/.rvmrc
140
155
  - spec/fixtures/app_set/loopy/Procfile
141
156
  - spec/fixtures/app_set/loopy/half_loop.rb
142
157
  - spec/fixtures/app_set/loopy/loop.rb
158
+ - spec/fixtures/app_set/noded/.rvmrc
159
+ - spec/fixtures/app_set/noded/nodified.js
143
160
  - spec/spec_helper.rb
144
161
  - spec/support/functional_helpers.rb
145
- - spec/terminal_spec.rb
162
+ - spec/support/log_helpers.rb
163
+ - spec/support/mock_apps.rb
164
+ - spec/waiter_spec.rb
@@ -1,5 +0,0 @@
1
- while (true)
2
- puts "Loop it when you can!"
3
- sleep 4
4
- end
5
-
@@ -1,5 +0,0 @@
1
- while (true)
2
- puts "Loop it if you can"
3
- sleep 4
4
- end
5
-