1require 'rubygems/package/tar_test_case'
2require 'rubygems/package/tar_writer'
3
4class TestGemPackageTarWriter < Gem::Package::TarTestCase
5
6  def setup
7    super
8
9    @data = 'abcde12345'
10    @io = TempIO.new
11    @tar_writer = Gem::Package::TarWriter.new @io
12  end
13
14  def teardown
15    @tar_writer.close unless @tar_writer.closed?
16
17    super
18  end
19
20  def test_add_file
21    @tar_writer.add_file 'x', 0644 do |f| f.write 'a' * 10 end
22
23    assert_headers_equal(tar_file_header('x', '', 0644, 10),
24                         @io.string[0, 512])
25    assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
26    assert_equal 1024, @io.pos
27  end
28
29  def test_add_file_digest
30    digest_algorithms = OpenSSL::Digest::SHA1, OpenSSL::Digest::SHA512
31
32    digests = @tar_writer.add_file_digest 'x', 0644, digest_algorithms do |io|
33      io.write 'a' * 10
34    end
35
36    assert_equal '3495ff69d34671d1e15b33a63c1379fdedd3a32a',
37                 digests['SHA1'].hexdigest
38    assert_equal '4714870aff6c97ca09d135834fdb58a6389a50c1' \
39                 '1fef8ec4afef466fb60a23ac6b7a9c92658f14df' \
40                 '4993d6b40a4e4d8424196afc347e97640d68de61' \
41                 'e1cf14b0',
42                 digests['SHA512'].hexdigest
43
44    assert_headers_equal(tar_file_header('x', '', 0644, 10),
45                         @io.string[0, 512])
46    assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
47    assert_equal 1024, @io.pos
48  end
49
50  def test_add_file_digest_multiple
51    digest_algorithms = [OpenSSL::Digest::SHA1, OpenSSL::Digest::SHA512]
52
53    digests = @tar_writer.add_file_digest 'x', 0644, digest_algorithms do |io|
54      io.write 'a' * 10
55    end
56
57    assert_equal '3495ff69d34671d1e15b33a63c1379fdedd3a32a',
58                 digests['SHA1'].hexdigest
59    assert_equal '4714870aff6c97ca09d135834fdb58a6389a50c1' \
60                 '1fef8ec4afef466fb60a23ac6b7a9c92658f14df' \
61                 '4993d6b40a4e4d8424196afc347e97640d68de61' \
62                 'e1cf14b0',
63                 digests['SHA512'].hexdigest
64
65    assert_headers_equal(tar_file_header('x', '', 0644, 10),
66                         @io.string[0, 512])
67    assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
68    assert_equal 1024, @io.pos
69  end
70
71  def test_add_file_signer
72    signer = Gem::Security::Signer.new PRIVATE_KEY, [PUBLIC_CERT]
73
74    @tar_writer.add_file_signed 'x', 0644, signer do |io|
75      io.write 'a' * 10
76    end
77
78    assert_headers_equal(tar_file_header('x', '', 0644, 10),
79                         @io.string[0, 512])
80    assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
81
82    digest = signer.digest_algorithm.new
83    digest.update 'a' * 10
84
85    signature = signer.sign digest.digest
86
87    assert_headers_equal(tar_file_header('x.sig', '', 0444, signature.length),
88                         @io.string[1024, 512])
89    assert_equal "#{signature}#{"\0" * (512 - signature.length)}",
90                 @io.string[1536, 512]
91
92    assert_equal 2048, @io.pos
93  end
94
95  def test_add_file_signer_empty
96    signer = Gem::Security::Signer.new nil, nil
97
98    @tar_writer.add_file_signed 'x', 0644, signer do |io|
99      io.write 'a' * 10
100    end
101
102    assert_headers_equal(tar_file_header('x', '', 0644, 10),
103                         @io.string[0, 512])
104    assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
105
106    digest = signer.digest_algorithm.new
107    digest.update 'a' * 10
108
109    assert_equal 1024, @io.pos
110  end
111
112  def test_add_file_simple
113    @tar_writer.add_file_simple 'x', 0644, 10 do |io| io.write "a" * 10 end
114
115    assert_headers_equal(tar_file_header('x', '', 0644, 10),
116                         @io.string[0, 512])
117
118    assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512]
119    assert_equal 1024, @io.pos
120  end
121
122  def test_add_file_simple_padding
123    @tar_writer.add_file_simple 'x', 0, 100
124
125    assert_headers_equal tar_file_header('x', '', 0, 100),
126                         @io.string[0, 512]
127
128    assert_equal "\0" * 512, @io.string[512, 512]
129  end
130
131  def test_add_file_simple_data
132    @tar_writer.add_file_simple("lib/foo/bar", 0, 10) { |f| f.write @data }
133    @tar_writer.flush
134
135    assert_equal @data + ("\0" * (512-@data.size)),
136                 @io.string[512, 512]
137  end
138
139  def test_add_file_simple_size
140    assert_raises Gem::Package::TarWriter::FileOverflow do
141      @tar_writer.add_file_simple("lib/foo/bar", 0, 10) do |io|
142        io.write "1" * 11
143      end
144    end
145  end
146
147  def test_add_file_unseekable
148    assert_raises Gem::Package::NonSeekableIO do
149      Gem::Package::TarWriter.new(Object.new).add_file 'x', 0
150    end
151  end
152
153  def test_close
154    @tar_writer.close
155
156    assert_equal "\0" * 1024, @io.string
157
158    e = assert_raises IOError do
159      @tar_writer.close
160    end
161    assert_equal 'closed Gem::Package::TarWriter', e.message
162
163    e = assert_raises IOError do
164      @tar_writer.flush
165    end
166    assert_equal 'closed Gem::Package::TarWriter', e.message
167
168    e = assert_raises IOError do
169      @tar_writer.add_file 'x', 0
170    end
171    assert_equal 'closed Gem::Package::TarWriter', e.message
172
173    e = assert_raises IOError do
174      @tar_writer.add_file_simple 'x', 0, 0
175    end
176    assert_equal 'closed Gem::Package::TarWriter', e.message
177
178    e = assert_raises IOError do
179      @tar_writer.mkdir 'x', 0
180    end
181    assert_equal 'closed Gem::Package::TarWriter', e.message
182  end
183
184  def test_mkdir
185    @tar_writer.mkdir 'foo', 0644
186
187    assert_headers_equal tar_dir_header('foo', '', 0644),
188                         @io.string[0, 512]
189    assert_equal 512, @io.pos
190  end
191
192  def test_split_name
193    assert_equal ['b' * 100, 'a' * 155],
194                 @tar_writer.split_name("#{'a' * 155}/#{'b' * 100}")
195
196    assert_equal ["#{'qwer/' * 19}bla", 'a' * 151],
197                 @tar_writer.split_name("#{'a' * 151}/#{'qwer/' * 19}bla")
198  end
199
200  def test_split_name_too_long_name
201    name = File.join 'a', 'b' * 100
202    assert_equal ['b' * 100, 'a'], @tar_writer.split_name(name)
203
204    assert_raises Gem::Package::TooLongFileName do
205      name = File.join 'a', 'b' * 101
206      @tar_writer.split_name name
207    end
208  end
209
210  def test_split_name_too_long_prefix
211    name = File.join 'a' * 155, 'b'
212    assert_equal ['b', 'a' * 155], @tar_writer.split_name(name)
213
214    assert_raises Gem::Package::TooLongFileName do
215      name = File.join 'a' * 156, 'b'
216      @tar_writer.split_name name
217    end
218  end
219
220  def test_split_name_too_long_total
221    assert_raises Gem::Package::TooLongFileName do
222      @tar_writer.split_name 'a' * 257
223    end
224  end
225
226end
227
228