summaryrefslogtreecommitdiff
path: root/test/rubygems/test_gem_package_tar_input.rb
blob: ee8e53712cf08105dc541e28e07c463307476879 (plain)
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
require 'rubygems/package/tar_test_case'
require 'rubygems/package/tar_input'

class TestGemPackageTarInput < Gem::Package::TarTestCase

  # Sometimes the setgid bit doesn't take.  Don't know if this is a problem on
  # all systems, or just some.  But for now, we will ignore it in the tests.
  SETGID_BIT = 02000

  def setup
    super

    inner_tar = tar_file_header("bla", "", 0612, 10)
    inner_tar += "0123456789" + "\0" * 502
    inner_tar += tar_file_header("foo", "", 0636, 5)
    inner_tar += "01234" + "\0" * 507
    inner_tar += tar_dir_header("__dir__", "", 0600)
    inner_tar += "\0" * 1024
    str = TempIO.new

    begin
      os = Zlib::GzipWriter.new str
      os.write inner_tar
    ensure
      os.finish
    end

    str.rewind

    @file = File.join @tempdir, 'bla.tar'

    File.open @file, 'wb' do |f|
      f.write tar_file_header("data.tar.gz", "", 0644, str.string.size)
      f.write str.string
      f.write "\0" * ((512 - (str.string.size % 512)) % 512 )

      @spec = Gem::Specification.new do |spec|
        spec.author = "Mauricio :)"
      end

      meta = @spec.to_yaml

      f.write tar_file_header("metadata", "", 0644, meta.size)
      f.write meta + "\0" * (1024 - meta.size)
      f.write "\0" * 1024
    end

    @entry_names = %w{bla foo __dir__}
    @entry_sizes = [10, 5, 0]
    #FIXME: are these modes system dependent?
    @entry_modes = [0100612, 0100636, 040600]
    @entry_files = %W[#{@tempdir}/bla #{@tempdir}/foo]
    @entry_contents = %w[0123456789 01234]
  end

  def test_initialize_no_metadata_file
    Tempfile.open 'no_meta' do |io|
      io.write tar_file_header('a', '', 0644, 1)
      io.write 'a'
      io.rewind

      e = assert_raises Gem::Package::FormatError do
        open io.path, Gem.binary_mode do |file|
          Gem::Package::TarInput.open file do end
        end
      end

      assert_equal "no metadata found in #{io.path}", e.message
      assert_equal io.path, e.path
    end
  end

  def test_each
    open @file, 'rb' do |io|
      Gem::Package::TarInput.open io do |tar_input|
        count = 0

        tar_input.each_with_index do |entry, i|
          count = i

          assert_kind_of Gem::Package::TarReader::Entry, entry
          assert_equal @entry_names[i], entry.header.name
          assert_equal @entry_sizes[i], entry.header.size
        end

        assert_equal 2, count

        assert_equal @spec, tar_input.metadata
      end
    end
  end

  def test_extract_entry
    open @file, 'rb' do |io|
      Gem::Package::TarInput.open io do |tar_input|
        assert_equal @spec, tar_input.metadata

        count = 0

        tar_input.each_with_index do |entry, i|
          count = i
          tar_input.extract_entry @tempdir, entry
          name = File.join @tempdir, entry.header.name

          if entry.directory? then
            assert File.directory?(name)
          else
            assert File.file?(name)
            assert_equal @entry_sizes[i], File.stat(name).size
            #FIXME: win32? !!
          end

          unless Gem.win_platform? then
            assert_equal @entry_modes[i], File.stat(name).mode & (~SETGID_BIT)
          end
        end

        assert_equal 2, count
      end
    end

    @entry_files.each_with_index do |x, i|
      assert File.file?(x)
      assert_equal @entry_contents[i], Gem.read_binary(x)
    end
  end

end