summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-02-08 13:35:27 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-02-08 13:35:27 +0000
commitc709040b3fed00cbd557cfa6f5f12a0dd31af096 (patch)
tree76de90cda5a027b9c3aa8c953324ae4ba5b489d3 /test
parent4e39dc864cc197923bf6e56b9359a1c4def7b1ae (diff)
* test/-ext-/string/test_modify_expand.rb: test for r34492.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_3@34493 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'test')
-rw-r--r--test/-ext-/string/test_modify_expand.rb29
-rw-r--r--test/ruby/memory_status.rb92
2 files changed, 121 insertions, 0 deletions
diff --git a/test/-ext-/string/test_modify_expand.rb b/test/-ext-/string/test_modify_expand.rb
new file mode 100644
index 0000000000..5fee7b3580
--- /dev/null
+++ b/test/-ext-/string/test_modify_expand.rb
@@ -0,0 +1,29 @@
+require 'test/unit'
+require "-test-/string/string"
+require_relative '../../ruby/envutil'
+
+class Test_StringModifyExpand < Test::Unit::TestCase
+ def test_modify_expand_memory_leak
+ before = after = nil
+ args = [
+ "--disable=gems", "-r-test-/string/string",
+ "-I"+File.expand_path("../../..", __FILE__),
+ "-rruby/memory_status",
+ "-e", <<-CMD
+ s=Bug::String.new
+ size=Memory::Status.new.size
+ puts size
+ 10.times{s.modify_expand!(size)}
+ s.replace("")
+ puts Memory::Status.new.size
+ CMD
+ ]
+ status = EnvUtil.invoke_ruby(args, "", true) do |in_p, out_p, err_p, pid|
+ before, after = out_p.readlines.map(&:to_i)
+ Process.wait(pid)
+ $?
+ end
+ assert_equal(true, status.success?)
+ assert_operator after.fdiv(before), :<, 2
+ end
+end
diff --git a/test/ruby/memory_status.rb b/test/ruby/memory_status.rb
new file mode 100644
index 0000000000..9cee933be3
--- /dev/null
+++ b/test/ruby/memory_status.rb
@@ -0,0 +1,92 @@
+module Memory
+ keys = []
+ vals = []
+
+ case
+ when File.exist?(procfile = "/proc/self/status")
+ PROC_FILE = procfile
+ VM_PAT = /^Vm(\w+):\s+(\d+)/
+ def self.read_status
+ IO.foreach(PROC_FILE) do |l|
+ yield($1.downcase.intern, $2.to_i * 1024) if VM_PAT =~ l
+ end
+ end
+
+ read_status {|k, v| keys << k; vals << v}
+
+ when /mswin|mingw/ =~ RUBY_PLATFORM
+ require 'dl/import'
+ require 'dl/types'
+
+ module Win32
+ extend DL::Importer
+ dlload "kernel32.dll", "psapi.dll"
+ include DL::Win32Types
+ typealias "SIZE_T", "DWORD"
+
+ PROCESS_MEMORY_COUNTERS = struct [
+ "DWORD cb",
+ "DWORD PageFaultCount",
+ "SIZE_T PeakWorkingSetSize",
+ "SIZE_T WorkingSetSize",
+ "SIZE_T QuotaPeakPagedPoolUsage",
+ "SIZE_T QuotaPagedPoolUsage",
+ "SIZE_T QuotaPeakNonPagedPoolUsage",
+ "SIZE_T QuotaNonPagedPoolUsage",
+ "SIZE_T PagefileUsage",
+ "SIZE_T PeakPagefileUsage",
+ ]
+
+ typealias "PPROCESS_MEMORY_COUNTERS", "PROCESS_MEMORY_COUNTERS*"
+
+ extern "HANDLE GetCurrentProcess()", :stdcall
+ extern "BOOL GetProcessMemoryInfo(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD)", :stdcall
+
+ module_function
+ def memory_info
+ size = PROCESS_MEMORY_COUNTERS.size
+ data = PROCESS_MEMORY_COUNTERS.malloc
+ data.cb = size
+ data if GetProcessMemoryInfo(GetCurrentProcess(), data, size)
+ end
+ end
+
+ keys << :peak << :size
+ def self.read_status
+ if info = Win32.memory_info
+ yield :peak, info.PeakPagefileUsage
+ yield :size, info.PagefileUsage
+ end
+ end
+ else
+ PSCMD = ["ps", "-o", "vsz=,rss=", "-p"]
+ PAT = /^\s*(\d+)\s+(\d+)$/
+
+ keys << :size << :rss
+ def self.read_status
+ if PAT =~ IO.popen(PSCMD + [$$.to_s], "r", err: [:child, :out], &:read)
+ yield :size, $1.to_i*1024
+ yield :rss, $2.to_i*1024
+ end
+ end
+ end
+
+ Status = Struct.new(*keys)
+
+ class Status
+ def _update
+ Memory.read_status do |key, val|
+ self[key] = val
+ end
+ end
+ end
+
+ class Status
+ Header = members.map {|k| k.to_s.upcase.rjust(6)}.join('')
+ Format = "%6d"
+
+ def initialize
+ _update
+ end
+ end
+end