ラベル Online Compiler の投稿を表示しています。 すべての投稿を表示
ラベル Online Compiler の投稿を表示しています。 すべての投稿を表示

2015年4月28日火曜日

Wandbox が複数ファイル対応したので試してみた



Wandbox が複数ファイルに対応したようなので、早速試してみました。
iuwandbox
iuwandbox は私が作っている C++ テスティングフレームワーク iutest を Wandbox 使うためのツールです。
今回はこちらを複数ファイル対応しました。

以前の、iuwandbox では iutest の実装をすべて1つのファイルに展開し、実現していました。
Wandbox の複数ファイル対応によって、この展開が不要になります。
以前の iuwandbox については、Boost.勉強会の LT でもお話しましたので、そちらのスライドを参考にしてください。

ブログズミ: Boost.勉強会#16 大阪に行ってきました > 発表資料
ブログズミ: Shippable + Wandbox で C++ の CI 環境構築

Wandbox の複数ファイル対応にあたって、API に codes パラメータが追加されています。
https://github.com/melpon/wandbox/blob/master/kennel2/API.rst
codes には、file にファイル名を code に内容を書いて配列データとして追加します。
Wandbox の API に関わる部分だけ切り出して公開してますので、ご自由にお使い下さい。
https://github.com/srz-zumix/wandbox-api

続いて、iuwandbox 側の修正です。
これまでは #include "path/iutest.hpp" という(パスは何でも良い)行があったら、そこにコードを全展開していました。
これを iutest.hpp という別ファイルと #include "iutest.hpp" として処理するようにしました。
また、--expand_include オプションを指定しなかった場合に、対象のファイルも追加ファイルとして送るように修正しています。

こちらの修正は github から取得できます。
https://github.com/srz-zumix/iutest

サンプル
https://github.com/srz-zumix/iutest/tree/master/tools/wandbox
こちらにあるサンプルの実行結果が以下になります。

複数ファイル対応前の結果:http://melpon.org/wandbox/permlink/rxop0vcJGIrj9BwC
複数ファイル対応後の結果:http://melpon.org/wandbox/permlink/HTCDKqWvJ8TlvmUa
※対応前のリンクは開くのに時間がかかるので注意!

複数ファイル対応後の方を開いていただくとわかると思いますが、ページを開くのがとっても速くなってます!
また、一番見たいテストコード部分がすぐに確認できるようにもなりました。

Wandbox ますます便利になりましたね\(^o^)/

2015年1月26日月曜日

ideone の API を使ってみた

前回は paiza.IO を使ってみました。「ブログズミ: paiza.IO の API を使ってみた
paiza.IO は実行できるコードサイズに制限があったため、iutest での使用要件を満たしていませんでした。
今回は、ideone の API を使ってみたいと思います。

まずは登録から
Ideone の API は Sphere Engine として提供されています。
この Sphere Engine を使うためには、Ideone のアカウントとは別に登録をしなければいけません。

ちなみに、この Sphere Engine は無償ではありません


Pay-As-You-Go のプランがお試しプランといった感じで、初期投資0円で使えます。
最初に一定回数分 API が使えるようになっています。

今回はこのプランで登録しました。
登録をすると、アカウント設定ページに API のパスワード設定が追加されているので好きなパスワードを設定してください。


API を使う
Ideone の API は WSDL を使う実装なようで、よくわからなかったのと、めんどくさかったので既存のパッケージを使いました。
https://pypi.python.org/pypi/ideone/0.2.0

from ideone import Ideone

i = Ideone('ユーザー名', 'パスワード')
r = i.create_submission(code, language_name='C++14')
link = r['link']
x = i.submission_status(link)
while not int(x['status']) == 0:
 x = i.submission_status(link)
print i.submission_details(link)

基本的には、create して status を確認して details で結果を取得する流れになります。

お試しコードを実行した結果
{status: 0, memory: 3140, langName: C++14, output: hoge
, signal: 0, error: OK, langId: 44, cmpinfo: , source: #include <iostream>

int main(int argc, char** argv)
{
        std::cout << "hoge" << std::endl;
        return 0;
}

, result: 15, stderr: , time: 0.0, date: 2015-01-24 12:52:06, input: , langVersion: gcc-4.9.2, public: True}

