docker-compose で mysql を立ててローカルで開発する

忘備録。


古い Django で作られたシステムがあって、訳あってローカルで動かしたい。
docker-compose があったので、動かした際にハマった問題。

version: '3.3'

services:
  db:
    image: 'mysql:5.7.22'
    restart: always
    ports:
    - '3306:3306'
    environment:
      MYSQL_DATABASE: root
      MYSQL_USER: foo
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'

docker-compose up してビルドして MySQL を起動する
次にローカルから MySQL につなぎ適当にユーザーと権限を付与。
めんどかったので全て解放した。

$ mysql -u root -h 127.0.0.1            
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 96
Server version: 5.7.22 MySQL Community Server (GPL)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>


Django の設定ファイルの DB のホストを `127.0.0.1` にする。

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'HOST': '127.0.0.1',
        'NAME': 'DBNAME',
        'USER': 'USERNAME',
        'PASSWORD': '',
    },
}

あとは syncdb して migrate して runserver したらいけた。


ハマったポイントが、 HOST 名。最初 Docker 内のホスト名にしたが、127.0.0.1 で良いみたい。

illegal hardware instruction

freezegun を使ってテストをした際に使っているテストで illegal hardware instruction が出た。


https://github.com/spulec/freezegun/issues/222
環境的には Virtualenv で Python3.6.2(ちょっと古い)で発生。
CI とか他の環境ではでない。


ググったり、上記の Issue を見たけどよく話からなった。
Python3 のバージョンが少し古かったので、brew の環境を入れ直して 新しいバージョンで Virtualenv の環境を作り直して、実行したら直った。


不思議。


ついでに homebrew の Python が例のアレによって python@2 を明示的にリンクしないと `/usr/local/bin/` に python として存在しなくなったので、Vim を起動すると Python のリンクができずに死亡した。
MacPorts だと port select で Python3 を python としてできるけど、homebrew ではどうやってやるんだろう。
早くローカルからは Python2 はなくなって欲しい…。

gdb を使ったデバッグ

macOS での方法の忘備録。


brew なり MacPorts で入れてコード署名をする必要がある。
OS XでGDBを使う(ためにコード署名をする)


taskgated を再起動するの忘れててしばらく使えなくて混乱した。
普通に pkill すれば良い。


Vimデバッグオプション付きでビルドする。

CFLAGS="-g -O0 -ggdb" LDFLAGS=-L/opt/local/lib ./configure --with-features=huge \
--enable-multibyte \
--enable-netbeans \
--with-tlib=ncurses \
--enable-cscope \
--enable-python3interp \
--enable-rubyinterp

終わったら make してビルドする。

src/vim にバイナリが出来上がってるので、gdb 経由で起動する。
(MacPorts を使ったので gddb になってる)

$ ggdb src/vim
GNU gdb (GDB) 8.0.1
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin15.6.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from src/vim...done.
(gdb) 

起動できた。

ブレークポイントを SEGV してるところの前らへんに適当にはる。

b channel.c:4153

デバッグするため Vim を起動する。

run -u NONE -U NONE ~/sample.txt

Vim を -u NONE -U NONE オプションで ~/sample.txt を開く。
Vim を操作しブレークポイントを張った箇所を通る操作をする。
あとは n とか step とか p とかで適当にデバッグしていく。

2017 年振り返り


ほぼお仕事のコミット。プライベートな開発があんまりできなかった。
Vim プラグインを幾つか作った程度。
Firefox57 になって Vimperator が完全に死んだので、Vim-Vixen にしたが自分にとって致命的に使いづらかった問題があったので PR 送った。
無事に取り込んでいただいて満足した。


お仕事では大きめのリリースが 6 月、12 月にあってその前後が多少忙しかった。
特に 4~6 月の色が濃いのはリリース前だったため。

リモートワーク

無事に 1 年半続けられた。オフィスでローカル開発してるチームの方々に感謝しかない。
7 月からもう 1 人フルリモート仲間ができた。
同じ悩みを共有できてとても嬉しい。
同時に健康問題にも直面したので課題が浮き彫りになった。

