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
data/spec/spec_helper.rb CHANGED
@@ -1,18 +1,18 @@
1
1
  #--
2
- # Copyright: Copyright (c) 2010 RightScale, Inc.
2
+ # Copyright: Copyright (c) 2010-2011 RightScale, Inc.
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
6
6
  # 'Software'), to deal in the Software without restriction, including
7
7
  # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
9
  # permit persons to whom the Software is furnished to do so, subject to
10
10
  # the following conditions:
11
11
  #
12
12
  # The above copyright notice and this permission notice shall be
13
13
  # included in all copies or substantial portions of the Software.
14
14
  #
15
- # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
16
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
17
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
18
  # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
@@ -22,18 +22,57 @@
22
22
  #++
23
23
 
24
24
  require 'rubygems'
25
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'right_scraper'))
26
+
25
27
  require 'flexmock'
26
- require 'spec'
28
+ require 'rspec'
27
29
  require 'find'
30
+ require 'json'
28
31
 
29
- $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'right_scraper')))
32
+ RSpec.configure do |c|
33
+ c.mock_with(:flexmock)
34
+ end
30
35
 
31
- Spec::Runner.configuration.mock_with :flexmock
36
+ ENV["DEVELOPMENT"] ||= "yes"
32
37
 
33
38
  # Helper module
34
- module RightScale
35
-
39
+ module RightScraper
40
+
36
41
  module SpecHelpers
42
+ module DevelopmentModeEnvironment
43
+ def DevelopmentModeEnvironment.included(mod)
44
+ mod.module_eval do
45
+ before(:each) do
46
+ @oldtest = ENV['DEVELOPMENT']
47
+ ENV['DEVELOPMENT'] = "yes"
48
+ end
49
+ after(:each) do
50
+ if @oldtest.nil?
51
+ ENV.delete('DEVELOPMENT')
52
+ else
53
+ ENV['DEVELOPMENT'] = @oldtest
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ module ProductionModeEnvironment
60
+ def ProductionModeEnvironment.included(mod)
61
+ mod.module_eval do
62
+ before(:each) do
63
+ @oldtest = ENV['DEVELOPMENT']
64
+ ENV.delete('DEVELOPMENT')
65
+ end
66
+ after(:each) do
67
+ if @oldtest.nil?
68
+ ENV.delete('DEVELOPMENT')
69
+ else
70
+ ENV['DEVELOPMENT'] = @oldtest
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
37
76
 
38
77
  # Set the 'verbose' environment variable for debugging a failing spec
39
78
  VERBOSE='verbose'
@@ -54,6 +93,16 @@ module RightScale
54
93
  return res, $?
55
94
  end
56
95
 
96
+ def create_cookbook(path, contents)
97
+ create_file_layout(path, contents)
98
+ File.open(File.join(path, 'metadata.json'), 'w') { |f| f.puts contents.to_json }
99
+ end
100
+
101
+ def create_workflow(path, name, definition, metadata)
102
+ File.open(File.join(path, "#{name}#{RightScraper::Resources::Workflow::DEFINITION_EXT}"), 'w') { |f| f.puts definition }
103
+ File.open(File.join(path, "#{name}#{RightScraper::Resources::Workflow::METADATA_EXT}"), 'w') { |f| f.puts metadata.to_json }
104
+ end
105
+
57
106
  # Create file layout from given array
58
107
  # Strings in array correspond to files while Hashes correspond to folders
59
108
  # File content is equal to filename
@@ -75,11 +124,11 @@ module RightScale
75
124
  end
76
125
  else
77
126
  File.open(File.join(path, elem.to_s), 'w') { |f| f.puts elem.to_s }
78
- end
127
+ end
79
128
  end
80
129
  true
81
130
  end
82
-
131
+
83
132
  # Extract array representing file layout for given directory
84
133
  #
85
134
  # === Parameters
@@ -105,8 +154,32 @@ module RightScale
105
154
  end
106
155
  dirs + files.sort
107
156
  end
108
-
109
-
157
+
158
+ RSpec::Matchers.define :begin_with do |path|
159
+ match do |directory|
160
+ directory[0...path.length] == path
161
+ end
162
+ end
163
+ end
164
+
165
+ module SharedExamples
166
+ shared_examples_for "a normal repository" do
167
+ it 'should scrape' do
168
+ @scraper.scrape(@repo)
169
+ @scraper.succeeded?.should be_true
170
+ @scraper.resources.should_not == []
171
+ @scraper.resources.size.should == 1
172
+ @scraper.resources[0].manifest.should == {
173
+ "folder1/file3"=>"1eb2267bae4e47cab81f8866bbc7e06764ea9be0",
174
+ "file1"=>"38be7d1b981f2fb6a4a0a052453f887373dc1fe8",
175
+ "folder2/folder3/file4"=>"a441d6d72884e442ef02692864eee99b4ad933f5",
176
+ "metadata.json"=>"c2901d21c81ba5a152a37a5cfae35a8e092f7b39",
177
+ "folder1/file2"=>"639daad06642a8eb86821ff7649e86f5f59c6139"}
178
+ @scraper.resources[0].metadata.should == [{"folder1"=>["file2", "file3"]},
179
+ {"folder2"=>[{"folder3"=>["file4"]}]},
180
+ "file1"]
181
+ end
182
+ end
110
183
  end