あと何回 API が使えるかどうかはアカウント設定ページの右側 manage codes のところで確認できます。


iutest で使う
コードが実行できるようになったので、iutest で実行してみました。

が、よくわからないエラーが出ました。
$ make sample USER=xxxx PASSWORD=xxxx
python iuideone.py sample.cpp -u xxxx -p xxxx --expand_include --encoding utf-8-sig
Traceback (most recent call last):
  File "iuideone.py", line 190, in <module>
    main()
  File "iuideone.py", line 187, in main
    run(options)
  File "iuideone.py", line 179, in run
    r = run_ideone(code, options)
  File "iuideone.py", line 124, in run_ideone
    r = i.create_submission(code, language_name=options.compiler, std_input=options.stdin)
  File "build/bdist.cygwin-1.7.32-i686/egg/ideone/__init__.py", line 176, in create_submission
  File "build/bdist.cygwin-1.7.32-i686/egg/suds/client.py", line 542, in __call__
  File "build/bdist.cygwin-1.7.32-i686/egg/suds/client.py", line 602, in invoke
  File "build/bdist.cygwin-1.7.32-i686/egg/suds/client.py", line 649, in send
  File "build/bdist.cygwin-1.7.32-i686/egg/suds/client.py", line 702, in failed
  File "build/bdist.cygwin-1.7.32-i686/egg/suds/bindings/binding.py", line 258,in get_fault
  File "build/bdist.cygwin-1.7.32-i686/egg/suds/sax/parser.py", line 136, in parse
  File "/usr/lib/python2.7/xml/sax/expatreader.py", line 107, in parse
    xmlreader.IncrementalParser.parse(self, source)
  File "/usr/lib/python2.7/xml/sax/xmlreader.py", line 123, in parse
    self.feed(buffer)
  File "/usr/lib/python2.7/xml/sax/expatreader.py", line 214, in feed
    self._err_handler.fatalError(exc)
  File "/usr/lib/python2.7/xml/sax/handler.py", line 38, in fatalError
    raise exception
xml.sax._exceptions.SAXParseException: <unknown>:1:49: syntax error
Makefile:17: recipe for target 'sample' failed
make: *** [sample] Error 1


ライブラリをちょこっといじってプリントデバッグしたところ、500 が返ってきてることがわかりました。
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>500 Internal Server Error</title>
</head><body>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error or
misconfiguration and was unable to complete
your request.</p>
<p>Please contact the server administrator,
 contact@ideone.com and inform them of the time the error occurred,
and anything you might have done that may have
caused the error.</p>
<p>More information about this error may be available
in the server error log.</p>
</body></html>

コードが長すぎるのでしょうかね…
(ボーダーラインを調べようとしたが、確定できなかったので長さだけが原因ではないかも)

というわけで、またもや Wandbox の偉大さを実感する結果となりました。
しばらくは、Wandbox のみを利用しつつ、気が向いたときにまた別のオンラインコンパイラーを試したいと思います。

2015年1月19日月曜日

paiza.IO の API を使ってみた


paiza.IO はオンラインコンパイラーの1つです。

特徴としては、
  • 多彩な言語
  • 複数ファイルに対応
  • Github(Gist)連携
  • Twitter から実行
  • ブログパーツ
  • API
といったところでしょうか。

今回は、iutest のテスト環境として使えないかの実験として API を使ってみました。

API 仕様
API の仕様は以下の URL から確認できます。
http://api.paiza.io/docs/swagger/#!/runners/
※ 公式トップからのリンクだと https で接続するのですが、それだと正しく表示されないので注意

API は3つ。
create
コードを送って、コンパイル・実行をします。
create の返答はセッションIDとステータスになります。
実行結果などを取得するには、取得したセッションIDを使って別の API から取得します。

get_status
実行状況を確認する API です。create で返ってきたセッションIDをパラメータに GET します。
GET すると、セッションIDとステータスが返ってきます。

get_detail
ステータスが "completed" になったら、get_detail API で詳細結果を取得します。
こちらもセッションIDをパラメータに GET します。

ビルドおよび実行時の標準出力やエラーの内容、実行時間や使用メモリ量などが返ってきます。

