github.com/iqoqo/nomad@v0.11.3-0.20200911112621-d7021c74d101/e2e/connect/connect.go (about) 1 package connect 2 3 import ( 4 "os" 5 "strings" 6 "time" 7 8 consulapi "github.com/hashicorp/consul/api" 9 "github.com/hashicorp/nomad/api" 10 "github.com/hashicorp/nomad/e2e/e2eutil" 11 "github.com/hashicorp/nomad/e2e/framework" 12 "github.com/hashicorp/nomad/helper/uuid" 13 "github.com/hashicorp/nomad/jobspec" 14 "github.com/kr/pretty" 15 "github.com/stretchr/testify/require" 16 ) 17 18 type ConnectE2ETest struct { 19 framework.TC 20 jobIds []string 21 } 22 23 func init() { 24 // connect tests without Consul ACLs enabled 25 framework.AddSuites(&framework.TestSuite{ 26 Component: "Connect", 27 CanRunLocal: true, 28 Consul: true, 29 Cases: []framework.TestCase{ 30 new(ConnectE2ETest), 31 new(ConnectClientStateE2ETest), 32 }, 33 }) 34 35 // connect tests with Consul ACLs enabled 36 framework.AddSuites(&framework.TestSuite{ 37 Component: "ConnectACLs", 38 CanRunLocal: false, 39 Consul: true, 40 Parallel: false, 41 Cases: []framework.TestCase{ 42 new(ConnectACLsE2ETest), 43 }, 44 }) 45 } 46 47 func (tc *ConnectE2ETest) BeforeAll(f *framework.F) { 48 e2eutil.WaitForLeader(f.T(), tc.Nomad()) 49 e2eutil.WaitForNodesReady(f.T(), tc.Nomad(), 2) 50 } 51 52 func (tc *ConnectE2ETest) AfterEach(f *framework.F) { 53 if os.Getenv("NOMAD_TEST_SKIPCLEANUP") == "1" { 54 return 55 } 56 57 for _, id := range tc.jobIds { 58 tc.Nomad().Jobs().Deregister(id, true, nil) 59 } 60 tc.jobIds = []string{} 61 tc.Nomad().System().GarbageCollect() 62 } 63 64 // TestConnectDemo tests the demo job file from the Consul Connect Technology 65 // Preview. 66 // 67 // https://github.com/hashicorp/nomad/blob/v0.9.5/website/source/guides/integrations/consul-connect/index.html.md#run-the-connect-enabled-services 68 // 69 func (tc *ConnectE2ETest) TestConnectDemo(f *framework.F) { 70 t := f.T() 71 uuid := uuid.Generate() 72 jobID := "connect" + uuid[0:8] 73 tc.jobIds = append(tc.jobIds, jobID) 74 jobapi := tc.Nomad().Jobs() 75 76 job, err := jobspec.ParseFile("connect/input/demo.nomad") 77 require.NoError(t, err) 78 job.ID = &jobID 79 80 resp, _, err := jobapi.Register(job, nil) 81 require.NoError(t, err) 82 require.NotNil(t, resp) 83 require.Zero(t, resp.Warnings) 84 85 EVAL: 86 qopts := &api.QueryOptions{ 87 WaitIndex: resp.EvalCreateIndex, 88 } 89 evalapi := tc.Nomad().Evaluations() 90 eval, qmeta, err := evalapi.Info(resp.EvalID, qopts) 91 require.NoError(t, err) 92 qopts.WaitIndex = qmeta.LastIndex 93 94 switch eval.Status { 95 case "pending": 96 goto EVAL 97 case "complete": 98 // Ok! 99 case "failed", "canceled", "blocked": 100 t.Fatalf("eval %s\n%s\n", eval.Status, pretty.Sprint(eval)) 101 default: 102 t.Fatalf("unknown eval status: %s\n%s\n", eval.Status, pretty.Sprint(eval)) 103 } 104 105 // Assert there were 0 placement failures 106 require.Zero(t, eval.FailedTGAllocs, pretty.Sprint(eval.FailedTGAllocs)) 107 require.Len(t, eval.QueuedAllocations, 2, pretty.Sprint(eval.QueuedAllocations)) 108 109 // Assert allocs are running 110 for i := 0; i < 20; i++ { 111 allocs, qmeta, err := evalapi.Allocations(eval.ID, qopts) 112 require.NoError(t, err) 113 require.Len(t, allocs, 2) 114 qopts.WaitIndex = qmeta.LastIndex 115 116 running := 0 117 for _, alloc := range allocs { 118 switch alloc.ClientStatus { 119 case "running": 120 running++ 121 case "pending": 122 // keep trying 123 default: 124 t.Fatalf("alloc failed: %s", pretty.Sprint(alloc)) 125 } 126 } 127 128 if running == len(allocs) { 129 break 130 } 131 132 time.Sleep(500 * time.Millisecond) 133 } 134 135 allocs, _, err := evalapi.Allocations(eval.ID, qopts) 136 require.NoError(t, err) 137 allocIDs := make(map[string]bool, 2) 138 for _, a := range allocs { 139 if a.ClientStatus != "running" || a.DesiredStatus != "run" { 140 t.Fatalf("alloc %s (%s) terminal; client=%s desired=%s", a.TaskGroup, a.ID, a.ClientStatus, a.DesiredStatus) 141 } 142 allocIDs[a.ID] = true 143 } 144 145 // Check Consul service health 146 agentapi := tc.Consul().Agent() 147 148 failing := map[string]*consulapi.AgentCheck{} 149 for i := 0; i < 60; i++ { 150 checks, err := agentapi.Checks() 151 require.NoError(t, err) 152 153 // Filter out checks for other services 154 for cid, check := range checks { 155 found := false 156 for allocID := range allocIDs { 157 if strings.Contains(check.ServiceID, allocID) { 158 found = true 159 break 160 } 161 } 162 163 if !found { 164 delete(checks, cid) 165 } 166 } 167 168 // Ensure checks are all passing 169 failing = map[string]*consulapi.AgentCheck{} 170 for _, check := range checks { 171 if check.Status != "passing" { 172 failing[check.CheckID] = check 173 break 174 } 175 } 176 177 if len(failing) == 0 { 178 break 179 } 180 181 t.Logf("still %d checks not passing", len(failing)) 182 183 time.Sleep(time.Second) 184 } 185 186 require.Len(t, failing, 0, pretty.Sprint(failing)) 187 }