健康面

4 月と 7 月に扁桃腺炎で 2 回倒れた。
4 月は東京出張から帰った後、7 月は大きいリリースが終わった後にホッとしたのか油断した。
ストレス溜めないように気をつけないと。

右耳がなんか詰まった感じがして、突然聴力が落ちた感じがした。左右のバランスが狂って非常に気持ち悪くなった。
1 日経ったら治るだろと思い放っておいたけど治らなかったので、耳鼻咽喉科に行って検査したら、見事に右の聴力が落ちていた。
突発性難聴では無かったのは幸いだった。
一ヶ月ほど週に 2 回ほど通院して治療して元に戻った*1

首と肩

2 月に突然左腕がだるい感じがした。病院を紹介してもらって診てもらったが初見では分からないので 3 月に MRI を受けた。
MRI は初だったけど、面白かった。人生の経験値が上がった気がする。
MRI の結果は神経系には特に異常がないとのことで、薬と湿布を出されて終わり。
運動不足を指摘されたので家の近くのジムで契約して泳ぎだす。
が、5 月、6 月はリリース前で忙しかったのを言い訳にまともに通ってなかった気がする。


7 月になって少し落ち着いたので、また泳ぎだしたら、左肩と左腕に痛みが走るようになった。
昔住んでた場所の近く(今のところから車で 1 時間くらいのところ)の鍼屋さんに行って鍼を打ってもらうも、その日は楽になるが 2 日くらい経つと元に戻る。
9 月になっても酷くなるだけで改善の兆しが見られなかったので、隣駅の整形外科に行く*2
レントゲンを撮ってもらい診断してもらうと、肩関節周囲炎(通称五十肩)であると診断される*3
5 週連続で注射を打ち、できるだけリハビリに通って、リハビリ以外の日は自宅でストレッチをするように言われる。


この時点で肩を垂直に上げることはできなかった。
服を着るのが辛かったり、ライヴで腕を上げたり、飛行機で荷物を棚に入れるのが辛かった。
注射とリハビリが激痛で辛いけど改善の兆しが見えてる。
来年もしばらく続きそう。

買ってよかったもの

近所でマンションを建てる工事をしていて、工事の音が非常にうるさかったので、イヤホンをして仕事をしてたが、耳が疲れるので良いスピーカーがないか探してた。
BOSE のやつとか視聴したが低音を強調されるだけで全く好みではなかった。
他の安いやつも似たり寄ったりだった。
結局ある程度お金をかけてモニタースピーカーにした方が良いと思った。


友人のマスタリングエンジニアが愛用してる ADAM AUDIO の AX シリーズが友人ちで聴かせてもらった凄く良かったし、お勧めされたが机が狭いので置くのが困難だった。
そこで別なのを勧めてもらったのが EVE AUDIO / SC203 だった。
元 ADAM AUDIO の人がスピンアウトして作られたらしく、これも良いよと教えてもらった。
ADAM AUDIO の AX-3 より小さくて自分の机にも邪魔にならない程度に置けてとても良い。
楽器屋に現物があったので、iPhone つなげて聴かせてもらったら、低域が強調されてないしフラットな感じでとてもよかった。
さほど割引してなくてネットで買ったほうが安かったんだろうが、すぐに欲しかったので即購入した。

エイジングが終わった今とても良い音を出してくれてる。
ヘッドホンで聴いてる音がそのまま出てくれてる感じがする。
ピアノのみの曲からデスメタルまで広範囲にきちんと表現してくれてとても気に入ってる。
音楽用(ギター)には物欲が高まったら AX-3 を買おうかなとも思ってる。

ライヴ

今の会社に入って、ハロプロの追っかけやジャニーズの追っかけがいて、経済を回していてる感がとてもしたので、真似てみようと、いけるライヴは行こうと決めた。
6 月からほぼ毎月何かのライヴに行けてとても幸せだった。来年も行ける余裕を持ちたい。

来年の目標

  • 健康
    • 肩の炎症が取れてドクターストップが解除されたら泳ぐのを再開する
  • 体重が少し減ったので、このまま継続して減らしたい

*1:鼻洗浄は慣れないままだった

*2:奇しくも右耳が治りかけくらいの時

*3:ちなみ 80 歳でも 20 歳でも発症するらしい

vader.vim をつかって E2E をやる

この記事は Vim Advent Calendar 2017 16日目の記事です。
「人は生まれたままの姿が一番美しい。ノーパンタイプ」に憧れるけど、風邪をひいちゃうので厚着の vimrc です。


TL;DR

  • 日本語で vader.vim のことを書かれてるのを見たことないので書いた
  • vader.vim 便利

Vim でテスト

以前作ったプラグインに不具合報告を頂くことがあった。手動で動作確認して直したり、新しい機能を作ったりしてて良くないなーと思っていた。

Vimユニットテストといえば Vim 本体にとてもシンプルな assertion がある。
GitHub - mattn/vim-left-pad
assert を書くだけでシンプルでわかりやすい。
ただし Vim にはテストランナーはないし*1、CI からも使うのめんどくさそうと思っていた。


日本のプラグイン作者界隈では themis.vim がよく使われてるようだが、自分で動かそうとしたけど思ったように動かなかった(完全に自分が悪い)のでめんどくさくなって、まぁ良いかと放置してた。


ある時「大幅に機能追加するから、その前にテスト書いたわ」というとてもありがたい PR をいただいた。
Add tests and fix some issues by letientai299 · Pull Request #14 · heavenshell/vim-pydocstring · GitHub


PR のテストは vader.vim が使われていた。
vader.vim の存在は知っていたけど、README を読んで初見はめんどくさそうというイメージを持っていた。
せっかく頂いた PR を見てみるととてもシンプルな書き方で驚いた。

Given python (def foo with 1 param):
    def foo(arg):
        pass

Execute:
    Pydocstring

Expect python:
    def foo(arg):
        """foo

        :param arg:
        """
        pass

この場合 1 つめのブロックの状態が Vim 上にあることになる。
つまり

def foo(arg):
    pass

というファイルがあり、2 つめのブロックは

:Pydocstring

というコマンドを実行し、その結果が 3 つめのブロックをあらわし

def foo(arg):
    """foo

    :param arg:
    """
    pass

となるのを確認する。

テストの実行方法

$ /Applications/MacVim.app/Contents/MacOS/Vim -Nu minimal_vimrc -R '+Vader! *.vader'

こんな感じで Vim から vader を起動し実行する。
Mac だとシステムの Vim は古いので MacVim を指定する。
普段使いの vimrc を使うよりもシンプルな vimrc を指定した方が良いので、テスト用の vimrc を用意する。

set nocompatible
filetype off
" Clear all rtp
set rtp=$VIMRUNTIME

" Add vader.vim to rtp
set rtp+=./vader.vim

" Add pydocstring folder into rtp
set rtp+=../
filetype plugin indent on

CI で動かすように テストファイルが置いてあるディレクトリに vader.vim を置く。
これで Run time path に vader.vim が追加されて、vader.vim が動くようになる。

vader.vim の印象

関数単位のユニットテストというよりも E2E のテストライブラリ。
基本的に Execute ブロックに Vim で実行するコマンド(大抵はプラグインのコマンド)を記述し、コマンドの実行結果を Expect ブロックに書くため、xUnit や RSpec 系のテストの書き方と違って Vim に特化した DSL という感じがする。
コマンドを実行してその結果がどうなっているかというのを確認するというのに特化していると思う。

vader.vim での assertion

とはいえ vader.vim では Expect ブロックに結果を書いてテストするが assertion もかける。


vim-prettier という Prettier を Vim から実行して整形するプラグインを書いた時はそれも使った。
vim-prettier/prettier.vader at master · heavenshell/vim-prettier · GitHub

