Ctrl K
ComunidadGuías…

iclient/config_test.go

Rama develop · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package iclient

import (
	"os"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/require"
)

// writeConfig writes a config.yml plus any extra files into a fresh dir. The
// host's /etc/incus is still merged in, but never overrides what the fixture names.
func writeConfig(t *testing.T, config string, extra map[string]string) string {
	t.Helper()

	dir := t.TempDir()

	err := os.WriteFile(filepath.Join(dir, "config.yml"), []byte(config), 0o600)
	require.NoError(t, err)

	for name, content := range extra {
		path := filepath.Join(dir, name)
		require.NoError(t, os.MkdirAll(filepath.Dir(path), 0o700))
		require.NoError(t, os.WriteFile(path, []byte(content), 0o600))
	}

	return filepath.Join(dir, "config.yml")
}

func TestReadConfigFillsDefaults(t *testing.T) {
	t.Parallel()

	path := writeConfig(t, `
default-remote: srv
remotes:
  srv:
    addr: https://one:8443,https://two:8443
    project: apps
  pub:
    addr: https://images.example.org
    public: true
    protocol: simplestreams
`, nil)

	c, err := ReadConfig(path)
	require.NoError(t, err)

	require.Equal(t, "srv", c.DefaultRemote)
	require.Equal(t, []string{"https://one:8443", "https://two:8443"}, c.Remotes["srv"].Addrs)

	// A private remote with no auth_type defaults to tls, a public one is left alone.
	require.Equal(t, "tls", c.Remotes["srv"].AuthType)
	require.Empty(t, c.Remotes["pub"].AuthType)

	// Protocol defaults to incus, an explicit one survives.
	require.Equal(t, "incus", c.Remotes["srv"].Protocol)
	require.Equal(t, "simplestreams", c.Remotes["pub"].Protocol)

	// local is static and always present.
	require.Equal(t, []string{"unix://"}, c.Remotes["local"].Addrs)
	require.True(t, c.Remotes["local"].Static)
}

func TestReadConfigMissingFileIsDefaults(t *testing.T) {
	t.Parallel()

	c, err := ReadConfig(filepath.Join(t.TempDir(), "nope.yml"))
	require.NoError(t, err)

	require.Equal(t, "local", c.DefaultRemote)
	require.Contains(t, c.Remotes, "local")
	require.Contains(t, c.Remotes, "images")
}

func TestRemoteInfosTLS(t *testing.T) {
	t.Parallel()

	path := writeConfig(t, `
default-remote: srv
remotes:
  srv:
    addr: https://one:8443,https://two:8443
    last_working_address: https://two:8443
    project: apps
`, map[string]string{
		"client.crt":          "CERT",
		"client.key":          "KEY",
		"servercerts/srv.crt": "SERVER",
	})

	c, err := ReadConfig(path)
	require.NoError(t, err)

	info, err := c.RemoteInfos("srv")
	require.NoError(t, err)

	// The last working address is tried first.
	require.Equal(t, []string{"https://two:8443", "https://one:8443"}, info.Addrs)

	require.Equal(t, "CERT", info.ClientCert)
	require.Equal(t, "KEY", info.ClientKey)
	require.Equal(t, "SERVER", info.ServerCert)

	// Absent is empty, not an error.
	require.Empty(t, info.ClientCA)
	require.False(t, info.Unix())
}

func TestRemoteInfosPerRemoteCertsWin(t *testing.T) {
	t.Parallel()

	path := writeConfig(t, `
remotes:
  srv:
    addr: https://one:8443
`, map[string]string{
		"client.crt":          "SHARED",
		"clientcerts/srv.crt": "MINE",
		"clientcerts/srv.key": "MINEKEY",
	})

	c, err := ReadConfig(path)
	require.NoError(t, err)

	info, err := c.RemoteInfos("srv")
	require.NoError(t, err)

	require.Equal(t, "MINE", info.ClientCert)
	require.Equal(t, "MINEKEY", info.ClientKey)
}

func TestRemoteInfosUnixHasNoTLS(t *testing.T) {
	t.Parallel()

	path := writeConfig(t, `
remotes: {}
`, map[string]string{"client.crt": "CERT"})

	c, err := ReadConfig(path)
	require.NoError(t, err)

	info, err := c.RemoteInfos("local")
	require.NoError(t, err)

	require.True(t, info.Unix())
	require.Empty(t, info.ClientCert)
	require.Empty(t, info.ServerCert)
}

func TestRemoteInfosDefault(t *testing.T) {
	t.Parallel()

	// `project` is no field of ours any more; a config carrying one still parses.
	path := writeConfig(t, `
default-remote: srv
remotes:
  srv:
    addr: https://one:8443
    project: apps
`, nil)

	c, err := ReadConfig(path)
	require.NoError(t, err)

	// An empty name resolves the default remote.
	info, err := c.RemoteInfos("")
	require.NoError(t, err)
	require.Equal(t, "srv", info.Name)
}

func TestRemoteInfosUnknown(t *testing.T) {
	t.Parallel()

	path := writeConfig(t, "remotes: {}\n", nil)

	c, err := ReadConfig(path)
	require.NoError(t, err)

	_, err = c.RemoteInfos("nope")
	require.ErrorIs(t, err, ErrConfigRemoteNotFound)
}