Class: Cucumber::Chef::TestLab

Inherits:
Object
  • Object
show all
Defined in:
lib/cucumber/chef/test_lab.rb

Constant Summary collapse

INVALID_STATES =
%w( terminated pending )
RUNNING_STATES =
%w( running starting-up )
SHUTDOWN_STATES =
%w( shutdown stopping stopped shutting-down )
VALID_STATES =
RUNNING_STATES+SHUTDOWN_STATES

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stdout = STDOUT, stderr = STDERR, stdin = STDIN) ⇒ TestLab

Returns a new instance of TestLab.



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/cucumber/chef/test_lab.rb', line 38

def initialize(stdout=STDOUT, stderr=STDERR, stdin=STDIN)
  @stdout, @stderr, @stdin = stdout, stderr, stdin
  @stdout.sync = true if @stdout.respond_to?(:sync=)

  @connection = Fog::Compute.new(
    :provider => 'AWS',
    :aws_access_key_id => Cucumber::Chef::Config[:aws][:aws_access_key_id],
    :aws_secret_access_key => Cucumber::Chef::Config[:aws][:aws_secret_access_key],
    :region => Cucumber::Chef::Config[:aws][:region]
  )
  ensure_security_group
end

Instance Attribute Details

#connectionObject (readonly)

Returns the value of attribute connection.



28
29
30
# File 'lib/cucumber/chef/test_lab.rb', line 28

def connection
  @connection
end

#serverObject (readonly)

Returns the value of attribute server.



28
29
30
# File 'lib/cucumber/chef/test_lab.rb', line 28

def server
  @server
end

#stderrObject

Returns the value of attribute stderr.



29
30
31
# File 'lib/cucumber/chef/test_lab.rb', line 29

def stderr
  @stderr
end

#stdinObject

Returns the value of attribute stdin.



29
30
31
# File 'lib/cucumber/chef/test_lab.rb', line 29

def stdin
  @stdin
end

#stdoutObject

Returns the value of attribute stdout.



29
30
31
# File 'lib/cucumber/chef/test_lab.rb', line 29

def stdout
  @stdout
end

Instance Method Details

#clientsObject



291
292
293
294
295
296
297
# File 'lib/cucumber/chef/test_lab.rb', line 291

def clients
  Cucumber::Chef.load_knife_config
  query = "tags:#{Cucumber::Chef::Config[:mode]} AND tags:#{Cucumber::Chef::Config[:user]}"
  $logger.debug { "query(#{query})" }
  clients, offset, total = ::Chef::Search::Query.new.search("client", URI.escape(query))
  clients.compact
end

#createObject



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/cucumber/chef/test_lab.rb', line 53

def create
  if (lab_exists? && (@server = labs_running.first))
    @stdout.puts("A test lab already exists using the AWS credentials you have supplied; attempting to reprovision it.")
  else
    server_definition = {
      :image_id => Cucumber::Chef::Config.aws_image_id,
      :groups => Cucumber::Chef::Config[:aws][:aws_security_group],
      :flavor_id => Cucumber::Chef::Config[:aws][:aws_instance_type],
      :key_name => Cucumber::Chef::Config[:aws][:aws_ssh_key_id],
      :availability_zone => Cucumber::Chef::Config[:aws][:availability_zone],
      :tags => { "purpose" => "cucumber-chef", "cucumber-chef-mode" => Cucumber::Chef::Config[:mode] },
      :identity_file => Cucumber::Chef::Config[:aws][:identity_file]
    }
    if (@server = @connection.servers.create(server_definition))
      @stdout.puts("Provisioning cucumber-chef test lab platform.")

      @stdout.print("Waiting for instance...")
      Cucumber::Chef.spinner do
        @server.wait_for { ready? }
      end
      @stdout.puts("done.\n")

      tag_server

      @stdout.print("Waiting for 20 seconds...")
      Cucumber::Chef.spinner do
        sleep(20)
      end
      @stdout.print("done.\n")
    end
  end

  if @server
    @stdout.print("Waiting for SSHD...")
    Cucumber::Chef.spinner do
      Cucumber::Chef::TCPSocket.new(@server.public_ip_address, 22).wait
    end
    @stdout.puts("done.\n")
  end

  @server

rescue Exception => e
  $logger.fatal { e.message }
  $logger.fatal { "Backtrace:\n#{e.backtrace.join("\n")}" }
  raise TestLabError, e.message
end

#destroyObject



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/cucumber/chef/test_lab.rb', line 103

def destroy
  if ((l = labs).count > 0)
    @stdout.puts("Destroying Servers:")
    l.each do |server|
      @stdout.puts("  * #{server.public_ip_address}")
      server.destroy
    end
  else
    @stdout.puts("There are no cucumber-chef test labs to destroy!")
  end

rescue Exception => e
  $logger.fatal { e.message }
  $logger.fatal { e.backtrace.join("\n") }
  raise TestLabError, e.message
end

#infoObject



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/cucumber/chef/test_lab.rb', line 174