111
-
112
- end
184
+
185
+ end
@@ -0,0 +1,97 @@
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
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'cookbook_helper'))
26
+
27
+ describe RightScraper::Resources::Cookbook do
28
+ include RightScraper::SpecHelpers::DevelopmentModeEnvironment
29
+
30
+ include RightScraper::CookbookHelper
31
+
32
+ shared_examples_for 'svn repositories' do
33
+ it_should_behave_like 'a generic repository'
34
+
35
+ it 'should have the appropriate credentials' do
36
+ @repository.username.should == 'username'
37
+ @repository.password.should == 'password'
38
+ end
39
+ end
40
+
41
+ context 'with a SVN repository' do
42
+ before(:each) do
43
+ @repository = RightScraper::Repositories::Svn.from_hash(:display_name => 'test repo',
44
+ :repo_type => :svn,
45
+ :url => "http://a.site/foo/bar/baz",
46
+ :first_credential => "username",
47
+ :second_credential => "password")
48
+ end
49
+
50
+ it_should_behave_like 'svn repositories'
51
+
52
+ it 'should have a tag' do
53
+ @repository.tag.should == "HEAD"
54
+ end
55
+
56
+ it 'should have a cookbook hash' do
57
+ repo_hash = Digest::SHA1.hexdigest("1\000svn\000http://a.site/foo/bar/baz\000HEAD")
58
+ example_cookbook(@repository).resource_hash.should ==
59
+ Digest::SHA1.hexdigest("1\000#{repo_hash}\000")
60
+ end
61
+
62
+ it 'should have a cookbook hash invariant under credential changes' do
63
+ old_hash = example_cookbook(@repository).resource_hash
64
+ @repository.first_credential = "b-key"
65
+ example_cookbook(@repository).resource_hash.should == old_hash
66
+ end
67
+
68
+ it 'should have a cookbook hash that varies when the tag changes' do
69
+ old_hash = example_cookbook(@repository).resource_hash
70
+ @repository.tag = "tag"
71
+ example_cookbook(@repository).resource_hash.should_not == old_hash
72
+ end
73
+
74
+ it 'should have a cookbook hash that varies when the position changes' do
75
+ example_cookbook(@repository, "foo").resource_hash.should_not ==
76
+ example_cookbook(@repository, "bar").resource_hash
77
+ end
78
+ end
79
+
80
+ context 'with a SVN repository with a tag' do
81
+ before(:each) do
82
+ @repository = RightScraper::Repositories::Svn.from_hash(:display_name => 'test repo',
83
+ :repo_type => :svn,
84
+ :url => "http://a.site/foo/bar/baz",
85
+ :tag => "foo",
86
+ :first_credential => "username",
87
+ :second_credential => "password")
88
+ end
89
+
90
+ it_should_behave_like 'svn repositories'
91
+
92
+ it 'should have a tag' do
93
+ @repository.tag.should == "foo"
94
+ end
95
+ end
96
+
97
+ end
@@ -0,0 +1,64 @@
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__), 'multi_svn_spec_helper'))
25
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'scraper_helper'))
26
+
27
+ describe RightScraper::Retrievers::Svn do
28
+ context 'in a multiple directory situation with a resources_path set' do
29
+ include RightScraper::SpecHelpers::DevelopmentModeEnvironment
30
+
31
+ include RightScraper::ScraperHelper
32
+
33
+ before(:all) do
34
+ @retriever_class = RightScraper::Retrievers::Svn
35
+ @ignore = ['.svn']
36
+ end
37
+
38
+ context 'given a SVN repository' do
39
+ before(:each) do
40
+ @helper = RightScraper::MultiSvnSpecHelper.new
41
+ @repo = @helper.repo
42
+ end
43
+
44
+ after(:each) do
45
+ @helper.close unless @helper.nil?
46
+ @helper = nil
47
+ end
48
+
49
+ include RightScraper::SpecHelpers::FromScratchScraping
50
+ include RightScraper::SpecHelpers::CookbookScraping
51
+
52
+ it 'should see two cookbooks' do
53
+ @scraper.next_resource.should_not == nil
54
+ @scraper.next_resource.should_not == nil
55
+ @scraper.next_resource.should == nil
56
+ end
57
+
58
+ it 'should set the position correctly' do
59
+ check_resource @scraper.next_resource, :position => "subdir1"
60
+ check_resource @scraper.next_resource, :position => "subdir2"
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,40 @@
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__), "svn_retriever_spec_helper"))
25
+
26
+ module RightScraper
27
+ class MultiSvnSpecHelper < SvnRetrieverSpecHelper
28
+ def make_cookbooks
29
+ super
30
+ create_cookbook(File.join(repo_path, 'subdir1'), repo_content)
31
+ create_cookbook(File.join(repo_path, 'subdir2'), repo_content)
32
+ end
33
+
34
+ def repo
35
+ r = super
36
+ r.resources_path = ['subdir1', 'subdir2']
37
+ r
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,72 @@
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::Svn do
27
+ include RightScraper::SpecHelpers::DevelopmentModeEnvironment
28
+
29
+ before(:each) do
30
+ @repo = RightScraper::Repositories::Base.from_hash(:display_name => 'test repo',
31
+ :repo_type => :svn,
32
+ :url => "http://foo.bar.baz.quux/%20CBLAH",
33
+ :tag => 'foo',
34
+ :first_credential => "foo:b/ar",
35
+ :second_credential => "foo@bar")
36
+ end
37
+
38
+ it 'should have the same repository hash with or without credentials' do
39
+ initial_hash = @repo.repository_hash
40
+ @repo.first_credential = nil
41
+ @repo.second_credential = nil
42
+ @repo.repository_hash.should == initial_hash
43
+ end
44
+
45
+ it 'should have the same checkout hash with or without credentials' do
46
+ initial_hash = @repo.checkout_hash
47
+ @repo.first_credential = nil
48
+ @repo.second_credential = nil
49
+ @repo.checkout_hash.should == initial_hash
50
+ end
51
+
52
+ it 'should have a checkout hash' do
53
+ @repo.checkout_hash.should ==
54
+ Digest::SHA1.hexdigest("1\000svn\000http://foo.bar.baz.quux/%20CBLAH\000foo")
55
+ end
56
+
57
+ it 'should have a different checkout hash from repository hash' do
58
+ @repo.repository_hash.should_not == @repo.checkout_hash
59
+ end
60
+
61
+ it 'should have the same repository hash regardless of tag' do
62
+ initial_hash = @repo.repository_hash
63
+ @repo.tag = 'bar'
64
+ @repo.repository_hash.should == initial_hash
65
+ end
66
+
67
+ it 'should have different checkout hashes as tags change' do
68
+ initial_hash = @repo.checkout_hash
69
+ @repo.tag = 'bar'
70
+ @repo.checkout_hash.should_not == initial_hash
71
+ end
72
+ end
@@ -0,0 +1,261 @@
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
+ require File.expand_path(File.join(File.dirname(__FILE__), 'svn_retriever_spec_helper'))
26
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'scraper_helper'))
27
+ require 'set'
28
+
29
+ describe RightScraper::Retrievers::Svn do
30
+ include RightScraper::SpecHelpers::DevelopmentModeEnvironment
31
+
32
+ include RightScraper::ScraperHelper
33
+
34
+ before(:all) do
35
+ @retriever_class = RightScraper::Retrievers::Svn
36
+ @ignore = ['.svn']
37
+ end
38
+
39
+ context 'given a remote SVN repository' do
40
+ before(:each) do
41
+ pending "Not run unless REMOTE_USER and REMOTE_PASSWORD set" unless ENV['REMOTE_USER'] && ENV['REMOTE_PASSWORD']
42
+ url = 'https://wush.net/svn/rightscale/cookbooks_test/'
43
+ @repo = RightScraper::Repositories::Base.from_hash(:display_name => 'wush',
44
+ :repo_type => :svn,
45
+ :url => url,
46
+ :first_credential => ENV['REMOTE_USER'],
47
+ :second_credential => ENV['REMOTE_PASSWORD'])
48
+ @retriever = @retriever_class.new(@repo, :max_bytes => 1024**2,
49
+ :max_seconds => 20)
50
+ end
51
+
52
+ it 'should scrape' do
53
+ @retriever.retrieve
54
+ @scraper = RightScraper::Scrapers::Base.scraper(:kind => :cookbook,
55
+ :ignorable_paths => @retriever.ignorable_paths,
56
+ :repo_dir => @retriever.repo_dir,
57
+ :repository => @retriever.repository)
58
+ first = @scraper.next_resource
59
+ first.should_not == nil
60
+ end
61
+
62
+ # quick_start not actually being a cookbook
63
+ it 'should scrape 5 repositories' do
64
+ locations = Set.new
65
+ (1..5).each {|n|
66
+ cookbook = @scraper.next_resource
67
+ locations << cookbook.pos
68
+ cookbook.should_not == nil
69
+ }
70
+ @retriever.retrieve
71
+ @scraper = RightScraper::Scrapers::Base.scraper(:kind => :cookbook,
72
+ :ignorable_paths => @retriever.ignorable_paths,
73
+ :repo_dir => @retriever.repo_dir,
74
+ :repository => @retriever.repository)
75
+ @scraper.next_resource.should == nil
76
+ locations.should == Set.new(["cookbooks/app_rails",
77
+ "cookbooks/db_mysql",
78
+ "cookbooks/repo_git",
79
+ "cookbooks/rs_utils",
80
+ "cookbooks/web_apache"])
81
+ end
82
+ end
83
+
84
+ context 'given a SVN repository' do
85
+ before(:each) do
86
+ @helper = RightScraper::SvnRetrieverSpecHelper.new
87
+ @repo = @helper.repo
88
+ end
89
+
90
+ after(:each) do
91
+ @helper.close unless @helper.nil?
92
+ @helper = nil
93
+ end
94
+
95
+ context 'with one cookbook' do
96
+ include RightScraper::SpecHelpers::FromScratchScraping
97
+ include RightScraper::SpecHelpers::CookbookScraping
98
+
99
+ it 'should scrape the master branch' do
100
+ check_resource @scraper.next_resource
101
+ end
102
+
103
+ it 'should only see one cookbook' do
104
+ @scraper.next_resource.should_not == nil
105
+ @scraper.next_resource.should == nil
106
+ end
107
+
108
+ it 'should record the head SHA' do
109
+ tag = @scraper.next_resource.repository.tag
110
+ tag.should_not == "master"
111
+ tag.should =~ /^[0-9]+$/
112
+ end
113
+ end
114
+
115
+ context 'with multiple cookbooks' do
116
+ def secondary_cookbook(where)
117
+ FileUtils.mkdir_p(where)
118
+ @helper.create_cookbook(where, @helper.repo_content)
119
+ end
120
+
121
+ before(:each) do
122
+ @helper.delete(File.join(@helper.repo_path, "metadata.json"))
123
+ @cookbook_places = [File.join(@helper.repo_path, "cookbooks", "first"),
124
+ File.join(@helper.repo_path, "cookbooks", "second"),
125
+ File.join(@helper.repo_path, "other_random_place")]
126
+ @cookbook_places.each {|place| secondary_cookbook(place)}
127
+ @helper.commit_content("secondary cookbooks added")
128
+ end
129
+
130
+ include RightScraper::SpecHelpers::FromScratchScraping
131
+ include RightScraper::SpecHelpers::CookbookScraping
132
+
133
+ it 'should scrape' do
134
+ @cookbook_places.each do |place|
135
+ check_resource @scraper.next_resource, :position => place[@helper.repo_path.length+1..-1]
136
+ end
137
+ scraped.should have(@cookbook_places.size).repositories
138
+ end
139
+
140
+ end
141
+
142
+ context 'and a revision' do
143
+ before(:each) do
144
+ @oldmetadata = @helper.repo_content
145
+ @helper.create_file_layout(@helper.repo_path, @helper.branch_content)
146
+ @helper.commit_content('added branch content')
147
+ @repo.tag = @helper.commit_id(1).to_s
148
+ end
149
+
150
+ include RightScraper::SpecHelpers::FromScratchScraping
151
+ include RightScraper::SpecHelpers::CookbookScraping
152
+
153
+ it 'should scrape a revision' do
154
+ check_resource @scraper.next_resource, :metadata => @oldmetadata, :rootdir => @retriever.repo_dir
155
+ end
156
+ end
157
+
158
+ context 'and an incremental scraper' do
159
+ before(:each) do
160
+ @retriever = @retriever_class.new(@repo,
161
+ :max_bytes => 1024**2,
162
+ :basedir => @helper.scraper_path,
163
+ :max_seconds => 20)
164
+ @retriever.retrieve
165
+ @scraper = RightScraper::Scrapers::Base.scraper(:kind => :cookbook,
166
+ :ignorable_paths => @retriever.ignorable_paths,
167
+ :repo_dir => @retriever.repo_dir,
168
+ :repository => @retriever.repository)
169
+ end
170
+
171
+ after(:each) do
172
+ @scraper.close
173
+ @scraper = nil
174
+ end
175
+
176
+ it 'the scraper should store intermediate versions where we expect' do
177
+ @retriever.repo_dir.should begin_with @helper.scraper_path
178
+ end
179
+
180
+ it 'the scraper should scrape' do
181
+ check_resource @scraper.next_resource
182
+ end
183
+
184
+ it 'the scraper should only see one cookbook' do
185
+ @scraper.next_resource.should_not == nil
186
+ @scraper.next_resource.should == nil
187
+ end
188
+
189
+ context 'when a change is made to the master repo' do
190
+ before(:each) do
191
+ @helper.create_file_layout(@helper.repo_path, @helper.branch_content)
192
+ @helper.commit_content
193
+ end
194
+
195
+ context 'a new scraper' do
196
+ before(:each) do
197
+ @olddir = @retriever.repo_dir
198
+ @retriever = @retriever_class.new(@repo,
199
+ :basedir => @helper.scraper_path,
200
+ :max_bytes => 1024**2,
201
+ :max_seconds => 20)
202
+ @retriever.retrieve
203
+ end
204
+
205
+ it 'should use the same directory for files' do
206
+ @olddir.should == @retriever.repo_dir
207
+ end
208
+
209
+ it 'should see the new change' do
210
+ File.exists?(File.join(@olddir, 'branch_folder', 'bfile1')).should be_true
211
+ end
212
+ end
213
+ end
214
+
215
+ context 'when a textual change is made to the master repo' do
216
+ before(:each) do
217
+ File.open(File.join(@helper.repo_path, "file1"), 'w') do |f|
218
+ f.puts "bar"
219
+ end
220
+ @helper.commit_content("appended bar")
221
+ File.open(File.join(@helper.repo_path, "file1"), 'a+') do |f|
222
+ f.puts "bar"
223
+ end
224
+ @helper.commit_content("appended bar again")
225
+ File.open(File.join(@helper.repo_path, "file1"), 'a+') do |f|
226
+ f.puts "bar"
227
+ end
228
+ @helper.commit_content("appended bar again^2")
229
+ File.open(File.join(@helper.repo_path, "file1"), 'a+') do |f|
230
+ f.puts "bar"
231
+ end
232
+ @helper.commit_content("appended bar again^3")
233
+ end
234
+
235
+ context 'a new scraper' do
236
+ before(:each) do
237
+ @olddir = @retriever.repo_dir
238
+ @retriever = @retriever_class.new(@repo,
239
+ :basedir => @helper.scraper_path,
240
+ :max_bytes => 1024**2,
241
+ :max_seconds => 20)
242
+ @retriever.retrieve
243
+ @scraper = RightScraper::Scrapers::Base.scraper(:kind => :cookbook,
244
+ :ignorable_paths => @retriever.ignorable_paths,
245
+ :repo_dir => @retriever.repo_dir,
246
+ :repository => @retriever.repository)
247
+ end
248
+
249
+ it 'should notice the new revision' do
250
+ cookbook = @scraper.next_resource
251
+ cookbook.repository.tag.should == "5"
252
+ end
253
+
254
+ it 'should see the new change' do
255
+ File.open(File.join(@olddir, 'file1')).read.should == "bar\n" * 4
256
+ end
257
+ end
258
+ end
259
+ end
260
+ end
261
+ end