vscripts 0.1.3 → 0.1.5

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.
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+ require 'vscripts'
3
+
4
+ describe 'Command: Identify' do
5
+ include_context 'VScripts'
6
+ include_context 'Suppressed output'
7
+ include_context 'Temporary'
8
+
9
+ subject { VScripts.run }
10
+
11
+ let(:identify) { VScripts::Commands::Identify }
12
+ let(:hostname_file) { "#{TEMP_DIR}/test-hostname" }
13
+ let(:hosts_file) { "#{TEMP_DIR}/test-hosts" }
14
+
15
+ before(:each) do
16
+ allow_any_instance_of(identify)
17
+ .to receive(:hostname_path).and_return(hostname_file)
18
+ allow_any_instance_of(identify)
19
+ .to receive(:hosts_path).and_return(hosts_file)
20
+ allow_any_instance_of(identify).to receive('`')
21
+ end
22
+
23
+ describe 'when \'--help\'' do
24
+ it 'exits and shows help' do
25
+ stub_cli_with('identify --help')
26
+ expect{subject}.to raise_error(SystemExit)
27
+ expect($stdout.string).to match(/USAGE:/)
28
+ end
29
+ end
30
+
31
+ context 'when unknown argument' do
32
+ it 'returns error with message' do
33
+ stub_cli_with('identify --xyz')
34
+ expect{subject}.to raise_error(SystemExit)
35
+ expect($stderr.string).to match(/Error: unknown argument/)
36
+ end
37
+ end
38
+
39
+ context 'when not an EC2 instance' do
40
+ include_context 'Not an EC2 Instance', VScripts::Commands::Identify
41
+ it 'returns error with message' do
42
+ stub_cli_with('identify')
43
+ expect{subject}.to raise_error(SystemExit)
44
+ expect($stderr.string)
45
+ .to match('FATAL: NOT an EC2 instance or could not connect to Metadata')
46
+ end
47
+ end
48
+
49
+ context 'when EC2 instance' do
50
+ include_context 'EC2 Instance without tags', VScripts::Commands::Identify
51
+
52
+ context 'without tags' do
53
+ it 'writes default hostname' do
54
+ stub_cli_with('identify')
55
+ allow_any_instance_of(identify).to receive(:tag)
56
+ subject
57
+ expect(IO.read(hostname_file)).to eq('1')
58
+ expect($stdout.string).to match('Done.')
59
+ end
60
+ end
61
+
62
+ context 'and when \'--ec2-tag-theme\'' do
63
+ it 'returns the themed host' do
64
+ stub_cli_with('identify --ec2-tag-theme=Test-#')
65
+ allow_any_instance_of(identify).to receive(:tag)
66
+ .and_return('TestValue')
67
+ subject
68
+ expect(IO.read(hostname_file)).to eq('TestValue-1')
69
+ end
70
+ end
71
+
72
+ context 'and when \'--host\'' do
73
+ it 'returns the new host' do
74
+ stub_cli_with('identify --host=test-host')
75
+ subject
76
+ expect(IO.read(hostname_file)).to eq('test-host')
77
+ end
78
+ end
79
+
80
+ context 'and when \'--domain\'' do
81
+ it 'returns the new domain' do
82
+ stub_cli_with('identify --domain=example.tld')
83
+ subject
84
+ expect(IO.read(hosts_file)).to match('example.tld')
85
+ end
86
+ end
87
+
88
+ context 'and when similar found' do
89
+ it 'returns the incremented host' do
90
+ stub_cli_with('identify --ec2-tag-theme=Test-#')
91
+ allow_any_instance_of(identify).to receive(:tag)
92
+ .and_return('TestName')
93
+ allow_any_instance_of(identify).to receive(:domain)
94
+ .and_return('TestDomain.tld')
95
+ subject
96
+ expect(IO.read(hostname_file)).to eq('TestName-2')
97
+ expect(IO.read(hosts_file)).to match('TestName-2.TestDomain.tld')
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+ require 'vscripts'
3
+
4
+ describe 'Command: Tags2Facts' do
5
+ include_context 'VScripts'
6
+ include_context 'Suppressed output'
7
+ include_context 'Temporary'
8
+
9
+ subject { VScripts.run }
10
+
11
+ let(:tags2facts) { VScripts::Commands::Tags2facts }
12
+
13
+ before(:each) do
14
+ stub_cli_with('tags2facts')
15
+ end
16
+
17
+ context 'when \'--help\'' do
18
+ it 'returns command specific help' do
19
+ stub_cli_with('tags2facts --help')
20
+ expect{subject}.to raise_error(SystemExit)
21
+ expect($stdout.string).to match(/USAGE:/)
22
+ expect($stdout.string).to match(/OPTIONS:/)
23
+ end
24
+ end
25
+
26
+ context 'when unknown argument' do
27
+ it 'returns error with message' do
28
+ stub_cli_with('tags2facts --xyz')
29
+ expect{subject}.to raise_error(SystemExit)
30
+ expect($stderr.string).to match(/Error: unknown argument/)
31
+ end
32
+ end
33
+
34
+ context 'when not an EC2 instance' do
35
+ include_context 'Not an EC2 Instance', VScripts::Commands::Tags2facts
36
+ it 'returns error with message' do
37
+ expect{subject}.to raise_error(SystemExit)
38
+ expect($stderr.string)
39
+ .to match('FATAL: NOT an EC2 instance or could not connect to Metadata')
40
+ end
41
+ end
42
+
43
+ context 'when EC2 instance' do
44
+ context 'without tags' do
45
+ include_context 'EC2 Instance without tags', VScripts::Commands::Tags2facts
46
+ it 'returns error with message' do
47
+ expect{subject}.to raise_error(SystemExit)
48
+ expect($stderr.string).to match(/No tags were found/)
49
+ end
50
+ end
51
+
52
+ context 'with tags' do
53
+ before(:each) do
54
+ allow_any_instance_of(tags2facts)
55
+ .to receive_message_chain('cli.file')
56
+ .and_return(test_file)
57
+ allow_any_instance_of(tags2facts)
58
+ .to receive_message_chain('cli.all').and_return(false)
59
+ end
60
+
61
+ context '--all specified' do
62
+ include_context 'EC2 Instance with tags', VScripts::Commands::Tags2facts
63
+ it 'creates file' do
64
+ stub_cli_with('tags2facts --all')
65
+ allow_any_instance_of(tags2facts)
66
+ .to receive_message_chain('cli.all').and_return(true)
67
+ subject
68
+ expect(IO.read(test_file)).to match(tags['Name'])
69
+ end
70
+ end
71
+
72
+ context '--all not specified' do
73
+ include_context 'EC2 Instance with tags', VScripts::Commands::Tags2facts
74
+ it 'creates file' do
75
+ subject
76
+ expect(IO.read(test_file)).to match(tags.keys.last)
77
+ end
78
+ end
79
+
80
+ context '--file specified' do
81
+ include_context 'EC2 Instance with tags', VScripts::Commands::Tags2facts
82
+ it 'creates file' do
83
+ stub_cli_with("tags2facts --file #{test_file}")
84
+ subject
85
+ expect(IO.read(test_file)).to match(tags.keys.last)
86
+ end
87
+ end
88
+
89
+ context '--file not specified' do
90
+ include_context 'EC2 Instance with tags', VScripts::Commands::Tags2facts
91
+ it 'creates file' do
92
+ subject
93
+ expect(IO.read(test_file)).to match(tags.keys.last)
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+ require 'vscripts'
3
+
4
+ describe 'Command: Unknown' do
5
+ include_context 'VScripts'
6
+ include_context 'Suppressed output'
7
+
8
+ it 'returns error with message' do
9
+ expect{stub_cli_with('xyz')}.to raise_error(SystemExit)
10
+ expect($stderr.string).to match(/Error: unknown subcommand/)
11
+ end
12
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+ require 'vscripts'
3
+
4
+ describe 'Configuration' do
5
+ let(:dotcfg) { "#{File.expand_path('~')}/.vscripts.yml" }
6
+ let(:syscfg) { '/etc/vscripts/config.yml' }
7
+
8
+ subject { VScripts::Config.new }
9
+
10
+ before(:each) do
11
+ allow(File).to receive(:read).with(dotcfg)
12
+ .and_return('loaded: dot_file')
13
+ allow(File).to receive(:read).with(syscfg)
14
+ .and_return('loaded: sys_file')
15
+ end
16
+
17
+ it 'loads the configuration' do
18
+ expect(subject.get).to be_a Hash
19
+ end
20
+
21
+ context 'and if a config file exists' do
22
+ it 'returns an empty hash if file is empty' do
23
+ allow(File).to receive(:exist?).and_return(false)
24
+ expect(subject.get).to be_empty
25
+ end
26
+ it 'returns a hash if file not empty' do
27
+ allow(File).to receive(:exist?).and_return(true)
28
+ expect(subject.get).to be_a Hash
29
+ expect(subject.get).not_to be_empty
30
+ end
31
+ end
32
+
33
+ context 'and if both files exist' do
34
+ it 'returns the command line configuration first' do
35
+ allow(File).to receive(:exist?).and_return(true)
36
+ allow(File).to receive(:read)
37
+ .and_return('---\nloaded: cli_file')
38
+ expect(subject.get).to be_a Hash
39
+ expect(subject.get.values.first).to eq('cli_file')
40
+ end
41
+
42
+ it 'returns the dotfiles second' do
43
+ allow(File).to receive(:exist?).with(dotcfg).and_return(true)
44
+ allow(File).to receive(:exist?).with(syscfg).and_return(true)
45
+ expect(subject.get).to be_a Hash
46
+ expect(subject.get.values.first).to eq('dot_file')
47
+ end
48
+
49
+ it 'and system file second third' do
50
+ allow(File).to receive(:exist?).with(dotcfg).and_return(false)
51
+ allow(File).to receive(:exist?).with(syscfg).and_return(true)
52
+ expect(subject.get).to be_a Hash
53
+ expect(subject.get.values.first).to eq('sys_file')
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+ require 'vscripts'
3
+
4
+ describe 'Global Options' do
5
+ include_context 'VScripts'
6
+ include_context 'Suppressed output'
7
+
8
+ subject { VScripts.run }
9
+
10
+ describe 'Help' do
11
+ context 'when \'-h\'' do
12
+ it 'returns help and exits' do
13
+ expect{stub_cli_with('-h')}.to raise_error(SystemExit)
14
+ expect($stdout.string).to match(/Available commands/)
15
+ end
16
+ end
17
+
18
+ context 'when \'--help\'' do
19
+ it 'returns help and exits' do
20
+ expect{stub_cli_with('--help')}.to raise_error(SystemExit)
21
+ expect($stdout.string).to match(/Available commands/)
22
+ end
23
+ end
24
+ end
25
+
26
+ describe 'Version' do
27
+ context 'when \'-v\'' do
28
+ it 'returns version and exits' do
29
+ expect{stub_cli_with('-v')}.to raise_error(SystemExit)
30
+ expect($stdout.string).to match(/VScripts.*(c)/)
31
+ end
32
+ end
33
+
34
+ context 'when \'--version\'' do
35
+ it 'returns version and exits' do
36
+ expect{stub_cli_with('--version')}.to raise_error(SystemExit)
37
+ expect($stdout.string).to match(/VScripts.*(c)/)
38
+ end
39
+ end
40
+ end
41
+ describe 'Unknown argument' do
42
+ context 'when short' do
43
+ it 'returns error with message' do
44
+ expect{stub_cli_with('-z')}.to raise_error(SystemExit)
45
+ expect($stderr.string).to match(/Error: unknown argument/)
46
+ end
47
+ end
48
+
49
+ context 'when long' do
50
+ it 'returns error with message' do
51
+ expect{stub_cli_with('--xyz')}.to raise_error(SystemExit)
52
+ expect($stderr.string).to match(/Error: unknown argument/)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -2,6 +2,8 @@
2
2
  require 'coveralls'
