[rubygems/rubygems] Use a constant empty tar header to avoid extra allocations
[ruby.git] / test / etc / test_etc.rb
blob2eddcf49d732e84b48988beb9b17a1bae5b6f5a0
1 # frozen_string_literal: true
2 require "test/unit"
3 require "etc"
5 class TestEtc < Test::Unit::TestCase
6   def test_getlogin
7     s = Etc.getlogin
8     return if s == nil
9     assert(s.is_a?(String), "getlogin must return a String or nil")
10     assert_predicate(s, :valid_encoding?, "login name should be a valid string")
11   end
13   def test_passwd
14     Etc.passwd do |s|
15       assert_instance_of(String, s.name)
16       assert_instance_of(String, s.passwd) if s.respond_to?(:passwd)
17       assert_kind_of(Integer, s.uid)
18       assert_kind_of(Integer, s.gid)
19       assert_instance_of(String, s.gecos) if s.respond_to?(:gecos)
20       assert_instance_of(String, s.dir)
21       assert_instance_of(String, s.shell)
22       assert_kind_of(Integer, s.change) if s.respond_to?(:change)
23       assert_kind_of(Integer, s.quota) if s.respond_to?(:quota)
24       assert(s.age.is_a?(Integer) || s.age.is_a?(String)) if s.respond_to?(:age)
25       assert_instance_of(String, s.uclass) if s.respond_to?(:uclass)
26       assert_instance_of(String, s.comment) if s.respond_to?(:comment)
27       assert_kind_of(Integer, s.expire) if s.respond_to?(:expire)
28     end
30     Etc.passwd { assert_raise(RuntimeError) { Etc.passwd { } }; break }
31   end
33   def test_getpwuid
34     # password database is not unique on UID, and which entry will be
35     # returned by getpwuid() is not specified.
36     passwd = Hash.new {[]}
37     # on MacOSX, same entries are returned from /etc/passwd and Open
38     # Directory.
39     Etc.passwd {|s| passwd[s.uid] |= [s]}
40     passwd.each_pair do |uid, s|
41       assert_include(s, Etc.getpwuid(uid))
42     end
43     s = passwd[Process.euid]
44     unless s.empty?
45       assert_include(s, Etc.getpwuid)
46     end
47   end unless RUBY_PLATFORM.include?("android")
49   def test_getpwnam
50     passwd = {}
51     Etc.passwd do |s|
52       passwd[s.name] ||= s unless /\A\+/ =~ s.name
53     end
54     passwd.each_value do |s|
55       assert_equal(s, Etc.getpwnam(s.name))
56     end
57   end unless RUBY_PLATFORM.include?("android")
59   def test_passwd_with_low_level_api
60     a = []
61     Etc.passwd {|s| a << s }
62     b = []
63     Etc.setpwent
64     while s = Etc.getpwent
65       b << s
66     end
67     Etc.endpwent
68     assert_equal(a, b)
69   end
71   def test_group
72     Etc.group do |s|
73       assert_instance_of(String, s.name)
74       assert_instance_of(String, s.passwd) if s.respond_to?(:passwd)
75       assert_kind_of(Integer, s.gid)
76     end
78     Etc.group { assert_raise(RuntimeError) { Etc.group { } }; break }
79   end
81   def test_getgrgid
82     # group database is not unique on GID, and which entry will be
83     # returned by getgrgid() is not specified.
84     groups = Hash.new {[]}
85     # on MacOSX, same entries are returned from /etc/group and Open
86     # Directory.
87     Etc.group {|s| groups[s.gid] |= [[s.name, s.gid]]}
88     groups.each_pair do |gid, s|
89       g = Etc.getgrgid(gid)
90       assert_include(s, [g.name, g.gid])
91     end
92     s = groups[Process.egid]
93     unless s.empty?
94       g = Etc.getgrgid
95       assert_include(s, [g.name, g.gid])
96     end
97   end
99   def test_getgrnam
100     groups = Hash.new {[]}
101     Etc.group do |s|
102       groups[s.name] |= [s.gid] unless /\A\+/ =~ s.name
103     end
104     groups.each_pair do |n, s|
105       assert_include(s, Etc.getgrnam(n).gid)
106     end
107   end
109   def test_group_with_low_level_api
110     a = []
111     Etc.group {|s| a << s }
112     b = []
113     Etc.setgrent
114     while s = Etc.getgrent
115       b << s
116     end
117     Etc.endgrent
118     assert_equal(a, b)
119   end
121   def test_uname
122     begin
123       uname = Etc.uname
124     rescue NotImplementedError
125       return
126     end
127     assert_kind_of(Hash, uname)
128     [:sysname, :nodename, :release, :version, :machine].each {|sym|
129       assert_operator(uname, :has_key?, sym)
130       assert_kind_of(String, uname[sym])
131     }
132   end
134   def test_sysconf
135     begin
136       Etc.sysconf
137     rescue NotImplementedError
138       return
139     rescue ArgumentError
140     end
141     assert_kind_of(Integer, Etc.sysconf(Etc::SC_CLK_TCK))
142   end if defined?(Etc::SC_CLK_TCK)
144   def test_confstr
145     begin
146       Etc.confstr
147     rescue NotImplementedError
148       return
149     rescue ArgumentError
150     end
151     assert_kind_of(String, Etc.confstr(Etc::CS_PATH))
152   end if defined?(Etc::CS_PATH)
154   def test_pathconf
155     begin
156       Etc.confstr
157     rescue NotImplementedError
158       return
159     rescue ArgumentError
160     end
161     IO.pipe {|r, w|
162       val = w.pathconf(Etc::PC_PIPE_BUF)
163       assert(val.nil? || val.kind_of?(Integer))
164     }
165   end if defined?(Etc::PC_PIPE_BUF)
167   def test_nprocessors
168     n = Etc.nprocessors
169     assert_operator(1, :<=, n)
170   end
172   def test_ractor
173     return unless Etc.passwd # => skip test if no platform support
174     Etc.endpwent
176     assert_ractor(<<~RUBY, require: 'etc')
177       ractor = Ractor.new do
178         Etc.passwd do |s|
179           Ractor.yield :sync
180           Ractor.yield s.name
181           break :done
182         end
183       end
184       ractor.take # => :sync
185       assert_raise RuntimeError, /parallel/ do
186         Etc.passwd {}
187       end
188       name = ractor.take # => first name
189       ractor.take # => :done
190       name2 = Etc.passwd do |s|
191         break s.name
192       end
193       assert_equal(name2, name)
194     RUBY
195   end