summaryrefslogtreecommitdiff
path: root/spec/ruby/core/gc
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core/gc')
-rw-r--r--spec/ruby/core/gc/auto_compact_spec.rb24
-rw-r--r--spec/ruby/core/gc/config_spec.rb97
-rw-r--r--spec/ruby/core/gc/count_spec.rb17
-rw-r--r--spec/ruby/core/gc/disable_spec.rb18
-rw-r--r--spec/ruby/core/gc/enable_spec.rb13
-rw-r--r--spec/ruby/core/gc/garbage_collect_spec.rb15
-rw-r--r--spec/ruby/core/gc/measure_total_time_spec.rb17
-rw-r--r--spec/ruby/core/gc/profiler/clear_spec.rb5
-rw-r--r--spec/ruby/core/gc/profiler/disable_spec.rb16
-rw-r--r--spec/ruby/core/gc/profiler/enable_spec.rb17
-rw-r--r--spec/ruby/core/gc/profiler/enabled_spec.rb21
-rw-r--r--spec/ruby/core/gc/profiler/report_spec.rb5
-rw-r--r--spec/ruby/core/gc/profiler/result_spec.rb7
-rw-r--r--spec/ruby/core/gc/profiler/total_time_spec.rb7
-rw-r--r--spec/ruby/core/gc/start_spec.rb12
-rw-r--r--spec/ruby/core/gc/stat_spec.rb62
-rw-r--r--spec/ruby/core/gc/stress_spec.rb27
-rw-r--r--spec/ruby/core/gc/total_time_spec.rb13
18 files changed, 393 insertions, 0 deletions
diff --git a/spec/ruby/core/gc/auto_compact_spec.rb b/spec/ruby/core/gc/auto_compact_spec.rb
new file mode 100644
index 0000000000..33ad1cb56c
--- /dev/null
+++ b/spec/ruby/core/gc/auto_compact_spec.rb
@@ -0,0 +1,24 @@
+require_relative '../../spec_helper'
+
+describe "GC.auto_compact" do
+ it "can set and get a boolean value" do
+ begin
+ GC.auto_compact = GC.auto_compact
+ rescue NotImplementedError # platform does not support autocompact
+ skip
+ end
+
+ original = GC.auto_compact
+ begin
+ GC.auto_compact = !original
+ rescue NotImplementedError # platform does not support autocompact
+ skip
+ end
+
+ begin
+ GC.auto_compact.should == !original
+ ensure
+ GC.auto_compact = original
+ end
+ end
+end
diff --git a/spec/ruby/core/gc/config_spec.rb b/spec/ruby/core/gc/config_spec.rb
new file mode 100644
index 0000000000..57160f122c
--- /dev/null
+++ b/spec/ruby/core/gc/config_spec.rb
@@ -0,0 +1,97 @@
+require_relative '../../spec_helper'
+
+ruby_version_is "3.4" do
+ describe "GC.config" do
+ context "without arguments" do
+ it "returns a hash of current settings" do
+ GC.config.should.is_a?(Hash)
+ end
+
+ it "includes the name of currently loaded GC implementation as a global key" do
+ GC.config.should.include?(:implementation)
+ GC.config[:implementation].should.is_a?(String)
+ end
+ end
+
+ context "with a hash of options" do
+ it "allows to set GC implementation's options, returning the new config" do
+ config = GC.config({})
+ # Try to find a boolean setting to reliably test changing it.
+ key, _value = config.find { |_k, v| v == true }
+ skip unless key
+
+ GC.config(key => false).should == config.merge(key => false)
+ GC.config[key].should == false
+ GC.config(key => true).should == config
+ GC.config[key].should == true
+ ensure
+ GC.config(config.except(:implementation))
+ end
+
+ it "does not change settings that aren't present in the hash" do
+ previous = GC.config
+ GC.config({})
+ GC.config.should == previous
+ end
+
+ it "ignores unknown keys" do
+ previous = GC.config
+ GC.config(foo: "bar")
+ GC.config.should == previous
+ end
+
+ ruby_version_is ""..."4.0" do
+ it "returns the same as GC.config but without the :implementation key" do
+ previous = GC.config
+ GC.config({}).should == previous.except(:implementation)
+ end
+ end
+
+ ruby_version_is "4.0" do
+ it "returns the same as GC.config, including the :implementation key" do
+ previous = GC.config
+ GC.config({}).should == previous
+ end
+ end
+
+ it "raises an ArgumentError if options include global keys" do
+ -> { GC.config(implementation: "default") }.should.raise(ArgumentError, 'Attempting to set read-only key "Implementation"')
+ end
+ end
+
+ context "with a non-hash argument" do
+ it "returns current settings if argument is nil" do
+ GC.config(nil).should == GC.config
+ end
+
+ it "raises ArgumentError for all other arguments" do
+ -> { GC.config([]) }.should.raise(ArgumentError)
+ -> { GC.config("default") }.should.raise(ArgumentError)
+ -> { GC.config(1) }.should.raise(ArgumentError)
+ end
+ end
+
+ guard -> { PlatformGuard.standard? && GC.config[:implementation] == "default" } do
+ context "with default GC implementation on MRI" do
+ before do
+ @default_config = GC.config({})
+ end
+
+ after do
+ GC.config(@default_config.except(:implementation))
+ end
+
+ it "includes :rgengc_allow_full_mark option, true by default" do
+ GC.config.should.include?(:rgengc_allow_full_mark)
+ GC.config[:rgengc_allow_full_mark].should == true
+ end
+
+ it "allows to set :rgengc_allow_full_mark" do
+ # This key maps truthy and falsey values to true and false.
+ GC.config(rgengc_allow_full_mark: nil).should == @default_config.merge(rgengc_allow_full_mark: false)
+ GC.config(rgengc_allow_full_mark: 1.23).should == @default_config.merge(rgengc_allow_full_mark: true)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/gc/count_spec.rb b/spec/ruby/core/gc/count_spec.rb
new file mode 100644
index 0000000000..fe20c4ed2b
--- /dev/null
+++ b/spec/ruby/core/gc/count_spec.rb
@@ -0,0 +1,17 @@
+require_relative '../../spec_helper'
+
+describe "GC.count" do
+ it "returns an integer" do
+ GC.count.should.is_a?(Integer)
+ end
+
+ it "increases as collections are run" do
+ count_before = GC.count
+ i = 0
+ while GC.count <= count_before and i < 10
+ GC.start
+ i += 1
+ end
+ GC.count.should > count_before
+ end
+end
diff --git a/spec/ruby/core/gc/disable_spec.rb b/spec/ruby/core/gc/disable_spec.rb
new file mode 100644
index 0000000000..f89a9d2768
--- /dev/null
+++ b/spec/ruby/core/gc/disable_spec.rb
@@ -0,0 +1,18 @@
+require_relative '../../spec_helper'
+
+describe "GC.disable" do
+ after :each do
+ GC.enable
+ end
+
+ it "returns true if and only if the garbage collection was previously disabled" do
+ GC.enable
+ GC.disable.should == false
+ GC.disable.should == true
+ GC.disable.should == true
+ GC.enable
+ GC.disable.should == false
+ GC.disable.should == true
+ end
+
+end
diff --git a/spec/ruby/core/gc/enable_spec.rb b/spec/ruby/core/gc/enable_spec.rb
new file mode 100644
index 0000000000..ca4488547a
--- /dev/null
+++ b/spec/ruby/core/gc/enable_spec.rb
@@ -0,0 +1,13 @@
+require_relative '../../spec_helper'
+
+describe "GC.enable" do
+
+ it "returns true if and only if the garbage collection was already disabled" do
+ GC.enable
+ GC.enable.should == false
+ GC.disable
+ GC.enable.should == true
+ GC.enable.should == false
+ end
+
+end
diff --git a/spec/ruby/core/gc/garbage_collect_spec.rb b/spec/ruby/core/gc/garbage_collect_spec.rb
new file mode 100644
index 0000000000..f67f0486c8
--- /dev/null
+++ b/spec/ruby/core/gc/garbage_collect_spec.rb
@@ -0,0 +1,15 @@
+require_relative '../../spec_helper'
+
+describe "GC#garbage_collect" do
+
+ before :each do
+ @obj = Object.new
+ @obj.extend(GC)
+ end
+
+ it "always returns nil" do
+ @obj.garbage_collect.should == nil
+ @obj.garbage_collect.should == nil
+ end
+
+end
diff --git a/spec/ruby/core/gc/measure_total_time_spec.rb b/spec/ruby/core/gc/measure_total_time_spec.rb
new file mode 100644
index 0000000000..f5377c18fd
--- /dev/null
+++ b/spec/ruby/core/gc/measure_total_time_spec.rb
@@ -0,0 +1,17 @@
+require_relative '../../spec_helper'
+
+describe "GC.measure_total_time" do
+ before :each do
+ @default = GC.measure_total_time
+ end
+
+ after :each do
+ GC.measure_total_time = @default
+ end
+
+ it "can set and get a boolean value" do
+ original = GC.measure_total_time
+ GC.measure_total_time = !original
+ GC.measure_total_time.should == !original
+ end
+end
diff --git a/spec/ruby/core/gc/profiler/clear_spec.rb b/spec/ruby/core/gc/profiler/clear_spec.rb
new file mode 100644
index 0000000000..95c3d4ed65
--- /dev/null
+++ b/spec/ruby/core/gc/profiler/clear_spec.rb
@@ -0,0 +1,5 @@
+require_relative '../../../spec_helper'
+
+describe "GC::Profiler.clear" do
+ it "needs to be reviewed for spec completeness"
+end
diff --git a/spec/ruby/core/gc/profiler/disable_spec.rb b/spec/ruby/core/gc/profiler/disable_spec.rb
new file mode 100644
index 0000000000..74089693eb
--- /dev/null
+++ b/spec/ruby/core/gc/profiler/disable_spec.rb
@@ -0,0 +1,16 @@
+require_relative '../../../spec_helper'
+
+describe "GC::Profiler.disable" do
+ before do
+ @status = GC::Profiler.enabled?
+ end
+
+ after do
+ @status ? GC::Profiler.enable : GC::Profiler.disable
+ end
+
+ it "disables the profiler" do
+ GC::Profiler.disable
+ GC::Profiler.should_not.enabled?
+ end
+end
diff --git a/spec/ruby/core/gc/profiler/enable_spec.rb b/spec/ruby/core/gc/profiler/enable_spec.rb
new file mode 100644
index 0000000000..313ca3d949
--- /dev/null
+++ b/spec/ruby/core/gc/profiler/enable_spec.rb
@@ -0,0 +1,17 @@
+require_relative '../../../spec_helper'
+
+describe "GC::Profiler.enable" do
+
+ before do
+ @status = GC::Profiler.enabled?
+ end
+
+ after do
+ @status ? GC::Profiler.enable : GC::Profiler.disable
+ end
+
+ it "enables the profiler" do
+ GC::Profiler.enable
+ GC::Profiler.should.enabled?
+ end
+end
diff --git a/spec/ruby/core/gc/profiler/enabled_spec.rb b/spec/ruby/core/gc/profiler/enabled_spec.rb
new file mode 100644
index 0000000000..cfcd0951f0
--- /dev/null
+++ b/spec/ruby/core/gc/profiler/enabled_spec.rb
@@ -0,0 +1,21 @@
+require_relative '../../../spec_helper'
+
+describe "GC::Profiler.enabled?" do
+ before do
+ @status = GC::Profiler.enabled?
+ end
+
+ after do
+ @status ? GC::Profiler.enable : GC::Profiler.disable
+ end
+
+ it "reports as enabled when enabled" do
+ GC::Profiler.enable
+ GC::Profiler.enabled?.should == true
+ end
+
+ it "reports as disabled when disabled" do
+ GC::Profiler.disable
+ GC::Profiler.enabled?.should == false
+ end
+end
diff --git a/spec/ruby/core/gc/profiler/report_spec.rb b/spec/ruby/core/gc/profiler/report_spec.rb
new file mode 100644
index 0000000000..732b1d0f51
--- /dev/null
+++ b/spec/ruby/core/gc/profiler/report_spec.rb
@@ -0,0 +1,5 @@
+require_relative '../../../spec_helper'
+
+describe "GC::Profiler.report" do
+ it "needs to be reviewed for spec completeness"
+end
diff --git a/spec/ruby/core/gc/profiler/result_spec.rb b/spec/ruby/core/gc/profiler/result_spec.rb
new file mode 100644
index 0000000000..e888f975dc
--- /dev/null
+++ b/spec/ruby/core/gc/profiler/result_spec.rb
@@ -0,0 +1,7 @@
+require_relative '../../../spec_helper'
+
+describe "GC::Profiler.result" do
+ it "returns a string" do
+ GC::Profiler.result.should.is_a?(String)
+ end
+end
diff --git a/spec/ruby/core/gc/profiler/total_time_spec.rb b/spec/ruby/core/gc/profiler/total_time_spec.rb
new file mode 100644
index 0000000000..a351e922af
--- /dev/null
+++ b/spec/ruby/core/gc/profiler/total_time_spec.rb
@@ -0,0 +1,7 @@
+require_relative '../../../spec_helper'
+
+describe "GC::Profiler.total_time" do
+ it "returns an float" do
+ GC::Profiler.total_time.should.is_a?(Float)
+ end
+end
diff --git a/spec/ruby/core/gc/start_spec.rb b/spec/ruby/core/gc/start_spec.rb
new file mode 100644
index 0000000000..c941058969
--- /dev/null
+++ b/spec/ruby/core/gc/start_spec.rb
@@ -0,0 +1,12 @@
+require_relative '../../spec_helper'
+
+describe "GC.start" do
+ it "always returns nil" do
+ GC.start.should == nil
+ GC.start.should == nil
+ end
+
+ it "accepts keyword arguments" do
+ GC.start(full_mark: true, immediate_sweep: true).should == nil
+ end
+end
diff --git a/spec/ruby/core/gc/stat_spec.rb b/spec/ruby/core/gc/stat_spec.rb
new file mode 100644
index 0000000000..6e4800b3e3
--- /dev/null
+++ b/spec/ruby/core/gc/stat_spec.rb
@@ -0,0 +1,62 @@
+require_relative '../../spec_helper'
+
+describe "GC.stat" do
+ it "returns hash of values" do
+ stat = GC.stat
+ stat.should.is_a?(Hash)
+ stat.keys.should.include?(:count)
+ end
+
+ it "updates the given hash values" do
+ hash = { count: "hello", __other__: "world" }
+ stat = GC.stat(hash)
+
+ stat.should.is_a?(Hash)
+ stat.should.equal? hash
+ stat[:count].should.is_a?(Integer)
+ stat[:__other__].should == "world"
+ end
+
+ it "the values are all Integer since rb_gc_stat() returns size_t" do
+ GC.stat.values.each { |value| value.should.is_a?(Integer) }
+ end
+
+ it "can return a single value" do
+ GC.stat(:count).should.is_a?(Integer)
+ end
+
+ it "increases count after GC is run" do
+ count = GC.stat(:count)
+ GC.start
+ GC.stat(:count).should > count
+ end
+
+ it "increases major_gc_count after GC is run" do
+ count = GC.stat(:major_gc_count)
+ GC.start
+ GC.stat(:major_gc_count).should > count
+ end
+
+ it "provides some number for count" do
+ GC.stat(:count).should.is_a?(Integer)
+ GC.stat[:count].should.is_a?(Integer)
+ end
+
+ it "provides some number for heap_free_slots" do
+ GC.stat(:heap_free_slots).should.is_a?(Integer)
+ GC.stat[:heap_free_slots].should.is_a?(Integer)
+ end
+
+ it "provides some number for total_allocated_objects" do
+ GC.stat(:total_allocated_objects).should.is_a?(Integer)
+ GC.stat[:total_allocated_objects].should.is_a?(Integer)
+ end
+
+ it "raises an error if argument is not nil, a symbol, or a hash" do
+ -> { GC.stat(7) }.should.raise(TypeError, "non-hash or symbol given")
+ end
+
+ it "raises an error if an unknown key is given" do
+ -> { GC.stat(:foo) }.should.raise(ArgumentError, "unknown key: foo")
+ end
+end
diff --git a/spec/ruby/core/gc/stress_spec.rb b/spec/ruby/core/gc/stress_spec.rb
new file mode 100644
index 0000000000..227a795e7f
--- /dev/null
+++ b/spec/ruby/core/gc/stress_spec.rb
@@ -0,0 +1,27 @@
+require_relative '../../spec_helper'
+
+describe "GC.stress" do
+ after :each do
+ # make sure that we never leave these tests in stress enabled GC!
+ GC.stress = false
+ end
+
+ it "returns current status of GC stress mode" do
+ GC.stress.should == false
+ GC.stress = true
+ GC.stress.should == true
+ GC.stress = false
+ GC.stress.should == false
+ end
+end
+
+describe "GC.stress=" do
+ after :each do
+ GC.stress = false
+ end
+
+ it "sets the stress mode" do
+ GC.stress = true
+ GC.stress.should == true
+ end
+end
diff --git a/spec/ruby/core/gc/total_time_spec.rb b/spec/ruby/core/gc/total_time_spec.rb
new file mode 100644
index 0000000000..f10e0ad742
--- /dev/null
+++ b/spec/ruby/core/gc/total_time_spec.rb
@@ -0,0 +1,13 @@
+require_relative '../../spec_helper'
+
+describe "GC.total_time" do
+ it "returns an Integer" do
+ GC.total_time.should.is_a?(Integer)
+ end
+
+ it "increases as collections are run" do
+ time_before = GC.total_time
+ GC.start
+ GC.total_time.should >= time_before
+ end
+end