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
@@ -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
@@ -21,25 +21,91 @@
21
21
  # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  #++
23
23
 
24
- require File.join(File.dirname(__FILE__), 'spec_helper')
25
- require 'repository'
26
-
27
- describe RightScale::Repository do
28
-
29
- it 'should be initializable from a hash' do
30
- repo = RightScale::Repository.from_hash(:display_name => 'display_name',
31
- :repo_type => 'repo_type',
32
- :url => 'url',
33
- :tag => 'tag',
34
- :first_credential => 'first_credential',
35
- :second_credential => 'second_credential')
36
- repo.should be_kind_of(RightScale::Repository)
37
- repo.display_name.should == 'display_name'
38
- repo.repo_type.should == 'repo_type'
39
- repo.url.should == 'url'
40
- repo.tag.should == 'tag'
41
- repo.first_credential.should == 'first_credential'
42
- repo.second_credential.should == 'second_credential'
24
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
25
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'right_scraper', 'repositories', 'mock'))
26
+
27
+ describe RightScraper::Repositories::Base do
28
+ include RightScraper::SpecHelpers::DevelopmentModeEnvironment
29
+
30
+ context 'with a repository type that doesn\'t exist' do
31
+ it 'should throw a comprehensible error when you try to create it' do
32
+ lambda {
33
+ RightScraper::Repositories::Base.from_hash(:display_name => 'display_name',
34
+ :repo_type => :nonexistent,
35
+ :url => 'url',
36
+ :tag => 'tag',
37
+ :first_credential => 'first_credential',
38
+ :second_credential => 'second_credential')
39
+ }.should raise_error(/Can't understand how to make nonexistent repos/)
40
+ end
41
+ end
42
+
43
+ context 'with a mock repository' do
44
+ before(:each) do
45
+ @repo = RightScraper::Repositories::Base.from_hash(:display_name => 'display_name',
46
+ :repo_type => :mock,
47
+ :url => 'url',
48
+ :tag => 'tag',
49
+ :first_credential => 'first_credential',
50
+ :second_credential => 'second_credential')
51
+ end
52
+
53
+ it 'should be initializable from a hash' do
54
+ @repo.should be_kind_of(RightScraper::Repositories::Base)
55
+ @repo.display_name.should == 'display_name'
56
+ @repo.repo_type.should == :mock
57
+ @repo.url.should == 'url'
58
+ @repo.tag.should == 'tag'
59
+ @repo.first_credential.should == 'first_credential'
60
+ @repo.second_credential.should == 'second_credential'
61
+ end
62
+
63
+ it 'should know the SHA-1 of its root location' do
64
+ @repo.repository_hash.should ==
65
+ Digest::SHA1.hexdigest("1\000mock\000url")
66
+ end
67
+
68
+ it 'should know the SHA-1 of the identifier for this specific checkout' do
69
+ @repo.checkout_hash.should ==
70
+ Digest::SHA1.hexdigest("1\000mock\000url")
71
+ end
72
+ end
73
+ end
74
+
75
+ describe RightScraper::Repositories::Download do
76
+ include RightScraper::SpecHelpers::DevelopmentModeEnvironment
77
+
78
+ before(:each) do
79
+ @repo = RightScraper::Repositories::Base.from_hash(:display_name => 'test repo',
80
+ :repo_type => :download,
81
+ :url => "http://foo.bar.baz.quux/%20CBLAH",
82
+ :tag => "412530982323",
83
+ :first_credential => "foo:b/ar",
84
+ :second_credential => "foo@bar")
85
+ end
86
+
87
+ it 'should have a tag' do
88
+ @repo.tag.should == '412530982323'
89
+ end
90
+
91
+ it 'should include the tag in the checkout hash' do
92
+ @repo.checkout_hash.should_not == @repo.repository_hash
93
+ oldhash = @repo.checkout_hash
94
+ @repo.tag = "42398"
95
+ @repo.checkout_hash.should_not == oldhash
96
+ end
97
+
98
+ it 'should have the same repository hash with or without credentials' do
99
+ initial_hash = @repo.repository_hash
100
+ @repo.first_credential = nil
101
+ @repo.second_credential = nil
102
+ @repo.repository_hash.should == initial_hash
103
+ end
104
+
105
+ it 'should have the same checkout hash with or without credentials' do
106
+ initial_hash = @repo.checkout_hash
107
+ @repo.first_credential = nil
108
+ @repo.second_credential = nil
109
+ @repo.checkout_hash.should == initial_hash
43
110
  end
44
-
45
111
  end
@@ -1,5 +1,5 @@
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
@@ -21,33 +21,67 @@
21
21
  # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  #++
23
23
 
24
+ require 'digest/sha1'
24
25
  require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
26
+ require 'tmpdir'
25
27
 
26
- module RightScale
28
+ module RightScraper
27
29
 
28
30
  # Base class for all scrapers spec helpers
29
31
  # Define helper methods used to manage repositories using each
30
32
  # source control software
31
- class ScraperSpecHelperBase
33
+ class RetrieverSpecHelper
32
34
 
33
35
  include SpecHelpers
34
36
 
37
+ def initialize
38
+ @tmpdir = Dir.mktmpdir
39
+ FileUtils.mkdir(repo_path)
40
+ @repo_content = [ { 'folder1' => [ 'file2', 'file3' ] },
41
+ { 'folder2' => [ { 'folder3' => [ 'file4' ] } ] },
42
+ 'file1' ]
43
+ end
44
+
45
+ def close
46
+ FileUtils.remove_entry_secure @tmpdir
47
+ end
48
+
35
49
  # Path to test repository
36
50
  #
37
51
  # === Return
38
52
  # repo_path(String):: Path to test repository
39
53
  def repo_path
40
- repo_path = File.join(File.dirname(__FILE__), '__repo')
54
+ File.join(@tmpdir, "repository")
41
55
  end
42
56
 
43
57
  # Default test repo content
44
58
  #
45
59
  # === Return
46
60
  # content(String):: Default test repo content
47
- def repo_content
48
- content = [ { 'folder1' => [ 'file2', 'file3' ] }, { 'folder2' => [ { 'folder3' => [ 'file4' ] } ] }, 'file1' ]
61
+ attr_reader :repo_content
62
+
63
+ def manifest
64
+ hash = {}
65
+ scan(@repo_content, hash, nil)
66
+ hash['metadata.json'] = Digest::SHA1.hexdigest(@repo_content.to_json + "\n")
67
+ hash
49
68
  end
50
69
 
70
+ def scan(contents, hash, position)
71
+ contents.each do |object|
72
+ if object.instance_of?(Hash)
73
+ object.each do |key, value|
74
+ relative_position = position ? File.join(position, key) : key
75
+ scan(value, hash, relative_position)
76
+ end
77
+ else
78
+ relative_position = position ? File.join(position, object) : object
79
+ hash[relative_position] = Digest::SHA1.hexdigest(object + "\n")
80
+ end
81
+ end
82
+ end
83
+ private :scan
84
+
51
85
  # Test branch content
52
86
  #
53
87
  # === Return
@@ -64,26 +98,6 @@ module RightScale
64
98
  content = [ { 'additional_folder' => [ 'afile1', 'afile2' ] }, 'afile3' ]
65
99
  end
66
100
 
67
- # Create test repository following given layout
68
- # Delete any previously created repo
69
- #
70
- # === Return
71
- # repo_path(String):: Path to created repositoy
72
- #
73
- # === Raise
74
- # Exception:: If repository initialization fails
75
- def setup_test_repo
76
- raise 'Not supported'
77
- end
78
-
79
- # Delete test repository
80
- #
81
- # === Return
82
- # true:: Always return true
83
- def delete_test_repo
84
- FileUtils.rm_rf(repo_path)
85
- end
86
-
87
101
  # Commit any non-commited changes of given directory
88
102
  #
89
103
  # === Parameters
@@ -129,4 +143,4 @@ module RightScale
129
143
  raise 'Not implemented'
130
144
  end
131
145
  end
132
- end
146
+ end
@@ -0,0 +1,61 @@
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__), 'download', 'download_retriever_spec_helper'))
26
+
27
+ describe RightScraper::Scanners::Base do
28
+ include RightScraper::SpecHelpers::DevelopmentModeEnvironment
29
+
30
+ before(:each) do
31
+ @helper = RightScraper::DownloadRetrieverSpecHelper.new
32
+ @repo = @helper.repo
33
+ end
34
+
35
+ after(:each) do
36
+ @helper.close
37
+ end
38
+
39
+ it 'should be called correctly' do
40
+ scanner = flexmock("scanner")
41
+ scanner.should_receive(:new).with(Hash).once.and_return(scanner)
42
+ scanner.should_receive(:begin).with(RightScraper::Resources::Cookbook).once
43
+ scanner.should_receive(:notice_dir).with(nil).once.and_return(true)
44
+ scanner.should_receive(:notice).with("file1", Proc).once
45
+ scanner.should_receive(:notice_dir).with("folder1").once.and_return(true)
46
+ scanner.should_receive(:notice).with("folder1/file2", Proc).once
47
+ scanner.should_receive(:notice).with("folder1/file3", Proc).once
48
+ scanner.should_receive(:notice_dir).with("folder2").once.and_return(false)
49
+ scanner.should_receive(:notice).with("metadata.json", Proc).once
50
+ scanner.should_receive(:end).with(RightScraper::Resources::Cookbook).once
51
+ scanner.should_receive(:finish).with().once
52
+
53
+ @scraper = RightScraper::Scrapers::Base.scraper(:repo_dir => @helper.download_repo_path,
54
+ :kind => :cookbook,
55
+ :scanners => [scanner],
56
+ :repository => @repo)
57
+ @scraper.next_resource.should_not be_nil
58
+ @scraper.next_resource.should be_nil
59
+ @scraper.close
60
+ end
61
+ end
@@ -0,0 +1,96 @@
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 'tmpdir'
26
+
27
+ module RightScraper
28
+ module SpecHelpers
29
+ module FromScratchScraping
30
+ def FromScratchScraping.included(mod)
31
+ mod.module_eval do
32
+ before(:each) do
33
+ @basedir = Dir.mktmpdir
34
+ @retriever = @retriever_class.new(@repo,
35
+ :basedir => @basedir,
36
+ :max_bytes => 1024**2,
37
+ :max_seconds => 20)
38
+ @retriever.retrieve
39
+ end
40
+
41
+ after(:each) do
42
+ FileUtils.remove_entry_secure(@basedir)
43
+ @scraper = nil
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ module CookbookScraping
50
+ def CookbookScraping.included(mod)
51
+ mod.module_eval do
52
+ before(:each) do
53
+ @scraper = RightScraper::Scrapers::Base.scraper(:repo_dir => @retriever.repo_dir,
54
+ :kind => :cookbook,
55
+ :repository => @retriever.repository,
56
+ :ignorable_paths => @retriever.ignorable_paths)
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ module WorkflowScraping
63
+ def WorkflowScraping.included(mod)
64
+ mod.module_eval do
65
+ before(:each) do
66
+ @scraper = RightScraper::Scrapers::Base.scraper(:repo_dir => @retriever.repo_dir,
67
+ :kind => :workflow,
68
+ :repository => @retriever.repository,
69
+ :ignorable_paths => @retriever.ignorable_paths)
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ end
76
+ module ScraperHelper
77
+ def archive_skeleton(archive)
78
+ files = Set.new
79
+ Archive.read_open_memory(archive) do |ar|
80
+ while entry = ar.next_header
81
+ files << [entry.pathname, ar.read_data]
82
+ end
83
+ end
84
+ files
85
+ end
86
+
87
+ def check_resource(resource, params={})
88
+ position = params[:position] || "."
89
+ resource.should_not == nil
90
+ resource.repository.should be_an_equal_repo @repo
91
+ resource.pos.should == position
92
+ resource.metadata.should == (params[:metadata] || @helper.repo_content)
93
+ resource.manifest.should == (params[:manifest] || @helper.manifest)
94
+ end
95
+ end
96
+ end
data/spec/scraper_spec.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
@@ -21,49 +21,127 @@
21
21
  # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  #++
