File: test_object_space.rb

package info (click to toggle)
jruby 1.7.26-1%2Bdeb9u1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 84,572 kB
  • sloc: ruby: 669,910; java: 253,056; xml: 35,152; ansic: 9,187; yacc: 7,267; cpp: 5,244; sh: 1,036; makefile: 345; jsp: 48; tcl: 40
file content (126 lines) | stat: -rw-r--r-- 3,464 bytes parent folder | download
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
require 'test/unit'
require 'test/test_helper'
require 'tempfile'
require 'rbconfig'
require 'jruby'

#
# Find the name of the interpreter.
#  FIXME: This should be moved to a common location.
#WINDOWS = RbConfig::CONFIG['host_os'] =~ /Windows|mswin/
#SEPARATOR = WINDOWS ? '\\' : '/'
#bin = RbConfig::CONFIG['bindir'].gsub('/', SEPARATOR)
#$interpreter = [bin, RbConfig::CONFIG['ruby_install_name']].join(SEPARATOR)

class TestObjectSpace < Test::Unit::TestCase
    include TestHelper

    #
    # Check that two arrays contain the same "bag" of elements.
    # A mathematical bag differs from a "set" by counting the
    # occurences of each element. So as a bag [1,2,1] differs from
    # [2,1] (but is equal to [1,1,2]).
    #
    # The method only relies on the == operator to match objects
    # from the two arrays. The elements of the arrays may contain
    # objects that are not "Comparable".
    # 
    # FIXME: This should be moved to common location.
    def assert_bag_equal(expected, actual)
      # For each object in "actual" we remove an equal object
      # from "expected". If we can match objects pairwise from the
      # two arrays we have two equal "bags". The method Array#index
      # uses == internally. We operate on a copy of "expected" to
      # avoid destructively changing the argument.
      #
      expected_left = expected.dup
      actual.each do |x|
        if j = expected_left.index(x)
          expected_left.slice!(j)
        end
      end
      assert( expected.length == actual.length && expected_left.length == 0,
             "Expected: #{expected.inspect}, Actual: #{actual.inspect}")
    end

  def test_s__id2ref
    skip("object space is not enabled") unless JRuby.runtime.object_space_enabled?
    s = "hello"
    t = ObjectSpace._id2ref(s.__id__)
    assert_equal(s, t)
    assert_equal(s.__id__, t.__id__)
  end


  # finalizer manipulation
  def test_s_finalizers
    tf = Tempfile.new("tf")
    begin
      tf.puts %{
	a = "string"
	ObjectSpace.define_finalizer(a) { puts "OK" }
      }
      tf.close
      if ENV['OS'] =~ /\AWin/
        command = %{#{interpreter} "#{tf.path}"}
      else
        command = %{#{interpreter} #{tf.path}}
      end
      IO.popen(command) do |p|
	assert_equal("OK", p.gets.chomp)
      end
    ensure
      tf.close(true) rescue nil
    end
  end

  class A;      end
  class B < A;  end
  class C < A;  end
  class D < C;  end

  def test_s_each_object
    skip("object space is not enabled") unless JRuby.runtime.object_space_enabled?
    a = A.new
    b = B.new
    c = C.new
    d = D.new

    res = []
    ObjectSpace.each_object(TestObjectSpace::A) { |o| res << o }
    assert_bag_equal([a, b, c, d], res)

    res = []
    ObjectSpace.each_object(B) { |o| res << o }
    assert_bag_equal([b], res)

    res = []
    ObjectSpace.each_object(C) { |o| res << o }
    assert_bag_equal([c, d], res)
  end

  # Demonstrate NPE referencing gc'ed var in conditional (JRUBY-1125)
  def test_object_ref_goes_away
    # make an object
    x = 'xxx'

    # save the id
    n = x.object_id

    # nil the reference
    x = nil

    # force GC (and wait until var is gone)
    t = Time.now
    (JRuby.gc; sleep 0.1) until (ObjectSpace._id2ref(n).nil? || (Time.now - t > 5))

    # straight reference should succeed
    assert_nil(ObjectSpace._id2ref n)

    # reference in conditional caused NPE
    assert_nothing_raised {
      if ObjectSpace._id2ref n
      end
    }
  end
end