gargor 0.0.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 9a0e56e2f33609bb3a739df6ca00ddb576f05cb8
4
+ data.tar.gz: be55f9ee9f9acf5f4364c0ab69f9205253cc6e36
5
+ SHA512:
6
+ metadata.gz: ab25e90cdf88f4d5d233de33f40595f950dfb5178eb8503d710ef02faea8bcea325d94da31e83a7d17c8ae59ece8b436149034ec93505cba5e1fba18be6ecbf7
7
+ data.tar.gz: e941026cbc712e296415605b7a7d4ba409f28fa8e63a0f130c5a3937757abe72fade5d2b5a7e31d37dd0c48d31979352c5631b14e08b32574ab3a00a0b958bd8
@@ -8,4 +8,4 @@ rvm:
8
8
  - 1.9.2
9
9
  - 1.9.3
10
10
  - 2.0.0
11
- script: bundle exec rspec
11
+ script: bundle exec rake spec
data/Gemfile CHANGED
@@ -1,9 +1,12 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'json'
4
- gem 'jsonpath'
3
+ gem "rake", "~> 10.1.0"
4
+ gem "json", "~> 1.8.0"
5
+ gem "jsonpath", "~> 0.5.3"
5
6
  gem "progressbar", "~> 0.20.0"
6
7
  gem "version", "~> 1.0.0"
8
+ gem "thor", "~> 0.18.1"
9
+ gem "terminal-table", "~> 1.4.5"
7
10
 
8
11
  group :development do
9
12
  gem 'pry'
@@ -15,8 +18,8 @@ group :test, :development do
15
18
  gem 'coveralls'
16
19
  gem 'fakeweb'
17
20
  gem 'rspec'
18
- gem 'rspec-mocks'
19
21
  gem 'simplecov'
22
+ gem 'coveralls', require: false
20
23
  end
21
24
 
22
25
  # Specify your gem's dependencies in gargor.gemspec
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # gargor [![Build Status](https://travis-ci.org/tumf/gargor.png?branch=master)](https://travis-ci.org/tumf/gargor) [![Gem Version](https://badge.fury.io/rb/gargor.png)](http://badge.fury.io/rb/gargor) [![Code Climate](https://codeclimate.com/github/tumf/gargor.png)](https://codeclimate.com/github/tumf/gargor) [![Dependency Status](https://gemnasium.com/tumf/gargor.png)](https://gemnasium.com/tumf/gargor)
1
+ # gargor [![Build Status](https://travis-ci.org/tumf/gargor.png?branch=master)](https://travis-ci.org/tumf/gargor) [![Gem Version](https://badge.fury.io/rb/gargor.png)](http://badge.fury.io/rb/gargor) [![Code Climate](https://codeclimate.com/github/tumf/gargor.png)](https://codeclimate.com/github/tumf/gargor) [![Dependency Status](https://gemnasium.com/tumf/gargor.png)](https://gemnasium.com/tumf/gargor) [![Coverage Status](https://coveralls.io/repos/tumf/gargor/badge.png)](https://coveralls.io/r/tumf/gargor)
2
2
 
3
3
  `gargor` is software which uses genetic algorithm to support parameter tuning of the servers controlled by Chef.Using this software, you are able to optimize and automate the server tuning, which you did until now based on a combination of my experience and intuition.  
4
4
 
@@ -19,7 +19,7 @@ Ruby 1.9-
19
19
 
20
20
  ## Usage
21
21
 
22
- $ gargor [dsl-file]
22
+ $ gargor [options] tune [dsl-file]
23
23
 
24
24
  The dsl-file of `gargor` should be written as belows:
25
25
 
@@ -33,7 +33,7 @@ population 10
33
33
  # elite number of some generation.(carried over)
34
34
  elite 1
35
35
 
36
- # Probability of mutation set "0.01" to "1%" (when crossover)
36
+ # Probability of mutation set "0.01" (is 1%)
37
37
  mutation 0.01
38
38
 
39
39
  # target cook command : '%s' will replace by node name.
@@ -49,7 +49,10 @@ attack_cmd "ssh attacker.example ./bin/ghakai www-1.example.yml 2>/dev/null"
49
49
  # logger
50
50
  logger "gargor.log"
51
51
 
52
- # or optional settings like blows:
52
+ # state
53
+ state ".gargor.state"
54
+
55
+ # or optional settings like belows:
53
56
  #
