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