validations 0.0.3

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