github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/e2e/lifecycle/lifecycle.go (about)

     1  package lifecycle
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/hashicorp/nomad/api"
     7  	"github.com/hashicorp/nomad/e2e/e2eutil"
     8  	"github.com/hashicorp/nomad/e2e/framework"
     9  	"github.com/hashicorp/nomad/helper/uuid"
    10  	"github.com/hashicorp/nomad/nomad/structs"
    11  	"github.com/hashicorp/nomad/testutil"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  type LifecycleE2ETest struct {
    16  	framework.TC
    17  	jobIDs []string
    18  }
    19  
    20  func init() {
    21  	framework.AddSuites(&framework.TestSuite{
    22  		Component:   "Lifecycle",
    23  		CanRunLocal: true,
    24  		Cases:       []framework.TestCase{new(LifecycleE2ETest)},
    25  	})
    26  }
    27  
    28  // Ensure cluster has leader and at least 1 client node
    29  // in a ready state before running tests
    30  func (tc *LifecycleE2ETest) BeforeAll(f *framework.F) {
    31  	e2eutil.WaitForLeader(f.T(), tc.Nomad())
    32  	e2eutil.WaitForNodesReady(f.T(), tc.Nomad(), 1)
    33  }
    34  
    35  // TestBatchJob runs a batch job with prestart and poststop hooks
    36  func (tc *LifecycleE2ETest) TestBatchJob(f *framework.F) {
    37  	t := f.T()
    38  	require := require.New(t)
    39  	nomadClient := tc.Nomad()
    40  	uuid := uuid.Generate()
    41  	jobID := "lifecycle-" + uuid[0:8]
    42  	tc.jobIDs = append(tc.jobIDs, jobID)
    43  
    44  	allocs := e2eutil.RegisterAndWaitForAllocs(f.T(), nomadClient, "lifecycle/inputs/batch.nomad", jobID, "")
    45  	require.Equal(1, len(allocs))
    46  	allocID := allocs[0].ID
    47  
    48  	// wait for the job to stop and assert we stopped successfully, not failed
    49  	e2eutil.WaitForAllocStopped(t, nomadClient, allocID)
    50  	alloc, _, err := nomadClient.Allocations().Info(allocID, nil)
    51  	require.NoError(err)
    52  	require.Equal(structs.AllocClientStatusComplete, alloc.ClientStatus)
    53  
    54  	// assert the files were written as expected
    55  	afi, _, err := nomadClient.AllocFS().List(alloc, "alloc", nil)
    56  	require.NoError(err)
    57  	expected := map[string]bool{
    58  		"init-ran": true, "main-ran": true, "poststart-ran": true, "poststop-ran": true,
    59  		"init-running": false, "main-running": false, "poststart-running": false}
    60  	got := checkFiles(expected, afi)
    61  	require.Equal(expected, got)
    62  }
    63  
    64  // TestServiceJob runs a service job with prestart and poststop hooks
    65  func (tc *LifecycleE2ETest) TestServiceJob(f *framework.F) {
    66  	t := f.T()
    67  	require := require.New(t)
    68  	nomadClient := tc.Nomad()
    69  	uuid := uuid.Generate()
    70  	jobID := "lifecycle-" + uuid[0:8]
    71  	tc.jobIDs = append(tc.jobIDs, jobID)
    72  
    73  	allocs := e2eutil.RegisterAndWaitForAllocs(f.T(), nomadClient, "lifecycle/inputs/service.nomad", jobID, "")
    74  	require.Equal(1, len(allocs))
    75  	allocID := allocs[0].ID
    76  
    77  	//e2eutil.WaitForAllocRunning(t, nomadClient, allocID)
    78  	testutil.WaitForResult(func() (bool, error) {
    79  		alloc, _, err := nomadClient.Allocations().Info(allocID, nil)
    80  		if err != nil {
    81  			return false, err
    82  		}
    83  
    84  		if alloc.ClientStatus != structs.AllocClientStatusRunning {
    85  			return false, fmt.Errorf("expected status running, but was: %s", alloc.ClientStatus)
    86  		}
    87  
    88  		if alloc.TaskStates["poststart"].FinishedAt.IsZero() {
    89  			return false, fmt.Errorf("poststart task hasn't started")
    90  		}
    91  
    92  		afi, _, err := nomadClient.AllocFS().List(alloc, "alloc", nil)
    93  		if err != nil {
    94  			return false, err
    95  		}
    96  		expected := map[string]bool{
    97  			"main-checked": true}
    98  		got := checkFiles(expected, afi)
    99  		if !got["main-checked"] {
   100  			return false, fmt.Errorf("main-checked file has not been written")
   101  		}
   102  
   103  		return true, nil
   104  	}, func(err error) {
   105  		require.NoError(err, "failed to wait on alloc")
   106  	})
   107  
   108  	alloc, _, err := nomadClient.Allocations().Info(allocID, nil)
   109  	require.NoError(err)
   110  
   111  	require.False(alloc.TaskStates["poststart"].Failed)
   112  
   113  	// stop the job
   114  	_, _, err = nomadClient.Jobs().Deregister(jobID, false, nil)
   115  	require.NoError(err)
   116  	e2eutil.WaitForAllocStopped(t, nomadClient, allocID)
   117  
   118  	require.False(alloc.TaskStates["poststop"].Failed)
   119  
   120  	// assert the files were written as expected
   121  	afi, _, err := nomadClient.AllocFS().List(alloc, "alloc", nil)
   122  	require.NoError(err)
   123  	expected := map[string]bool{
   124  		"init-ran": true, "sidecar-ran": true, "main-ran": true, "poststart-ran": true, "poststop-ran": true,
   125  		"poststart-started": true, "main-started": true, "poststop-started": true,
   126  		"init-running": false, "poststart-running": false, "poststop-running": false,
   127  		"main-checked": true}
   128  	got := checkFiles(expected, afi)
   129  	require.Equal(expected, got)
   130  }
   131  
   132  // checkFiles returns a map of whether the expected files were found
   133  // in the file info response
   134  func checkFiles(expected map[string]bool, got []*api.AllocFileInfo) map[string]bool {
   135  	results := map[string]bool{}
   136  	for expect := range expected {
   137  		results[expect] = false
   138  	}
   139  	for _, file := range got {
   140  		// there will be files unrelated to the test, so ignore those
   141  		if _, ok := results[file.Name]; ok {
   142  			results[file.Name] = true
   143  		}
   144  	}
   145  	return results
   146  }