3
3
  Coveralls.wear!
4
4
 
5
+ TEMP_DIR = File.join(File.dirname(__FILE__),'..','tmp')
6
+
5
7
  # Development code coverage
6
8
  SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
7
9
  Coveralls::SimpleCov::Formatter,
@@ -19,13 +21,135 @@ RSpec.configure {|config|
19
21
  # Use color not only in STDOUT but also in pagers and files
20
22
  config.tty = true
21
23
 
24
+ # Show test times
25
+ config.profile_examples = true
26
+
22
27
  # Use the specified formatter
23
28
  config.formatter = :documentation # :progress, :html, :textmate
24
29
 
30
+ # Create temporary files
31
+ config.before(:suite) {
32
+ FileUtils.mkdir_p TEMP_DIR
33
+ FileUtils.touch "#{TEMP_DIR}/test-file"
34
+ File.open("#{TEMP_DIR}/test-hostname", 'w') do |newfile|
35
+ newfile.write('TestHostname')
36
+ end
37
+ File.open("#{TEMP_DIR}/test-hosts", 'w') do |newfile|
38
+ newfile.write('127.0.0.1 TestHostname')
39
+ end
40
+ }
41
+
25
42
  # Clean up
26
43
  config.after(:suite) {
27
- unless ENV['TRAVIS']
28
- `ls /tmp/vscripts-test-* &> /dev/null && rm -r /tmp/vscripts-test-*`
29
- end
44
+ FileUtils.rm_rf TEMP_DIR if Dir[TEMP_DIR]
30
45
  }
31
46
  }
