github.com/outbrain/consul@v1.4.5/agent/user_event_test.go (about) 1 package agent 2 3 import ( 4 "strings" 5 "testing" 6 7 "github.com/hashicorp/consul/acl" 8 "github.com/hashicorp/consul/agent/structs" 9 "github.com/hashicorp/consul/testutil/retry" 10 ) 11 12 func TestValidateUserEventParams(t *testing.T) { 13 t.Parallel() 14 p := &UserEvent{} 15 err := validateUserEventParams(p) 16 if err == nil || err.Error() != "User event missing name" { 17 t.Fatalf("err: %v", err) 18 } 19 p.Name = "foo" 20 21 p.NodeFilter = "(" 22 err = validateUserEventParams(p) 23 if err == nil || !strings.Contains(err.Error(), "Invalid node filter") { 24 t.Fatalf("err: %v", err) 25 } 26 27 p.NodeFilter = "" 28 p.ServiceFilter = "(" 29 err = validateUserEventParams(p) 30 if err == nil || !strings.Contains(err.Error(), "Invalid service filter") { 31 t.Fatalf("err: %v", err) 32 } 33 34 p.ServiceFilter = "foo" 35 p.TagFilter = "(" 36 err = validateUserEventParams(p) 37 if err == nil || !strings.Contains(err.Error(), "Invalid tag filter") { 38 t.Fatalf("err: %v", err) 39 } 40 41 p.ServiceFilter = "" 42 p.TagFilter = "foo" 43 err = validateUserEventParams(p) 44 if err == nil || !strings.Contains(err.Error(), "tag filter without service") { 45 t.Fatalf("err: %v", err) 46 } 47 } 48 49 func TestShouldProcessUserEvent(t *testing.T) { 50 t.Parallel() 51 a := NewTestAgent(t, t.Name(), "") 52 defer a.Shutdown() 53 54 srv1 := &structs.NodeService{ 55 ID: "mysql", 56 Service: "mysql", 57 Tags: []string{"test", "foo", "bar", "master"}, 58 Port: 5000, 59 } 60 a.State.AddService(srv1, "") 61 62 p := &UserEvent{} 63 if !a.shouldProcessUserEvent(p) { 64 t.Fatalf("bad") 65 } 66 67 // Bad node name 68 p = &UserEvent{ 69 NodeFilter: "foobar", 70 } 71 if a.shouldProcessUserEvent(p) { 72 t.Fatalf("bad") 73 } 74 75 // Good node name 76 p = &UserEvent{ 77 NodeFilter: "^Node", 78 } 79 if !a.shouldProcessUserEvent(p) { 80 t.Fatalf("bad") 81 } 82 83 // Bad service name 84 p = &UserEvent{ 85 ServiceFilter: "foobar", 86 } 87 if a.shouldProcessUserEvent(p) { 88 t.Fatalf("bad") 89 } 90 91 // Good service name 92 p = &UserEvent{ 93 ServiceFilter: ".*sql", 94 } 95 if !a.shouldProcessUserEvent(p) { 96 t.Fatalf("bad") 97 } 98 99 // Bad tag name 100 p = &UserEvent{ 101 ServiceFilter: ".*sql", 102 TagFilter: "slave", 103 } 104 if a.shouldProcessUserEvent(p) { 105 t.Fatalf("bad") 106 } 107 108 // Good service name 109 p = &UserEvent{ 110 ServiceFilter: ".*sql", 111 TagFilter: "master", 112 } 113 if !a.shouldProcessUserEvent(p) { 114 t.Fatalf("bad") 115 } 116 } 117 118 func TestIngestUserEvent(t *testing.T) { 119 t.Parallel() 120 a := NewTestAgent(t, t.Name(), "") 121 defer a.Shutdown() 122 123 for i := 0; i < 512; i++ { 124 msg := &UserEvent{LTime: uint64(i), Name: "test"} 125 a.ingestUserEvent(msg) 126 if a.LastUserEvent() != msg { 127 t.Fatalf("bad: %#v", msg) 128 } 129 events := a.UserEvents() 130 131 expectLen := 256 132 if i < 256 { 133 expectLen = i + 1 134 } 135 if len(events) != expectLen { 136 t.Fatalf("bad: %d %d %d", i, expectLen, len(events)) 137 } 138 139 counter := i 140 for j := len(events) - 1; j >= 0; j-- { 141 if events[j].LTime != uint64(counter) { 142 t.Fatalf("bad: %#v", events) 143 } 144 counter-- 145 } 146 } 147 } 148 149 func TestFireReceiveEvent(t *testing.T) { 150 t.Parallel() 151 a := NewTestAgent(t, t.Name(), "") 152 defer a.Shutdown() 153 154 srv1 := &structs.NodeService{ 155 ID: "mysql", 156 Service: "mysql", 157 Tags: []string{"test", "foo", "bar", "master"}, 158 Port: 5000, 159 } 160 a.State.AddService(srv1, "") 161 162 p1 := &UserEvent{Name: "deploy", ServiceFilter: "web"} 163 err := a.UserEvent("dc1", "root", p1) 164 if err != nil { 165 t.Fatalf("err: %v", err) 166 } 167 168 p2 := &UserEvent{Name: "deploy"} 169 err = a.UserEvent("dc1", "root", p2) 170 if err != nil { 171 t.Fatalf("err: %v", err) 172 } 173 retry.Run(t, func(r *retry.R) { 174 if got, want := len(a.UserEvents()), 1; got != want { 175 r.Fatalf("got %d events want %d", got, want) 176 } 177 }) 178 179 last := a.LastUserEvent() 180 if last.ID != p2.ID { 181 t.Fatalf("bad: %#v", last) 182 } 183 } 184 185 func TestUserEventToken(t *testing.T) { 186 t.Parallel() 187 a := NewTestAgent(t, t.Name(), TestACLConfig()+` 188 acl_default_policy = "deny" 189 `) 190 defer a.Shutdown() 191 192 // Create an ACL token 193 args := structs.ACLRequest{ 194 Datacenter: "dc1", 195 Op: structs.ACLSet, 196 ACL: structs.ACL{ 197 Name: "User token", 198 Type: structs.ACLTokenTypeClient, 199 Rules: testEventPolicy, 200 }, 201 WriteRequest: structs.WriteRequest{Token: "root"}, 202 } 203 var token string 204 if err := a.RPC("ACL.Apply", &args, &token); err != nil { 205 t.Fatalf("err: %v", err) 206 } 207 208 type tcase struct { 209 name string 210 expect bool 211 } 212 cases := []tcase{ 213 {"foo", false}, 214 {"bar", false}, 215 {"baz", true}, 216 {"zip", false}, 217 } 218 for _, c := range cases { 219 event := &UserEvent{Name: c.name} 220 err := a.UserEvent("dc1", token, event) 221 allowed := !acl.IsErrPermissionDenied(err) 222 if allowed != c.expect { 223 t.Fatalf("bad: %#v result: %v", c, allowed) 224 } 225 } 226 } 227 228 const testEventPolicy = ` 229 event "foo" { 230 policy = "deny" 231 } 232 event "bar" { 233 policy = "read" 234 } 235 event "baz" { 236 policy = "write" 237 } 238 `