omohayui blog

おも‐はゆ・い【面映ゆい】[形][文]おもはゆ・し[ク]《顔を合わせるとまばゆく感じられる意》きまりが悪い。てれくさい。

protobuf v2 で protocmp.IgnoreFields() 使う

はじめに

これは完全に自分用の備忘録です。
もしも同じところで引っかかった方がいて参考になる場合は別ですが、特に読んでいただくほどのものではないです。 あしからず!

Go protobuf API v1 と v2

blog.golang.org

The github.com/golang/protobuf module is APIv1.
The google.golang.org/protobuf module is APIv2.

こちらの記事にあるように、github.com/golang/protobuf が v1, google.golang.org/protobuf が v2 です。
そして、proto.Message インターフェイスを変換して、2つのインターフェイス間の移行を容易にする関数が用意されてるとありますが、
つまり下位互換性はないということです。

protobuf の Diff で cmpopts.IgnoreFields() を使う

テストの中で cmp.Diff で struct 同士の Diff を取ることはよくあると思うのですが、protobuf 同士でもこれを使うことがあります。
そして、 cmp.Diff で特定の field の diff を無視したいときに使うのが、 cmpopts.IgnoreFields() ですが、
これは v1 では ignore されるのですが、v2 に移行するときに必要になる protocmp.Transform() と合わせて使おうとすると、ignore されません。

// protobuf v1
if diff := cmp.Diff(want, resp,
    cmpopts.IgnoreFields(todopb.Task{}, "Created", "Updated"),
); diff != "" {
    t.Errorf("differs: (+got -want)\n%s", diff)
}

そこで、v2 では、 cmpopts.IgnoreFields() を使う必要があります。

// protobuf v2
if diff := cmp.Diff(want, resp,
    protocmp.IgnoreFields(proto.MessageV2(&todopb.Task{}), "created", "updated"),
    protocmp.Transform(),
); diff != "" {
    t.Errorf("differs: (+got -want)\n%s", diff)
}

protocmp.Transform() を付けなくてはいけないという認識はあったのですが、ここを書き換えることに気づかず、なんで ignore されないんだろうなって考えてました。

以上、備忘録です。