API を試してみる
API仕様のページで「Try it out!」のボタンを押すと、APIを実際に試すことができます。
http://api.paiza.io/docs/swagger/#!/runners/

まずは、runners/create を開いて source_code に適当なコードを書きます。
他のパラメータはデフォルトのままで OK です。

「Try it out!」ボタンを押すと、下のように結果が表示されます。


次に、runners/get_status を開きます。
id のところに create の返答の id のところにある文字列をコピペします。

「Try it out!」ボタンを押すと、下のように結果が表示されます。


ステータスが completed になったら、runners/get_details を開きます。
get_status と同様に id を入力します。


「Try it out!」ボタンを押すと、下のように結果が表示されます。


簡単ですねぇ^^

iutest を使えるようにしてみる
Wandbox と同様に iutest が実行できるようにしてみました。
https://github.com/srz-zumix/iutest/tree/master/tools/paiza.io

で、早速サンプルを実行してみたのですが、
source_code: Too long

ざんねーーん…orz
2万行超のコードでも余裕で実行できる Wandbox の素晴らしさを再確認しました(T^T)

困ったこと
残念な結果に終わりました。
とりあえず、ここまでやってみて困ったことをまとめておきます。

  • でかいコードが実行できない
    実験した結果では、100,000 byte まで実行可能でした。
    iutest のソースコードは 720,334 byte あるので余裕でオーバーしてます。。。
  • コンパイルオプションが指定できない
  • 複数ファイルに対応しているが API からは使えない

まとめ
使ってみた感想としては、API を使って CI 環境の一部として使うのは難しそうだと感じた。
(他の言語、環境によっては十分かもしれないが)
ただ、WEB ページからの実行は便利だと思いました。Twitter のツイートでも実行できるし、公式の謳い文句にあるように勉強会のときには使えるのかも。

iutest としては、次は ideone を試してみようと思ってます。

2014年12月5日金曜日

Shippable + Wandbox で C++ の CI 環境構築

C++ Advent Calendar 2014
こちらは C++ Advent Calendar 2014 5日目の記事になります。

前置き
CI 環境構築のお話ですが、まずは簡単に用語の説明をしたいと思います。
  • CI
    Continuous Integration (継続的インテグレーション) の頭文字を取って CI 。
    ビルドやテストなどを継続的に(繰り返し)実行することで、問題の発見などをする手法です。
    この CI 環境のためのツールがたくさんあります。代表的なのは Jenkins でしょうか。
  • Shippable
    Shippable は CI ツールの一つです。
    github や bitbucket と連携して push をトリガーに、任意の処理を実行できるサービスです。
    類似サービスに Travis-CI があり、こちらの方が有名だとは思います(私も使ってます)
    が、今回は Shippable を使います。
  • Wandbox
    Wandbox は説明するまでもないでしょう。Online Compiler のひとつです。

ということで、
今回は Shippable と Wandbox を利用して、 C++ のソースコードを定期的にビルド、テストしてみようと思います。

なぜ Shippable と Wandbox か?
Wandbox は便利である
今回 Wandbox を使う理由は、
  • 豊富なコンパイラー
  • API がある
の2点です。

Wandbox でなくとも複数のコンパイラーで動作検証することは可能です。
しかし、環境構築の手間がかなりあると思います。
Wandbox ならば、そのような面倒なことをしなくとも API でコードを投げるだけで、コンパイル結果と実行結果が得られます。

なぜ Shippable か?
実は、Shippable のサポート言語には C++ がありません。
なので、 C++ の CI 環境としては Shippable は通常適さないのですが、今回はコンパイルや実行は Wandbox にお任せなので、CI 環境の要件としては Wandbox に API でコードを投げれるかどうかになります。まぁ簡単に言えば、Wandbox さえあればなんでも OK です!

でも、なんでわざわざサポートされていない環境を使うの?と思う方もいると思います。

それは、前述した通り C++ がサポートされているかどうかは、Wandbox を使うので関係ないからです。
つまり、サポート言語の縛りがなく、料金体系や private リポジトリを扱えるのかどうかなど、他の条件で CI サービスを選ぶことができます。

私の場合、Travis-CI を既に利用しており、そちらはそちらでテストが稼働中だったのと、
「言語サポートされていない環境でも CI できる」というのがネタになると思ったので、Shippable にしました。

