かまたま日記3

プログラミングメイン、たまに日常

住宅購入記録 (1)

昨年末に家 (建売新築) を買ったのでその記録です。今回は購入する所まで。

  • 家を買うに至った経緯
    • 定期借家契約の終了
    • 賃貸 or 持ち家
  • 家探し
    • マンション or 戸建て
      • マンションの特徴
      • 戸建ての特徴
    • 戸建て探し
      • 決めたポイント
      • 妥協した点
      • 余談
  • 記事一覧
続きを読む

ETLとELTの違い

https://www.xplenty.com/jp/blog/etl-vs-elt-ja/

を読んでのETLとELTの違いのざっくりしたまとめ

ETL

  • Extract Transform Loadの順番で行う. ソースシステムからステージ環境にExtractして変換したものをData warehouseにLoadする流れ
  • OLAPデータウェアハウスを使う際は、構造化したデータにする必要があるので、DWHにロードする前に変換する必要がある
  • 構造をDWHに入れる前に決定する必要があるので、設計変更などがあった場合、データエンジニアの作業が発生する。SaaSも増えてきてそこのコストは低減してきている
  • 事前に処理したデータを使って分析するのでデータの信頼性、処理の高速性などに利点がある
  • DWHに入れる前にデータ処理を行っているので、GDPR個人情報保護法などコンプライアンスに関する規制に対応しやすい

ELT

  • ELTはExtract Load Transformの順番で処理を行う.
    • データレイクにためた非構造化データ *1 を含んだ雑多なデータを要件に応じて変換して使う形
  • 高性能なクラウドコンピューティング環境の登場によって生まれた概念
  • 必要なデータのみを処理するため、大量のデータがある場合でも比較的高速に処理できる *2
  • 事前に構造を定義しないといけないETLにくらべて柔軟性が高い
  • データの信頼性は低い
  • Load処理は生データをデータレイクに入れるだけなので、メンテナンス性と高速性が高い

*1:JSONファイル、画像データなど

*2:ETLは入ってくるデータ全てに処理を行わないと行けない

cgroupのDevice Whitelist Controllerについて

https://www.kernel.org/doc/Documentation/cgroup-v1/devices.txt

cgroupはmknod (特殊ファイルの作成) を制限できる。

echo 'c 1:3 mr' > /sys/fs/cgroup/1/devices.allow

これは 「cgroup 1 に/dev/nullのread and mknod の権限を追加する」という意味になる

  • 最初のcはtypeでa (all), c (char), or b (block) の3つがある
  • 1:3 はMajor, minorデバイス番号。詳細は ここ 参照
  • 最後のmrは権限でr (read), w (write), m (mknod)

参考: https://linuxcommand.net/mknod

Dockerで設定する場合 --device-cgroup-rule を使う

docker run --rm --device-cgroup-rule 'c 1:3 mr' myapp

Terraformのlockfileを更新するGitHub Actionを作った

Terraform 0.14からDependency Lock File が導入されました。 そのためTerraformのproviderを更新する際にこちらのlock file (.terraform.lock.hcl) も更新する必要があります。

SEQSENSEでは Renovate を使ってライブラリアップデートを行っていますが*1、Terraformのproviderのバージョンアップは対応しているものの、lock fileの更新は2021/6/6時点でまだ未対応です。

github.com

そのため、RenovateのPRが作成された後にlock fileを更新してpushするGitHub Actionを作成しました。

github.com

以下の設定をすると、RenovateのPRが作成された際に、.terraform.lock.hcl を検知して更新したものをpushしてくれます。

name: terraform-lock-fix
on:
  push:
    branches:
      - renovate/*

jobs:
  terraform-lock-fix:
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v2
        with:
          fetch-depth: 2
      - name: fix
        uses: seqsense/terraform-lock-fix-action@v0
        with:
          git_user: @@MAINTAINER_NAME@@
          git_email: @@MAINTAINER_EMAIL_ADDRESS@@
          github_token: ${{ secrets.GITHUB_TOKEN }}
          commit_style: squash
          push: force

余談

Terraformのproviderのバージョン指定は範囲指定など柔軟にできるようになってますが (参考)、Renovateを使う場合、次のバージョンの検知はRenovateが勝手にやってくれるので、Renovate外での不要な更新を避けるために固定バージョンでやるのが良いと思います。

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "3.44.0"
      //      version = "~> 3.0"
    }
  }
}

Pull requestでPostされたBotのコメントを消すGitHub Actionを作った

皆さんCIで実行したテストやLint, カバレッジレポートの結果をbotがPull requestにpostするというのはやったことがあるのではないかと思います。 ただ、何回もPushしているとそのコメントが溜まってきて見づらくなったりすることは無いでしょうか?

たとえば弊社ではTerraformの設定ファイルが置いてあるレポジトリではCIで terraform plan をした結果をこんな感じでコメントとして貼り付けてます。

f:id:kamatama_41:20201118072616p:plain

(アプリケーションの環境ごとにポストしているので1 pushにつき4つのコメントが投稿されます)

これが毎pushごとに追加されるので、コミットが増えてくるとかなり見づらいです。今までは手動で消したり隠したりしてたのですが、自動で隠せるようにGitHub Actionを作りました。

github.com

使い方

こんな感じでActionを呼び出すだけです。絞り込み条件は2つあって、指定しない場合は過去に投稿されたコメント 全部を隠します ので、注意してください。

  • author: コメントしたアカウントのusername, たとえばbotのusername.
  • message_regex: 隠したいコメントの内容を正規表現でマッチさせる
on: pull_request

jobs:
  hide-pr-comments-action:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Hide PR comments
      uses: kamatama41/hide-pr-comments-action@v0
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        author: my-system-bot                 # OPTIONAL
        message_regex: "Test result: (OK|NG)" # OPTIONAL

実行するとこんな感じで過去のコメントが隠れます

f:id:kamatama_41:20201118073431p:plain

もし同じようなことで困っていたら、使ってみてください〜

Goでtesting.T#Helperを使う

Goのテストでヘルパーメソッドを作って共通のアサーションを定義することがあるかと思います。

package test

import "testing"

func Add(x, y int) int {
    return x + y
}

func TestAdd(t *testing.T) {
    AssertEquals(t, 2, Add(1, 1))
    AssertEquals(t, 3, Add(1, 2))
    AssertEquals(t, 4, Add(1, 3))
}

func AssertEquals(t *testing.T, expected, actual int) {
    if expected != actual {
        t.Errorf("Unexpected int\nexpected:%d, actual:%d", expected, actual)
    }
}

ここで言う AssertEquals が共通のアサーションですね。 これをこんな感じで、わざと失敗させてると以下のような出力になります。

func TestAdd(t *testing.T) {
    AssertEquals(t, 1, Add(1, 1))
    AssertEquals(t, 2, Add(1, 2))
    AssertEquals(t, 3, Add(1, 3))
}
=== RUN   TestAdd
    TestAdd: add_test.go:17: Unexpected int
        expected:1, actual:2
    TestAdd: add_test.go:17: Unexpected int
        expected:2, actual:3
    TestAdd: add_test.go:17: Unexpected int
        expected:3, actual:4
--- FAIL: TestAdd (0.00s)
FAIL

出力される行番号が全部ヘルパーメソッドの位置になってて実際のテストのどこで失敗したかが分かりづらいですね。 *1

こういうときは t.Helper() を呼ぶとそのヘルパーメソッドがcallerのスタックから除外されます。

AssertEquals関数を以下のように変更して実行します

func AssertEquals(t *testing.T, expected, actual int) {
    t.Helper()
    if expected != actual {
        t.Errorf("Unexpected int\nexpected:%d, actual:%d", expected, actual)
    }
}
=== RUN   TestAdd
    TestAdd: add_test.go:10: Unexpected int
        expected:1, actual:2
    TestAdd: add_test.go:11: Unexpected int
        expected:2, actual:3
    TestAdd: add_test.go:12: Unexpected int
        expected:3, actual:4
--- FAIL: TestAdd (0.00s)
FAIL

実際のアサーションを実行しているテストケースの行番号になりました。

まとめ

テストのヘルパーメソッドでは t.Helper() を呼び出すべし

*1:本来はこういうテストは一つのケースにまとめないでケースを分けるなどをした方が良いと思います