54
57
  # logger "gargor.log" do |log|
55
58
  # log.level = Logger::INFO
@@ -236,6 +239,15 @@ I use [green hakai](https://github.com/KLab/green-hakai/).
236
239
 
237
240
  You can use ab(Apache bench) and so on.
238
241
 
242
+ ## Continuous Performance Tuning
243
+
244
+ After v1.0, `gargor` can save last status of the individuals to file (which indicates `state` in DSL or `--state=FILE` option).
245
+ You can excecute `gargor` by the daily cron, your servers will be tuned continuouslly.
246
+
247
+ ```
248
+ 0 4 * * * cd /path/to/project && gargor --state=.gargor.status
249
+ ```
250
+
239
251
  ## Contributing
240
252
 
241
253
  1. Fork it
@@ -19,7 +19,9 @@ Ruby 1.9以降が必要です
19
19
 
20
20
  ## 使い方
21
21
 
22
- $ gargor [dsl-file]
22
+ $ gargor [options] tune [dsl-file]
23
+
24
+ ### DSLファイル
23
25
 
24
26
  `gargor`の設定情報は、内部DSLによりに以下のように記述します。
25
27
 
@@ -247,7 +249,17 @@ MaxRequestsPerChild <%= node["httpd"]["max_request_per_child"] %>
247
249
 
248
250
  ***** EXTERMINATION ******
249
251
 
250
- これは、個体の環境が厳しすぎるためで負荷の条件を緩めて再度実施してください。
252
+ これは、個体の環境が厳しすぎるためで負荷の条件を緩めて再度実施してください。
253
+
254
+ `v1.0`より個体が全滅すると、初期状態のパラメータに戻すようになりました。 
255
+
256
+ ## 継続的パフォーマンスチューニング
257
+
258
+ `v1.0`より、`gargor`は最後の世代状態をファイル保存し再利用する事ができるようになりました。このファイル名はDSLの中で`state`か`--state=FILE` オプションで指定します。`gargor`を毎日動作するようにcronに仕掛けることで継続的なパフォーマンスチューニングを行うことができます。
259
+
260
+ ```
261
+ 0 4 * * * cd /path/to/project && gargor --state=.gargor.status
262
+ ```
251
263
 
252
264
  ## FAQ
253
265
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 1.0.0
data/bin/gargor CHANGED
@@ -1,41 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
2
  $:.unshift(File.dirname(__FILE__) + '/../lib')
3
3
  $TESTING=false
4
- require 'gargor'
5
- require 'progressbar'
6
-
7
- dsl_file=ARGV.last||"gargor.rb"
8
-
9
- def usage
10
- STDERR.print "usage: #{$0} [dsl-file]\n"
11
- end
12
-
13
- begin
14
- Gargor.start
15
- Gargor.load_dsl(dsl_file)
16
- rescue =>e
17
- STDERR.puts e.backtrace.join("\n")
18
-
19
- usage
20
- exit 1
21
- end
22
-
23
- pbar = ProgressBar.new("auto-tuning",Gargor.total_trials)
24
- loop {
25
- Gargor.populate.each { |i|
26
- if i.fitness == nil
27
- i.set_params
28
- i.attack if i.deploy
29
- end
30
- pbar.set(Gargor.total_trials-Gargor.last_trials)
31
- }
32
- break unless Gargor.next_generation
33
- }
34
- pbar.finish
35
-
36
- best = Gargor.individuals.max { |a,b| a.fitness <=> b.fitness }
37
- if best
38
- best.set_params
39
- best.deploy
40
- end
41
- p best
4
+ require 'gargor/cli'
@@ -5,33 +5,11 @@ require "logger"
5
5
  require "gargor/version"
6
6
  require "gargor/individual"
7
7
  require "gargor/parameter"
8
+ require "gargor/exceptions"
9
+ require "gargor/individuals"
10
+ require "gargor/dsl"
8
11
 
9
12
  class Gargor
10
- class GargorError < RuntimeError; end
11
- class ExterminationError < GargorError; end
12
- class ParameterError < GargorError; end
13
- class ValidationError < GargorError; end
14
- class ArgumentError < GargorError; end
15
-
16
- class Individuals < Array
17
- def has? i
18
- !!self.find { |ii| ii.params == i.params }
19
- end
20
- end
21
-
22
- GLOBAL_OPTS = ["population","max_generations","target_nodes",
23
- "attack_cmd","elite","mutation","target_cooking_cmd",
24
- "fitness_precision"]
25
-
26
- GLOBAL_OPTS.each { |name|
27
- define_method(name) { |val|
28
- Gargor.class_variable_set("@@#{name}", val)
29
- }
30
- }
31
-
32
- def log message,level=Logger::INFO
33
- Gargor.log(message,level)
34
- end
35
13
  class << self
36
14
  def log message,level=Logger::INFO
37
15
  return if $TESTING
@@ -43,34 +21,51 @@ class Gargor
43
21
  end
44
22
 
45
23
  def params
46
- result = {}
47
- GLOBAL_OPTS.map { |name|
48
- result[name] = Gargor.class_variable_get("@@#{name}")
49
- }
50
- result
24
+ @@dsl.params
25
+ end
26
+
27
+ def generation
28
+ @@generation
29
+ end
30
+
31
+ def prev_generation
32
+ @@prev_generation
33
+ end
34
+
35
+ def individuals
36
+ @@individuals
37
+ end
38
+
39
+ def logger
40
+ @@logger
41
+ end
42
+
43
+ def logger= logger
44
+ @@logger = logger
45
+ end
46
+
47
+ def opt name
48
+ @@dsl.send(name)
49
+ end
50
+
51
+ def base
52
+ @@base
51
53
  end
52
54
 
53
55
  def start
54
56
  @@logger = Logger.new(STDOUT)
55
- @@fitness_precision = 100000000
56
- @@prev_generation = nil
57
+ @@base = nil
57
58
  @@individuals = []
58
- @@param_procs = {}
59
- @@population = 0
60
- @@max_generations = 1
59
+ @@prev_generation = nil
61
60
  @@generation = 1
62
- @@elite = 0
63
- @@attack_cmd = "false"
64
- @@attack_proc = nil
65
- @@evaluate_proc = Proc.new { 0 }
66
- @@target_nodes = []
61
+ @@dsl = Dsl.new
67
62
  @@dsl_file = nil
68
63
  true
69
64
  end
70
65
  Gargor.start
71
66
 
72
67
  def validate
73
- raise ValidationError,"POPULATION isn't > 0" unless @@population > 0
68
+ raise ValidationError,"POPULATION isn't > 0" unless opt("population") > 0
74
69
  true
75
70
  end
76
71
 
@@ -87,28 +82,27 @@ class Gargor
87
82
  def load_dsl(params_file)
88
83
  @@dsl_file = params_file
89
84
  contents = File.read(params_file)
90
- new.instance_eval(contents)
85
+ @@dsl.instance_eval(contents)
91
86
  validate
92
87
  end
93
88
 
89
+ def options= options
90
+ @@dsl.options = options
91
+ end
92
+
94
93
  def mutate
95
- individual = Individual.new
96
- @@param_procs.each { |name,proc|
97
- param = Parameter.new(name)
98
- param.instance_eval(&proc)
99
- individual.params[name] = param
100
- }
94
+ individual = @@dsl.create_individual
101
95
  log "mutate #{individual}"
102
96
  individual
103
97
  end
104
98
 
105
99
  # 浮動小数点対応のrand
106
- def float_rand(f,p = @@fitness_precision)
100
+ def float_rand(f,p = @@dsl.fitness_precision)
107
101
  raise ArgumentError,"max must be > 0" unless f > 0
108
- f *= @@fitness_precision
102
+ f *= p
109
103
  i = f.to_i
110
104
  f = rand(i)
111
- f / @@fitness_precision.to_f
105
+ f / p.to_f
112
106
  end
113
107
 
114
108
  def crossover a,b
@@ -131,13 +125,15 @@ class Gargor
131
125
  end
132
126
 
133
127
  def populate_first_generation
134
- individuals = Gargor::Individuals.new
135
- individuals << mutate.load_now
136
- loop{
137
- break if individuals.length >= @@population
138
- individuals << mutate
139
- }
140
-
128
+ @@base = @@dsl.create_individual.load_now
129
+ individuals = @@dsl.load_state if @@dsl.has_state?
130
+ unless individuals
131
+ individuals = Gargor::Individuals.new
132
+ individuals << base
133
+ until individuals.length >= opt("population")
134
+ individuals << mutate
135
+ end
136
+ end
141
137
  Gargor::Individuals.new(individuals.shuffle)
142
138
  end
143
139
 
@@ -146,7 +142,7 @@ class Gargor
146
142
  Gargor::Individuals.new(g.sort{ |a,b| a.fitness<=>b.fitness }.last(count))
147
143
  end
148
144
 
149
- def mutation? mutation=@@mutation
145
+ def mutation? mutation= opt("mutation")
150
146
  rand <= mutation
151
147
  end
152
148
 
@@ -164,15 +160,12 @@ class Gargor
164
160
 
165
161
  def populate_next_generation
166
162
  log "population: #{@@prev_generation.length}"
167
- individuals = Gargor::Individuals.new(select_elites @@prev_generation,@@elite)
163
+ individuals = Gargor::Individuals.new(select_elites @@prev_generation,opt("elite"))
168
164
 
169
- loop{
170
- break if individuals.length >= @@population
165
+ until individuals.length >= opt("population") do
171
166
  i = populate_one
172
167
  individuals << i unless individuals.has?(i)
173
- }
174
- log "populate:"
175
- individuals.each { |i| log i }
168
+ end
176
169
  Gargor::Individuals.new(individuals.shuffle)
177
170
  end
178
171
 
@@ -185,33 +178,29 @@ class Gargor
185
178
  raise ExterminationError unless prev_count >= 2
186
179
  populate_next_generation
187
180
  end
188
- end
189
181
 
182
+ @@dsl.save_state(@@individuals) if @@dsl.has_state?
183
+
184
+ log "populate:"
185
+ @@individuals.each { |i| log i }
186
+ end
190
187
 
191
188
  def next_generation
192
189
  log "<== end generation #{@@generation}"
193
190
  @@generation += 1
194
- return false if @@generation > @@max_generations
191
+ return false if @@generation > opt("max_generations")
195
192
 
196
193
  log "==> next generation #{@@generation}"
197
194
  @@prev_generation = @@individuals
198
195
  true
199
196
  end
200
197
 
201
- def individuals
202
- @@individuals
203
- end
204
-
205
- def opt name
206
- Gargor.class_variable_get("@@#{name}")
207
- end
208
-
209
198
  def logfile file
210
199
  File.expand_path(File.join(File.dirname(@@dsl_file),file))
211
200
  end
212
201
 
213
202
  def total_trials
214
- @@population+(@@population-@@elite)*(@@max_generations-1)
203
+ opt("population")+(opt("population")-opt("elite"))*(opt("max_generations")-1)
215
204
  end
216
205
 
217
206
  def last_trials_at_this_generation
@@ -220,28 +209,8 @@ class Gargor
220
209
 
221
210
  def last_trials
222
211
  last_trials_at_this_generation +
223
- (@@max_generations-@@generation)*(@@population-@@elite)
212
+ (opt("max_generations")-@@generation)*(opt("population")-opt("elite"))
224
213
  end
225
214
 
226
215
  end
227
-
228
- def param name,&block
229
- @@param_procs[name] = block
230
- end
231
-
232
- def attack cmd,&block
233
- @@attack_cmd = cmd
234
- @@attack_proc = block
235
- end
236
-
237
- def evaluate &block
238
- @@evaluate_proc = block
239
- end
240
-
241
- def logger *args, &block
242
- file = args.shift
243
- @@logger = Logger.new(Gargor.logfile(file),*args)
244
- block.call(@@logger) if block
245
- end
246
-
247
216
  end
@@ -0,0 +1,91 @@
1
+ # -*- coding: utf-8 -*-
2
+ require "gargor"
3
+ require "thor"
4
+ class Gargor
5
+ class Double
6
+ def method_missing(name, *arguments);end
7
+ end
8
+
9
+ class CLI < Thor
10
+ default_command :tune
11
+ class_option :verbose, :type => :boolean, :aliases =>:v
12
+
13
+ desc "tune [gargor.rb]", "execute GA-search"
14
+ option :no_progress_bar, :type => :boolean, :aliases =>:q
15
+ option :max_generations, :type => :numeric, :aliases =>:g
16
+ option :population, :type => :numeric, :aliases =>:p
17
+ option :elite, :type => :numeric, :aliases =>:e
18
+ option :mutation, :type => :numeric, :aliases =>:m
19
+ option :target_cooking_cmd, :type =>:string, :banner =>"<COMMAND>"
20
+ option :target_nodes, :type =>:string, :banner =>"<NODE1,NODE2,NODE3...>"
21
+ option :attack_cmd, :type => :string, :banner =>"<COMMAND>"
22
+ option :logger, :type =>:string, :banner =>"<FILE>"
23
+ option :state, :type=>:string, :banner =>"<FILE>"
24
+
25
+ def tune file="gargor.rb"
26
+ require 'gargor/reporter'
27
+ require 'progressbar'
28
+ Gargor.start
29
+ Gargor.load_dsl(file)
30
+ Gargor.options = options
31
+
32
+ pbar.set(0)
33
+ trials
34
+ best = best_individual
35
+ deploy best
36
+ pbar.finish
37
+ puts Gargor::OptimizeReporter.table(Gargor.base,best)
38
+ rescue ExterminationError =>e
39
+ recover
40
+ report_error_exit(e)
41
+ rescue =>e
42
+ report_error_exit(e)
43
+ end
44
+
45
+ no_commands{
46
+ def trials
47
+ begin
48
+ Gargor.populate.each { |i|
49
+ trial(i) if i.fitness == nil
50
+ pbar.set(Gargor.total_trials-Gargor.last_trials)
51
+ }
52
+ end while(Gargor.next_generation)
53
+ end
54
+
55
+ def recover
56
+ Gargor.base && deploy(Gargor.base)
57
+ end
58
+
59
+ def report_error_exit e,ret = 1
60
+ unless $TESTING
61
+ STDERR.puts e.message
62
+ STDERR.puts e.backtrace.join("\n") if options["verbose"]
63
+ end
64
+ exit ret
65
+ end
66
+
67
+ def pbar
68
+ @pbar = Double.new if options["no_progress_bar"]
69
+ @pbar ||= ProgressBar.new(" Tuning",Gargor.total_trials)
70
+ end
71
+
72
+ def deploy i
73
+ i.set_params
74
+ i.deploy
75
+ end
76
+
77
+ def trial i
78
+ deploy i
79
+ i.attack
80
+ rescue Gargor::DeployError =>e
81
+ i.fitness = 0
82
+ end
83
+
84
+ def best_individual
85
+ Gargor.individuals.max { |a,b| a.fitness <=> b.fitness }
86
+ end
87
+ }
88
+
89
+ end
90
+ end
91
+ Gargor::CLI.start(ARGV)
@@ -0,0 +1,111 @@
1
+ require 'json'
2
+ class Gargor
3
+ class Dsl
4
+ GLOBAL_OPTS = ["population","max_generations","target_nodes",
5
+ "attack_cmd","elite","mutation","target_cooking_cmd",
6
+ "fitness_precision","state"]
7
+
8
+ GLOBAL_OPTS.each { |name|
9
+ define_method(name) { |*args|
10
+ if args.count > 0
11
+ instance_variable_set("@#{name}", args.shift)
12
+ end
13
+ instance_variable_get("@#{name}")
14
+ }
15
+ }
16
+ def target_nodes *args
17
+ return @target_nodes if args.count == 0
18
+ nodes = args.shift
19
+ @target_nodes = if nodes.is_a? Array
20
+ nodes
21
+ else
22
+ nodes.split(",")
23
+ end
24
+ end
25
+
26
+ attr_accessor :param_procs, :attack_proc, :evaluate_proc
27
+
28
+ def initialize
29
+ @param_procs = {}
30
+ @attack_proc = nil
31
+ @evaluate_proc = Proc.new { 0 }
32
+ @fitness_precision = 100000000
33
+ @population = 0
34
+ @max_generations = 1
35
+ @elite = 0
36
+ @attack_cmd = "false"
37
+ @target_nodes = []
38
+ @state = nil
39
+ end
40
+
41
+ def params
42
+ result = {}
43
+ GLOBAL_OPTS.map { |name| result[name] = send(name) }
44
+ result
45
+ end
46
+
47
+ def options= options
48
+ GLOBAL_OPTS.each { |name|
49
+ send(name.to_sym,options[name]) if options.has_key?(name)
50
+ }
51
+ end
52
+
53
+ def log message,level=Logger::INFO
54
+ Gargor.log(message,level)
55
+ end
56
+
57
+ def param name,&block
58
+ @param_procs[name] = block
59
+ end
60
+
61
+ def attack cmd,&block
62
+ @attack_cmd = cmd
63
+ @attack_proc = block
64
+ end
65
+
66
+ def evaluate &block
67
+ @evaluate_proc = block
68
+ end
69
+
70
+ def logger *args, &block
71
+ file = args.shift
72
+ logger = Logger.new(Gargor.logfile(file),*args)
73
+ block.call(logger) if block
74
+ Gargor.logger = logger
75
+ end
76
+
77
+ def has_state?
78
+ !!@state
79
+ end
80
+
81
+ def create_individual values = nil
82
+ individual = Individual.new
83
+ param_procs.each { |name,proc|
84
+ param = Parameter.new(name)
85
+ param.instance_eval(&proc)
86
+ values && param.value = values[name]
87
+ individual.params[name] = param
88
+ }
89
+ individual
90
+ end
91
+
92
+ def load_state file=@state
93
+ log "load state #{file}"
94
+ state = JSON.parse(File.read(file))
95
+ individuals = Individuals.new
96
+ state.each { |i|
97
+ individuals << create_individual(i)
98
+ }
99
+ individuals
100
+ rescue Errno::ENOENT =>e
101
+ false
102
+ end
103
+
104
+ def save_state individuals,file = @state
105
+ log "save state #{file}"
106
+ json = individuals.to_json
107
+ File.open(file,"w") { |f| f.write(json) }
108
+ end
109
+
110
+ end
111
+ end
@@ -0,0 +1,11 @@
1
+
2
+
3
+ class Gargor
4
+ class GargorError < RuntimeError; end
5
+
6
+ class ExterminationError < GargorError; end
7
+ class DeployError < GargorError; end
8
+ class ParameterError < GargorError; end
9
+ class ValidationError < GargorError; end
10
+ class ArgumentError < GargorError; end
11
+ end
@@ -15,6 +15,12 @@ class Gargor
15
15
  [@params,@fitness].to_s
16
16
  end
17
17
 
18
+ def to_hash
19
+ hash = {}
20
+ @params.each { |name,param| hash[name] = param.value }
21
+ hash
22
+ end
23
+
18
24
  def log message,level = Logger::INFO
19
25
  Gargor.log message,level
20
26
  end
@@ -59,7 +65,7 @@ class Gargor
59
65
  log "deploy failed",Logger::ERROR
60
66
  @fitness = 0
61
67
  sleep 1
62
- return false
68
+ raise Gargor::DeployError
63
69
  end
64
70
  }
