github.com/bigcommerce/nomad@v0.9.3-bc/client/allocrunner/taskrunner/logmon_hook_test.go (about) 1 package taskrunner 2 3 import ( 4 "context" 5 "encoding/json" 6 "io/ioutil" 7 "net" 8 "os" 9 "testing" 10 11 plugin "github.com/hashicorp/go-plugin" 12 "github.com/hashicorp/nomad/client/allocrunner/interfaces" 13 "github.com/hashicorp/nomad/helper" 14 "github.com/hashicorp/nomad/helper/testlog" 15 "github.com/hashicorp/nomad/nomad/mock" 16 pstructs "github.com/hashicorp/nomad/plugins/shared/structs" 17 "github.com/stretchr/testify/require" 18 ) 19 20 // Statically assert the logmon hook implements the expected interfaces 21 var _ interfaces.TaskPrestartHook = (*logmonHook)(nil) 22 var _ interfaces.TaskStopHook = (*logmonHook)(nil) 23 24 // TestTaskRunner_LogmonHook_LoadReattach unit tests loading logmon reattach 25 // config from persisted hook state. 26 func TestTaskRunner_LogmonHook_LoadReattach(t *testing.T) { 27 t.Parallel() 28 29 // No hook data should return nothing 30 cfg, err := reattachConfigFromHookData(nil) 31 require.Nil(t, cfg) 32 require.NoError(t, err) 33 34 // Hook data without the appropriate key should return nothing 35 cfg, err = reattachConfigFromHookData(map[string]string{"foo": "bar"}) 36 require.Nil(t, cfg) 37 require.NoError(t, err) 38 39 // Create a realistic reattach config and roundtrip it 40 addr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:0") 41 require.NoError(t, err) 42 43 orig := &plugin.ReattachConfig{ 44 Protocol: plugin.ProtocolGRPC, 45 Addr: addr, 46 Pid: 4, 47 } 48 origJSON, err := json.Marshal(pstructs.ReattachConfigFromGoPlugin(orig)) 49 require.NoError(t, err) 50 51 cfg, err = reattachConfigFromHookData(map[string]string{ 52 logmonReattachKey: string(origJSON), 53 }) 54 require.NoError(t, err) 55 56 require.Equal(t, orig, cfg) 57 } 58 59 // TestTaskRunner_LogmonHook_StartStop asserts that a new logmon is created the 60 // first time Prestart is called, reattached to on subsequent restarts, and 61 // killed on Stop. 62 func TestTaskRunner_LogmonHook_StartStop(t *testing.T) { 63 t.Parallel() 64 65 alloc := mock.BatchAlloc() 66 task := alloc.Job.TaskGroups[0].Tasks[0] 67 68 dir, err := ioutil.TempDir("", "nomadtest") 69 require.NoError(t, err) 70 defer func() { 71 require.NoError(t, os.RemoveAll(dir)) 72 }() 73 74 hookConf := newLogMonHookConfig(task.Name, dir) 75 hook := newLogMonHook(hookConf, testlog.HCLogger(t)) 76 77 req := interfaces.TaskPrestartRequest{ 78 Task: task, 79 } 80 resp := interfaces.TaskPrestartResponse{} 81 82 // First prestart should set reattach key but never be Done as it needs 83 // to rerun on agent restarts to reattach. 84 require.NoError(t, hook.Prestart(context.Background(), &req, &resp)) 85 defer hook.Stop(context.Background(), nil, nil) 86 87 require.False(t, resp.Done) 88 origHookData := resp.State[logmonReattachKey] 89 require.NotEmpty(t, origHookData) 90 91 // Running prestart again should effectively noop as it reattaches to 92 // the running logmon. 93 req.PreviousState = map[string]string{ 94 logmonReattachKey: origHookData, 95 } 96 require.NoError(t, hook.Prestart(context.Background(), &req, &resp)) 97 require.False(t, resp.Done) 98 origHookData = resp.State[logmonReattachKey] 99 require.Equal(t, origHookData, req.PreviousState[logmonReattachKey]) 100 101 // Running stop should shutdown logmon 102 stopReq := interfaces.TaskStopRequest{ 103 ExistingState: helper.CopyMapStringString(resp.State), 104 } 105 require.NoError(t, hook.Stop(context.Background(), &stopReq, nil)) 106 }