about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2009-11-07 08:08:18 +0000
committerEric Wong <normalperson@yhbt.net>2009-11-07 00:09:41 -0800
commitb36235131e0b5517fc5070c02c72be01c4b7f1f9 (patch)
tree3c4774be5d51c905dcf9384c4ba5bc7816e7905d
parent1a9a718a3f9a5b582a4a339a9bb9249c2ca392d7 (diff)
downloadrainbows-b36235131e0b5517fc5070c02c72be01c4b7f1f9.tar.gz
sha1sum(1) is only common GNU systems, and it may be installed
as gsha1sum on *BSDs.  We'll also try using the openssl sha1
implementation, too.  And finally, we'll provide our own Ruby
sha1sum.rb implementation as a last resort.

We go to great lengths to avoid our own Ruby version because we
want to avoid putting too much trust in ourselves, our Ruby
skills, and even the Ruby implementations.  This is especially
with regard to our knowledge and correct usage of Ruby 1.9
encoding support.  It would actually be *easier* to only use
sha1sum.rb and call it a day.  We just choose to support
SHA1 implementations provided by third parties if possible.

Performance is not a factor since sha1sum.rb performance is very
close to the C implementations.
-rwxr-xr-xt/bin/sha1sum.rb23
-rwxr-xr-xt/t0100-rack-input-hammer.sh7
-rw-r--r--t/test-lib.sh10
3 files changed, 39 insertions, 1 deletions
diff --git a/t/bin/sha1sum.rb b/t/bin/sha1sum.rb
new file mode 100755
index 0000000..b602e79
--- /dev/null
+++ b/t/bin/sha1sum.rb
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+# -*- encoding: binary -*-
+
+# Reads from stdin and outputs the SHA1 hex digest of the input this is
+# ONLY used as a last resort, our test code will try to use sha1sum(1),
+# openssl(1), or gsha1sum(1) before falling back to using this.  We try
+# all options first because we have a strong and healthy distrust of our
+# Ruby abilities in general, and *especially* when it comes to
+# understanding (and trusting the implementation of) Ruby 1.9 encoding.
+
+require 'digest/sha1'
+$stdout.sync = $stderr.sync = true
+$stdout.binmode
+$stdin.binmode
+bs = 16384
+digest = Digest::SHA1.new
+if buf = $stdin.read(bs)
+  begin
+    digest.update(buf)
+  end while $stdin.read(bs, buf)
+end
+
+$stdout.syswrite("#{digest.hexdigest}\n")
diff --git a/t/t0100-rack-input-hammer.sh b/t/t0100-rack-input-hammer.sh
index c333883..c871913 100755
--- a/t/t0100-rack-input-hammer.sh
+++ b/t/t0100-rack-input-hammer.sh
@@ -2,6 +2,11 @@ nr_client=${nr_client-4}
 . ./test-lib.sh
 test -r random_blob || die "random_blob required, run with 'make $0'"
 
+# basically we don't trust our own implementation of content-md5-put
+# nor our Ruby 1.9 knowledge nor proper use of encodings in Ruby.
+# So we try to use things like curl and sha1sum that are implemented
+# without the Ruby interpreter to validate our own Ruby internals.
+
 t_plan 7 "concurrent rack.input hammer stress test"
 
 t_begin "setup and startup" && {
@@ -35,7 +40,7 @@ t_begin "all responses identical" && {
 }
 
 t_begin "sha1 matches on-disk sha1" && {
-        blob_sha1=$( expr "$(sha1sum < random_blob)" : '\([a-f0-9]\{40\}\)')
+        blob_sha1=$(rsha1 < random_blob)
         t_info blob_sha1=$blob_sha1
         test x"$blob_sha1" = x"$(sort < $curl_out | uniq)"
 }
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 9e67d1d..d28eaa0 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -134,6 +134,16 @@ rainbows_wait_start () {
         rainbows_pid=$(cat $pid)
 }
 
+rsha1 () {
+        _cmd="$(which sha1sum 2>/dev/null || :)"
+        test -n "$_cmd" || _cmd="$(which openssl 2>/dev/null || :) sha1"
+        test "$_cmd" != " sha1" || _cmd="$(which gsha1sum 2>/dev/null || :)"
+
+        # last resort, see comments in sha1sum.rb for reasoning
+        test -n "$_cmd" || _cmd=sha1sum.rb
+        expr "$($_cmd < random_blob)" : '\([a-f0-9]\{40\}\)'
+}
+
 case $model in
 Rev) require_check rev Rev::VERSION ;;
 Revactor) require_check revactor Revactor::VERSION ;;