1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
|
#! /usr/bin/env ruby
require 'spec_helper'
require 'puppet/util/checksums'
describe Puppet::Util::Checksums do
include PuppetSpec::Files
before do
@summer = Object.new
@summer.extend(Puppet::Util::Checksums)
end
content_sums = [:md5, :md5lite, :sha1, :sha1lite, :sha256, :sha256lite]
file_only = [:ctime, :mtime, :none]
content_sums.each do |sumtype|
it "should be able to calculate #{sumtype} sums from strings" do
@summer.should be_respond_to(sumtype)
end
end
content_sums.each do |sumtype|
it "should know the expected length of #{sumtype} sums" do
@summer.should be_respond_to(sumtype.to_s + "_hex_length")
end
end
[content_sums, file_only].flatten.each do |sumtype|
it "should be able to calculate #{sumtype} sums from files" do
@summer.should be_respond_to(sumtype.to_s + "_file")
end
end
[content_sums, file_only].flatten.each do |sumtype|
it "should be able to calculate #{sumtype} sums from stream" do
@summer.should be_respond_to(sumtype.to_s + "_stream")
end
end
it "should have a method for determining whether a given string is a checksum" do
@summer.should respond_to(:checksum?)
end
%w{{md5}asdfasdf {sha1}asdfasdf {ctime}asdasdf {mtime}asdfasdf
{sha256}asdfasdf {sha256lite}asdfasdf}.each do |sum|
it "should consider #{sum} to be a checksum" do
@summer.should be_checksum(sum)
end
end
%w{{nosuchsumthislong}asdfasdf {a}asdfasdf {ctime}}.each do |sum|
it "should not consider #{sum} to be a checksum" do
@summer.should_not be_checksum(sum)
end
end
it "should have a method for stripping a sum type from an existing checksum" do
@summer.sumtype("{md5}asdfasdfa").should == "md5"
end
it "should have a method for stripping the data from a checksum" do
@summer.sumdata("{md5}asdfasdfa").should == "asdfasdfa"
end
it "should return a nil sumtype if the checksum does not mention a checksum type" do
@summer.sumtype("asdfasdfa").should be_nil
end
{:md5 => Digest::MD5, :sha1 => Digest::SHA1, :sha256 => Digest::SHA256}.each do |sum, klass|
describe("when using #{sum}") do
it "should use #{klass} to calculate string checksums" do
klass.expects(:hexdigest).with("mycontent").returns "whatever"
@summer.send(sum, "mycontent").should == "whatever"
end
it "should use incremental #{klass} sums to calculate file checksums" do
digest = mock 'digest'
klass.expects(:new).returns digest
file = "/path/to/my/file"
fh = mock 'filehandle'
fh.expects(:read).with(4096).times(3).returns("firstline").then.returns("secondline").then.returns(nil)
#fh.expects(:read).with(512).returns("secondline")
#fh.expects(:read).with(512).returns(nil)
File.expects(:open).with(file, "rb").yields(fh)
digest.expects(:<<).with "firstline"
digest.expects(:<<).with "secondline"
digest.expects(:hexdigest).returns :mydigest
@summer.send(sum.to_s + "_file", file).should == :mydigest
end
it "should yield #{klass} to the given block to calculate stream checksums" do
digest = mock 'digest'
klass.expects(:new).returns digest
digest.expects(:hexdigest).returns :mydigest
@summer.send(sum.to_s + "_stream") do |checksum|
checksum.should == digest
end.should == :mydigest
end
end
end
{:md5lite => Digest::MD5, :sha1lite => Digest::SHA1, :sha256lite => Digest::SHA256}.each do |sum, klass|
describe("when using #{sum}") do
it "should use #{klass} to calculate string checksums from the first 512 characters of the string" do
content = "this is a test" * 100
klass.expects(:hexdigest).with(content[0..511]).returns "whatever"
@summer.send(sum, content).should == "whatever"
end
it "should use #{klass} to calculate a sum from the first 512 characters in the file" do
digest = mock 'digest'
klass.expects(:new).returns digest
file = "/path/to/my/file"
fh = mock 'filehandle'
fh.expects(:read).with(512).returns('my content')
File.expects(:open).with(file, "rb").yields(fh)
digest.expects(:<<).with "my content"
digest.expects(:hexdigest).returns :mydigest
@summer.send(sum.to_s + "_file", file).should == :mydigest
end
end
end
[:ctime, :mtime].each do |sum|
describe("when using #{sum}") do
it "should use the '#{sum}' on the file to determine the ctime" do
file = "/my/file"
stat = mock 'stat', sum => "mysum"
Puppet::FileSystem.expects(:stat).with(file).returns(stat)
@summer.send(sum.to_s + "_file", file).should == "mysum"
end
it "should return nil for streams" do
expectation = stub "expectation"
expectation.expects(:do_something!).at_least_once
@summer.send(sum.to_s + "_stream"){ |checksum| checksum << "anything" ; expectation.do_something! }.should be_nil
end
end
end
describe "when using the none checksum" do
it "should return an empty string" do
@summer.none_file("/my/file").should == ""
end
it "should return an empty string for streams" do
expectation = stub "expectation"
expectation.expects(:do_something!).at_least_once
@summer.none_stream{ |checksum| checksum << "anything" ; expectation.do_something! }.should == ""
end
end
{:md5 => Digest::MD5, :sha1 => Digest::SHA1}.each do |sum, klass|
describe "when using #{sum}" do
let(:content) { "hello\r\nworld" }
let(:path) do
path = tmpfile("checksum_#{sum}")
File.open(path, 'wb') {|f| f.write(content)}
path
end
it "should preserve nl/cr sequences" do
@summer.send(sum.to_s + "_file", path).should == klass.hexdigest(content)
end
end
end
end
|