mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00

26 git mv mvcc wal auth etcdserver etcdmain proxy embed/ lease/ server 36 git mv go.mod go.sum server
196 lines
5.1 KiB
Go
196 lines
5.1 KiB
Go
// Copyright 2020 The etcd Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package membership
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/coreos/go-semver/semver"
|
|
"go.etcd.io/etcd/api/v3/version"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
func TestMustDetectDowngrade(t *testing.T) {
|
|
lv := semver.Must(semver.NewVersion(version.Version))
|
|
lv = &semver.Version{Major: lv.Major, Minor: lv.Minor}
|
|
oneMinorHigher := &semver.Version{Major: lv.Major, Minor: lv.Minor + 1}
|
|
oneMinorLower := &semver.Version{Major: lv.Major, Minor: lv.Minor - 1}
|
|
downgradeEnabledHigherVersion := &DowngradeInfo{Enabled: true, TargetVersion: oneMinorHigher.String()}
|
|
downgradeEnabledEqualVersion := &DowngradeInfo{Enabled: true, TargetVersion: lv.String()}
|
|
downgradeEnabledLowerVersion := &DowngradeInfo{Enabled: true, TargetVersion: oneMinorLower.String()}
|
|
downgradeDisabled := &DowngradeInfo{Enabled: false}
|
|
|
|
tests := []struct {
|
|
name string
|
|
clusterVersion *semver.Version
|
|
downgrade *DowngradeInfo
|
|
success bool
|
|
message string
|
|
}{
|
|
{
|
|
"Succeeded when downgrade is disabled and cluster version is nil",
|
|
nil,
|
|
downgradeDisabled,
|
|
true,
|
|
"",
|
|
},
|
|
{
|
|
"Succeeded when downgrade is disabled and cluster version is one minor lower",
|
|
oneMinorLower,
|
|
downgradeDisabled,
|
|
true,
|
|
"",
|
|
},
|
|
{
|
|
"Succeeded when downgrade is disabled and cluster version is server version",
|
|
lv,
|
|
downgradeDisabled,
|
|
true,
|
|
"",
|
|
},
|
|
{
|
|
"Failed when downgrade is disabled and server version is lower than determined cluster version ",
|
|
oneMinorHigher,
|
|
downgradeDisabled,
|
|
false,
|
|
"invalid downgrade; server version is lower than determined cluster version",
|
|
},
|
|
{
|
|
"Succeeded when downgrade is enabled and cluster version is nil",
|
|
nil,
|
|
downgradeEnabledEqualVersion,
|
|
true,
|
|
"",
|
|
},
|
|
{
|
|
"Failed when downgrade is enabled and server version is target version",
|
|
lv,
|
|
downgradeEnabledEqualVersion,
|
|
true,
|
|
"cluster is downgrading to target version",
|
|
},
|
|
{
|
|
"Succeeded when downgrade to lower version and server version is cluster version ",
|
|
lv,
|
|
downgradeEnabledLowerVersion,
|
|
false,
|
|
"invalid downgrade; server version is not allowed to join when downgrade is enabled",
|
|
},
|
|
{
|
|
"Failed when downgrade is enabled and local version is out of range and cluster version is nil",
|
|
nil,
|
|
downgradeEnabledHigherVersion,
|
|
false,
|
|
"invalid downgrade; server version is not allowed to join when downgrade is enabled",
|
|
},
|
|
|
|
{
|
|
"Failed when downgrade is enabled and local version is out of range",
|
|
lv,
|
|
downgradeEnabledHigherVersion,
|
|
false,
|
|
"invalid downgrade; server version is not allowed to join when downgrade is enabled",
|
|
},
|
|
}
|
|
|
|
if os.Getenv("DETECT_DOWNGRADE") != "" {
|
|
i := os.Getenv("DETECT_DOWNGRADE")
|
|
iint, _ := strconv.Atoi(i)
|
|
logPath := filepath.Join(os.TempDir(), fmt.Sprintf("test-log-must-detect-downgrade-%v", iint))
|
|
|
|
lcfg := zap.NewProductionConfig()
|
|
lcfg.OutputPaths = []string{logPath}
|
|
lcfg.ErrorOutputPaths = []string{logPath}
|
|
lg, _ := lcfg.Build()
|
|
|
|
mustDetectDowngrade(lg, tests[iint].clusterVersion, tests[iint].downgrade)
|
|
return
|
|
}
|
|
|
|
for i, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
logPath := filepath.Join(os.TempDir(), fmt.Sprintf("test-log-must-detect-downgrade-%d", i))
|
|
t.Log(logPath)
|
|
defer os.RemoveAll(logPath)
|
|
|
|
cmd := exec.Command(os.Args[0], "-test.run=TestMustDetectDowngrade")
|
|
cmd.Env = append(os.Environ(), fmt.Sprintf("DETECT_DOWNGRADE=%d", i))
|
|
if err := cmd.Start(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
errCmd := cmd.Wait()
|
|
|
|
data, err := ioutil.ReadFile(logPath)
|
|
if err == nil {
|
|
if !bytes.Contains(data, []byte(tt.message)) {
|
|
t.Errorf("Expected to find %v in log", tt.message)
|
|
}
|
|
} else {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if !tt.success {
|
|
e, ok := errCmd.(*exec.ExitError)
|
|
if !ok || e.Success() {
|
|
t.Errorf("Expected exit with status 1; Got %v", err)
|
|
}
|
|
}
|
|
|
|
if tt.success && errCmd != nil {
|
|
t.Errorf("Expected not failure; Got %v", errCmd)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsValidDowngrade(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
verFrom string
|
|
verTo string
|
|
result bool
|
|
}{
|
|
{
|
|
"Valid downgrade",
|
|
"3.5.0",
|
|
"3.4.0",
|
|
true,
|
|
},
|
|
{
|
|
"Invalid downgrade",
|
|
"3.5.2",
|
|
"3.3.0",
|
|
false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
res := isValidDowngrade(
|
|
semver.Must(semver.NewVersion(tt.verFrom)), semver.Must(semver.NewVersion(tt.verTo)))
|
|
if res != tt.result {
|
|
t.Errorf("Expected downgrade valid is %v; Got %v", tt.result, res)
|
|
}
|
|
})
|
|
}
|
|
}
|