Shippable + Wandbox で C++ の CI 環境構築
前置きはこのくらいにして、ここからどのように環境を整えたのか説明していきます。
実例
長々と説明を始めてもわかりにくいと思いますので、
はじめに Shippable + Wandbox で CI をしている実例を紹介したいと思います。

https://github.com/srz-zumix/iutest
こちらは私が作成している C++ テスティングフレームワークです。
ページを開くと README にバッジが付いているのがわかると思います。

そこに Shippable のバッジがあります。(build:shippable と書かれている黄緑のやつです)

バッジをクリックすると Shippable のページにジャンプします。
https://app.shippable.com/projects/541904d2ac22859af743f867/builds/latest


コンソールログの script あたりに Wandbox での実行結果が出力されていると思います。
こんな感じで、push があるたびに Shippable が自動的にビルドとテストをしてくれます。

だいたいどんな感じで動いているか、わかりましたでしょうか?
それでは、仕組みについて説明をしていきます。

Wandbox API を使う
まずは、Wandbox にコードを投げられるようにします。
API のドキュメントがあるのでそちらを参考に作成しました。
https://github.com/melpon/wandbox/blob/master/kennel2/API.rst

import requests
import json;

class Wandbox:
 """wandbox api class"""
 api_url = 'http://melpon.org/wandbox/api'
 parameter = { 'code':'' }
 def get_compiler_list(self):
  r = requests.get(self.api_url + '/list.json')
  r.raise_for_status()
  return r.json()
 def run(self):
  headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
  payload = json.dumps(self.parameter)
  r = requests.post(self.api_url + '/compile.json', data=payload, headers=headers)
  r.raise_for_status()
  return r.json()
 def get_permlink(self, link):
  r = requests.get(self.api_url + '/permlink/' + link )
  r.raise_for_status()
  return r.json()

 def code(self, str):
  self.parameter.update({'code':str})
 def compiler(self, str):
  self.parameter.update({'compiler':str})
 def options(self, str):
  self.parameter.update({'options':str})
 def stdin(self, str):
  self.parameter.update({'stdin':str})
 def compiler_options(self, str):
  self.parameter.update({'compiler-option-raw':str})
 def runtime_options(self, str):
  self.parameter.update({'runtime-option-raw':str})
 def permanent_link(self, b):
  self.parameter.update({'save':b})
 def dump(self):
  print self.parameter

if __name__ == '__main__':
 w = Wandbox()
 w.compiler('gcc-head')
 w.options('warning,gnu++1y')
 w.compiler_options('-Dx=hogefuga\n-O3')
 w.code('#include <iostream>\nint main() { int x = 0; std::cout << "hoge" << std::endl; }')
 print w.run()

こちらはベースとなるコードで、
iutest ではコマンドラインオプションに対応などをした iuwandbox.py という形で提供しています。
https://github.com/srz-zumix/iutest/blob/master/tools/wandbox/iuwandbox.py
使い方に関しては前回のブログで書いてますのでそちらを参照してください。
ブログズミ: iutest v1.11.0 をリリースしました

Wandbox でのコンパイルと実行ができるようになったら、ローカルでテストしておくとよいでしょう。

Shippable の登録とプロジェクト設定
Shippable の設定をします。
まずは、アカウント登録をします。

github か bitbucket が選べるのでお好きな方を使ってください。
今回は github で説明します。


github を選ぶとアクセス権を要求されます。問題なければ許可してください。




アカウント登録が済んだら、ダッシュボードの Organizations から github/bitbucket のアカウントを選択、
Repos から実行させたいリポジトリを選択するとプロジェクトが作成されます。



Shippable.yml の設定
次に、実行する処理の設定をします。
Shippable はリポジトリ直下の shippable.yml ファイルの記述にしたがって動作します。
shippable.yml の書き方は公式ドキュメントも確認してください。

language: python

python: 2.7

install:
  - pip install requests

before_script:
  - export PYTHONDONTWRITEBYTECODE=1
  - make -C tools/fuse

script:
  - cd tools/wandbox
  - python ./iuwandbox.py ../../test/iutest_syntax_tests.cpp -c ${WANDBOX_COMPILER} -f"-DIUTEST_USE_MAIN=1" --encoding utf-8-sig --expand_include

