Galaxy の Planemo Virtual Applianceを利用する その1

Galaxyのツールを作成するためのユーティリティー [Planemo](https://planemo.readthedocs.io/en/latest/appliance.html) の実行環境が提供されているので、これを利用してみる

## 説明する内容

- Dokcerを利用したPlanemo Virtual Applianceの利用方法
- planemo tool_init を利用したGalaxy用のxmlの作成
- planemo lint による構文チェック
- planemo test によるテスト

## Planemo Virtual Appliance

Planemoのイメージは

- Docker Container
- Open Virtual Format のOVA形式

の両方で提供されているが、ここではDocker Containerを利用する

## 確認事項

- dockerがインストールされている
- インターネットに接続されている

## planemoの実行

ターミナルを起動し、ツールを作成する（もしくはしている）ディレクトリに移動し次のコマンドを実行
(Galaxy自身も内部に含まれているため、起動には若干時間がかかる)

```terminal
$ docker run -p 8010:80 -p 9009:9009 -v `pwd`:/opt/galaxy/tools -i -t planemo/interactive /bin/bash
```

**以下は全てコンテナの中での操作**

```terminal
# source ./planemo-virtualenv/bin/activate
# cd /opt/galaxy/tools
```

```terminal
# planemo tool_init --force \
--id 'line_count' \
--name 'Count number of lines (wc -l)' \
--example_command 'wc -l target.txt > result.txt' \
--example_input target.txt \
--example_output result.txt 

Tool written to line_count.xml
```

line_count.xmlという名前のファイルが作成され、内容は下記の通り

```xml
<tool id="line_count" name="Count number of lines (wc -l)" version="0.1.0">
    <requirements>
    </requirements>
    <command detect_errors="exit_code"><![CDATA[
        wc -l "$input1" > "$output1"
    ]]></command>
    <inputs>
        <param type="data" name="input1" format="txt" />
    </inputs>
    <outputs>
        <data name="output1" format="txt" />
    </outputs>
    <help><![CDATA[
        TODO: Fill in help.
    ]]></help>
</tool>
```

## テストケースを自動生成する場合

テストに利用するためのデータを事前に作成しておく

```terminal
# seq 1 9 > target.txt
# wc -l target.txt > result.txt
```

```terminal
# planemo tool_init --force \
--id 'line_count' \
--name 'Count number of lines (wc -l)' \
--example_command 'wc -l target.txt > result.txt' \
--example_input target.txt \
--example_output result.txt \
--test_case
Tool written to line_count.xml
Copying test-file target.txt
cp 'target.txt' 'test-data'
Copying test-file result.txt
cp 'result.txt' 'test-data'
```

test-dataディレクトリが作成され、その中にテスト用のファイルがコピーされる

```terminal
# ls -aR
.:
.  ..  line_count.xml  result.txt  target.txt  test-data

./test-data:
.  ..  result.txt  target.txt
```

作成されたxmlファイルは下記の通り

```xml
<tool id="line_count" name="Count number of lines (wc -l)" version="0.1.0">
    <requirements>
    </requirements>
    <command detect_errors="exit_code"><![CDATA[
        wc -l "$input1" > "$output1"
    ]]></command>
    <inputs>
        <param type="data" name="input1" format="txt" />
    </inputs>
    <outputs>
        <data name="output1" format="txt" />
    </outputs>
    <tests>
        <test>
            <param name="input1" value="target.txt"/>
            <output name="output1" file="result.txt"/>
        </test>
    </tests>
    <help><![CDATA[
        TODO: Fill in help.
    ]]></help>
</tool>
```

## 構文チェック

planemo lintを利用して利用して構文チェック

```terminal
# planemo lint line_count.xml 
Linting tool /opt/galaxy/tools/planemo/line_count.xml
Applying linter tests... CHECK
.. CHECK: 1 test(s) found.
Applying linter output... CHECK
.. INFO: 1 outputs found.
Applying linter inputs... CHECK
.. INFO: Found 1 input parameters.
Applying linter help... WARNING
.. WARNING: Help contains TODO text.
.. CHECK: Tool contains help section.
.. CHECK: Help contains valid reStructuredText.
Applying linter general... CHECK
.. CHECK: Tool defines a version [0.1.0].
.. CHECK: Tool defines a name [Count number of lines (wc -l)].
.. CHECK: Tool defines an id [line_count].
.. CHECK: Tool targets 16.01 Galaxy profile.
Applying linter command... CHECK
.. INFO: Tool contains a command.
Applying linter citations... WARNING
.. WARNING: No citations found, consider adding citations to your tool.
Applying linter tool_xsd... CHECK
.. INFO: File validates against XML schema.
Failed linting
```

警告の内容は次の通り

- Help部分がTODOのまま
- citationsが記述されていない

(Helpの中身を適切に記述し、<help></help>の後に<citations>...</citations>を記入することで"Failed"にならずにlintを成功させる事ができる)

## テストの実行

今回はWarningをこのままにしてtestを実行してみる

```terminal
# planemo test line_count.xml
git clone --bare  'https://github.com/galaxyproject/galaxy' '/root/.planemo/gx_repo'
Cloning into bare repository '/root/.planemo/gx_repo'...
remote: Counting objects: 344814, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 344814 (delta 2), reused 1 (delta 1), pack-reused 344807
Receiving objects: 100% (344814/344814), 434.19 MiB | 3.79 MiB/s, done.
Resolving deltas: 100% (274423/274423), done.
Checking connectivity... done.
cd /tmp/tmp76zZ8I; git clone  --branch 'master' '/root/.planemo/gx_repo' 'galaxy-dev'; cd galaxy-dev; if [ -d .venv ] || [ -f dist-eggs.ini ]; then GALAXY_VIRTUAL_ENV=.venv;  else GALAXY_VIRTUAL_ENV=/root/.planemo/gx_venv; fi; export GALAXY_VIRTUAL_ENV; if [ ! -e $GALAXY_VIRTUAL_ENV ]; then /home/ubuntu/planemo-virtualenv/bin/virtualenv -p /home/ubuntu/planemo-virtualenv/bin/python2.7 $GALAXY_VIRTUAL_ENV; fi; [ -e $GALAXY_VIRTUAL_ENV ] && . $GALAXY_VIRTUAL_ENV/bin/activate; COMMON_STARTUP_ARGS=; $(grep -q 'skip-venv' run_tests.sh) && COMMON_STARTUP_ARGS="--dev-wheels"; export COMMON_STARTUP_ARGS; echo "Set COMMON_STARTUP_ARGS to ${COMMON_STARTUP_ARGS}"; ./scripts/common_startup.sh ${COMMON_STARTUP_ARGS}
Cloning into 'galaxy-dev'...
...
```

初回実行時には、galaxyをダウンロードする等実行環境を整えるのでかなり時間がかかる
コーヒーブレイクタイム:coffee:

そして最終結果は失敗

```terminal
======================================================================
FAIL: Count number of lines (wc -l) ( line_count ) > Test-1
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/tmp/tmpbwFF2Q/galaxy-dev/test/functional/test_toolbox.py", line 316, in test_tool
    self.do_it(td)
  File "/tmp/tmpbwFF2Q/galaxy-dev/test/functional/test_toolbox.py", line 82, in do_it
    raise e
JobOutputsError: History item  different than expected, difference (using diff):
( /opt/galaxy/tools/planemo/test-data/result.txt v. /tmp/tmpVsOQVBresult.txt )
--- local_file
+++ history_data
@@ -1 +1 @@
-9 target.txt
+9 /tmp/tmpbwFF2Q/files/000/dataset_1.dat

----------------------------------------------------------------------
XML: /tmp/tmpbwFF2Q/xunit.xml
----------------------------------------------------------------------
Ran 1 test in 8.632s

FAILED (failures=1)
```

`wc -l target.txt > result.txt`を実行すると出力結果にファイル名が含まれるが、Galaxyの実行環境では出力ファイルのパスを含むファイル名は実行時に与えられる

- target.txt (テストデータ):　 "9 target.txt"
- result.txt (Galaxyの実行結果): "9 /tmp/tmpbwFF2Q/files/000/dataset_1.dat"

との差異が生じたためテストが失敗する

## テストデータ及びコマンドを変更してやり直し

テストに利用するためのデータを再作成
(ファイル名を出力させないために、wcコマンドへのデータの与え方を変更した)

```terminal
# seq 1 9 > target.txt
# wc -l < target.txt > result.txt
# cat result.txt
9
```

planemoを利用してxmlを再作成

```terminal
# planemo tool_init --force \
--id 'line_count' \
--name 'Count number of lines (wc -l)' \
--example_command 'wc -l < target.txt > result.txt' \
--example_input target.txt \
--example_output result.txt \
--test_case
```

そして、テストを実行
(出力結果が長いので、2箇所で省略`...`)

```terminal
# planemo test
git --git-dir /root/.planemo/gx_repo fetch >/dev/null 2>&1
...
----------------------------------------------------------------------
XML: /tmp/tmpQiOVQK/xunit.xml
----------------------------------------------------------------------
Ran 1 test in 8.370s

OK
...
Testing complete. HTML report is in "/opt/galaxy/tools/planemo/tool_test_output.html".
All 1 test(s) executed passed.
line_count[0]: passed
```

テストがパスした
Galaxyのインスタンスを内部で起動してからテストを実行するので、テストにはちょっと時間がかかる

実行結果がtool_test_output.htmlとして出力されているのでブラウザで開いてみる

<img width="934" alt="Screen Shot 2018-05-10 at 19.00.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/213053/046c50e1-4092-15bb-47c0-3a2ef6c9df95.png">


今日はここまで:smile:

Galaxy のDocker container内部でplanemoを利用する方法については@youyuh48さんの[Galaxy用のツールを開発してみる](https://qiita.com/youyuh48/items/1f76807c1b5fedace637)を参照すると良いでしょう