概要

dockerコンテナでgolangを動かしtomlを読み込んで標準フォーマットで出力する。

ファイル構成

今回はdockerを使ってコンテナ上で動かしますので以下のファイル構成で行うこととします。

goTest
  ├docker-compose.yml
  ├Dockerfile
  └src
   ├main.go
   ├config
   │  └testConfig.toml
   └tomlexec
      ├tomlexec.go
      └tomlexec_test.go

登場ファイル

主な登場ファイルはdockerファイルを除けば難しい事はなく、以下の4ファイルになります。
・main.go
・testConfig.toml
・tomlexec.go
・tomlexec_test.go

各ファイルの設定を見ていきましょう。

docker-compose.yml

version: '3.7'
services:
  #golangの設定
  app:
    build: ./
    container_name: goTest
    tty: true
    volumes:
      - ../:/go/src/charts_server/src
    working_dir: /go/src/charts_server/src/goTest/src
    ports:
      - "8080:8080"
    command: go run main.go
    environment:
          - "GOPATH=/go/src/charts_server"
解説

細かい説明は省きますが、以下の通りとなります。
volumes:localのディレクトリとdockerコンテナのディレクトリの同期をここで行っています。
working_dir:ここで基準になるディレクトリを設定しています。
ports:アクセスする際のポートナンバーです。
environment:ここではdockerコンテナ内でのGOPATHを指定しています。今回は「/go/src/charts_server」

Dockerfile

FROM golang:latest
RUN mkdir /go/src/charts_server
WORKDIR /go/src/charts_server/src/goTest/src
ADD . /go/src/charts_server

ここに関してはdockerの設定を行っていますが、シンプルなものとなっていますので説明は不要かと思います。

main.go

package main

import (
    "goTest/src/tomlexec"
)

func main() {
    tomlexec.Exec()
}
解説

とてもシンプルです。
1階層下のパッケージ、tomlexecをインポートして、tomlexecパッケージのExec関数を呼び出しているだけです。

testConfig.toml

[TestToml]
No    = 1
Name  = "testName"

解説

今回はgoの構造体に合わせて上記のような設定をしています。
Noはint、Nameはstringとなっています。
TestTomlに関してはmapで言うkeyのようなものと思えば良いと思います。
TestTomlと言うキーの中に、No、Nameと言うmapがあると思えば想像しやすいかもしれません。

tomlExec.go

package tomlexec

import (
    "fmt"

    "github.com/BurntSushi/toml"
)

// TConfig ...
type TConfig struct {
    TestToml *TomlConfig
}

// TomlConfig ...
type TomlConfig struct {
    No   int
    Name string
}

// Exec ...
func Exec() {
    var cfg TConfig
    _, err := toml.DecodeFile("./config/testConfig.toml", &cfg)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Println(cfg.TestToml.Name)
}
解説

TConfig、TomlConfigはそれぞれ、構造体の定義を行っています。
toml.DecodeFileで読み込むtomlファイルと読み込ませる構造体を指定しています。
今回は読み込んだ後にNameだけ標準出力するようにしています。

tomlexec_test.go

package tomlexec

import (
    "os"
    "path/filepath"
    "testing"
)

func TestExec(t *testing.T) {
    apath, _ := filepath.Abs("../")
    os.Chdir(apath)
    Exec()
}
解説

tomlExecパッケージのExec関数を呼んでいるだけの簡単なtestです。
ポイントはfilepath.Abs(“../”)とos.Chdir。
これをやらないとエラーとなってしまいます。
理由はmain.goの実行場所とこのテストの実行場所が違うと言うことです。
最初に挙げたファイル構成を見て頂けるとわかりますが、main.goよりも1階層深い場所にこのテストがあります。
このまま実行すると./config/testConfig.tomlがどこにあるのかプログラム上では分からなくなり、エラーとなりますが、filepath.Abs(“../”)で1階層下の絶対パスを取得し、それを引数にos.Chdirでワーキングディレクトリを指定することで同じように読むことが可能となります。
※pathが崩れてtestが通らない所を、通すのが目的なのでassertなどは記載していません。

実行

goTest> docker-compose up
Starting goTest ... done
Attaching to goTest
goTest | testName

testNameが表示されているのでしっかり読めていますね。

テスト

手順は
1.起動しているコンテナを検索
2.コンテナの中に入る
3.テストのあるディレクトリまで移動してテストを実行
となります。

goTest> docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
c38c50f20df5        gotest_app          "go run main.go"    24 hours ago        Up 27 minutes       0.0.0.0:8080->8080/tcp   goTest 
goTest> docker exec -ti c38c50f20df5 bash
root@c38c50f20df5:/go/src/charts_server/src/goTest/src# 
goTest/src# ls 
charts_server  config  main.exe  main.go  tmp  tomlexec
goTest/src# cd tomlexec/
goTest/src/tomlexec# go test -v
=== RUN   TestExec
testName
--- PASS: TestExec (0.01s)
PASS
ok      goTest/src/tomlexec     0.011s

ここまでで終了です。
テストも通りました。

一応上記のコードはgitで公開していますので、見たい方は参考までにどうぞ。

git

bannerAds