github.com/emate/nomad@v0.8.2-wo-binpacking/client/task_runner_test.go (about)

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