Skip to content

Commit

Permalink
[launcher] refactor and test classiclink
Browse files Browse the repository at this point in the history
in order to test classic link, we need to stub out API calls. lets factor
creating the EC2 object into a method which can be stubbed. then we add basic
specs.
  • Loading branch information
igor47 committed Jul 27, 2016
1 parent 492580c commit 8f2e169
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 34 deletions.
65 changes: 34 additions & 31 deletions lib/stemcell/launcher.rb
Expand Up @@ -8,11 +8,6 @@

module Stemcell
class Launcher

REQUIRED_OPTIONS = [
'region'
]

REQUIRED_LAUNCH_PARAMETERS = [
'chef_role',
'chef_environment',
Expand Down Expand Up @@ -71,29 +66,13 @@ def initialize(opts={})
@log.debug "creating new stemcell object"
@log.debug "opts are #{opts.inspect}"

REQUIRED_OPTIONS.each do |req|
raise ArgumentError, "missing required param #{req}" unless opts[req]
instance_variable_set("@#{req}",opts[req])
end

@ec2_url = "ec2.#{@region}.amazonaws.com"

aws_configs = {:region => @region}
aws_configs.merge!({
:access_key_id => @aws_access_key,
:secret_access_key => @aws_secret_key
}) if @aws_access_key && @aws_secret_key
AWS.config(aws_configs)

if opts['vpc_id']
puts 'using vpc tho'
@ec2 = AWS::VPC.new(opts['vpc_id'], :ec2_endpoint => @ec2_url)
else
@ec2 = AWS::EC2.new(:ec2_endpoint => @ec2_url)
end
raise ArgumentError, "missing required option 'region'" unless opts['region']
@region = opts['region']
@vpc_id = opts['vpc_id']
@aws_access_key = opts['aws_access_key']
@aws_secret_key = opts['aws_secret_key']
end


def launch(opts={})
verify_required_options(opts, REQUIRED_LAUNCH_PARAMETERS)

Expand Down Expand Up @@ -283,7 +262,7 @@ def wait(instances)
@log.info "all instances in running state"
end

def verify_required_options(params,required_options)
def verify_required_options(params, required_options)
@log.debug "params is #{params}"
@log.debug "required_options are #{required_options}"
required_options.each do |required|
Expand All @@ -296,7 +275,7 @@ def verify_required_options(params,required_options)
def do_launch(opts={})
@log.debug "about to launch instance(s) with options #{opts}"
@log.info "launching instances"
instances = @ec2.instances.create(opts)
instances = ec2.instances.create(opts)
instances = [instances] unless Array === instances
instances.each do |instance|
@log.info "launched instance #{instance.instance_id}"
Expand Down Expand Up @@ -339,12 +318,12 @@ def set_classic_link(left_to_process, classic_link)
processed += recently_running
errors += run_batch_operation(recently_running) do |instance|
begin
result = @ec2.client.attach_classic_link_vpc({
result = ec2.client.attach_classic_link_vpc({
:instance_id => instance.id,
:vpc_id => classic_link['vpc_id'],
:groups => classic_link['security_group_ids'],
})
(result.return == true) ? nil : "classic link attach request failed"
result.error
rescue StandardError => e
e
end
Expand All @@ -358,7 +337,7 @@ def enable_termination_protection(instances)
@log.info "enabling termination protection on instance(s)"
errors = run_batch_operation(instances) do |instance|
begin
resp = @ec2.client.modify_instance_attribute({
resp = ec2.client.modify_instance_attribute({
:instance_id => instance.id,
:disable_api_termination => {
:value => true
Expand Down Expand Up @@ -412,5 +391,29 @@ def check_errors(operation, instance_ids, errors)
instance_ids.zip(errors).reject { |i, e| e.nil? }
)
end

def ec2
return @ec2 if @ec2

# configure AWS with creds/region
aws_configs = {:region => @region}
aws_configs.merge!({
:access_key_id => @aws_access_key,
:secret_access_key => @aws_secret_key
}) if @aws_access_key && @aws_secret_key
AWS.config(aws_configs)

# calculate our ec2 url
ec2_url = "ec2.#{@region}.amazonaws.com"

if @vpc_id
@ec2 = AWS::VPC.new(@vpc_id, :ec2_endpoint => ec2_url)
else
@ec2 = AWS::EC2.new(:ec2_endpoint => ec2_url)
end

@ec2
end

end
end
33 changes: 30 additions & 3 deletions spec/lib/stemcell/launcher_spec.rb
Expand Up @@ -8,24 +8,51 @@ def initialize(id)
def id
@id
end

def status
:running
end
end

class MockException < StandardError
end

describe Stemcell::Launcher do
let(:launcher) {
opts = {}
Stemcell::Launcher::REQUIRED_OPTIONS.map { |k| opts[k] = "" }
opts = {'region' => 'region'}
launcher = Stemcell::Launcher.new(opts)
launcher
}
let(:operation) { 'op' }
let(:instances) { (1..4).map { |id| MockInstance.new(id) } }
let(:instance_ids) { instances.map(&:id) }

describe '#run_batch_operation' do
describe '#set_classic_link' do
let(:ec2) { instance_double(AWS::EC2) }
let(:client) { double(AWS::EC2::Client) }
let(:response) { instance_double(AWS::Core::Response) }
before do
allow(launcher).to receive(:ec2).and_return(ec2)
allow(ec2).to receive(:client).and_return(client)
allow(response).to receive(:error).and_return(nil)
end

let(:classic_link) { {'vpc_id' => 'vpc_id', 'security_group_ids' => ['sg1', 'sg2']} }

it 'invokes classic link on all of the instances' do
instances.each do |instance|
expect(client).to receive(:attach_classic_link_vpc).ordered.with(a_hash_including(
:instance_id => instance.id,
:vpc_id => classic_link['vpc_id'],
:groups => classic_link['security_group_ids'],
)).and_return(response)
end

launcher.send(:set_classic_link, instances, classic_link)
end
end

describe '#run_batch_operation' do
it "raises no exception when no internal error occur" do
errors = launcher.send(:run_batch_operation, instances) {}
expect(errors.all?(&:nil?)).to be true
Expand Down

0 comments on commit 8f2e169

Please sign in to comment.