enzyme+React
enzymeとは
GitHub - airbnb/enzyme: JavaScript Testing utilities for React
Enzyme is a JavaScript Testing utility for React that makes it easier to assert, manipulate, and traverse your React Components' output.
karmaとかと組み合わせることも可能なのでできることは結構幅広いと思う
書いてみる
utf8_unicode_ci
全角と半角を区別する
create table test ( id int PRIMARY KEY , name varchar(255) COLLATE utf8_unicode_ci, title varchar(255) ); INSERT INTO test(id, name, title) VALUES (1, 'abc', 'abc'),(2, 'ABC', 'ABC'),(3, 'ABC', 'ABC');
結果
mysql> SELECT * from test where name ='abc'; +----+-----------+-----------+ | id | name | title | +----+-----------+-----------+ | 1 | abc | abc | | 2 | ABC | ABC | | 3 | ABC | ABC | +----+-----------+-----------+ 3 rows in set (0.01 sec) mysql> SELECT * from test where title ='abc'; +----+------+-------+ | id | name | title | +----+------+-------+ | 1 | abc | abc | | 2 | ABC | ABC | +----+------+-------+ 2 rows in set (0.01 sec)
ridgepole 0.6.4 メモ
実戦で使えるように素振り
URL
https://github.com/winebarrel/ridgepole
install
gem 'ridgepole' # スキーマにoptions(ストレージエンジンの設定など)をつける gem 'activerecord-mysql-awesome'
エクスポート
すでにテーブルがある場合はexportする.
ridgepole -c config/database.yml --export -o db/schemas/Schemafile \ --dump-with-default-fk-name --split --enable-mysql-awesome
--dump-with-default-fk-name
Railsの場合は外部キーの名前がfk_rails_xxxx
になるのでそれもエクスポートする。applyするときにも必要--split
テーブルごとにスキーマファイルを分ける--enable-mysql-awesome
create文にoptionをつける
ちなみに limit:4
は4バイト
create_table "tasks", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" do |t| t.integer "project_id", limit: 4, null: false t.string "title", limit: 255, null: false t.text "description", limit: 65535 t.integer "creator_id", limit: 4, null: false t.integer "updater_id", limit: 4, null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false end add_index "tasks", ["project_id"], name: "fk_rails_02e851e3b7", using: :btree
実行
runするときには --dry-run
をはずす
ridgepole -c config/database.yml --apply \ --dry-run -f db/schemas/Schemafile \ --dump-with-default-fk-name
比較
通常の比較
DBとファイルを比較
ridgepole --diff config/database.yml db/schemas/Schemafile \ --dump-with-default-fk-name
ロールバック的な
ridgepole --diff config/database.yml db/schemas/Schemafile \ --reverse \ --dump-with-default-fk-name
AWS CodeDeployで遊んでみた
会社でCodeDeployを使ってたけど、使ったことなかったので遊んでみた。
AWS CodeDeployとは?
https://aws.amazon.com/jp/codedeploy/ より
AWS CodeDeploy は、Amazon EC2 インスタンス、およびオンプレミスで稼働するインスタンスを含む、さまざまなインスタンスへのコードのデプロイを自動化するサービスです。
シンプルなデプロイであればこれで十二分に思える。デプロイを自動化してくれるサービスなのでCI的なことをやりたいのであれば、CodePipelineとかつかうんだろう。
全体図
GitHubにpushするとCircleCIが走るので、テストが通ったらアプリをS3にput後デプロイする。 リージョンは安いからus-east-1
内容
一部でも読んだドキュメント
- What Is AWS CodeDeploy? - AWS CodeDeploy
- Continuous Deployment with AWS CodeDeploy - CircleCI
- ポリシーでのアクセス許可の指定 - Amazon Simple Storage Service
- ユーザーポリシーの例 - Amazon Simple Storage Service
- AppSpec File Example - AWS CodeDeploy
- Install or Reinstall the AWS CodeDeploy Agent - AWS CodeDeploy
IAMユーザとロールの作成
- APIを叩くためのユーザ(ユーザ名:codeDeployUser)を作成する(このユーザのaccess id をCircleCIに管理画面で登録する) Step 1: Provision an IAM User - AWS CodeDeploy をみてロールを適切に付与する。やりたいことにもよるが,最低限S3とCodeDeploy関連があればOK
- CodeDeployで実行するときに必要なデプロイグループ用ロール(ロール名:CodeDeployServiceRole)を作成する
- アクセス許可の管理ポリシーに
AWSCodeDeployRole
を追加する - 信頼されたエンティティを追加する
- アクセス許可の管理ポリシーに
- EC2を作るときに設定するIAMロール(ロール名:CodeDeployDemo-EC2)を作成する
- 管理用ポリシーに
AmazonEC2FullAccess
を追加した(ここは多分ちゃんと絞るべき) - インラインポリシーにポリシー(ポリシー名:ec2-role-permission)を追加
- 信頼関係を追加する
- 管理用ポリシーに
CodeDeployServiceRoleの信頼関係
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "codedeploy.us-east-1.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
CodeDeployDemo-EC2のインラインポリシー
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:Get*", "s3:List*" ], "Resource": [ "arn:aws:s3:::aws-codedeploy-us-east-1/*" ] } ] }
CodeDeployDemo-EC2の信頼関係
{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
S3バケットの追加
特定者からのみのアクセスをうけるように、バケットポリシーにユーザ codeDeployUserとロールCodeDeployDemo-EC2を追加した。
EC2ユーザ作成
2台以上で作ること。
- インスタンスを作成するときにIAMロールCodeDeployDemo-EC2を忘れない
- CodeDeployのグループの対象インスタンスとなるようにタグを作成するときにキー:Role, 値:WebAppという名前をつけた
- AWS CodeDeploy agentをインストールする
CodeDeployの設定
途中で失敗してもアプリの内容はロールバックしないので注意(正常にデプロイしたものがあればそれはそのまま)
- アプリケーションを新規で作成する
- アプリケーション名:sample-app (ここは circle.ymlで使う)
- デプロイグループ名:SampleAppsGroup (ここは circle.ymlで使う)
- EC2インスタンスタグ:Role:WebApp
- サービスロール ARN:CodeDeployServiceRole を選択した
- デプロイ設定:CodeDeployDefault.OneAtATime ここはお好み
CircleCIの設定
- codeDeployUserのaccess Key IDとSecret Keyを登録する
アプリの設定
circle.yml
にデプロイの設定を記載appspec.yml
にcodeDeployで実行する内容を記載する。(この辺はあまり調べられてない)
circle.ymlの内容の抜粋
deployment: staging: branch: master codedeploy: sample-app: # ここはアプリケーション名と合わせる application_root: / region: us-east-1 deployment_group: SampleAppsGroup # ここはデプロイメントグループと合わせる revision_location: revision_type: S3 s3_location: bucket: バケット名 key_pattern: my-sample-app-{SHORT_COMMIT}-{BUILD_NUM} # キーパターンは適当
appspec.ymlの内容
version: 0.0 os: linux files: - source: / destination: /usr/local/demo-app # アプリ配置先 hooks: BeforeInstall: - location: deploy/before_install.sh # インストールする前の実行するシェル(ELBから外すとか..)
その他
/var/log/aws/codedeploy-agent/codedeploy-agent.log
にログが出るので途中で失敗した時は確認する
Jenkins2.0 + http2をつかってみた
Jenkinsには足を向けて寝れないほど毎日使ってる人間なので、めでたくJenkins2が出たのでやってみた
ついでにhttp2使ったらどのぐらいはやくなるのかな?というみたかった。
あとLet's Encryptもつかってみよう
環境
- jenkins 2.6
- nginx 1.11
- AWS(AMI ami-f5f41398) t2.micro US East (N. Virginia)リージョン
結論
http2にすると大体0.5秒〜1.0秒ぐらい速くなった。体感的には若干速くなったと感じる程度。
積極的に使っていっていいと思います
ざっくりした環境構築
Let' Encryptのインストール
gitを入れる必要がある
git clone https://github.com/certbot/certbot cd certbot/ ./certbot-auto --debug ./certbot-auto certonly --standalone -d <domain>
nginxのインストール
/etc/yum.repos.d/nginx.repo
に以下を追加してから yum install nginx
でインストール
[nginx] name=nginx repo baseurl=http://nginx.org/packages/mainline/centos/6/$basearch/ gpgcheck=0 enabled=1 priority=1
nginx.confの一部
upstream backend { server 127.0.0.1:8080; } server { listen 443 ssl http2 ; listen [::]:443 ssl http2; #listen 443 ssl ; #listen [::]:443 ssl ; server_name <domain; root /usr/share/nginx/html; gzip on; ssl_certificate "/etc/letsencrypt/live/<domain>/fullchain.pem"; ssl_certificate_key "/etc/letsencrypt/live/<domain>/privkey.pem"; # It is *strongly* recommended to generate unique DH parameters # Generate them with: openssl dhparam -out /etc/pki/nginx/dhparams.pem 2048 #ssl_dhparam "/etc/pki/nginx/dhparams.pem"; ssl_session_cache shared:SSL:1m; ssl_session_timeout 10m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers AESGCM:HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP; ssl_prefer_server_ciphers on; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { proxy_pass http://backend ; proxy_redirect default; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_max_temp_file_size 0; #this is the maximum upload size client_max_body_size 10m; client_body_buffer_size 128k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }
Jenkinsのインストール
sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo sudo rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key yum install jenkins
久しぶりに技術的なことを書けて楽しかった
不具合を分析しすぎてチームに悪影響を与えたかもしれない
担当サービスの品質を担保するというのが仕事の1つなので、不具合の分析などを行うことはよくある。
ここでいう分析とは以下のことを指してる
- 不具合がいつからいつまで発生していたか
- なぜ発生したか
- どのような対応をおこなったのか
- ユーザにどのような案内をしたのか
- (ソーシャルゲームなので)どのようなお詫び(アイテム補填)をしたのか
- どうやったら再発しないようにするか
この辺の分析はある程度の経験やスキルが必要だと思っている。 ユーザへの案内などは
- 自分が草案を出して、企画職やCSがそれに補完する
- 例:過去の事例に照らし合わせるとか、ルール上問題ないか
- 企画職やCSが草案を出して自分が補完する
- 例: 長文で書くよりも箇条書きにしようとか、時系列で書くとか
という感じでやっているので、まぁ得意不得意を補完してていいかなーとは思える。
今回のメインは「なぜ不具合が発生したか」というところ。
基本全員日々の作業に追われているし、嫌な過去は見たくないものなのであまり調べたがらない。
みんな不都合な過去をなかったことにしたいからソシャゲやってる会社はダメだと叩かれる
が、ある程度エンジニア(特にSIer)をやっていると「なぜを3回繰り返せ」というありがたい教えを聞かされるはずだ。自分は新卒2年目で叩きこまれた。
Web業界にきてだいぶ年数が経つが、若い時に叩きこまれたことは習慣(悪いものは呪いという)のようになるので癖で調べてしまう。
分析する上で色々話をきかせてもらった結果、 チームが必要以上に不具合に敏感になりすぎてる気がする。
敏感になりすぎている人と鈍感なままな人がいるというのが正確な表現
もちろん不具合はないほうがいい。不具合を起こして誰も幸せにならないからだ。
みんな可能なかぎりゼロにすることを心がけてる。 作ってる人みんなで触ってみてる場も儲けてるし、QAテストも時間かけてる。
ユーザへの影響がほとんどないものはさっさと直せばいいし、そこをいちいち分析しても大した答えは出てこないと思う。
変に敏感になり過ぎててなんか硬直してる(動きが遅い)組織になってきてる気がする。
この辺はみんなどういうマネジメントしてるんだろうか
テストの改善案の案
エンジニアのKPTで「CircleCIで走らせてるテストが項目数の割には30分超えてきたから速くしたい」という話をしたけどちゃんと説明できなかったので書く
環境
問題点
テスト実行の最初(いわゆる @Beforeとかsetup)で、マスタデータをJVMメモリに乗せているが、本番環境と同じデータを使ってる。
いちいち作らなくてもいいというメリットがあるが、本番環境と同じデータなのでいかんせんデータ量が多い。
本番環境のデータをそのまま使うとコード上通らない箇所(フェイルセーフしてる箇所)や、昔動いてたけど今は使わなくなったコードがあるのでカバレッジが上がらない。
あと、テスト用のユーザデータ(マスタデータ)を入れるときに、SQLスクリプトを生で実行したり、ヘルパークラス経由で入れてるので、バラバラになってる
2年ほど前に途中でこのチームに入った時に、テストがなかったので「勢いで」自分が入れたのが敗因だった。もう少し戦略的にやればよかったと反省しているが、入れたことへの後悔はしてない
改善案
本番環境とテスト用のデータを分けて、必要な物だけ入れる また、テストデータがバラバラになっているのはコメントが書けるYAMLに合わせる 例
user: - # ああいうユーザ id: 1 name: 10 birthday: 2016-01-01 - # こういうユーザ id: 2 name: test birthday: 2017-01-01
このファイルを用意しておき、テストを書く人がsetup時に読み込ませる。読み込ませるときには一度databaseをdrop→createした上で読み込ませる。(テストが並列化できないが、そもそもJUnitでは並列化できないからいい)
あとは既存のデータをYAMLへ変換するツールなどを作ればちょっとは楽になるかな?と思ってる。
ちなみにはてブ上で盛り上がったテスト書かなくてもいいよ的な話は、育ってきた環境やフェーズが違うからどちらが正しいとも言えないと思う。