github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/nomad/state/deployment_events_test.go (about) 1 package state 2 3 import ( 4 "context" 5 "testing" 6 "time" 7 8 "github.com/hashicorp/nomad/ci" 9 "github.com/hashicorp/nomad/nomad/mock" 10 "github.com/hashicorp/nomad/nomad/stream" 11 "github.com/hashicorp/nomad/nomad/structs" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func TestDeploymentEventFromChanges(t *testing.T) { 16 ci.Parallel(t) 17 s := TestStateStoreCfg(t, TestStateStorePublisher(t)) 18 defer s.StopEventBroker() 19 20 // setup 21 setupTx := s.db.WriteTxn(10) 22 23 j := mock.Job() 24 e := mock.Eval() 25 e.JobID = j.ID 26 27 d := mock.Deployment() 28 d.JobID = j.ID 29 30 require.NoError(t, s.upsertJobImpl(10, j, false, setupTx)) 31 require.NoError(t, s.upsertDeploymentImpl(10, d, setupTx)) 32 33 setupTx.Txn.Commit() 34 35 msgType := structs.DeploymentStatusUpdateRequestType 36 37 req := &structs.DeploymentStatusUpdateRequest{ 38 DeploymentUpdate: &structs.DeploymentStatusUpdate{ 39 DeploymentID: d.ID, 40 Status: structs.DeploymentStatusPaused, 41 StatusDescription: structs.DeploymentStatusDescriptionPaused, 42 }, 43 Eval: e, 44 // Exlude Job and assert its added 45 } 46 47 require.NoError(t, s.UpdateDeploymentStatus(msgType, 100, req)) 48 49 events := WaitForEvents(t, s, 100, 1, 1*time.Second) 50 require.Len(t, events, 2) 51 52 got := events[0] 53 require.Equal(t, uint64(100), got.Index) 54 require.Equal(t, d.ID, got.Key) 55 56 de := got.Payload.(*structs.DeploymentEvent) 57 require.Equal(t, structs.DeploymentStatusPaused, de.Deployment.Status) 58 require.Contains(t, got.FilterKeys, j.ID) 59 60 } 61 62 func WaitForEvents(t *testing.T, s *StateStore, index uint64, minEvents int, timeout time.Duration) []structs.Event { 63 ctx, cancel := context.WithCancel(context.Background()) 64 defer cancel() 65 66 go func() { 67 select { 68 case <-ctx.Done(): 69 return 70 case <-time.After(timeout): 71 require.Fail(t, "timeout waiting for events") 72 } 73 }() 74 75 maxAttempts := 10 76 for { 77 got := EventsForIndex(t, s, index) 78 if len(got) >= minEvents { 79 return got 80 } 81 maxAttempts-- 82 if maxAttempts == 0 { 83 require.Failf(t, "reached max attempts waiting for desired event count", "count %d", len(got)) 84 } 85 time.Sleep(10 * time.Millisecond) 86 } 87 } 88 89 func EventsForIndex(t *testing.T, s *StateStore, index uint64) []structs.Event { 90 pub, err := s.EventBroker() 91 require.NoError(t, err) 92 93 sub, err := pub.Subscribe(&stream.SubscribeRequest{ 94 Topics: map[structs.Topic][]string{ 95 "*": {"*"}, 96 }, 97 Namespace: "default", 98 Index: index, 99 StartExactlyAtIndex: true, 100 }) 101 if err != nil { 102 return []structs.Event{} 103 } 104 defer sub.Unsubscribe() 105 106 require.NoError(t, err) 107 108 var events []structs.Event 109 for { 110 e, err := sub.NextNoBlock() 111 require.NoError(t, err) 112 if e == nil { 113 break 114 } 115 events = append(events, e...) 116 } 117 return events 118 }