github.com/hernad/nomad@v1.6.112/e2e/servicediscovery/nomad_checks_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package servicediscovery
     5  
     6  import (
     7  	"context"
     8  	"regexp"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/hernad/nomad/e2e/e2eutil"
    14  	"github.com/hernad/nomad/helper/uuid"
    15  	"github.com/hernad/nomad/nomad/structs"
    16  	"github.com/shoenig/test"
    17  	"github.com/shoenig/test/must"
    18  	"github.com/shoenig/test/wait"
    19  	"github.com/stretchr/testify/require"
    20  )
    21  
    22  func testChecksHappy(t *testing.T) {
    23  	nomadClient := e2eutil.NomadClient(t)
    24  
    25  	// Generate our unique job ID which will be used for this test.
    26  	jobID := "nsd-check-happy-" + uuid.Short()
    27  	jobIDs := []string{jobID}
    28  
    29  	// Defer a cleanup function to remove the job. This will trigger if the
    30  	// test fails, unless the cancel function is called.
    31  	ctx, cancel := context.WithCancel(context.Background())
    32  	defer cancel()
    33  	defer e2eutil.CleanupJobsAndGCWithContext(t, ctx, &jobIDs)
    34  
    35  	// Register the happy checks job.
    36  	allocStubs := e2eutil.RegisterAndWaitForAllocs(t, nomadClient, jobChecksHappy, jobID, "")
    37  	must.Len(t, 1, allocStubs)
    38  
    39  	// wait for the alloc to be running
    40  	e2eutil.WaitForAllocRunning(t, nomadClient, allocStubs[0].ID)
    41  
    42  	// Get and test the output of 'nomad alloc checks'.
    43  	require.Eventually(t, func() bool {
    44  		output, err := e2eutil.AllocChecks(allocStubs[0].ID)
    45  		if err != nil {
    46  			return false
    47  		}
    48  
    49  		// assert the output contains success
    50  		statusRe := regexp.MustCompile(`Status\s+=\s+success`)
    51  		if !statusRe.MatchString(output) {
    52  			return false
    53  		}
    54  
    55  		// assert the output contains 200 status code
    56  		statusCodeRe := regexp.MustCompile(`StatusCode\s+=\s+200`)
    57  		if !statusCodeRe.MatchString(output) {
    58  			return false
    59  		}
    60  
    61  		// assert output contains nomad's success string
    62  		return strings.Contains(output, `nomad: http ok`)
    63  	}, 5*time.Second, 200*time.Millisecond)
    64  }
    65  
    66  func testChecksSad(t *testing.T) {
    67  	nomadClient := e2eutil.NomadClient(t)
    68  
    69  	// Generate our unique job ID which will be used for this test.
    70  	jobID := "nsd-check-sad-" + uuid.Short()
    71  	jobIDs := []string{jobID}
    72  
    73  	// Defer a cleanup function to remove the job. This will trigger if the
    74  	// test fails, unless the cancel function is called.
    75  	ctx, cancel := context.WithCancel(context.Background())
    76  	defer cancel()
    77  	defer e2eutil.CleanupJobsAndGCWithContext(t, ctx, &jobIDs)
    78  
    79  	// Register the sad checks job.
    80  	allocStubs := e2eutil.RegisterAndWaitForAllocs(t, nomadClient, jobChecksSad, jobID, "")
    81  	must.Len(t, 1, allocStubs)
    82  
    83  	// wait for the alloc to be running
    84  	e2eutil.WaitForAllocRunning(t, nomadClient, allocStubs[0].ID)
    85  
    86  	// Get and test the output of 'nomad alloc checks'.
    87  	require.Eventually(t, func() bool {
    88  		output, err := e2eutil.AllocChecks(allocStubs[0].ID)
    89  		if err != nil {
    90  			return false
    91  		}
    92  
    93  		// assert the output contains failure
    94  		statusRe := regexp.MustCompile(`Status\s+=\s+failure`)
    95  		if !statusRe.MatchString(output) {
    96  			return false
    97  		}
    98  
    99  		// assert the output contains 501 status code
   100  		statusCodeRe := regexp.MustCompile(`StatusCode\s+=\s+501`)
   101  		if !statusCodeRe.MatchString(output) {
   102  			return false
   103  		}
   104  
   105  		// assert output contains error output from python http.server
   106  		return strings.Contains(output, `<p>Error code explanation: HTTPStatus.NOT_IMPLEMENTED - Server does not support this operation.</p>`)
   107  	}, 5*time.Second, 200*time.Millisecond)
   108  }
   109  
   110  func testChecksServiceReRegisterAfterCheckRestart(t *testing.T) {
   111  	const (
   112  		jobChecksAfterRestartMain   = "./input/checks_task_restart_main.nomad"
   113  		jobChecksAfterRestartHelper = "./input/checks_task_restart_helper.nomad"
   114  	)
   115  
   116  	nomadClient := e2eutil.NomadClient(t)
   117  
   118  	idJobMain := "nsd-check-restart-services-" + uuid.Short()
   119  	idJobHelper := "nsd-check-restart-services-helper-" + uuid.Short()
   120  	jobIDs := []string{idJobMain, idJobHelper}
   121  
   122  	// Defer a cleanup function to remove the job. This will trigger if the
   123  	// test fails, unless the cancel function is called.
   124  	ctx, cancel := context.WithCancel(context.Background())
   125  	defer cancel()
   126  	defer e2eutil.CleanupJobsAndGCWithContext(t, ctx, &jobIDs)
   127  
   128  	// register the main job
   129  	allocStubs := e2eutil.RegisterAndWaitForAllocs(t, nomadClient, jobChecksAfterRestartMain, idJobMain, "")
   130  	must.Len(t, 1, allocStubs)
   131  
   132  	// wait for task restart due to failing health check
   133  	must.Wait(t, wait.InitialSuccess(
   134  		wait.BoolFunc(func() bool {
   135  			allocEvents, err := e2eutil.AllocTaskEventsForJob(idJobMain, "")
   136  			if err != nil {
   137  				t.Log("failed to get task events for job", idJobMain, err)
   138  				return false
   139  			}
   140  			for _, events := range allocEvents {
   141  				for _, event := range events {
   142  					if event["Type"] == "Restarting" {
   143  						return true
   144  					}
   145  				}
   146  			}
   147  			return false
   148  		}),
   149  		wait.Timeout(30*time.Second),
   150  		wait.Gap(3*time.Second),
   151  	))
   152  
   153  	runHelper := func(command string) {
   154  		vars := []string{"-var", "nodeID=" + allocStubs[0].NodeID, "-var", "cmd=touch", "-var", "delay=3s"}
   155  		err := e2eutil.RegisterWithArgs(idJobHelper, jobChecksAfterRestartHelper, vars...)
   156  		test.NoError(t, err)
   157  	}
   158  
   159  	// register helper job, triggering check to start passing
   160  	runHelper("touch")
   161  	defer func() {
   162  		runHelper("rm")
   163  	}()
   164  
   165  	// wait for main task to become healthy
   166  	e2eutil.WaitForAllocStatus(t, nomadClient, allocStubs[0].ID, structs.AllocClientStatusRunning)
   167  
   168  	// finally assert we have services
   169  	services := nomadClient.Services()
   170  	serviceStubs, _, err := services.Get("nsd-checks-task-restart-test", nil)
   171  	must.NoError(t, err)
   172  	must.Len(t, 1, serviceStubs)
   173  }