Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
nownabe opened this issue Sep 1, 2017 · 29 comments
Open

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

nownabe opened this issue Sep 1, 2017 · 29 comments

Comments

@nownabe
Copy link

nownabe commented Sep 1, 2017

取り組んだ課題

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

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

成果

今後

  • サンドボックス要件が完全には満たせていないので、ビルドディレクトリにのみ閉じて(make install不要)Gemのテストを実行できるように修正する
  • /toolにスクリプトを作り、make testgemのような形で実行できるようにする
  • ある程度、レポジトリやテストコマンドを自動検知できるようにする
@nownabe
Copy link
Author

nownabe commented Sep 4, 2017

土日で続きをやってみました。
nownabe/ruby@fafe53e

現在はまだいろいろ制限がありますが、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

制限:

  • --enable-shared必須
  • Linuxnのみ (Fedora 25でしか確認できていない)

課題

  • --enable-sharedなしでのテスト (必要?)
  • 他の環境でのテスト
  • Mac対応

@nownabe
Copy link
Author

nownabe commented Sep 5, 2017

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
Copy link
Author

nownabe commented Sep 5, 2017

テスト状況

v2_4_2 / --enable-sharedなし

  • Debian 8
  • Debian 9
  • CentOS 6
  • CentOS 7
  • Ubuntu 14.04
  • Ubuntu 16.04
  • Ubuntu 17.04
  • macOS Sierra

v2_4_2 / --enable-sharedあり

  • Debian 8
  • Debian 9
  • CentOS 6
  • CentOS 7
  • Ubuntu 14.04
  • Ubuntu 16.04
  • Ubuntu 17.04
  • macOS Sierra

trunk / --enable-sharedなし

  • Debian 8
  • Debian 9
  • CentOS 6
  • CentOS 7
  • Ubuntu 14.04
  • Ubuntu 16.04
  • Ubuntu 17.04
  • macOS Sierra

trunk / --enable-sharedあり

  • Debian 8
  • Debian 9
  • CentOS 6
  • CentOS 7
  • Ubuntu 14.04
  • Ubuntu 16.04
  • Ubuntu 17.04
  • macOS Sierra

@hsbt
Copy link
Sponsor

hsbt commented Sep 5, 2017

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

@ko1
Copy link
Owner

ko1 commented Sep 5, 2017

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

@nownabe
Copy link
Author

nownabe commented Sep 5, 2017

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

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

@hsbt
Copy link
Sponsor

hsbt commented Sep 5, 2017

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

@nownabe
Copy link
Author

nownabe commented Sep 6, 2017

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

Mac対応は一旦保留 😞

@ko1
Copy link
Owner

ko1 commented Sep 6, 2017

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

@nownabe
Copy link
Author

nownabe commented Sep 7, 2017

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

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

@nownabe
Copy link
Author

nownabe commented Sep 10, 2017

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
Copy link
Author

nownabe commented Sep 10, 2017

$ 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
Copy link
Author

nownabe commented Sep 10, 2017

--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
Copy link
Author

nownabe commented Sep 18, 2017

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

@ko1
Copy link
Owner

ko1 commented Sep 18, 2017

RubyKaigi にいらっしゃいます?

@nownabe
Copy link
Author

nownabe commented Sep 19, 2017

@ko1 すみません今年は参加していません 😭🙏

@nownabe
Copy link
Author

nownabe commented Sep 19, 2017

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

  • 本当にテストが通っていない感じのもの (C拡張ライブラリ系が多い感じ) => 2.4.1をビルドして試す
  • RSpecのバグ?(trunkで動かない?)に引きずられている感じのもの => 2.4.1をビルドして試す
  • Rakefileがないもの => テストコマンド調べる
  • 特殊な環境でしかテストできないもの (activerecord, net-scpなど) => 無視
  • インストール済みの2.4.1でもテストが失敗するもの => CIなどをみてみる
  • テスト方法がわからないもの => 調べる
  • 依存関係がうまく解決できないもの (railsファミリーに多い) => --preとか?
  • 何かが足りないもの => 追加してみる

@nownabe
Copy link
Author

nownabe commented Sep 20, 2017

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

  • bundler
  • pry
  • rspec-core

@nownabe
Copy link
Author

nownabe commented Sep 20, 2017

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
Copy link
Owner

ko1 commented Sep 21, 2017

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

@nownabe
Copy link
Author

nownabe commented Sep 21, 2017

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

@nownabe
Copy link
Author

nownabe commented Sep 21, 2017

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

@nownabe
Copy link
Author

nownabe commented Sep 21, 2017

TODO

  • trunkでruby-runner => exe/ruby の変更があったので追従する必要がありそう
  • rbconfig.rbにパッチあててるのでロックする
  • if: { platform: "mac" }のような形でテストを実行する条件を指定できるようにする
  • Resultをskippedという状態も持てるようにする
  • オプションで--depth 1
  • CI
  • Rubyアソシエーション 開発助成金2017 応募

@ko1
Copy link
Owner

ko1 commented Sep 22, 2017

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

@nownabe
Copy link
Author

nownabe commented Sep 22, 2017

承知しました!

@nownabe
Copy link
Author

nownabe commented Sep 22, 2017

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

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

@nownabe
Copy link
Author

nownabe commented Sep 23, 2017

bundlerは一旦保留

  • パス周り細かく見てたりしてEXTOUTとか参照させてるとfailする
  • ruby本体に取り込まれる予定
  • インストール済みの2.4.2でもfailする

@nownabe
Copy link
Author

nownabe commented Sep 24, 2017

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

@nownabe
Copy link
Author

nownabe commented Oct 11, 2017

TODO

  • コピーしてるファイルの変更に追随する (変更日時)
  • WindowsはSymlink動かない (Windowsではサポートしない? / 動かないGemも多そう)
  • https://github.com/ruby/chkbuild に対応する
  • オプションでYAMLも指定できるようにすれば柔軟になる
  • オプションでGemレポジトリのディレクトリを指定できるようにする (CIでキャッシュできるように)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants