github.com/dkerwin/nomad@v0.3.3-0.20160525181927-74554135514b/client/consul/sync_test.go (about) 1 package consul 2 3 import ( 4 "fmt" 5 "log" 6 "os" 7 "reflect" 8 "testing" 9 "time" 10 11 "github.com/hashicorp/go-multierror" 12 "github.com/hashicorp/nomad/nomad/structs" 13 ) 14 15 const ( 16 allocID = "12" 17 ) 18 19 var ( 20 logger = log.New(os.Stdout, "", log.LstdFlags) 21 check1 = structs.ServiceCheck{ 22 Name: "check-foo-1", 23 Type: structs.ServiceCheckTCP, 24 Interval: 30 * time.Second, 25 Timeout: 5 * time.Second, 26 } 27 service1 = structs.Service{ 28 Name: "foo-1", 29 Tags: []string{"tag1", "tag2"}, 30 PortLabel: "port1", 31 Checks: []*structs.ServiceCheck{ 32 &check1, 33 }, 34 } 35 36 service2 = structs.Service{ 37 Name: "foo-2", 38 Tags: []string{"tag1", "tag2"}, 39 PortLabel: "port2", 40 } 41 ) 42 43 func TestConsulServiceRegisterServices(t *testing.T) { 44 cs, err := NewConsulService(&ConsulConfig{}, logger) 45 if err != nil { 46 t.Fatalf("Err: %v", err) 47 } 48 // Skipping the test if consul isn't present 49 if !cs.consulPresent() { 50 return 51 } 52 task := mockTask() 53 cs.SetServiceIdentifier(GenerateServiceIdentifier(allocID, task.Name)) 54 cs.SetAddrFinder(task.FindHostAndPortFor) 55 if err := cs.SyncServices(task.Services); err != nil { 56 t.Fatalf("err: %v", err) 57 } 58 defer cs.Shutdown() 59 60 service1ID := service1.ID(GenerateServiceIdentifier(allocID, task.Name)) 61 service2ID := service2.ID(GenerateServiceIdentifier(allocID, task.Name)) 62 if err := servicesPresent(t, []string{service1ID, service2ID}, cs); err != nil { 63 t.Fatalf("err : %v", err) 64 } 65 if err := checksPresent(t, []string{check1.Hash(service1ID)}, cs); err != nil { 66 t.Fatalf("err : %v", err) 67 } 68 } 69 70 func TestConsulServiceUpdateService(t *testing.T) { 71 cs, err := NewConsulService(&ConsulConfig{}, logger) 72 if err != nil { 73 t.Fatalf("Err: %v", err) 74 } 75 // Skipping the test if consul isn't present 76 if !cs.consulPresent() { 77 return 78 } 79 80 task := mockTask() 81 cs.SetServiceIdentifier(GenerateServiceIdentifier(allocID, task.Name)) 82 cs.SetAddrFinder(task.FindHostAndPortFor) 83 if err := cs.SyncServices(task.Services); err != nil { 84 t.Fatalf("err: %v", err) 85 } 86 defer cs.Shutdown() 87 88 //Update Service defn 1 89 newTags := []string{"tag3"} 90 task.Services[0].Tags = newTags 91 if err := cs.SyncServices(task.Services); err != nil { 92 t.Fatalf("err: %v", err) 93 } 94 // Make sure all the services and checks are still present 95 service1ID := service1.ID(GenerateServiceIdentifier(allocID, task.Name)) 96 service2ID := service2.ID(GenerateServiceIdentifier(allocID, task.Name)) 97 if err := servicesPresent(t, []string{service1ID, service2ID}, cs); err != nil { 98 t.Fatalf("err : %v", err) 99 } 100 if err := checksPresent(t, []string{check1.Hash(service1ID)}, cs); err != nil { 101 t.Fatalf("err : %v", err) 102 } 103 104 // check if service defn 1 has been updated 105 services, err := cs.client.Agent().Services() 106 if err != nil { 107 t.Fatalf("errL: %v", err) 108 } 109 srv, _ := services[service1ID] 110 if !reflect.DeepEqual(srv.Tags, newTags) { 111 t.Fatalf("expected tags: %v, actual: %v", newTags, srv.Tags) 112 } 113 } 114 115 func servicesPresent(t *testing.T, serviceIDs []string, consulService *ConsulService) error { 116 var mErr multierror.Error 117 services, err := consulService.client.Agent().Services() 118 if err != nil { 119 t.Fatalf("err: %v", err) 120 } 121 122 for _, serviceID := range serviceIDs { 123 if _, ok := services[serviceID]; !ok { 124 mErr.Errors = append(mErr.Errors, fmt.Errorf("service ID %q not synced", serviceID)) 125 } 126 } 127 return mErr.ErrorOrNil() 128 } 129 130 func checksPresent(t *testing.T, checkIDs []string, consulService *ConsulService) error { 131 var mErr multierror.Error 132 checks, err := consulService.client.Agent().Checks() 133 if err != nil { 134 t.Fatalf("err: %v", err) 135 } 136 137 for _, checkID := range checkIDs { 138 if _, ok := checks[checkID]; !ok { 139 mErr.Errors = append(mErr.Errors, fmt.Errorf("check ID %q not synced", checkID)) 140 } 141 } 142 return mErr.ErrorOrNil() 143 } 144 145 func mockTask() *structs.Task { 146 task := structs.Task{ 147 Name: "foo", 148 Services: []*structs.Service{&service1, &service2}, 149 Resources: &structs.Resources{ 150 Networks: []*structs.NetworkResource{ 151 &structs.NetworkResource{ 152 IP: "10.10.11.5", 153 DynamicPorts: []structs.Port{ 154 structs.Port{ 155 Label: "port1", 156 Value: 20002, 157 }, 158 structs.Port{ 159 Label: "port2", 160 Value: 20003, 161 }, 162 }, 163 }, 164 }, 165 }, 166 } 167 return &task 168 }