github.com/superfly/nomad@v0.10.5-fly/command/agent/consul/catalog_testing.go (about) 1 package consul 2 3 import ( 4 "fmt" 5 "sync" 6 7 "github.com/hashicorp/consul/api" 8 "github.com/hashicorp/go-hclog" 9 "github.com/hashicorp/nomad/helper" 10 ) 11 12 // MockCatalog can be used for testing where the CatalogAPI is needed. 13 type MockCatalog struct { 14 logger hclog.Logger 15 } 16 17 func NewMockCatalog(l hclog.Logger) *MockCatalog { 18 return &MockCatalog{logger: l.Named("mock_consul")} 19 } 20 21 func (m *MockCatalog) Datacenters() ([]string, error) { 22 dcs := []string{"dc1"} 23 m.logger.Trace("Datacenters()", "dcs", dcs, "error", "nil") 24 return dcs, nil 25 } 26 27 func (m *MockCatalog) Service(service, tag string, q *api.QueryOptions) ([]*api.CatalogService, *api.QueryMeta, error) { 28 m.logger.Trace("Services()", "service", service, "tag", tag, "query_options", q) 29 return nil, nil, nil 30 } 31 32 // MockAgent is a fake in-memory Consul backend for ServiceClient. 33 type MockAgent struct { 34 // maps of what services and checks have been registered 35 services map[string]*api.AgentServiceRegistration 36 checks map[string]*api.AgentCheckRegistration 37 38 // hits is the total number of times agent methods have been called 39 hits int 40 41 // mu guards above fields 42 mu sync.Mutex 43 44 // when UpdateTTL is called the check ID will have its counter inc'd 45 checkTTLs map[string]int 46 47 // What check status to return from Checks() 48 checkStatus string 49 } 50 51 // NewMockAgent that returns all checks as passing. 52 func NewMockAgent() *MockAgent { 53 return &MockAgent{ 54 services: make(map[string]*api.AgentServiceRegistration), 55 checks: make(map[string]*api.AgentCheckRegistration), 56 checkTTLs: make(map[string]int), 57 checkStatus: api.HealthPassing, 58 } 59 } 60 61 // getHits returns how many Consul Agent API calls have been made. 62 func (c *MockAgent) getHits() int { 63 c.mu.Lock() 64 defer c.mu.Unlock() 65 return c.hits 66 } 67 68 // SetStatus that Checks() should return. Returns old status value. 69 func (c *MockAgent) SetStatus(s string) string { 70 c.mu.Lock() 71 old := c.checkStatus 72 c.checkStatus = s 73 c.mu.Unlock() 74 return old 75 } 76 77 func (c *MockAgent) Self() (map[string]map[string]interface{}, error) { 78 c.mu.Lock() 79 defer c.mu.Unlock() 80 c.hits++ 81 82 s := map[string]map[string]interface{}{ 83 "Member": { 84 "Addr": "127.0.0.1", 85 "DelegateCur": 4, 86 "DelegateMax": 5, 87 "DelegateMin": 2, 88 "Name": "rusty", 89 "Port": 8301, 90 "ProtocolCur": 2, 91 "ProtocolMax": 5, 92 "ProtocolMin": 1, 93 "Status": 1, 94 "Tags": map[string]interface{}{ 95 "build": "0.8.1:'e9ca44d", 96 }, 97 }, 98 } 99 return s, nil 100 } 101 102 func (c *MockAgent) Services() (map[string]*api.AgentService, error) { 103 c.mu.Lock() 104 defer c.mu.Unlock() 105 c.hits++ 106 107 r := make(map[string]*api.AgentService, len(c.services)) 108 for k, v := range c.services { 109 r[k] = &api.AgentService{ 110 ID: v.ID, 111 Service: v.Name, 112 Tags: make([]string, len(v.Tags)), 113 Meta: helper.CopyMapStringString(v.Meta), 114 Port: v.Port, 115 Address: v.Address, 116 EnableTagOverride: v.EnableTagOverride, 117 } 118 copy(r[k].Tags, v.Tags) 119 } 120 return r, nil 121 } 122 123 // Checks implements the Agent API Checks method. 124 func (c *MockAgent) Checks() (map[string]*api.AgentCheck, error) { 125 c.mu.Lock() 126 defer c.mu.Unlock() 127 c.hits++ 128 129 r := make(map[string]*api.AgentCheck, len(c.checks)) 130 for k, v := range c.checks { 131 r[k] = &api.AgentCheck{ 132 CheckID: v.ID, 133 Name: v.Name, 134 Status: c.checkStatus, 135 Notes: v.Notes, 136 ServiceID: v.ServiceID, 137 ServiceName: c.services[v.ServiceID].Name, 138 } 139 } 140 return r, nil 141 } 142 143 // CheckRegs returns the raw AgentCheckRegistrations registered with this mock 144 // agent. 145 func (c *MockAgent) CheckRegs() []*api.AgentCheckRegistration { 146 c.mu.Lock() 147 defer c.mu.Unlock() 148 regs := make([]*api.AgentCheckRegistration, 0, len(c.checks)) 149 for _, check := range c.checks { 150 regs = append(regs, check) 151 } 152 return regs 153 } 154 155 func (c *MockAgent) CheckRegister(check *api.AgentCheckRegistration) error { 156 c.mu.Lock() 157 defer c.mu.Unlock() 158 c.hits++ 159 160 c.checks[check.ID] = check 161 162 // Be nice and make checks reachable-by-service 163 scheck := check.AgentServiceCheck 164 c.services[check.ServiceID].Checks = append(c.services[check.ServiceID].Checks, &scheck) 165 return nil 166 } 167 168 func (c *MockAgent) CheckDeregister(checkID string) error { 169 c.mu.Lock() 170 defer c.mu.Unlock() 171 c.hits++ 172 delete(c.checks, checkID) 173 delete(c.checkTTLs, checkID) 174 return nil 175 } 176 177 func (c *MockAgent) ServiceRegister(service *api.AgentServiceRegistration) error { 178 c.mu.Lock() 179 defer c.mu.Unlock() 180 c.hits++ 181 c.services[service.ID] = service 182 return nil 183 } 184 185 func (c *MockAgent) ServiceDeregister(serviceID string) error { 186 c.mu.Lock() 187 defer c.mu.Unlock() 188 c.hits++ 189 delete(c.services, serviceID) 190 return nil 191 } 192 193 func (c *MockAgent) UpdateTTL(id string, output string, status string) error { 194 c.mu.Lock() 195 defer c.mu.Unlock() 196 c.hits++ 197 198 check, ok := c.checks[id] 199 if !ok { 200 return fmt.Errorf("unknown check id: %q", id) 201 } 202 // Flip initial status to passing 203 check.Status = "passing" 204 c.checkTTLs[id]++ 205 return nil 206 }