validations 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ require 'validations/index_validations'
2
+
3
+ module Validations
4
+ end
@@ -0,0 +1,113 @@
1
+ require 'params'
2
+ require 'log'
3
+ require 'content_data'
4
+ require 'file_indexing/index_agent'
5
+
6
+ # TODO additional params?
7
+ # TODO are params names good enough?
8
+ module Validations
9
+ class IndexValidations
10
+
11
+ # TODO should it be renamed cause it can validate any indexes, not specially remote, one against another.
12
+
13
+ # Validates remote index against local file system.
14
+ # Remote index defined valid when every remote content has at least one valid local instance.
15
+ #
16
+ # There are two levels of validation, controlled by instance_check_level system parameter:
17
+ # * shallow - quick, tests instance for file existence and attributes.
18
+ # * deep - can take more time, in addition to shallow recalculates hash sum.
19
+ # For more infoemation see <tt>ContentData</tt> documentation.
20
+ # @param [ContentData] remote_index it's contents should be validate against local index
21
+ # @param [ContentData] local_index contains local contents and instances used for validation
22
+ # @param [Hash] params hash of parameters of validation, can be used to return additional data
23
+ #
24
+ # Supported key/value combinations:
25
+ # * key is <tt>:failed</tt> value is <tt>ContentData</tt> used to return failed instances
26
+ # @return [Boolean] true when every remote content has at least one valid local instance, false otherwise
27
+ # @raise [ArgumentError] when instance_check_level is incorrect
28
+ def IndexValidations.validate_remote_index(remote_index, local_index, params = nil)
29
+ raise ArgumentError 'remote_index must be defined' if remote_index.nil?
30
+ raise ArgumentError 'local index must be defined' if local_index.nil?
31
+
32
+ # used to answer whether specific param was set
33
+ param_exists = Proc.new do |param|
34
+ !(params.nil? || params[param].nil?)
35
+ end
36
+
37
+ # used to process method parameters centrally
38
+ process_params = Proc.new do |values|
39
+ # values is a Hash with keys: :content, :instance and value appropriate to key
40
+ if param_exists.call :failed
41
+ unless values[:content].nil?
42
+ params[:failed].add_content values[:content]
43
+ end
44
+ unless values[:instance].nil?
45
+ # appropriate content should be already added
46
+ params[:failed].add_instance values[:instance]
47
+ end
48
+ end
49
+ end
50
+
51
+ # result variable
52
+ is_valid = true
53
+ # contains contents absent or without valid instances on local system
54
+ # and corresponding local instances
55
+ failed = ContentData::ContentData.new
56
+ # contains checksums of contains absent in local
57
+ absent_checksums = Array.new
58
+
59
+ # contains local instances corresponding to given remote index contents
60
+ local_index_to_check = ContentData::ContentData.new
61
+
62
+ # check whether remote contents exist locally and add them for further validations
63
+ remote_index.contents.each_key do |checksum|
64
+ if local_index.content_exists checksum
65
+ local_index_to_check.add_content local_index.contents[checksum]
66
+ else
67
+ is_valid = false
68
+ failed.add_content remote_index.contents[checksum]
69
+ absent_checksums << checksum
70
+ end
71
+ end
72
+
73
+ # add instances of contents that should be check
74
+ local_index.instances.each_value do |instance|
75
+ if remote_index.content_exists instance.checksum
76
+ local_index_to_check.add_instance instance
77
+ end
78
+ end
79
+
80
+
81
+ # validate against local file system
82
+ is_valid = local_index_to_check.validate(:failed => failed) && is_valid
83
+
84
+ # contains contents that have at least one valid local instance,
85
+ # then also corresponding remote content defined valid
86
+ contents_with_succeeded_instances = ContentData::ContentData.remove_instances failed, local_index
87
+
88
+ # write summary to log
89
+ # TODO should be controlled from params?
90
+ failed.contents.each_key do |checksum|
91
+ if absent_checksums.include? checksum
92
+ Log.warning "Content #{checksum} is absent in the local file system"
93
+ elsif !contents_with_succeeded_instances.content_exists checksum
94
+ # if checked content have no valid local instances
95
+ # then content defined invalid
96
+ Log.warning "Content #{checksum} is invalid in the local file system"
97
+ end
98
+ end
99
+
100
+ # if needed process output params
101
+ unless params.nil? || params.empty?
102
+ remote_index.instances.each_value do |instance|
103
+ unless contents_with_succeeded_instances.content_exists instance.checksum
104
+ process_params.call :content => remote_index.contents[instance.checksum], :instance => instance
105
+ end
106
+ end
107
+ end
108
+
109
+ is_valid
110
+ end
111
+
112
+ end # class IndexValidations
113
+ end # module Validations
@@ -0,0 +1,3 @@
1
+ module Validations
2
+ VERSION = "0.0.3"
3
+ end
@@ -0,0 +1,100 @@
1
+ require 'rspec'
2
+ require_relative '../../lib/validations.rb'
3
+
4
+ module Validations
5
+ module Spec
6
+ describe 'Index validation' do
7
+ context 'of index from other file system' do
8
+ before :all do
9
+ @size = 100
10
+ @path = '/dir1/dir2/file'
11
+ @path2 = '/dir3/dir4/file'
12
+ @path3 = '/dir5/dir6/file'
13
+ @path4 = '/dir7/dir8/file'
14
+ @mod_time = 123456
15
+ @checksum = 'abcde987654321'
16
+ @checksum2 = '987654321abcde'
17
+ end
18
+
19
+ before :each do
20
+ @index = ContentData::ContentData.new
21
+ @remote_index = ContentData::ContentData.new
22
+
23
+ @content = double :content, :checksum => @checksum,
24
+ :size => @size, :first_appearance_time => @mod_time
25
+ @content2 = double :content2, :checksum => @checksum2,
26
+ :size => @size, :first_appearance_time => @mod_time
27
+
28
+ @instance = double :instance, :checksum => @checksum, :global_path => @path,
29
+ :size => @size, :full_path => @path, :modification_time => @mod_time
30
+ @instance2 = double :instance2, :checksum => @checksum2, :global_path => @path2,
31
+ :size => @size, :full_path => @path2, :modification_time => @mod_time
32
+ @instance3 = double :instance3, :checksum => @checksum, :global_path => @path3,
33
+ :size => @size, :full_path => @path3, :modification_time => @mod_time
34
+ @instance4 = double :instance4, :checksum => @checksum2, :global_path => @path4,
35
+ :size => @size, :full_path => @path4, :modification_time => @mod_time
36
+
37
+ @index.add_content @content
38
+ @index.add_content @content2
39
+ @index.add_instance @instance
40
+ @index.add_instance @instance2
41
+
42
+ @remote_index.add_content @content
43
+ @remote_index.add_content @content2
44
+ @remote_index.add_instance @instance3
45
+ @remote_index.add_instance @instance4
46
+
47
+ File.stub(:exists?).and_return(true)
48
+ File.stub(:size).and_return(@size)
49
+ File.stub(:mtime).and_return(@mod_time)
50
+ #ContentData::ContentData.stub(:format_time).with(@mod_time).and_return(@mod_time)
51
+ Params['instance_check_level'] = 'shallow'
52
+ end
53
+
54
+ it 'succeeds when all remote contents has valid local instance' do
55
+ IndexValidations.validate_remote_index(@remote_index, @index).should be_true
56
+ end
57
+
58
+ it 'fails when remote content is absent' do
59
+ absent_checksum = '123'
60
+ absent_content = double :absent_content, :checksum => absent_checksum, \
61
+ :size => @size, :first_appearance_time => @mod_time
62
+ @remote_index.add_content absent_content
63
+ IndexValidations.validate_remote_index(@remote_index, @index).should be_false
64
+ end
65
+
66
+ it 'fails when local instance of remote content is invalid' do
67
+ modified_mtime = @mod_time + 10
68
+ File.stub(:mtime).with(@path).and_return(modified_mtime)
69
+ #ContentData::ContentData.stub(:format_time).with(modified_mtime).and_return(modified_mtime)
70
+ IndexValidations.validate_remote_index(@remote_index, @index).should be_false
71
+ end
72
+
73
+ it ':failed param returns index of absent contents or contents without valid instances' do
74
+ absent_checksum = '123'
75
+ absent_path = '/dir9/dir10/absent_file'
76
+ absent_content = double :absent_content, :checksum => absent_checksum, \
77
+ :size => @size, :first_appearance_time => @mod_time
78
+ absent_instance = double :instance, :checksum => absent_checksum, :global_path => absent_path,
79
+ :size => @size, :full_path => absent_path, :modification_time => @mod_time
80
+ @remote_index.add_content absent_content
81
+ @remote_index.add_instance absent_instance
82
+
83
+ # invalid instance has @path2 path on local and @path4 on remote
84
+ modified_mtime = @mod_time + 10
85
+ File.stub(:mtime).with(@path2).and_return(modified_mtime)
86
+ #ContentData::ContentData.stub(:format_time).with(modified_mtime).and_return(modified_mtime)
87
+
88
+ failed = ContentData::ContentData.new
89
+ IndexValidations.validate_remote_index(@remote_index, @index, :failed => failed)
90
+ failed.contents.should have(2).items
91
+ failed.contents.keys.should include(absent_checksum, @checksum2)
92
+ failed.instances.should have(2).items
93
+ failed.instances.keys.should include(@path4)
94
+
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: validations
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Genady Petelko
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: log
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: params
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: content_data
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: file_indexing
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Used to validate ContentData objects.
79
+ email: nukegluk@gmail.com
80
+ executables: []
81
+ extensions: []
82
+ extra_rdoc_files: []
83
+ files:
84
+ - lib/validations.rb
85
+ - lib/validations/index_validations.rb
86
+ - lib/validations/version.rb
87
+ - spec/validations/index_validations_spec.rb
88
+ homepage: http://github.com/kolmanv/bbfs
89
+ licenses: []
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 1.8.25
109
+ signing_key:
110
+ specification_version: 3
111
+ summary: Library for validating data.
112
+ test_files:
113
+ - spec/validations/index_validations_spec.rb
114
+ has_rdoc: