cumuli 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
-