github.com/zhizhiboom/nomad@v0.8.5-0.20180907175415-f28fd3a1a056/client/allocrunner/taskrunner/task_runner_test.go (about)

     1  package taskrunner
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"os"
     9  	"path/filepath"
    10  	"reflect"
    11  	"strings"
    12  	"syscall"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/boltdb/bolt"
    17  	"github.com/golang/snappy"
    18  	"github.com/hashicorp/nomad/client/allocdir"
    19  	"github.com/hashicorp/nomad/client/allocrunner/taskrunner/restarts"
    20  	"github.com/hashicorp/nomad/client/config"
    21  	consulApi "github.com/hashicorp/nomad/client/consul"
    22  	"github.com/hashicorp/nomad/client/driver/env"
    23  	cstructs "github.com/hashicorp/nomad/client/structs"
    24  	"github.com/hashicorp/nomad/client/vaultclient"
    25  	"github.com/hashicorp/nomad/command/agent/consul"
    26  	"github.com/hashicorp/nomad/helper/testlog"
    27  	"github.com/hashicorp/nomad/nomad/mock"
    28  	"github.com/hashicorp/nomad/nomad/structs"
    29  	"github.com/hashicorp/nomad/testutil"
    30  	"github.com/kr/pretty"
    31  )
    32  
    33  // Returns a tracker that never restarts.
    34  func noRestartsTracker() *restarts.RestartTracker {
    35  	policy := &structs.RestartPolicy{Attempts: 0, Mode: structs.RestartPolicyModeFail}
    36  	return restarts.NewRestartTracker(policy, structs.JobTypeBatch)
    37  }
    38  
    39  type MockTaskStateUpdater struct {
    40  	state  string
    41  	failed bool
    42  	events []*structs.TaskEvent
    43  }
    44  
    45  func (m *MockTaskStateUpdater) Update(name, state string, event *structs.TaskEvent, _ bool) {
    46  	if state != "" {
    47  		m.state = state
    48  	}
    49  	if event != nil {
    50  		if event.FailsTask {
    51  			m.failed = true
    52  		}
    53  		m.events = append(m.events, event)
    54  	}
    55  }
    56  
    57  // String for debugging purposes.
    58  func (m *MockTaskStateUpdater) String() string {
    59  	s := fmt.Sprintf("Updates:\n  state=%q\n  failed=%t\n  events=\n", m.state, m.failed)
    60  	for _, e := range m.events {
    61  		s += fmt.Sprintf("    %#v\n", e)
    62  	}
    63  	return s
    64  }
    65  
    66  type taskRunnerTestCtx struct {
    67  	upd          *MockTaskStateUpdater
    68  	tr           *TaskRunner
    69  	allocDir     *allocdir.AllocDir
    70  	vault        *vaultclient.MockVaultClient
    71  	consul       *consul.MockAgent
    72  	consulClient *consul.ServiceClient
    73  }
    74  
    75  // Cleanup calls Destroy on the task runner and alloc dir
    76  func (ctx *taskRunnerTestCtx) Cleanup() {
    77  	ctx.consulClient.Shutdown()
    78  	ctx.tr.Destroy(structs.NewTaskEvent(structs.TaskKilled))
    79  	ctx.allocDir.Destroy()
    80  }
    81  
    82  func testTaskRunner(t *testing.T, restarts bool) *taskRunnerTestCtx {
    83  	// Use mock driver
    84  	alloc := mock.Alloc()
    85  	task := alloc.Job.TaskGroups[0].Tasks[0]
    86  	task.Driver = "mock_driver"
    87  	task.Config["run_for"] = "500ms"
    88  	return testTaskRunnerFromAlloc(t, restarts, alloc)
    89  }
    90  
    91  // Creates a mock task runner using the first task in the first task group of
    92  // the passed allocation.
    93  //
    94  // Callers should defer Cleanup() to cleanup after completion
    95  func testTaskRunnerFromAlloc(t *testing.T, restarts bool, alloc *structs.Allocation) *taskRunnerTestCtx {
    96  	logger := testlog.Logger(t)
    97  	conf := config.DefaultConfig()
    98  	conf.Node = mock.Node()
    99  	conf.StateDir = os.TempDir()
   100  	conf.AllocDir = os.TempDir()
   101  
   102  	tmp, err := ioutil.TempFile("", "state-db")
   103  	if err != nil {
   104  		t.Fatalf("error creating state db file: %v", err)
   105  	}
   106  	db, err := bolt.Open(tmp.Name(), 0600, nil)
   107  	if err != nil {
   108  		t.Fatalf("error creating state db: %v", err)
   109  	}
   110  
   111  	upd := &MockTaskStateUpdater{}
   112  	task := alloc.Job.TaskGroups[0].Tasks[0]
   113  
   114  	allocDir := allocdir.NewAllocDir(testlog.Logger(t), filepath.Join(conf.AllocDir, alloc.ID))
   115  	if err := allocDir.Build(); err != nil {
   116  		t.Fatalf("error building alloc dir: %v", err)
   117  		return nil
   118  	}
   119  
   120  	//HACK to get FSIsolation and chroot without using AllocRunner,
   121  	//     TaskRunner, or Drivers
   122  	fsi := cstructs.FSIsolationImage
   123  	switch task.Driver {
   124  	case "raw_exec":
   125  		fsi = cstructs.FSIsolationNone
   126  	case "exec", "java":
   127  		fsi = cstructs.FSIsolationChroot
   128  	}
   129  	taskDir := allocDir.NewTaskDir(task.Name)
   130  	if err := taskDir.Build(false, config.DefaultChrootEnv, fsi); err != nil {
   131  		t.Fatalf("error building task dir %q: %v", task.Name, err)
   132  		return nil
   133  	}
   134  
   135  	vclient := vaultclient.NewMockVaultClient()
   136  	cclient := consul.NewMockAgent()
   137  	serviceClient := consul.NewServiceClient(cclient, logger, true)
   138  	go serviceClient.Run()
   139  	tr := NewTaskRunner(logger, conf, db, upd.Update, taskDir, alloc, task, vclient, serviceClient)
   140  	if !restarts {
   141  		tr.restartTracker = noRestartsTracker()
   142  	}
   143  	return &taskRunnerTestCtx{
   144  		upd:          upd,
   145  		tr:           tr,
   146  		allocDir:     allocDir,
   147  		vault:        vclient,
   148  		consul:       cclient,
   149  		consulClient: serviceClient,
   150  	}
   151  }
   152  
   153  // testWaitForTaskToStart waits for the task to or fails the test
   154  func testWaitForTaskToStart(t *testing.T, ctx *taskRunnerTestCtx) {
   155  	// Wait for the task to start
   156  	testutil.WaitForResult(func() (bool, error) {
   157  		l := len(ctx.upd.events)
   158  		if l < 2 {
   159  			return false, fmt.Errorf("Expect two events; got %v", l)
   160  		}
   161  
   162  		if ctx.upd.events[0].Type != structs.TaskReceived {
   163  			return false, fmt.Errorf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
   164  		}
   165  
   166  		if l >= 3 {
   167  			if ctx.upd.events[1].Type != structs.TaskSetup {
   168  				return false, fmt.Errorf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskSetup)
   169  			}
   170  			if ctx.upd.events[2].Type != structs.TaskStarted {
   171  				return false, fmt.Errorf("Third Event was %v; want %v", ctx.upd.events[2].Type, structs.TaskStarted)
   172  			}
   173  		} else {
   174  			if ctx.upd.events[1].Type != structs.TaskStarted {
   175  				return false, fmt.Errorf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskStarted)
   176  			}
   177  		}
   178  
   179  		return true, nil
   180  	}, func(err error) {
   181  		t.Fatalf("err: %v", err)
   182  	})
   183  }
   184  
   185  func TestTaskRunner_SimpleRun(t *testing.T) {
   186  	t.Parallel()
   187  	ctx := testTaskRunner(t, false)
   188  	ctx.tr.MarkReceived()
   189  	go ctx.tr.Run()
   190  	defer ctx.Cleanup()
   191  
   192  	select {
   193  	case <-ctx.tr.WaitCh():
   194  	case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second):
   195  		t.Fatalf("timeout")
   196  	}
   197  
   198  	if len(ctx.upd.events) != 4 {
   199  		t.Fatalf("should have 3 ctx.updates: %#v", ctx.upd.events)
   200  	}
   201  
   202  	if ctx.upd.state != structs.TaskStateDead {
   203  		t.Fatalf("TaskState %v; want %v", ctx.upd.state, structs.TaskStateDead)
   204  	}
   205  
   206  	event := ctx.upd.events[0]
   207  
   208  	if event.Type != structs.TaskReceived {
   209  		t.Fatalf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
   210  	}
   211  
   212  	event = ctx.upd.events[1]
   213  	if event.Type != structs.TaskSetup {
   214  		t.Fatalf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskSetup)
   215  	}
   216  	displayMsg := event.DisplayMessage
   217  
   218  	if displayMsg != "Building Task Directory" {
   219  		t.Fatalf("Bad display message:%v", displayMsg)
   220  	}
   221  
   222  	event = ctx.upd.events[2]
   223  	if event.Type != structs.TaskStarted {
   224  		t.Fatalf("Second Event was %v; want %v", ctx.upd.events[2].Type, structs.TaskStarted)
   225  	}
   226  	displayMsg = event.DisplayMessage
   227  	if displayMsg != "Task started by client" {
   228  		t.Fatalf("Bad display message:%v", displayMsg)
   229  	}
   230  
   231  	event = ctx.upd.events[3]
   232  	if event.Type != structs.TaskTerminated {
   233  		t.Fatalf("Third Event was %v; want %v", event.Type, structs.TaskTerminated)
   234  	}
   235  	displayMsg = event.DisplayMessage
   236  	if displayMsg != "Exit Code: 0" {
   237  		t.Fatalf("Bad display message:%v", displayMsg)
   238  	}
   239  	if event.Details["exit_code"] != "0" {
   240  		t.Fatalf("Bad details map :%v", event.Details)
   241  	}
   242  
   243  }
   244  
   245  func TestTaskRunner_Run_RecoverableStartError(t *testing.T) {
   246  	t.Parallel()
   247  	alloc := mock.Alloc()
   248  	task := alloc.Job.TaskGroups[0].Tasks[0]
   249  	task.Driver = "mock_driver"
   250  	task.Config = map[string]interface{}{
   251  		"exit_code":               0,
   252  		"start_error":             "driver failure",
   253  		"start_error_recoverable": true,
   254  	}
   255  
   256  	ctx := testTaskRunnerFromAlloc(t, true, alloc)
   257  	ctx.tr.MarkReceived()
   258  	go ctx.tr.Run()
   259  	defer ctx.Cleanup()
   260  
   261  	testutil.WaitForResult(func() (bool, error) {
   262  		if l := len(ctx.upd.events); l < 4 {
   263  			return false, fmt.Errorf("Expect at least four events; got %v", l)
   264  		}
   265  
   266  		if ctx.upd.events[0].Type != structs.TaskReceived {
   267  			return false, fmt.Errorf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
   268  		}
   269  
   270  		if ctx.upd.events[1].Type != structs.TaskSetup {
   271  			return false, fmt.Errorf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskSetup)
   272  		}
   273  
   274  		if ctx.upd.events[2].Type != structs.TaskDriverFailure {
   275  			return false, fmt.Errorf("Third Event was %v; want %v", ctx.upd.events[2].Type, structs.TaskDriverFailure)
   276  		}
   277  
   278  		if ctx.upd.events[3].Type != structs.TaskRestarting {
   279  			return false, fmt.Errorf("Fourth Event was %v; want %v", ctx.upd.events[3].Type, structs.TaskRestarting)
   280  		}
   281  
   282  		return true, nil
   283  	}, func(err error) {
   284  		t.Fatalf("err: %v", err)
   285  	})
   286  }
   287  
   288  func TestTaskRunner_Destroy(t *testing.T) {
   289  	t.Parallel()
   290  	alloc := mock.Alloc()
   291  	task := alloc.Job.TaskGroups[0].Tasks[0]
   292  	task.Driver = "mock_driver"
   293  	task.Config = map[string]interface{}{
   294  		"run_for": "1000s",
   295  	}
   296  
   297  	ctx := testTaskRunnerFromAlloc(t, true, alloc)
   298  	ctx.tr.MarkReceived()
   299  	go ctx.tr.Run()
   300  	defer ctx.Cleanup()
   301  
   302  	// Wait for the task to start
   303  	testWaitForTaskToStart(t, ctx)
   304  
   305  	// Begin the tear down
   306  	ctx.tr.Destroy(structs.NewTaskEvent(structs.TaskKilled))
   307  
   308  	select {
   309  	case <-ctx.tr.WaitCh():
   310  	case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second):
   311  		t.Fatalf("timeout")
   312  	}
   313  
   314  	if len(ctx.upd.events) != 5 {
   315  		t.Fatalf("should have 5 ctx.updates: %#v", ctx.upd.events)
   316  	}
   317  
   318  	if ctx.upd.state != structs.TaskStateDead {
   319  		t.Fatalf("TaskState %v; want %v", ctx.upd.state, structs.TaskStateDead)
   320  	}
   321  
   322  	if ctx.upd.events[3].Type != structs.TaskKilling {
   323  		t.Fatalf("Third Event was %v; want %v", ctx.upd.events[3].Type, structs.TaskKilling)
   324  	}
   325  
   326  	if ctx.upd.events[4].Type != structs.TaskKilled {
   327  		t.Fatalf("Third Event was %v; want %v", ctx.upd.events[4].Type, structs.TaskKilled)
   328  	}
   329  }
   330  
   331  func TestTaskRunner_Update(t *testing.T) {
   332  	t.Parallel()
   333  	alloc := mock.Alloc()
   334  	task := alloc.Job.TaskGroups[0].Tasks[0]
   335  	task.Services[0].Checks[0] = &structs.ServiceCheck{
   336  		Name:      "http-check",
   337  		Type:      "http",
   338  		PortLabel: "http",
   339  		Path:      "${NOMAD_META_foo}",
   340  	}
   341  	task.Driver = "mock_driver"
   342  	task.Config = map[string]interface{}{
   343  		"run_for": "100s",
   344  	}
   345  
   346  	ctx := testTaskRunnerFromAlloc(t, true, alloc)
   347  	ctx.tr.MarkReceived()
   348  	go ctx.tr.Run()
   349  	defer ctx.Cleanup()
   350  
   351  	testWaitForTaskToStart(t, ctx)
   352  
   353  	// Update the task definition
   354  	updateAlloc := ctx.tr.alloc.Copy()
   355  
   356  	// Update the restart policy
   357  	newTG := updateAlloc.Job.TaskGroups[0]
   358  	newMode := "foo"
   359  	newTG.RestartPolicy.Mode = newMode
   360  
   361  	newTask := newTG.Tasks[0]
   362  	newTask.Driver = "mock_driver"
   363  
   364  	// Update meta to make sure service checks are interpolated correctly
   365  	// #2180
   366  	newTask.Meta["foo"] = "/UPDATE"
   367  
   368  	// Update the kill timeout
   369  	oldHandle := ctx.tr.handle.ID()
   370  	newTask.KillTimeout = time.Hour
   371  	ctx.tr.Update(updateAlloc)
   372  
   373  	// Wait for ctx.update to take place
   374  	testutil.WaitForResult(func() (bool, error) {
   375  		if ctx.tr.task == newTask {
   376  			return false, fmt.Errorf("We copied the pointer! This would be very bad")
   377  		}
   378  		if ctx.tr.task.Driver != newTask.Driver {
   379  			return false, fmt.Errorf("Task not copied")
   380  		}
   381  		if ctx.tr.restartTracker.GetPolicy().Mode != newMode {
   382  			return false, fmt.Errorf("expected restart policy %q but found %q", newMode, ctx.tr.restartTracker.GetPolicy().Mode)
   383  		}
   384  		if ctx.tr.handle.ID() == oldHandle {
   385  			return false, fmt.Errorf("handle not ctx.updated")
   386  		}
   387  
   388  		// Make sure Consul services were interpolated correctly during
   389  		// the update #2180
   390  		checks := ctx.consul.CheckRegs()
   391  		if n := len(checks); n != 1 {
   392  			return false, fmt.Errorf("expected 1 check but found %d", n)
   393  		}
   394  		for _, check := range checks {
   395  			if found := check.HTTP; !strings.HasSuffix(found, "/UPDATE") {
   396  				return false, fmt.Errorf("expected consul check path to end with /UPDATE but found: %q", found)
   397  			}
   398  		}
   399  		return true, nil
   400  	}, func(err error) {
   401  		t.Fatalf("err: %v", err)
   402  	})
   403  }
   404  
   405  func TestTaskRunner_SaveRestoreState(t *testing.T) {
   406  	t.Parallel()
   407  	alloc := mock.Alloc()
   408  	task := alloc.Job.TaskGroups[0].Tasks[0]
   409  	task.Driver = "mock_driver"
   410  	task.Config = map[string]interface{}{
   411  		"exit_code": "0",
   412  		"run_for":   "5s",
   413  	}
   414  
   415  	// Give it a Vault token
   416  	task.Vault = &structs.Vault{Policies: []string{"default"}}
   417  
   418  	ctx := testTaskRunnerFromAlloc(t, false, alloc)
   419  	ctx.tr.MarkReceived()
   420  	go ctx.tr.Run()
   421  	defer ctx.Cleanup()
   422  
   423  	// Wait for the task to be running and then snapshot the state
   424  	testWaitForTaskToStart(t, ctx)
   425  
   426  	if err := ctx.tr.SaveState(); err != nil {
   427  		t.Fatalf("err: %v", err)
   428  	}
   429  
   430  	// Read the token from the file system
   431  	tokenPath := filepath.Join(ctx.tr.taskDir.SecretsDir, vaultTokenFile)
   432  	data, err := ioutil.ReadFile(tokenPath)
   433  	if err != nil {
   434  		t.Fatalf("Failed to read file: %v", err)
   435  	}
   436  	token := string(data)
   437  	if len(token) == 0 {
   438  		t.Fatalf("Token not written to disk")
   439  	}
   440  
   441  	// Create a new task runner
   442  	task2 := &structs.Task{Name: ctx.tr.task.Name, Driver: ctx.tr.task.Driver, Vault: ctx.tr.task.Vault}
   443  	tr2 := NewTaskRunner(ctx.tr.logger, ctx.tr.config, ctx.tr.stateDB, ctx.upd.Update,
   444  		ctx.tr.taskDir, ctx.tr.alloc, task2, ctx.tr.vaultClient, ctx.tr.consul)
   445  	tr2.restartTracker = noRestartsTracker()
   446  	if _, err := tr2.RestoreState(); err != nil {
   447  		t.Fatalf("err: %v", err)
   448  	}
   449  	go tr2.Run()
   450  	defer tr2.Destroy(structs.NewTaskEvent(structs.TaskKilled))
   451  
   452  	// Destroy and wait
   453  	select {
   454  	case <-tr2.WaitCh():
   455  	case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second):
   456  		t.Fatalf("timeout")
   457  	}
   458  
   459  	// Check that we recovered the token
   460  	if act := tr2.vaultFuture.Get(); act != token {
   461  		t.Fatalf("Vault token not properly recovered")
   462  	}
   463  }
   464  
   465  func TestTaskRunner_Download_List(t *testing.T) {
   466  	t.Parallel()
   467  	ts := httptest.NewServer(http.FileServer(http.Dir(filepath.Dir("."))))
   468  	defer ts.Close()
   469  
   470  	// Create an allocation that has a task with a list of artifacts.
   471  	alloc := mock.Alloc()
   472  	task := alloc.Job.TaskGroups[0].Tasks[0]
   473  	task.Driver = "mock_driver"
   474  	task.Config = map[string]interface{}{
   475  		"exit_code": "0",
   476  		"run_for":   "10s",
   477  	}
   478  	f1 := "task_runner_test.go"
   479  	f2 := "task_runner.go"
   480  	artifact1 := structs.TaskArtifact{
   481  		GetterSource: fmt.Sprintf("%s/%s", ts.URL, f1),
   482  	}
   483  	artifact2 := structs.TaskArtifact{
   484  		GetterSource: fmt.Sprintf("%s/%s", ts.URL, f2),
   485  	}
   486  	task.Artifacts = []*structs.TaskArtifact{&artifact1, &artifact2}
   487  
   488  	ctx := testTaskRunnerFromAlloc(t, false, alloc)
   489  	ctx.tr.MarkReceived()
   490  	go ctx.tr.Run()
   491  	defer ctx.Cleanup()
   492  
   493  	select {
   494  	case <-ctx.tr.WaitCh():
   495  	case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second):
   496  		t.Fatalf("timeout")
   497  	}
   498  
   499  	if len(ctx.upd.events) != 5 {
   500  		t.Fatalf("should have 5 ctx.updates: %#v", ctx.upd.events)
   501  	}
   502  
   503  	if ctx.upd.state != structs.TaskStateDead {
   504  		t.Fatalf("TaskState %v; want %v", ctx.upd.state, structs.TaskStateDead)
   505  	}
   506  
   507  	if ctx.upd.events[0].Type != structs.TaskReceived {
   508  		t.Fatalf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
   509  	}
   510  
   511  	if ctx.upd.events[1].Type != structs.TaskSetup {
   512  		t.Fatalf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskSetup)
   513  	}
   514  
   515  	if ctx.upd.events[2].Type != structs.TaskDownloadingArtifacts {
   516  		t.Fatalf("Third Event was %v; want %v", ctx.upd.events[2].Type, structs.TaskDownloadingArtifacts)
   517  	}
   518  
   519  	if ctx.upd.events[3].Type != structs.TaskStarted {
   520  		t.Fatalf("Forth Event was %v; want %v", ctx.upd.events[3].Type, structs.TaskStarted)
   521  	}
   522  
   523  	if ctx.upd.events[4].Type != structs.TaskTerminated {
   524  		t.Fatalf("Fifth Event was %v; want %v", ctx.upd.events[4].Type, structs.TaskTerminated)
   525  	}
   526  
   527  	// Check that both files exist.
   528  	if _, err := os.Stat(filepath.Join(ctx.tr.taskDir.Dir, f1)); err != nil {
   529  		t.Fatalf("%v not downloaded", f1)
   530  	}
   531  	if _, err := os.Stat(filepath.Join(ctx.tr.taskDir.Dir, f2)); err != nil {
   532  		t.Fatalf("%v not downloaded", f2)
   533  	}
   534  }
   535  
   536  func TestTaskRunner_Download_Retries(t *testing.T) {
   537  	t.Parallel()
   538  	// Create an allocation that has a task with bad artifacts.
   539  	alloc := mock.Alloc()
   540  	task := alloc.Job.TaskGroups[0].Tasks[0]
   541  	task.Driver = "mock_driver"
   542  	task.Config = map[string]interface{}{
   543  		"exit_code": "0",
   544  		"run_for":   "10s",
   545  	}
   546  	artifact := structs.TaskArtifact{
   547  		GetterSource: "http://127.0.0.1:0/foo/bar/baz",
   548  	}
   549  	task.Artifacts = []*structs.TaskArtifact{&artifact}
   550  
   551  	// Make the restart policy try one ctx.update
   552  	alloc.Job.TaskGroups[0].RestartPolicy = &structs.RestartPolicy{
   553  		Attempts: 1,
   554  		Interval: 10 * time.Minute,
   555  		Delay:    1 * time.Second,
   556  		Mode:     structs.RestartPolicyModeFail,
   557  	}
   558  
   559  	ctx := testTaskRunnerFromAlloc(t, true, alloc)
   560  	ctx.tr.MarkReceived()
   561  	go ctx.tr.Run()
   562  	defer ctx.Cleanup()
   563  
   564  	select {
   565  	case <-ctx.tr.WaitCh():
   566  	case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second):
   567  		t.Fatalf("timeout")
   568  	}
   569  
   570  	if len(ctx.upd.events) != 8 {
   571  		t.Fatalf("should have 8 ctx.updates: %#v", ctx.upd.events)
   572  	}
   573  
   574  	if ctx.upd.state != structs.TaskStateDead {
   575  		t.Fatalf("TaskState %v; want %v", ctx.upd.state, structs.TaskStateDead)
   576  	}
   577  
   578  	if ctx.upd.events[0].Type != structs.TaskReceived {
   579  		t.Fatalf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
   580  	}
   581  
   582  	if ctx.upd.events[1].Type != structs.TaskSetup {
   583  		t.Fatalf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskSetup)
   584  	}
   585  
   586  	if ctx.upd.events[2].Type != structs.TaskDownloadingArtifacts {
   587  		t.Fatalf("Third Event was %v; want %v", ctx.upd.events[2].Type, structs.TaskDownloadingArtifacts)
   588  	}
   589  
   590  	if ctx.upd.events[3].Type != structs.TaskArtifactDownloadFailed {
   591  		t.Fatalf("Fourth Event was %v; want %v", ctx.upd.events[3].Type, structs.TaskArtifactDownloadFailed)
   592  	}
   593  
   594  	if ctx.upd.events[4].Type != structs.TaskRestarting {
   595  		t.Fatalf("Fifth Event was %v; want %v", ctx.upd.events[4].Type, structs.TaskRestarting)
   596  	}
   597  
   598  	if ctx.upd.events[5].Type != structs.TaskDownloadingArtifacts {
   599  		t.Fatalf("Sixth Event was %v; want %v", ctx.upd.events[5].Type, structs.TaskDownloadingArtifacts)
   600  	}
   601  
   602  	if ctx.upd.events[6].Type != structs.TaskArtifactDownloadFailed {
   603  		t.Fatalf("Seventh Event was %v; want %v", ctx.upd.events[6].Type, structs.TaskArtifactDownloadFailed)
   604  	}
   605  
   606  	if ctx.upd.events[7].Type != structs.TaskNotRestarting {
   607  		t.Fatalf("Eighth Event was %v; want %v", ctx.upd.events[7].Type, structs.TaskNotRestarting)
   608  	}
   609  }
   610  
   611  // TestTaskRunner_UnregisterConsul_Retries asserts a task is unregistered from
   612  // Consul when waiting to be retried.
   613  func TestTaskRunner_UnregisterConsul_Retries(t *testing.T) {
   614  	t.Parallel()
   615  	// Create an allocation that has a task with bad artifacts.
   616  	alloc := mock.Alloc()
   617  
   618  	// Make the restart policy try one ctx.update
   619  	alloc.Job.TaskGroups[0].RestartPolicy = &structs.RestartPolicy{
   620  		Attempts: 1,
   621  		Interval: 10 * time.Minute,
   622  		Delay:    time.Nanosecond,
   623  		Mode:     structs.RestartPolicyModeFail,
   624  	}
   625  
   626  	task := alloc.Job.TaskGroups[0].Tasks[0]
   627  	task.Driver = "mock_driver"
   628  	task.Config = map[string]interface{}{
   629  		"exit_code": "1",
   630  		"run_for":   "1ns",
   631  	}
   632  
   633  	ctx := testTaskRunnerFromAlloc(t, true, alloc)
   634  
   635  	// Use mockConsulServiceClient
   636  	consul := consulApi.NewMockConsulServiceClient(t)
   637  	ctx.tr.consul = consul
   638  
   639  	ctx.tr.MarkReceived()
   640  	ctx.tr.Run()
   641  	defer ctx.Cleanup()
   642  
   643  	// Assert it is properly registered and unregistered
   644  	if expected := 6; len(consul.Ops) != expected {
   645  		t.Errorf("expected %d consul ops but found: %d", expected, len(consul.Ops))
   646  	}
   647  	if consul.Ops[0].Op != "add" {
   648  		t.Errorf("expected first Op to be add but found: %q", consul.Ops[0].Op)
   649  	}
   650  	if consul.Ops[1].Op != "remove" {
   651  		t.Errorf("expected second op to be remove but found: %q", consul.Ops[1].Op)
   652  	}
   653  	if consul.Ops[2].Op != "remove" {
   654  		t.Errorf("expected third op to be remove but found: %q", consul.Ops[2].Op)
   655  	}
   656  	if consul.Ops[3].Op != "add" {
   657  		t.Errorf("expected fourth op to be add but found: %q", consul.Ops[3].Op)
   658  	}
   659  	if consul.Ops[4].Op != "remove" {
   660  		t.Errorf("expected fifth op to be remove but found: %q", consul.Ops[4].Op)
   661  	}
   662  	if consul.Ops[5].Op != "remove" {
   663  		t.Errorf("expected sixth op to be remove but found: %q", consul.Ops[5].Op)
   664  	}
   665  }
   666  
   667  func TestTaskRunner_Validate_UserEnforcement(t *testing.T) {
   668  	t.Parallel()
   669  	ctx := testTaskRunner(t, false)
   670  	defer ctx.Cleanup()
   671  
   672  	// Try to run as root with exec.
   673  	ctx.tr.task.Driver = "exec"
   674  	ctx.tr.task.User = "root"
   675  	if err := ctx.tr.validateTask(); err == nil {
   676  		t.Fatalf("expected error running as root with exec")
   677  	}
   678  
   679  	// Try to run a non-blacklisted user with exec.
   680  	ctx.tr.task.Driver = "exec"
   681  	ctx.tr.task.User = "foobar"
   682  	if err := ctx.tr.validateTask(); err != nil {
   683  		t.Fatalf("unexpected error: %v", err)
   684  	}
   685  
   686  	// Try to run as root with docker.
   687  	ctx.tr.task.Driver = "docker"
   688  	ctx.tr.task.User = "root"
   689  	if err := ctx.tr.validateTask(); err != nil {
   690  		t.Fatalf("unexpected error: %v", err)
   691  	}
   692  }
   693  
   694  func TestTaskRunner_RestartTask(t *testing.T) {
   695  	t.Parallel()
   696  	alloc := mock.Alloc()
   697  	task := alloc.Job.TaskGroups[0].Tasks[0]
   698  	task.Driver = "mock_driver"
   699  	task.Config = map[string]interface{}{
   700  		"exit_code": "0",
   701  		"run_for":   "100s",
   702  	}
   703  
   704  	ctx := testTaskRunnerFromAlloc(t, true, alloc)
   705  	ctx.tr.MarkReceived()
   706  	go ctx.tr.Run()
   707  	defer ctx.Cleanup()
   708  
   709  	// Wait for it to start
   710  	go func() {
   711  		testWaitForTaskToStart(t, ctx)
   712  		ctx.tr.Restart("test", "restart", false)
   713  
   714  		// Wait for it to restart then kill
   715  		go func() {
   716  			// Wait for the task to start again
   717  			testutil.WaitForResult(func() (bool, error) {
   718  				if len(ctx.upd.events) != 8 {
   719  					return false, fmt.Errorf("task %q in alloc %q should have 8 ctx.updates: %#v", task.Name, alloc.ID, ctx.upd.events)
   720  				}
   721  
   722  				return true, nil
   723  			}, func(err error) {
   724  				t.Fatalf("err: %v", err)
   725  			})
   726  			ctx.tr.Kill("test", "restart", false)
   727  		}()
   728  	}()
   729  
   730  	select {
   731  	case <-ctx.tr.WaitCh():
   732  	case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second):
   733  		t.Fatalf("timeout")
   734  	}
   735  
   736  	if len(ctx.upd.events) != 10 {
   737  		t.Fatalf("should have 10 ctx.updates: %#v", ctx.upd.events)
   738  	}
   739  
   740  	if ctx.upd.state != structs.TaskStateDead {
   741  		t.Fatalf("TaskState %v; want %v", ctx.upd.state, structs.TaskStateDead)
   742  	}
   743  
   744  	if ctx.upd.events[0].Type != structs.TaskReceived {
   745  		t.Fatalf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
   746  	}
   747  
   748  	if ctx.upd.events[1].Type != structs.TaskSetup {
   749  		t.Fatalf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskSetup)
   750  	}
   751  
   752  	if ctx.upd.events[2].Type != structs.TaskStarted {
   753  		t.Fatalf("Third Event was %v; want %v", ctx.upd.events[2].Type, structs.TaskStarted)
   754  	}
   755  
   756  	if ctx.upd.events[3].Type != structs.TaskRestartSignal {
   757  		t.Fatalf("Fourth Event was %v; want %v", ctx.upd.events[3].Type, structs.TaskRestartSignal)
   758  	}
   759  
   760  	if ctx.upd.events[4].Type != structs.TaskKilling {
   761  		t.Fatalf("Fifth Event was %v; want %v", ctx.upd.events[4].Type, structs.TaskKilling)
   762  	}
   763  
   764  	if ctx.upd.events[5].Type != structs.TaskKilled {
   765  		t.Fatalf("Sixth Event was %v; want %v", ctx.upd.events[5].Type, structs.TaskKilled)
   766  	}
   767  
   768  	if ctx.upd.events[6].Type != structs.TaskRestarting {
   769  		t.Fatalf("Seventh Event was %v; want %v", ctx.upd.events[6].Type, structs.TaskRestarting)
   770  	}
   771  
   772  	if ctx.upd.events[7].Type != structs.TaskStarted {
   773  		t.Fatalf("Eighth Event was %v; want %v", ctx.upd.events[8].Type, structs.TaskStarted)
   774  	}
   775  	if ctx.upd.events[8].Type != structs.TaskKilling {
   776  		t.Fatalf("Ninth  Event was %v; want %v", ctx.upd.events[8].Type, structs.TaskKilling)
   777  	}
   778  
   779  	if ctx.upd.events[9].Type != structs.TaskKilled {
   780  		t.Fatalf("Tenth Event was %v; want %v", ctx.upd.events[9].Type, structs.TaskKilled)
   781  	}
   782  }
   783  
   784  func TestTaskRunner_KillTask(t *testing.T) {
   785  	t.Parallel()
   786  	alloc := mock.Alloc()
   787  	task := alloc.Job.TaskGroups[0].Tasks[0]
   788  	task.Driver = "mock_driver"
   789  	task.Config = map[string]interface{}{
   790  		"exit_code": "0",
   791  		"run_for":   "10s",
   792  	}
   793  
   794  	ctx := testTaskRunnerFromAlloc(t, false, alloc)
   795  	ctx.tr.MarkReceived()
   796  	go ctx.tr.Run()
   797  	defer ctx.Cleanup()
   798  
   799  	go func() {
   800  		testWaitForTaskToStart(t, ctx)
   801  		ctx.tr.Kill("test", "kill", true)
   802  	}()
   803  
   804  	select {
   805  	case <-ctx.tr.WaitCh():
   806  	case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second):
   807  		t.Fatalf("timeout")
   808  	}
   809  
   810  	if len(ctx.upd.events) != 5 {
   811  		t.Fatalf("should have 4 ctx.updates: %#v", ctx.upd.events)
   812  	}
   813  
   814  	if ctx.upd.state != structs.TaskStateDead {
   815  		t.Fatalf("TaskState %v; want %v", ctx.upd.state, structs.TaskStateDead)
   816  	}
   817  
   818  	if !ctx.upd.failed {
   819  		t.Fatalf("TaskState should be failed: %+v", ctx.upd)
   820  	}
   821  
   822  	if ctx.upd.events[0].Type != structs.TaskReceived {
   823  		t.Fatalf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
   824  	}
   825  
   826  	if ctx.upd.events[1].Type != structs.TaskSetup {
   827  		t.Fatalf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskSetup)
   828  	}
   829  
   830  	if ctx.upd.events[2].Type != structs.TaskStarted {
   831  		t.Fatalf("Third Event was %v; want %v", ctx.upd.events[2].Type, structs.TaskStarted)
   832  	}
   833  
   834  	if ctx.upd.events[3].Type != structs.TaskKilling {
   835  		t.Fatalf("Fourth Event was %v; want %v", ctx.upd.events[3].Type, structs.TaskKilling)
   836  	}
   837  
   838  	if ctx.upd.events[4].Type != structs.TaskKilled {
   839  		t.Fatalf("Fifth Event was %v; want %v", ctx.upd.events[4].Type, structs.TaskKilled)
   840  	}
   841  }
   842  
   843  func TestTaskRunner_SignalFailure(t *testing.T) {
   844  	t.Parallel()
   845  	alloc := mock.Alloc()
   846  	task := alloc.Job.TaskGroups[0].Tasks[0]
   847  	task.Driver = "mock_driver"
   848  	task.Config = map[string]interface{}{
   849  		"exit_code":    "0",
   850  		"run_for":      "10s",
   851  		"signal_error": "test forcing failure",
   852  	}
   853  
   854  	ctx := testTaskRunnerFromAlloc(t, false, alloc)
   855  	ctx.tr.MarkReceived()
   856  	go ctx.tr.Run()
   857  	defer ctx.Cleanup()
   858  
   859  	// Wait for the task to start
   860  	testWaitForTaskToStart(t, ctx)
   861  
   862  	if err := ctx.tr.Signal("test", "test", syscall.SIGINT); err == nil {
   863  		t.Fatalf("Didn't receive error")
   864  	}
   865  }
   866  
   867  func TestTaskRunner_BlockForVault(t *testing.T) {
   868  	t.Parallel()
   869  	alloc := mock.Alloc()
   870  	task := alloc.Job.TaskGroups[0].Tasks[0]
   871  	task.Driver = "mock_driver"
   872  	task.Config = map[string]interface{}{
   873  		"exit_code": "0",
   874  		"run_for":   "1s",
   875  	}
   876  	task.Vault = &structs.Vault{Policies: []string{"default"}}
   877  
   878  	ctx := testTaskRunnerFromAlloc(t, false, alloc)
   879  	ctx.tr.MarkReceived()
   880  	defer ctx.Cleanup()
   881  
   882  	// Control when we get a Vault token
   883  	token := "1234"
   884  	waitCh := make(chan struct{})
   885  	handler := func(*structs.Allocation, []string) (map[string]string, error) {
   886  		<-waitCh
   887  		return map[string]string{task.Name: token}, nil
   888  	}
   889  	ctx.tr.vaultClient.(*vaultclient.MockVaultClient).DeriveTokenFn = handler
   890  
   891  	go ctx.tr.Run()
   892  
   893  	select {
   894  	case <-ctx.tr.WaitCh():
   895  		t.Fatalf("premature exit")
   896  	case <-time.After(1 * time.Second):
   897  	}
   898  
   899  	if len(ctx.upd.events) != 2 {
   900  		t.Fatalf("should have 2 ctx.updates: %#v", ctx.upd.events)
   901  	}
   902  
   903  	if ctx.upd.state != structs.TaskStatePending {
   904  		t.Fatalf("TaskState %v; want %v", ctx.upd.state, structs.TaskStatePending)
   905  	}
   906  
   907  	if ctx.upd.events[0].Type != structs.TaskReceived {
   908  		t.Fatalf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
   909  	}
   910  
   911  	if ctx.upd.events[1].Type != structs.TaskSetup {
   912  		t.Fatalf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskSetup)
   913  	}
   914  
   915  	// Unblock
   916  	close(waitCh)
   917  
   918  	select {
   919  	case <-ctx.tr.WaitCh():
   920  	case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second):
   921  		t.Fatalf("timeout")
   922  	}
   923  
   924  	if len(ctx.upd.events) != 4 {
   925  		t.Fatalf("should have 4 ctx.updates: %#v", ctx.upd.events)
   926  	}
   927  
   928  	if ctx.upd.state != structs.TaskStateDead {
   929  		t.Fatalf("TaskState %v; want %v", ctx.upd.state, structs.TaskStateDead)
   930  	}
   931  
   932  	if ctx.upd.events[0].Type != structs.TaskReceived {
   933  		t.Fatalf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
   934  	}
   935  
   936  	if ctx.upd.events[1].Type != structs.TaskSetup {
   937  		t.Fatalf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskSetup)
   938  	}
   939  
   940  	if ctx.upd.events[2].Type != structs.TaskStarted {
   941  		t.Fatalf("Third Event was %v; want %v", ctx.upd.events[2].Type, structs.TaskStarted)
   942  	}
   943  
   944  	if ctx.upd.events[3].Type != structs.TaskTerminated {
   945  		t.Fatalf("Fourth Event was %v; want %v", ctx.upd.events[3].Type, structs.TaskTerminated)
   946  	}
   947  
   948  	// Check that the token is on disk
   949  	tokenPath := filepath.Join(ctx.tr.taskDir.SecretsDir, vaultTokenFile)
   950  	data, err := ioutil.ReadFile(tokenPath)
   951  	if err != nil {
   952  		t.Fatalf("Failed to read file: %v", err)
   953  	}
   954  
   955  	if act := string(data); act != token {
   956  		t.Fatalf("Token didn't get written to disk properly, got %q; want %q", act, token)
   957  	}
   958  
   959  	// Check the token was revoked
   960  	m := ctx.tr.vaultClient.(*vaultclient.MockVaultClient)
   961  	testutil.WaitForResult(func() (bool, error) {
   962  		if len(m.StoppedTokens) != 1 {
   963  			return false, fmt.Errorf("Expected a stopped token: %v", m.StoppedTokens)
   964  		}
   965  
   966  		if a := m.StoppedTokens[0]; a != token {
   967  			return false, fmt.Errorf("got stopped token %q; want %q", a, token)
   968  		}
   969  		return true, nil
   970  	}, func(err error) {
   971  		t.Fatalf("err: %v", err)
   972  	})
   973  }
   974  
   975  func TestTaskRunner_DeriveToken_Retry(t *testing.T) {
   976  	t.Parallel()
   977  	alloc := mock.Alloc()
   978  	task := alloc.Job.TaskGroups[0].Tasks[0]
   979  	task.Driver = "mock_driver"
   980  	task.Config = map[string]interface{}{
   981  		"exit_code": "0",
   982  		"run_for":   "1s",
   983  	}
   984  	task.Vault = &structs.Vault{Policies: []string{"default"}}
   985  
   986  	ctx := testTaskRunnerFromAlloc(t, false, alloc)
   987  	ctx.tr.MarkReceived()
   988  	defer ctx.Cleanup()
   989  
   990  	// Control when we get a Vault token
   991  	token := "1234"
   992  	count := 0
   993  	handler := func(*structs.Allocation, []string) (map[string]string, error) {
   994  		if count > 0 {
   995  			return map[string]string{task.Name: token}, nil
   996  		}
   997  
   998  		count++
   999  		return nil, structs.NewRecoverableError(fmt.Errorf("Want a retry"), true)
  1000  	}
  1001  	ctx.tr.vaultClient.(*vaultclient.MockVaultClient).DeriveTokenFn = handler
  1002  	go ctx.tr.Run()
  1003  
  1004  	select {
  1005  	case <-ctx.tr.WaitCh():
  1006  	case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second):
  1007  		t.Fatalf("timeout")
  1008  	}
  1009  
  1010  	if len(ctx.upd.events) != 4 {
  1011  		t.Fatalf("should have 4 ctx.updates: %#v", ctx.upd.events)
  1012  	}
  1013  
  1014  	if ctx.upd.state != structs.TaskStateDead {
  1015  		t.Fatalf("TaskState %v; want %v", ctx.upd.state, structs.TaskStateDead)
  1016  	}
  1017  
  1018  	if ctx.upd.events[0].Type != structs.TaskReceived {
  1019  		t.Fatalf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
  1020  	}
  1021  
  1022  	if ctx.upd.events[1].Type != structs.TaskSetup {
  1023  		t.Fatalf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskSetup)
  1024  	}
  1025  
  1026  	if ctx.upd.events[2].Type != structs.TaskStarted {
  1027  		t.Fatalf("Third Event was %v; want %v", ctx.upd.events[2].Type, structs.TaskStarted)
  1028  	}
  1029  
  1030  	if ctx.upd.events[3].Type != structs.TaskTerminated {
  1031  		t.Fatalf("Fourth Event was %v; want %v", ctx.upd.events[3].Type, structs.TaskTerminated)
  1032  	}
  1033  
  1034  	// Check that the token is on disk
  1035  	tokenPath := filepath.Join(ctx.tr.taskDir.SecretsDir, vaultTokenFile)
  1036  	data, err := ioutil.ReadFile(tokenPath)
  1037  	if err != nil {
  1038  		t.Fatalf("Failed to read file: %v", err)
  1039  	}
  1040  
  1041  	if act := string(data); act != token {
  1042  		t.Fatalf("Token didn't get written to disk properly, got %q; want %q", act, token)
  1043  	}
  1044  
  1045  	// Check the token was revoked
  1046  	m := ctx.tr.vaultClient.(*vaultclient.MockVaultClient)
  1047  	testutil.WaitForResult(func() (bool, error) {
  1048  		if len(m.StoppedTokens) != 1 {
  1049  			return false, fmt.Errorf("Expected a stopped token: %v", m.StoppedTokens)
  1050  		}
  1051  
  1052  		if a := m.StoppedTokens[0]; a != token {
  1053  			return false, fmt.Errorf("got stopped token %q; want %q", a, token)
  1054  		}
  1055  		return true, nil
  1056  	}, func(err error) {
  1057  		t.Fatalf("err: %v", err)
  1058  	})
  1059  }
  1060  
  1061  func TestTaskRunner_DeriveToken_Unrecoverable(t *testing.T) {
  1062  	t.Parallel()
  1063  	alloc := mock.Alloc()
  1064  	task := alloc.Job.TaskGroups[0].Tasks[0]
  1065  	task.Driver = "mock_driver"
  1066  	task.Config = map[string]interface{}{
  1067  		"exit_code": "0",
  1068  		"run_for":   "10s",
  1069  	}
  1070  	task.Vault = &structs.Vault{
  1071  		Policies:   []string{"default"},
  1072  		ChangeMode: structs.VaultChangeModeRestart,
  1073  	}
  1074  
  1075  	ctx := testTaskRunnerFromAlloc(t, false, alloc)
  1076  	ctx.tr.MarkReceived()
  1077  	defer ctx.Cleanup()
  1078  
  1079  	// Error the token derivation
  1080  	vc := ctx.tr.vaultClient.(*vaultclient.MockVaultClient)
  1081  	vc.SetDeriveTokenError(alloc.ID, []string{task.Name}, fmt.Errorf("Non recoverable"))
  1082  	go ctx.tr.Run()
  1083  
  1084  	// Wait for the task to start
  1085  	testutil.WaitForResult(func() (bool, error) {
  1086  		if l := len(ctx.upd.events); l != 3 {
  1087  			return false, fmt.Errorf("Expect 3 events; got %v", l)
  1088  		}
  1089  
  1090  		if ctx.upd.events[0].Type != structs.TaskReceived {
  1091  			return false, fmt.Errorf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
  1092  		}
  1093  
  1094  		if ctx.upd.events[1].Type != structs.TaskSetup {
  1095  			return false, fmt.Errorf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskSetup)
  1096  		}
  1097  
  1098  		if ctx.upd.events[2].Type != structs.TaskKilling {
  1099  			return false, fmt.Errorf("Third Event was %v; want %v", ctx.upd.events[2].Type, structs.TaskKilling)
  1100  		}
  1101  
  1102  		return true, nil
  1103  	}, func(err error) {
  1104  		t.Fatalf("err: %v", err)
  1105  	})
  1106  }
  1107  
  1108  func TestTaskRunner_Template_Block(t *testing.T) {
  1109  	t.Parallel()
  1110  	alloc := mock.Alloc()
  1111  	task := alloc.Job.TaskGroups[0].Tasks[0]
  1112  	task.Driver = "mock_driver"
  1113  	task.Config = map[string]interface{}{
  1114  		"exit_code": "0",
  1115  		"run_for":   "1s",
  1116  	}
  1117  	task.Templates = []*structs.Template{
  1118  		{
  1119  			EmbeddedTmpl: "{{key \"foo\"}}",
  1120  			DestPath:     "local/test",
  1121  			ChangeMode:   structs.TemplateChangeModeNoop,
  1122  		},
  1123  	}
  1124  
  1125  	ctx := testTaskRunnerFromAlloc(t, false, alloc)
  1126  	ctx.tr.MarkReceived()
  1127  	go ctx.tr.Run()
  1128  	defer ctx.Cleanup()
  1129  
  1130  	select {
  1131  	case <-ctx.tr.WaitCh():
  1132  		t.Fatalf("premature exit")
  1133  	case <-time.After(1 * time.Second):
  1134  	}
  1135  
  1136  	if len(ctx.upd.events) != 2 {
  1137  		t.Fatalf("should have 2 ctx.updates: %#v", ctx.upd.events)
  1138  	}
  1139  
  1140  	if ctx.upd.state != structs.TaskStatePending {
  1141  		t.Fatalf("TaskState %v; want %v", ctx.upd.state, structs.TaskStatePending)
  1142  	}
  1143  
  1144  	if ctx.upd.events[0].Type != structs.TaskReceived {
  1145  		t.Fatalf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
  1146  	}
  1147  
  1148  	if ctx.upd.events[1].Type != structs.TaskSetup {
  1149  		t.Fatalf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskSetup)
  1150  	}
  1151  
  1152  	// Unblock
  1153  	ctx.tr.UnblockStart("test")
  1154  
  1155  	select {
  1156  	case <-ctx.tr.WaitCh():
  1157  	case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second):
  1158  		t.Fatalf("timeout")
  1159  	}
  1160  
  1161  	if len(ctx.upd.events) != 4 {
  1162  		t.Fatalf("should have 4 ctx.updates: %#v", ctx.upd.events)
  1163  	}
  1164  
  1165  	if ctx.upd.state != structs.TaskStateDead {
  1166  		t.Fatalf("TaskState %v; want %v", ctx.upd.state, structs.TaskStateDead)
  1167  	}
  1168  
  1169  	if ctx.upd.events[0].Type != structs.TaskReceived {
  1170  		t.Fatalf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
  1171  	}
  1172  
  1173  	if ctx.upd.events[1].Type != structs.TaskSetup {
  1174  		t.Fatalf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskSetup)
  1175  	}
  1176  
  1177  	if ctx.upd.events[2].Type != structs.TaskStarted {
  1178  		t.Fatalf("Third Event was %v; want %v", ctx.upd.events[2].Type, structs.TaskStarted)
  1179  	}
  1180  
  1181  	if ctx.upd.events[3].Type != structs.TaskTerminated {
  1182  		t.Fatalf("Fourth Event was %v; want %v", ctx.upd.events[3].Type, structs.TaskTerminated)
  1183  	}
  1184  }
  1185  
  1186  func TestTaskRunner_Template_Artifact(t *testing.T) {
  1187  	t.Parallel()
  1188  	dir, err := os.Getwd()
  1189  	if err != nil {
  1190  		t.Fatalf("bad: %v", err)
  1191  	}
  1192  
  1193  	ts := httptest.NewServer(http.FileServer(http.Dir(filepath.Join(dir, "../../.."))))
  1194  	defer ts.Close()
  1195  
  1196  	alloc := mock.Alloc()
  1197  	task := alloc.Job.TaskGroups[0].Tasks[0]
  1198  	task.Driver = "mock_driver"
  1199  	task.Config = map[string]interface{}{
  1200  		"exit_code": "0",
  1201  		"run_for":   "1s",
  1202  	}
  1203  	// Create an allocation that has a task that renders a template from an
  1204  	// artifact
  1205  	f1 := "CHANGELOG.md"
  1206  	artifact := structs.TaskArtifact{
  1207  		GetterSource: fmt.Sprintf("%s/%s", ts.URL, f1),
  1208  	}
  1209  	task.Artifacts = []*structs.TaskArtifact{&artifact}
  1210  	task.Templates = []*structs.Template{
  1211  		{
  1212  			SourcePath: "CHANGELOG.md",
  1213  			DestPath:   "local/test",
  1214  			ChangeMode: structs.TemplateChangeModeNoop,
  1215  		},
  1216  	}
  1217  
  1218  	ctx := testTaskRunnerFromAlloc(t, false, alloc)
  1219  	ctx.tr.MarkReceived()
  1220  	defer ctx.Cleanup()
  1221  	go ctx.tr.Run()
  1222  
  1223  	select {
  1224  	case <-ctx.tr.WaitCh():
  1225  	case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second):
  1226  		t.Fatalf("timeout")
  1227  	}
  1228  
  1229  	if len(ctx.upd.events) != 5 {
  1230  		t.Fatalf("should have 5 ctx.updates: %#v", ctx.upd.events)
  1231  	}
  1232  
  1233  	if ctx.upd.state != structs.TaskStateDead {
  1234  		t.Fatalf("TaskState %v; want %v", ctx.upd.state, structs.TaskStateDead)
  1235  	}
  1236  
  1237  	if ctx.upd.events[0].Type != structs.TaskReceived {
  1238  		t.Fatalf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
  1239  	}
  1240  
  1241  	if ctx.upd.events[1].Type != structs.TaskSetup {
  1242  		t.Fatalf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskSetup)
  1243  	}
  1244  
  1245  	if ctx.upd.events[2].Type != structs.TaskDownloadingArtifacts {
  1246  		t.Fatalf("Third Event was %v; want %v", ctx.upd.events[2].Type, structs.TaskDownloadingArtifacts)
  1247  	}
  1248  
  1249  	if ctx.upd.events[3].Type != structs.TaskStarted {
  1250  		t.Fatalf("Fourth Event was %v; want %v", ctx.upd.events[3].Type, structs.TaskStarted)
  1251  	}
  1252  
  1253  	if ctx.upd.events[4].Type != structs.TaskTerminated {
  1254  		t.Fatalf("Fifth Event was %v; want %v", ctx.upd.events[4].Type, structs.TaskTerminated)
  1255  	}
  1256  
  1257  	// Check that both files exist.
  1258  	if _, err := os.Stat(filepath.Join(ctx.tr.taskDir.Dir, f1)); err != nil {
  1259  		t.Fatalf("%v not downloaded", f1)
  1260  	}
  1261  	if _, err := os.Stat(filepath.Join(ctx.tr.taskDir.LocalDir, "test")); err != nil {
  1262  		t.Fatalf("template not rendered")
  1263  	}
  1264  }
  1265  
  1266  func TestTaskRunner_Template_NewVaultToken(t *testing.T) {
  1267  	t.Parallel()
  1268  	alloc := mock.Alloc()
  1269  	task := alloc.Job.TaskGroups[0].Tasks[0]
  1270  	task.Driver = "mock_driver"
  1271  	task.Config = map[string]interface{}{
  1272  		"exit_code": "0",
  1273  		"run_for":   "1s",
  1274  	}
  1275  	task.Templates = []*structs.Template{
  1276  		{
  1277  			EmbeddedTmpl: "{{key \"foo\"}}",
  1278  			DestPath:     "local/test",
  1279  			ChangeMode:   structs.TemplateChangeModeNoop,
  1280  		},
  1281  	}
  1282  	task.Vault = &structs.Vault{Policies: []string{"default"}}
  1283  
  1284  	ctx := testTaskRunnerFromAlloc(t, false, alloc)
  1285  	ctx.tr.MarkReceived()
  1286  	defer ctx.Cleanup()
  1287  	go ctx.tr.Run()
  1288  
  1289  	// Wait for a Vault token
  1290  	var token string
  1291  	testutil.WaitForResult(func() (bool, error) {
  1292  		if token = ctx.tr.vaultFuture.Get(); token == "" {
  1293  			return false, fmt.Errorf("No Vault token")
  1294  		}
  1295  
  1296  		return true, nil
  1297  	}, func(err error) {
  1298  		t.Fatalf("err: %v", err)
  1299  	})
  1300  
  1301  	// Error the token renewal
  1302  	renewalCh, ok := ctx.vault.RenewTokens[token]
  1303  	if !ok {
  1304  		t.Fatalf("no renewal channel")
  1305  	}
  1306  
  1307  	originalManager := ctx.tr.templateManager
  1308  
  1309  	renewalCh <- fmt.Errorf("Test killing")
  1310  	close(renewalCh)
  1311  
  1312  	// Wait for a new Vault token
  1313  	var token2 string
  1314  	testutil.WaitForResult(func() (bool, error) {
  1315  		if token2 = ctx.tr.vaultFuture.Get(); token2 == "" || token2 == token {
  1316  			return false, fmt.Errorf("No new Vault token")
  1317  		}
  1318  
  1319  		if originalManager == ctx.tr.templateManager {
  1320  			return false, fmt.Errorf("Template manager not ctx.updated")
  1321  		}
  1322  
  1323  		return true, nil
  1324  	}, func(err error) {
  1325  		t.Fatalf("err: %v", err)
  1326  	})
  1327  
  1328  	// Check the token was revoked
  1329  	testutil.WaitForResult(func() (bool, error) {
  1330  		if len(ctx.vault.StoppedTokens) != 1 {
  1331  			return false, fmt.Errorf("Expected a stopped token: %v", ctx.vault.StoppedTokens)
  1332  		}
  1333  
  1334  		if a := ctx.vault.StoppedTokens[0]; a != token {
  1335  			return false, fmt.Errorf("got stopped token %q; want %q", a, token)
  1336  		}
  1337  		return true, nil
  1338  	}, func(err error) {
  1339  		t.Fatalf("err: %v", err)
  1340  	})
  1341  }
  1342  
  1343  func TestTaskRunner_VaultManager_Restart(t *testing.T) {
  1344  	t.Parallel()
  1345  	alloc := mock.Alloc()
  1346  	task := alloc.Job.TaskGroups[0].Tasks[0]
  1347  	task.Driver = "mock_driver"
  1348  	task.Config = map[string]interface{}{
  1349  		"exit_code": "0",
  1350  		"run_for":   "10s",
  1351  	}
  1352  	task.Vault = &structs.Vault{
  1353  		Policies:   []string{"default"},
  1354  		ChangeMode: structs.VaultChangeModeRestart,
  1355  	}
  1356  
  1357  	ctx := testTaskRunnerFromAlloc(t, false, alloc)
  1358  	ctx.tr.MarkReceived()
  1359  	defer ctx.Cleanup()
  1360  	go ctx.tr.Run()
  1361  
  1362  	// Wait for the task to start
  1363  	testWaitForTaskToStart(t, ctx)
  1364  
  1365  	// Error the token renewal
  1366  	renewalCh, ok := ctx.vault.RenewTokens[ctx.tr.vaultFuture.Get()]
  1367  	if !ok {
  1368  		t.Fatalf("no renewal channel")
  1369  	}
  1370  
  1371  	renewalCh <- fmt.Errorf("Test killing")
  1372  	close(renewalCh)
  1373  
  1374  	// Ensure a restart
  1375  	testutil.WaitForResult(func() (bool, error) {
  1376  		if l := len(ctx.upd.events); l != 8 {
  1377  			return false, fmt.Errorf("Expect eight events; got %#v", ctx.upd.events)
  1378  		}
  1379  
  1380  		if ctx.upd.events[0].Type != structs.TaskReceived {
  1381  			return false, fmt.Errorf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
  1382  		}
  1383  
  1384  		if ctx.upd.events[1].Type != structs.TaskSetup {
  1385  			return false, fmt.Errorf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskStarted)
  1386  		}
  1387  
  1388  		if ctx.upd.events[2].Type != structs.TaskStarted {
  1389  			return false, fmt.Errorf("Third Event was %v; want %v", ctx.upd.events[2].Type, structs.TaskStarted)
  1390  		}
  1391  
  1392  		if ctx.upd.events[3].Type != structs.TaskRestartSignal {
  1393  			return false, fmt.Errorf("Fourth Event was %v; want %v", ctx.upd.events[3].Type, structs.TaskRestartSignal)
  1394  		}
  1395  
  1396  		if ctx.upd.events[4].Type != structs.TaskKilling {
  1397  			return false, fmt.Errorf("Fifth Event was %v; want %v", ctx.upd.events[4].Type, structs.TaskKilling)
  1398  		}
  1399  
  1400  		if ctx.upd.events[5].Type != structs.TaskKilled {
  1401  			return false, fmt.Errorf("Sixth Event was %v; want %v", ctx.upd.events[5].Type, structs.TaskKilled)
  1402  		}
  1403  
  1404  		if ctx.upd.events[6].Type != structs.TaskRestarting {
  1405  			return false, fmt.Errorf("Seventh Event was %v; want %v", ctx.upd.events[6].Type, structs.TaskRestarting)
  1406  		}
  1407  
  1408  		if ctx.upd.events[7].Type != structs.TaskStarted {
  1409  			return false, fmt.Errorf("Eight Event was %v; want %v", ctx.upd.events[7].Type, structs.TaskStarted)
  1410  		}
  1411  
  1412  		return true, nil
  1413  	}, func(err error) {
  1414  		t.Fatalf("err: %v", err)
  1415  	})
  1416  }
  1417  
  1418  func TestTaskRunner_VaultManager_Signal(t *testing.T) {
  1419  	t.Parallel()
  1420  	alloc := mock.Alloc()
  1421  	task := alloc.Job.TaskGroups[0].Tasks[0]
  1422  	task.Driver = "mock_driver"
  1423  	task.Config = map[string]interface{}{
  1424  		"exit_code": "0",
  1425  		"run_for":   "10s",
  1426  	}
  1427  	task.Vault = &structs.Vault{
  1428  		Policies:     []string{"default"},
  1429  		ChangeMode:   structs.VaultChangeModeSignal,
  1430  		ChangeSignal: "SIGUSR1",
  1431  	}
  1432  
  1433  	ctx := testTaskRunnerFromAlloc(t, false, alloc)
  1434  	ctx.tr.MarkReceived()
  1435  	go ctx.tr.Run()
  1436  	defer ctx.Cleanup()
  1437  
  1438  	// Wait for the task to start
  1439  	testWaitForTaskToStart(t, ctx)
  1440  
  1441  	// Error the token renewal
  1442  	renewalCh, ok := ctx.vault.RenewTokens[ctx.tr.vaultFuture.Get()]
  1443  	if !ok {
  1444  		t.Fatalf("no renewal channel")
  1445  	}
  1446  
  1447  	renewalCh <- fmt.Errorf("Test killing")
  1448  	close(renewalCh)
  1449  
  1450  	// Ensure a restart
  1451  	testutil.WaitForResult(func() (bool, error) {
  1452  		if l := len(ctx.upd.events); l != 4 {
  1453  			return false, fmt.Errorf("Expect four events; got %#v", ctx.upd.events)
  1454  		}
  1455  
  1456  		if ctx.upd.events[0].Type != structs.TaskReceived {
  1457  			return false, fmt.Errorf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
  1458  		}
  1459  
  1460  		if ctx.upd.events[1].Type != structs.TaskSetup {
  1461  			return false, fmt.Errorf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskSetup)
  1462  		}
  1463  
  1464  		if ctx.upd.events[2].Type != structs.TaskStarted {
  1465  			return false, fmt.Errorf("Third Event was %v; want %v", ctx.upd.events[2].Type, structs.TaskStarted)
  1466  		}
  1467  
  1468  		if ctx.upd.events[3].Type != structs.TaskSignaling {
  1469  			return false, fmt.Errorf("Fourth Event was %v; want %v", ctx.upd.events[3].Type, structs.TaskSignaling)
  1470  		}
  1471  
  1472  		return true, nil
  1473  	}, func(err error) {
  1474  		t.Fatalf("err: %v", err)
  1475  	})
  1476  }
  1477  
  1478  // Test that the payload is written to disk
  1479  func TestTaskRunner_SimpleRun_Dispatch(t *testing.T) {
  1480  	t.Parallel()
  1481  	alloc := mock.Alloc()
  1482  	task := alloc.Job.TaskGroups[0].Tasks[0]
  1483  	task.Driver = "mock_driver"
  1484  	task.Config = map[string]interface{}{
  1485  		"exit_code": "0",
  1486  		"run_for":   "1s",
  1487  	}
  1488  	fileName := "test"
  1489  	task.DispatchPayload = &structs.DispatchPayloadConfig{
  1490  		File: fileName,
  1491  	}
  1492  	alloc.Job.ParameterizedJob = &structs.ParameterizedJobConfig{}
  1493  
  1494  	// Add an encrypted payload
  1495  	expected := []byte("hello world")
  1496  	compressed := snappy.Encode(nil, expected)
  1497  	alloc.Job.Payload = compressed
  1498  
  1499  	ctx := testTaskRunnerFromAlloc(t, false, alloc)
  1500  	ctx.tr.MarkReceived()
  1501  	defer ctx.tr.Destroy(structs.NewTaskEvent(structs.TaskKilled))
  1502  	defer ctx.allocDir.Destroy()
  1503  	go ctx.tr.Run()
  1504  
  1505  	select {
  1506  	case <-ctx.tr.WaitCh():
  1507  	case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second):
  1508  		t.Fatalf("timeout")
  1509  	}
  1510  
  1511  	if len(ctx.upd.events) != 4 {
  1512  		t.Fatalf("should have 4 updates: %#v", ctx.upd.events)
  1513  	}
  1514  
  1515  	if ctx.upd.state != structs.TaskStateDead {
  1516  		t.Fatalf("TaskState %v; want %v", ctx.upd.state, structs.TaskStateDead)
  1517  	}
  1518  
  1519  	if ctx.upd.events[0].Type != structs.TaskReceived {
  1520  		t.Fatalf("First Event was %v; want %v", ctx.upd.events[0].Type, structs.TaskReceived)
  1521  	}
  1522  
  1523  	if ctx.upd.events[1].Type != structs.TaskSetup {
  1524  		t.Fatalf("Second Event was %v; want %v", ctx.upd.events[1].Type, structs.TaskSetup)
  1525  	}
  1526  
  1527  	if ctx.upd.events[2].Type != structs.TaskStarted {
  1528  		t.Fatalf("Third Event was %v; want %v", ctx.upd.events[2].Type, structs.TaskStarted)
  1529  	}
  1530  
  1531  	if ctx.upd.events[3].Type != structs.TaskTerminated {
  1532  		t.Fatalf("Fourth Event was %v; want %v", ctx.upd.events[3].Type, structs.TaskTerminated)
  1533  	}
  1534  
  1535  	// Check that the file was written to disk properly
  1536  	payloadPath := filepath.Join(ctx.tr.taskDir.LocalDir, fileName)
  1537  	data, err := ioutil.ReadFile(payloadPath)
  1538  	if err != nil {
  1539  		t.Fatalf("Failed to read file: %v", err)
  1540  	}
  1541  	if !reflect.DeepEqual(data, expected) {
  1542  		t.Fatalf("Bad; got %v; want %v", string(data), string(expected))
  1543  	}
  1544  }
  1545  
  1546  // TestTaskRunner_CleanupEmpty ensures TaskRunner works when createdResources
  1547  // is empty.
  1548  func TestTaskRunner_CleanupEmpty(t *testing.T) {
  1549  	t.Parallel()
  1550  	alloc := mock.Alloc()
  1551  	task := alloc.Job.TaskGroups[0].Tasks[0]
  1552  	task.Driver = "mock_driver"
  1553  
  1554  	ctx := testTaskRunnerFromAlloc(t, false, alloc)
  1555  	ctx.tr.MarkReceived()
  1556  
  1557  	defer ctx.Cleanup()
  1558  	ctx.tr.Run()
  1559  
  1560  	// Since we only failed once, createdResources should be empty
  1561  	if len(ctx.tr.createdResources.Resources) != 0 {
  1562  		t.Fatalf("createdResources should still be empty: %v", ctx.tr.createdResources)
  1563  	}
  1564  }
  1565  
  1566  func TestTaskRunner_CleanupOK(t *testing.T) {
  1567  	t.Parallel()
  1568  	alloc := mock.Alloc()
  1569  	task := alloc.Job.TaskGroups[0].Tasks[0]
  1570  	task.Driver = "mock_driver"
  1571  	key := "ERR"
  1572  
  1573  	ctx := testTaskRunnerFromAlloc(t, false, alloc)
  1574  	ctx.tr.config.Options = map[string]string{
  1575  		"cleanup_fail_on":  key,
  1576  		"cleanup_fail_num": "1",
  1577  	}
  1578  	ctx.tr.MarkReceived()
  1579  
  1580  	ctx.tr.createdResources.Resources[key] = []string{"x", "y"}
  1581  	ctx.tr.createdResources.Resources["foo"] = []string{"z"}
  1582  
  1583  	defer ctx.Cleanup()
  1584  	ctx.tr.Run()
  1585  
  1586  	// Since we only failed once, createdResources should be empty
  1587  	if len(ctx.tr.createdResources.Resources) > 0 {
  1588  		t.Fatalf("expected all created resources to be removed: %#v", ctx.tr.createdResources.Resources)
  1589  	}
  1590  }
  1591  
  1592  func TestTaskRunner_CleanupFail(t *testing.T) {
  1593  	t.Parallel()
  1594  	alloc := mock.Alloc()
  1595  	task := alloc.Job.TaskGroups[0].Tasks[0]
  1596  	task.Driver = "mock_driver"
  1597  	key := "ERR"
  1598  	ctx := testTaskRunnerFromAlloc(t, false, alloc)
  1599  	ctx.tr.config.Options = map[string]string{
  1600  		"cleanup_fail_on":  key,
  1601  		"cleanup_fail_num": "5",
  1602  	}
  1603  	ctx.tr.MarkReceived()
  1604  
  1605  	ctx.tr.createdResources.Resources[key] = []string{"x"}
  1606  	ctx.tr.createdResources.Resources["foo"] = []string{"y", "z"}
  1607  
  1608  	defer ctx.Cleanup()
  1609  	ctx.tr.Run()
  1610  
  1611  	// Since we failed > 3 times, the failed key should remain
  1612  	expected := map[string][]string{key: {"x"}}
  1613  	if !reflect.DeepEqual(expected, ctx.tr.createdResources.Resources) {
  1614  		t.Fatalf("expected %#v but found: %#v", expected, ctx.tr.createdResources.Resources)
  1615  	}
  1616  }
  1617  
  1618  func TestTaskRunner_Pre06ScriptCheck(t *testing.T) {
  1619  	t.Parallel()
  1620  	run := func(ver, driver, checkType string, exp bool) (string, func(t *testing.T)) {
  1621  		name := fmt.Sprintf("%s %s %s returns %t", ver, driver, checkType, exp)
  1622  		return name, func(t *testing.T) {
  1623  			services := []*structs.Service{
  1624  				{
  1625  					Checks: []*structs.ServiceCheck{
  1626  						{
  1627  							Type: checkType,
  1628  						},
  1629  					},
  1630  				},
  1631  			}
  1632  			if act := pre06ScriptCheck(ver, driver, services); act != exp {
  1633  				t.Errorf("expected %t received %t", exp, act)
  1634  			}
  1635  		}
  1636  	}
  1637  	t.Run(run("0.5.6", "exec", "script", true))
  1638  	t.Run(run("0.5.6", "java", "script", true))
  1639  	t.Run(run("0.5.6", "mock_driver", "script", true))
  1640  	t.Run(run("0.5.9", "exec", "script", true))
  1641  	t.Run(run("0.5.9", "java", "script", true))
  1642  	t.Run(run("0.5.9", "mock_driver", "script", true))
  1643  
  1644  	t.Run(run("0.6.0dev", "exec", "script", false))
  1645  	t.Run(run("0.6.0dev", "java", "script", false))
  1646  	t.Run(run("0.6.0dev", "mock_driver", "script", false))
  1647  	t.Run(run("0.6.0", "exec", "script", false))
  1648  	t.Run(run("0.6.0", "java", "script", false))
  1649  	t.Run(run("0.6.0", "mock_driver", "script", false))
  1650  	t.Run(run("1.0.0", "exec", "script", false))
  1651  	t.Run(run("1.0.0", "java", "script", false))
  1652  	t.Run(run("1.0.0", "mock_driver", "script", false))
  1653  
  1654  	t.Run(run("0.5.6", "rkt", "script", false))
  1655  	t.Run(run("0.5.6", "docker", "script", false))
  1656  	t.Run(run("0.5.6", "qemu", "script", false))
  1657  	t.Run(run("0.5.6", "raw_exec", "script", false))
  1658  	t.Run(run("0.5.6", "invalid", "script", false))
  1659  
  1660  	t.Run(run("0.5.6", "exec", "tcp", false))
  1661  	t.Run(run("0.5.6", "java", "tcp", false))
  1662  	t.Run(run("0.5.6", "mock_driver", "tcp", false))
  1663  }
  1664  
  1665  func TestTaskRunner_interpolateServices(t *testing.T) {
  1666  	t.Parallel()
  1667  	task := &structs.Task{
  1668  		Services: []*structs.Service{
  1669  			{
  1670  				Name:      "${name}",
  1671  				PortLabel: "${portlabel}",
  1672  				Tags:      []string{"${tags}"},
  1673  				Checks: []*structs.ServiceCheck{
  1674  					{
  1675  						Name:          "${checkname}",
  1676  						Type:          "${checktype}",
  1677  						Command:       "${checkcmd}",
  1678  						Args:          []string{"${checkarg}"},
  1679  						Path:          "${checkstr}",
  1680  						Protocol:      "${checkproto}",
  1681  						PortLabel:     "${checklabel}",
  1682  						InitialStatus: "${checkstatus}",
  1683  						Method:        "${checkmethod}",
  1684  						Header: map[string][]string{
  1685  							"${checkheaderk}": {"${checkheaderv}"},
  1686  						},
  1687  					},
  1688  				},
  1689  			},
  1690  		},
  1691  	}
  1692  
  1693  	env := &env.TaskEnv{
  1694  		EnvMap: map[string]string{
  1695  			"name":         "name",
  1696  			"portlabel":    "portlabel",
  1697  			"tags":         "tags",
  1698  			"checkname":    "checkname",
  1699  			"checktype":    "checktype",
  1700  			"checkcmd":     "checkcmd",
  1701  			"checkarg":     "checkarg",
  1702  			"checkstr":     "checkstr",
  1703  			"checkpath":    "checkpath",
  1704  			"checkproto":   "checkproto",
  1705  			"checklabel":   "checklabel",
  1706  			"checkstatus":  "checkstatus",
  1707  			"checkmethod":  "checkmethod",
  1708  			"checkheaderk": "checkheaderk",
  1709  			"checkheaderv": "checkheaderv",
  1710  		},
  1711  	}
  1712  
  1713  	interpTask := interpolateServices(env, task)
  1714  
  1715  	exp := &structs.Task{
  1716  		Services: []*structs.Service{
  1717  			{
  1718  				Name:      "name",
  1719  				PortLabel: "portlabel",
  1720  				Tags:      []string{"tags"},
  1721  				Checks: []*structs.ServiceCheck{
  1722  					{
  1723  						Name:          "checkname",
  1724  						Type:          "checktype",
  1725  						Command:       "checkcmd",
  1726  						Args:          []string{"checkarg"},
  1727  						Path:          "checkstr",
  1728  						Protocol:      "checkproto",
  1729  						PortLabel:     "checklabel",
  1730  						InitialStatus: "checkstatus",
  1731  						Method:        "checkmethod",
  1732  						Header: map[string][]string{
  1733  							"checkheaderk": {"checkheaderv"},
  1734  						},
  1735  					},
  1736  				},
  1737  			},
  1738  		},
  1739  	}
  1740  
  1741  	if diff := pretty.Diff(interpTask, exp); len(diff) > 0 {
  1742  		t.Fatalf("diff:\n%s\n", strings.Join(diff, "\n"))
  1743  	}
  1744  }
  1745  
  1746  func TestTaskRunner_ShutdownDelay(t *testing.T) {
  1747  	t.Parallel()
  1748  
  1749  	alloc := mock.Alloc()
  1750  	task := alloc.Job.TaskGroups[0].Tasks[0]
  1751  	task.Services[0].Tags = []string{"tag1"}
  1752  	task.Services = task.Services[:1] // only need 1 for this test
  1753  	task.Driver = "mock_driver"
  1754  	task.Config = map[string]interface{}{
  1755  		"run_for": "1000s",
  1756  	}
  1757  
  1758  	// No shutdown escape hatch for this delay, so don't set it too high
  1759  	task.ShutdownDelay = 500 * time.Duration(testutil.TestMultiplier()) * time.Millisecond
  1760  
  1761  	ctx := testTaskRunnerFromAlloc(t, true, alloc)
  1762  	ctx.tr.MarkReceived()
  1763  	go ctx.tr.Run()
  1764  	defer ctx.Cleanup()
  1765  
  1766  	// Wait for the task to start
  1767  	testWaitForTaskToStart(t, ctx)
  1768  
  1769  	testutil.WaitForResult(func() (bool, error) {
  1770  		services, _ := ctx.consul.Services()
  1771  		if n := len(services); n != 1 {
  1772  			return false, fmt.Errorf("expected 1 service found %d", n)
  1773  		}
  1774  		for _, s := range services {
  1775  			if !reflect.DeepEqual(s.Tags, task.Services[0].Tags) {
  1776  				return false, fmt.Errorf("expected tags=%q but found %q",
  1777  					strings.Join(task.Services[0].Tags, ","), strings.Join(s.Tags, ","))
  1778  			}
  1779  		}
  1780  		return true, nil
  1781  	}, func(err error) {
  1782  		services, _ := ctx.consul.Services()
  1783  		for _, s := range services {
  1784  			t.Logf("Service: %#v", s)
  1785  		}
  1786  		t.Fatalf("err: %v", err)
  1787  	})
  1788  
  1789  	// Begin the tear down
  1790  	ctx.tr.Destroy(structs.NewTaskEvent(structs.TaskKilled))
  1791  	destroyed := time.Now()
  1792  
  1793  	testutil.WaitForResult(func() (bool, error) {
  1794  		services, _ := ctx.consul.Services()
  1795  		if n := len(services); n == 1 {
  1796  			return false, fmt.Errorf("expected 0 services found %d", n)
  1797  		}
  1798  		return true, nil
  1799  	}, func(err error) {
  1800  		t.Fatalf("err: %v", err)
  1801  	})
  1802  
  1803  	// Wait for actual exit
  1804  	select {
  1805  	case <-ctx.tr.WaitCh():
  1806  	case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second):
  1807  		t.Fatalf("timeout")
  1808  	}
  1809  
  1810  	// It should be impossible to reach here in less time than the shutdown delay
  1811  	if time.Now().Before(destroyed.Add(task.ShutdownDelay)) {
  1812  		t.Fatalf("task exited before shutdown delay")
  1813  	}
  1814  }
  1815  
  1816  // TestTaskRunner_CheckWatcher_Restart asserts that when enabled an unhealthy
  1817  // Consul check will cause a task to restart following restart policy rules.
  1818  func TestTaskRunner_CheckWatcher_Restart(t *testing.T) {
  1819  	t.Parallel()
  1820  
  1821  	alloc := mock.Alloc()
  1822  
  1823  	// Make the restart policy fail within this test
  1824  	tg := alloc.Job.TaskGroups[0]
  1825  	tg.RestartPolicy.Attempts = 2
  1826  	tg.RestartPolicy.Interval = 1 * time.Minute
  1827  	tg.RestartPolicy.Delay = 10 * time.Millisecond
  1828  	tg.RestartPolicy.Mode = structs.RestartPolicyModeFail
  1829  
  1830  	task := tg.Tasks[0]
  1831  	task.Driver = "mock_driver"
  1832  	task.Config = map[string]interface{}{
  1833  		"exit_code": "0",
  1834  		"run_for":   "100s",
  1835  	}
  1836  
  1837  	// Make the task register a check that fails
  1838  	task.Services[0].Checks[0] = &structs.ServiceCheck{
  1839  		Name:     "test-restarts",
  1840  		Type:     structs.ServiceCheckTCP,
  1841  		Interval: 50 * time.Millisecond,
  1842  		CheckRestart: &structs.CheckRestart{
  1843  			Limit: 2,
  1844  			Grace: 100 * time.Millisecond,
  1845  		},
  1846  	}
  1847  
  1848  	ctx := testTaskRunnerFromAlloc(t, true, alloc)
  1849  
  1850  	// Replace mock Consul ServiceClient, with the real ServiceClient
  1851  	// backed by a mock consul whose checks are always unhealthy.
  1852  	consulAgent := consul.NewMockAgent()
  1853  	consulAgent.SetStatus("critical")
  1854  	consulClient := consul.NewServiceClient(consulAgent, ctx.tr.logger, true)
  1855  	go consulClient.Run()
  1856  	defer consulClient.Shutdown()
  1857  
  1858  	ctx.tr.consul = consulClient
  1859  	ctx.consul = nil // prevent accidental use of old mock
  1860  
  1861  	ctx.tr.MarkReceived()
  1862  	go ctx.tr.Run()
  1863  	defer ctx.Cleanup()
  1864  
  1865  	select {
  1866  	case <-ctx.tr.WaitCh():
  1867  	case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second):
  1868  		t.Fatalf("timeout")
  1869  	}
  1870  
  1871  	expected := []string{
  1872  		"Received",
  1873  		"Task Setup",
  1874  		"Started",
  1875  		"Restart Signaled",
  1876  		"Killing",
  1877  		"Killed",
  1878  		"Restarting",
  1879  		"Started",
  1880  		"Restart Signaled",
  1881  		"Killing",
  1882  		"Killed",
  1883  		"Restarting",
  1884  		"Started",
  1885  		"Restart Signaled",
  1886  		"Killing",
  1887  		"Killed",
  1888  		"Not Restarting",
  1889  	}
  1890  
  1891  	if n := len(ctx.upd.events); n != len(expected) {
  1892  		t.Fatalf("should have %d ctx.updates found %d: %s", len(expected), n, ctx.upd)
  1893  	}
  1894  
  1895  	if ctx.upd.state != structs.TaskStateDead {
  1896  		t.Fatalf("TaskState %v; want %v", ctx.upd.state, structs.TaskStateDead)
  1897  	}
  1898  
  1899  	if !ctx.upd.failed {
  1900  		t.Fatalf("expected failed")
  1901  	}
  1902  
  1903  	for i, actual := range ctx.upd.events {
  1904  		if actual.Type != expected[i] {
  1905  			t.Errorf("%.2d - Expected %q but found %q", i, expected[i], actual.Type)
  1906  		}
  1907  	}
  1908  }
  1909  
  1910  // TestTaskRunner_DriverNetwork asserts that a driver's network is properly
  1911  // used in services and checks.
  1912  func TestTaskRunner_DriverNetwork(t *testing.T) {
  1913  	t.Parallel()
  1914  
  1915  	alloc := mock.Alloc()
  1916  	task := alloc.Job.TaskGroups[0].Tasks[0]
  1917  	task.Driver = "mock_driver"
  1918  	task.Config = map[string]interface{}{
  1919  		"exit_code":       0,
  1920  		"run_for":         "100s",
  1921  		"driver_ip":       "10.1.2.3",
  1922  		"driver_port_map": "http:80",
  1923  	}
  1924  
  1925  	// Create services and checks with custom address modes to exercise
  1926  	// address detection logic
  1927  	task.Services = []*structs.Service{
  1928  		{
  1929  			Name:        "host-service",
  1930  			PortLabel:   "http",
  1931  			AddressMode: "host",
  1932  			Checks: []*structs.ServiceCheck{
  1933  				{
  1934  					Name:        "driver-check",
  1935  					Type:        "tcp",
  1936  					PortLabel:   "1234",
  1937  					AddressMode: "driver",
  1938  				},
  1939  			},
  1940  		},
  1941  		{
  1942  			Name:        "driver-service",
  1943  			PortLabel:   "5678",
  1944  			AddressMode: "driver",
  1945  			Checks: []*structs.ServiceCheck{
  1946  				{
  1947  					Name:      "host-check",
  1948  					Type:      "tcp",
  1949  					PortLabel: "http",
  1950  				},
  1951  				{
  1952  					Name:        "driver-label-check",
  1953  					Type:        "tcp",
  1954  					PortLabel:   "http",
  1955  					AddressMode: "driver",
  1956  				},
  1957  			},
  1958  		},
  1959  	}
  1960  
  1961  	ctx := testTaskRunnerFromAlloc(t, false, alloc)
  1962  	ctx.tr.MarkReceived()
  1963  	go ctx.tr.Run()
  1964  	defer ctx.Cleanup()
  1965  
  1966  	// Wait for the task to start
  1967  	testWaitForTaskToStart(t, ctx)
  1968  
  1969  	testutil.WaitForResult(func() (bool, error) {
  1970  		services, _ := ctx.consul.Services()
  1971  		if n := len(services); n != 2 {
  1972  			return false, fmt.Errorf("expected 2 services, but found %d", n)
  1973  		}
  1974  		for _, s := range services {
  1975  			switch s.Service {
  1976  			case "host-service":
  1977  				if expected := "192.168.0.100"; s.Address != expected {
  1978  					return false, fmt.Errorf("expected host-service to have IP=%s but found %s",
  1979  						expected, s.Address)
  1980  				}
  1981  			case "driver-service":
  1982  				if expected := "10.1.2.3"; s.Address != expected {
  1983  					return false, fmt.Errorf("expected driver-service to have IP=%s but found %s",
  1984  						expected, s.Address)
  1985  				}
  1986  				if expected := 5678; s.Port != expected {
  1987  					return false, fmt.Errorf("expected driver-service to have port=%d but found %d",
  1988  						expected, s.Port)
  1989  				}
  1990  			default:
  1991  				return false, fmt.Errorf("unexpected service: %q", s.Service)
  1992  			}
  1993  
  1994  		}
  1995  
  1996  		checks := ctx.consul.CheckRegs()
  1997  		if n := len(checks); n != 3 {
  1998  			return false, fmt.Errorf("expected 3 checks, but found %d", n)
  1999  		}
  2000  		for _, check := range checks {
  2001  			switch check.Name {
  2002  			case "driver-check":
  2003  				if expected := "10.1.2.3:1234"; check.TCP != expected {
  2004  					return false, fmt.Errorf("expected driver-check to have address %q but found %q", expected, check.TCP)
  2005  				}
  2006  			case "driver-label-check":
  2007  				if expected := "10.1.2.3:80"; check.TCP != expected {
  2008  					return false, fmt.Errorf("expected driver-label-check to have address %q but found %q", expected, check.TCP)
  2009  				}
  2010  			case "host-check":
  2011  				if expected := "192.168.0.100:"; !strings.HasPrefix(check.TCP, expected) {
  2012  					return false, fmt.Errorf("expected host-check to have address start with %q but found %q", expected, check.TCP)
  2013  				}
  2014  			default:
  2015  				return false, fmt.Errorf("unexpected check: %q", check.Name)
  2016  			}
  2017  		}
  2018  
  2019  		return true, nil
  2020  	}, func(err error) {
  2021  		services, _ := ctx.consul.Services()
  2022  		for _, s := range services {
  2023  			t.Logf(pretty.Sprint("Service: ", s))
  2024  		}
  2025  		for _, c := range ctx.consul.CheckRegs() {
  2026  			t.Logf(pretty.Sprint("Check:   ", c))
  2027  		}
  2028  		t.Fatalf("error: %v", err)
  2029  	})
  2030  }