65
71
  true
@@ -0,0 +1,11 @@
1
+ require 'json'
2
+ class Gargor
3
+ class Individuals < Array
4
+ def has? i
5
+ !!self.find { |ii| ii.params == i.params }
6
+ end
7
+ def to_json
8
+ collect { |i| i.to_hash }.to_json
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,20 @@
1
+ require 'terminal-table'
2
+ class Gargor
3
+ class Reporter;end
4
+ class OptimizeReporter < Reporter
5
+ class << self
6
+ def table from,to
7
+ table = Terminal::Table.new :headings => ['param', 'from', 'to'] do |t|
8
+ from.params.each do |name,f|
9
+ t << [name,f,to.params[name]]
10
+ end
11
+ t << :separator
12
+ t << ['Fitness', from.fitness,to.fitness]
13
+ end
14
+ [1,2].map { |n| table.align_column(n, :right) }
15
+ table.style={:border_y => "", :border_i => "-"}
16
+ table
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ require 'helper'
2
+ require 'gargor/cli'
3
+
4
+ describe Gargor::CLI,".start" do
5
+ it "exits when raise ExterminationError" do
6
+ to_load_fixture "sample-1.rb"
7
+ Gargor.stub(:start) {
8
+ raise Gargor::ExterminationError
9
+ }
10
+ expect{Gargor::CLI.start([])}.to raise_error(SystemExit)
11
+ end
12
+ end
@@ -27,11 +27,11 @@ describe Gargor::Individual, "#deploy" do
27
27
  expect(@i.deploy).to be true
28
28
  end
29
29
 
30
- it "returns false if deploy failed" do
30
+ it "raise Gargor::DeployError if deploy failed" do
31
31
  @i.stub(:shell) { |cmd|
32
32
  ["",255]
33
33
  }
34
- expect(@i.deploy).to be false
34
+ expect{@i.deploy}.to raise_error Gargor::DeployError
35
35
 
36
36
  end
37
37
  end
@@ -53,9 +53,9 @@ describe Gargor,".poplutate" do
53
53
  Gargor.load_dsl("dummy")
54
54
  to_load_contents("{}") # dummy json
55
55
  expect(Gargor.populate.size).to be Gargor.params["population"]
56
- expect(Gargor.opt("generation")).to be 1
56
+ expect(Gargor.generation).to be 1
57
57
  expect(Gargor.next_generation).to be true
58
- expect(Gargor.opt("generation")).to be 2
58
+ expect(Gargor.generation).to be 2
59
59
 
60
60
  expect{
61
61
  Gargor.populate
@@ -177,7 +177,16 @@ describe Gargor, ".logger" do
177
177
  to_load_fixture "sample-1.rb"
178
178
  Gargor.start
179
179
  Gargor.load_dsl("/tmp/test.rb")
180
- expect(Gargor.opt("logger")).to be_kind_of Logger
181
- expect(Gargor.opt("logger").level).to be Logger::INFO
180
+ expect(Gargor.logger).to be_kind_of Logger
181
+ expect(Gargor.logger.level).to be Logger::INFO
182
182
  end
183
183
  end
184
+
185
+ describe Gargor, ".options=" do
186
+ it "set options['target_nodes'] to array " do
187
+ options = {"target_nodes" => "node1,node2,node3"}
188
+ Gargor.options= options
189
+ expect(Gargor.opt("target_nodes")).to be_kind_of Array
190
+ end
191
+ end
192
+
@@ -28,3 +28,7 @@ end
28
28
  def to_load_contents text
29
29
  File.stub(:read).and_return(text)
30
30
  end
31
+
32
+
33
+ require 'coveralls'
34
+ Coveralls.wear!
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gargor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
5
- prerelease:
4
+ version: 1.0.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Yoshihiro TAKAHARA
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-07-03 00:00:00.000000000 Z
11
+ date: 2013-07-15 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: bundler
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ~>
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ~>
28
25
  - !ruby/object:Gem::Version
@@ -30,21 +27,19 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rake
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
- description: ! 'An auto-tuning tool for internet servers w/ Genetic Algorithm and
47
- Chef. You can get good settings during sleeping ;) '
41
+ description: 'An auto-tuning tool for internet servers w/ Genetic Algorithm and Chef.
42
+ You can get good settings during sleeping ;) '
48
43
  email:
