github.com/Ilhicas/nomad@v1.0.4-0.20210304152020-e86851182bc3/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  		"xDS": {
    99  			"SupportedProxies": map[string]interface{}{
   100  				"envoy": []interface{}{
   101  					"1.14.2",
   102  					"1.13.2",
   103  					"1.12.4",
   104  					"1.11.2",
   105  				},
   106  			},
   107  		},
   108  	}
   109  	return s, nil
   110  }
   111  
   112  func (c *MockAgent) Services() (map[string]*api.AgentService, error) {
   113  	c.mu.Lock()
   114  	defer c.mu.Unlock()
   115  	c.hits++
   116  
   117  	r := make(map[string]*api.AgentService, len(c.services))
   118  	for k, v := range c.services {
   119  		r[k] = &api.AgentService{
   120  			ID:                v.ID,
   121  			Service:           v.Name,
   122  			Tags:              make([]string, len(v.Tags)),
   123  			Meta:              helper.CopyMapStringString(v.Meta),
   124  			Port:              v.Port,
   125  			Address:           v.Address,
   126  			EnableTagOverride: v.EnableTagOverride,
   127  		}
   128  		copy(r[k].Tags, v.Tags)
   129  	}
   130  	return r, nil
   131  }
   132  
   133  // Checks implements the Agent API Checks method.
   134  func (c *MockAgent) Checks() (map[string]*api.AgentCheck, error) {
   135  	c.mu.Lock()
   136  	defer c.mu.Unlock()
   137  	c.hits++
   138  
   139  	r := make(map[string]*api.AgentCheck, len(c.checks))
   140  	for k, v := range c.checks {
   141  		r[k] = &api.AgentCheck{
   142  			CheckID:     v.ID,
   143  			Name:        v.Name,
   144  			Status:      c.checkStatus,
   145  			Notes:       v.Notes,
   146  			ServiceID:   v.ServiceID,
   147  			ServiceName: c.services[v.ServiceID].Name,
   148  		}
   149  	}
   150  	return r, nil
   151  }
   152  
   153  // CheckRegs returns the raw AgentCheckRegistrations registered with this mock
   154  // agent.
   155  func (c *MockAgent) CheckRegs() []*api.AgentCheckRegistration {
   156  	c.mu.Lock()
   157  	defer c.mu.Unlock()
   158  	regs := make([]*api.AgentCheckRegistration, 0, len(c.checks))
   159  	for _, check := range c.checks {
   160  		regs = append(regs, check)
   161  	}
   162  	return regs
   163  }
   164  
   165  func (c *MockAgent) CheckRegister(check *api.AgentCheckRegistration) error {
   166  	c.mu.Lock()
   167  	defer c.mu.Unlock()
   168  	c.hits++
   169  
   170  	c.checks[check.ID] = check
   171  
   172  	// Be nice and make checks reachable-by-service
   173  	scheck := check.AgentServiceCheck
   174  	c.services[check.ServiceID].Checks = append(c.services[check.ServiceID].Checks, &scheck)
   175  	return nil
   176  }
   177  
   178  func (c *MockAgent) CheckDeregister(checkID string) error {
   179  	c.mu.Lock()
   180  	defer c.mu.Unlock()
   181  	c.hits++
   182  	delete(c.checks, checkID)
   183  	delete(c.checkTTLs, checkID)
   184  	return nil
   185  }
   186  
   187  func (c *MockAgent) ServiceRegister(service *api.AgentServiceRegistration) error {
   188  	c.mu.Lock()
   189  	defer c.mu.Unlock()
   190  	c.hits++
   191  	c.services[service.ID] = service
   192  	return nil
   193  }
   194  
   195  func (c *MockAgent) ServiceDeregister(serviceID string) error {
   196  	c.mu.Lock()
   197  	defer c.mu.Unlock()
   198  	c.hits++
   199  	delete(c.services, serviceID)
   200  	for k, v := range c.checks {
   201  		if v.ServiceID == serviceID {
   202  			delete(c.checks, k)
   203  			delete(c.checkTTLs, k)
   204  		}
   205  	}
   206  	return nil
   207  }
   208  
   209  func (c *MockAgent) UpdateTTL(id string, output string, status string) error {
   210  	c.mu.Lock()
   211  	defer c.mu.Unlock()
   212  	c.hits++
   213  
   214  	check, ok := c.checks[id]
   215  	if !ok {
   216  		return fmt.Errorf("unknown check id: %q", id)
   217  	}
   218  	// Flip initial status to passing
   219  	check.Status = "passing"
   220  	c.checkTTLs[id]++
   221  	return nil
   222  }
   223  
   224  // a convenience method for looking up a registered service by name
   225  func (c *MockAgent) lookupService(name string) []*api.AgentServiceRegistration {
   226  	c.mu.Lock()
   227  	defer c.mu.Unlock()
   228  
   229  	var services []*api.AgentServiceRegistration
   230  	for _, service := range c.services {
   231  		if service.Name == name {
   232  			services = append(services, service)
   233  		}
   234  	}
   235  	return services
   236  }