right_scraper 1.0.26 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. data/Gemfile +16 -0
  2. data/README.rdoc +9 -28
  3. data/Rakefile +51 -39
  4. data/lib/right_scraper/builders/base.rb +64 -0
  5. data/lib/right_scraper/builders/filesystem.rb +96 -0
  6. data/lib/right_scraper/builders/union.rb +57 -0
  7. data/lib/right_scraper/logger.rb +102 -0
  8. data/lib/right_scraper/loggers/noisy.rb +85 -0
  9. data/lib/right_scraper/processes/ssh.rb +188 -0
  10. data/lib/right_scraper/repositories/base.rb +299 -0
  11. data/lib/right_scraper/repositories/download.rb +90 -0
  12. data/lib/right_scraper/repositories/git.rb +92 -0
  13. data/lib/right_scraper/repositories/mock.rb +70 -0
  14. data/lib/right_scraper/repositories/svn.rb +96 -0
  15. data/lib/right_scraper/resources/base.rb +70 -0
  16. data/{spec/scraper_base_spec.rb → lib/right_scraper/resources/cookbook.rb} +9 -23
  17. data/lib/right_scraper/resources/workflow.rb +55 -0
  18. data/lib/right_scraper/retrievers/base.rb +114 -0
  19. data/lib/right_scraper/retrievers/checkout.rb +79 -0
  20. data/lib/right_scraper/retrievers/download.rb +97 -0
  21. data/lib/right_scraper/retrievers/git.rb +140 -0
  22. data/lib/right_scraper/retrievers/svn.rb +87 -0
  23. data/lib/right_scraper/scanners/base.rb +111 -0
  24. data/lib/right_scraper/scanners/cookbook_manifest.rb +59 -0
  25. data/lib/right_scraper/scanners/cookbook_metadata.rb +69 -0
  26. data/lib/right_scraper/scanners/cookbook_s3_upload.rb +84 -0
  27. data/lib/right_scraper/scanners/union.rb +89 -0
  28. data/lib/right_scraper/scanners/workflow_manifest.rb +86 -0
  29. data/lib/right_scraper/scanners/workflow_metadata.rb +70 -0
  30. data/lib/right_scraper/scanners/workflow_s3_upload.rb +85 -0
  31. data/lib/right_scraper/scraper.rb +81 -57
  32. data/lib/right_scraper/scraper_logger.rb +61 -0
  33. data/lib/right_scraper/scrapers/base.rb +262 -0
  34. data/lib/right_scraper/scrapers/cookbook.rb +73 -0
  35. data/lib/right_scraper/scrapers/workflow.rb +88 -0
  36. data/lib/right_scraper/svn_client.rb +101 -0
  37. data/lib/right_scraper/version.rb +28 -0
  38. data/lib/right_scraper.rb +35 -11
  39. data/right_scraper.gemspec +26 -13
  40. data/right_scraper.rconf +13 -0
  41. data/spec/builder_spec.rb +50 -0
  42. data/spec/cookbook_helper.rb +73 -0
  43. data/spec/cookbook_manifest_spec.rb +55 -0
  44. data/spec/cookbook_s3_upload_spec.rb +152 -0
  45. data/spec/download/download_retriever_spec.rb +118 -0
  46. data/spec/download/download_retriever_spec_helper.rb +72 -0
  47. data/spec/download/download_spec.rb +130 -0
  48. data/spec/download/multi_dir_spec.rb +106 -0
  49. data/spec/download/multi_dir_spec_helper.rb +40 -0
  50. data/spec/git/cookbook_spec.rb +166 -0
  51. data/spec/git/demokey +27 -0
  52. data/spec/git/demokey.pub +1 -0
  53. data/spec/git/password_key +30 -0
  54. data/spec/git/password_key.pub +1 -0
  55. data/spec/git/repository_spec.rb +110 -0
  56. data/spec/git/retriever_spec.rb +505 -0
  57. data/spec/git/retriever_spec_helper.rb +112 -0
  58. data/spec/git/scraper_spec.rb +136 -0
  59. data/spec/git/ssh_spec.rb +170 -0
  60. data/spec/git/url_spec.rb +103 -0
  61. data/spec/logger_spec.rb +185 -0
  62. data/spec/repository_spec.rb +89 -23
  63. data/spec/{scraper_spec_helper_base.rb → retriever_spec_helper.rb} +41 -27
  64. data/spec/scanner_spec.rb +61 -0
  65. data/spec/scraper_helper.rb +96 -0
  66. data/spec/scraper_spec.rb +123 -45
  67. data/spec/spec_helper.rb +87 -14
  68. data/spec/svn/cookbook_spec.rb +97 -0
  69. data/spec/svn/multi_svn_spec.rb +64 -0
  70. data/spec/svn/multi_svn_spec_helper.rb +40 -0
  71. data/spec/svn/repository_spec.rb +72 -0
  72. data/spec/svn/retriever_spec.rb +261 -0
  73. data/spec/svn/scraper_spec.rb +90 -0
  74. data/spec/svn/{svn_scraper_spec_helper.rb → svn_retriever_spec_helper.rb} +46 -27
  75. data/spec/svn/url_spec.rb +47 -0
  76. data/spec/url_spec.rb +164 -0
  77. metadata +203 -31
  78. data/lib/right_scraper/linux/process_monitor.rb +0 -84
  79. data/lib/right_scraper/repository.rb +0 -78
  80. data/lib/right_scraper/scraper_base.rb +0 -175
  81. data/lib/right_scraper/scrapers/download_scraper.rb +0 -67
  82. data/lib/right_scraper/scrapers/git_scraper.rb +0 -283
  83. data/lib/right_scraper/scrapers/svn_scraper.rb +0 -119
  84. data/lib/right_scraper/watcher.rb +0 -158
  85. data/lib/right_scraper/win32/process_monitor.rb +0 -98
  86. data/spec/download/download_scraper_spec.rb +0 -94
  87. data/spec/git/git_scraper_spec.rb +0 -165
  88. data/spec/git/git_scraper_spec_helper.rb +0 -72
  89. data/spec/rcov.opts +0 -1
  90. data/spec/spec.opts +0 -2
  91. data/spec/svn/svn_scraper_spec.rb +0 -148
  92. data/spec/watcher_spec.rb +0 -74
