mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Merge pull request #9712 from gyuho/unparam
*: test with "unparam", fix "v2v3" store stored get
This commit is contained in:
commit
67b1ff6724
@ -43,7 +43,7 @@ func NewDelCommand() *cobra.Command {
|
|||||||
|
|
||||||
// delCommandFunc executes the "del" command.
|
// delCommandFunc executes the "del" command.
|
||||||
func delCommandFunc(cmd *cobra.Command, args []string) {
|
func delCommandFunc(cmd *cobra.Command, args []string) {
|
||||||
key, opts := getDelOp(cmd, args)
|
key, opts := getDelOp(args)
|
||||||
ctx, cancel := commandCtx(cmd)
|
ctx, cancel := commandCtx(cmd)
|
||||||
resp, err := mustClientFromCmd(cmd).Delete(ctx, key, opts...)
|
resp, err := mustClientFromCmd(cmd).Delete(ctx, key, opts...)
|
||||||
cancel()
|
cancel()
|
||||||
@ -53,7 +53,7 @@ func delCommandFunc(cmd *cobra.Command, args []string) {
|
|||||||
display.Del(*resp)
|
display.Del(*resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDelOp(cmd *cobra.Command, args []string) (string, []clientv3.OpOption) {
|
func getDelOp(args []string) (string, []clientv3.OpOption) {
|
||||||
if len(args) == 0 || len(args) > 2 {
|
if len(args) == 0 || len(args) > 2 {
|
||||||
ExitWithError(ExitBadArgs, fmt.Errorf("del command needs one argument as key and an optional argument as range_end."))
|
ExitWithError(ExitBadArgs, fmt.Errorf("del command needs one argument as key and an optional argument as range_end."))
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ func NewGetCommand() *cobra.Command {
|
|||||||
|
|
||||||
// getCommandFunc executes the "get" command.
|
// getCommandFunc executes the "get" command.
|
||||||
func getCommandFunc(cmd *cobra.Command, args []string) {
|
func getCommandFunc(cmd *cobra.Command, args []string) {
|
||||||
key, opts := getGetOp(cmd, args)
|
key, opts := getGetOp(args)
|
||||||
ctx, cancel := commandCtx(cmd)
|
ctx, cancel := commandCtx(cmd)
|
||||||
resp, err := mustClientFromCmd(cmd).Get(ctx, key, opts...)
|
resp, err := mustClientFromCmd(cmd).Get(ctx, key, opts...)
|
||||||
cancel()
|
cancel()
|
||||||
@ -74,7 +74,7 @@ func getCommandFunc(cmd *cobra.Command, args []string) {
|
|||||||
display.Get(*resp)
|
display.Get(*resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getGetOp(cmd *cobra.Command, args []string) (string, []clientv3.OpOption) {
|
func getGetOp(args []string) (string, []clientv3.OpOption) {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
ExitWithError(ExitBadArgs, fmt.Errorf("range command needs arguments."))
|
ExitWithError(ExitBadArgs, fmt.Errorf("range command needs arguments."))
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ will store the content of the file to <key>.
|
|||||||
|
|
||||||
// putCommandFunc executes the "put" command.
|
// putCommandFunc executes the "put" command.
|
||||||
func putCommandFunc(cmd *cobra.Command, args []string) {
|
func putCommandFunc(cmd *cobra.Command, args []string) {
|
||||||
key, value, opts := getPutOp(cmd, args)
|
key, value, opts := getPutOp(args)
|
||||||
|
|
||||||
ctx, cancel := commandCtx(cmd)
|
ctx, cancel := commandCtx(cmd)
|
||||||
resp, err := mustClientFromCmd(cmd).Put(ctx, key, value, opts...)
|
resp, err := mustClientFromCmd(cmd).Put(ctx, key, value, opts...)
|
||||||
@ -76,7 +76,7 @@ func putCommandFunc(cmd *cobra.Command, args []string) {
|
|||||||
display.Put(*resp)
|
display.Put(*resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPutOp(cmd *cobra.Command, args []string) (string, string, []clientv3.OpOption) {
|
func getPutOp(args []string) (string, string, []clientv3.OpOption) {
|
||||||
if len(args) == 0 {
|
if len(args) == 0 {
|
||||||
ExitWithError(ExitBadArgs, fmt.Errorf("put command needs 1 argument and input from stdin or 2 arguments."))
|
ExitWithError(ExitBadArgs, fmt.Errorf("put command needs 1 argument and input from stdin or 2 arguments."))
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var txnInteractive bool
|
||||||
txnInteractive bool
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewTxnCommand returns the cobra command for "txn".
|
// NewTxnCommand returns the cobra command for "txn".
|
||||||
func NewTxnCommand() *cobra.Command {
|
func NewTxnCommand() *cobra.Command {
|
||||||
@ -129,17 +127,17 @@ func parseRequestUnion(line string) (*clientv3.Op, error) {
|
|||||||
|
|
||||||
put := NewPutCommand()
|
put := NewPutCommand()
|
||||||
put.Run = func(cmd *cobra.Command, args []string) {
|
put.Run = func(cmd *cobra.Command, args []string) {
|
||||||
key, value, opts := getPutOp(cmd, args)
|
key, value, opts := getPutOp(args)
|
||||||
opc <- clientv3.OpPut(key, value, opts...)
|
opc <- clientv3.OpPut(key, value, opts...)
|
||||||
}
|
}
|
||||||
get := NewGetCommand()
|
get := NewGetCommand()
|
||||||
get.Run = func(cmd *cobra.Command, args []string) {
|
get.Run = func(cmd *cobra.Command, args []string) {
|
||||||
key, opts := getGetOp(cmd, args)
|
key, opts := getGetOp(args)
|
||||||
opc <- clientv3.OpGet(key, opts...)
|
opc <- clientv3.OpGet(key, opts...)
|
||||||
}
|
}
|
||||||
del := NewDelCommand()
|
del := NewDelCommand()
|
||||||
del.Run = func(cmd *cobra.Command, args []string) {
|
del.Run = func(cmd *cobra.Command, args []string) {
|
||||||
key, opts := getDelOp(cmd, args)
|
key, opts := getDelOp(args)
|
||||||
opc <- clientv3.OpDelete(key, opts...)
|
opc <- clientv3.OpDelete(key, opts...)
|
||||||
}
|
}
|
||||||
cmds := &cobra.Command{SilenceErrors: true}
|
cmds := &cobra.Command{SilenceErrors: true}
|
||||||
|
@ -258,9 +258,9 @@ func parseWatchArgs(osArgs, commandArgs []string, envKey, envRange string, inter
|
|||||||
}
|
}
|
||||||
|
|
||||||
flagset := NewWatchCommand().Flags()
|
flagset := NewWatchCommand().Flags()
|
||||||
if err := flagset.Parse(watchArgs); err != nil {
|
if perr := flagset.Parse(watchArgs); perr != nil {
|
||||||
watchPrefix, watchRev, watchPrevKey = false, 0, false
|
watchPrefix, watchRev, watchPrevKey = false, 0, false
|
||||||
return nil, nil, err
|
return nil, nil, perr
|
||||||
}
|
}
|
||||||
pArgs := flagset.Args()
|
pArgs := flagset.Args()
|
||||||
|
|
||||||
@ -298,8 +298,8 @@ func parseWatchArgs(osArgs, commandArgs []string, envKey, envRange string, inter
|
|||||||
|
|
||||||
if interactive {
|
if interactive {
|
||||||
flagset := NewWatchCommand().Flags()
|
flagset := NewWatchCommand().Flags()
|
||||||
if err := flagset.Parse(argsWithSep); err != nil {
|
if perr := flagset.Parse(argsWithSep); perr != nil {
|
||||||
return nil, nil, err
|
return nil, nil, perr
|
||||||
}
|
}
|
||||||
watchArgs = flagset.Args()
|
watchArgs = flagset.Args()
|
||||||
|
|
||||||
|
@ -106,8 +106,8 @@ func startGateway(cmd *cobra.Command, args []string) {
|
|||||||
srvs.Endpoints = stripSchema(srvs.Endpoints)
|
srvs.Endpoints = stripSchema(srvs.Endpoints)
|
||||||
if len(srvs.SRVs) == 0 {
|
if len(srvs.SRVs) == 0 {
|
||||||
for _, ep := range srvs.Endpoints {
|
for _, ep := range srvs.Endpoints {
|
||||||
h, p, err := net.SplitHostPort(ep)
|
h, p, serr := net.SplitHostPort(ep)
|
||||||
if err != nil {
|
if serr != nil {
|
||||||
fmt.Printf("error parsing endpoint %q", ep)
|
fmt.Printf("error parsing endpoint %q", ep)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,10 @@ import (
|
|||||||
"github.com/coreos/etcd/etcdserver/api/v2http/httptypes"
|
"github.com/coreos/etcd/etcdserver/api/v2http/httptypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
func capabilityHandler(c api.Capability, fn func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
|
func authCapabilityHandler(fn func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
if !api.IsCapabilityEnabled(c) {
|
if !api.IsCapabilityEnabled(api.AuthCapability) {
|
||||||
notCapable(w, r, c)
|
notCapable(w, r, api.AuthCapability)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fn(w, r)
|
fn(w, r)
|
||||||
|
@ -155,7 +155,7 @@ func (h *keysHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
plog.Errorf("error writing event (%v)", err)
|
plog.Errorf("error writing event (%v)", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reportRequestCompleted(rr, resp, startTime)
|
reportRequestCompleted(rr, startTime)
|
||||||
case resp.Watcher != nil:
|
case resp.Watcher != nil:
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), defaultWatchTimeout)
|
ctx, cancel := context.WithTimeout(context.Background(), defaultWatchTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
@ -228,11 +228,11 @@ func writeNoAuth(lg *zap.Logger, w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleAuth(mux *http.ServeMux, sh *authHandler) {
|
func handleAuth(mux *http.ServeMux, sh *authHandler) {
|
||||||
mux.HandleFunc(authPrefix+"/roles", capabilityHandler(api.AuthCapability, sh.baseRoles))
|
mux.HandleFunc(authPrefix+"/roles", authCapabilityHandler(sh.baseRoles))
|
||||||
mux.HandleFunc(authPrefix+"/roles/", capabilityHandler(api.AuthCapability, sh.handleRoles))
|
mux.HandleFunc(authPrefix+"/roles/", authCapabilityHandler(sh.handleRoles))
|
||||||
mux.HandleFunc(authPrefix+"/users", capabilityHandler(api.AuthCapability, sh.baseUsers))
|
mux.HandleFunc(authPrefix+"/users", authCapabilityHandler(sh.baseUsers))
|
||||||
mux.HandleFunc(authPrefix+"/users/", capabilityHandler(api.AuthCapability, sh.handleUsers))
|
mux.HandleFunc(authPrefix+"/users/", authCapabilityHandler(sh.handleUsers))
|
||||||
mux.HandleFunc(authPrefix+"/enable", capabilityHandler(api.AuthCapability, sh.enableDisable))
|
mux.HandleFunc(authPrefix+"/enable", authCapabilityHandler(sh.enableDisable))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sh *authHandler) baseRoles(w http.ResponseWriter, r *http.Request) {
|
func (sh *authHandler) baseRoles(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -438,8 +438,8 @@ func TestGetUserGrantedWithNonexistingRole(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustAuthRequest(method, username, password string) *http.Request {
|
func mustAuthRequest(username, password string) *http.Request {
|
||||||
req, err := http.NewRequest(method, "path", strings.NewReader(""))
|
req, err := http.NewRequest(http.MethodGet, "path", strings.NewReader(""))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("Cannot make auth request: " + err.Error())
|
panic("Cannot make auth request: " + err.Error())
|
||||||
}
|
}
|
||||||
@ -447,8 +447,8 @@ func mustAuthRequest(method, username, password string) *http.Request {
|
|||||||
return req
|
return req
|
||||||
}
|
}
|
||||||
|
|
||||||
func unauthedRequest(method string) *http.Request {
|
func unauthedRequest() *http.Request {
|
||||||
req, err := http.NewRequest(method, "path", strings.NewReader(""))
|
req, err := http.NewRequest(http.MethodGet, "path", strings.NewReader(""))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("Cannot make request: " + err.Error())
|
panic("Cannot make request: " + err.Error())
|
||||||
}
|
}
|
||||||
@ -484,7 +484,7 @@ func TestPrefixAccess(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
key: "/foo",
|
key: "/foo",
|
||||||
req: mustAuthRequest("GET", "root", "good"),
|
req: mustAuthRequest("root", "good"),
|
||||||
store: &mockAuthStore{
|
store: &mockAuthStore{
|
||||||
users: map[string]*v2auth.User{
|
users: map[string]*v2auth.User{
|
||||||
"root": {
|
"root": {
|
||||||
@ -506,7 +506,7 @@ func TestPrefixAccess(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "/foo",
|
key: "/foo",
|
||||||
req: mustAuthRequest("GET", "user", "good"),
|
req: mustAuthRequest("user", "good"),
|
||||||
store: &mockAuthStore{
|
store: &mockAuthStore{
|
||||||
users: map[string]*v2auth.User{
|
users: map[string]*v2auth.User{
|
||||||
"user": {
|
"user": {
|
||||||
@ -534,7 +534,7 @@ func TestPrefixAccess(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "/foo",
|
key: "/foo",
|
||||||
req: mustAuthRequest("GET", "user", "good"),
|
req: mustAuthRequest("user", "good"),
|
||||||
store: &mockAuthStore{
|
store: &mockAuthStore{
|
||||||
users: map[string]*v2auth.User{
|
users: map[string]*v2auth.User{
|
||||||
"user": {
|
"user": {
|
||||||
@ -562,7 +562,7 @@ func TestPrefixAccess(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "/foo",
|
key: "/foo",
|
||||||
req: mustAuthRequest("GET", "user", "bad"),
|
req: mustAuthRequest("user", "bad"),
|
||||||
store: &mockAuthStore{
|
store: &mockAuthStore{
|
||||||
users: map[string]*v2auth.User{
|
users: map[string]*v2auth.User{
|
||||||
"user": {
|
"user": {
|
||||||
@ -590,7 +590,7 @@ func TestPrefixAccess(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "/foo",
|
key: "/foo",
|
||||||
req: mustAuthRequest("GET", "user", "good"),
|
req: mustAuthRequest("user", "good"),
|
||||||
store: &mockAuthStore{
|
store: &mockAuthStore{
|
||||||
users: map[string]*v2auth.User{},
|
users: map[string]*v2auth.User{},
|
||||||
err: errors.New("Not the user"),
|
err: errors.New("Not the user"),
|
||||||
@ -659,7 +659,7 @@ func TestPrefixAccess(t *testing.T) {
|
|||||||
// check access for multiple roles
|
// check access for multiple roles
|
||||||
{
|
{
|
||||||
key: "/foo",
|
key: "/foo",
|
||||||
req: mustAuthRequest("GET", "user", "good"),
|
req: mustAuthRequest("user", "good"),
|
||||||
store: &mockAuthStore{
|
store: &mockAuthStore{
|
||||||
users: map[string]*v2auth.User{
|
users: map[string]*v2auth.User{
|
||||||
"user": {
|
"user": {
|
||||||
@ -815,20 +815,20 @@ func TestUserFromClientCertificate(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
// non tls request
|
// non tls request
|
||||||
req: unauthedRequest("GET"),
|
req: unauthedRequest(),
|
||||||
userExists: false,
|
userExists: false,
|
||||||
store: witherror,
|
store: witherror,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// cert with cn of existing user
|
// cert with cn of existing user
|
||||||
req: tlsAuthedRequest(unauthedRequest("GET"), "user"),
|
req: tlsAuthedRequest(unauthedRequest(), "user"),
|
||||||
userExists: true,
|
userExists: true,
|
||||||
username: "user",
|
username: "user",
|
||||||
store: noerror,
|
store: noerror,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// cert with cn of non-existing user
|
// cert with cn of non-existing user
|
||||||
req: tlsAuthedRequest(unauthedRequest("GET"), "otheruser"),
|
req: tlsAuthedRequest(unauthedRequest(), "otheruser"),
|
||||||
userExists: false,
|
userExists: false,
|
||||||
store: witherror,
|
store: witherror,
|
||||||
},
|
},
|
||||||
@ -871,30 +871,30 @@ func TestUserFromBasicAuth(t *testing.T) {
|
|||||||
{
|
{
|
||||||
// valid user, valid pass
|
// valid user, valid pass
|
||||||
username: "user",
|
username: "user",
|
||||||
req: mustAuthRequest("GET", "user", "password"),
|
req: mustAuthRequest("user", "password"),
|
||||||
userExists: true,
|
userExists: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// valid user, bad pass
|
// valid user, bad pass
|
||||||
username: "user",
|
username: "user",
|
||||||
req: mustAuthRequest("GET", "user", "badpass"),
|
req: mustAuthRequest("user", "badpass"),
|
||||||
userExists: false,
|
userExists: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// valid user, no pass
|
// valid user, no pass
|
||||||
username: "user",
|
username: "user",
|
||||||
req: mustAuthRequest("GET", "user", ""),
|
req: mustAuthRequest("user", ""),
|
||||||
userExists: false,
|
userExists: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// missing user
|
// missing user
|
||||||
username: "missing",
|
username: "missing",
|
||||||
req: mustAuthRequest("GET", "missing", "badpass"),
|
req: mustAuthRequest("missing", "badpass"),
|
||||||
userExists: false,
|
userExists: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// no basic auth
|
// no basic auth
|
||||||
req: unauthedRequest("GET"),
|
req: unauthedRequest(),
|
||||||
userExists: false,
|
userExists: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ import (
|
|||||||
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/coreos/etcd/etcdserver"
|
|
||||||
"github.com/coreos/etcd/etcdserver/api/v2http/httptypes"
|
"github.com/coreos/etcd/etcdserver/api/v2http/httptypes"
|
||||||
"github.com/coreos/etcd/etcdserver/etcdserverpb"
|
"github.com/coreos/etcd/etcdserver/etcdserverpb"
|
||||||
"github.com/coreos/etcd/etcdserver/v2error"
|
"github.com/coreos/etcd/etcdserver/v2error"
|
||||||
@ -64,7 +63,7 @@ func reportRequestReceived(request etcdserverpb.Request) {
|
|||||||
incomingEvents.WithLabelValues(methodFromRequest(request)).Inc()
|
incomingEvents.WithLabelValues(methodFromRequest(request)).Inc()
|
||||||
}
|
}
|
||||||
|
|
||||||
func reportRequestCompleted(request etcdserverpb.Request, response etcdserver.Response, startTime time.Time) {
|
func reportRequestCompleted(request etcdserverpb.Request, startTime time.Time) {
|
||||||
method := methodFromRequest(request)
|
method := methodFromRequest(request)
|
||||||
successfulEventsHandlingTime.WithLabelValues(method).Observe(time.Since(startTime).Seconds())
|
successfulEventsHandlingTime.WithLabelValues(method).Observe(time.Since(startTime).Seconds())
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path"
|
"path"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -94,6 +95,9 @@ func (s *v2v3Store) Get(nodePath string, recursive, sorted bool) (*v2store.Event
|
|||||||
func (s *v2v3Store) getDir(nodePath string, recursive, sorted bool, rev int64) ([]*v2store.NodeExtern, error) {
|
func (s *v2v3Store) getDir(nodePath string, recursive, sorted bool, rev int64) ([]*v2store.NodeExtern, error) {
|
||||||
rootNodes, err := s.getDirDepth(nodePath, 1, rev)
|
rootNodes, err := s.getDirDepth(nodePath, 1, rev)
|
||||||
if err != nil || !recursive {
|
if err != nil || !recursive {
|
||||||
|
if sorted {
|
||||||
|
sort.Sort(v2store.NodeExterns(rootNodes))
|
||||||
|
}
|
||||||
return rootNodes, err
|
return rootNodes, err
|
||||||
}
|
}
|
||||||
nextNodes := rootNodes
|
nextNodes := rootNodes
|
||||||
@ -110,6 +114,10 @@ func (s *v2v3Store) getDir(nodePath string, recursive, sorted bool, rev int64) (
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if sorted {
|
||||||
|
sort.Sort(v2store.NodeExterns(rootNodes))
|
||||||
|
}
|
||||||
return rootNodes, nil
|
return rootNodes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ func (_ passwordStore) HashPassword(password string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *store) AllUsers() ([]string, error) {
|
func (s *store) AllUsers() ([]string, error) {
|
||||||
resp, err := s.requestResource("/users/", false, false)
|
resp, err := s.requestResource("/users/", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if e, ok := err.(*v2error.Error); ok {
|
if e, ok := err.(*v2error.Error); ok {
|
||||||
if e.ErrorCode == v2error.EcodeKeyNotFound {
|
if e.ErrorCode == v2error.EcodeKeyNotFound {
|
||||||
@ -245,7 +245,7 @@ func (s *store) DeleteUser(name string) error {
|
|||||||
if s.AuthEnabled() && name == "root" {
|
if s.AuthEnabled() && name == "root" {
|
||||||
return authErr(http.StatusForbidden, "Cannot delete root user while auth is enabled.")
|
return authErr(http.StatusForbidden, "Cannot delete root user while auth is enabled.")
|
||||||
}
|
}
|
||||||
_, err := s.deleteResource("/users/" + name)
|
err := s.deleteResource("/users/" + name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if e, ok := err.(*v2error.Error); ok {
|
if e, ok := err.(*v2error.Error); ok {
|
||||||
if e.ErrorCode == v2error.EcodeKeyNotFound {
|
if e.ErrorCode == v2error.EcodeKeyNotFound {
|
||||||
@ -293,7 +293,7 @@ func (s *store) UpdateUser(user User) (User, error) {
|
|||||||
|
|
||||||
func (s *store) AllRoles() ([]string, error) {
|
func (s *store) AllRoles() ([]string, error) {
|
||||||
nodes := []string{RootRoleName}
|
nodes := []string{RootRoleName}
|
||||||
resp, err := s.requestResource("/roles/", false, false)
|
resp, err := s.requestResource("/roles/", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if e, ok := err.(*v2error.Error); ok {
|
if e, ok := err.(*v2error.Error); ok {
|
||||||
if e.ErrorCode == v2error.EcodeKeyNotFound {
|
if e.ErrorCode == v2error.EcodeKeyNotFound {
|
||||||
@ -338,7 +338,7 @@ func (s *store) DeleteRole(name string) error {
|
|||||||
if name == RootRoleName {
|
if name == RootRoleName {
|
||||||
return authErr(http.StatusForbidden, "Cannot modify role %s: is root role.", name)
|
return authErr(http.StatusForbidden, "Cannot modify role %s: is root role.", name)
|
||||||
}
|
}
|
||||||
_, err := s.deleteResource("/roles/" + name)
|
err := s.deleteResource("/roles/" + name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if e, ok := err.(*v2error.Error); ok {
|
if e, ok := err.(*v2error.Error); ok {
|
||||||
if e.ErrorCode == v2error.EcodeKeyNotFound {
|
if e.ErrorCode == v2error.EcodeKeyNotFound {
|
||||||
@ -696,7 +696,7 @@ func attachRootRole(u User) User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *store) getUser(name string, quorum bool) (User, error) {
|
func (s *store) getUser(name string, quorum bool) (User, error) {
|
||||||
resp, err := s.requestResource("/users/"+name, false, quorum)
|
resp, err := s.requestResource("/users/"+name, quorum)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if e, ok := err.(*v2error.Error); ok {
|
if e, ok := err.(*v2error.Error); ok {
|
||||||
if e.ErrorCode == v2error.EcodeKeyNotFound {
|
if e.ErrorCode == v2error.EcodeKeyNotFound {
|
||||||
@ -721,7 +721,7 @@ func (s *store) getRole(name string, quorum bool) (Role, error) {
|
|||||||
if name == RootRoleName {
|
if name == RootRoleName {
|
||||||
return rootRole, nil
|
return rootRole, nil
|
||||||
}
|
}
|
||||||
resp, err := s.requestResource("/roles/"+name, false, quorum)
|
resp, err := s.requestResource("/roles/"+name, quorum)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if e, ok := err.(*v2error.Error); ok {
|
if e, ok := err.(*v2error.Error); ok {
|
||||||
if e.ErrorCode == v2error.EcodeKeyNotFound {
|
if e.ErrorCode == v2error.EcodeKeyNotFound {
|
||||||
|
@ -94,7 +94,7 @@ func (s *store) detectAuth() bool {
|
|||||||
if s.server == nil {
|
if s.server == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
value, err := s.requestResource("/enabled", false, false)
|
value, err := s.requestResource("/enabled", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if e, ok := err.(*v2error.Error); ok {
|
if e, ok := err.(*v2error.Error); ok {
|
||||||
if e.ErrorCode == v2error.EcodeKeyNotFound {
|
if e.ErrorCode == v2error.EcodeKeyNotFound {
|
||||||
@ -128,7 +128,7 @@ func (s *store) detectAuth() bool {
|
|||||||
return u
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *store) requestResource(res string, dir, quorum bool) (etcdserver.Response, error) {
|
func (s *store) requestResource(res string, quorum bool) (etcdserver.Response, error) {
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), s.timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), s.timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
p := path.Join(StorePermsPrefix, res)
|
p := path.Join(StorePermsPrefix, res)
|
||||||
@ -139,7 +139,7 @@ func (s *store) requestResource(res string, dir, quorum bool) (etcdserver.Respon
|
|||||||
rr := etcdserverpb.Request{
|
rr := etcdserverpb.Request{
|
||||||
Method: method,
|
Method: method,
|
||||||
Path: p,
|
Path: p,
|
||||||
Dir: dir,
|
Dir: false, // TODO: always false?
|
||||||
}
|
}
|
||||||
return s.server.Do(ctx, rr)
|
return s.server.Do(ctx, rr)
|
||||||
}
|
}
|
||||||
@ -171,19 +171,19 @@ func (s *store) setResource(res string, value interface{}, prevexist bool) (etcd
|
|||||||
return s.server.Do(ctx, rr)
|
return s.server.Do(ctx, rr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *store) deleteResource(res string) (etcdserver.Response, error) {
|
func (s *store) deleteResource(res string) error {
|
||||||
err := s.ensureAuthDirectories()
|
err := s.ensureAuthDirectories()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return etcdserver.Response{}, err
|
return err
|
||||||
}
|
}
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), s.timeout)
|
ctx, cancel := context.WithTimeout(context.Background(), s.timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
pex := true
|
pex := true
|
||||||
p := path.Join(StorePermsPrefix, res)
|
p := path.Join(StorePermsPrefix, res)
|
||||||
rr := etcdserverpb.Request{
|
_, err = s.server.Do(ctx, etcdserverpb.Request{
|
||||||
Method: "DELETE",
|
Method: "DELETE",
|
||||||
Path: p,
|
Path: p,
|
||||||
PrevExist: &pex,
|
PrevExist: &pex,
|
||||||
}
|
})
|
||||||
return s.server.Do(ctx, rr)
|
return err
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,9 @@ type v2TestStore struct {
|
|||||||
func (s *v2TestStore) Close() {}
|
func (s *v2TestStore) Close() {}
|
||||||
|
|
||||||
func newTestStore(t *testing.T, ns ...string) StoreCloser {
|
func newTestStore(t *testing.T, ns ...string) StoreCloser {
|
||||||
|
if len(ns) == 0 {
|
||||||
|
t.Logf("new v2 store with no namespace")
|
||||||
|
}
|
||||||
return &v2TestStore{v2store.New(ns...)}
|
return &v2TestStore{v2store.New(ns...)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,13 +71,13 @@ func (srv *Server) handleTesterRequest(req *rpcpb.Request) (resp *rpcpb.Response
|
|||||||
return srv.handle_SIGQUIT_ETCD_AND_REMOVE_DATA_AND_STOP_AGENT()
|
return srv.handle_SIGQUIT_ETCD_AND_REMOVE_DATA_AND_STOP_AGENT()
|
||||||
|
|
||||||
case rpcpb.Operation_BLACKHOLE_PEER_PORT_TX_RX:
|
case rpcpb.Operation_BLACKHOLE_PEER_PORT_TX_RX:
|
||||||
return srv.handle_BLACKHOLE_PEER_PORT_TX_RX()
|
return srv.handle_BLACKHOLE_PEER_PORT_TX_RX(), nil
|
||||||
case rpcpb.Operation_UNBLACKHOLE_PEER_PORT_TX_RX:
|
case rpcpb.Operation_UNBLACKHOLE_PEER_PORT_TX_RX:
|
||||||
return srv.handle_UNBLACKHOLE_PEER_PORT_TX_RX()
|
return srv.handle_UNBLACKHOLE_PEER_PORT_TX_RX(), nil
|
||||||
case rpcpb.Operation_DELAY_PEER_PORT_TX_RX:
|
case rpcpb.Operation_DELAY_PEER_PORT_TX_RX:
|
||||||
return srv.handle_DELAY_PEER_PORT_TX_RX()
|
return srv.handle_DELAY_PEER_PORT_TX_RX(), nil
|
||||||
case rpcpb.Operation_UNDELAY_PEER_PORT_TX_RX:
|
case rpcpb.Operation_UNDELAY_PEER_PORT_TX_RX:
|
||||||
return srv.handle_UNDELAY_PEER_PORT_TX_RX()
|
return srv.handle_UNDELAY_PEER_PORT_TX_RX(), nil
|
||||||
|
|
||||||
default:
|
default:
|
||||||
msg := fmt.Sprintf("operation not found (%v)", req.Operation)
|
msg := fmt.Sprintf("operation not found (%v)", req.Operation)
|
||||||
@ -719,7 +719,7 @@ func (srv *Server) handle_SIGQUIT_ETCD_AND_REMOVE_DATA_AND_STOP_AGENT() (*rpcpb.
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv *Server) handle_BLACKHOLE_PEER_PORT_TX_RX() (*rpcpb.Response, error) {
|
func (srv *Server) handle_BLACKHOLE_PEER_PORT_TX_RX() *rpcpb.Response {
|
||||||
for port, px := range srv.advertisePeerPortToProxy {
|
for port, px := range srv.advertisePeerPortToProxy {
|
||||||
srv.lg.Info("blackholing", zap.Int("peer-port", port))
|
srv.lg.Info("blackholing", zap.Int("peer-port", port))
|
||||||
px.BlackholeTx()
|
px.BlackholeTx()
|
||||||
@ -729,10 +729,10 @@ func (srv *Server) handle_BLACKHOLE_PEER_PORT_TX_RX() (*rpcpb.Response, error) {
|
|||||||
return &rpcpb.Response{
|
return &rpcpb.Response{
|
||||||
Success: true,
|
Success: true,
|
||||||
Status: "blackholed peer port tx/rx",
|
Status: "blackholed peer port tx/rx",
|
||||||
}, nil
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv *Server) handle_UNBLACKHOLE_PEER_PORT_TX_RX() (*rpcpb.Response, error) {
|
func (srv *Server) handle_UNBLACKHOLE_PEER_PORT_TX_RX() *rpcpb.Response {
|
||||||
for port, px := range srv.advertisePeerPortToProxy {
|
for port, px := range srv.advertisePeerPortToProxy {
|
||||||
srv.lg.Info("unblackholing", zap.Int("peer-port", port))
|
srv.lg.Info("unblackholing", zap.Int("peer-port", port))
|
||||||
px.UnblackholeTx()
|
px.UnblackholeTx()
|
||||||
@ -742,10 +742,10 @@ func (srv *Server) handle_UNBLACKHOLE_PEER_PORT_TX_RX() (*rpcpb.Response, error)
|
|||||||
return &rpcpb.Response{
|
return &rpcpb.Response{
|
||||||
Success: true,
|
Success: true,
|
||||||
Status: "unblackholed peer port tx/rx",
|
Status: "unblackholed peer port tx/rx",
|
||||||
}, nil
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv *Server) handle_DELAY_PEER_PORT_TX_RX() (*rpcpb.Response, error) {
|
func (srv *Server) handle_DELAY_PEER_PORT_TX_RX() *rpcpb.Response {
|
||||||
lat := time.Duration(srv.Tester.UpdatedDelayLatencyMs) * time.Millisecond
|
lat := time.Duration(srv.Tester.UpdatedDelayLatencyMs) * time.Millisecond
|
||||||
rv := time.Duration(srv.Tester.DelayLatencyMsRv) * time.Millisecond
|
rv := time.Duration(srv.Tester.DelayLatencyMsRv) * time.Millisecond
|
||||||
|
|
||||||
@ -767,10 +767,10 @@ func (srv *Server) handle_DELAY_PEER_PORT_TX_RX() (*rpcpb.Response, error) {
|
|||||||
return &rpcpb.Response{
|
return &rpcpb.Response{
|
||||||
Success: true,
|
Success: true,
|
||||||
Status: "delayed peer port tx/rx",
|
Status: "delayed peer port tx/rx",
|
||||||
}, nil
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv *Server) handle_UNDELAY_PEER_PORT_TX_RX() (*rpcpb.Response, error) {
|
func (srv *Server) handle_UNDELAY_PEER_PORT_TX_RX() *rpcpb.Response {
|
||||||
for port, px := range srv.advertisePeerPortToProxy {
|
for port, px := range srv.advertisePeerPortToProxy {
|
||||||
srv.lg.Info("undelaying", zap.Int("peer-port", port))
|
srv.lg.Info("undelaying", zap.Int("peer-port", port))
|
||||||
px.UndelayTx()
|
px.UndelayTx()
|
||||||
@ -780,5 +780,5 @@ func (srv *Server) handle_UNDELAY_PEER_PORT_TX_RX() (*rpcpb.Response, error) {
|
|||||||
return &rpcpb.Response{
|
return &rpcpb.Response{
|
||||||
Success: true,
|
Success: true,
|
||||||
Status: "undelayed peer port tx/rx",
|
Status: "undelayed peer port tx/rx",
|
||||||
}, nil
|
}
|
||||||
}
|
}
|
||||||
|
@ -493,9 +493,9 @@ func (clus *Cluster) sendOpWithResp(idx int, op rpcpb.Operation) (*rpcpb.Respons
|
|||||||
|
|
||||||
m, secure := clus.Members[idx], false
|
m, secure := clus.Members[idx], false
|
||||||
for _, cu := range m.Etcd.AdvertiseClientURLs {
|
for _, cu := range m.Etcd.AdvertiseClientURLs {
|
||||||
u, err := url.Parse(cu)
|
u, perr := url.Parse(cu)
|
||||||
if err != nil {
|
if perr != nil {
|
||||||
return nil, err
|
return nil, perr
|
||||||
}
|
}
|
||||||
if u.Scheme == "https" { // TODO: handle unix
|
if u.Scheme == "https" { // TODO: handle unix
|
||||||
secure = true
|
secure = true
|
||||||
|
@ -54,6 +54,7 @@ func newRunnerStresser(
|
|||||||
return &runnerStresser{
|
return &runnerStresser{
|
||||||
stype: stype,
|
stype: stype,
|
||||||
etcdClientEndpoint: ep,
|
etcdClientEndpoint: ep,
|
||||||
|
lg: lg,
|
||||||
cmdStr: cmdStr,
|
cmdStr: cmdStr,
|
||||||
args: args,
|
args: args,
|
||||||
rl: rl,
|
rl: rl,
|
||||||
|
@ -155,12 +155,12 @@ func (b *bridge) serveConn(bc *bridgeConn) {
|
|||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(2)
|
wg.Add(2)
|
||||||
go func() {
|
go func() {
|
||||||
b.ioCopy(bc, bc.out, bc.in)
|
b.ioCopy(bc.out, bc.in)
|
||||||
bc.close()
|
bc.close()
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
b.ioCopy(bc, bc.in, bc.out)
|
b.ioCopy(bc.in, bc.out)
|
||||||
bc.close()
|
bc.close()
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
@ -200,7 +200,7 @@ func (b *bridge) Unblackhole() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ref. https://github.com/golang/go/blob/master/src/io/io.go copyBuffer
|
// ref. https://github.com/golang/go/blob/master/src/io/io.go copyBuffer
|
||||||
func (b *bridge) ioCopy(bc *bridgeConn, dst io.Writer, src io.Reader) (err error) {
|
func (b *bridge) ioCopy(dst io.Writer, src io.Reader) (err error) {
|
||||||
buf := make([]byte, 32*1024)
|
buf := make([]byte, 32*1024)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
@ -450,10 +450,10 @@ func (c *cluster) waitLeader(t *testing.T, membs []*member) int {
|
|||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cluster) WaitNoLeader(t *testing.T) { c.waitNoLeader(t, c.Members) }
|
func (c *cluster) WaitNoLeader() { c.waitNoLeader(c.Members) }
|
||||||
|
|
||||||
// waitNoLeader waits until given members lose leader.
|
// waitNoLeader waits until given members lose leader.
|
||||||
func (c *cluster) waitNoLeader(t *testing.T, membs []*member) {
|
func (c *cluster) waitNoLeader(membs []*member) {
|
||||||
noLeader := false
|
noLeader := false
|
||||||
for !noLeader {
|
for !noLeader {
|
||||||
noLeader = true
|
noLeader = true
|
||||||
@ -992,7 +992,7 @@ func (m *member) Stop(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// checkLeaderTransition waits for leader transition, returning the new leader ID.
|
// checkLeaderTransition waits for leader transition, returning the new leader ID.
|
||||||
func checkLeaderTransition(t *testing.T, m *member, oldLead uint64) uint64 {
|
func checkLeaderTransition(m *member, oldLead uint64) uint64 {
|
||||||
interval := time.Duration(m.s.Cfg.TickMs) * time.Millisecond
|
interval := time.Duration(m.s.Cfg.TickMs) * time.Millisecond
|
||||||
for m.s.Lead() == 0 || (m.s.Lead() == oldLead) {
|
for m.s.Lead() == 0 || (m.s.Lead() == oldLead) {
|
||||||
time.Sleep(interval)
|
time.Sleep(interval)
|
||||||
|
@ -41,7 +41,7 @@ func TestNetworkPartition5MembersLeaderInMinority(t *testing.T) {
|
|||||||
injectPartition(t, minorityMembers, majorityMembers)
|
injectPartition(t, minorityMembers, majorityMembers)
|
||||||
|
|
||||||
// minority leader must be lost
|
// minority leader must be lost
|
||||||
clus.waitNoLeader(t, minorityMembers)
|
clus.waitNoLeader(minorityMembers)
|
||||||
|
|
||||||
// wait extra election timeout
|
// wait extra election timeout
|
||||||
time.Sleep(2 * majorityMembers[0].ElectionTimeout())
|
time.Sleep(2 * majorityMembers[0].ElectionTimeout())
|
||||||
@ -89,7 +89,7 @@ func testNetworkPartition5MembersLeaderInMajority(t *testing.T) error {
|
|||||||
injectPartition(t, majorityMembers, minorityMembers)
|
injectPartition(t, majorityMembers, minorityMembers)
|
||||||
|
|
||||||
// minority leader must be lost
|
// minority leader must be lost
|
||||||
clus.waitNoLeader(t, minorityMembers)
|
clus.waitNoLeader(minorityMembers)
|
||||||
|
|
||||||
// wait extra election timeout
|
// wait extra election timeout
|
||||||
time.Sleep(2 * majorityMembers[0].ElectionTimeout())
|
time.Sleep(2 * majorityMembers[0].ElectionTimeout())
|
||||||
@ -128,7 +128,7 @@ func TestNetworkPartition4Members(t *testing.T) {
|
|||||||
injectPartition(t, leaderPartition, followerPartition)
|
injectPartition(t, leaderPartition, followerPartition)
|
||||||
|
|
||||||
// no group has quorum, so leader must be lost in all members
|
// no group has quorum, so leader must be lost in all members
|
||||||
clus.WaitNoLeader(t)
|
clus.WaitNoLeader()
|
||||||
|
|
||||||
// recover network partition (bi-directional)
|
// recover network partition (bi-directional)
|
||||||
recoverPartition(t, leaderPartition, followerPartition)
|
recoverPartition(t, leaderPartition, followerPartition)
|
||||||
|
@ -41,7 +41,7 @@ func testMoveLeader(t *testing.T, auto bool) {
|
|||||||
for i := range clus.Members {
|
for i := range clus.Members {
|
||||||
if oldLeadIdx != i {
|
if oldLeadIdx != i {
|
||||||
go func(m *member) {
|
go func(m *member) {
|
||||||
idc <- checkLeaderTransition(t, m, oldLeadID)
|
idc <- checkLeaderTransition(m, oldLeadID)
|
||||||
}(clus.Members[i])
|
}(clus.Members[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -639,13 +639,13 @@ func TestKVRestore(t *testing.T) {
|
|||||||
kvss = append(kvss, r.KVs)
|
kvss = append(kvss, r.KVs)
|
||||||
}
|
}
|
||||||
|
|
||||||
keysBefore := readGaugeInt(&keysGauge)
|
keysBefore := readGaugeInt(keysGauge)
|
||||||
s.Close()
|
s.Close()
|
||||||
|
|
||||||
// ns should recover the the previous state from backend.
|
// ns should recover the the previous state from backend.
|
||||||
ns := NewStore(zap.NewExample(), b, &lease.FakeLessor{}, nil)
|
ns := NewStore(zap.NewExample(), b, &lease.FakeLessor{}, nil)
|
||||||
|
|
||||||
if keysRestore := readGaugeInt(&keysGauge); keysBefore != keysRestore {
|
if keysRestore := readGaugeInt(keysGauge); keysBefore != keysRestore {
|
||||||
t.Errorf("#%d: got %d key count, expected %d", i, keysRestore, keysBefore)
|
t.Errorf("#%d: got %d key count, expected %d", i, keysRestore, keysBefore)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -664,9 +664,9 @@ func TestKVRestore(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func readGaugeInt(g *prometheus.Gauge) int {
|
func readGaugeInt(g prometheus.Gauge) int {
|
||||||
ch := make(chan prometheus.Metric, 1)
|
ch := make(chan prometheus.Metric, 1)
|
||||||
keysGauge.Collect(ch)
|
g.Collect(ch)
|
||||||
m := <-ch
|
m := <-ch
|
||||||
mm := &dto.Metric{}
|
mm := &dto.Metric{}
|
||||||
m.Write(mm)
|
m.Write(mm)
|
||||||
|
@ -41,7 +41,7 @@ func NewListener(addr, scheme string, tlsinfo *TLSInfo) (l net.Listener, err err
|
|||||||
if l, err = newListener(addr, scheme); err != nil {
|
if l, err = newListener(addr, scheme); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return wrapTLS(addr, scheme, tlsinfo, l)
|
return wrapTLS(scheme, tlsinfo, l)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newListener(addr string, scheme string) (net.Listener, error) {
|
func newListener(addr string, scheme string) (net.Listener, error) {
|
||||||
@ -52,7 +52,7 @@ func newListener(addr string, scheme string) (net.Listener, error) {
|
|||||||
return net.Listen("tcp", addr)
|
return net.Listen("tcp", addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func wrapTLS(addr, scheme string, tlsinfo *TLSInfo, l net.Listener) (net.Listener, error) {
|
func wrapTLS(scheme string, tlsinfo *TLSInfo, l net.Listener) (net.Listener, error) {
|
||||||
if scheme != "https" && scheme != "unixs" {
|
if scheme != "https" && scheme != "unixs" {
|
||||||
return l, nil
|
return l, nil
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ func NewTimeoutListener(addr string, scheme string, tlsinfo *TLSInfo, rdtimeoutd
|
|||||||
rdtimeoutd: rdtimeoutd,
|
rdtimeoutd: rdtimeoutd,
|
||||||
wtimeoutd: wtimeoutd,
|
wtimeoutd: wtimeoutd,
|
||||||
}
|
}
|
||||||
if ln, err = wrapTLS(addr, scheme, tlsinfo, ln); err != nil {
|
if ln, err = wrapTLS(scheme, tlsinfo, ln); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return ln, nil
|
return ln, nil
|
||||||
|
@ -1182,7 +1182,7 @@ func TestCommit(t *testing.T) {
|
|||||||
storage.Append(tt.logs)
|
storage.Append(tt.logs)
|
||||||
storage.hardState = pb.HardState{Term: tt.smTerm}
|
storage.hardState = pb.HardState{Term: tt.smTerm}
|
||||||
|
|
||||||
sm := newTestRaft(1, []uint64{1}, 5, 1, storage)
|
sm := newTestRaft(1, []uint64{1}, 10, 2, storage)
|
||||||
for j := 0; j < len(tt.matches); j++ {
|
for j := 0; j < len(tt.matches); j++ {
|
||||||
sm.setProgress(uint64(j)+1, tt.matches[j], tt.matches[j]+1, false)
|
sm.setProgress(uint64(j)+1, tt.matches[j], tt.matches[j]+1, false)
|
||||||
}
|
}
|
||||||
@ -2733,7 +2733,7 @@ func TestRestoreWithLearner(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
storage := NewMemoryStorage()
|
storage := NewMemoryStorage()
|
||||||
sm := newTestLearnerRaft(3, []uint64{1, 2}, []uint64{3}, 10, 1, storage)
|
sm := newTestLearnerRaft(3, []uint64{1, 2}, []uint64{3}, 8, 2, storage)
|
||||||
if ok := sm.restore(s); !ok {
|
if ok := sm.restore(s); !ok {
|
||||||
t.Error("restore fail, want succeed")
|
t.Error("restore fail, want succeed")
|
||||||
}
|
}
|
||||||
@ -4070,16 +4070,16 @@ func (nw *network) drop(from, to uint64, perc float64) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (nw *network) cut(one, other uint64) {
|
func (nw *network) cut(one, other uint64) {
|
||||||
nw.drop(one, other, 1)
|
nw.drop(one, other, 2.0) // always drop
|
||||||
nw.drop(other, one, 1)
|
nw.drop(other, one, 2.0) // always drop
|
||||||
}
|
}
|
||||||
|
|
||||||
func (nw *network) isolate(id uint64) {
|
func (nw *network) isolate(id uint64) {
|
||||||
for i := 0; i < len(nw.peers); i++ {
|
for i := 0; i < len(nw.peers); i++ {
|
||||||
nid := uint64(i) + 1
|
nid := uint64(i) + 1
|
||||||
if nid != id {
|
if nid != id {
|
||||||
nw.drop(id, nid, 1.0)
|
nw.drop(id, nid, 1.0) // always drop
|
||||||
nw.drop(nid, id, 1.0)
|
nw.drop(nid, id, 1.0) // always drop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
13
test
13
test
@ -479,6 +479,18 @@ function unused_pass {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function unparam_pass {
|
||||||
|
if which unparam >/dev/null; then
|
||||||
|
unparamResult=$(unparam "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true)
|
||||||
|
if [ -n "${unparamResult}" ]; then
|
||||||
|
echo -e "unparam checking failed:\\n${unparamResult}"
|
||||||
|
exit 255
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Skipping unparam..."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
function staticcheck_pass {
|
function staticcheck_pass {
|
||||||
if which staticcheck >/dev/null; then
|
if which staticcheck >/dev/null; then
|
||||||
staticcheckResult=$(staticcheck "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true)
|
staticcheckResult=$(staticcheck "${STATIC_ANALYSIS_PATHS[@]}" 2>&1 || true)
|
||||||
@ -601,6 +613,7 @@ function fmt_pass {
|
|||||||
govet_shadow \
|
govet_shadow \
|
||||||
gosimple \
|
gosimple \
|
||||||
unused \
|
unused \
|
||||||
|
unparam \
|
||||||
staticcheck \
|
staticcheck \
|
||||||
unconvert \
|
unconvert \
|
||||||
ineffassign \
|
ineffassign \
|
||||||
|
@ -34,6 +34,7 @@ RUN ln -s /lib64/libhunspell-1.6.so /lib64/libhunspell.so
|
|||||||
RUN go get -v -u -tags spell github.com/chzchzchz/goword \
|
RUN go get -v -u -tags spell github.com/chzchzchz/goword \
|
||||||
&& go get -v -u github.com/coreos/license-bill-of-materials \
|
&& go get -v -u github.com/coreos/license-bill-of-materials \
|
||||||
&& go get -v -u github.com/mdempsky/unconvert \
|
&& go get -v -u github.com/mdempsky/unconvert \
|
||||||
|
&& go get -v -u mvdan.cc/unparam \
|
||||||
&& go get -v -u honnef.co/go/tools/cmd/gosimple \
|
&& go get -v -u honnef.co/go/tools/cmd/gosimple \
|
||||||
&& go get -v -u honnef.co/go/tools/cmd/unused \
|
&& go get -v -u honnef.co/go/tools/cmd/unused \
|
||||||
&& go get -v -u honnef.co/go/tools/cmd/staticcheck \
|
&& go get -v -u honnef.co/go/tools/cmd/staticcheck \
|
||||||
|
@ -251,7 +251,7 @@ func testCtlV2Backup(t *testing.T, snapCount int, v3 bool) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := etcdctlSet(epc1, "foo1", "bar"); err != nil {
|
if err := etcdctlSet(epc1, "foo1", "bar1"); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +276,7 @@ func testCtlV2Backup(t *testing.T, snapCount int, v3 bool) {
|
|||||||
epc2 := setupEtcdctlTest(t, &cfg2, false)
|
epc2 := setupEtcdctlTest(t, &cfg2, false)
|
||||||
|
|
||||||
// check if backup went through correctly
|
// check if backup went through correctly
|
||||||
if err := etcdctlGet(epc2, "foo1", "bar", false); err != nil {
|
if err := etcdctlGet(epc2, "foo1", "bar1", false); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,10 +292,10 @@ func testCtlV2Backup(t *testing.T, snapCount int, v3 bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if it can serve client requests
|
// check if it can serve client requests
|
||||||
if err := etcdctlSet(epc2, "foo2", "bar"); err != nil {
|
if err := etcdctlSet(epc2, "foo2", "bar2"); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := etcdctlGet(epc2, "foo2", "bar", false); err != nil {
|
if err := etcdctlGet(epc2, "foo2", "bar2", false); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -968,7 +968,7 @@ func authTestSnapshot(cx ctlCtx) {
|
|||||||
cx.user, cx.pass = "root", "root"
|
cx.user, cx.pass = "root", "root"
|
||||||
authSetupTestUser(cx)
|
authSetupTestUser(cx)
|
||||||
|
|
||||||
fpath := "test.snapshot"
|
fpath := "test-auth.snapshot"
|
||||||
defer os.RemoveAll(fpath)
|
defer os.RemoveAll(fpath)
|
||||||
|
|
||||||
// ordinary user cannot save a snapshot
|
// ordinary user cannot save a snapshot
|
||||||
|
@ -18,9 +18,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCtlV3Put(t *testing.T) { testCtl(t, putTest) }
|
func TestCtlV3Put(t *testing.T) { testCtl(t, putTest, withDialTimeout(7*time.Second)) }
|
||||||
func TestCtlV3PutNoTLS(t *testing.T) { testCtl(t, putTest, withCfg(configNoTLS)) }
|
func TestCtlV3PutNoTLS(t *testing.T) { testCtl(t, putTest, withCfg(configNoTLS)) }
|
||||||
func TestCtlV3PutClientTLS(t *testing.T) { testCtl(t, putTest, withCfg(configClientTLS)) }
|
func TestCtlV3PutClientTLS(t *testing.T) { testCtl(t, putTest, withCfg(configClientTLS)) }
|
||||||
func TestCtlV3PutClientAutoTLS(t *testing.T) { testCtl(t, putTest, withCfg(configClientAutoTLS)) }
|
func TestCtlV3PutClientAutoTLS(t *testing.T) { testCtl(t, putTest, withCfg(configClientAutoTLS)) }
|
||||||
|
@ -84,7 +84,7 @@ func testLock(cx ctlCtx) {
|
|||||||
if err = holder.Signal(os.Interrupt); err != nil {
|
if err = holder.Signal(os.Interrupt); err != nil {
|
||||||
cx.t.Fatal(err)
|
cx.t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err = closeWithTimeout(holder, time.Second); err != nil {
|
if err = closeWithTimeout(holder, 200*time.Millisecond+time.Second); err != nil {
|
||||||
cx.t.Fatal(err)
|
cx.t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ func snapshotTest(cx ctlCtx) {
|
|||||||
cx.t.Fatalf("snapshot: ctlV3Put error (%v)", err)
|
cx.t.Fatalf("snapshot: ctlV3Put error (%v)", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fpath := "test.snapshot"
|
fpath := "test1.snapshot"
|
||||||
defer os.RemoveAll(fpath)
|
defer os.RemoveAll(fpath)
|
||||||
|
|
||||||
if err = ctlV3SnapshotSave(cx, fpath); err != nil {
|
if err = ctlV3SnapshotSave(cx, fpath); err != nil {
|
||||||
@ -65,7 +65,7 @@ func snapshotTest(cx ctlCtx) {
|
|||||||
func TestCtlV3SnapshotCorrupt(t *testing.T) { testCtl(t, snapshotCorruptTest) }
|
func TestCtlV3SnapshotCorrupt(t *testing.T) { testCtl(t, snapshotCorruptTest) }
|
||||||
|
|
||||||
func snapshotCorruptTest(cx ctlCtx) {
|
func snapshotCorruptTest(cx ctlCtx) {
|
||||||
fpath := "test.snapshot"
|
fpath := "test2.snapshot"
|
||||||
defer os.RemoveAll(fpath)
|
defer os.RemoveAll(fpath)
|
||||||
|
|
||||||
if err := ctlV3SnapshotSave(cx, fpath); err != nil {
|
if err := ctlV3SnapshotSave(cx, fpath); err != nil {
|
||||||
@ -98,7 +98,7 @@ func snapshotCorruptTest(cx ctlCtx) {
|
|||||||
func TestCtlV3SnapshotStatusBeforeRestore(t *testing.T) { testCtl(t, snapshotStatusBeforeRestoreTest) }
|
func TestCtlV3SnapshotStatusBeforeRestore(t *testing.T) { testCtl(t, snapshotStatusBeforeRestoreTest) }
|
||||||
|
|
||||||
func snapshotStatusBeforeRestoreTest(cx ctlCtx) {
|
func snapshotStatusBeforeRestoreTest(cx ctlCtx) {
|
||||||
fpath := "test.snapshot"
|
fpath := "test3.snapshot"
|
||||||
defer os.RemoveAll(fpath)
|
defer os.RemoveAll(fpath)
|
||||||
|
|
||||||
if err := ctlV3SnapshotSave(cx, fpath); err != nil {
|
if err := ctlV3SnapshotSave(cx, fpath); err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user