github.com/iqoqo/nomad@v0.11.3-0.20200911112621-d7021c74d101/client/allocrunner/task_hook_coordinator_test.go (about)

     1  package allocrunner
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/stretchr/testify/require"
     8  
     9  	"github.com/hashicorp/nomad/nomad/structs"
    10  
    11  	"github.com/hashicorp/nomad/helper/testlog"
    12  	"github.com/hashicorp/nomad/nomad/mock"
    13  )
    14  
    15  func TestTaskHookCoordinator_OnlyMainApp(t *testing.T) {
    16  	alloc := mock.Alloc()
    17  	tasks := alloc.Job.TaskGroups[0].Tasks
    18  	task := tasks[0]
    19  	logger := testlog.HCLogger(t)
    20  
    21  	coord := newTaskHookCoordinator(logger, tasks)
    22  
    23  	ch := coord.startConditionForTask(task)
    24  
    25  	require.Truef(t, isChannelClosed(ch), "%s channel was open, should be closed", task.Name)
    26  }
    27  
    28  func TestTaskHookCoordinator_PrestartRunsBeforeMain(t *testing.T) {
    29  	logger := testlog.HCLogger(t)
    30  
    31  	alloc := mock.LifecycleAlloc()
    32  	tasks := alloc.Job.TaskGroups[0].Tasks
    33  
    34  	mainTask := tasks[0]
    35  	sideTask := tasks[1]
    36  	initTask := tasks[2]
    37  
    38  	coord := newTaskHookCoordinator(logger, tasks)
    39  	initCh := coord.startConditionForTask(initTask)
    40  	sideCh := coord.startConditionForTask(sideTask)
    41  	mainCh := coord.startConditionForTask(mainTask)
    42  
    43  	require.Truef(t, isChannelClosed(initCh), "%s channel was open, should be closed", initTask.Name)
    44  	require.Truef(t, isChannelClosed(sideCh), "%s channel was open, should be closed", sideTask.Name)
    45  	require.Falsef(t, isChannelClosed(mainCh), "%s channel was closed, should be open", mainTask.Name)
    46  }
    47  
    48  func TestTaskHookCoordinator_MainRunsAfterPrestart(t *testing.T) {
    49  	logger := testlog.HCLogger(t)
    50  
    51  	alloc := mock.LifecycleAlloc()
    52  	tasks := alloc.Job.TaskGroups[0].Tasks
    53  
    54  	mainTask := tasks[0]
    55  	sideTask := tasks[1]
    56  	initTask := tasks[2]
    57  
    58  	coord := newTaskHookCoordinator(logger, tasks)
    59  	initCh := coord.startConditionForTask(initTask)
    60  	sideCh := coord.startConditionForTask(sideTask)
    61  	mainCh := coord.startConditionForTask(mainTask)
    62  
    63  	require.Truef(t, isChannelClosed(initCh), "%s channel was open, should be closed", initTask.Name)
    64  	require.Truef(t, isChannelClosed(sideCh), "%s channel was open, should be closed", sideTask.Name)
    65  	require.Falsef(t, isChannelClosed(mainCh), "%s channel was closed, should be open", mainTask.Name)
    66  
    67  	states := map[string]*structs.TaskState{
    68  		mainTask.Name: {
    69  			State:  structs.TaskStatePending,
    70  			Failed: false,
    71  		},
    72  		initTask.Name: {
    73  			State:      structs.TaskStateDead,
    74  			Failed:     false,
    75  			StartedAt:  time.Now(),
    76  			FinishedAt: time.Now(),
    77  		},
    78  		sideTask.Name: {
    79  			State:     structs.TaskStateRunning,
    80  			Failed:    false,
    81  			StartedAt: time.Now(),
    82  		},
    83  	}
    84  
    85  	coord.taskStateUpdated(states)
    86  
    87  	require.Truef(t, isChannelClosed(initCh), "%s channel was open, should be closed", initTask.Name)
    88  	require.Truef(t, isChannelClosed(sideCh), "%s channel was open, should be closed", sideTask.Name)
    89  	require.Truef(t, isChannelClosed(mainCh), "%s channel was open, should be closed", mainTask.Name)
    90  }
    91  
    92  func TestTaskHookCoordinator_MainRunsAfterManyInitTasks(t *testing.T) {
    93  	logger := testlog.HCLogger(t)
    94  
    95  	alloc := mock.LifecycleAlloc()
    96  	alloc.Job = mock.VariableLifecycleJob(structs.Resources{CPU: 100, MemoryMB: 256}, 1, 2, 0)
    97  	tasks := alloc.Job.TaskGroups[0].Tasks
    98  
    99  	mainTask := tasks[0]
   100  	init1Task := tasks[1]
   101  	init2Task := tasks[2]
   102  
   103  	coord := newTaskHookCoordinator(logger, tasks)
   104  	mainCh := coord.startConditionForTask(mainTask)
   105  	init1Ch := coord.startConditionForTask(init1Task)
   106  	init2Ch := coord.startConditionForTask(init2Task)
   107  
   108  	require.Truef(t, isChannelClosed(init1Ch), "%s channel was open, should be closed", init1Task.Name)
   109  	require.Truef(t, isChannelClosed(init2Ch), "%s channel was open, should be closed", init2Task.Name)
   110  	require.Falsef(t, isChannelClosed(mainCh), "%s channel was closed, should be open", mainTask.Name)
   111  
   112  	states := map[string]*structs.TaskState{
   113  		mainTask.Name: {
   114  			State:  structs.TaskStatePending,
   115  			Failed: false,
   116  		},
   117  		init1Task.Name: {
   118  			State:      structs.TaskStateDead,
   119  			Failed:     false,
   120  			StartedAt:  time.Now(),
   121  			FinishedAt: time.Now(),
   122  		},
   123  		init2Task.Name: {
   124  			State:     structs.TaskStateDead,
   125  			Failed:    false,
   126  			StartedAt: time.Now(),
   127  		},
   128  	}
   129  
   130  	coord.taskStateUpdated(states)
   131  
   132  	require.Truef(t, isChannelClosed(init1Ch), "%s channel was open, should be closed", init1Task.Name)
   133  	require.Truef(t, isChannelClosed(init2Ch), "%s channel was open, should be closed", init2Task.Name)
   134  	require.Truef(t, isChannelClosed(mainCh), "%s channel was open, should be closed", mainTask.Name)
   135  }
   136  
   137  func TestTaskHookCoordinator_FailedInitTask(t *testing.T) {
   138  	logger := testlog.HCLogger(t)
   139  
   140  	alloc := mock.LifecycleAlloc()
   141  	alloc.Job = mock.VariableLifecycleJob(structs.Resources{CPU: 100, MemoryMB: 256}, 1, 2, 0)
   142  	tasks := alloc.Job.TaskGroups[0].Tasks
   143  
   144  	mainTask := tasks[0]
   145  	init1Task := tasks[1]
   146  	init2Task := tasks[2]
   147  
   148  	coord := newTaskHookCoordinator(logger, tasks)
   149  	mainCh := coord.startConditionForTask(mainTask)
   150  	init1Ch := coord.startConditionForTask(init1Task)
   151  	init2Ch := coord.startConditionForTask(init2Task)
   152  
   153  	require.Truef(t, isChannelClosed(init1Ch), "%s channel was open, should be closed", init1Task.Name)
   154  	require.Truef(t, isChannelClosed(init2Ch), "%s channel was open, should be closed", init2Task.Name)
   155  	require.Falsef(t, isChannelClosed(mainCh), "%s channel was closed, should be open", mainTask.Name)
   156  
   157  	states := map[string]*structs.TaskState{
   158  		mainTask.Name: {
   159  			State:  structs.TaskStatePending,
   160  			Failed: false,
   161  		},
   162  		init1Task.Name: {
   163  			State:      structs.TaskStateDead,
   164  			Failed:     false,
   165  			StartedAt:  time.Now(),
   166  			FinishedAt: time.Now(),
   167  		},
   168  		init2Task.Name: {
   169  			State:     structs.TaskStateDead,
   170  			Failed:    true,
   171  			StartedAt: time.Now(),
   172  		},
   173  	}
   174  
   175  	coord.taskStateUpdated(states)
   176  
   177  	require.Truef(t, isChannelClosed(init1Ch), "%s channel was open, should be closed", init1Task.Name)
   178  	require.Truef(t, isChannelClosed(init2Ch), "%s channel was open, should be closed", init2Task.Name)
   179  	require.Falsef(t, isChannelClosed(mainCh), "%s channel was closed, should be open", mainTask.Name)
   180  }
   181  
   182  func TestTaskHookCoordinator_SidecarNeverStarts(t *testing.T) {
   183  	logger := testlog.HCLogger(t)
   184  
   185  	alloc := mock.LifecycleAlloc()
   186  	tasks := alloc.Job.TaskGroups[0].Tasks
   187  
   188  	mainTask := tasks[0]
   189  	sideTask := tasks[1]
   190  	initTask := tasks[2]
   191  
   192  	coord := newTaskHookCoordinator(logger, tasks)
   193  	initCh := coord.startConditionForTask(initTask)
   194  	sideCh := coord.startConditionForTask(sideTask)
   195  	mainCh := coord.startConditionForTask(mainTask)
   196  
   197  	require.Truef(t, isChannelClosed(initCh), "%s channel was open, should be closed", initTask.Name)
   198  	require.Truef(t, isChannelClosed(sideCh), "%s channel was open, should be closed", sideTask.Name)
   199  	require.Falsef(t, isChannelClosed(mainCh), "%s channel was closed, should be open", mainTask.Name)
   200  
   201  	states := map[string]*structs.TaskState{
   202  		mainTask.Name: {
   203  			State:  structs.TaskStatePending,
   204  			Failed: false,
   205  		},
   206  		initTask.Name: {
   207  			State:      structs.TaskStateDead,
   208  			Failed:     false,
   209  			StartedAt:  time.Now(),
   210  			FinishedAt: time.Now(),
   211  		},
   212  		sideTask.Name: {
   213  			State:  structs.TaskStatePending,
   214  			Failed: false,
   215  		},
   216  	}
   217  
   218  	coord.taskStateUpdated(states)
   219  
   220  	require.Truef(t, isChannelClosed(initCh), "%s channel was open, should be closed", initTask.Name)
   221  	require.Truef(t, isChannelClosed(sideCh), "%s channel was open, should be closed", sideTask.Name)
   222  	require.Falsef(t, isChannelClosed(mainCh), "%s channel was closed, should be open", mainTask.Name)
   223  }
   224  
   225  func isChannelClosed(ch <-chan struct{}) bool {
   226  	select {
   227  	case <-ch:
   228  		return true
   229  	default:
   230  		return false
   231  	}
   232  }