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 }