まとめ的なの

Vim script はスクリプトスコープな関数をテストから簡単に呼べなくて、テストを書くのが面倒だと思っていたが、E2E から始めりゃいいんだと気づかせてくれた。
vader.vim の PR を頂いた後に自分でテストランナーとか書いてみたけど、vader.vim で良いかと思うようになった。


個人的なポリシーとして自分の Vim プラグインは極力外部のものに依存したくないが、テスト系は例外とした。
(プラグイン本体を使うのにインストールされてなくても影響ないため)


とにかく簡単にテストを始められるのでオススメ。

*1:Vim 本体のテスト用にはあるが流用しがたい

Misspell を Vim から呼べるようにした

GitHub - heavenshell/vim-misspell: misspell for Vim.

Misspell が便利だったので Vim から呼べるようにプラグイン化した*1


直接 buffer を misspell に突っ込んだら Vim が SEGV したので channel 経由で入れたらうまくいった*2

便利。

*1:多分 ale にはないはず

*2:原因を追求する気力がない

MacPorts + MySQL5.7

プライベートな環境を久々に更新しようと思ってやったら思いの外はまった。
仕事は homebrew だけどプライベートマシンは MacPorts を使ってる。
*1


Python3.6.0, MySQL5.6 だったので Python3.6.1, MySQL5.7.17 にするかとports upgrade outdated して、MySQL を新規にインストールしようとしたらどハマりしたのでメモ。


入れる先。

  • /opt/local/var/run/mysql57
  • /opt/local/var/db/mysql57
  • /opt/local/var/log/mysql57


`$ sudo -u _mysql /opt/local/lib/mysql57/bin/mysqld --initialize` をするとに権限がないと怒られるので、`--tmpdir=/tmp` をつける。

`$ sudo /opt/local/lib/mysql57/bin/mysqld --initialize --user=_mysql --tmpdir=/tmp`


これでログに色々非推奨になったものとかが出てくるので、まずは my.cnf をきれいにする。

 innodb_large_prefix
-innodb_file_format=Barracuda
-sql_mode="NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES"
+sql_mode="NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER"
+explicit_defaults_for_timestamp=1

これで非推奨な警告らしいものは消えた。


起動したはずだからログに出てるパスワードを使って cli から接続してみると、

Error: Can't connect to local MySQL server through socket '/opt/local/var/run/mysql57/mysqld.sock' (2)

が出た。


/opt/local/var/run/mysql57 に mysql.sock を touch し chown _mysql しておく。

それでもまだ同じのが出るので、ググったら、
`secure-file-priv` とやらを設定する必要がありそうだ。

+secure-file-priv=/opt/local/var/db/mysql57/files

/opt/local/var/db/mysql57/files を 770 に設定。


再度実行。

2017-07-17T04:45:09.183964Z 0 [Warning] Setting lower_case_table_names=2 because file system for /opt/local/var/db/mysql57/ is case insensitive
2017-07-17T04:45:09.184760Z 0 [Warning] You need to use --log-bin to make --binlog-format work.
 100 200 300 400 500
 100 200 300 400 500
