github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/e2e/operator_scheduler/operator_scheduler_test.go (about)

     1  package operator_scheduler
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/hashicorp/nomad/e2e/e2eutil"
    10  	"github.com/hashicorp/nomad/helper/uuid"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  const jobBasic = "./input/basic.nomad"
    16  
    17  // TestOperatorScheduler runs the Nomad Operator Scheduler suit of tests which
    18  // focus on the behaviour of the /v1/operator/scheduler API.
    19  func TestOperatorScheduler(t *testing.T) {
    20  
    21  	// Wait until we have a usable cluster before running the tests.
    22  	nomadClient := e2eutil.NomadClient(t)
    23  	e2eutil.WaitForLeader(t, nomadClient)
    24  	e2eutil.WaitForNodesReady(t, nomadClient, 1)
    25  
    26  	// Run our test cases.
    27  	t.Run("TestOperatorScheduler_ConfigPauseEvalBroker", testConfigPauseEvalBroker)
    28  }
    29  
    30  // testConfig tests pausing and un-pausing the eval broker and ensures the
    31  // correct behaviour is observed at each stage.
    32  func testConfigPauseEvalBroker(t *testing.T) {
    33  
    34  	nomadClient := e2eutil.NomadClient(t)
    35  
    36  	// Generate our job ID which will be used for the entire test.
    37  	jobID := "operator-scheduler-config-pause-eval-broker-" + uuid.Generate()[:8]
    38  	jobIDs := []string{jobID}
    39  
    40  	// Defer a cleanup function to remove the job. This will trigger if the
    41  	// test fails, unless the cancel function is called.
    42  	ctx, cancel := context.WithCancel(context.Background())
    43  	defer e2eutil.CleanupJobsAndGCWithContext(t, ctx, &jobIDs)
    44  
    45  	// Register the job and ensure the alloc reaches the running state before
    46  	// moving safely on.
    47  	allocStubs := e2eutil.RegisterAndWaitForAllocs(t, nomadClient, jobBasic, jobID, "")
    48  	require.Len(t, allocStubs, 1)
    49  	e2eutil.WaitForAllocRunning(t, nomadClient, allocStubs[0].ID)
    50  
    51  	// Get the current scheduler config object.
    52  	schedulerConfig, _, err := nomadClient.Operator().SchedulerGetConfiguration(nil)
    53  	require.NoError(t, err)
    54  	require.NotNil(t, schedulerConfig.SchedulerConfig)
    55  
    56  	// Set the eval broker to be paused.
    57  	schedulerConfig.SchedulerConfig.PauseEvalBroker = true
    58  
    59  	// Write the config back to Nomad.
    60  	schedulerConfigUpdate, _, err := nomadClient.Operator().SchedulerSetConfiguration(
    61  		schedulerConfig.SchedulerConfig, nil)
    62  	require.NoError(t, err)
    63  	require.True(t, schedulerConfigUpdate.Updated)
    64  
    65  	// Perform a deregister call. The call will succeed and create an
    66  	// evaluation. Do not use purge, so we can check the job status when
    67  	// dereigster happens.
    68  	evalID, _, err := nomadClient.Jobs().Deregister(jobID, false, nil)
    69  	require.NoError(t, err)
    70  	require.NotEmpty(t, evalID)
    71  
    72  	// Evaluation status is set to pending initially, so there isn't a great
    73  	// way to ensure it doesn't transition to another status other than polling
    74  	// for a long enough time to assume it won't change.
    75  	timedFn := func() error {
    76  
    77  		// 5 seconds should be more than enough time for an eval to change
    78  		// status unless the broker is disabled.
    79  		timer := time.NewTimer(5 * time.Second)
    80  		defer timer.Stop()
    81  
    82  		for {
    83  			select {
    84  			case <-timer.C:
    85  				return nil
    86  			default:
    87  				evalInfo, _, err := nomadClient.Evaluations().Info(evalID, nil)
    88  				if err != nil {
    89  					return err
    90  				}
    91  				if !assert.Equal(t, "pending", evalInfo.Status) {
    92  					return fmt.Errorf(`expected eval status "pending", got %q`, evalInfo.Status)
    93  				}
    94  				time.Sleep(1 * time.Second)
    95  			}
    96  		}
    97  	}
    98  	require.NoError(t, timedFn())
    99  
   100  	// Set the eval broker to be un-paused.
   101  	schedulerConfig.SchedulerConfig.PauseEvalBroker = false
   102  
   103  	// Write the config back to Nomad.
   104  	schedulerConfigUpdate, _, err = nomadClient.Operator().SchedulerSetConfiguration(
   105  		schedulerConfig.SchedulerConfig, nil)
   106  	require.NoError(t, err)
   107  	require.True(t, schedulerConfigUpdate.Updated)
   108  
   109  	// Ensure the job is stopped, then run the garbage collection to clear out
   110  	// all resources.
   111  	e2eutil.WaitForJobStopped(t, nomadClient, jobID)
   112  	_, err = e2eutil.Command("nomad", "system", "gc")
   113  	require.NoError(t, err)
   114  
   115  	// If we have reached this far, we do not need to run the cleanup function.
   116  	cancel()
   117  }