ko1 / rubyhackchallenge

464 stars 83 forks source link

ビルドしたRubyでのGemのテスト #25

Open nownabe opened 7 years ago

nownabe commented 7 years ago

取り組んだ課題

https://github.com/ko1/rubyhackchallenge/blob/master/tasks.md#ビルドした-ruby-での-gem-のテスト

現在、ビルドした Ruby で Gem など、外部ライブラリを、ビルドした Ruby で、他の影響を与えないで適切にテストする方法がありません。 というのも、Gem の場合、Gem のテストのために他の Gem を利用したりする必要があるためです。 区切られた環境(サンドボックス)を用いることで

成果

今後

nownabe commented 7 years ago

土日で続きをやってみました。 https://github.com/nownabe/ruby/commit/fafe53e43badaa55eff8541484359328627e8039

現在はまだいろいろ制限がありますが、make testgemで環境を汚さずにGemがテストできるようになりました。

Usage:

$ mkdir build
$ cd build
$ ../ruby/configure --prefix=`pwd`/../install --enable-shared
$ make -j

# YAMLに定義されているGemすべてのテストを実行
$ make testgem

# 特定のGemのテストを実行
$ make testgem GEMS=benchmark_driver

制限:

課題

nownabe commented 7 years ago

make testgemを通すために必要な環境構築

Debian 9 (Stretch)

sudo apt-get install \
  g++ \
  ncurses-dev \
  ragel \
  libxml2-dev \
  default-libmysqlclient-dev \
  libpq-dev \
  libsqlite3-dev \
  libfcgi-dev

CentOS 7

sudo yum install -y epel-release
sudo yum install -y \
  git \
  autoconf \
  ruby \
  gcc \
  bison \
  bzip2 \
  openssl-devel \
  libyaml-devel \
  libffi-devel \
  readline-devel \
  zlib-devel \
  gdbm-devel \
  ncurses-devel \
  gcc-c++ \
  libxml2-devel \
  mysql-devel \
  postgresql-devel \
  sqlite-devel \
  fcgi-devel

Fedora 25

sudo dnf install -y \
  cmake \
  pandoc
nownabe commented 7 years ago

テスト状況

v2_4_2 / --enable-sharedなし

v2_4_2 / --enable-sharedあり

trunk / --enable-sharedなし

trunk / --enable-sharedあり

hsbt commented 7 years ago

@nownabe こんにちは、 @ko1 さんから紹介いただきました。Bundled Gems 全般を僕がみているので、レビューのち本体にマージできそうならマージしたいと思います。

ko1 commented 7 years ago

すげーどうでも良い話なんですが、test-all とか test-spec という既存の名前に合わせて、test-gem もしくは test-gems が良さそうに思いました。

nownabe commented 7 years ago

@hsbt ありがとうございます!ruby/rubyにPull Request投げる形でよろしいでしょうか?

@ko1 それもそうですね。test-gemsにします 🙌

hsbt commented 7 years ago

@nownabe pull request でお願いします!

nownabe commented 7 years ago

macOSはEl CapitanからDYLD_LIBRARY_PATHやDYLD_INSERT_LIBRARIESが継承できなくなっているらしい。。。 http://paulbeachsblog.blogspot.jp/2016/03/dyldlibrarypath-and-el-capitan.html

Mac対応は一旦保留 😞

ko1 commented 7 years ago

そのために、Mac だと ruby-runner というものを作っているようです。

nownabe commented 7 years ago

@ko1 なるほど…!そういえばrunrubyでみました。確認してみます!:pray:

Gem::Ext::Builderが実行するコマンドをなんらかのパッチで差し替える感じかな

nownabe commented 6 years ago

https://gist.github.com/nownabe/5d50e0d988d1f6593b91efd0a28a9045

--enable-sharedなしでうまくいかなかったときのログ:

==============================
Current Directory: /home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/gems/gems/stackprof-0.2.10/ext/stackprof

ENV:
{"GEM_HOME"=>
  "/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/gems",
 "GEM_PATH"=>
  "/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/gems",
 "LD_LIBRARY_PATH"=>
  "/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled:/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled",
 "PATH"=>
  "/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/bin:/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/gems/bin:/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-
enabled/bin:/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/gems/bin:/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled:/home/nownabe/.cargo/bin:/home/nownabe/tmp/sdk/appengi
ne-java-sdk-1.9.51/bin:/home/nownabe/tmp/google-cloud-sdk/bin:/home/nownabe/bin:/home/nownabe/.anyenv/envs/rbenv/shims:/home/nownabe/.anyenv/envs/rbenv/bin:/home/nownabe/.anyenv/envs/pyenv/shims:/home/nownabe/
.anyenv/envs/pyenv/bin:/home/nownabe/.anyenv/envs/ndenv/bin:/home/nownabe/.anyenv/bin:/home/nownabe/.cargo/bin:/home/nownabe/tmp/sdk/appengine-java-sdk-1.9.51/bin:/home/nownabe/tmp/google-cloud-sdk/bin:/home/n
ownabe/.sdkman/candidates/gradle/current/bin:/home/nownabe/bin:/home/nownabe/.anyenv/envs/rbenv/shims:/home/nownabe/.anyenv/envs/rbenv/bin:/home/nownabe/.anyenv/envs/pyenv/shims:/home/nownabe/.anyenv/envs/pyen
v/bin:/home/nownabe/.anyenv/envs/ndenv/shims:/home/nownabe/.anyenv/envs/ndenv/bin:/home/nownabe/.anyenv/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin",
 "PWD"=>
  "/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/gems/gems/stackprof-0.2.10/ext/stackprof",
 "RUBY"=>
  "/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/bin/ruby",
 "RUBYLIB"=>
  "/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/lib:/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/.ext/common:/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-
no-enabled/.ext/x86_64-linux:/home/nownabe/tmp/rubyhackchallenge/gemtest/ruby/lib:/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled",
 "RUBYOPT"=>"-EUTF-8",
 "SHLVL"=>"1",
 "_"=>
  "/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/bin/ruby"}

==============================

#### begin: try_link(src, opt = "", *opts, &b) ####
    #### begin: try_link0(src, opts = "", *opts, &b) ####
        #### begin: try_do(src, command, *opts, &b) ####
            #### begin: have_devel? ####
                $hava_devel is not defined.
                MAIN_DOES_NOTHING: int main(int argc, char **argv)
                {
                  return 0;
                }
                #### begin: try_link(src, opt = "", *opts, &b) ####
                    #### begin: try_link0(src, opts = "", *opts, &b) ####
                        #### begin: try_do(src, command, *opts, &b) ####
                            #### begin: have_devel? ####
                            #### end: have_devel? ####
                            #### begin: xsystem(command, opts = nil) ####
                                libpath_env: {"LD_LIBRARY_PATH"=>".:/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/lib:/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled:/ho
me/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled"}
                                command: gcc -o conftest -I/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/include/ruby-2.5.0/x86_64-linux -I/home/nownabe/tmp/rubyhackchallenge/gemtest/build
-trunk-no-enabled/include/ruby-2.5.0/ruby/backward -I/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/include/ruby-2.5.0 -I.    -O3 -fno-fast-math -ggdb3 -DRUBY_DEVEL=1 -Wall -Wextra -Wno-unu
sed-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wno-tautological-compare -Wno-parentheses-equality -Wno-constant-logical-operand -Wno-self-assign -Wunused-variable -Wimplicit-int
 -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration -Wdeprecated-declarations -Wno-packed-bitfield-compat -Wsuggest-attribute=noreturn -Wsuggest-attribute=format -Wno
-maybe-uninitialized conftest.c  -L. -L/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/lib -Wl,-rpath,/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/lib -L. -fstack-prote
ctor -rdynamic -Wl,-export-dynamic     -Wl,-rpath,/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/lib -L/home/nownabe/tmp/rubyhackchallenge/gemtest/build-trunk-no-enabled/lib -lruby-static  
-lpthread -ldl -lcrypt -lm   -lc
                                Stdout: 
                                Stderr: /usr/bin/ld: cannot find -lruby-static
                                collect2: error: ld returned 1 exit status
                                Result: pid 2962 exit 1
                            #### end: xsystem(command, opts = nil) ####
                        #### end: try_do(src, command, *opts, &b) ####
                    #### end: try_link0(src, opts = "", *opts, &b) ####
                    exe: 
                #### end: try_link(src, opt = "", *opts, &b) ####
                $have_devel = false
            #### end: have_devel? ####
            RuntimeError
            The compiler failed to generate an executable file.
            You have to install development tools first.

            /home/nownabe/tmp/rubyhackchallenge/gemtest/ruby/lib/mkmf.rb:541:in `try_do'
            /home/nownabe/tmp/rubyhackchallenge/gemtest/ruby/lib/mkmf.rb:632:in `try_link0'
            /home/nownabe/tmp/rubyhackchallenge/gemtest/ruby/lib/mkmf.rb:652:in `try_link'
            /home/nownabe/tmp/rubyhackchallenge/gemtest/ruby/lib/mkmf.rb:878:in `try_func'
            /home/nownabe/tmp/rubyhackchallenge/gemtest/ruby/lib/mkmf.rb:1165:in `block in have_func'
            /home/nownabe/tmp/rubyhackchallenge/gemtest/ruby/lib/mkmf.rb:1055:in `block in checking_for'
            /home/nownabe/tmp/rubyhackchallenge/gemtest/ruby/lib/mkmf.rb:406:in `block (2 levels) in postpone'
            /home/nownabe/tmp/rubyhackchallenge/gemtest/ruby/lib/mkmf.rb:376:in `open'
            /home/nownabe/tmp/rubyhackchallenge/gemtest/ruby/lib/mkmf.rb:406:in `block in postpone'
            /home/nownabe/tmp/rubyhackchallenge/gemtest/ruby/lib/mkmf.rb:376:in `open'
            /home/nownabe/tmp/rubyhackchallenge/gemtest/ruby/lib/mkmf.rb:402:in `postpone'
            /home/nownabe/tmp/rubyhackchallenge/gemtest/ruby/lib/mkmf.rb:1054:in `checking_for'
            /home/nownabe/tmp/rubyhackchallenge/gemtest/ruby/lib/mkmf.rb:1164:in `have_func'
            extconf.rb:2:in `<main>'
        #### end: try_do(src, command, *opts, &b) ####
    #### end: try_link0(src, opts = "", *opts, &b) ####
#### end: try_link(src, opt = "", *opts, &b) ####

==============================

ruby-staticがないらしい?

CONFIG["LIBRUBYARG_STATIC"] = "-Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static"
nownabe commented 6 years ago
$ ar x libruby-static.a 
$ ls
addr2line.o  compile.o        dln_find.o    enum.o            hash.o            loadpath.o    numeric.o  process.o   regenc.o     ruby.o          strftime.o  thread.o     util.o          vm_trace.o
array.o      complex.o        dln.o         error.o           inits.o           localeinit.o  object.o   proc.o      regerror.o   safe.o          string.o    time.o       variable.o
ascii.o      cont.o           dmyenc.o      eval.o            io.o              marshal.o     pack.o     random.o    regexec.o    setproctitle.o  strlcat.o   transcode.o  version.o
bignum.o     debug_counter.o  dmyext.o      explicit_bzero.o  iseq.o            math.o        parse.o    range.o     regparse.o   signal.o        strlcpy.o   unicode.o    vm_backtrace.o
class.o      debug.o          encoding.o    file.o            libruby-static.a  newline.o     prelude.o  rational.o  regsyntax.o  sprintf.o       struct.o    us_ascii.o   vm_dump.o
compar.o     dir.o            enumerator.o  gc.o              load.o            node.o        probes.o   regcomp.o   re.o         st.o            symbol.o    utf_8.o      vm.o
nownabe commented 6 years ago

--enable-sharedがないとeventmachineがビルドできない。

extconf.rbから生成されたMakefileのCPPFLAGSに-DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_RB_THREAD_FD_SELECTを追加するとビルドできる。 https://github.com/eventmachine/eventmachine/blob/master/ext/em.h#L25 https://github.com/eventmachine/eventmachine/blob/master/ext/em.cpp#L623

--enable-sharedありの場合のMakefileは-DHAVE_RB_WAIT_FOR_SINGLE_FD -DHAVE_RB_THREAD_FD_SELECTが定義されている。

このへんおっかける https://github.com/ruby/ruby/blob/trunk/lib/mkmf.rb#L1056 https://github.com/eventmachine/eventmachine/blob/master/ext/extconf.rb#L109

nownabe commented 6 years ago

--enable-sharedなしとMacでも動くようになったので、Gemを増やしていきたい http://bestgems.org/total このへんみつつ

ko1 commented 6 years ago

RubyKaigi にいらっしゃいます?

nownabe commented 6 years ago

@ko1 すみません今年は参加していません :sob::pray:

nownabe commented 6 years ago

BestGemsのTop100のGemを試して、trunkでテストが通らないGemの傾向 (2.4ではまだできていない)

nownabe commented 6 years ago

今の所test-gemsの環境でのみテストが通らないのは3つ

nownabe commented 6 years ago

rspecは、erb.rbをソースディレクトリに置いたままRUBYLIBで参照させていたのが原因っぽい

RSpecのbacktraceをフィルタリングする箇所でtest-gems環境だとパスがlib/rubyにマッチしないのでフィルタリングできていなかった。 https://github.com/rspec/rspec-core/blob/master/lib/rspec/core/backtrace_formatter.rb#L11

ko1 commented 6 years ago

そういえば、これを進めて http://www.ruby.or.jp/ja/news/20170804 に出しません?

nownabe commented 6 years ago

@ko1 出してみたいです!こんなのあるんですね

nownabe commented 6 years ago

@ko1 応募メールに記載する担当者は笹田さんでよろしいでしょうか?

nownabe commented 6 years ago

TODO

ko1 commented 6 years ago

メンターですかね? 私で結構です。

nownabe commented 6 years ago

承知しました!

nownabe commented 6 years ago

ブログに簡単に使い方をまとめました。

https://blog.nownabe.com/2017/09/22/1133.html

nownabe commented 6 years ago

bundlerは一旦保留

nownabe commented 6 years ago

テスト用のスクリプト: https://github.com/nownabe/gem_tester/tree/master/scripts CIで回したい…

nownabe commented 6 years ago

TODO