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