github.com/bigcommerce/nomad@v0.9.3-bc/e2e/affinities/affinities.go (about)

     1  package affinities
     2  
     3  import (
     4  	"github.com/hashicorp/nomad/e2e/framework"
     5  	"github.com/stretchr/testify/require"
     6  
     7  	"github.com/hashicorp/nomad/e2e/e2eutil"
     8  	"github.com/hashicorp/nomad/helper/uuid"
     9  )
    10  
    11  type BasicAffinityTest struct {
    12  	framework.TC
    13  	jobIds []string
    14  }
    15  
    16  func init() {
    17  	framework.AddSuites(&framework.TestSuite{
    18  		Component:   "Affinity",
    19  		CanRunLocal: true,
    20  		Cases: []framework.TestCase{
    21  			new(BasicAffinityTest),
    22  		},
    23  	})
    24  }
    25  
    26  func (tc *BasicAffinityTest) BeforeAll(f *framework.F) {
    27  	// Ensure cluster has leader before running tests
    28  	e2eutil.WaitForLeader(f.T(), tc.Nomad())
    29  	// Ensure that we have four client nodes in ready state
    30  	e2eutil.WaitForNodesReady(f.T(), tc.Nomad(), 4)
    31  }
    32  
    33  func (tc *BasicAffinityTest) TestSingleAffinities(f *framework.F) {
    34  	nomadClient := tc.Nomad()
    35  	uuid := uuid.Generate()
    36  	jobId := "aff" + uuid[0:8]
    37  	tc.jobIds = append(tc.jobIds, jobId)
    38  	allocs := e2eutil.RegisterAndWaitForAllocs(f.T(), nomadClient, "affinities/input/single_affinity.nomad", jobId)
    39  
    40  	jobAllocs := nomadClient.Allocations()
    41  	require := require.New(f.T())
    42  	// Verify affinity score metadata
    43  	for _, allocStub := range allocs {
    44  		alloc, _, err := jobAllocs.Info(allocStub.ID, nil)
    45  		require.Nil(err)
    46  		require.NotEmpty(alloc.Metrics.ScoreMetaData)
    47  		for _, sm := range alloc.Metrics.ScoreMetaData {
    48  			score, ok := sm.Scores["node-affinity"]
    49  			if ok {
    50  				require.Equal(1.0, score)
    51  			}
    52  		}
    53  	}
    54  
    55  }
    56  
    57  func (tc *BasicAffinityTest) TestMultipleAffinities(f *framework.F) {
    58  	nomadClient := tc.Nomad()
    59  	uuid := uuid.Generate()
    60  	jobId := "multiaff" + uuid[0:8]
    61  	tc.jobIds = append(tc.jobIds, jobId)
    62  	allocs := e2eutil.RegisterAndWaitForAllocs(f.T(), nomadClient, "affinities/input/multiple_affinities.nomad", jobId)
    63  
    64  	jobAllocs := nomadClient.Allocations()
    65  	require := require.New(f.T())
    66  
    67  	// Verify affinity score metadata
    68  	for _, allocStub := range allocs {
    69  		alloc, _, err := jobAllocs.Info(allocStub.ID, nil)
    70  		require.Nil(err)
    71  		require.NotEmpty(alloc.Metrics.ScoreMetaData)
    72  
    73  		node, _, err := nomadClient.Nodes().Info(alloc.NodeID, nil)
    74  		require.Nil(err)
    75  
    76  		dcMatch := node.Datacenter == "dc1"
    77  		rackMatch := node.Meta != nil && node.Meta["rack"] == "r1"
    78  
    79  		// Figure out expected node affinity score based on whether both affinities match or just one does
    80  		expectedNodeAffinityScore := 0.0
    81  		if dcMatch && rackMatch {
    82  			expectedNodeAffinityScore = 1.0
    83  		} else if dcMatch || rackMatch {
    84  			expectedNodeAffinityScore = 0.5
    85  		}
    86  
    87  		nodeScore := 0.0
    88  		// Find the node's score for this alloc
    89  		for _, sm := range alloc.Metrics.ScoreMetaData {
    90  			score, ok := sm.Scores["node-affinity"]
    91  			if ok && sm.NodeID == alloc.NodeID {
    92  				nodeScore = score
    93  			}
    94  		}
    95  		require.Equal(nodeScore, expectedNodeAffinityScore)
    96  	}
    97  }
    98  
    99  func (tc *BasicAffinityTest) TestAntiAffinities(f *framework.F) {
   100  	nomadClient := tc.Nomad()
   101  	uuid := uuid.Generate()
   102  	jobId := "antiaff" + uuid[0:8]
   103  	tc.jobIds = append(tc.jobIds, jobId)
   104  	allocs := e2eutil.RegisterAndWaitForAllocs(f.T(), nomadClient, "affinities/input/anti_affinities.nomad", jobId)
   105  
   106  	jobAllocs := nomadClient.Allocations()
   107  	require := require.New(f.T())
   108  
   109  	// Verify affinity score metadata
   110  	for _, allocStub := range allocs {
   111  		alloc, _, err := jobAllocs.Info(allocStub.ID, nil)
   112  		require.Nil(err)
   113  		require.NotEmpty(alloc.Metrics.ScoreMetaData)
   114  
   115  		node, _, err := nomadClient.Nodes().Info(alloc.NodeID, nil)
   116  		require.Nil(err)
   117  
   118  		dcMatch := node.Datacenter == "dc1"
   119  		rackMatch := node.Meta != nil && node.Meta["rack"] == "r1"
   120  
   121  		// Figure out expected node affinity score based on whether both affinities match or just one does
   122  		expectedAntiAffinityScore := 0.0
   123  		if dcMatch && rackMatch {
   124  			expectedAntiAffinityScore = -1.0
   125  		} else if dcMatch || rackMatch {
   126  			expectedAntiAffinityScore = -0.5
   127  		}
   128  
   129  		nodeScore := 0.0
   130  
   131  		// Find the node's score for this alloc
   132  		for _, sm := range alloc.Metrics.ScoreMetaData {
   133  			score, ok := sm.Scores["node-affinity"]
   134  			if ok && sm.NodeID == alloc.NodeID {
   135  				nodeScore = score
   136  			}
   137  		}
   138  		require.Equal(nodeScore, expectedAntiAffinityScore)
   139  	}
   140  }
   141  
   142  func (tc *BasicAffinityTest) AfterEach(f *framework.F) {
   143  	nomadClient := tc.Nomad()
   144  	jobs := nomadClient.Jobs()
   145  	// Stop all jobs in test
   146  	for _, id := range tc.jobIds {
   147  		jobs.Deregister(id, true, nil)
   148  	}
   149  	// Garbage collect
   150  	nomadClient.System().GarbageCollect()
   151  }