github.com/sl1pm4t/consul@v1.4.5-0.20190325224627-74c31c540f9c/api/prepared_query_test.go (about)

     1  package api
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  
     7  	"github.com/hashicorp/consul/testutil/retry"
     8  )
     9  
    10  func TestAPI_PreparedQuery(t *testing.T) {
    11  	t.Parallel()
    12  	c, s := makeClient(t)
    13  	defer s.Stop()
    14  
    15  	// Set up a node and a service.
    16  	reg := &CatalogRegistration{
    17  		Datacenter: "dc1",
    18  		Node:       "foobar",
    19  		Address:    "192.168.10.10",
    20  		TaggedAddresses: map[string]string{
    21  			"wan": "127.0.0.1",
    22  		},
    23  		NodeMeta: map[string]string{"somekey": "somevalue"},
    24  		Service: &AgentService{
    25  			ID:      "redis1",
    26  			Service: "redis",
    27  			Tags:    []string{"master", "v1"},
    28  			Meta:    map[string]string{"redis-version": "4.0"},
    29  			Port:    8000,
    30  		},
    31  	}
    32  
    33  	catalog := c.Catalog()
    34  	retry.Run(t, func(r *retry.R) {
    35  		if _, err := catalog.Register(reg, nil); err != nil {
    36  			r.Fatal(err)
    37  		}
    38  		if _, _, err := catalog.Node("foobar", nil); err != nil {
    39  			r.Fatal(err)
    40  		}
    41  	})
    42  
    43  	// Create a simple prepared query.
    44  	def := &PreparedQueryDefinition{
    45  		Name: "test",
    46  		Service: ServiceQuery{
    47  			Service:     "redis",
    48  			NodeMeta:    map[string]string{"somekey": "somevalue"},
    49  			ServiceMeta: map[string]string{"redis-version": "4.0"},
    50  		},
    51  	}
    52  
    53  	query := c.PreparedQuery()
    54  	var err error
    55  	def.ID, _, err = query.Create(def, nil)
    56  	if err != nil {
    57  		t.Fatalf("err: %s", err)
    58  	}
    59  
    60  	// Read it back.
    61  	defs, _, err := query.Get(def.ID, nil)
    62  	if err != nil {
    63  		t.Fatalf("err: %s", err)
    64  	}
    65  	if len(defs) != 1 || !reflect.DeepEqual(defs[0], def) {
    66  		t.Fatalf("bad: %v", defs)
    67  	}
    68  
    69  	// List them all.
    70  	defs, _, err = query.List(nil)
    71  	if err != nil {
    72  		t.Fatalf("err: %s", err)
    73  	}
    74  	if len(defs) != 1 || !reflect.DeepEqual(defs[0], def) {
    75  		t.Fatalf("bad: %v", defs)
    76  	}
    77  
    78  	// Make an update.
    79  	def.Name = "my-query"
    80  	_, err = query.Update(def, nil)
    81  	if err != nil {
    82  		t.Fatalf("err: %s", err)
    83  	}
    84  
    85  	// Read it back again to verify the update worked.
    86  	defs, _, err = query.Get(def.ID, nil)
    87  	if err != nil {
    88  		t.Fatalf("err: %s", err)
    89  	}
    90  	if len(defs) != 1 || !reflect.DeepEqual(defs[0], def) {
    91  		t.Fatalf("bad: %v", defs)
    92  	}
    93  
    94  	// Execute by ID.
    95  	results, _, err := query.Execute(def.ID, nil)
    96  	if err != nil {
    97  		t.Fatalf("err: %s", err)
    98  	}
    99  	if len(results.Nodes) != 1 || results.Nodes[0].Node.Node != "foobar" {
   100  		t.Fatalf("bad: %v", results)
   101  	}
   102  	if wan, ok := results.Nodes[0].Node.TaggedAddresses["wan"]; !ok || wan != "127.0.0.1" {
   103  		t.Fatalf("bad: %v", results)
   104  	}
   105  
   106  	// Execute by name.
   107  	results, _, err = query.Execute("my-query", nil)
   108  	if err != nil {
   109  		t.Fatalf("err: %s", err)
   110  	}
   111  	if len(results.Nodes) != 1 || results.Nodes[0].Node.Node != "foobar" {
   112  		t.Fatalf("bad: %v", results)
   113  	}
   114  	if wan, ok := results.Nodes[0].Node.TaggedAddresses["wan"]; !ok || wan != "127.0.0.1" {
   115  		t.Fatalf("bad: %v", results)
   116  	}
   117  	if results.Nodes[0].Node.Datacenter != "dc1" {
   118  		t.Fatalf("bad datacenter: %v", results)
   119  	}
   120  
   121  	// Add new node with failing health check.
   122  	reg2 := reg
   123  	reg2.Node = "failingnode"
   124  	reg2.Check = &AgentCheck{
   125  		Node:        "failingnode",
   126  		ServiceID:   "redis1",
   127  		ServiceName: "redis",
   128  		Name:        "failingcheck",
   129  		Status:      "critical",
   130  	}
   131  	retry.Run(t, func(r *retry.R) {
   132  		if _, err := catalog.Register(reg2, nil); err != nil {
   133  			r.Fatal(err)
   134  		}
   135  		if _, _, err := catalog.Node("failingnode", nil); err != nil {
   136  			r.Fatal(err)
   137  		}
   138  	})
   139  
   140  	// Execute by ID. Should return only healthy node.
   141  	results, _, err = query.Execute(def.ID, nil)
   142  	if err != nil {
   143  		t.Fatalf("err: %s", err)
   144  	}
   145  	if len(results.Nodes) != 1 || results.Nodes[0].Node.Node != "foobar" {
   146  		t.Fatalf("bad: %v", results)
   147  	}
   148  	if wan, ok := results.Nodes[0].Node.TaggedAddresses["wan"]; !ok || wan != "127.0.0.1" {
   149  		t.Fatalf("bad: %v", results)
   150  	}
   151  
   152  	// Update PQ with ignore rule for the failing check
   153  	def.Service.IgnoreCheckIDs = []string{"failingcheck"}
   154  	_, err = query.Update(def, nil)
   155  	if err != nil {
   156  		t.Fatalf("err: %s", err)
   157  	}
   158  
   159  	// Execute by ID. Should return BOTH nodes ignoring the failing check.
   160  	results, _, err = query.Execute(def.ID, nil)
   161  	if err != nil {
   162  		t.Fatalf("err: %s", err)
   163  	}
   164  	if len(results.Nodes) != 2 {
   165  		t.Fatalf("got %d nodes, want 2", len(results.Nodes))
   166  	}
   167  
   168  	// Delete it.
   169  	_, err = query.Delete(def.ID, nil)
   170  	if err != nil {
   171  		t.Fatalf("err: %s", err)
   172  	}
   173  
   174  	// Make sure there are no longer any queries.
   175  	defs, _, err = query.List(nil)
   176  	if err != nil {
   177  		t.Fatalf("err: %s", err)
   178  	}
   179  	if len(defs) != 0 {
   180  		t.Fatalf("bad: %v", defs)
   181  	}
   182  }