23
23
 
24
- require File.join(File.dirname(__FILE__), 'spec_helper')
25
- require File.join(File.dirname(__FILE__), '..', 'lib', 'right_scraper', 'scraper_base')
26
- require File.join(File.dirname(__FILE__), '..', 'lib', 'right_scraper', 'scrapers', 'git_scraper')
27
- require File.join(File.dirname(__FILE__), '..', 'lib', 'right_scraper', 'scrapers', 'svn_scraper')
28
- require File.join(File.dirname(__FILE__), '..', 'lib', 'right_scraper', 'scrapers', 'download_scraper')
29
- require File.join(File.dirname(__FILE__), '..', 'lib', 'right_scraper', 'repository')
30
- require File.join(File.dirname(__FILE__), '..', 'lib', 'right_scraper', 'scraper')
31
-
32
- describe RightScale::Scraper do
33
-
34
- before(:each) do
35
- @scraper = RightScale::Scraper.new('/tmp')
36
- @mock_scraper = flexmock('MockScraper')
37
- mock_scraper_klass = flexmock('MockScraperClass', :new => @mock_scraper)
38
- RightScale::SCRAPERS.merge!('mock' => mock_scraper_klass)
39
- end
40
-
41
- after(:all) do
42
- RightScale::SCRAPERS.delete('mock')
43
- end
44
-
45
- it 'should scrape' do
46
- repo = RightScale::Repository.new
47
- repo.repo_type = :mock
48
- @mock_scraper.should_receive(:scrape).with(repo, true, Proc).and_return(true)
49
- @mock_scraper.should_receive(:succeeded?).and_return(true)
50
- @mock_scraper.should_receive(:current_repo_dir).and_return('42')
51
- @scraper.scrape(repo) { }.should be_true
52
- @scraper.last_repo_dir.should == '42'
24
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
25
+ require File.expand_path(File.join(File.dirname(__FILE__), 'download', 'download_retriever_spec_helper'))
26
+ require 'tmpdir'
27
+ require 'flexmock'
28
+
29
+ describe RightScraper::Scraper do
30
+ include RightScraper::SpecHelpers::DevelopmentModeEnvironment
31
+
32
+ include RightScraper::SharedExamples
33
+
34
+ shared_examples_for 'scrapes to given base dir' do
35
+ before(:each) do
36
+ @scraper = RightScraper::Scraper.new(:basedir => @tmpdir, :kind => :cookbook)
37
+ end
38
+
39
+ after(:each) do
40
+ FileUtils.remove_entry_secure @tmpdir unless @tmpdir.nil?
41
+ end
42
+
43
+ it 'starts out successful' do
44
+ @scraper.succeeded?.should be_true
45
+ @scraper.errors.should == []
46
+ end
47
+
48
+ context 'given a legal download repository' do
49
+ before(:each) do
50
+ @helper = RightScraper::DownloadRetrieverSpecHelper.new
51
+ @repo = @helper.repo
52
+ end
53
+
54
+ after(:each) do
55
+ @helper.close
56
+ end
57
+
58
+ it_should_behave_like "a normal repository"
59
+
60
+ it 'should log correctly as it scrapes' do
61
+ callback = flexmock("callback")
62
+ callback.should_receive(:call).with(:begin, :retrieving, "from #{@repo}", nil).once.ordered
63
+ callback.should_receive(:call).with(:begin, :initialize, String, nil).once.ordered
64
+ callback.should_receive(:call).with(:commit, :initialize, String, nil).once.ordered
65
+ callback.should_receive(:call).with(:begin, :downloading, "", nil).once.ordered
66
+ callback.should_receive(:call).with(:begin, :running_command, String, nil).once.ordered
67
+ callback.should_receive(:call).with(:commit, :running_command, String, nil).once.ordered
68
+ callback.should_receive(:call).with(:commit, :downloading, "", nil).once.ordered
69
+ callback.should_receive(:call).with(:begin, :unpacking, "", nil).once.ordered
70
+ callback.should_receive(:call).with(:begin, :running_command, String, nil).once.ordered
71
+ callback.should_receive(:call).with(:commit, :running_command, String, nil).once.ordered
72
+ callback.should_receive(:call).with(:commit, :unpacking, "", nil).once.ordered
73
+ callback.should_receive(:call).with(:commit, :retrieving, "from #{@repo}", nil).once.ordered
74
+ callback.should_receive(:call).with(:begin, :scraping, String, nil).once.ordered
75
+ callback.should_receive(:call).with(:begin, :finding_next_cookbook, String, nil).once.ordered
76
+ callback.should_receive(:call).with(:begin, :reading_cookbook, String, nil).once.ordered
77
+ callback.should_receive(:call).with(:begin, :scanning_filesystem, String, nil).once.ordered
78
+ callback.should_receive(:call).with(:begin, :metadata_parsing, "", nil).once.ordered
79
+ callback.should_receive(:call).with(:commit, :metadata_parsing, "", nil).once.ordered
80
+ callback.should_receive(:call).with(:commit, :scanning_filesystem, String, nil).once.ordered
81
+ callback.should_receive(:call).with(:commit, :reading_cookbook, String, nil).once.ordered
82
+ callback.should_receive(:call).with(:commit, :finding_next_cookbook, String, nil).once.ordered
83
+ callback.should_receive(:call).with(:begin, :next, "", nil).once.ordered
84
+ callback.should_receive(:call).with(:begin, :searching, "", nil).once.ordered
85
+ callback.should_receive(:call).with(:commit, :searching, "", nil).once.ordered
86
+ callback.should_receive(:call).with(:commit, :next, "", nil).once.ordered
87
+ callback.should_receive(:call).with(:begin, :next, "", nil).once.ordered
88
+ callback.should_receive(:call).with(:commit, :next, "", nil).once.ordered
89
+ callback.should_receive(:call).with(:commit, :scraping, String, nil).once.ordered
90
+ @scraper.scrape(@repo) do |phase, operation, explanation, exception|
91
+ callback.call(phase, operation, explanation, exception)
92
+ end
93
+ @scraper.errors.should == []
94
+ @scraper.succeeded?.should be_true
95
+ @scraper.resources.size.should == 1
96
+ end
97
+ end
98
+
99
+ context 'given several repositories' do
100
+ it 'should continue to scrape even if errors occur' do
101
+ GC.start
102
+ repo = RightScraper::Repositories::Base.from_hash(:display_name => 'illegal repo',
103
+ :repo_type => :download,
104
+ :url => "http://example.com/foo")
105
+ @scraper.scrape(repo)
106
+ helpers = [RightScraper::DownloadRetrieverSpecHelper,
107
+ RightScraper::DownloadRetrieverSpecHelper,
108
+ RightScraper::DownloadRetrieverSpecHelper]
109
+ helpers.each do |klass|
110
+ helper = klass.new
111
+ @scraper.scrape(helper.repo)
112
+ helper.close
113
+ end
114
+ @scraper.succeeded?.should be_false
115
+ @scraper.resources.size.should == 3
116
+ @scraper.errors.size.should == 1
117
+ end
118
+ end
119
+
120
+ it 'catches normal logging behavior' do
121
+ logger = @scraper.instance_variable_get(:@logger)
122
+ logger.should_not be_nil
123
+ logger.info("foo")
124
+ logger.error("foo")
125
+ @scraper.succeeded?.should be_false
126
+ @scraper.errors.should == [[nil, :log, {:severity => Logger::ERROR,
127
+ :message => "foo",
128
+ :progname => nil}]]
129
+ end
53
130
  end
54
-
55
- it 'should scrape from a hash' do
56
- @mock_scraper.should_receive(:scrape).with(RightScale::Repository, true, Proc).and_return(true)
57
- @mock_scraper.should_receive(:succeeded?).and_return(true)
58
- @mock_scraper.should_receive(:current_repo_dir).and_return('42')
59
- @scraper.scrape({:repo_type => :mock}) { }.should be_true
131
+
132
+ context 'when base dir is not provided' do
133
+ before(:each) do
134
+ @tmpdir = nil
135
+ end
136
+
137
+ it_should_behave_like 'scrapes to given base dir'
60
138
  end
61
-
62
- it 'should report failures' do
63
- @mock_scraper.should_receive(:scrape).with(RightScale::Repository, true, Proc).and_return(true)
64
- @mock_scraper.should_receive(:succeeded?).and_return(false)
65
- @mock_scraper.should_receive(:current_repo_dir).and_return('42')
66
- @scraper.scrape({:repo_type => :mock}) { }.should be_false
139
+
140
+ context 'when base dir is provided' do
141
+ before(:each) do
142
+ @tmpdir = Dir.mktmpdir
143
+ end
144
+
145
+ it_should_behave_like 'scrapes to given base dir'
67
146
  end
68
-
69
147
  end