def info
  if lab_exists?
    labs.each do |lab|
      @stdout.puts("Instance ID: #{lab.id}")
      @stdout.puts("State: #{lab.state}")
      @stdout.puts("Username: #{lab.username}") if lab.username
      if (lab.public_ip_address || lab.private_ip_address)
        @stdout.puts
        @stdout.puts("IP Address:")
        @stdout.puts("  Public...: #{lab.public_ip_address}") if lab.public_ip_address
        @stdout.puts("  Private..: #{lab.private_ip_address}") if lab.private_ip_address
      end
      if (lab.dns_name || lab.private_dns_name)
        @stdout.puts
        @stdout.puts("DNS:")
        @stdout.puts("  Public...: #{lab.dns_name}") if lab.dns_name
        @stdout.puts("  Private..: #{lab.private_dns_name}") if lab.private_dns_name
      end
      if (lab.tags.count > 0)
        @stdout.puts
        @stdout.puts("Tags:")
        lab.tags.to_hash.each do |k,v|
          @stdout.puts("  #{k}: #{v}")
        end
      end
      if lab.public_ip_address
        @stdout.puts
        @stdout.puts("Chef-Server WebUI:")
        @stdout.puts("  http://#{lab.public_ip_address}:4040/")
      end
      @stdout.puts
      if (labs_running.include?(lab) && (n = nodes))
        @stdout.puts
        @stdout.puts("Nodes:")
        n.each do |node|
          @stdout.puts("  * #{node.name} (#{node.cloud.public_ipv4})")
        end
      end
      if (labs_running.include?(lab) && (c = clients))
        @stdout.puts
        @stdout.puts("Clients:")
        c.each do |client|
          @stdout.puts("  * #{client.name}")
        end
      end
    end
  else
    @stdout.puts("There are no cucumber-chef test labs to display information for!")
  end

rescue Exception => e
  $logger.fatal { e.message }
  $logger.fatal { e.backtrace.join("\n") }
  raise TestLabError, e.message
end

#lab_exists?Boolean

Returns:

  • (Boolean)


232
233
234
# File 'lib/cucumber/chef/test_lab.rb', line 232

def lab_exists?
  (labs.size > 0)
end

#labsObject



238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/cucumber/chef/test_lab.rb', line 238

def labs
  results = @connection.servers.select do |server|
    $logger.debug("candidate") { "ID=#{server.id}, state='#{server.state}'" }
    ( server.tags['cucumber-chef-mode'] == Cucumber::Chef::Config[:mode].to_s &&
      server.tags['cucumber-chef-user'] == Cucumber::Chef::Config[:user].to_s &&
      VALID_STATES.any?{ |state| state == server.state } )
  end
  results.each do |server|
    $logger.debug("results") { "ID=#{server.id}, state='#{server.state}'" }
  end
  results
end

#labs_runningObject



253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/cucumber/chef/test_lab.rb', line 253

def labs_running
  results = @connection.servers.select do |server|
    $logger.debug("candidate") { "ID=#{server.id}, state='#{server.state}'" }
    ( server.tags['cucumber-chef-mode'] == Cucumber::Chef::Config[:mode].to_s &&
      server.tags['cucumber-chef-user'] == Cucumber::Chef::Config[:user].to_s &&
      RUNNING_STATES.any?{ |state| state == server.state } )
  end
  results.each do |server|
    $logger.debug("results") { "ID=#{server.id}, state='#{server.state}'" }
  end
  results
end

#labs_shutdownObject



268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/cucumber/chef/test_lab.rb', line 268

def labs_shutdown
  results = @connection.servers.select do |server|
    $logger.debug("candidate") { "ID=#{server.id}, state='#{server.state}'" }
    ( server.tags['cucumber-chef-mode'] == Cucumber::Chef::Config[:mode].to_s &&
      server.tags['cucumber-chef-user'] == Cucumber::Chef::Config[:user].to_s &&
      SHUTDOWN_STATES.any?{ |state| state == server.state } )
  end
  results.each do |server|
    $logger.debug("results") { "ID=#{server.id}, state='#{server.state}'" }
  end
  results
end

#nodesObject



283
284
285
286
287
288
289
# File 'lib/cucumber/chef/test_lab.rb', line 283

def nodes
  Cucumber::Chef.load_knife_config
  query = "tags:#{Cucumber::Chef::Config[:mode]} AND tags:#{Cucumber::Chef::Config[:user]}"
  $logger.debug { "query(#{query})" }
  nodes, offset, total = ::Chef::Search::Query.new.search("node", URI.escape(query))
  nodes.compact
end

#startObject



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/cucumber/chef/test_lab.rb', line 122

def start
  if (lab_exists? && (@server = labs_shutdown.first))
    if @server.start

      @stdout.print("Waiting for instance...")
      Cucumber::Chef.spinner do
        @server.wait_for { ready? }
      end
      @stdout.puts("done.\n")

      @stdout.print("Waiting for SSHD...")
      Cucumber::Chef.spinner do
        Cucumber::Chef::TCPSocket.new(@server.public_ip_address, 22).wait
      end
      @stdout.puts("done.\n")

      @stdout.puts("Successfully started up cucumber-chef test lab!")

      info
    else
      @stdout.puts("Failed to start up cucumber-chef test lab!")
    end
  else
    @stdout.puts("There are no available cucumber-chef test labs to start up!")
  end

rescue Exception => e
  $logger.fatal { e.message }
  $logger.fatal { e.backtrace.join("\n") }
  raise TestLabError, e.message
end

#stopObject



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/cucumber/chef/test_lab.rb', line 155

def stop
  if (lab_exists? && (@server = labs_running.first))
    if @server.stop
      @stdout.puts("Successfully shutdown cucumber-chef test lab!")
    else
      @stdout.puts("Failed to shutdown cucumber-chef test lab!")
    end
  else
    @stdout.puts("There are no available cucumber-chef test labs top shutdown!")
  end

rescue Exception => e
  $logger.fatal { e.message }
  $logger.fatal { e.backtrace.join("\n") }
  raise TestLabError, e.message
end