Files
kata-containers/src/runtime/cli/release_test.go
Peng Tao 74192d179d runtime: fix static check errors
It turns out we have managed to break the static checker in many
difference places with the absence of static checker in github action.
Let's fix them while enabling static checker in github actions...

Signed-off-by: Peng Tao <bergwolf@hyper.sh>
2021-03-24 20:10:19 +08:00

520 lines
12 KiB
Go

// Copyright (c) 2020 Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0
//
package main
import (
"fmt"
"os"
"strings"
"testing"
"github.com/blang/semver"
"github.com/stretchr/testify/assert"
)
var currentSemver semver.Version
var expectedReleasesURL string
func init() {
var err error
currentSemver, err = semver.Make(version)
if err != nil {
panic(fmt.Sprintf("failed to create semver for testing: %v", err))
}
if currentSemver.Major == 1 {
expectedReleasesURL = kataLegacyReleaseURL
} else {
expectedReleasesURL = kataReleaseURL
}
}
func TestReleaseCmd(t *testing.T) {
assert := assert.New(t)
for i, value := range []ReleaseCmd{RelCmdCheck, RelCmdList} {
assert.True(value.Valid(), "test[%d]: %+v", i, value)
}
for i, value := range []int{-1, 2, 42, 255} {
invalid := ReleaseCmd(i)
assert.False(invalid.Valid(), "test[%d]: %+v", i, value)
}
}
func TestGetReleaseURL(t *testing.T) {
assert := assert.New(t)
const kata1xURL = "https://api.github.com/repos/kata-containers/runtime/releases"
const kata2xURL = "https://api.github.com/repos/kata-containers/kata-containers/releases"
type testData struct {
currentVersion string
expectError bool
expectedURL string
}
data := []testData{
{"0.0.0", true, ""},
{"1.0.0", false, kata1xURL},
{"1.9999.9999", false, kata1xURL},
{"2.0.0-alpha3", false, kata2xURL},
{"2.9999.9999", false, kata2xURL},
}
for i, d := range data {
msg := fmt.Sprintf("test[%d]: %+v", i, d)
ver, err := semver.Make(d.currentVersion)
msg = fmt.Sprintf("%s, version: %v, error: %v", msg, ver, err)
assert.NoError(err, msg)
url, err := getReleaseURL(ver)
if d.expectError {
assert.Error(err, msg)
} else {
assert.NoError(err, msg)
assert.Equal(url, d.expectedURL, msg)
assert.True(strings.HasPrefix(url, projectAPIURL), msg)
}
}
url, err := getReleaseURL(currentSemver)
assert.NoError(err)
assert.Equal(url, expectedReleasesURL)
assert.True(strings.HasPrefix(url, projectAPIURL))
}
func TestGetReleaseURLEnvVar(t *testing.T) {
assert := assert.New(t)
type testData struct {
envVarValue string
expectError bool
expectedURL string
}
data := []testData{
{"", false, expectedReleasesURL},
{"http://google.com", true, ""},
{"https://katacontainers.io", true, ""},
{"https://github.com/kata-containers/runtime/releases/latest", true, ""},
{"https://github.com/kata-containers/kata-containers/releases/latest", true, ""},
{expectedReleasesURL, false, expectedReleasesURL},
}
assert.Equal(os.Getenv("KATA_RELEASE_URL"), "")
defer os.Setenv("KATA_RELEASE_URL", "")
for i, d := range data {
msg := fmt.Sprintf("test[%d]: %+v", i, d)
err := os.Setenv("KATA_RELEASE_URL", d.envVarValue)
msg = fmt.Sprintf("%s, error: %v", msg, err)
assert.NoError(err, msg)
url, err := getReleaseURL(currentSemver)
if d.expectError {
assert.Errorf(err, msg)
} else {
assert.NoErrorf(err, msg)
assert.Equal(d.expectedURL, url, msg)
}
}
}
func TestMakeRelease(t *testing.T) {
assert := assert.New(t)
type testData struct {
release map[string]interface{}
expectError bool
expectedVersion string
expectedDetails releaseDetails
}
invalidRel1 := map[string]interface{}{"foo": 1}
invalidRel2 := map[string]interface{}{"foo": "bar"}
invalidRel3 := map[string]interface{}{"foo": true}
testDate := "2020-09-01T22:10:44Z"
testRelVersion := "1.2.3"
testFilename := "kata-static-1.12.0-alpha1-x86_64.tar.xz"
testURL := fmt.Sprintf("https://github.com/kata-containers/runtime/releases/download/%s/%s", testRelVersion, testFilename)
testSemver, err := semver.Make(testRelVersion)
assert.NoError(err)
invalidRelMissingVersion := map[string]interface{}{}
invalidRelInvalidVersion := map[string]interface{}{
"tag_name": "not.valid.semver",
}
invalidRelMissingAssets := map[string]interface{}{
"tag_name": testRelVersion,
"name": testFilename,
"assets": []interface{}{},
}
invalidAssetsMissingURL := []interface{}{
map[string]interface{}{
"name": testFilename,
"created_at": testDate,
},
}
invalidAssetsMissingFile := []interface{}{
map[string]interface{}{
"browser_download_url": testURL,
"created_at": testDate,
},
}
invalidAssetsMissingDate := []interface{}{
map[string]interface{}{
"name": testFilename,
"browser_download_url": testURL,
},
}
validAssets := []interface{}{
map[string]interface{}{
"browser_download_url": testURL,
"name": testFilename,
"created_at": testDate,
},
}
invalidRelAssetsMissingURL := map[string]interface{}{
"tag_name": testRelVersion,
"name": testFilename,
"assets": invalidAssetsMissingURL,
}
invalidRelAssetsMissingFile := map[string]interface{}{
"tag_name": testRelVersion,
"name": testFilename,
"assets": invalidAssetsMissingFile,
}
invalidRelAssetsMissingDate := map[string]interface{}{
"tag_name": testRelVersion,
"name": testFilename,
"assets": invalidAssetsMissingDate,
}
validRel := map[string]interface{}{
"tag_name": testRelVersion,
"name": testFilename,
"assets": validAssets,
}
validReleaseDetails := releaseDetails{
version: testSemver,
date: testDate,
url: testURL,
filename: testFilename,
}
data := []testData{
{invalidRel1, true, "", releaseDetails{}},
{invalidRel2, true, "", releaseDetails{}},
{invalidRel3, true, "", releaseDetails{}},
{invalidRelMissingVersion, true, "", releaseDetails{}},
{invalidRelInvalidVersion, true, "", releaseDetails{}},
{invalidRelMissingAssets, true, "", releaseDetails{}},
{invalidRelAssetsMissingURL, true, "", releaseDetails{}},
{invalidRelAssetsMissingFile, true, "", releaseDetails{}},
{invalidRelAssetsMissingDate, true, "", releaseDetails{}},
{validRel, false, testRelVersion, validReleaseDetails},
}
for i, d := range data {
msg := fmt.Sprintf("test[%d]: %+v", i, d)
version, details, err := makeRelease(d.release)
msg = fmt.Sprintf("%s, version: %v, details: %+v, error: %v", msg, version, details, err)
if d.expectError {
assert.Error(err, msg)
continue
}
assert.NoError(err, msg)
assert.Equal(d.expectedVersion, version, msg)
assert.Equal(d.expectedDetails, details, msg)
}
}
func TestReleaseURLIsValid(t *testing.T) {
assert := assert.New(t)
type testData struct {
url string
expectError bool
}
data := []testData{
{"", true},
{"foo", true},
{"foo bar", true},
{"https://google.com", true},
{projectAPIURL, true},
{kataLegacyReleaseURL, false},
{kataReleaseURL, false},
}
for i, d := range data {
msg := fmt.Sprintf("test[%d]: %+v", i, d)
err := releaseURLIsValid(d.url)
msg = fmt.Sprintf("%s, error: %v", msg, err)
if d.expectError {
assert.Error(err, msg)
} else {
assert.NoError(err, msg)
}
}
}
func TestDownloadURLIsValid(t *testing.T) {
assert := assert.New(t)
type testData struct {
url string
expectError bool
}
validKata1xDownload := "https://github.com/kata-containers/runtime/releases/download/1.12.0-alpha1/kata-static-1.12.0-alpha1-x86_64.tar.xz"
validKata2xDownload := "https://github.com/kata-containers/kata-containers/releases/download/2.0.0-alpha3/kata-static-2.0.0-alpha3-x86_64.tar.xz"
data := []testData{
{"", true},
{"foo", true},
{"foo bar", true},
{"https://google.com", true},
{projectURL, true},
{validKata1xDownload, false},
{validKata2xDownload, false},
}
for i, d := range data {
msg := fmt.Sprintf("test[%d]: %+v", i, d)
err := downloadURLIsValid(d.url)
msg = fmt.Sprintf("%s, error: %v", msg, err)
if d.expectError {
assert.Error(err, msg)
} else {
assert.NoError(err, msg)
}
}
}
func TestIgnoreRelease(t *testing.T) {
assert := assert.New(t)
type testData struct {
details releaseDetails
includeAll bool
expectIgnore bool
}
verWithoutPreRelease, err := semver.Make("2.0.0")
assert.NoError(err)
verWithPreRelease, err := semver.Make("2.0.0-alpha3")
assert.NoError(err)
relWithoutPreRelease := releaseDetails{
version: verWithoutPreRelease,
}
relWithPreRelease := releaseDetails{
version: verWithPreRelease,
}
data := []testData{
{relWithoutPreRelease, false, false},
{relWithoutPreRelease, true, false},
{relWithPreRelease, false, true},
{relWithPreRelease, true, false},
}
for i, d := range data {
msg := fmt.Sprintf("test[%d]: %+v", i, d)
ignore := ignoreRelease(d.details, d.includeAll)
if d.expectIgnore {
assert.True(ignore, msg)
} else {
assert.False(ignore, msg)
}
}
}
func TestGetReleases(t *testing.T) {
assert := assert.New(t)
url := "foo"
expectedErrMsg := "unsupported protocol scheme"
for _, includeAll := range []bool{true, false} {
euid := os.Geteuid()
msg := fmt.Sprintf("includeAll: %v, euid: %v", includeAll, euid)
_, _, err := getReleases(url, includeAll)
msg = fmt.Sprintf("%s, error: %v", msg, err)
assert.Error(err, msg)
if euid == 0 {
assert.Equal(err.Error(), errNoNetChecksAsRoot, msg)
} else {
assert.True(strings.Contains(err.Error(), expectedErrMsg), msg)
}
}
}
func TestFindNewestRelease(t *testing.T) {
assert := assert.New(t)
type testData struct {
versions []semver.Version
currentVer semver.Version
expectVersion semver.Version
expectError bool
expectAvailable bool
}
ver1, err := semver.Make("1.11.1")
assert.NoError(err)
ver2, err := semver.Make("1.11.3")
assert.NoError(err)
ver3, err := semver.Make("2.0.0")
assert.NoError(err)
data := []testData{
{[]semver.Version{}, semver.Version{}, semver.Version{}, true, false},
{[]semver.Version{}, ver1, semver.Version{}, true, false},
{[]semver.Version{ver1}, ver1, semver.Version{}, false, false},
{[]semver.Version{ver1}, ver2, semver.Version{}, false, false},
{[]semver.Version{ver2}, ver1, ver2, false, true},
{[]semver.Version{ver3}, ver1, ver3, false, true},
{[]semver.Version{ver2, ver3}, ver1, ver3, false, true},
{[]semver.Version{ver1, ver3}, ver2, ver3, false, true},
{[]semver.Version{ver1}, ver2, semver.Version{}, false, false},
}
for i, d := range data {
msg := fmt.Sprintf("test[%d]: %+v", i, d)
available, version, err := findNewestRelease(d.currentVer, d.versions)
msg = fmt.Sprintf("%s, available: %v, version: %v, error: %v", msg, available, version, err)
if d.expectError {
assert.Error(err, msg)
continue
}
assert.NoError(err, msg)
if !d.expectAvailable {
assert.False(available, msg)
continue
}
assert.Equal(d.expectVersion, version)
}
}
func TestGetNewReleaseType(t *testing.T) {
assert := assert.New(t)
type testData struct {
currentVer string
latestVer string
expectError bool
result string
}
data := []testData{
// Check build metadata (ignored for version comparisons)
{"2.0.0+build", "2.0.0", true, ""},
{"2.0.0+build-1", "2.0.0+build-2", true, ""},
{"1.12.0+build", "1.12.0", true, ""},
{"2.0.0-rc3+foo", "2.0.0", false, "major"},
{"2.0.0-rc3+foo", "2.0.0-rc4", false, "pre-release"},
{"1.12.0+foo", "1.13.0", false, "minor"},
{"1.12.0+build", "2.0.0", false, "major"},
{"1.12.0+build", "1.13.0", false, "minor"},
{"1.12.0-rc2+build", "1.12.1", false, "patch"},
{"1.12.0-rc2+build", "1.12.1-foo", false, "patch pre-release"},
{"1.12.0-rc4+wibble", "1.12.0", false, "major"},
{"2.0.0-alpha3", "1.0.0", true, ""},
{"1.0.0", "1.0.0", true, ""},
{"2.0.0", "1.0.0", true, ""},
{"1.0.0", "2.0.0", false, "major"},
{"2.0.0-alpha3", "2.0.0-alpha4", false, "pre-release"},
{"1.0.0", "2.0.0-alpha3", false, "major pre-release"},
{"1.0.0", "1.1.2", false, "minor"},
{"1.0.0", "1.1.2-pre2", false, "minor pre-release"},
{"1.0.0", "1.1.2-foo", false, "minor pre-release"},
{"1.0.0", "1.0.3", false, "patch"},
{"1.0.0-beta29", "1.0.0-beta30", false, "pre-release"},
{"1.0.0", "1.0.3-alpha99.1b", false, "patch pre-release"},
{"2.0.0-rc0", "2.0.0", false, "major"},
{"2.0.0-rc1", "2.0.0", false, "major"},
{"1.12.0-rc0", "1.12.0", false, "major"},
{"1.12.0-rc5", "1.12.0", false, "major"},
}
for i, d := range data {
msg := fmt.Sprintf("test[%d]: %+v", i, d)
current, err := semver.Make(d.currentVer)
msg = fmt.Sprintf("%s, current: %v, error: %v", msg, current, err)
assert.NoError(err, msg)
latest, err := semver.Make(d.latestVer)
assert.NoError(err, msg)
desc, err := getNewReleaseType(current, latest)
if d.expectError {
assert.Error(err, msg)
continue
}
assert.NoError(err, msg)
assert.Equal(d.result, desc, msg)
}
}