47
+
48
+ shared_context 'Temporary' do
49
+ let(:temp_dir) { TEMP_DIR }
50
+ let(:test_dir) { "#{TEMP_DIR}/test-dir" }
51
+ let(:test_file) { "#{TEMP_DIR}/test-file" }
52
+ let(:test_missing_file) { "#{test_dir}/test-file" }
53
+ let(:test_cont) { 'VScripts Test Content.' }
54
+ end
55
+
56
+ shared_context 'Suppressed output' do
57
+ before(:each) do
58
+ $stdout = StringIO.new
59
+ $stderr = StringIO.new
60
+ end
61
+
62
+ after(:each) do
63
+ $stdout = STDOUT
64
+ $stderr = STDERR
65
+ end
66
+ end
67
+
68
+ def stub_cli_with(args)
69
+ allow(VScripts).to receive(:cli)
70
+ .and_return(VScripts::CommandLine.new(args.split))
71
+ end
72
+
73
+ shared_context 'VScripts' do
74
+ let(:cmd) { VScripts::Commands.list.first.to_s.downcase }
75
+ end
76
+
77
+ shared_context 'Not an EC2 Instance' do
78
+ before(:each) do
79
+ allow(Net::HTTP).to receive(:get_response).and_return(false)
80
+ end
81
+ end
82
+
83
+ shared_context 'Amazon Web Services' do |subject|
84
+ # Preload AWS library
85
+ AWS.eager_autoload! AWS::Core # Make sure to load Core first.
86
+ AWS.eager_autoload! AWS::EC2 # Load the EC2 class
87
+
88
+ ::AWS.config({
89
+ :access_key_id => '1234',
90
+ :secret_access_key => '5678',
91
+ :logger => nil,
92
+ :stub_requests => true
93
+ })
94
+
95
+ let(:region) {'us-east-1'}
96
+
97
+ let(:fake_instances) {::AWS::Core::Data.new([
98
+ {id: 'i-abcdefg1', status: :running, tags: tags},
99
+ {id: 'i-abcdefg2', status: :terminated, tags: tags},
100
+ {id: 'i-abcdefg3', status: :running, tags: {}},
101
+ {id: 'i-abcdefg4', status: :terminated, tags: {}},
102
+ ])}
103
+
104
+ let(:tags) {{
105
+ 'Name' => 'TestName-1.TestDomain.tld',
106
+ 'Domain' => 'TestDomainValue.tld',
107
+ 'TestTagKey' => 'TestTagValue',
108
+ }}
109
+
110
+ before(:each) do
111
+ allow_any_instance_of(subject)
112
+ .to receive_message_chain('ec2.instances.tagged')
113
+ .and_return(fake_instances[0..1])
114
+ allow_any_instance_of(subject)
115
+ .to receive_message_chain(:named_instances)
116
+ .and_return(fake_instances[0..1])
117
+ end
118
+ end
119
+
120
+ shared_context 'EC2 Instance' do |subject|
121
+ include_context 'Amazon Web Services', subject
122
+
123
+ before(:each) do
124
+ allow(Net::HTTP).to receive(:get_response).and_return(true)
125
+ allow(subject).to receive_message_chain('open.read')
126
+ .and_return('Remote server response')
127
+ allow_any_instance_of(subject).to receive(:zone)
128
+ allow_any_instance_of(subject).to receive(:region)
129
+ .and_return('us-east-1')
130
+ allow_any_instance_of(subject).to receive(:instance_id)
131
+ .and_return(fake_instances[1].id)
132
+ allow_any_instance_of(subject)
133
+ .to receive_message_chain('ec2.tags.create')
134
+ end
135
+ end
136
+
137
+ shared_context 'EC2 Instance without tags' do |subject|
138
+ include_context 'EC2 Instance', subject
139
+
140
+ before(:each) do
141
+ allow_any_instance_of(subject)
142
+ .to receive_message_chain('instance.tags')
143
+ .and_return({})
144
+ end
145
+ end
146
+
147
+ shared_context 'EC2 Instance with tags' do |subject|
148
+ include_context 'EC2 Instance', subject
149
+
150
+ before(:each) do
151
+ allow_any_instance_of(subject)
152
+ .to receive_message_chain('instance.tags')
153
+ .and_return(tags)
154
+ end
155
+ end