2017-07-17T04:45:11.707991Z 0 [Warning] InnoDB: New log files created, LSN=45790
2017-07-17T04:45:11.755651Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.
2017-07-17T04:45:11.815967Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: b7c42696-6aaa-11e7-ab9a-2c830cb15594.
2017-07-17T04:45:11.836664Z 0 [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened.
2017-07-17T04:45:12.110979Z 0 [Warning] CA certificate ca.pem is self signed.
2017-07-17T04:45:12.140515Z 1 [Note] A temporary password is generated for root@localhost: yMPR*aN3jPs.
2017-07-17T04:45:50.765696Z 0 [Warning] Insecure configuration for --secure-file-priv: Location is accessible to all OS users. Consider choosing a different directory.
2017-07-17T04:45:50.766060Z 0 [Note] /opt/local/lib/mysql57/bin/mysqld (mysqld 5.7.17-log) starting as process 10452 ...
2017-07-17T04:45:50.768018Z 0 [Warning] Setting lower_case_table_names=2 because file system for /opt/local/var/db/mysql57/ is case insensitive
2017-07-17T04:45:50.768420Z 0 [Warning] You need to use --log-bin to make --binlog-format work.
2017-07-17T04:45:50.769777Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2017-07-17T04:45:50.769812Z 0 [Note] InnoDB: Uses event mutexes
2017-07-17T04:45:50.769827Z 0 [Note] InnoDB: GCC builtin __atomic_thread_fence() is used for memory barrier
2017-07-17T04:45:50.769898Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2017-07-17T04:45:50.770818Z 0 [Note] InnoDB: Number of pools: 1
2017-07-17T04:45:50.770961Z 0 [Note] InnoDB: Using CPU crc32 instructions
2017-07-17T04:45:50.773358Z 0 [Note] InnoDB: Initializing buffer pool, total size = 512M, instances = 1, chunk size = 128M
2017-07-17T04:45:50.821204Z 0 [Note] InnoDB: Completed initialization of buffer pool
2017-07-17T04:45:50.880435Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
2017-07-17T04:45:50.897177Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2017-07-17T04:45:50.897331Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2017-07-17T04:45:50.933367Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2017-07-17T04:45:50.934408Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo rollback segment(s) are active.
2017-07-17T04:45:50.934428Z 0 [Note] InnoDB: 32 non-redo rollback segment(s) are active.
2017-07-17T04:45:50.934644Z 0 [Note] InnoDB: Waiting for purge to start
2017-07-17T04:45:51.059136Z 0 [Note] InnoDB: 5.7.17 started; log sequence number 2534561
2017-07-17T04:45:51.059358Z 0 [Note] InnoDB: Loading buffer pool(s) from /opt/local/var/db/mysql57/ib_buffer_pool
2017-07-17T04:45:51.059568Z 0 [Note] Plugin 'FEDERATED' is disabled.
2017-07-17T04:45:51.061839Z 0 [Note] InnoDB: Buffer pool(s) load completed at 170717 13:45:51
2017-07-17T04:45:51.069359Z 0 [Note] Found ca.pem, server-cert.pem and server-key.pem in data directory. Trying to enable SSL support using them.
2017-07-17T04:45:51.069387Z 0 [Note] Skipping generation of SSL certificates as certificate files are present in data directory.
2017-07-17T04:45:51.070018Z 0 [Warning] CA certificate ca.pem is self signed.
2017-07-17T04:45:51.070075Z 0 [Note] Skipping generation of RSA key pair as key files are present in data directory.
2017-07-17T04:45:51.077066Z 0 [Note] Server hostname (bind-address): '127.0.0.1'; port: 3306
2017-07-17T04:45:51.077602Z 0 [Note]   - '127.0.0.1' resolves to '127.0.0.1';
2017-07-17T04:45:51.077688Z 0 [Note] Server socket created on IP: '127.0.0.1'.
2017-07-17T04:45:51.093262Z 0 [Note] Event Scheduler: Loaded 0 events
2017-07-17T04:45:51.093377Z 0 [Note] Executing 'SELECT * FROM INFORMATION_SCHEMA.TABLES;' to get a list of tables using the deprecated partition engine. You may use the startup option '--disable-partition-engine-check' to skip this check. 
2017-07-17T04:45:51.093393Z 0 [Note] Beginning of list of non-natively partitioned tables
2017-07-17T04:45:51.106188Z 0 [Note] End of list of non-natively partitioned tables
2017-07-17T04:45:51.106279Z 0 [Note] /opt/local/lib/mysql57/bin/mysqld: ready for connections.
Version: '5.7.17-log'  socket: '/opt/local/var/run/mysql57/mysql.sock'  port: 3306  Source distribution
 $ mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.17-log

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

動いた。大変だった。

*1:古いバージョンとか簡単に入って便利