packer: Add Cancel() method to hook
This commit is contained in:
parent
d5c6b9fad3
commit
80e8e09ec7
|
@ -13,7 +13,7 @@ func testBuild() *coreBuild {
|
|||
builderConfig: 42,
|
||||
builderType: "foo",
|
||||
hooks: map[string][]Hook{
|
||||
"foo": []Hook{&TestHook{}},
|
||||
"foo": []Hook{&MockHook{}},
|
||||
},
|
||||
provisioners: []coreBuildProvisioner{
|
||||
coreBuildProvisioner{&TestProvisioner{}, []interface{}{42}},
|
||||
|
@ -187,9 +187,9 @@ func TestBuild_Run(t *testing.T) {
|
|||
dispatchHook := builder.runHook
|
||||
dispatchHook.Run("foo", nil, nil, 42)
|
||||
|
||||
hook := build.hooks["foo"][0].(*TestHook)
|
||||
assert.True(hook.runCalled, "run should be called")
|
||||
assert.Equal(hook.runData, 42, "should have correct data")
|
||||
hook := build.hooks["foo"][0].(*MockHook)
|
||||
assert.True(hook.RunCalled, "run should be called")
|
||||
assert.Equal(hook.RunData, 42, "should have correct data")
|
||||
|
||||
// Verify provisioners run
|
||||
dispatchHook.Run(HookProvision, nil, nil, 42)
|
||||
|
|
|
@ -227,7 +227,7 @@ func TestEnvironment_DefaultCli_Version(t *testing.T) {
|
|||
func TestEnvironment_Hook(t *testing.T) {
|
||||
assert := asserts.NewTestingAsserts(t, true)
|
||||
|
||||
hook := &TestHook{}
|
||||
hook := &MockHook{}
|
||||
hooks := make(map[string]Hook)
|
||||
hooks["foo"] = hook
|
||||
|
||||
|
|
|
@ -11,8 +11,14 @@ const HookProvision = "packer_provision"
|
|||
// you must reference the documentation for the specific hook you're interested
|
||||
// in. In addition to that, the Hook is given access to a UI so that it can
|
||||
// output things to the user.
|
||||
//
|
||||
// Cancel is called when the hook needs to be cancelled. This will usually
|
||||
// be called when Run is still in progress so the mechanism that handles this
|
||||
// must be race-free. Cancel should attempt to cancel the hook in the
|
||||
// quickest, safest way possible.
|
||||
type Hook interface {
|
||||
Run(string, Ui, Communicator, interface{}) error
|
||||
Cancel()
|
||||
}
|
||||
|
||||
// A Hook implementation that dispatches based on an internal mapping.
|
||||
|
@ -38,3 +44,5 @@ func (h *DispatchHook) Run(name string, ui Ui, comm Communicator, data interface
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *DispatchHook) Cancel() {}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package packer
|
||||
|
||||
// MockHook is an implementation of Hook that can be used for tests.
|
||||
type MockHook struct {
|
||||
RunCalled bool
|
||||
RunComm Communicator
|
||||
RunData interface{}
|
||||
RunName string
|
||||
RunUi Ui
|
||||
CancelCalled bool
|
||||
}
|
||||
|
||||
func (t *MockHook) Run(name string, ui Ui, comm Communicator, data interface{}) error {
|
||||
t.RunCalled = true
|
||||
t.RunComm = comm
|
||||
t.RunData = data
|
||||
t.RunName = name
|
||||
t.RunUi = ui
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *MockHook) Cancel() {
|
||||
t.CancelCalled = true
|
||||
}
|
|
@ -5,23 +5,6 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
type TestHook struct {
|
||||
runCalled bool
|
||||
runComm Communicator
|
||||
runData interface{}
|
||||
runName string
|
||||
runUi Ui
|
||||
}
|
||||
|
||||
func (t *TestHook) Run(name string, ui Ui, comm Communicator, data interface{}) error {
|
||||
t.runCalled = true
|
||||
t.runComm = comm
|
||||
t.runData = data
|
||||
t.runName = name
|
||||
t.runUi = ui
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestDispatchHook_Implements(t *testing.T) {
|
||||
assert := asserts.NewTestingAsserts(t, true)
|
||||
|
||||
|
@ -40,14 +23,14 @@ func TestDispatchHook_Run_NoHooks(t *testing.T) {
|
|||
func TestDispatchHook_Run(t *testing.T) {
|
||||
assert := asserts.NewTestingAsserts(t, true)
|
||||
|
||||
hook := &TestHook{}
|
||||
hook := &MockHook{}
|
||||
|
||||
mapping := make(map[string][]Hook)
|
||||
mapping["foo"] = []Hook{hook}
|
||||
dh := &DispatchHook{mapping}
|
||||
dh.Run("foo", nil, nil, 42)
|
||||
|
||||
assert.True(hook.runCalled, "run should be called")
|
||||
assert.Equal(hook.runName, "foo", "should be proper event")
|
||||
assert.Equal(hook.runData, 42, "should be correct data")
|
||||
assert.True(hook.RunCalled, "run should be called")
|
||||
assert.Equal(hook.RunName, "foo", "should be proper event")
|
||||
assert.Equal(hook.RunData, 42, "should be correct data")
|
||||
}
|
||||
|
|
|
@ -19,8 +19,17 @@ func (c *cmdHook) Run(name string, ui packer.Ui, comm packer.Communicator, data
|
|||
return c.hook.Run(name, ui, comm, data)
|
||||
}
|
||||
|
||||
func (c *cmdHook) Cancel() {
|
||||
defer func() {
|
||||
r := recover()
|
||||
c.checkExit(r, nil)
|
||||
}()
|
||||
|
||||
c.hook.Cancel()
|
||||
}
|
||||
|
||||
func (c *cmdHook) checkExit(p interface{}, cb func()) {
|
||||
if c.client.Exited() {
|
||||
if c.client.Exited() && cb != nil {
|
||||
cb()
|
||||
} else if p != nil && !Killed {
|
||||
log.Panic(p)
|
||||
|
|
|
@ -1,17 +1,10 @@
|
|||
package plugin
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"os/exec"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type helperHook byte
|
||||
|
||||
func (helperHook) Run(string, packer.Ui, packer.Communicator, interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestHook_NoExist(t *testing.T) {
|
||||
c := NewClient(&ClientConfig{Cmd: exec.Command("i-should-not-exist")})
|
||||
defer c.Kill()
|
||||
|
|
|
@ -2,6 +2,7 @@ package plugin
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
@ -54,7 +55,7 @@ func TestHelperProcess(*testing.T) {
|
|||
case "command":
|
||||
ServeCommand(new(helperCommand))
|
||||
case "hook":
|
||||
ServeHook(new(helperHook))
|
||||
ServeHook(new(packer.MockHook))
|
||||
case "invalid-rpc-address":
|
||||
fmt.Println("lolinvalid")
|
||||
case "mock":
|
||||
|
|
|
@ -32,3 +32,8 @@ func (h *ProvisionHook) Run(name string, ui Ui, comm Communicator, data interfac
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Cancels the privisioners that are still running.
|
||||
func (h *ProvisionHook) Cancel() {
|
||||
// TODO(mitchellh): implement
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ func TestBuilderRPC(t *testing.T) {
|
|||
|
||||
// Test Run
|
||||
cache := new(testCache)
|
||||
hook := &testHook{}
|
||||
hook := &packer.MockHook{}
|
||||
ui := &testUi{}
|
||||
artifact, err := bClient.Run(ui, hook, cache)
|
||||
assert.Nil(err, "should have no error")
|
||||
|
@ -83,7 +83,7 @@ func TestBuilderRPC(t *testing.T) {
|
|||
assert.True(cache.lockCalled, "lock should be called")
|
||||
|
||||
b.runHook.Run("foo", nil, nil, nil)
|
||||
assert.True(hook.runCalled, "run should be called")
|
||||
assert.True(hook.RunCalled, "run should be called")
|
||||
|
||||
b.runUi.Say("format")
|
||||
assert.True(ui.sayCalled, "say should be called")
|
||||
|
|
|
@ -37,6 +37,10 @@ func (h *hook) Run(name string, ui packer.Ui, comm packer.Communicator, data int
|
|||
return h.client.Call("Hook.Run", args, new(interface{}))
|
||||
}
|
||||
|
||||
func (h *hook) Cancel() {
|
||||
// TODO(mitchellh): implement
|
||||
}
|
||||
|
||||
func (h *HookServer) Run(args *HookRunArgs, reply *interface{}) error {
|
||||
client, err := rpc.Dial("tcp", args.RPCAddress)
|
||||
if err != nil {
|
||||
|
|
|
@ -7,21 +7,11 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
type testHook struct {
|
||||
runCalled bool
|
||||
runUi packer.Ui
|
||||
}
|
||||
|
||||
func (h *testHook) Run(name string, ui packer.Ui, comm packer.Communicator, data interface{}) error {
|
||||
h.runCalled = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestHookRPC(t *testing.T) {
|
||||
assert := asserts.NewTestingAsserts(t, true)
|
||||
|
||||
// Create the UI to test
|
||||
h := new(testHook)
|
||||
h := new(packer.MockHook)
|
||||
|
||||
// Serve
|
||||
server := rpc.NewServer()
|
||||
|
@ -37,7 +27,7 @@ func TestHookRPC(t *testing.T) {
|
|||
// Test Run
|
||||
ui := &testUi{}
|
||||
hClient.Run("foo", ui, nil, 42)
|
||||
assert.True(h.runCalled, "run should be called")
|
||||
assert.True(h.RunCalled, "run should be called")
|
||||
}
|
||||
|
||||
func TestHook_Implements(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue