github.com/smithx10/nomad@v0.9.1-rc1/command/agent/consul/catalog_testing.go (about) 1 package consul 2 3 import ( 4 "fmt" 5 "sync" 6 7 log "github.com/hashicorp/go-hclog" 8 9 "github.com/hashicorp/consul/api" 10 ) 11 12 // MockCatalog can be used for testing where the CatalogAPI is needed. 13 type MockCatalog struct { 14 logger log.Logger 15 } 16 17 func NewMockCatalog(l log.Logger) *MockCatalog { 18 l = l.Named("mock_consul") 19 return &MockCatalog{logger: l} 20 } 21 22 func (m *MockCatalog) Datacenters() ([]string, error) { 23 dcs := []string{"dc1"} 24 m.logger.Trace("Datacenters()", "dcs", dcs, "error", "nil") 25 return dcs, nil 26 } 27 28 func (m *MockCatalog) Service(service, tag string, q *api.QueryOptions) ([]*api.CatalogService, *api.QueryMeta, error) { 29 m.logger.Trace("Services()", "service", service, "tag", tag, "query_options", q) 30 return nil, nil, nil 31 } 32 33 // MockAgent is a fake in-memory Consul backend for ServiceClient. 34 type MockAgent struct { 35 // maps of what services and checks have been registered 36 services map[string]*api.AgentServiceRegistration 37 checks map[string]*api.AgentCheckRegistration 38 39 // hits is the total number of times agent methods have been called 40 hits int 41 42 // mu guards above fields 43 mu sync.Mutex 44 45 // when UpdateTTL is called the check ID will have its counter inc'd 46 checkTTLs map[string]int 47 48 // What check status to return from Checks() 49 checkStatus string 50 } 51 52 // NewMockAgent that returns all checks as passing. 53 func NewMockAgent() *MockAgent { 54 return &MockAgent{ 55 services: make(map[string]*api.AgentServiceRegistration), 56 checks: make(map[string]*api.AgentCheckRegistration), 57 checkTTLs: make(map[string]int), 58 checkStatus: api.HealthPassing, 59 } 60 } 61 62 // getHits returns how many Consul Agent API calls have been made. 63 func (c *MockAgent) getHits() int { 64 c.mu.Lock() 65 defer c.mu.Unlock() 66 return c.hits 67 } 68 69 // SetStatus that Checks() should return. Returns old status value. 70 func (c *MockAgent) SetStatus(s string) string { 71 c.mu.Lock() 72 old := c.checkStatus 73 c.checkStatus = s 74 c.mu.Unlock() 75 return old 76 } 77 78 func (c *MockAgent) Self() (map[string]map[string]interface{}, error) { 79 c.mu.Lock() 80 defer c.mu.Unlock() 81 c.hits++ 82 83 s := map[string]map[string]interface{}{ 84 "Member": { 85 "Addr": "127.0.0.1", 86 "DelegateCur": 4, 87 "DelegateMax": 5, 88 "DelegateMin": 2, 89 "Name": "rusty", 90 "Port": 8301, 91 "ProtocolCur": 2, 92 "ProtocolMax": 5, 93 "ProtocolMin": 1, 94 "Status": 1, 95 "Tags": map[string]interface{}{ 96 "build": "0.8.1:'e9ca44d", 97 }, 98 }, 99 } 100 return s, nil 101 } 102 103 func (c *MockAgent) Services() (map[string]*api.AgentService, error) { 104 c.mu.Lock() 105 defer c.mu.Unlock() 106 c.hits++ 107 108 r := make(map[string]*api.AgentService, len(c.services)) 109 for k, v := range c.services { 110 r[k] = &api.AgentService{ 111 ID: v.ID, 112 Service: v.Name, 113 Tags: make([]string, len(v.Tags)), 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 }