right_scraper 1.0.26 → 3.0.0

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.
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