simple_perf 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *.swp
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use ruby-1.9.3-p385@simple_perf --create
data/CHANGELOG ADDED
@@ -0,0 +1 @@
1
+ ## HEAD
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in simple_perf.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Intuit Inc
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,27 @@
1
+ I use CAP for distributed jmeter performance testing in AWS EC2.
2
+
3
+ Getting Started
4
+ ---------------
5
+
6
+ Install the gem
7
+
8
+ ```
9
+ gem install simple_perf
10
+ ```
11
+
12
+ Create a file **~/.simple_deploy.yml** and include within it:
13
+
14
+ ```
15
+ environments:
16
+ preprod_shared_us_east_1:
17
+ access_key: XXX
18
+ secret_key: yyy
19
+ region: us-east-1
20
+ user: XXX (example: ec2-user)
21
+ key: ~/yyy.pem (example: ~/mykeypair.pem)
22
+ ```
23
+
24
+ Commands
25
+ --------
26
+
27
+ For a list of commands, run simple_perf -h. To get more information about each subcommand, append a -h after the subcommand. For example: **simple_perf status -h**.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ desc 'Run specs'
5
+
6
+ RSpec::Core::RakeTask.new do |t|
7
+ t.rspec_opts = %w(--color)
8
+ end
data/bin/simple_perf ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'simple_perf'
4
+ require 'simple_perf/cli'
5
+
6
+ SimplePerf::CLI.start
@@ -0,0 +1,52 @@
1
+ require 'trollop'
2
+
3
+ module SimplePerf
4
+ module CLI
5
+ class Chaos
6
+ include Shared
7
+
8
+ def execute
9
+ opts = Trollop::options do
10
+ version SimplePerf::VERSION
11
+ banner <<-EOS
12
+
13
+ Randomly terminates an instance in the specified stack
14
+
15
+ Usage:
16
+ simple_perf chaos -e ENVIRONMENT -n STACK_NAME
17
+ EOS
18
+ opt :help, "Display Help"
19
+ opt :environment, "Set the target environment", :type => :string
20
+ opt :name, "Stack name to manage", :type => :string
21
+ end
22
+ Trollop::die :environment, "is required but not specified" unless opts[:environment]
23
+ Trollop::die :name, "is required but not specified" unless opts[:name]
24
+
25
+ config = Config.new.environment opts[:environment]
26
+
27
+ command = 'simple_deploy instances' +
28
+ ' -e ' + opts[:environment] +
29
+ ' -n ' + opts[:name]
30
+
31
+ output = `#{command}`
32
+ output.gsub!(/\r\n?/, "\n")
33
+ list = output.split("\n")
34
+ target = list.sample
35
+
36
+ puts "Target locked: " + target
37
+
38
+ AWS.config(
39
+ :access_key_id => config['access_key'],
40
+ :secret_access_key => config['secret_key'])
41
+
42
+ ec2 = AWS::EC2.new(:region => config['region'])
43
+ ec2.instances.each do |i|
44
+ if(i.ip_address == target)
45
+ puts "Terminating instance: " + target
46
+ i.terminate
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,55 @@
1
+ require 'trollop'
2
+
3
+ module SimplePerf
4
+ module CLI
5
+ class Create
6
+ include Shared
7
+
8
+ def execute
9
+ opts = Trollop::options do
10
+ version SimplePerf::VERSION
11
+ banner <<-EOS
12
+
13
+ Creates CloudFormation stack for JMeter instances.
14
+
15
+ Usage:
16
+ simple_perf create -e ENVIRONMENT -n STACK_NAME -a AMI -i INSTANCE_TYPE -s S3_BUCKET
17
+ EOS
18
+ opt :help, "Display Help"
19
+ opt :environment, "Set the target environment", :type => :string
20
+ opt :name, "Stack name to manage", :type => :string
21
+ opt :ami, "AWS ami", :type => :string
22
+ opt :instancetype, "AWS instance type", :type => :string
23
+ opt :s3bucket, "AWS s3 bucket", :type => :string
24
+ end
25
+ Trollop::die :environment, "is required but not specified" unless opts[:environment]
26
+ Trollop::die :name, "is required but not specified" unless opts[:name]
27
+ Trollop::die :ami, "is required but not specified" unless opts[:ami]
28
+ Trollop::die :instancetype, "is required but not specified" unless opts[:instancetype]
29
+ Trollop::die :s3bucket, "is required but not specified" unless opts[:s3bucket]
30
+
31
+ gem_root = File.expand_path '../..', __FILE__
32
+
33
+ config = Config.new.environment opts[:environment]
34
+
35
+ command = 'simple_deploy create' +
36
+ ' -e ' + opts[:environment] +
37
+ ' -n ' + opts[:name] +
38
+ ' -t '+ gem_root + '/cloud_formation_templates/instance_group.json' +
39
+ ' -a Description="EC2 JMeter Instance"' +
40
+ ' -a KeyName=' + extract_keyname(config['key']) +
41
+ ' -a AmiId=' + opts[:ami] +
42
+ ' -a S3BucketName=' + opts[:s3bucket] +
43
+ ' -a InstanceType=' + opts[:instancetype]
44
+
45
+ Shared::pretty_print `#{command}`
46
+ end
47
+
48
+ def extract_keyname(fullpath_keypair)
49
+ a = fullpath_keypair.split('/')
50
+ a[a.length-1].sub('.pem', '')
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,51 @@
1
+ require 'trollop'
2
+
3
+ module SimplePerf
4
+ module CLI
5
+ class CreateBucket
6
+ def execute
7
+ opts = Trollop::options do
8
+ version SimplePerf::VERSION
9
+ banner <<-EOS
10
+
11
+ Creates CloudFormation stack for s3 bucket.
12
+
13
+ Usage:
14
+ simple_perf create_bucket -e ENVIRONMENT -n STACK_NAME
15
+ EOS
16
+ opt :help, "Display Help"
17
+ opt :environment, "Set the target environment", :type => :string
18
+ opt :name, "Stack name to manage", :type => :string
19
+ end
20
+ Trollop::die :environment, "is required but not specified" unless opts[:environment]
21
+ Trollop::die :name, "is required but not specified" unless opts[:name]
22
+
23
+ gem_root = File.expand_path '../..', __FILE__
24
+
25
+ config = Config.new.environment opts[:environment]
26
+
27
+ command = 'simple_deploy create' +
28
+ ' -e ' + opts[:environment] +
29
+ ' -n ' + opts[:name] +
30
+ ' -t '+ gem_root + '/cloud_formation_templates/s3_bucket.json'
31
+
32
+ `#{command}`
33
+
34
+ command = 'simple_deploy outputs' +
35
+ ' -e ' + opts[:environment] +
36
+ ' -n ' + opts[:name]
37
+
38
+ (0..5).each do |i|
39
+ puts "Getting s3 bucket name..."
40
+ sleep 10
41
+ output = `#{command}`
42
+ if output.length > 0
43
+ puts output
44
+ break
45
+ end
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,91 @@
1
+ require 'trollop'
2
+ require 'aws-sdk'
3
+
4
+ module SimplePerf
5
+ module CLI
6
+ class Deploy
7
+ include Shared
8
+
9
+ def execute
10
+ opts = Trollop::options do
11
+ version SimplePerf::VERSION
12
+ banner <<-EOS
13
+
14
+ Deploys jmeter test assets (csv's and jmx) to EC2 jmeter instances.
15
+
16
+ Usage:
17
+ simple_perf deploy -e ENVIRONMENT -n STACK_NAME
18
+ EOS
19
+ opt :help, "Display Help"
20
+ opt :environment, "Set the target environment", :type => :string
21
+ opt :name, "Stack name to manage", :type => :string
22
+ end
23
+ Trollop::die :environment, "is required but not specified" unless opts[:environment]
24
+ Trollop::die :name, "is required but not specified" unless opts[:name]
25
+
26
+ file_name = 'test.zip'
27
+
28
+ `#{'zip ' + file_name + ' *'}`
29
+
30
+ config = Config.new.environment opts[:environment]
31
+
32
+ ENV['SIMPLE_DEPLOY_SSH_KEY'] = config['key']
33
+ ENV['SIMPLE_DEPLOY_SSH_USER'] = config['user']
34
+
35
+ AWS.config(
36
+ :access_key_id => config['access_key'],
37
+ :secret_access_key => config['secret_key'])
38
+
39
+ #TODO - This is a bad idea...there could be multiple stacks with s3 in the name...fix later
40
+ command = 'simple_deploy list' +
41
+ ' -e ' + opts[:environment] +
42
+ ' | grep s3'
43
+ bucket_stack = `#{command}`
44
+
45
+ command = 'simple_deploy outputs' +
46
+ ' -e ' + opts[:environment] +
47
+ ' -n ' + bucket_stack
48
+ bucket_name = `#{command}`
49
+ bucket_name = bucket_name.split(' ')[1]
50
+
51
+ if(config['region'] == 'us-east-1')
52
+ s3_endpoint = 's3.amazonaws.com'
53
+ else
54
+ s3_endpoint = "s3-#{config['region']}.amazonaws.com"
55
+ end
56
+
57
+ s3 = AWS::S3.new(:s3_endpoint => s3_endpoint)
58
+
59
+ # create a bucket
60
+ #b = s3.buckets.create(bucket_name)
61
+
62
+ # use existing s3 bucket
63
+ b = s3.buckets[bucket_name] # no request made
64
+
65
+ # upload a file
66
+ basename = File.basename(file_name)
67
+ o = b.objects[basename]
68
+ o.write(:file => file_name)
69
+
70
+ puts "Uploaded #{file_name} to:"
71
+ puts o.public_url
72
+
73
+ command = 'simple_deploy execute' +
74
+ ' -e ' + opts[:environment] +
75
+ ' -n ' + opts[:name] +
76
+ ' -c "~/sync_jmeter_files.sh"' +
77
+ ' -l debug'
78
+
79
+ Shared::pretty_print `#{command}`
80
+
81
+ command = 'simple_deploy execute' +
82
+ ' -e ' + opts[:environment] +
83
+ ' -n ' + opts[:name] +
84
+ ' -c "cd ~/jmeter_test_files; unzip -o "' + file_name +
85
+ ' -l debug'
86
+
87
+ Shared::pretty_print `#{command}`
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,33 @@
1
+ require 'trollop'
2
+
3
+ module SimplePerf
4
+ module CLI
5
+ class Destroy
6
+ include Shared
7
+
8
+ def execute
9
+ opts = Trollop::options do
10
+ version SimplePerf::VERSION
11
+ banner <<-EOS
12
+
13
+ Destroys CloudFormation stack.
14
+
15
+ Usage:
16
+ simple_perf destroy -e ENVIRONMENT -n STACK_NAME
17
+ EOS
18
+ opt :help, "Display Help"
19
+ opt :environment, "Set the target environment", :type => :string
20
+ opt :name, "Stack name to manage", :type => :string
21
+ end
22
+ Trollop::die :environment, "is required but not specified" unless opts[:environment]
23
+ Trollop::die :name, "is required but not specified" unless opts[:name]
24
+
25
+ command = 'simple_deploy destroy' +
26
+ ' -e ' + opts[:environment] +
27
+ ' -n ' + opts[:name]
28
+
29
+ Shared::pretty_print `#{command}`
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,42 @@
1
+ require 'trollop'
2
+
3
+ module SimplePerf
4
+ module CLI
5
+ class Results
6
+ include Shared
7
+
8
+ def execute
9
+ opts = Trollop::options do
10
+ version SimplePerf::VERSION
11
+ banner <<-EOS
12
+
13
+ Display JMeter log file results.
14
+
15
+ Usage:
16
+ simple_perf results -e ENVIRONMENT -n STACK_NAME
17
+ EOS
18
+ opt :help, "Display Help"
19
+ opt :environment, "Set the target environment", :type => :string
20
+ opt :name, "Stack name to manage", :type => :string
21
+ end
22
+ Trollop::die :environment, "is required but not specified" unless opts[:environment]
23
+ Trollop::die :name, "is required but not specified" unless opts[:name]
24
+
25
+ config = Config.new.environment opts[:environment]
26
+
27
+ ENV['SIMPLE_DEPLOY_SSH_KEY'] = config['key']
28
+ ENV['SIMPLE_DEPLOY_SSH_USER'] = config['user']
29
+
30
+ grep_command = %q['grep "Generate Summary Results +" /home/ec2-user/jmeter_test_files/jmeter.log | tail -n 3']
31
+
32
+ command = 'simple_deploy execute' +
33
+ ' -e ' + opts[:environment] +
34
+ ' -n ' + opts[:name] +
35
+ ' -c ' + grep_command +
36
+ ' -l debug'
37
+
38
+ Shared::pretty_print `#{command}`
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,15 @@
1
+ module SimplePerf
2
+ module CLI
3
+ module Shared
4
+
5
+ def self.pretty_print(output)
6
+ output.gsub!(/\r\n?/, "\n")
7
+
8
+ output.each_line { |line|
9
+ puts line.split(" : ")[1]
10
+ }
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,42 @@
1
+ require 'trollop'
2
+
3
+ module SimplePerf
4
+ module CLI
5
+ class Start
6
+ include Shared
7
+
8
+ def execute
9
+ opts = Trollop::options do
10
+ version SimplePerf::VERSION
11
+ banner <<-EOS
12
+
13
+ Starts JMeter java processes.
14
+
15
+ Usage:
16
+ simple_perf start -e ENVIRONMENT -n STACK_NAME -t JMETER_TEST_PLAN
17
+ EOS
18
+ opt :help, "Display Help"
19
+ opt :environment, "Set the target environment", :type => :string
20
+ opt :name, "Stack name to manage", :type => :string
21
+ opt :testplan, "JMeter Test Plan (.jmx file)", :type => :string
22
+ end
23
+ Trollop::die :environment, "is required but not specified" unless opts[:environment]
24
+ Trollop::die :name, "is required but not specified" unless opts[:name]
25
+ Trollop::die :testplan, "is required but not specified" unless opts[:testplan]
26
+
27
+ config = Config.new.environment opts[:environment]
28
+
29
+ ENV['SIMPLE_DEPLOY_SSH_KEY'] = config['key']
30
+ ENV['SIMPLE_DEPLOY_SSH_USER'] = config['user']
31
+
32
+ command = 'simple_deploy execute' +
33
+ ' -e ' + opts[:environment] +
34
+ ' -n ' + opts[:name] +
35
+ ' -c "cd ~/jmeter_test_files; nohup jmeter -Dsun.net.inetaddr.ttl=60 -n -t ' + opts[:testplan] + ' </dev/null >/dev/null 2>&1 &"' +
36
+ ' -l debug'
37
+
38
+ Shared::pretty_print `#{command}`
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,40 @@
1
+ require 'trollop'
2
+
3
+ module SimplePerf
4
+ module CLI
5
+ class Status
6
+ include Shared
7
+
8
+ def execute
9
+ opts = Trollop::options do
10
+ version SimplePerf::VERSION
11
+ banner <<-EOS
12
+
13
+ Display JMeter army process status
14
+
15
+ Usage:
16
+ simple_perf status -e ENVIRONMENT -n STACK_NAME
17
+ EOS
18
+ opt :help, "Display Help"
19
+ opt :environment, "Set the target environment", :type => :string
20
+ opt :name, "Stack name to manage", :type => :string
21
+ end
22
+ Trollop::die :environment, "is required but not specified" unless opts[:environment]
23
+ Trollop::die :name, "is required but not specified" unless opts[:name]
24
+
25
+ config = Config.new.environment opts[:environment]
26
+
27
+ ENV['SIMPLE_DEPLOY_SSH_KEY'] = config['key']
28
+ ENV['SIMPLE_DEPLOY_SSH_USER'] = config['user']
29
+
30
+ command = 'simple_deploy execute' +
31
+ ' -e ' + opts[:environment] +
32
+ ' -n ' + opts[:name] +
33
+ ' -c "ps -ef | grep java | grep -v grep || echo \"jmeter process not found\""' +
34
+ ' -l debug'
35
+
36
+ Shared::pretty_print `#{command}`
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,40 @@
1
+ require 'trollop'
2
+
3
+ module SimplePerf
4
+ module CLI
5
+ class Stop
6
+ include Shared
7
+
8
+ def execute
9
+ opts = Trollop::options do
10
+ version SimplePerf::VERSION
11
+ banner <<-EOS
12
+
13
+ Stops the current test by killing JMeter java processes.
14
+
15
+ Usage:
16
+ simple_perf stop -e ENVIRONMENT -n STACK_NAME
17
+ EOS
18
+ opt :help, "Display Help"
19
+ opt :environment, "Set the target environment", :type => :string
20
+ opt :name, "Stack name to manage", :type => :string
21
+ end
22
+ Trollop::die :environment, "is required but not specified" unless opts[:environment]
23
+ Trollop::die :name, "is required but not specified" unless opts[:name]
24
+
25
+ config = Config.new.environment opts[:environment]
26
+
27
+ ENV['SIMPLE_DEPLOY_SSH_KEY'] = config['key']
28
+ ENV['SIMPLE_DEPLOY_SSH_USER'] = config['user']
29
+
30
+ command = 'simple_deploy execute' +
31
+ ' -e ' + opts[:environment] +
32
+ ' -n ' + opts[:name] +
33
+ ' -c "killall java"' +
34
+ ' -l debug'
35
+
36
+ Shared::pretty_print `#{command}`
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,37 @@
1
+ require 'trollop'
2
+
3
+ module SimplePerf
4
+ module CLI
5
+ class Update
6
+ include Shared
7
+
8
+ def execute
9
+ opts = Trollop::options do
10
+ version SimplePerf::VERSION
11
+ banner <<-EOS
12
+
13
+ Updates CloudFormation stack parameters.
14
+
15
+ Usage:
16
+ simple_perf update -e ENVIRONMENT -n STACK_NAME -c COUNT
17
+ EOS
18
+ opt :help, "Display Help"
19
+ opt :environment, "Set the target environment", :type => :string
20
+ opt :name, "Stack name to manage", :type => :string
21
+ opt :count, "Number of jmeter instances", :type => :string
22
+ end
23
+ Trollop::die :environment, "is required but not specified" unless opts[:environment]
24
+ Trollop::die :name, "is required but not specified" unless opts[:name]
25
+ Trollop::die :count, "is required but not specified" unless opts[:count]
26
+
27
+ command = 'simple_deploy update' +
28
+ ' -e ' + opts[:environment] +
29
+ ' -n ' + opts[:name] +
30
+ ' -a MinimumInstances=' + opts[:count] +
31
+ ' -a MaximumInstances=' + opts[:count]
32
+
33
+ Shared::pretty_print `#{command}`
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,56 @@
1
+ require 'trollop'
2
+
3
+ require 'simple_perf/cli/shared'
4
+
5
+ require 'simple_perf/cli/start'
6
+ require 'simple_perf/cli/stop'
7
+ require 'simple_perf/cli/deploy'
8
+ require 'simple_perf/cli/create'
9
+ require 'simple_perf/cli/create_bucket'
10
+ require 'simple_perf/cli/destroy'
11
+ require 'simple_perf/cli/status'
12
+ require 'simple_perf/cli/results'
13
+ require 'simple_perf/cli/update'
14
+ require 'simple_perf/cli/chaos'
15
+
16
+ module SimplePerf
17
+ module CLI
18
+ def self.start
19
+ cmd = ARGV.shift
20
+
21
+ case cmd
22
+ when 'start'
23
+ CLI::Start.new.execute
24
+ when 'stop'
25
+ CLI::Stop.new.execute
26
+ when 'deploy'
27
+ CLI::Deploy.new.execute
28
+ when 'create'
29
+ CLI::Create.new.execute
30
+ when 'create_bucket'
31
+ CLI::CreateBucket.new.execute
32
+ when 'destroy'
33
+ CLI::Destroy.new.execute
34
+ when 'status'
35
+ CLI::Status.new.execute
36
+ when 'results'
37
+ CLI::Results.new.execute
38
+ when 'update'
39
+ CLI::Update.new.execute
40
+ when 'chaos'
41
+ CLI::Chaos.new.execute
42
+ when '-h'
43
+ puts "simple_perf [start|stop|deploy|create|create_bucket|destroy|status|results|update|chaos] [options]"
44
+ puts "Append -h for help on specific subcommand."
45
+ when '-v'
46
+ puts SimplePerf::VERSION
47
+ else
48
+ puts "Unknown command: '#{cmd}'."
49
+ puts "simple_perf [start|stop|deploy|create|create_bucket|destroy|status|results|update|chaos] [options]"
50
+ puts "Append -h for help on specific subcommand."
51
+ exit 1
52
+ end
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,306 @@
1
+ {
2
+ "AWSTemplateFormatVersion": "2010-09-09",
3
+ "Description": "Simple Perf Instance Group",
4
+
5
+ "Parameters": {
6
+
7
+ "MaximumInstances": {
8
+ "Type": "String",
9
+ "Description": "Maximum number of app instances",
10
+ "Default": "1"
11
+ },
12
+ "MinimumInstances": {
13
+ "Type": "String",
14
+ "Description": "Minimum number of app instances",
15
+ "Default": "1"
16
+ },
17
+ "AmiId" : {
18
+ "Description" : "Ami to provision",
19
+ "Type" : "String"
20
+ },
21
+ "KeyName": {
22
+ "Description": "Name of EC2 key pair to use",
23
+ "Type": "String"
24
+ },
25
+ "InstanceType" : {
26
+ "Description" : "EC2 instance type",
27
+ "Type" : "String",
28
+ "Default" : "m1.medium",
29
+ "AllowedValues" : [ "m1.small","m1.medium","m1.large","m1.xlarge",
30
+ "m3.xlarge", "m3.2xlarge", "c1.xlarge" ],
31
+ "ConstraintDescription" : "must be a valid EC2 instance type."
32
+ },
33
+ "S3BucketName": {
34
+ "Description": "Name of S3 bucket",
35
+ "Type": "String"
36
+ },
37
+ "Abort": {
38
+ "Description": "Should the entire deployment be aborted if bootstraping fails?",
39
+ "Type": "String",
40
+ "Default": "yes",
41
+ "AllowedValues": [ "yes", "no" ],
42
+ "ConstraintDescription": "yes or no"
43
+ }
44
+ },
45
+
46
+ "Mappings": {
47
+ "BootstrapSettingMap": {
48
+ "abort": { "yes": "$?", "no": "0" }
49
+ },
50
+ "S3Map": {
51
+ "us-east-1": { "s3": "s3:/",
52
+ "http": "http://s3.amazonaws.com",
53
+ "https": "https://s3.amazonaws.com",
54
+ "endpoint": "s3.amazonaws.com"
55
+ },
56
+ "us-west-1": { "s3": "s3:/",
57
+ "http": "http://s3-us-west-1.amazonaws.com",
58
+ "https": "https://s3-us-west-1.amazonaws.com",
59
+ "endpoint": "s3-us-west-1.amazonaws.com"
60
+ },
61
+ "us-west-2": { "s3": "s3:/",
62
+ "http": "http://s3-us-west-2.amazonaws.com",
63
+ "https": "https://s3-us-west-2.amazonaws.com",
64
+ "endpoint": "s3-us-west-2.amazonaws.com"
65
+ }
66
+ }
67
+ },
68
+
69
+ "Resources": {
70
+ "User": {
71
+ "Type": "AWS::IAM::User",
72
+ "Properties": {
73
+ "Path": "/",
74
+ "Policies": [{
75
+ "PolicyName": "user_resource_access",
76
+ "PolicyDocument": {
77
+ "Statement":[
78
+ {
79
+ "Effect": "Allow",
80
+ "Action": "cloudformation:DescribeStackResource",
81
+ "Resource": "*"
82
+ },
83
+ {
84
+ "Effect": "Allow",
85
+ "Action": ["s3:ListAllMyBuckets"],
86
+ "Resource": "arn:aws:s3:::*"
87
+ },
88
+ {
89
+ "Effect": "Allow",
90
+ "Action": ["s3:*"],
91
+ "Resource": [ { "Fn::Join": [ "", [ "arn:aws:s3:::",
92
+ { "Ref": "S3BucketName" } ] ] },
93
+ { "Fn::Join": [ "", [ "arn:aws:s3:::",
94
+ { "Ref": "S3BucketName" }, "/*" ] ] }
95
+ ]
96
+ }
97
+ ]
98
+
99
+ }
100
+ }]
101
+ }
102
+ },
103
+
104
+ "UserKey": {
105
+ "Type": "AWS::IAM::AccessKey",
106
+ "Properties": {
107
+ "UserName": {"Ref": "User"}
108
+ }
109
+ },
110
+
111
+ "Instances": {
112
+ "Type": "AWS::AutoScaling::AutoScalingGroup",
113
+ "Properties": {
114
+ "AvailabilityZones": { "Fn::GetAZs": "" },
115
+ "LaunchConfigurationName": { "Ref": "InstanceLaunchConfig" },
116
+ "MaxSize": { "Ref": "MaximumInstances" },
117
+ "MinSize": { "Ref": "MinimumInstances" },
118
+ "Tags": [ {
119
+ "Key": "Name",
120
+ "Value": { "Ref": "AWS::StackName" } ,
121
+ "PropagateAtLaunch": "true" }
122
+ ]
123
+ }
124
+ },
125
+
126
+ "InstanceLaunchConfig": {
127
+ "Type": "AWS::AutoScaling::LaunchConfiguration",
128
+ "Metadata": {
129
+
130
+ "AWS::CloudFormation::Init": {
131
+
132
+ "configSets": {
133
+ "default": [ "base", "s3cmd", "jmeter" ]
134
+ },
135
+
136
+ "base": {
137
+
138
+ "files": {
139
+ "/etc/yum.repos.d/intu-packages.repo": {
140
+ "content": { "Fn::Join": [ "", [
141
+ "[intu-packages-", { "Ref": "AWS::Region" }, "]\n",
142
+ "name=Intuit Custom RPM Packages\n",
143
+ "baseurl=",
144
+ { "Fn::FindInMap": [ "S3Map", { "Ref": "AWS::Region" }, "http" ] },
145
+ "/intu-packages-", { "Ref": "AWS::Region" }, "/rhel/6/x86_64\n",
146
+ "gpgcheck=0\n",
147
+ "enabled=1\n"
148
+ ] ] },
149
+ "owner": "root",
150
+ "group": "root",
151
+ "mode": "000644"
152
+ }
153
+
154
+ }
155
+
156
+ },
157
+
158
+ "s3cmd": {
159
+
160
+ "files": {
161
+
162
+ "/home/ec2-user/.s3cfg": {
163
+ "content": { "Fn::Join": ["", [
164
+ "access_key = ", { "Ref": "UserKey" }, "\n",
165
+ "secret_key = ", {"Fn::GetAtt": ["UserKey", "SecretAccessKey"]}, "\n"
166
+ ]]},
167
+ "mode" : "000400",
168
+ "owner" : "ec2-user",
169
+ "group" : "ec2-user"
170
+ },
171
+
172
+ "/root/.s3cfg": {
173
+ "content": { "Fn::Join": ["", [
174
+ "access_key = ", { "Ref": "UserKey" }, "\n",
175
+ "secret_key = ", {"Fn::GetAtt": ["UserKey", "SecretAccessKey"]}, "\n"
176
+ ]]},
177
+ "mode" : "000400",
178
+ "owner" : "ec2-user",
179
+ "group" : "ec2-user"
180
+ }
181
+
182
+ },
183
+
184
+ "packages": {
185
+ "yum": {
186
+ "s3cmd": []
187
+ }
188
+ }
189
+
190
+ },
191
+
192
+ "jmeter": {
193
+
194
+ "commands": {
195
+
196
+ "jmeter_batch_mode": {
197
+ "command": "sed -i 's/#mode=Batch/mode=Batch/' /opt/jakarta-jmeter/bin/jmeter.properties"
198
+ },
199
+
200
+ "jmeter_rmi_enable": {
201
+ "command": "sed -i 's/#server.rmi.localport=4000/server.rmi.localport=4000/' /opt/jakarta-jmeter/bin/jmeter.properties"
202
+ },
203
+
204
+ "jmeter_disable_cookie_check": {
205
+ "command": "sed -i 's/#CookieManager.check.cookies=true/CookieManager.check.cookies=false/' /opt/jakarta-jmeter/bin/jmeter.properties"
206
+ }
207
+
208
+ },
209
+
210
+ "files": {
211
+
212
+ "/etc/profile.d/jmeter.sh": {
213
+ "content": { "Fn::Join": [ "", [ "export JMETER_HOME=/opt/jakarta-jmeter", "\n",
214
+ "export PATH=/opt/jakarta-jmeter/bin:$PATH" ] ] },
215
+ "owner": "root",
216
+ "group": "root",
217
+ "mode": "000644"
218
+ },
219
+
220
+ "/home/ec2-user/sync_jmeter_files.sh": {
221
+ "content": { "Fn::Join": [ "", [ "#!/bin/bash", "\n",
222
+ "mkdir -p ~/jmeter_test_files", "\n",
223
+ "cd ~/jmeter_test_files", "\n",
224
+ "s3cmd sync s3://",
225
+ { "Ref": "S3BucketName" },
226
+ " ." ] ] },
227
+ "owner": "ec2-user",
228
+ "group": "ec2-user",
229
+ "mode": "000770"
230
+ }
231
+
232
+ },
233
+
234
+ "packages": {
235
+ "yum": {
236
+ "intu-jakarta-jmeter": [ "2.5.1" ]
237
+ }
238
+ }
239
+
240
+ }
241
+ }
242
+ },
243
+
244
+ "Properties": {
245
+ "KeyName" : { "Ref": "KeyName" },
246
+ "ImageId" : { "Ref" : "AmiId" },
247
+ "InstanceType": { "Ref": "InstanceType" },
248
+ "SecurityGroups": [ { "Ref": "InstancesSecurityGroup" } ],
249
+ "UserData": { "Fn::Base64": { "Fn::Join": ["", [
250
+ "#!/bin/bash\n",
251
+
252
+ "chmod 644 /etc/resolv.conf", "\n",
253
+
254
+ "if [ -f /etc/yum.repos.d/intu-packages-us-west-1.repo ]; then", "\n",
255
+ "rm -f /etc/yum.repos.d/intu-packages-us-west-1.repo", "\n",
256
+ "fi", "\n",
257
+
258
+ "/opt/aws/bin/cfn-init ",
259
+ " -s ", { "Ref": "AWS::StackName" },
260
+ " -r InstanceLaunchConfig",
261
+ " --region=", { "Ref": "AWS::Region" },
262
+ " --access-key=", { "Ref": "UserKey" },
263
+ " --secret-key=", { "Fn::GetAtt": ["UserKey", "SecretAccessKey"] }, "\n",
264
+
265
+ "runuser -c \"~/sync_jmeter_files.sh\" ec2-user", "\n",
266
+
267
+ "/opt/aws/bin/cfn-signal -e ",
268
+ { "Fn::FindInMap": [ "BootstrapSettingMap", "abort", { "Ref": "Abort" } ] },
269
+ " '", { "Ref": "InstancesWaitHandle" }, "'\n"
270
+ ]]}}
271
+ }
272
+ },
273
+
274
+ "InstancesSecurityGroup": {
275
+ "Type": "AWS::EC2::SecurityGroup",
276
+ "Properties": {
277
+ "GroupDescription": "Security Group for the app the instance",
278
+ "SecurityGroupIngress": [
279
+ {
280
+ "IpProtocol" : "tcp",
281
+ "FromPort" : "22",
282
+ "ToPort" : "22",
283
+ "CidrIp" : "0.0.0.0/0"
284
+ }
285
+ ]
286
+ }
287
+ },
288
+
289
+ "InstancesWaitHandle": {
290
+ "Type": "AWS::CloudFormation::WaitConditionHandle",
291
+ "Properties": {}
292
+ },
293
+
294
+ "InstancesWaitCondition": {
295
+ "Type": "AWS::CloudFormation::WaitCondition",
296
+ "DependsOn": [ "InstanceLaunchConfig" ],
297
+ "Properties": {
298
+ "Handle": { "Ref": "InstancesWaitHandle" },
299
+ "Count": "1",
300
+ "Timeout": "900"
301
+ }
302
+ }
303
+
304
+ }
305
+
306
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "AWSTemplateFormatVersion": "2010-09-09",
3
+ "Description": "Simple Perf S3 Bucket",
4
+
5
+ "Resources": {
6
+
7
+ "S3Bucket": {
8
+ "Type" : "AWS::S3::Bucket"
9
+ }
10
+
11
+ },
12
+
13
+ "Outputs": {
14
+ "S3Bucket": {
15
+ "Value": { "Ref": "S3Bucket" },
16
+ "Description": "S3 Bucket Name"
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,50 @@
1
+ module SimplePerf
2
+ class Config
3
+
4
+ attr_accessor :config
5
+
6
+ def initialize(args = {})
7
+ load_config_file
8
+ end
9
+
10
+ def environments
11
+ config['environments']
12
+ end
13
+
14
+ def environment(name)
15
+ raise "Environment not found" unless environments.include? name
16
+ environments[name]
17
+ end
18
+
19
+ def notifications
20
+ config['notifications']
21
+ end
22
+
23
+ def region(name)
24
+ environment(name)['region']
25
+ end
26
+
27
+ private
28
+
29
+ def load_config_file
30
+ config_file = "#{ENV['HOME']}/.simple_deploy.yml"
31
+
32
+ begin
33
+ self.config = YAML::load( File.open( config_file ) )
34
+ rescue Errno::ENOENT
35
+ raise "#{config_file} not found"
36
+ rescue Psych::SyntaxError => e
37
+ raise "#{config_file} is corrupt"
38
+ end
39
+ end
40
+
41
+ def env_home
42
+ ENV['HOME']
43
+ end
44
+
45
+ def env_user
46
+ ENV['USER']
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,3 @@
1
+ module SimplePerf
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,2 @@
1
+ require 'simple_perf/config'
2
+ require 'simple_perf/version'
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "simple_perf/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "simple_perf"
7
+ s.version = SimplePerf::VERSION
8
+ s.authors = ["Jimmy Armitage"]
9
+ s.email = ["mrjimmy410@gmail.com"]
10
+ s.homepage = "http://www.example.com"
11
+ s.summary = %q{I help with performance testing}
12
+ s.description = %q{I am designed to control a JMeter army of AWS EC2 instances}
13
+
14
+ s.rubyforge_project = "simple_perf"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "rake"
22
+ s.add_development_dependency "rspec", "~> 2.11.0"
23
+
24
+ s.add_runtime_dependency "trollop", "2.0"
25
+ s.add_runtime_dependency "simple_deploy", "0.7.2"
26
+ s.add_runtime_dependency "aws-sdk", ">= 1.9.5"
27
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'simple_perf'
5
+
6
+ RSpec.configure do |config|
7
+ #spec config
8
+ end
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple_perf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jimmy Armitage
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 2.11.0
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 2.11.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: trollop
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - '='
52
+ - !ruby/object:Gem::Version
53
+ version: '2.0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: '2.0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: simple_deploy
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - '='
68
+ - !ruby/object:Gem::Version
69
+ version: 0.7.2
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - '='
76
+ - !ruby/object:Gem::Version
77
+ version: 0.7.2
78
+ - !ruby/object:Gem::Dependency
79
+ name: aws-sdk
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: 1.9.5
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: 1.9.5
94
+ description: I am designed to control a JMeter army of AWS EC2 instances
95
+ email:
96
+ - mrjimmy410@gmail.com
97
+ executables:
98
+ - simple_perf
99
+ extensions: []
100
+ extra_rdoc_files: []
101
+ files:
102
+ - .gitignore
103
+ - .rvmrc
104
+ - CHANGELOG
105
+ - Gemfile
106
+ - LICENSE
107
+ - README.md
108
+ - Rakefile
109
+ - bin/simple_perf
110
+ - lib/simple_perf.rb
111
+ - lib/simple_perf/cli.rb
112
+ - lib/simple_perf/cli/chaos.rb
113
+ - lib/simple_perf/cli/create.rb
114
+ - lib/simple_perf/cli/create_bucket.rb
115
+ - lib/simple_perf/cli/deploy.rb
116
+ - lib/simple_perf/cli/destroy.rb
117
+ - lib/simple_perf/cli/results.rb
118
+ - lib/simple_perf/cli/shared.rb
119
+ - lib/simple_perf/cli/start.rb
120
+ - lib/simple_perf/cli/status.rb
121
+ - lib/simple_perf/cli/stop.rb
122
+ - lib/simple_perf/cli/update.rb
123
+ - lib/simple_perf/cloud_formation_templates/instance_group.json
124
+ - lib/simple_perf/cloud_formation_templates/s3_bucket.json
125
+ - lib/simple_perf/config.rb
126
+ - lib/simple_perf/version.rb
127
+ - simple_perf.gemspec
128
+ - spec/spec_helper.rb
129
+ homepage: http://www.example.com
130
+ licenses: []
131
+ post_install_message:
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ none: false
137
+ requirements:
138
+ - - ! '>='
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ none: false
143
+ requirements:
144
+ - - ! '>='
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubyforge_project: simple_perf
149
+ rubygems_version: 1.8.25
150
+ signing_key:
151
+ specification_version: 3
152
+ summary: I help with performance testing
153
+ test_files:
154
+ - spec/spec_helper.rb