cosmovisor: tests -> test suites (#7887)
This commit is contained in:
parent
136f3ade88
commit
e564d7f5cc
|
@ -5,10 +5,18 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/suite"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestConfigPaths(t *testing.T) {
|
type argsTestSuite struct {
|
||||||
|
suite.Suite
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestArgsTestSuite(t *testing.T) {
|
||||||
|
suite.Run(t, new(argsTestSuite))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *argsTestSuite) TestConfigPaths() {
|
||||||
cases := map[string]struct {
|
cases := map[string]struct {
|
||||||
cfg Config
|
cfg Config
|
||||||
upgradeName string
|
upgradeName string
|
||||||
|
@ -32,23 +40,21 @@ func TestConfigPaths(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, tc := range cases {
|
for _, tc := range cases {
|
||||||
t.Run(name, func(t *testing.T) {
|
s.Require().Equal(tc.cfg.Root(), filepath.FromSlash(tc.expectRoot))
|
||||||
assert.Equal(t, tc.cfg.Root(), filepath.FromSlash(tc.expectRoot))
|
s.Require().Equal(tc.cfg.GenesisBin(), filepath.FromSlash(tc.expectGenesis))
|
||||||
assert.Equal(t, tc.cfg.GenesisBin(), filepath.FromSlash(tc.expectGenesis))
|
s.Require().Equal(tc.cfg.UpgradeBin(tc.upgradeName), filepath.FromSlash(tc.expectUpgrade))
|
||||||
assert.Equal(t, tc.cfg.UpgradeBin(tc.upgradeName), filepath.FromSlash(tc.expectUpgrade))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test validate
|
// Test validate
|
||||||
func TestValidate(t *testing.T) {
|
func (s *argsTestSuite) TestValidate() {
|
||||||
relPath := filepath.Join("testdata", "validate")
|
relPath := filepath.Join("testdata", "validate")
|
||||||
absPath, err := filepath.Abs(relPath)
|
absPath, err := filepath.Abs(relPath)
|
||||||
assert.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
testdata, err := filepath.Abs("testdata")
|
testdata, err := filepath.Abs("testdata")
|
||||||
assert.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
cases := map[string]struct {
|
cases := map[string]struct {
|
||||||
cfg Config
|
cfg Config
|
||||||
|
@ -84,28 +90,25 @@ func TestValidate(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, tc := range cases {
|
for _, tc := range cases {
|
||||||
t.Run(name, func(t *testing.T) {
|
err := tc.cfg.validate()
|
||||||
err := tc.cfg.validate()
|
if tc.valid {
|
||||||
if tc.valid {
|
s.Require().NoError(err)
|
||||||
assert.NoError(t, err)
|
} else {
|
||||||
} else {
|
s.Require().Error(err)
|
||||||
assert.Error(t, err)
|
}
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEnsureBin(t *testing.T) {
|
func (s *argsTestSuite) TestEnsureBin() {
|
||||||
relPath := filepath.Join("testdata", "validate")
|
relPath := filepath.Join("testdata", "validate")
|
||||||
absPath, err := filepath.Abs(relPath)
|
absPath, err := filepath.Abs(relPath)
|
||||||
assert.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
cfg := Config{Home: absPath, Name: "dummyd"}
|
cfg := Config{Home: absPath, Name: "dummyd"}
|
||||||
assert.NoError(t, cfg.validate())
|
s.Require().NoError(cfg.validate())
|
||||||
|
|
||||||
err = EnsureBinary(cfg.GenesisBin())
|
s.Require().NoError(EnsureBinary(cfg.GenesisBin()))
|
||||||
assert.NoError(t, err)
|
|
||||||
|
|
||||||
cases := map[string]struct {
|
cases := map[string]struct {
|
||||||
upgrade string
|
upgrade string
|
||||||
|
@ -117,14 +120,12 @@ func TestEnsureBin(t *testing.T) {
|
||||||
"no directory": {"foobarbaz", false},
|
"no directory": {"foobarbaz", false},
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, tc := range cases {
|
for _, tc := range cases {
|
||||||
t.Run(name, func(t *testing.T) {
|
err := EnsureBinary(cfg.UpgradeBin(tc.upgrade))
|
||||||
err := EnsureBinary(cfg.UpgradeBin(tc.upgrade))
|
if tc.hasBin {
|
||||||
if tc.hasBin {
|
s.Require().NoError(err)
|
||||||
assert.NoError(t, err)
|
} else {
|
||||||
} else {
|
s.Require().Error(err)
|
||||||
assert.Error(t, err)
|
}
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,110 +1,114 @@
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
package cosmovisor
|
package cosmovisor_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"os"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/suite"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/cosmovisor"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestLaunchProcess will try running the script a few times and watch upgrades work properly
|
type processTestSuite struct {
|
||||||
// and args are passed through
|
suite.Suite
|
||||||
func TestLaunchProcess(t *testing.T) {
|
}
|
||||||
home, err := copyTestData("validate")
|
|
||||||
cfg := &Config{Home: home, Name: "dummyd"}
|
|
||||||
require.NoError(t, err)
|
|
||||||
defer os.RemoveAll(home)
|
|
||||||
|
|
||||||
// should run the genesis binary and produce expected output
|
func TestProcessTestSuite(t *testing.T) {
|
||||||
var stdout, stderr bytes.Buffer
|
suite.Run(t, new(processTestSuite))
|
||||||
currentBin, err := cfg.CurrentBin()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
require.Equal(t, cfg.GenesisBin(), currentBin)
|
|
||||||
|
|
||||||
args := []string{"foo", "bar", "1234"}
|
|
||||||
doUpgrade, err := LaunchProcess(cfg, args, &stdout, &stderr)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.True(t, doUpgrade)
|
|
||||||
assert.Equal(t, "", stderr.String())
|
|
||||||
assert.Equal(t, "Genesis foo bar 1234\nUPGRADE \"chain2\" NEEDED at height: 49: {}\n", stdout.String())
|
|
||||||
|
|
||||||
// ensure this is upgraded now and produces new output
|
|
||||||
|
|
||||||
currentBin, err = cfg.CurrentBin()
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, cfg.UpgradeBin("chain2"), currentBin)
|
|
||||||
args = []string{"second", "run", "--verbose"}
|
|
||||||
stdout.Reset()
|
|
||||||
stderr.Reset()
|
|
||||||
doUpgrade, err = LaunchProcess(cfg, args, &stdout, &stderr)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.False(t, doUpgrade)
|
|
||||||
assert.Equal(t, "", stderr.String())
|
|
||||||
assert.Equal(t, "Chain 2 is live!\nArgs: second run --verbose\nFinished successfully\n", stdout.String())
|
|
||||||
|
|
||||||
// ended without other upgrade
|
|
||||||
require.Equal(t, cfg.UpgradeBin("chain2"), currentBin)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestLaunchProcess will try running the script a few times and watch upgrades work properly
|
// TestLaunchProcess will try running the script a few times and watch upgrades work properly
|
||||||
// and args are passed through
|
// and args are passed through
|
||||||
func TestLaunchProcessWithDownloads(t *testing.T) {
|
func (s *processTestSuite) TestLaunchProcess() {
|
||||||
|
home := copyTestData(s.T(), "validate")
|
||||||
|
cfg := &cosmovisor.Config{Home: home, Name: "dummyd"}
|
||||||
|
|
||||||
|
// should run the genesis binary and produce expected output
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
currentBin, err := cfg.CurrentBin()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
s.Require().Equal(cfg.GenesisBin(), currentBin)
|
||||||
|
|
||||||
|
args := []string{"foo", "bar", "1234"}
|
||||||
|
doUpgrade, err := cosmovisor.LaunchProcess(cfg, args, &stdout, &stderr)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().True(doUpgrade)
|
||||||
|
s.Require().Equal("", stderr.String())
|
||||||
|
s.Require().Equal("Genesis foo bar 1234\nUPGRADE \"chain2\" NEEDED at height: 49: {}\n", stdout.String())
|
||||||
|
|
||||||
|
// ensure this is upgraded now and produces new output
|
||||||
|
|
||||||
|
currentBin, err = cfg.CurrentBin()
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().Equal(cfg.UpgradeBin("chain2"), currentBin)
|
||||||
|
args = []string{"second", "run", "--verbose"}
|
||||||
|
stdout.Reset()
|
||||||
|
stderr.Reset()
|
||||||
|
doUpgrade, err = cosmovisor.LaunchProcess(cfg, args, &stdout, &stderr)
|
||||||
|
s.Require().NoError(err)
|
||||||
|
s.Require().False(doUpgrade)
|
||||||
|
s.Require().Equal("", stderr.String())
|
||||||
|
s.Require().Equal("Chain 2 is live!\nArgs: second run --verbose\nFinished successfully\n", stdout.String())
|
||||||
|
|
||||||
|
// ended without other upgrade
|
||||||
|
s.Require().Equal(cfg.UpgradeBin("chain2"), currentBin)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestLaunchProcess will try running the script a few times and watch upgrades work properly
|
||||||
|
// and args are passed through
|
||||||
|
func (s *processTestSuite) TestLaunchProcessWithDownloads() {
|
||||||
// this is a fun path
|
// this is a fun path
|
||||||
// genesis -> "chain2" = zip_binary
|
// genesis -> "chain2" = zip_binary
|
||||||
// zip_binary -> "chain3" = ref_zipped -> zip_directory
|
// zip_binary -> "chain3" = ref_zipped -> zip_directory
|
||||||
// zip_directory no upgrade
|
// zip_directory no upgrade
|
||||||
home, err := copyTestData("download")
|
home := copyTestData(s.T(), "download")
|
||||||
cfg := &Config{Home: home, Name: "autod", AllowDownloadBinaries: true}
|
cfg := &cosmovisor.Config{Home: home, Name: "autod", AllowDownloadBinaries: true}
|
||||||
require.NoError(t, err)
|
|
||||||
defer os.RemoveAll(home)
|
|
||||||
|
|
||||||
// should run the genesis binary and produce expected output
|
// should run the genesis binary and produce expected output
|
||||||
var stdout, stderr bytes.Buffer
|
var stdout, stderr bytes.Buffer
|
||||||
currentBin, err := cfg.CurrentBin()
|
currentBin, err := cfg.CurrentBin()
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
require.Equal(t, cfg.GenesisBin(), currentBin)
|
s.Require().Equal(cfg.GenesisBin(), currentBin)
|
||||||
args := []string{"some", "args"}
|
args := []string{"some", "args"}
|
||||||
doUpgrade, err := LaunchProcess(cfg, args, &stdout, &stderr)
|
doUpgrade, err := cosmovisor.LaunchProcess(cfg, args, &stdout, &stderr)
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
assert.True(t, doUpgrade)
|
s.Require().True(doUpgrade)
|
||||||
assert.Equal(t, "", stderr.String())
|
s.Require().Equal("", stderr.String())
|
||||||
assert.Equal(t, "Preparing auto-download some args\n"+`ERROR: UPGRADE "chain2" NEEDED at height: 49: {"binaries":{"linux/amd64":"https://github.com/cosmos/cosmos-sdk/raw/51249cb93130810033408934454841c98423ed4b/cosmovisor/testdata/repo/zip_binary/autod.zip?checksum=sha256:dc48829b4126ae95bc0db316c66d4e9da5f3db95e212665b6080638cca77e998"}} module=main`+"\n", stdout.String())
|
s.Require().Equal("Preparing auto-download some args\n"+`ERROR: UPGRADE "chain2" NEEDED at height: 49: {"binaries":{"linux/amd64":"https://github.com/cosmos/cosmos-sdk/raw/51249cb93130810033408934454841c98423ed4b/cosmovisor/testdata/repo/zip_binary/autod.zip?checksum=sha256:dc48829b4126ae95bc0db316c66d4e9da5f3db95e212665b6080638cca77e998"}} module=main`+"\n", stdout.String())
|
||||||
|
|
||||||
// ensure this is upgraded now and produces new output
|
// ensure this is upgraded now and produces new output
|
||||||
currentBin, err = cfg.CurrentBin()
|
currentBin, err = cfg.CurrentBin()
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
require.Equal(t, cfg.UpgradeBin("chain2"), currentBin)
|
s.Require().Equal(cfg.UpgradeBin("chain2"), currentBin)
|
||||||
args = []string{"run", "--fast"}
|
args = []string{"run", "--fast"}
|
||||||
stdout.Reset()
|
stdout.Reset()
|
||||||
stderr.Reset()
|
stderr.Reset()
|
||||||
doUpgrade, err = LaunchProcess(cfg, args, &stdout, &stderr)
|
doUpgrade, err = cosmovisor.LaunchProcess(cfg, args, &stdout, &stderr)
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
assert.True(t, doUpgrade)
|
s.Require().True(doUpgrade)
|
||||||
assert.Equal(t, "", stderr.String())
|
s.Require().Equal("", stderr.String())
|
||||||
assert.Equal(t, "Chain 2 from zipped binary link to referral\nArgs: run --fast\n"+`ERROR: UPGRADE "chain3" NEEDED at height: 936: https://github.com/cosmos/cosmos-sdk/raw/0eae1a50612b8bf803336d35055896fbddaa1ddd/cosmovisor/testdata/repo/ref_zipped?checksum=sha256:0a428575de718ed3cf0771c9687eefaf6f19359977eca4d94a0abd0e11ef8e64 module=main`+"\n", stdout.String())
|
s.Require().Equal("Chain 2 from zipped binary link to referral\nArgs: run --fast\n"+`ERROR: UPGRADE "chain3" NEEDED at height: 936: https://github.com/cosmos/cosmos-sdk/raw/0eae1a50612b8bf803336d35055896fbddaa1ddd/cosmovisor/testdata/repo/ref_zipped?checksum=sha256:0a428575de718ed3cf0771c9687eefaf6f19359977eca4d94a0abd0e11ef8e64 module=main`+"\n", stdout.String())
|
||||||
|
|
||||||
// ended with one more upgrade
|
// ended with one more upgrade
|
||||||
currentBin, err = cfg.CurrentBin()
|
currentBin, err = cfg.CurrentBin()
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
require.Equal(t, cfg.UpgradeBin("chain3"), currentBin)
|
s.Require().Equal(cfg.UpgradeBin("chain3"), currentBin)
|
||||||
// make sure this is the proper binary now....
|
// make sure this is the proper binary now....
|
||||||
args = []string{"end", "--halt"}
|
args = []string{"end", "--halt"}
|
||||||
stdout.Reset()
|
stdout.Reset()
|
||||||
stderr.Reset()
|
stderr.Reset()
|
||||||
doUpgrade, err = LaunchProcess(cfg, args, &stdout, &stderr)
|
doUpgrade, err = cosmovisor.LaunchProcess(cfg, args, &stdout, &stderr)
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
assert.False(t, doUpgrade)
|
s.Require().False(doUpgrade)
|
||||||
assert.Equal(t, "", stderr.String())
|
s.Require().Equal("", stderr.String())
|
||||||
assert.Equal(t, "Chain 2 from zipped directory\nArgs: end --halt\n", stdout.String())
|
s.Require().Equal("Chain 2 from zipped directory\nArgs: end --halt\n", stdout.String())
|
||||||
|
|
||||||
// and this doesn't upgrade
|
// and this doesn't upgrade
|
||||||
currentBin, err = cfg.CurrentBin()
|
currentBin, err = cfg.CurrentBin()
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
require.Equal(t, cfg.UpgradeBin("chain3"), currentBin)
|
s.Require().Equal(cfg.UpgradeBin("chain3"), currentBin)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
package cosmovisor
|
package cosmovisor_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/cosmos/cosmos-sdk/cosmovisor"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestWaitForInfo(t *testing.T) {
|
func TestWaitForInfo(t *testing.T) {
|
||||||
cases := map[string]struct {
|
cases := map[string]struct {
|
||||||
write []string
|
write []string
|
||||||
expectUpgrade *UpgradeInfo
|
expectUpgrade *cosmovisor.UpgradeInfo
|
||||||
expectErr bool
|
expectErr bool
|
||||||
}{
|
}{
|
||||||
"no match": {
|
"no match": {
|
||||||
|
@ -19,14 +21,14 @@ func TestWaitForInfo(t *testing.T) {
|
||||||
},
|
},
|
||||||
"match name with no info": {
|
"match name with no info": {
|
||||||
write: []string{"first line\n", `UPGRADE "myname" NEEDED at height: 123: `, "\nnext line\n"},
|
write: []string{"first line\n", `UPGRADE "myname" NEEDED at height: 123: `, "\nnext line\n"},
|
||||||
expectUpgrade: &UpgradeInfo{
|
expectUpgrade: &cosmovisor.UpgradeInfo{
|
||||||
Name: "myname",
|
Name: "myname",
|
||||||
Info: "",
|
Info: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"match name with info": {
|
"match name with info": {
|
||||||
write: []string{"first line\n", `UPGRADE "take2" NEEDED at height: 123: DownloadData here!`, "\nnext line\n"},
|
write: []string{"first line\n", `UPGRADE "take2" NEEDED at height: 123: DownloadData here!`, "\nnext line\n"},
|
||||||
expectUpgrade: &UpgradeInfo{
|
expectUpgrade: &cosmovisor.UpgradeInfo{
|
||||||
Name: "take2",
|
Name: "take2",
|
||||||
Info: "DownloadData",
|
Info: "DownloadData",
|
||||||
},
|
},
|
||||||
|
@ -42,20 +44,20 @@ func TestWaitForInfo(t *testing.T) {
|
||||||
go func() {
|
go func() {
|
||||||
for _, line := range tc.write {
|
for _, line := range tc.write {
|
||||||
n, err := w.Write([]byte(line))
|
n, err := w.Write([]byte(line))
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, len(line), n)
|
require.Equal(t, len(line), n)
|
||||||
}
|
}
|
||||||
w.Close()
|
w.Close()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// now scan the info
|
// now scan the info
|
||||||
info, err := WaitForUpdate(scan)
|
info, err := cosmovisor.WaitForUpdate(scan)
|
||||||
if tc.expectErr {
|
if tc.expectErr {
|
||||||
assert.Error(t, err)
|
require.Error(t, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, tc.expectUpgrade, info)
|
require.Equal(t, tc.expectUpgrade, info)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,12 +119,12 @@ func GetDownloadURL(info *UpgradeInfo) (string, error) {
|
||||||
var config UpgradeConfig
|
var config UpgradeConfig
|
||||||
|
|
||||||
if err := json.Unmarshal([]byte(doc), &config); err == nil {
|
if err := json.Unmarshal([]byte(doc), &config); err == nil {
|
||||||
url, ok := config.Binaries[osArch()]
|
url, ok := config.Binaries[OSArch()]
|
||||||
if !ok {
|
if !ok {
|
||||||
url, ok = config.Binaries["any"]
|
url, ok = config.Binaries["any"]
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", fmt.Errorf("cannot find binary for os/arch: neither %s, nor any", osArch())
|
return "", fmt.Errorf("cannot find binary for os/arch: neither %s, nor any", OSArch())
|
||||||
}
|
}
|
||||||
|
|
||||||
return url, nil
|
return url, nil
|
||||||
|
@ -133,7 +133,7 @@ func GetDownloadURL(info *UpgradeInfo) (string, error) {
|
||||||
return "", errors.New("upgrade info doesn't contain binary map")
|
return "", errors.New("upgrade info doesn't contain binary map")
|
||||||
}
|
}
|
||||||
|
|
||||||
func osArch() string {
|
func OSArch() string {
|
||||||
return fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
|
return fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,139 +1,138 @@
|
||||||
// +build linux
|
// +build linux
|
||||||
|
|
||||||
package cosmovisor
|
package cosmovisor_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
copy2 "github.com/otiai10/copy"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/otiai10/copy"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/cosmovisor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCurrentBin(t *testing.T) {
|
type upgradeTestSuite struct {
|
||||||
home, err := copyTestData("validate")
|
suite.Suite
|
||||||
require.NoError(t, err)
|
}
|
||||||
defer os.RemoveAll(home)
|
|
||||||
|
|
||||||
cfg := Config{Home: home, Name: "dummyd"}
|
func TestUpgradeTestSuite(t *testing.T) {
|
||||||
|
suite.Run(t, new(upgradeTestSuite))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *upgradeTestSuite) TestCurrentBin() {
|
||||||
|
home := copyTestData(s.T(), "validate")
|
||||||
|
cfg := cosmovisor.Config{Home: home, Name: "dummyd"}
|
||||||
|
|
||||||
currentBin, err := cfg.CurrentBin()
|
currentBin, err := cfg.CurrentBin()
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
assert.Equal(t, cfg.GenesisBin(), currentBin)
|
s.Require().Equal(cfg.GenesisBin(), currentBin)
|
||||||
|
|
||||||
// ensure we cannot set this to an invalid value
|
// ensure we cannot set this to an invalid value
|
||||||
for _, name := range []string{"missing", "nobin", "noexec"} {
|
for _, name := range []string{"missing", "nobin", "noexec"} {
|
||||||
err = cfg.SetCurrentUpgrade(name)
|
s.Require().Error(cfg.SetCurrentUpgrade(name), name)
|
||||||
require.Error(t, err, name)
|
|
||||||
|
|
||||||
currentBin, err := cfg.CurrentBin()
|
currentBin, err := cfg.CurrentBin()
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
assert.Equal(t, cfg.GenesisBin(), currentBin, name)
|
s.Require().Equal(cfg.GenesisBin(), currentBin, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// try a few times to make sure this can be reproduced
|
// try a few times to make sure this can be reproduced
|
||||||
for _, upgrade := range []string{"chain2", "chain3", "chain2"} {
|
for _, upgrade := range []string{"chain2", "chain3", "chain2"} {
|
||||||
// now set it to a valid upgrade and make sure CurrentBin is now set properly
|
// now set it to a valid upgrade and make sure CurrentBin is now set properly
|
||||||
err = cfg.SetCurrentUpgrade(upgrade)
|
err = cfg.SetCurrentUpgrade(upgrade)
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
// we should see current point to the new upgrade dir
|
// we should see current point to the new upgrade dir
|
||||||
currentBin, err := cfg.CurrentBin()
|
currentBin, err := cfg.CurrentBin()
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
assert.Equal(t, cfg.UpgradeBin(upgrade), currentBin)
|
s.Require().Equal(cfg.UpgradeBin(upgrade), currentBin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCurrentAlwaysSymlinkToDirectory(t *testing.T) {
|
func (s *upgradeTestSuite) TestCurrentAlwaysSymlinkToDirectory() {
|
||||||
home, err := copyTestData("validate")
|
home := copyTestData(s.T(), "validate")
|
||||||
require.NoError(t, err)
|
cfg := cosmovisor.Config{Home: home, Name: "dummyd"}
|
||||||
defer os.RemoveAll(home)
|
|
||||||
|
|
||||||
cfg := Config{Home: home, Name: "dummyd"}
|
|
||||||
|
|
||||||
currentBin, err := cfg.CurrentBin()
|
currentBin, err := cfg.CurrentBin()
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
assert.Equal(t, cfg.GenesisBin(), currentBin)
|
s.Require().Equal(cfg.GenesisBin(), currentBin)
|
||||||
assertCurrentLink(t, cfg, "genesis")
|
s.assertCurrentLink(cfg, "genesis")
|
||||||
|
|
||||||
err = cfg.SetCurrentUpgrade("chain2")
|
err = cfg.SetCurrentUpgrade("chain2")
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
currentBin, err = cfg.CurrentBin()
|
currentBin, err = cfg.CurrentBin()
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
assert.Equal(t, cfg.UpgradeBin("chain2"), currentBin)
|
s.Require().Equal(cfg.UpgradeBin("chain2"), currentBin)
|
||||||
assertCurrentLink(t, cfg, filepath.Join("upgrades", "chain2"))
|
s.assertCurrentLink(cfg, filepath.Join("upgrades", "chain2"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertCurrentLink(t *testing.T, cfg Config, target string) {
|
func (s *upgradeTestSuite) assertCurrentLink(cfg cosmovisor.Config, target string) {
|
||||||
link := filepath.Join(cfg.Root(), currentLink)
|
link := filepath.Join(cfg.Root(), "current")
|
||||||
// ensure this is a symlink
|
// ensure this is a symlink
|
||||||
info, err := os.Lstat(link)
|
info, err := os.Lstat(link)
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
require.Equal(t, os.ModeSymlink, info.Mode()&os.ModeSymlink)
|
s.Require().Equal(os.ModeSymlink, info.Mode()&os.ModeSymlink)
|
||||||
|
|
||||||
dest, err := os.Readlink(link)
|
dest, err := os.Readlink(link)
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
expected := filepath.Join(cfg.Root(), target)
|
expected := filepath.Join(cfg.Root(), target)
|
||||||
require.Equal(t, expected, dest)
|
s.Require().Equal(expected, dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: test with download (and test all download functions)
|
// TODO: test with download (and test all download functions)
|
||||||
func TestDoUpgradeNoDownloadUrl(t *testing.T) {
|
func (s *upgradeTestSuite) TestDoUpgradeNoDownloadUrl() {
|
||||||
home, err := copyTestData("validate")
|
home := copyTestData(s.T(), "validate")
|
||||||
require.NoError(t, err)
|
cfg := &cosmovisor.Config{Home: home, Name: "dummyd", AllowDownloadBinaries: true}
|
||||||
defer os.RemoveAll(home)
|
|
||||||
|
|
||||||
cfg := &Config{Home: home, Name: "dummyd", AllowDownloadBinaries: true}
|
|
||||||
|
|
||||||
currentBin, err := cfg.CurrentBin()
|
currentBin, err := cfg.CurrentBin()
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
assert.Equal(t, cfg.GenesisBin(), currentBin)
|
s.Require().Equal(cfg.GenesisBin(), currentBin)
|
||||||
|
|
||||||
// do upgrade ignores bad files
|
// do upgrade ignores bad files
|
||||||
for _, name := range []string{"missing", "nobin", "noexec"} {
|
for _, name := range []string{"missing", "nobin", "noexec"} {
|
||||||
info := &UpgradeInfo{Name: name}
|
info := &cosmovisor.UpgradeInfo{Name: name}
|
||||||
err = DoUpgrade(cfg, info)
|
err = cosmovisor.DoUpgrade(cfg, info)
|
||||||
require.Error(t, err, name)
|
s.Require().Error(err, name)
|
||||||
currentBin, err := cfg.CurrentBin()
|
currentBin, err := cfg.CurrentBin()
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
assert.Equal(t, cfg.GenesisBin(), currentBin, name)
|
s.Require().Equal(cfg.GenesisBin(), currentBin, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure it updates a few times
|
// make sure it updates a few times
|
||||||
for _, upgrade := range []string{"chain2", "chain3"} {
|
for _, upgrade := range []string{"chain2", "chain3"} {
|
||||||
// now set it to a valid upgrade and make sure CurrentBin is now set properly
|
// now set it to a valid upgrade and make sure CurrentBin is now set properly
|
||||||
info := &UpgradeInfo{Name: upgrade}
|
info := &cosmovisor.UpgradeInfo{Name: upgrade}
|
||||||
err = DoUpgrade(cfg, info)
|
err = cosmovisor.DoUpgrade(cfg, info)
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
// we should see current point to the new upgrade dir
|
// we should see current point to the new upgrade dir
|
||||||
upgradeBin := cfg.UpgradeBin(upgrade)
|
upgradeBin := cfg.UpgradeBin(upgrade)
|
||||||
currentBin, err := cfg.CurrentBin()
|
currentBin, err := cfg.CurrentBin()
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
assert.Equal(t, upgradeBin, currentBin)
|
s.Require().Equal(upgradeBin, currentBin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestOsArch(t *testing.T) {
|
func (s *upgradeTestSuite) TestOsArch() {
|
||||||
// all download tests will fail if we are not on linux...
|
// all download tests will fail if we are not on linux...
|
||||||
assert.Equal(t, "linux/amd64", osArch())
|
s.Require().Equal("linux/amd64", cosmovisor.OSArch())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetDownloadURL(t *testing.T) {
|
func (s *upgradeTestSuite) TestGetDownloadURL() {
|
||||||
// all download tests will fail if we are not on linux...
|
// all download tests will fail if we are not on linux...
|
||||||
ref, err := filepath.Abs(filepath.FromSlash("./testdata/repo/ref_zipped"))
|
ref, err := filepath.Abs(filepath.FromSlash("./testdata/repo/ref_zipped"))
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
badref, err := filepath.Abs(filepath.FromSlash("./testdata/repo/zip_binary/autod.zip"))
|
badref, err := filepath.Abs(filepath.FromSlash("./testdata/repo/zip_binary/autod.zip"))
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
cases := map[string]struct {
|
cases := map[string]struct {
|
||||||
info string
|
info string
|
||||||
|
@ -173,20 +172,18 @@ func TestGetDownloadURL(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, tc := range cases {
|
for _, tc := range cases {
|
||||||
t.Run(name, func(t *testing.T) {
|
url, err := cosmovisor.GetDownloadURL(&cosmovisor.UpgradeInfo{Info: tc.info})
|
||||||
url, err := GetDownloadURL(&UpgradeInfo{Info: tc.info})
|
if tc.isErr {
|
||||||
if tc.isErr {
|
s.Require().Error(err)
|
||||||
assert.Error(t, err)
|
} else {
|
||||||
} else {
|
s.Require().NoError(err)
|
||||||
assert.NoError(t, err)
|
s.Require().Equal(tc.url, url)
|
||||||
assert.Equal(t, tc.url, url)
|
}
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDownloadBinary(t *testing.T) {
|
func (s *upgradeTestSuite) TestDownloadBinary() {
|
||||||
cases := map[string]struct {
|
cases := map[string]struct {
|
||||||
url string
|
url string
|
||||||
canDownload bool
|
canDownload bool
|
||||||
|
@ -228,65 +225,55 @@ func TestDownloadBinary(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, tc := range cases {
|
for _, tc := range cases {
|
||||||
t.Run(name, func(t *testing.T) {
|
var err error
|
||||||
// make temp dir
|
// make temp dir
|
||||||
home, err := copyTestData("download")
|
home := copyTestData(s.T(), "download")
|
||||||
require.NoError(t, err)
|
|
||||||
defer os.RemoveAll(home)
|
|
||||||
|
|
||||||
cfg := &Config{
|
cfg := &cosmovisor.Config{
|
||||||
Home: home,
|
Home: home,
|
||||||
Name: "autod",
|
Name: "autod",
|
||||||
AllowDownloadBinaries: true,
|
AllowDownloadBinaries: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we have a relative path, make it absolute, but don't change eg. https://... urls
|
// if we have a relative path, make it absolute, but don't change eg. https://... urls
|
||||||
url := tc.url
|
url := tc.url
|
||||||
if strings.HasPrefix(url, "./") {
|
if strings.HasPrefix(url, "./") {
|
||||||
url, err = filepath.Abs(url)
|
url, err = filepath.Abs(url)
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
upgrade := "amazonas"
|
upgrade := "amazonas"
|
||||||
info := &UpgradeInfo{
|
info := &cosmovisor.UpgradeInfo{
|
||||||
Name: upgrade,
|
Name: upgrade,
|
||||||
Info: fmt.Sprintf(`{"binaries":{"%s": "%s"}}`, osArch(), url),
|
Info: fmt.Sprintf(`{"binaries":{"%s": "%s"}}`, cosmovisor.OSArch(), url),
|
||||||
}
|
}
|
||||||
|
|
||||||
err = DownloadBinary(cfg, info)
|
err = cosmovisor.DownloadBinary(cfg, info)
|
||||||
if !tc.canDownload {
|
if !tc.canDownload {
|
||||||
assert.Error(t, err)
|
s.Require().Error(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
err = EnsureBinary(cfg.UpgradeBin(upgrade))
|
err = cosmovisor.EnsureBinary(cfg.UpgradeBin(upgrade))
|
||||||
if tc.validBinary {
|
if tc.validBinary {
|
||||||
require.NoError(t, err)
|
s.Require().NoError(err)
|
||||||
} else {
|
} else {
|
||||||
require.Error(t, err)
|
s.Require().Error(err)
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// copyTestData will make a tempdir and then
|
// copyTestData will make a tempdir and then
|
||||||
// "cp -r" a subdirectory under testdata there
|
// "cp -r" a subdirectory under testdata there
|
||||||
// returns the directory (which can now be used as Config.Home) and modified safely
|
// returns the directory (which can now be used as Config.Home) and modified safely
|
||||||
func copyTestData(subdir string) (string, error) {
|
func copyTestData(t *testing.T, subdir string) string {
|
||||||
tmpdir, err := ioutil.TempDir("", "upgrade-manager-test")
|
t.Helper()
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("couldn't create temporary directory: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
src := filepath.Join("testdata", subdir)
|
tmpdir := t.TempDir()
|
||||||
|
|
||||||
err = copy2.Copy(src, tmpdir)
|
require.NoError(t, copy.Copy(filepath.Join("testdata", subdir), tmpdir))
|
||||||
if err != nil {
|
|
||||||
os.RemoveAll(tmpdir)
|
|
||||||
return "", fmt.Errorf("couldn't copy files: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return tmpdir, nil
|
return tmpdir
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue