git » chasquid » next » tree

[next] / chasquid_test.go

package main

import (
	"errors"
	"os"
	"path/filepath"
	"strings"
	"syscall"
	"testing"

	"blitiri.com.ar/go/chasquid/internal/testlib"
)

func mustMkdir(t *testing.T, path string) string {
	t.Helper()
	err := os.Mkdir(path, 0700)
	if err != nil {
		t.Fatalf("failed to create directory: %v", err)
	}
	return path
}

func TestFindCertKey(t *testing.T) {
	tmpDir := testlib.MustTempDir(t)
	defer testlib.RemoveIfOk(t, tmpDir)

	cases := []struct {
		name  string
		files []string
		want  string
	}{
		{"certbot", []string{"privkey.pem"}, "privkey.pem"},
		{"lego", []string{"key.pem"}, "key.pem"},
		{"both", []string{"privkey.pem", "key.pem"}, "privkey.pem"},
	}
	for _, c := range cases {
		dir := mustMkdir(t, filepath.Join(tmpDir, c.name))
		for _, f := range c.files {
			testlib.Rewrite(t, filepath.Join(dir, f), "")
		}

		got, err := findCertKey(dir)
		if err != nil {
			t.Errorf("%s: unexpected error: %v", c.name, err)
		}
		if want := filepath.Join(dir, c.want); got != want {
			t.Errorf("%s: got %q, expected %q", c.name, got, want)
		}
	}

	// No key files: the error should mention the directory.
	dir := mustMkdir(t, filepath.Join(tmpDir, "empty"))
	got, err := findCertKey(dir)
	if err == nil || !strings.Contains(err.Error(), dir) {
		t.Errorf("empty: got %q, %v, expected 'no private key' error",
			got, err)
	}

	// privkey.pem is there but can't be stat'ed (a symlink loop here, which
	// also works when running as root). We expect that error to be returned,
	// instead of silently falling back to key.pem.
	dir = mustMkdir(t, filepath.Join(tmpDir, "loop"))
	err = os.Symlink("privkey.pem", filepath.Join(dir, "privkey.pem"))
	if err != nil {
		t.Fatalf("failed to create symlink: %v", err)
	}
	testlib.Rewrite(t, filepath.Join(dir, "key.pem"), "")
	got, err = findCertKey(dir)
	if !errors.Is(err, syscall.ELOOP) {
		t.Errorf("loop: got %q, %v, expected ELOOP error", got, err)
	}
}