func TestACL_MultiDC_Found(t *testing.T) { dir1, s1 := testServerWithConfig(t, func(c *Config) { c.ACLDatacenter = "dc1" c.ACLMasterToken = "root" }) defer os.RemoveAll(dir1) defer s1.Shutdown() client := rpcClient(t, s1) defer client.Close() dir2, s2 := testServerWithConfig(t, func(c *Config) { c.Datacenter = "dc2" c.ACLDatacenter = "dc1" // Enable ACLs! }) defer os.RemoveAll(dir2) defer s2.Shutdown() // Try to join addr := fmt.Sprintf("127.0.0.1:%d", s1.config.SerfWANConfig.MemberlistConfig.BindPort) if _, err := s2.JoinWAN([]string{addr}); err != nil { t.Fatalf("err: %v", err) } testutil.WaitForLeader(t, client.Call, "dc1") testutil.WaitForLeader(t, client.Call, "dc2") // Create a new token arg := structs.ACLRequest{ Datacenter: "dc1", Op: structs.ACLSet, ACL: structs.ACL{ Name: "User token", Type: structs.ACLTypeClient, Rules: testACLPolicy, }, WriteRequest: structs.WriteRequest{Token: "root"}, } var id string if err := client.Call("ACL.Apply", &arg, &id); err != nil { t.Fatalf("err: %v", err) } // Token should resolve acl, err := s2.resolveToken(id) if err != nil { t.Fatalf("err: %v", err) } if acl == nil { t.Fatalf("missing acl") } // Check the policy if acl.KeyRead("bar") { t.Fatalf("unexpected read") } if !acl.KeyRead("foo/test") { t.Fatalf("unexpected failed read") } }
func TestCatalogListNodes_ConsistentRead_Fail(t *testing.T) { dir1, s1 := testServer(t) defer os.RemoveAll(dir1) defer s1.Shutdown() client1 := rpcClient(t, s1) defer client1.Close() dir2, s2 := testServerDCBootstrap(t, "dc1", false) defer os.RemoveAll(dir2) defer s2.Shutdown() client2 := rpcClient(t, s2) defer client2.Close() // Try to join addr := fmt.Sprintf("127.0.0.1:%d", s1.config.SerfLANConfig.MemberlistConfig.BindPort) if _, err := s2.JoinLAN([]string{addr}); err != nil { t.Fatalf("err: %v", err) } testutil.WaitForLeader(t, client1.Call, "dc1") testutil.WaitForLeader(t, client2.Call, "dc1") // Use the leader as the client, kill the follower var client *rpc.Client if s1.IsLeader() { client = client1 s2.Shutdown() } else { client = client2 s1.Shutdown() } args := structs.DCSpecificRequest{ Datacenter: "dc1", QueryOptions: structs.QueryOptions{RequireConsistent: true}, } var out structs.IndexedNodes if err := client.Call("Catalog.ListNodes", &args, &out); !strings.HasPrefix(err.Error(), "leadership lost") { t.Fatalf("err: %v", err) } if out.QueryMeta.LastContact != 0 { t.Fatalf("should not have a last contact time") } if out.QueryMeta.KnownLeader { t.Fatalf("should have no known leader") } }
func TestACL_Authority_Management(t *testing.T) { dir1, s1 := testServerWithConfig(t, func(c *Config) { c.ACLDatacenter = "dc1" // Enable ACLs! c.ACLMasterToken = "foobar" c.ACLDefaultPolicy = "deny" }) defer os.RemoveAll(dir1) defer s1.Shutdown() client := rpcClient(t, s1) defer client.Close() testutil.WaitForLeader(t, client.Call, "dc1") // Resolve the token acl, err := s1.resolveToken("foobar") if err != nil { t.Fatalf("err: %v", err) } if acl == nil { t.Fatalf("missing acl") } // Check the policy, should allow all if !acl.KeyRead("foo/test") { t.Fatalf("unexpected failed read") } }
func testRemoteExecGetSpec(t *testing.T, c *Config) { dir, agent := makeAgent(t, c) defer os.RemoveAll(dir) defer agent.Shutdown() testutil.WaitForLeader(t, agent.RPC, "dc1") event := &remoteExecEvent{ Prefix: "_rexec", Session: makeRexecSession(t, agent), } defer destroySession(t, agent, event.Session) spec := &remoteExecSpec{ Command: "uptime", Script: []byte("#!/bin/bash"), Wait: time.Second, } buf, err := json.Marshal(spec) if err != nil { t.Fatalf("err: %v", err) } key := "_rexec/" + event.Session + "/job" setKV(t, agent, key, buf) var out remoteExecSpec if !agent.remoteExecGetSpec(event, &out) { t.Fatalf("bad") } if !reflect.DeepEqual(spec, &out) { t.Fatalf("bad spec") } }
func TestDNS_ServiceLookup_TagPeriod(t *testing.T) { dir, srv := makeDNSServer(t) defer os.RemoveAll(dir) defer srv.agent.Shutdown() testutil.WaitForLeader(t, srv.agent.RPC, "dc1") // Register node args := &structs.RegisterRequest{ Datacenter: "dc1", Node: "foo", Address: "127.0.0.1", Service: &structs.NodeService{ Service: "db", Tags: []string{"v1.master"}, Port: 12345, }, } var out struct{} if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil { t.Fatalf("err: %v", err) } m := new(dns.Msg) m.SetQuestion("v1.master.db.service.consul.", dns.TypeSRV) c := new(dns.Client) addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS) in, _, err := c.Exchange(m, addr.String()) if err != nil { t.Fatalf("err: %v", err) } if len(in.Answer) != 1 { t.Fatalf("Bad: %#v", in) } srvRec, ok := in.Answer[0].(*dns.SRV) if !ok { t.Fatalf("Bad: %#v", in.Answer[0]) } if srvRec.Port != 12345 { t.Fatalf("Bad: %#v", srvRec) } if srvRec.Target != "foo.node.dc1.consul." { t.Fatalf("Bad: %#v", srvRec) } aRec, ok := in.Extra[0].(*dns.A) if !ok { t.Fatalf("Bad: %#v", in.Extra[0]) } if aRec.Hdr.Name != "foo.node.dc1.consul." { t.Fatalf("Bad: %#v", in.Extra[0]) } if aRec.A.String() != "127.0.0.1" { t.Fatalf("Bad: %#v", in.Extra[0]) } }
func TestCatalogNodes_Blocking(t *testing.T) { dir, srv := makeHTTPServer(t) defer os.RemoveAll(dir) defer srv.Shutdown() defer srv.agent.Shutdown() testutil.WaitForLeader(t, srv.agent.RPC, "dc1") // Register node args := &structs.DCSpecificRequest{ Datacenter: "dc1", } var out structs.IndexedNodes if err := srv.agent.RPC("Catalog.ListNodes", *args, &out); err != nil { t.Fatalf("err: %v", err) } // Do an update in a little while start := time.Now() go func() { time.Sleep(50 * time.Millisecond) args := &structs.RegisterRequest{ Datacenter: "dc1", Node: "foo", Address: "127.0.0.1", } var out struct{} if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil { t.Fatalf("err: %v", err) } }() // Do a blocking read req, err := http.NewRequest("GET", fmt.Sprintf("/v1/catalog/nodes?wait=60s&index=%d", out.Index), nil) if err != nil { t.Fatalf("err: %v", err) } resp := httptest.NewRecorder() obj, err := srv.CatalogNodes(resp, req) if err != nil { t.Fatalf("err: %v", err) } // Should block for a while if time.Now().Sub(start) < 50*time.Millisecond { t.Fatalf("too fast") } if idx := getIndex(t, resp); idx <= out.Index { t.Fatalf("bad: %v", idx) } nodes := obj.(structs.Nodes) if len(nodes) != 2 { t.Fatalf("bad: %v", obj) } }
func TestHealthServiceNodes(t *testing.T) { dir, srv := makeHTTPServer(t) defer os.RemoveAll(dir) defer srv.Shutdown() defer srv.agent.Shutdown() testutil.WaitForLeader(t, srv.agent.RPC, "dc1") req, err := http.NewRequest("GET", "/v1/health/service/consul?dc=dc1", nil) if err != nil { t.Fatalf("err: %v", err) } resp := httptest.NewRecorder() obj, err := srv.HealthServiceNodes(resp, req) if err != nil { t.Fatalf("err: %v", err) } assertIndex(t, resp) // Should be 1 health check for consul nodes := obj.(structs.CheckServiceNodes) if len(nodes) != 1 { t.Fatalf("bad: %v", obj) } }
func TestACLEndpoint_Apply_Denied(t *testing.T) { dir1, s1 := testServerWithConfig(t, func(c *Config) { c.ACLDatacenter = "dc1" }) defer os.RemoveAll(dir1) defer s1.Shutdown() client := rpcClient(t, s1) defer client.Close() testutil.WaitForLeader(t, client.Call, "dc1") arg := structs.ACLRequest{ Datacenter: "dc1", Op: structs.ACLSet, ACL: structs.ACL{ Name: "User token", Type: structs.ACLTypeClient, }, } var out string err := client.Call("ACL.Apply", &arg, &out) if err == nil || !strings.Contains(err.Error(), permissionDenied) { t.Fatalf("err: %v", err) } }
func TestCatalogDeregister(t *testing.T) { dir, srv := makeHTTPServer(t) defer os.RemoveAll(dir) defer srv.Shutdown() defer srv.agent.Shutdown() testutil.WaitForLeader(t, srv.agent.RPC, "dc1") // Register node req, err := http.NewRequest("GET", "/v1/catalog/deregister", nil) if err != nil { t.Fatalf("err: %v", err) } args := &structs.DeregisterRequest{ Node: "foo", } req.Body = encodeReq(args) obj, err := srv.CatalogDeregister(nil, req) if err != nil { t.Fatalf("err: %v", err) } res := obj.(bool) if res != true { t.Fatalf("bad: %v", res) } }
func TestHealthNodeChecks(t *testing.T) { dir, srv := makeHTTPServer(t) defer os.RemoveAll(dir) defer srv.Shutdown() defer srv.agent.Shutdown() testutil.WaitForLeader(t, srv.agent.RPC, "dc1") req, err := http.NewRequest("GET", fmt.Sprintf("/v1/health/node/%s?dc=dc1", srv.agent.config.NodeName), nil) if err != nil { t.Fatalf("err: %v", err) } resp := httptest.NewRecorder() obj, err := srv.HealthNodeChecks(resp, req) if err != nil { t.Fatalf("err: %v", err) } assertIndex(t, resp) // Should be 1 health check for the server nodes := obj.(structs.HealthChecks) if len(nodes) != 1 { t.Fatalf("bad: %v", obj) } }
func TestStatusLeader(t *testing.T) { dir1, s1 := testServer(t) defer os.RemoveAll(dir1) defer s1.Shutdown() client := rpcClient(t, s1) defer client.Close() arg := struct{}{} var leader string if err := client.Call("Status.Leader", arg, &leader); err != nil { t.Fatalf("err: %v", err) } if leader != "" { t.Fatalf("unexpected leader: %v", leader) } testutil.WaitForLeader(t, client.Call, "dc1") if err := client.Call("Status.Leader", arg, &leader); err != nil { t.Fatalf("err: %v", err) } if leader == "" { t.Fatalf("no leader") } }
func TestUiNodeInfo(t *testing.T) { dir, srv := makeHTTPServer(t) defer os.RemoveAll(dir) defer srv.Shutdown() defer srv.agent.Shutdown() testutil.WaitForLeader(t, srv.agent.RPC, "dc1") req, err := http.NewRequest("GET", fmt.Sprintf("/v1/internal/ui/node/%s", srv.agent.config.NodeName), nil) if err != nil { t.Fatalf("err: %v", err) } resp := httptest.NewRecorder() obj, err := srv.UINodeInfo(resp, req) if err != nil { t.Fatalf("err: %v", err) } assertIndex(t, resp) // Should be 1 node for the server node := obj.(*structs.NodeInfo) if node.Node != srv.agent.config.NodeName { t.Fatalf("bad: %v", node) } }
func TestInvalidateSession(t *testing.T) { dir1, s1 := testServer(t) defer os.RemoveAll(dir1) defer s1.Shutdown() testutil.WaitForLeader(t, s1.RPC, "dc1") // Create a session state := s1.fsm.State() state.EnsureNode(1, structs.Node{"foo", "127.0.0.1"}) session := &structs.Session{ ID: generateUUID(), Node: "foo", TTL: "10s", } if err := state.SessionCreate(100, session); err != nil { t.Fatalf("err: %v", err) } // This should cause a destroy s1.invalidateSession(session.ID) // Check it is gone _, sess, err := state.SessionGet(session.ID) if err != nil { t.Fatalf("err: %v", err) } if sess != nil { t.Fatalf("should destroy session") } }
func TestResetSessionTimer_NoTTL(t *testing.T) { dir1, s1 := testServer(t) defer os.RemoveAll(dir1) defer s1.Shutdown() testutil.WaitForLeader(t, s1.RPC, "dc1") // Create a session state := s1.fsm.State() state.EnsureNode(1, structs.Node{"foo", "127.0.0.1"}) session := &structs.Session{ ID: generateUUID(), Node: "foo", TTL: "0000s", } if err := state.SessionCreate(100, session); err != nil { t.Fatalf("err: %v", err) } // Reset the session timer err := s1.resetSessionTimer(session.ID, session) if err != nil { t.Fatalf("err: %v", err) } // Check that we have a timer _, ok := s1.sessionTimers[session.ID] if ok { t.Fatalf("should not have session timer") } }
func TestACLEndpoint_List(t *testing.T) { dir1, s1 := testServerWithConfig(t, func(c *Config) { c.ACLDatacenter = "dc1" c.ACLMasterToken = "root" }) defer os.RemoveAll(dir1) defer s1.Shutdown() client := rpcClient(t, s1) defer client.Close() testutil.WaitForLeader(t, client.Call, "dc1") ids := []string{} for i := 0; i < 5; i++ { arg := structs.ACLRequest{ Datacenter: "dc1", Op: structs.ACLSet, ACL: structs.ACL{ Name: "User token", Type: structs.ACLTypeClient, }, WriteRequest: structs.WriteRequest{Token: "root"}, } var out string if err := client.Call("ACL.Apply", &arg, &out); err != nil { t.Fatalf("err: %v", err) } ids = append(ids, out) } getR := structs.DCSpecificRequest{ Datacenter: "dc1", QueryOptions: structs.QueryOptions{Token: "root"}, } var acls structs.IndexedACLs if err := client.Call("ACL.List", &getR, &acls); err != nil { t.Fatalf("err: %v", err) } if acls.Index == 0 { t.Fatalf("Bad: %v", acls) } // 5 + anonymous + master if len(acls.ACLs) != 7 { t.Fatalf("Bad: %v", acls.ACLs) } for i := 0; i < len(acls.ACLs); i++ { s := acls.ACLs[i] if s.ID == anonymousToken || s.ID == "root" { continue } if !strContains(ids, s.ID) { t.Fatalf("bad: %v", s) } if s.Name != "User token" { t.Fatalf("bad: %v", s) } } }
func TestDNS_CaseInsensitiveNodeLookup(t *testing.T) { dir, srv := makeDNSServer(t) defer os.RemoveAll(dir) defer srv.agent.Shutdown() testutil.WaitForLeader(t, srv.agent.RPC, "dc1") // Register node args := &structs.RegisterRequest{ Datacenter: "dc1", Node: "Foo", Address: "127.0.0.1", } var out struct{} if err := srv.agent.RPC("Catalog.Register", args, &out); err != nil { t.Fatalf("err: %v", err) } m := new(dns.Msg) m.SetQuestion("fOO.node.dc1.consul.", dns.TypeANY) c := new(dns.Client) addr, _ := srv.agent.config.ClientListener("", srv.agent.config.Ports.DNS) in, _, err := c.Exchange(m, addr.String()) if err != nil { t.Fatalf("err: %v", err) } if len(in.Answer) != 1 { t.Fatalf("empty lookup: %#v", in) } }
func TestACLEndpoint_Apply_RootChange(t *testing.T) { dir1, s1 := testServerWithConfig(t, func(c *Config) { c.ACLDatacenter = "dc1" c.ACLMasterToken = "root" }) defer os.RemoveAll(dir1) defer s1.Shutdown() client := rpcClient(t, s1) defer client.Close() testutil.WaitForLeader(t, client.Call, "dc1") arg := structs.ACLRequest{ Datacenter: "dc1", Op: structs.ACLSet, ACL: structs.ACL{ ID: "manage", Name: "User token", Type: structs.ACLTypeClient, }, WriteRequest: structs.WriteRequest{Token: "root"}, } var out string err := client.Call("ACL.Apply", &arg, &out) if err == nil || !strings.Contains(err.Error(), "root ACL") { t.Fatalf("err: %v", err) } }
func TestCatalogRegister_ForwardDC(t *testing.T) { dir1, s1 := testServer(t) defer os.RemoveAll(dir1) defer s1.Shutdown() client := rpcClient(t, s1) defer client.Close() dir2, s2 := testServerDC(t, "dc2") defer os.RemoveAll(dir2) defer s2.Shutdown() // Try to join addr := fmt.Sprintf("127.0.0.1:%d", s1.config.SerfWANConfig.MemberlistConfig.BindPort) if _, err := s2.JoinWAN([]string{addr}); err != nil { t.Fatalf("err: %v", err) } testutil.WaitForLeader(t, client.Call, "dc2") arg := structs.RegisterRequest{ Datacenter: "dc2", // SHould forward through s1 Node: "foo", Address: "127.0.0.1", Service: &structs.NodeService{ Service: "db", Tags: []string{"master"}, Port: 8000, }, } var out struct{} if err := client.Call("Catalog.Register", &arg, &out); err != nil { t.Fatalf("err: %v", err) } }
func TestInternal_EventFire_Token(t *testing.T) { dir, srv := testServerWithConfig(t, func(c *Config) { c.ACLDatacenter = "dc1" c.ACLMasterToken = "root" c.ACLDownPolicy = "deny" c.ACLDefaultPolicy = "deny" }) defer os.RemoveAll(dir) defer srv.Shutdown() client := rpcClient(t, srv) defer client.Close() testutil.WaitForLeader(t, client.Call, "dc1") // No token is rejected event := structs.EventFireRequest{ Name: "foo", Datacenter: "dc1", Payload: []byte("nope"), } err := client.Call("Internal.EventFire", &event, nil) if err == nil || err.Error() != permissionDenied { t.Fatalf("bad: %s", err) } // Root token is allowed to fire event.Token = "root" err = client.Call("Internal.EventFire", &event, nil) if err != nil { t.Fatalf("err: %s", err) } }
func TestUiNodes(t *testing.T) { dir, srv := makeHTTPServer(t) defer os.RemoveAll(dir) defer srv.Shutdown() defer srv.agent.Shutdown() testutil.WaitForLeader(t, srv.agent.RPC, "dc1") req, err := http.NewRequest("GET", "/v1/internal/ui/nodes/dc1", nil) if err != nil { t.Fatalf("err: %v", err) } resp := httptest.NewRecorder() obj, err := srv.UINodes(resp, req) if err != nil { t.Fatalf("err: %v", err) } assertIndex(t, resp) // Should be 1 node for the server nodes := obj.(structs.NodeDump) if len(nodes) != 1 { t.Fatalf("bad: %v", obj) } }
func TestACLEndpoint_Apply(t *testing.T) { dir1, s1 := testServerWithConfig(t, func(c *Config) { c.ACLDatacenter = "dc1" c.ACLMasterToken = "root" }) defer os.RemoveAll(dir1) defer s1.Shutdown() client := rpcClient(t, s1) defer client.Close() testutil.WaitForLeader(t, client.Call, "dc1") arg := structs.ACLRequest{ Datacenter: "dc1", Op: structs.ACLSet, ACL: structs.ACL{ Name: "User token", Type: structs.ACLTypeClient, }, WriteRequest: structs.WriteRequest{Token: "root"}, } var out string if err := client.Call("ACL.Apply", &arg, &out); err != nil { t.Fatalf("err: %v", err) } id := out // Verify state := s1.fsm.State() _, s, err := state.ACLGet(out) if err != nil { t.Fatalf("err: %v", err) } if s == nil { t.Fatalf("should not be nil") } if s.ID != out { t.Fatalf("bad: %v", s) } if s.Name != "User token" { t.Fatalf("bad: %v", s) } // Do a delete arg.Op = structs.ACLDelete arg.ACL.ID = out if err := client.Call("ACL.Apply", &arg, &out); err != nil { t.Fatalf("err: %v", err) } // Verify _, s, err = state.ACLGet(id) if err != nil { t.Fatalf("err: %v", err) } if s != nil { t.Fatalf("bad: %v", s) } }
func TestKVSEndpoint_ListKeys(t *testing.T) { dir, srv := makeHTTPServer(t) defer os.RemoveAll(dir) defer srv.Shutdown() defer srv.agent.Shutdown() testutil.WaitForLeader(t, srv.agent.RPC, "dc1") keys := []string{ "bar", "baz", "foo/sub1", "foo/sub2", "zip", } for _, key := range keys { buf := bytes.NewBuffer([]byte("test")) req, err := http.NewRequest("PUT", "/v1/kv/"+key, buf) if err != nil { t.Fatalf("err: %v", err) } resp := httptest.NewRecorder() obj, err := srv.KVSEndpoint(resp, req) if err != nil { t.Fatalf("err: %v", err) } if res := obj.(bool); !res { t.Fatalf("should work") } } { // Get all the keys req, err := http.NewRequest("GET", "/v1/kv/?keys&seperator=/", nil) if err != nil { t.Fatalf("err: %v", err) } resp := httptest.NewRecorder() obj, err := srv.KVSEndpoint(resp, req) if err != nil { t.Fatalf("err: %v", err) } assertIndex(t, resp) res, ok := obj.([]string) if !ok { t.Fatalf("should work") } expect := []string{"bar", "baz", "foo/", "zip"} if !reflect.DeepEqual(res, expect) { t.Fatalf("bad: %v", res) } } }
func httpTestWithConfig(t *testing.T, f func(srv *HTTPServer), cb func(c *Config)) { dir, srv := makeHTTPServerWithConfig(t, cb) defer os.RemoveAll(dir) defer srv.Shutdown() defer srv.agent.Shutdown() testutil.WaitForLeader(t, srv.agent.RPC, "dc1") f(srv) }
func TestCatalogRegister_ForwardLeader(t *testing.T) { dir1, s1 := testServer(t) defer os.RemoveAll(dir1) defer s1.Shutdown() client1 := rpcClient(t, s1) defer client1.Close() dir2, s2 := testServer(t) defer os.RemoveAll(dir2) defer s2.Shutdown() client2 := rpcClient(t, s2) defer client2.Close() // Try to join addr := fmt.Sprintf("127.0.0.1:%d", s1.config.SerfLANConfig.MemberlistConfig.BindPort) if _, err := s2.JoinLAN([]string{addr}); err != nil { t.Fatalf("err: %v", err) } testutil.WaitForLeader(t, client1.Call, "dc1") testutil.WaitForLeader(t, client2.Call, "dc1") // Use the follower as the client var client *rpc.Client if !s1.IsLeader() { client = client1 } else { client = client2 } arg := structs.RegisterRequest{ Datacenter: "dc1", Node: "foo", Address: "127.0.0.1", Service: &structs.NodeService{ Service: "db", Tags: []string{"master"}, Port: 8000, }, } var out struct{} if err := client.Call("Catalog.Register", &arg, &out); err != nil { t.Fatalf("err: %v", err) } }
func TestSessionEndpoint_Apply(t *testing.T) { dir1, s1 := testServer(t) defer os.RemoveAll(dir1) defer s1.Shutdown() client := rpcClient(t, s1) defer client.Close() testutil.WaitForLeader(t, client.Call, "dc1") // Just add a node s1.fsm.State().EnsureNode(1, structs.Node{"foo", "127.0.0.1"}) arg := structs.SessionRequest{ Datacenter: "dc1", Op: structs.SessionCreate, Session: structs.Session{ Node: "foo", Name: "my-session", }, } var out string if err := client.Call("Session.Apply", &arg, &out); err != nil { t.Fatalf("err: %v", err) } id := out // Verify state := s1.fsm.State() _, s, err := state.SessionGet(out) if err != nil { t.Fatalf("err: %v", err) } if s == nil { t.Fatalf("should not be nil") } if s.Node != "foo" { t.Fatalf("bad: %v", s) } if s.Name != "my-session" { t.Fatalf("bad: %v", s) } // Do a delete arg.Op = structs.SessionDestroy arg.Session.ID = out if err := client.Call("Session.Apply", &arg, &out); err != nil { t.Fatalf("err: %v", err) } // Verify _, s, err = state.SessionGet(id) if err != nil { t.Fatalf("err: %v", err) } if s != nil { t.Fatalf("bad: %v", s) } }
func TestKVSEndpoint_List(t *testing.T) { dir1, s1 := testServer(t) defer os.RemoveAll(dir1) defer s1.Shutdown() client := rpcClient(t, s1) defer client.Close() testutil.WaitForLeader(t, client.Call, "dc1") keys := []string{ "/test/key1", "/test/key2", "/test/sub/key3", } for _, key := range keys { arg := structs.KVSRequest{ Datacenter: "dc1", Op: structs.KVSSet, DirEnt: structs.DirEntry{ Key: key, Flags: 1, }, } var out bool if err := client.Call("KVS.Apply", &arg, &out); err != nil { t.Fatalf("err: %v", err) } } getR := structs.KeyRequest{ Datacenter: "dc1", Key: "/test", } var dirent structs.IndexedDirEntries if err := client.Call("KVS.List", &getR, &dirent); err != nil { t.Fatalf("err: %v", err) } if dirent.Index == 0 { t.Fatalf("Bad: %v", dirent) } if len(dirent.Entries) != 3 { t.Fatalf("Bad: %v", dirent.Entries) } for i := 0; i < len(dirent.Entries); i++ { d := dirent.Entries[i] if d.Key != keys[i] { t.Fatalf("bad: %v", d) } if d.Flags != 1 { t.Fatalf("bad: %v", d) } if d.Value != nil { t.Fatalf("bad: %v", d) } } }
func TestSessionEndpoint_NodeSessions(t *testing.T) { dir1, s1 := testServer(t) defer os.RemoveAll(dir1) defer s1.Shutdown() client := rpcClient(t, s1) defer client.Close() testutil.WaitForLeader(t, client.Call, "dc1") s1.fsm.State().EnsureNode(1, structs.Node{"foo", "127.0.0.1"}) s1.fsm.State().EnsureNode(1, structs.Node{"bar", "127.0.0.1"}) ids := []string{} for i := 0; i < 10; i++ { arg := structs.SessionRequest{ Datacenter: "dc1", Op: structs.SessionCreate, Session: structs.Session{ Node: "bar", }, } if i < 5 { arg.Session.Node = "foo" } var out string if err := client.Call("Session.Apply", &arg, &out); err != nil { t.Fatalf("err: %v", err) } if i < 5 { ids = append(ids, out) } } getR := structs.NodeSpecificRequest{ Datacenter: "dc1", Node: "foo", } var sessions structs.IndexedSessions if err := client.Call("Session.NodeSessions", &getR, &sessions); err != nil { t.Fatalf("err: %v", err) } if sessions.Index == 0 { t.Fatalf("Bad: %v", sessions) } if len(sessions.Sessions) != 5 { t.Fatalf("Bad: %v", sessions.Sessions) } for i := 0; i < len(sessions.Sessions); i++ { s := sessions.Sessions[i] if !strContains(ids, s.ID) { t.Fatalf("bad: %v", s) } if s.Node != "foo" { t.Fatalf("bad: %v", s) } } }
func testHandleRemoteExec(t *testing.T, command string, expectedSubstring string, expectedReturnCode string) { dir, agent := makeAgent(t, nextConfig()) defer os.RemoveAll(dir) defer agent.Shutdown() testutil.WaitForLeader(t, agent.RPC, "dc1") event := &remoteExecEvent{ Prefix: "_rexec", Session: makeRexecSession(t, agent), } defer destroySession(t, agent, event.Session) spec := &remoteExecSpec{ Command: command, Wait: time.Second, } buf, err := json.Marshal(spec) if err != nil { t.Fatalf("err: %v", err) } key := "_rexec/" + event.Session + "/job" setKV(t, agent, key, buf) buf, err = json.Marshal(event) if err != nil { t.Fatalf("err: %v", err) } msg := &UserEvent{ ID: generateUUID(), Payload: buf, } // Handle the event... agent.handleRemoteExec(msg) // Verify we have an ack key = "_rexec/" + event.Session + "/" + agent.config.NodeName + "/ack" d := getKV(t, agent, key) if d == nil || d.Session != event.Session { t.Fatalf("bad ack: %#v", d) } // Verify we have output key = "_rexec/" + event.Session + "/" + agent.config.NodeName + "/out/00000" d = getKV(t, agent, key) if d == nil || d.Session != event.Session || !bytes.Contains(d.Value, []byte(expectedSubstring)) { t.Fatalf("bad output: %#v", d) } // Verify we have an exit code key = "_rexec/" + event.Session + "/" + agent.config.NodeName + "/exit" d = getKV(t, agent, key) if d == nil || d.Session != event.Session || string(d.Value) != expectedReturnCode { t.Fatalf("bad output: %#v", d) } }
func TestACLEndpoint_GetPolicy(t *testing.T) { dir1, s1 := testServerWithConfig(t, func(c *Config) { c.ACLDatacenter = "dc1" c.ACLMasterToken = "root" }) defer os.RemoveAll(dir1) defer s1.Shutdown() client := rpcClient(t, s1) defer client.Close() testutil.WaitForLeader(t, client.Call, "dc1") arg := structs.ACLRequest{ Datacenter: "dc1", Op: structs.ACLSet, ACL: structs.ACL{ Name: "User token", Type: structs.ACLTypeClient, }, WriteRequest: structs.WriteRequest{Token: "root"}, } var out string if err := client.Call("ACL.Apply", &arg, &out); err != nil { t.Fatalf("err: %v", err) } getR := structs.ACLPolicyRequest{ Datacenter: "dc1", ACL: out, } var acls structs.ACLPolicy if err := client.Call("ACL.GetPolicy", &getR, &acls); err != nil { t.Fatalf("err: %v", err) } if acls.Policy == nil { t.Fatalf("Bad: %v", acls) } if acls.TTL != 30*time.Second { t.Fatalf("bad: %v", acls) } // Do a conditional lookup with etag getR.ETag = acls.ETag var out2 structs.ACLPolicy if err := client.Call("ACL.GetPolicy", &getR, &out2); err != nil { t.Fatalf("err: %v", err) } if out2.Policy != nil { t.Fatalf("Bad: %v", out2) } if out2.TTL != 30*time.Second { t.Fatalf("bad: %v", out2) } }
func TestKVSEndpoint_ListKeys(t *testing.T) { dir1, s1 := testServer(t) defer os.RemoveAll(dir1) defer s1.Shutdown() client := rpcClient(t, s1) defer client.Close() testutil.WaitForLeader(t, client.Call, "dc1") keys := []string{ "/test/key1", "/test/key2", "/test/sub/key3", } for _, key := range keys { arg := structs.KVSRequest{ Datacenter: "dc1", Op: structs.KVSSet, DirEnt: structs.DirEntry{ Key: key, Flags: 1, }, } var out bool if err := client.Call("KVS.Apply", &arg, &out); err != nil { t.Fatalf("err: %v", err) } } getR := structs.KeyListRequest{ Datacenter: "dc1", Prefix: "/test/", Seperator: "/", } var dirent structs.IndexedKeyList if err := client.Call("KVS.ListKeys", &getR, &dirent); err != nil { t.Fatalf("err: %v", err) } if dirent.Index == 0 { t.Fatalf("Bad: %v", dirent) } if len(dirent.Keys) != 3 { t.Fatalf("Bad: %v", dirent.Keys) } if dirent.Keys[0] != "/test/key1" { t.Fatalf("Bad: %v", dirent.Keys) } if dirent.Keys[1] != "/test/key2" { t.Fatalf("Bad: %v", dirent.Keys) } if dirent.Keys[2] != "/test/sub/" { t.Fatalf("Bad: %v", dirent.Keys) } }