@@ -0,0 +1,136 @@
1
+ #--
2
+ # Copyright: Copyright (c) 2010-2011 RightScale, Inc.
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # 'Software'), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ require 'stringio'
25
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
26
+ require File.expand_path(File.join(File.dirname(__FILE__), 'retriever_spec_helper'))
27
+ require 'tmpdir'
28
+ require 'flexmock'
29
+
30
+ describe RightScraper::Scraper do
31
+ include RightScraper::SpecHelpers::DevelopmentModeEnvironment
32
+
33
+ include RightScraper::SharedExamples
34
+
35
+ before(:each) do
36
+ @stream = StringIO.new()
37
+ @tmpdir = Dir.mktmpdir
38
+ @scraper = RightScraper::Scraper.new(:basedir => @tmpdir, :kind => :cookbook)
39
+ end
40
+
41
+ after(:each) do
42
+ FileUtils.remove_entry_secure @tmpdir
43
+ end
44
+
45
+ it 'starts out successful' do
46
+ @scraper.succeeded?.should be_true
47
+ @scraper.errors.should == []
48
+ end
49
+
50
+ context 'given a Git repository' do
51
+ before(:each) do
52
+ @helper = RightScraper::GitRetrieverSpecHelper.new
53
+ @helper.setup_cookbooks
54
+ @repo = @helper.repo
55
+ end
56
+
57
+ after(:each) do
58
+ @helper.close
59
+ end
60
+
61
+ it_should_behave_like "a normal repository"
62
+
63
+ it 'should log correctly as it scrapes' do
64
+ callback = flexmock("callback")
65
+ callback.should_receive(:call).with(:begin, :retrieving, "from #{@repo}", nil).once.ordered
66
+ callback.should_receive(:call).with(:begin, :initialize, String, nil).once.ordered
67
+ callback.should_receive(:call).with(:commit, :initialize, String, nil).once.ordered
68
+ callback.should_receive(:call).with(:begin, :checkout, "", nil).once.ordered
69
+ callback.should_receive(:call).with(:begin, :cloning, "to #{RightScraper::Retrievers::Base.repo_dir(@tmpdir, @repo)}", nil).once.ordered
70
+ callback.should_receive(:call).with(:commit, :cloning, "to #{RightScraper::Retrievers::Base.repo_dir(@tmpdir, @repo)}", nil).once.ordered
71
+ callback.should_receive(:call).with(:begin, :fetch, "", nil).once.ordered
72
+ callback.should_receive(:call).with(:commit, :fetch, "", nil).once.ordered
73
+ callback.should_receive(:call).with(:begin, :checkout_revision, "", nil).once.ordered
74
+ callback.should_receive(:call).with(:commit, :checkout_revision, "", nil).once.ordered
75
+ callback.should_receive(:call).with(:commit, :checkout, "", nil).once.ordered
76
+ callback.should_receive(:call).with(:commit, :retrieving, "from #{@repo}", nil).once.ordered
77
+ callback.should_receive(:call).with(:begin, :scraping, String, nil).once.ordered
78
+ callback.should_receive(:call).with(:begin, :finding_next_cookbook, String, nil).once.ordered
79
+ callback.should_receive(:call).with(:begin, :reading_cookbook, String, nil).once.ordered
80
+ callback.should_receive(:call).with(:begin, :scanning_filesystem, String, nil).once.ordered
81
+ callback.should_receive(:call).with(:begin, :metadata_parsing, "", nil).once.ordered
82
+ callback.should_receive(:call).with(:commit, :metadata_parsing, "", nil).once.ordered
83
+ callback.should_receive(:call).with(:commit, :scanning_filesystem, String, nil).once.ordered
84
+ callback.should_receive(:call).with(:commit, :reading_cookbook, String, nil).once.ordered
85
+ callback.should_receive(:call).with(:commit, :finding_next_cookbook, String, nil).once.ordered
86
+ callback.should_receive(:call).with(:begin, :next, "", nil).once.ordered
87
+ callback.should_receive(:call).with(:begin, :searching, "", nil).once.ordered
88
+ callback.should_receive(:call).with(:commit, :searching, "", nil).once.ordered
89
+ callback.should_receive(:call).with(:commit, :next, "", nil).once.ordered
90
+ callback.should_receive(:call).with(:begin, :next, "", nil).once.ordered
91
+ callback.should_receive(:call).with(:commit, :next, "", nil).once.ordered
92
+ callback.should_receive(:call).with(:commit, :scraping, String, nil).once.ordered
93
+
94
+ @scraper.scrape(@repo) do |phase, operation, explanation, exception|
95
+ callback.call(phase, operation, explanation, exception)
96
+ end
97
+ @scraper.succeeded?.should be_true
98
+ end
99
+
100
+ context 'with tag being an empty string' do
101
+ before(:each) do
102
+ @repo.tag = ""
103
+ end
104
+
105
+ it_should_behave_like "a normal repository"
106
+ end
107
+
108
+ context 'with some additional commits' do
109
+ before(:each) do
110
+ @helper.create_file_layout(@helper.repo_path, @helper.branch_content)
111
+ @helper.commit_content("change to master")
112
+ end
113
+
114
+ context 'after a successful scraper run' do
115
+ before(:each) do
116
+ @scraper.scrape(@repo)
117
+ @scraper.succeeded?.should be_true
118
+ end
119
+
120
+ context 'with some incompatible changes' do
121
+ before(:each) do
122
+ @helper.create_file_layout(@helper.repo_path, [{'other_branch_folder' => ['file7']}])
123
+ @helper.commit_content("2nd change to master")
124
+ @helper.force_rebase('master^', 'master^^')
125
+ end
126
+
127
+ it 'should still be successful' do
128
+ @scraper.scrape(@repo)
129
+ @scraper.errors.should == []
130
+ @scraper.succeeded?.should be_true
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,170 @@
1
+ #--
2
+ # Copyright: Copyright (c) 2010-2011 RightScale, Inc.
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # 'Software'), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
25
+
26
+ describe RightScraper::Processes::SSHAgent do
27
+ shared_examples_for 'a process that sets environment variables' do
28
+ def setvar(name, value)
29
+ if value.nil?
30
+ ENV.delete name
31
+ else
32
+ ENV[name] = value
33
+ end
34
+ end
35
+
36
+ it 'should set SSH_AUTH_SOCK' do
37
+ oldsock = ENV['SSH_AUTH_SOCK']
38
+ RightScraper::Processes::SSHAgent.with do |agent|
39
+ ENV.should have_key('SSH_AUTH_SOCK')
40
+ ENV['SSH_AUTH_SOCK'].should_not be_empty
41
+ File.exists?(ENV['SSH_AUTH_SOCK']).should == true
42
+ end
43
+ ENV['SSH_AUTH_SOCK'].should == oldsock
44
+ end
45
+
46
+ it 'should set SSH_AGENT_PID' do
47
+ oldpid = ENV['SSH_AUTH_PID']
48
+ RightScraper::Processes::SSHAgent.with do |agent|
49
+ ENV.should have_key('SSH_AGENT_PID')
50
+ ENV['SSH_AGENT_PID'].should_not be_empty
51
+ # This is a Unixism; sending signal 0 to a process tests whether
52
+ # it exists, but has no effect on the process. I have no idea
53
+ # how to express this on Windows.
54
+ Process.kill(0, ENV['SSH_AGENT_PID'].to_i).should be_true
55
+ end
56
+ ENV['SSH_AUTH_PID'].should == oldpid
57
+ end
58
+
59
+ it 'should set SSH_ASKPASS' do
60
+ oldpass = ENV['SSH_ASKPASS']
61
+ RightScraper::Processes::SSHAgent.with do |agent|
62
+ ENV.should have_key('SSH_ASKPASS')
63
+ ENV['SSH_ASKPASS'].should_not be_empty
64
+
65
+ script = File.expand_path(File.join(File.dirname(__FILE__), '..', '..',
66
+ 'scripts', 'stub_ssh_askpass'))
67
+ ENV['SSH_ASKPASS'].should == script
68
+ end
69
+ ENV['SSH_ASKPASS'].should == oldpass
70
+ end
71
+
72
+ it 'should set HOME' do
73
+ oldhome = ENV['HOME']
74
+ RightScraper::Processes::SSHAgent.with do |agent|
75
+ ENV.should have_key('HOME')
76
+ ENV['HOME'].should_not be_empty
77
+ ENV['HOME'].should == "/dev/null"
78
+ end
79
+ ENV['HOME'].should == oldhome
80
+ end
81
+ end
82
+
83
+ context 'with no relevant environment variables' do
84
+ before(:each) do
85
+ @display = ENV['DISPLAY']
86
+ @askpass = ENV['SSH_ASKPASS']
87
+ @sshauth = ENV['SSH_AUTH_SOCK']
88
+ @agentpid = ENV['SSH_AGENT_PID']
89
+ @home = ENV['HOME']
90
+ ENV.delete 'DISPLAY'
91
+ ENV.delete 'SSH_ASKPASS'
92
+ ENV.delete 'SSH_AUTH_SOCK'
93
+ ENV.delete 'SSH_AGENT_PID'
94
+ ENV.delete 'HOME'
95
+ end
96
+
97
+ after(:each) do
98
+ setvar 'DISPLAY', @display
99
+ setvar 'SSH_ASKPASS', @askpass
100
+ setvar 'SSH_AUTH_SOCK', @sshauth
101
+ setvar 'SSH_AGENT_PID', @agentpid
102
+ setvar 'HOME', @home
103
+ end
104
+
105
+ it_should_behave_like 'a process that sets environment variables'
106
+ end
107
+
108
+ context 'with relevant environment variables set' do
109
+ before(:each) do
110
+ @display = ENV['DISPLAY']
111
+ @askpass = ENV['SSH_ASKPASS']
112
+ @sshauth = ENV['SSH_AUTH_SOCK']
113
+ @agentpid = ENV['SSH_AGENT_PID']
114
+ @home = ENV['HOME']
115
+ ENV['DISPLAY'] = "foo"
116
+ ENV['SSH_ASKPASS'] = "bar"
117
+ ENV['SSH_AUTH_SOCK'] = "baz"
118
+ ENV['SSH_AGENT_PID'] = "quux"
119
+ ENV['HOME'] = "fred"
120
+ end
121
+
122
+ after(:each) do
123
+ setvar 'DISPLAY', @display
124
+ setvar 'SSH_ASKPASS', @askpass
125
+ setvar 'SSH_AUTH_SOCK', @sshauth
126
+ setvar 'SSH_AGENT_PID', @agentpid
127
+ setvar 'HOME', @home
128
+ end
129
+
130
+ it_should_behave_like 'a process that sets environment variables'
131
+ end
132
+
133
+ it 'should be able to load the demo key' do
134
+ RightScraper::Processes::SSHAgent.with do |agent|
135
+ demofile = File.expand_path(File.join(File.dirname(__FILE__), 'demokey'))
136
+ File.chmod(0600, demofile)
137
+ demofile = File.join(File.dirname(__FILE__), 'demokey')
138
+ agent.add_keyfile(demofile)
139
+ `ssh-add -l`.should == "2048 3d:6a:4f:8b:ec:35:da:e9:7e:cc:e8:2d:03:2f:6f:23 #{demofile} (RSA)\n"
140
+ `ssh-add -L`.should == <<FULLOUTPUT
141
+ ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxJsM8sZ6++Nky/ogLEYhKtKivB37sPB9M6Un0z6PkIRgUsGdntMJqP1U6820jH+n1/lOH/MnlUsvzoo8DnOdbe9kGOHBmtWmNcjqacZUn9DbpbjvlI7RUUmZ5OBKn8Pjt2qbSXnnci9Q5j5Rgh6DR8A70S04FIUP8AGpCIO23BhA928CiM18zN5mBvzET7L2DYiNhJJFsFWMbN13CdukTjNVNLETEusNVUU09G1NxX4esKky7tHh1c9APFvu98KjYOHkv1o7dB7T4dO3KaKCNWINCHeeoE+QmAkhAZwI72ijRkPxH+QMisMsHucPFvgOVVObxHWu9hRlNWIOodANHQ== #{demofile}
142
+ FULLOUTPUT
143
+ end
144
+ end
145
+
146
+ it 'should fail on the passworded key' do
147
+ pid = nil
148
+ lambda {
149
+ RightScraper::Processes::SSHAgent.with do |agent|
150
+ pid = ENV['SSH_AGENT_PID'].to_i
151
+ demofile = File.expand_path(File.join(File.dirname(__FILE__), 'password_key'))
152
+ File.chmod(0600, demofile)
153
+ agent.add_keyfile(demofile)
154
+ end
155
+ }.should raise_exception(ProcessWatcher::NonzeroExitCode, /Attempted to use credentials that require passwords; bailing/)
156
+ lambda {
157
+ Process.kill(0, pid)
158
+ }.should raise_exception(Errno::ESRCH)
159
+ end
160
+
161
+ it 'should be able to load the demo key from memory' do
162
+ RightScraper::Processes::SSHAgent.with do |agent|
163
+ demofile = File.join(File.dirname(__FILE__), 'demokey')
164
+ demodata = File.open(demofile).read
165
+ agent.add_key(demodata)
166
+ `ssh-add -l`.should =~ /^2048 3d:6a:4f:8b:ec:35:da:e9:7e:cc:e8:2d:03:2f:6f:23 .*? \(RSA\)\n$/
167
+ `ssh-add -L`.should =~ %r{^ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxJsM8sZ6\+\+Nky/ogLEYhKtKivB37sPB9M6Un0z6PkIRgUsGdntMJqP1U6820jH\+n1/lOH/MnlUsvzoo8DnOdbe9kGOHBmtWmNcjqacZUn9DbpbjvlI7RUUmZ5OBKn8Pjt2qbSXnnci9Q5j5Rgh6DR8A70S04FIUP8AGpCIO23BhA928CiM18zN5mBvzET7L2DYiNhJJFsFWMbN13CdukTjNVNLETEusNVUU09G1NxX4esKky7tHh1c9APFvu98KjYOHkv1o7dB7T4dO3KaKCNWINCHeeoE\+QmAkhAZwI72ijRkPxH\+QMisMsHucPFvgOVVObxHWu9hRlNWIOodANHQ== .*\n$}
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,103 @@
1
+ #--
2
+ # Copyright: Copyright (c) 2010-2011 RightScale, Inc.
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # 'Software'), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
25
+
26
+ describe RightScraper::Repositories::Base do
27
+ def make_repo(url)
28
+ @repo = RightScraper::Repositories::Base.from_hash(:display_name => 'test repo',
29
+ :repo_type => :git,
30
+ :url => url,
31
+ :first_credential => "foo")
32
+ end
33
+ include RightScraper::SpecHelpers::ProductionModeEnvironment
34
+
35
+ context 'with Git URIs' do
36
+ it 'should not throw an error for http URIs' do
37
+ lambda do
38
+ make_repo "http://rightscale.com/%20CBLAH"
39
+ end.should_not raise_exception
40
+ end
41
+ it 'should not throw an error for git URIs' do
42
+ lambda do
43
+ make_repo "git://rightscale.com/%20CBLAH"
44
+ end.should_not raise_exception
45
+ end
46
+ it 'should not throw an error for absolute SCP URIs' do
47
+ lambda do
48
+ make_repo "git@rightscale.com:/%20CBLAH"
49
+ end.should_not raise_exception
50
+ end
51
+ it 'should not throw an error for SCP URIs with dashes in the username' do
52
+ lambda do
53
+ make_repo "git-foo@rightscale.com:/%20CBLAH"
54
+ end.should_not raise_exception
55
+ end
56
+ it 'should not throw an error for relative SCP URIs' do
57
+ lambda do
58
+ make_repo "git-foo@rightscale.com:%20CBLAH"
59
+ end.should_not raise_exception
60
+ end
61
+ it 'should not throw an error for git+ssh URIs' do
62
+ lambda do
63
+ make_repo "git+ssh://rightscale.com/%20CBLAH"
64
+ end.should_not raise_exception
65
+ end
66
+ it 'should not throw an error for ssh URIs' do
67
+ lambda do
68
+ make_repo "ssh://rightscale.com/%20CBLAH"
69
+ end.should_not raise_exception
70
+ end
71
+ end
72
+
73
+ context '#to_url' do
74
+ it 'should correctly convert http URIs' do
75
+ make_repo("http://rightscale.com/%20CBLAH").to_url.to_s.should ==
76
+ "http://foo@rightscale.com/%20CBLAH"
77
+ end
78
+ it 'should correctly convert git URIs' do
79
+ make_repo("git://rightscale.com/%20CBLAH").to_url.to_s.should ==
80
+ "git://foo@rightscale.com/%20CBLAH"
81
+ end
82
+ it 'should correctly convert SCP URIs' do
83
+ make_repo("git@rightscale.com:/%20CBLAH").to_url.to_s.should ==
84
+ "ssh://git:foo@rightscale.com/%20CBLAH"
85
+ end
86
+ it 'should correctly convert SCP URIs with dashes in the username' do
87
+ make_repo("git-foo@rightscale.com:/%20CBLAH").to_url.to_s.should ==
88
+ "ssh://git-foo:foo@rightscale.com/%20CBLAH"
89
+ end
90
+ it 'should correctly convert relative SCP URIs' do
91
+ make_repo("git-foo@rightscale.com:%20CBLAH").to_url.to_s.should ==
92
+ "ssh://git-foo:foo@rightscale.com/%20CBLAH"
93
+ end
94
+ it 'should correctly convert git+ssh URIs' do
95
+ make_repo("git+ssh://rightscale.com/%20CBLAH").to_url.to_s.should ==
96
+ "git+ssh://foo@rightscale.com/%20CBLAH"
97
+ end
98
+ it 'should correctly convert ssh URIs' do
99
+ make_repo("ssh://rightscale.com/%20CBLAH").to_url.to_s.should ==
100
+ "ssh://foo@rightscale.com/%20CBLAH"
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,185 @@
1
+ #--
2
+ # Copyright: Copyright (c) 2010-2011 RightScale, Inc.
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # 'Software'), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
+ # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
+ # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
+ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
+ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ require 'stringio'
25
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
26
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'right_scraper', 'loggers', 'noisy'))
27
+
28
+ describe RightScraper::Logger do
29
+ before(:each) do
30
+ @stream = StringIO.new()
31
+ @logger = RightScraper::Logger.new(@stream)
32
+ @logger.level = Logger::WARN
33
+ end
34
+
35
+ after(:each) do
36
+ @logger.close
37
+ end
38
+
39
+ def match_log_entry(entry, type, message)
40
+ shortform, longform = case type
41
+ when Logger::DEBUG then ["D", "DEBUG"]
42
+ when Logger::INFO then ["I", "INFO"]
43
+ when Logger::WARN then ["W", "WARN"]
44
+ when Logger::ERROR then ["E", "ERROR"]
45
+ when Logger::FATAL then ["F", "FATAL"]
46
+ when Logger::FATAL then ["U", "UNKNOWN"]
47
+ end
48
+ datestamp = /[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}/
49
+ timestamp = /[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}.[[:digit:]]+/
50
+ datetimestamp = /#{datestamp}T#{timestamp}/
51
+ entry.should =~ %r{^#{shortform}, \[#{datetimestamp} \#[[:digit:]]+\] #{longform} -- : #{message}\n$}
52
+ end
53
+
54
+ it 'should log to the stream' do
55
+ @logger.debug("foo")
56
+ @logger.info("first")
57
+ @logger.error("baz")
58
+ @logger.fatal("quux")
59
+ @stream.rewind
60
+ match_log_entry(@stream.readline, Logger::ERROR, "baz")
61
+ match_log_entry(@stream.readline, Logger::FATAL, "quux")
62
+ @stream.eof?.should be_true
63
+ end
64
+
65
+ it 'should note errors properly' do
66
+ @logger.note_error(Exception.new("foo!"), :baz)
67
+ match_log_entry(@stream.string, Logger::ERROR, "Saw foo! during baz")
68
+ end
69
+
70
+ it 'should note errors with an explanation properly' do
71
+ @logger.note_error(Exception.new("foo!"), :baz, "an explanation")
72
+ match_log_entry(@stream.string, Logger::ERROR, "Saw foo! during baz: an explanation")
73
+ end
74
+
75
+ it 'should pass values through the block' do
76
+ result = @logger.operation(:passthrough) { 4 }
77
+ result.should == 4
78
+ end
79
+ end
80
+
81
+ describe RightScraper::Loggers::NoisyLogger do
82
+ before(:each) do
83
+ @stream = StringIO.new()
84
+ @logger = RightScraper::Loggers::NoisyLogger.new(@stream)
85
+ end
86
+
87
+ after(:each) do
88
+ @logger.close
89
+ end
90
+
91
+ def match_log_entry(entry, type, message)
92
+ shortform, longform = case type
93
+ when Logger::DEBUG then ["D", "DEBUG"]
94
+ when Logger::INFO then ["I", "INFO"]
95
+ when Logger::WARN then ["W", "WARN"]
96
+ when Logger::ERROR then ["E", "ERROR"]
97
+ when Logger::FATAL then ["F", "FATAL"]
98
+ when Logger::FATAL then ["U", "UNKNOWN"]
99
+ end
100
+ datestamp = /[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}/
101
+ timestamp = /[[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}.[[:digit:]]+/
102
+ datetimestamp = /#{datestamp}T#{timestamp}/
103
+ entry.should =~ %r{^#{shortform}, \[#{datetimestamp} \#[[:digit:]]+\] #{longform} -- : #{message}\n$}
104
+ end
105
+
106
+ context 'with the level set to WARN' do
107
+ before(:each) do
108
+ @logger.level = Logger::WARN
109
+ end
110
+
111
+ it 'should not log operations' do
112
+ @logger.operation(:foo) do
113
+ @logger.operation(:bar) do
114
+ end
115
+ end
116
+ @stream.string.should == ""
117
+ end
118
+
119
+ it 'should note errors with context' do
120
+ begin
121
+ @logger.operation(:foo) do
122
+ @logger.operation(:bar, "blah") do
123
+ @logger.note_error("an exception", :note, "bar")
124
+ end
125
+ end
126
+ rescue
127
+ end
128
+ @stream.rewind
129
+ match_log_entry(@stream.readline, Logger::ERROR, "Saw an exception during note: bar in bar: blah in foo")
130
+ @stream.eof?.should be_true
131
+ end
132
+
133
+ it 'should note errors when the level is set to WARN and an exception occurs' do
134
+ begin
135
+ @logger.operation(:foo) do
136
+ @logger.operation(:bar, "blah") do
137
+ raise "foo"
138
+ end
139
+ end
140
+ rescue
141
+ end
142
+ @stream.rewind
143
+ match_log_entry(@stream.readline, Logger::ERROR, "Saw foo during bar: blah in foo")
144
+ @stream.eof?.should be_true
145
+ end
146
+ end
147
+
148
+ context 'with the level set to DEBUG' do
149
+ before(:each) do
150
+ @logger.level = Logger::DEBUG
151
+ end
152
+
153
+ it 'should log begin/commit' do
154
+ @logger.operation(:foo) do
155
+ @logger.operation(:bar, "blah") do
156
+ end
157
+ end
158
+ @stream.rewind
159
+ match_log_entry(@stream.readline, Logger::DEBUG, "> begin foo")
160
+ match_log_entry(@stream.readline, Logger::DEBUG, ">> begin bar: blah")
161
+ match_log_entry(@stream.readline, Logger::DEBUG, ">> commit bar: blah")
162
+ match_log_entry(@stream.readline, Logger::DEBUG, "> commit foo")
163
+ @stream.eof?.should be_true
164
+ end
165
+
166
+ it 'should log begin/abort when an exception occurs' do
167
+ @logger.level = Logger::DEBUG
168
+ begin
169
+ @logger.operation(:foo) do
170
+ @logger.operation(:bar, "blah") do
171
+ raise "foo"
172
+ end
173
+ end
174
+ rescue
175
+ end
176
+ @stream.rewind
177
+ match_log_entry(@stream.readline, Logger::DEBUG, "> begin foo")
178
+ match_log_entry(@stream.readline, Logger::DEBUG, ">> begin bar: blah")
179
+ match_log_entry(@stream.readline, Logger::ERROR, "Saw foo during bar: blah in foo")
180
+ match_log_entry(@stream.readline, Logger::DEBUG, ">> abort bar: blah")
181
+ match_log_entry(@stream.readline, Logger::DEBUG, "> abort foo")
182
+ @stream.eof?.should be_true
183
+ end
184
+ end
185
+ end