File: ruby-test-svnserve-race

package info (click to toggle)
subversion 1.14.5-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 80,416 kB
  • sloc: ansic: 1,039,361; python: 140,229; cpp: 24,862; java: 24,547; ruby: 12,312; lisp: 7,619; sh: 7,414; perl: 7,010; sql: 1,686; makefile: 1,191; xml: 577
file content (66 lines) | stat: -rw-r--r-- 2,172 bytes parent folder | download | duplicates (4)
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
From: James McCoy <jamessan@debian.org>
Date: Wed, 1 Aug 2018 20:44:36 -0400
Subject: ruby-test-svnserve-race

Bug #378837: Ruby testsuite: wait for svnserve to start before
Bug #378837: Ruby testsuite: wait for svnserve to start before
connecting to it.  This mainly affects very slow machines - observed
on various arm and m68k builds.

Thanks to Roman Zippel, Kobayashi Noritada, Wouter Verhelst and Martin
Michlmayr.
---
 subversion/bindings/swig/ruby/test/util.rb | 28 +++++++++++++++++++++++-----
 1 file changed, 23 insertions(+), 5 deletions(-)

diff --git a/subversion/bindings/swig/ruby/test/util.rb b/subversion/bindings/swig/ruby/test/util.rb
index 06ae7ba..4f54992 100644
--- a/subversion/bindings/swig/ruby/test/util.rb
+++ b/subversion/bindings/swig/ruby/test/util.rb
@@ -19,6 +19,7 @@
 
 require "fileutils"
 require "pathname"
+require "socket"
 
 # Tale of a hack...
 #
@@ -289,11 +290,7 @@ realm = #{@realm}
                "-d", "--foreground")
         }
         pid, status = Process.waitpid2(@svnserve_pid, Process::WNOHANG)
-        if status and status.exited?
-          if $DEBUG
-            STDERR.puts "port #{port} couldn't be used for svnserve"
-          end
-        else
+        if wait_until_svnserve_gets_available_at(port)
           # svnserve started successfully.  Note port number and cease
           # startup attempts.
           @svnserve_port = port
@@ -359,4 +356,25 @@ exit 1
     include Svnserve
     extend SetupEnvironment
   end
+
+  # Waits until svnserve gets available at port +port+, avoiding the race
+  # condition between starting up a svnserve process and trying to connect
+  # to it (Bug#378837 in Debian's BTS).
+  def wait_until_svnserve_gets_available_at(port)
+    1000.times do |n|
+      begin
+	pid, status = Process.waitpid2(@svnserve_pid, Process::WNOHANG)
+	if status and status.exited?
+	  STDERR.puts "port #{port} couldn't be used for svnserve"
+	  return false
+	end
+	TCPSocket.new(@svnserve_host, port).close
+      rescue Errno::ECONNREFUSED
+	sleep(n < 10 ? 0.2 : 0.5)
+      else
+	return true
+      end
+    end
+    raise "svnserve couldn't get available at port #{port}"
+  end
 end