49
44
  - y.takahara@gmail.com
50
45
  executables:
@@ -65,10 +60,16 @@ files:
65
60
  - doc/sample.rb
66
61
  - gargor.gemspec
67
62
  - lib/gargor.rb
63
+ - lib/gargor/cli.rb
64
+ - lib/gargor/dsl.rb
65
+ - lib/gargor/exceptions.rb
68
66
  - lib/gargor/individual.rb
67
+ - lib/gargor/individuals.rb
69
68
  - lib/gargor/parameter.rb
69
+ - lib/gargor/reporter.rb
70
70
  - lib/gargor/version.rb
71
71
  - spec/fixtures/sample-1.rb
72
+ - spec/gargor_cli_spec.rb
72
73
  - spec/gargor_individual_spec.rb
73
74
  - spec/gargor_spec.rb
74
75
  - spec/gargor_version_spec.rb
@@ -76,31 +77,31 @@ files:
76
77
  homepage: https://github.com/tumf/gargor
77
78
  licenses:
78
79
  - MIT
80
+ metadata: {}
79
81
  post_install_message:
80
82
  rdoc_options: []
81
83
  require_paths:
82
84
  - lib
83
85
  required_ruby_version: !ruby/object:Gem::Requirement
84
- none: false
85
86
  requirements:
86
- - - ! '>='
87
+ - - '>='
87
88
  - !ruby/object:Gem::Version
88
89
  version: '0'
89
90
  required_rubygems_version: !ruby/object:Gem::Requirement
90
- none: false
91
91
  requirements:
92
- - - ! '>='
92
+ - - '>='
93
93
  - !ruby/object:Gem::Version
94
94
  version: '0'
95
95
  requirements: []
96
96
  rubyforge_project:
97
- rubygems_version: 1.8.25
97
+ rubygems_version: 2.0.5
98
98
  signing_key:
99
- specification_version: 3
99
+ specification_version: 4
100
100
  summary: It is software which uses generic algorithm to support parameter tuning of
101
101
  the servers controlled by Chef.
102
102
  test_files:
103
103
  - spec/fixtures/sample-1.rb
104
+ - spec/gargor_cli_spec.rb
104
105
  - spec/gargor_individual_spec.rb
105
106
  - spec/gargor_spec.rb
106
107
  - spec/gargor_version_spec.rb