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 }