mirror of
https://github.com/hanzoai/visor.git
synced 2026-09-24 17:04:14 +00:00
This ensures that sidecars must be installed from the same release. See issue #13718.
320 lines
8.1 KiB
Go
320 lines
8.1 KiB
Go
// Copyright 2022 The gVisor 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 cmd
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
)
|
|
|
|
type runtimeDef struct {
|
|
path string
|
|
runtimeArgs []string
|
|
}
|
|
|
|
func (r *runtimeDef) MarshalJSON() ([]byte, error) {
|
|
args, err := json.Marshal(r.runtimeArgs)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
str := fmt.Sprintf(`{"path": "%s", "runtimeArgs":%s}`, r.path, args)
|
|
return []byte(str), nil
|
|
}
|
|
|
|
func (r *runtimeDef) UnmarshalJSON(data []byte) error {
|
|
var dat map[string]any
|
|
if err := json.Unmarshal(data, &dat); err != nil {
|
|
return err
|
|
}
|
|
if p, ok := dat["path"]; ok {
|
|
r.path = p.(string)
|
|
}
|
|
if p, ok := dat["runtimeArgs"]; ok {
|
|
r.runtimeArgs = p.([]string)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
var defaultInput = map[string]any{
|
|
"runtimes": map[string]*runtimeDef{
|
|
"runtime1": {
|
|
path: "runtime1_path",
|
|
runtimeArgs: []string{"some", "args"},
|
|
},
|
|
"other runtime": {
|
|
path: "other_runtime_path",
|
|
runtimeArgs: []string{"some", "other", "args"},
|
|
},
|
|
"myRuntime": {
|
|
path: "myRuntimePath",
|
|
runtimeArgs: []string{"super", "cool", "args"},
|
|
},
|
|
},
|
|
"exec-opts": []string{"some-cgroup-driver=something", "native.cgroupdriver=init_driver"},
|
|
}
|
|
|
|
func TestInstall(t *testing.T) {
|
|
|
|
for _, tc := range []struct {
|
|
name string
|
|
i *Install
|
|
input map[string]any
|
|
output map[string]any
|
|
}{
|
|
{
|
|
name: "clobber",
|
|
i: &Install{
|
|
Runtime: "myRuntime",
|
|
Experimental: true,
|
|
Clobber: true,
|
|
CgroupDriver: "my_driver",
|
|
executablePath: "some_runsc_path",
|
|
runtimeArgs: []string{"new", "cool", "args"},
|
|
},
|
|
input: defaultInput,
|
|
output: map[string]any{
|
|
"runtimes": map[string]*runtimeDef{
|
|
"runtime1": {
|
|
path: "runtime1_path",
|
|
runtimeArgs: []string{"some", "args"},
|
|
},
|
|
"other runtime": {
|
|
path: "other_runtime_path",
|
|
runtimeArgs: []string{"some", "other", "args"},
|
|
},
|
|
"myRuntime": {
|
|
path: "some_runsc_path",
|
|
runtimeArgs: []string{"new", "cool", "args"},
|
|
},
|
|
},
|
|
"exec-opts": []string{"some-cgroup-driver=something", "native.cgroupdriver=my_driver"},
|
|
"experimental": true,
|
|
},
|
|
},
|
|
{
|
|
name: "no clobber",
|
|
i: &Install{
|
|
Runtime: "myRuntime",
|
|
Experimental: true,
|
|
Clobber: false,
|
|
CgroupDriver: "my_driver",
|
|
executablePath: "some_runsc_path",
|
|
runtimeArgs: []string{"new", "cool", "args"},
|
|
},
|
|
input: defaultInput,
|
|
output: map[string]any{
|
|
"runtimes": map[string]*runtimeDef{
|
|
"runtime1": {
|
|
path: "runtime1_path",
|
|
runtimeArgs: []string{"some", "args"},
|
|
},
|
|
"other runtime": {
|
|
path: "other_runtime_path",
|
|
runtimeArgs: []string{"some", "other", "args"},
|
|
},
|
|
"myRuntime": {
|
|
path: "myRuntimePath",
|
|
runtimeArgs: []string{"super", "cool", "args"},
|
|
},
|
|
},
|
|
"exec-opts": []string{"some-cgroup-driver=something", "native.cgroupdriver=init_driver", "native.cgroupdriver=my_driver"},
|
|
"experimental": true,
|
|
},
|
|
},
|
|
{
|
|
name: "new runtime",
|
|
i: &Install{
|
|
Runtime: "newRuntime",
|
|
Experimental: true,
|
|
executablePath: "newPath",
|
|
runtimeArgs: []string{"new", "cool", "args"},
|
|
},
|
|
input: defaultInput,
|
|
output: map[string]any{
|
|
"runtimes": map[string]*runtimeDef{
|
|
"runtime1": {
|
|
path: "runtime1_path",
|
|
runtimeArgs: []string{"some", "args"},
|
|
},
|
|
"newRuntime": {
|
|
path: "newPath",
|
|
runtimeArgs: []string{"new", "cool", "args"},
|
|
},
|
|
"other runtime": {
|
|
path: "other_runtime_path",
|
|
runtimeArgs: []string{"some", "other", "args"},
|
|
},
|
|
"myRuntime": {
|
|
path: "myRuntimePath",
|
|
runtimeArgs: []string{"super", "cool", "args"},
|
|
},
|
|
},
|
|
"exec-opts": []string{"some-cgroup-driver=something", "native.cgroupdriver=init_driver"},
|
|
"experimental": true,
|
|
},
|
|
},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
mockRead := func(_ string) ([]byte, error) {
|
|
return json.MarshalIndent(tc.input, "", " ")
|
|
}
|
|
|
|
got := []byte{}
|
|
mockWrite := func(c map[string]any, _ string) error {
|
|
res, err := json.MarshalIndent(c, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
got = res
|
|
return nil
|
|
}
|
|
|
|
rw := configReaderWriter{
|
|
read: mockRead,
|
|
write: mockWrite,
|
|
}
|
|
|
|
if err := doInstallConfig(tc.i, rw); err != nil {
|
|
t.Fatalf("Error updating config: %v", err)
|
|
}
|
|
|
|
want, err := json.MarshalIndent(tc.output, "", " ")
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal output: %v", err)
|
|
}
|
|
|
|
if res := cmp.Diff(string(want), string(got)); res != "" {
|
|
t.Fatalf("Mismatch output (-want +got): %s", res)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUninstall(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
name string
|
|
u *Uninstall
|
|
input map[string]any
|
|
output map[string]any
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "runtime found",
|
|
u: &Uninstall{
|
|
Runtime: "other runtime",
|
|
},
|
|
input: defaultInput,
|
|
output: map[string]any{
|
|
"runtimes": map[string]*runtimeDef{
|
|
"runtime1": {
|
|
path: "runtime1_path",
|
|
runtimeArgs: []string{"some", "args"},
|
|
},
|
|
"myRuntime": {
|
|
path: "myRuntimePath",
|
|
runtimeArgs: []string{"super", "cool", "args"},
|
|
},
|
|
},
|
|
"exec-opts": []string{"some-cgroup-driver=something", "native.cgroupdriver=init_driver"},
|
|
},
|
|
},
|
|
{
|
|
name: "runtime not found",
|
|
u: &Uninstall{
|
|
Runtime: "not found runtime",
|
|
},
|
|
input: defaultInput,
|
|
wantErr: true,
|
|
},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
mockRead := func(_ string) ([]byte, error) {
|
|
return json.MarshalIndent(tc.input, "", " ")
|
|
}
|
|
|
|
got := []byte{}
|
|
mockWrite := func(c map[string]any, _ string) error {
|
|
res, err := json.MarshalIndent(c, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
got = res
|
|
return nil
|
|
}
|
|
|
|
rw := configReaderWriter{
|
|
read: mockRead,
|
|
write: mockWrite,
|
|
}
|
|
|
|
err := doUninstallConfig(tc.u, rw)
|
|
if tc.wantErr {
|
|
if err == nil {
|
|
t.Fatalf("Did not get an error when expected.")
|
|
}
|
|
return
|
|
}
|
|
if err != nil {
|
|
t.Fatalf("Error updating config: %v", err)
|
|
}
|
|
|
|
want, err := json.MarshalIndent(tc.output, "", " ")
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal output: %v", err)
|
|
}
|
|
if res := cmp.Diff(string(want), string(got)); res != "" {
|
|
t.Fatalf("Mismatch output (-want +got-): %s", res)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReleaseTarballURL(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
version string
|
|
goarch string
|
|
want string // Empty means an error is expected.
|
|
}{
|
|
{"release-20260706.0", "amd64", "https://storage.googleapis.com/gvisor/releases/release/20260706.0/x86_64/gvisor.tar.bz2"},
|
|
{"release-20260706", "arm64", "https://storage.googleapis.com/gvisor/releases/release/20260706/aarch64/gvisor.tar.bz2"},
|
|
{"gfoo-20260706.0", "amd64", "https://storage.googleapis.com/gvisor/releases/release/20260706.0/x86_64/gvisor.tar.bz2"},
|
|
{"release-20260706.0-14-gabcdef123456", "amd64", ""},
|
|
{"gfoo-20260706.0-14-gabcdef123456", "amd64", ""},
|
|
{"xfoo-20260706.0", "amd64", ""},
|
|
{"g1-20260706.0", "amd64", ""},
|
|
{"VERSION_MISSING", "amd64", ""},
|
|
{"release-20260706.0", "riscv64", ""},
|
|
} {
|
|
got, err := releaseTarballURL(tc.version, tc.goarch)
|
|
if tc.want == "" {
|
|
if err == nil {
|
|
t.Errorf("releaseTarballURL(%q, %q) = %q, want error", tc.version, tc.goarch, got)
|
|
}
|
|
continue
|
|
}
|
|
if err != nil {
|
|
t.Errorf("releaseTarballURL(%q, %q): %v", tc.version, tc.goarch, err)
|
|
continue
|
|
}
|
|
if got != tc.want {
|
|
t.Errorf("releaseTarballURL(%q, %q) = %q, want %q", tc.version, tc.goarch, got, tc.want)
|
|
}
|
|
}
|
|
}
|