github.com/bigcommerce/nomad@v0.9.3-bc/client/fingerprint/consul_test.go (about)

     1  package fingerprint
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"net/http/httptest"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/hashicorp/nomad/client/config"
    11  	"github.com/hashicorp/nomad/helper/testlog"
    12  	"github.com/hashicorp/nomad/nomad/structs"
    13  	"github.com/stretchr/testify/assert"
    14  )
    15  
    16  func TestConsulFingerprint(t *testing.T) {
    17  	fp := NewConsulFingerprint(testlog.HCLogger(t))
    18  	node := &structs.Node{
    19  		Attributes: make(map[string]string),
    20  	}
    21  
    22  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    23  		w.Header().Set("Content-Type", "application/json")
    24  		fmt.Fprintln(w, mockConsulResponse)
    25  	}))
    26  	defer ts.Close()
    27  
    28  	conf := config.DefaultConfig()
    29  	conf.ConsulConfig.Addr = strings.TrimPrefix(ts.URL, "http://")
    30  
    31  	request := &FingerprintRequest{Config: conf, Node: node}
    32  	var response FingerprintResponse
    33  	err := fp.Fingerprint(request, &response)
    34  	if err != nil {
    35  		t.Fatalf("Failed to fingerprint: %s", err)
    36  	}
    37  
    38  	if !response.Detected {
    39  		t.Fatalf("expected response to be applicable")
    40  	}
    41  
    42  	assertNodeAttributeContains(t, response.Attributes, "consul.server")
    43  	assertNodeAttributeContains(t, response.Attributes, "consul.version")
    44  	assertNodeAttributeContains(t, response.Attributes, "consul.revision")
    45  	assertNodeAttributeContains(t, response.Attributes, "unique.consul.name")
    46  	assertNodeAttributeContains(t, response.Attributes, "consul.datacenter")
    47  
    48  	if _, ok := response.Links["consul"]; !ok {
    49  		t.Errorf("Expected a link to consul, none found")
    50  	}
    51  }
    52  
    53  // Taken from tryconsul using consul release 0.5.2
    54  const mockConsulResponse = `
    55  {
    56    "Config": {
    57      "Bootstrap": false,
    58      "BootstrapExpect": 3,
    59      "Server": true,
    60      "Datacenter": "vagrant",
    61      "DataDir": "/var/lib/consul",
    62      "DNSRecursor": "",
    63      "DNSRecursors": [],
    64      "DNSConfig": {
    65        "NodeTTL": 0,
    66        "ServiceTTL": null,
    67        "AllowStale": false,
    68        "EnableTruncate": false,
    69        "MaxStale": 5000000000,
    70        "OnlyPassing": false
    71      },
    72      "Domain": "consul.",
    73      "LogLevel": "INFO",
    74      "NodeName": "consul2",
    75      "ClientAddr": "0.0.0.0",
    76      "BindAddr": "0.0.0.0",
    77      "AdvertiseAddr": "172.16.59.133",
    78      "AdvertiseAddrWan": "172.16.59.133",
    79      "Ports": {
    80        "DNS": 8600,
    81        "HTTP": 8500,
    82        "HTTPS": -1,
    83        "RPC": 8400,
    84        "SerfLan": 8301,
    85        "SerfWan": 8302,
    86        "Server": 8300
    87      },
    88      "Addresses": {
    89        "DNS": "",
    90        "HTTP": "",
    91        "HTTPS": "",
    92        "RPC": ""
    93      },
    94      "LeaveOnTerm": false,
    95      "SkipLeaveOnInt": false,
    96      "StatsiteAddr": "",
    97      "StatsitePrefix": "consul",
    98      "StatsdAddr": "",
    99      "Protocol": 2,
   100      "EnableDebug": false,
   101      "VerifyIncoming": false,
   102      "VerifyOutgoing": false,
   103      "VerifyServerHostname": false,
   104      "CAFile": "",
   105      "CertFile": "",
   106      "KeyFile": "",
   107      "ServerName": "",
   108      "StartJoin": [],
   109      "StartJoinWan": [],
   110      "RetryJoin": [],
   111      "RetryMaxAttempts": 0,
   112      "RetryIntervalRaw": "",
   113      "RetryJoinWan": [],
   114      "RetryMaxAttemptsWan": 0,
   115      "RetryIntervalWanRaw": "",
   116      "UiDir": "/opt/consul-ui",
   117      "PidFile": "",
   118      "EnableSyslog": true,
   119      "SyslogFacility": "LOCAL0",
   120      "RejoinAfterLeave": false,
   121      "CheckUpdateInterval": 300000000000,
   122      "ACLDatacenter": "",
   123      "ACLTTL": 30000000000,
   124      "ACLTTLRaw": "",
   125      "ACLDefaultPolicy": "allow",
   126      "ACLDownPolicy": "extend-cache",
   127      "Watches": null,
   128      "DisableRemoteExec": false,
   129      "DisableUpdateCheck": false,
   130      "DisableAnonymousSignature": false,
   131      "HTTPAPIResponseHeaders": null,
   132      "AtlasInfrastructure": "",
   133      "AtlasJoin": false,
   134      "Revision": "9a9cc9341bb487651a0399e3fc5e1e8a42e62dd9+CHANGES",
   135      "Version": "0.5.2",
   136      "VersionPrerelease": "",
   137      "UnixSockets": {
   138        "Usr": "",
   139        "Grp": "",
   140        "Perms": ""
   141      },
   142      "SessionTTLMin": 0,
   143      "SessionTTLMinRaw": ""
   144    },
   145    "Member": {
   146      "Name": "consul2",
   147      "Addr": "172.16.59.133",
   148      "Port": 8301,
   149      "Tags": {
   150        "build": "0.5.2:9a9cc934",
   151        "dc": "vagrant",
   152        "expect": "3",
   153        "port": "8300",
   154        "role": "consul",
   155        "vsn": "2"
   156      },
   157      "Status": 1,
   158      "ProtocolMin": 1,
   159      "ProtocolMax": 2,
   160      "ProtocolCur": 2,
   161      "DelegateMin": 2,
   162      "DelegateMax": 4,
   163      "DelegateCur": 4
   164    }
   165  }
   166  `
   167  
   168  // TestConsulFingerprint_UnexpectedResponse asserts that the Consul
   169  // fingerprinter does not panic when it encounters an unexpected response.
   170  // See https://github.com/hashicorp/nomad/issues/3326
   171  func TestConsulFingerprint_UnexpectedResponse(t *testing.T) {
   172  	assert := assert.New(t)
   173  	fp := NewConsulFingerprint(testlog.HCLogger(t))
   174  	node := &structs.Node{
   175  		Attributes: make(map[string]string),
   176  	}
   177  
   178  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   179  		w.Header().Set("Content-Type", "application/json")
   180  		fmt.Fprintln(w, "{}")
   181  	}))
   182  	defer ts.Close()
   183  
   184  	conf := config.DefaultConfig()
   185  	conf.ConsulConfig.Addr = strings.TrimPrefix(ts.URL, "http://")
   186  
   187  	request := &FingerprintRequest{Config: conf, Node: node}
   188  	var response FingerprintResponse
   189  	err := fp.Fingerprint(request, &response)
   190  	assert.Nil(err)
   191  
   192  	if !response.Detected {
   193  		t.Fatalf("expected response to be applicable")
   194  	}
   195  
   196  	attrs := []string{
   197  		"consul.server",
   198  		"consul.version",
   199  		"consul.revision",
   200  		"unique.consul.name",
   201  		"consul.datacenter",
   202  	}
   203  
   204  	for _, attr := range attrs {
   205  		if v, ok := response.Attributes[attr]; ok {
   206  			t.Errorf("unexpected node attribute %q with vlaue %q", attr, v)
   207  		}
   208  	}
   209  
   210  	if v, ok := response.Links["consul"]; ok {
   211  		t.Errorf("Unexpected link to consul: %v", v)
   212  	}
   213  }