DRYな備忘録

Don't Repeat Yourself.

(メモ)docker/machineのテストが落ちる問題

github.com

bash-4.4$ DRIVER=virtualbox make test-integration test/integration/core/core-commands.bats
test/integration/run-bats.sh test/integration/core/core-commands.bats
INFO: Run the tests with B2D_CACHE=1 to avoid downloading the boot2docker iso each time.
=> test/integration/core/core-commands.bats
 ✓ virtualbox: machine should not exist
 ✓ virtualbox: appears with ls
 ✓ virtualbox: has status 'started' appearing in ls
 ✓ virtualbox: create with same name again fails
 ✓ virtualbox: run busybox container
 ✓ virtualbox: url
 ✓ virtualbox: ip
 ✓ virtualbox: ssh
 ✓ virtualbox: version
 ✓ virtualbox: docker commands with the socket should work
 ✓ virtualbox: stop
 ✓ virtualbox: machine should show stopped after stop
 ✓ virtualbox: url should show an error when machine is stopped
 ✓ virtualbox: env should show an error when machine is stopped
 ✓ virtualbox: version should show an error when machine is stopped
 ✗ virtualbox: machine should not allow upgrade when stopped
   (in test file test/integration/core/core-commands.bats, line 109)
     `[[ "$status" -eq 1 ]]` failed
   Starting machine so machine can be upgraded... Starting "bats-virtualbox-test-shared-1498198301"... (bats-virtualbox-test-shared-1498198301) Check network to re-create if needed... (bats-virtualbox-test-shared-1498198301) Waiting for an IP... Machine "bats-virtualbox-test-shared-1498198301" was started. Waiting for SSH to be available... Detecting the provisioner... Waiting for SSH to be available... Detecting the provisioner... Upgrading docker... Stopping machine to do the upgrade... Upgrading machine "bats-virtualbox-test-shared-1498198301"... Copying /tmp/machine-bats-test-virtualbox/cache/boot2docker.iso to /tmp/machine-bats-test-virtualbox/machines/bats-virtualbox-test-shared-1498198301/boot2docker.iso... Starting machine back up... (bats-virtualbox-test-shared-1498198301) Check network to re-create if needed... (bats-virtualbox-test-shared-1498198301) Waiting for an IP... Restarting docker...
 ✗ virtualbox: start
   (in test file test/integration/core/core-commands.bats, line 115)
     `[ "$status" -eq 0  ]` failed
   Starting "bats-virtualbox-test-shared-1498198301"... Machine "bats-virtualbox-test-shared-1498198301" is already running.
 ✓ virtualbox: machine should show running after start
 ✓ virtualbox: kill
 ✓ virtualbox: machine should show stopped after kill
 ✓ virtualbox: restart
 ✓ virtualbox: machine should show running after restart
 ✓ virtualbox: status

23 tests, 2 failures

make: *** [test-integration] Error 1
bash-4.4$

Code Reading

まず、(in test file test/integration/core/core-commands.bats, line 109) とあるので、その行へ行く

@test "$DRIVER: machine should not allow upgrade when stopped" {
  run machine upgrade $NAME
  echo ${output}
  [[ "$status" -eq 1 ]]
}

run machine upgradeがstatus 1で終わるべきだが、status 0で成功している。

次に、run machine upgradeの内容としてcommands/upgrade.goを見る

package commands

import "github.com/docker/machine/libmachine"

func cmdUpgrade(c CommandLine, api libmachine.API) error {
    return runAction("upgrade", c, api)
}

commands/commands.go

runAction抜粋

   if errs := runActionForeachMachine(actionName, hosts); len(errs) > 0 {
        return consolidateErrs(errs)
    }

runActionForeachMachine抜粋

   for _, machine := range machines {
        numConcurrentActions++
        go machineCommand(actionName, machine, errorChan)
    }

machineCommand

// machineCommand maps the command name to the corresponding machine command.
// We run commands concurrently and communicate back an error if there was one.
func machineCommand(actionName string, host *host.Host, errorChan chan<- error) {
    // TODO: These actions should have their own type.
    commands := map[string](func() error){
        "configureAuth": host.ConfigureAuth,
        "start":         host.Start,
        "stop":          host.Stop,
        "restart":       host.Restart,
        "kill":          host.Kill,
        "upgrade":       host.Upgrade,
        "ip":            printIP(host),
        "provision":     host.Provision,
    }

    log.Debugf("command=%s machine=%s", actionName, host.Name)

    errorChan <- commands[actionName]()
}

host.Upgradeが呼ばれている

libmachine/host/host.go

Upgrade冒頭抜粋

func (h *Host) Upgrade() error {
    machineState, err := h.Driver.GetState()
    if err != nil {
        return err
    }

    if machineState != state.Running {
        log.Info("Starting machine so machine can be upgraded...")
        if err := h.Start(); err != nil {
            return err
        }
    }

テストのエラー文言にもあったように、明らかにUpgradeするためにStartを試みている。この実装をした日時と最後にテストが編集された日時が欲しい。blameしてみる。

f:id:otiai10:20170623163828p:plain

このコミットは、Start machine if needed for upgrade · docker/machine@e55dfb2 · GitHub

2017/02/23。対して、test/integration/core/core-commands.batsは、History for test/integration/core/core-commands.bats - docker/machine · GitHub この時点で2016/01/08なので、明らかにテストのほうが追従していない。

試しに、host.Upgradeの中で、machineが動いて無くてもStartしないように変更を加えると、

func (h *Host) Upgrade() error {
-  machineState, err := h.Driver.GetState()
-  if err != nil {
-      return err
-  }
-
-  if machineState != state.Running {
-      log.Info("Starting machine so machine can be upgraded...")
-      if err := h.Start(); err != nil {
-          return err
-      }
-  }

    provisioner, err := provision.DetectProvisioner(h.Driver)
    if err != nil {
        return err
    }

testそのものは

bash-4.4$ DRIVER=virtualbox make test-integration test/integration/core/core-commands.bats
test/integration/run-bats.sh test/integration/core/core-commands.bats
INFO: Run the tests with B2D_CACHE=1 to avoid downloading the boot2docker iso each time.
=> test/integration/core/core-commands.bats
 ✓ virtualbox: machine should not exist
 ✓ virtualbox: appears with ls
 ✓ virtualbox: has status 'started' appearing in ls
 ✓ virtualbox: create with same name again fails
 ✓ virtualbox: run busybox container
 ✓ virtualbox: url
 ✓ virtualbox: ip
 ✓ virtualbox: ssh
 ✓ virtualbox: version
 ✓ virtualbox: docker commands with the socket should work
 ✓ virtualbox: stop
 ✓ virtualbox: machine should show stopped after stop
 ✓ virtualbox: url should show an error when machine is stopped
 ✓ virtualbox: env should show an error when machine is stopped
 ✓ virtualbox: version should show an error when machine is stopped
 ✓ virtualbox: machine should not allow upgrade when stopped
 ✓ virtualbox: start
 ✓ virtualbox: machine should show running after start
 ✓ virtualbox: kill
 ✓ virtualbox: machine should show stopped after kill
 ✓ virtualbox: restart
 ✓ virtualbox: machine should show running after restart
 ✓ virtualbox: status

23 tests, 0 failures

make: Nothing to be done for `test/integration/core/core-commands.bats`.
bash-4.4$

通る。

結論

以下のどちらか

  1. host.Upgradeの仕様を戻す
  2. core-commands.batsのシナリオをちゃんと更新する

まあ2かな。

DRY


追記 2017/06/23 17:40

issue立てた

github.com