env:
  - WANDBOX_COMPILER=gcc-head
  - WANDBOX_COMPILER=gcc-4.9.1
#  - WANDBOX_COMPILER=gcc-4.9.0 # wercker
  - WANDBOX_COMPILER=gcc-4.8.2
#  - WANDBOX_COMPILER=gcc-4.8.1 # travis
  - WANDBOX_COMPILER=gcc-4.7.3
#  - WANDBOX_COMPILER=gcc-4.6.4 # drone
  - WANDBOX_COMPILER=gcc-4.5.4
#  - WANDBOX_COMPILER=gcc-4.4.7 # wercker
  - WANDBOX_COMPILER=gcc-4.3.6
  - WANDBOX_COMPILER=clang-head
#  - WANDBOX_COMPILER=clang-3.5
#  - WANDBOX_COMPILER=clang-3.4 # travis
  - WANDBOX_COMPILER=clang-3.3
#  - WANDBOX_COMPILER=clang-3.2 # wercker
#  - WANDBOX_COMPILER=clang-3.1 # wercker
  - WANDBOX_COMPILER=clang-3.0

notifications:
  email:
    on_success: change
    on_failure: always
こちらは iutest で実際に使用している設定です。
https://github.com/srz-zumix/iutest/blob/master/shippable.yml

Wandbox 連携部分(iuwandbox.py)を Python で書いているので言語は Python にしています。
install や script、before_script などはそれぞれビルドしたい内容にあわせて書くことになると思います。

また、env にコンパイラーを列挙してマトリックスを組んでいます。
Wandbox を使うのですから、様々なコンパイラーでテストするよう設定しました。

設定は以上
設定は以上です。あとはリポジトリに push すれば、自動的にビルドが走り出し、テストまでやってくれます!

バッジをつける
せっかくなので、バッジを付けたいと思います。
README なんかでよく見るアレです。

Shippable もバッジに対応していてます。
プロジェクトページの Badge を開くと、画像のリンクか Markdown のテキストが出てくるので適宜コピーして使ってください。




まとめ
  • Wandbox 最高!
    今回 CI 環境構築の肝となったのが Wandbox でした。
    多種多様なコンパイラーが扱えるので、テストに大変役に立っています。
    ホントにありがとうございます。いつもお世話になっておりますm(__)m

    とはいえ、今回紹介した iutest では push する度に 3万行近くのソースコードを投げているのですが、(しかも、マトリックス組んでるので x 10)こういう使い方は大丈夫なんでしょうか…今のところ問題は出ていませんが…ただ、それだけが気がかりではあります。

    最近だと、paiza.IO というのもリリースされたようですので、そちらも試してみようかと思ってます。

  • 使える CI ツールの幅が広がった!
    C++ で絞ると割と数が限られていた CI サービスですが、今回の方法なら言語サポートを気にすることなく使えますので、選択の幅が大きく広がったと思います。
  • C++ の話はほとんどなかった…
    C++ の話は皆無でしたね…すみません(汗)

C++ Advent Calendar 2014
明日は Fuyutsubaki さんです。よろしくお願いします。

それでは!


おまけ
この記事を執筆中、Shippable が不安定だったため、別の CI サービスとして wercker も試していました。
おまけとして簡単に紹介しておきます。

wercker も Shippable と同様に CI サービスの一種です。
対応言語は、PHP/Python/Ruby/Node.js/Go/java:android 。こちらも C++ がサポート外ですが問題ありません。

wercker も yml で動作を設定します。http://devcenter.wercker.com/articles/werckeryml/
wercker は Box と Step の組み合わせで動作する仕組みが特徴です。
http://devcenter.wercker.com/articles/introduction/pipeline.html

これら Box や Step は自作も可能ですが、今回はやってません。

また、Shippable のようなマトリックスができなさそうだったので、直列に各コンパイラーごとに Step を記述しました。
iutest の wercker.yml はこちら。
https://github.com/srz-zumix/iutest/blob/master/wercker.yml
実行結果はこんな感じになります。
https://app.wercker.com/project/bykey/d385156052aa4118a7f24affe4a8f851