github.com/iqoqo/nomad@v0.11.3-0.20200911112621-d7021c74d101/e2e/connect/multi_service.go (about)

     1  package connect
     2  
     3  import (
     4  	"strings"
     5  	"time"
     6  
     7  	consulapi "github.com/hashicorp/consul/api"
     8  	"github.com/hashicorp/nomad/api"
     9  	"github.com/hashicorp/nomad/e2e/framework"
    10  	"github.com/hashicorp/nomad/helper/uuid"
    11  	"github.com/hashicorp/nomad/jobspec"
    12  	"github.com/kr/pretty"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  // TestMultiServiceConnect tests running multiple envoy sidecars in the same allocation.
    17  func (tc *ConnectE2ETest) TestMultiServiceConnect(f *framework.F) {
    18  	t := f.T()
    19  	uuid := uuid.Generate()
    20  	jobID := "connect" + uuid[0:8]
    21  	tc.jobIds = append(tc.jobIds, jobID)
    22  	jobapi := tc.Nomad().Jobs()
    23  
    24  	job, err := jobspec.ParseFile("connect/input/multi-service.nomad")
    25  	require.NoError(t, err)
    26  	job.ID = &jobID
    27  
    28  	resp, _, err := jobapi.Register(job, nil)
    29  	require.NoError(t, err)
    30  	require.NotNil(t, resp)
    31  	require.Zero(t, resp.Warnings)
    32  
    33  EVAL:
    34  	qopts := &api.QueryOptions{
    35  		WaitIndex: resp.EvalCreateIndex,
    36  	}
    37  	evalapi := tc.Nomad().Evaluations()
    38  	eval, qmeta, err := evalapi.Info(resp.EvalID, qopts)
    39  	require.NoError(t, err)
    40  	qopts.WaitIndex = qmeta.LastIndex
    41  
    42  	switch eval.Status {
    43  	case "pending":
    44  		goto EVAL
    45  	case "complete":
    46  		// Ok!
    47  	case "failed", "canceled", "blocked":
    48  		t.Fatalf("eval %s\n%s\n", eval.Status, pretty.Sprint(eval))
    49  	default:
    50  		t.Fatalf("unknown eval status: %s\n%s\n", eval.Status, pretty.Sprint(eval))
    51  	}
    52  
    53  	// Assert there were 0 placement failures
    54  	require.Zero(t, eval.FailedTGAllocs, pretty.Sprint(eval.FailedTGAllocs))
    55  	require.Len(t, eval.QueuedAllocations, 1, pretty.Sprint(eval.QueuedAllocations))
    56  
    57  	// Assert allocs are running
    58  	for i := 0; i < 20; i++ {
    59  		allocs, qmeta, err := evalapi.Allocations(eval.ID, qopts)
    60  		require.NoError(t, err)
    61  		require.Len(t, allocs, 1)
    62  		qopts.WaitIndex = qmeta.LastIndex
    63  
    64  		running := 0
    65  		for _, alloc := range allocs {
    66  			switch alloc.ClientStatus {
    67  			case "running":
    68  				running++
    69  			case "pending":
    70  				// keep trying
    71  			default:
    72  				require.Failf(t, "alloc failed", "alloc: %s", pretty.Sprint(alloc))
    73  			}
    74  		}
    75  
    76  		if running == len(allocs) {
    77  			break
    78  		}
    79  
    80  		time.Sleep(500 * time.Millisecond)
    81  	}
    82  
    83  	allocs, _, err := evalapi.Allocations(eval.ID, qopts)
    84  	require.NoError(t, err)
    85  	allocIDs := make(map[string]bool, 1)
    86  	for _, a := range allocs {
    87  		if a.ClientStatus != "running" || a.DesiredStatus != "run" {
    88  			t.Fatalf("alloc %s (%s) terminal; client=%s desired=%s", a.TaskGroup, a.ID, a.ClientStatus, a.DesiredStatus)
    89  		}
    90  		allocIDs[a.ID] = true
    91  	}
    92  
    93  	// Check Consul service health
    94  	agentapi := tc.Consul().Agent()
    95  
    96  	failing := map[string]*consulapi.AgentCheck{}
    97  	require.Eventually(t, func() bool {
    98  		checks, err := agentapi.Checks()
    99  		require.NoError(t, err)
   100  
   101  		// Filter out checks for other services
   102  		for cid, check := range checks {
   103  			found := false
   104  			for allocID := range allocIDs {
   105  				if strings.Contains(check.ServiceID, allocID) {
   106  					found = true
   107  					break
   108  				}
   109  			}
   110  
   111  			if !found {
   112  				delete(checks, cid)
   113  			}
   114  		}
   115  
   116  		// Ensure checks are all passing
   117  		failing = map[string]*consulapi.AgentCheck{}
   118  		for _, check := range checks {
   119  			if check.Status != "passing" {
   120  				failing[check.CheckID] = check
   121  				break
   122  			}
   123  		}
   124  
   125  		if len(failing) == 0 {
   126  			return true
   127  		}
   128  
   129  		t.Logf("still %d checks not passing", len(failing))
   130  		return false
   131  	}, time.Minute, time.Second)
   132  
   133  	require.Len(t, failing, 0, pretty.Sprint(failing))
   134  }