github.com/hernad/nomad@v1.6.112/e2e/operator_scheduler/operator_scheduler_test.go (about)

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