Ctrl K
ComunidadGuías…

internal/memory/stores_test.go

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

Archivo original ↗Preguntar a KiBot
package memory_test

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

	"github.com/yeomyeonggeori/blueclaw/internal/memory"
	"github.com/yeomyeonggeori/blueclaw/internal/memory/memorytest"
	"github.com/yeomyeonggeori/blueclaw/internal/policy"
	"github.com/yeomyeonggeori/blueclaw/internal/security"
	"github.com/yeomyeonggeori/bluememo"
	"github.com/yeomyeonggeori/bluememo/bluememotest"
)

func TestMergePersonRenamesTheLosingFileWhenTheSurvivorHasNone(t *testing.T) {
	stores := memorytest.Open(t)
	ctx := context.Background()
	memorytest.Remember(t, stores, memory.PersonScope("legacy-person"), "이샘플 prefers the morning slot.")

	if errorValue := stores.MergePerson(ctx, "legacy-person", "person-1"); errorValue != nil {
		t.Fatalf("merge: %v", errorValue)
	}

	if held := memorytest.Count(t, stores, memory.PersonScope("person-1")); held != 1 {
		t.Errorf("the survivor holds %d memories, want the one that moved", held)
	}
	if left := memorytest.Count(t, stores, memory.PersonScope("legacy-person")); left != 0 {
		t.Errorf("the merged-away person still holds %d memories, want none", left)
	}
}

func TestMergePersonCarriesTheMemoriesWhenBothFilesExist(t *testing.T) {
	stores := memorytest.Open(t)
	ctx := context.Background()
	memorytest.Remember(t, stores, memory.PersonScope("legacy-person"), "이샘플 prefers the morning slot.")
	memorytest.Remember(t, stores, memory.PersonScope("person-1"), "이샘플 chairs the safety review.")

	if errorValue := stores.MergePerson(ctx, "legacy-person", "person-1"); errorValue != nil {
		t.Fatalf("merge: %v", errorValue)
	}

	if held := memorytest.Count(t, stores, memory.PersonScope("person-1")); held != 2 {
		t.Errorf("the survivor holds %d memories, want both", held)
	}
	if left := memorytest.Count(t, stores, memory.PersonScope("legacy-person")); left != 0 {
		t.Errorf("the merged-away person still holds %d memories, want none", left)
	}
}

func TestMergePersonIsQuietWhenThereIsNothingToMove(t *testing.T) {
	stores := memorytest.Open(t)
	ctx := context.Background()

	if errorValue := stores.MergePerson(ctx, "legacy-person", "person-1"); errorValue != nil {
		t.Fatalf("merge with no file: %v", errorValue)
	}
	if errorValue := stores.MergePerson(ctx, "person-1", "person-1"); errorValue != nil {
		t.Fatalf("merge into itself: %v", errorValue)
	}
}

func TestASubjectsMemorySitsInTheirOwnWorkspaceUnderProtected(t *testing.T) {
	stores := memorytest.Open(t)
	for name, expectation := range map[string]struct {
		scope  memory.Scope
		suffix string
	}{
		"a person": {memory.PersonScope("person-1"), "/private/protected/person-1/memory.db"},
		"a circle": {memory.CircleScope("member"), "/circles/member/.protected/memory.db"},
		"everyone": {memory.WorkspaceScope(), "/shared/.protected/memory.db"},
	} {
		t.Run(name, func(t *testing.T) {
			path, errorValue := stores.Path(expectation.scope)
			if errorValue != nil {
				t.Fatalf("path: %v", errorValue)
			}
			if !strings.HasSuffix(path, expectation.suffix) {
				t.Fatalf("memory for %s sits at %q, which does not end in %q", name, path, expectation.suffix)
			}
		})
	}
}

func TestAMemoryFileIsReadableByItsSubjectAndWritableByNobodyElse(t *testing.T) {
	stores := memorytest.Open(t)
	scope := memory.PersonScope("person-1")
	memorytest.Remember(t, stores, scope, "박예시 keeps the quarterly ledger")

	path, errorValue := stores.Path(scope)
	if errorValue != nil {
		t.Fatalf("path: %v", errorValue)
	}
	information, errorValue := os.Stat(path)
	if errorValue != nil {
		t.Fatalf("stat: %v", errorValue)
	}
	if mode := information.Mode().Perm(); mode != 0o640 {
		t.Fatalf("a memory file carries mode %04o; the subject's group must read it and only the service write it", mode)
	}
}

func TestAMemoryNobodyWroteRecallsNothingRatherThanFailing(t *testing.T) {
	stores := memorytest.Open(t)

	recalled, errorValue := stores.RecallAcross(
		context.Background(),
		policy.PersonAccess{PersonID: "person-nobody-wrote-for"},
		[]memory.Scope{memory.PersonScope("person-nobody-wrote-for"), memory.WorkspaceScope()},
		"anything",
		10,
	)

	if errorValue != nil {
		t.Fatalf("a recall of files nobody has written failed: %v", errorValue)
	}
	if len(recalled.Facts) != 0 {
		t.Fatalf("a recall of files nobody has written answered with %d facts", len(recalled.Facts))
	}
}

func TestARefusedReadFailsTheRecallRatherThanThinningIt(t *testing.T) {
	stores := memory.NewStores(t.TempDir(), bluememo.Configuration{
		Embedder: &bluememotest.HashEmbedder{},
	}, refusingActor{})
	t.Cleanup(func() { _ = stores.Close() })
	if _, errorValue := stores.Store(context.Background(), memory.PersonScope("person-1")); errorValue != nil {
		t.Fatalf("open the file the read is refused: %v", errorValue)
	}

	_, errorValue := stores.RecallAcross(
		context.Background(),
		policy.PersonAccess{PersonID: "person-1"},
		[]memory.Scope{memory.PersonScope("person-1")},
		"anything",
		10,
	)

	if errorValue == nil {
		t.Fatal("a recall whose read was refused reported success, so a refusal would read as an empty memory")
	}
	if !strings.Contains(errorValue.Error(), "refused") {
		t.Fatalf("a refused recall failed with something else: %v", errorValue)
	}
}

type refusingActor struct {
	security.WorkspaceActor
}

func (refusingActor) Requester(context.Context, security.WorkspaceActorRequest) (security.WorkspaceActor, error) {
	return refusingActor{}, nil
}

func (refusingActor) CanListDirectory(context.Context) bool { return false }

func (refusingActor) Run(context.Context, security.CommandRequest) (security.CommandResult, error) {
	return security.CommandResult{ExitCode: 1, Stderr: "permission denied"}, nil
}

func TestEveryScopeAnAdministratorReachesSitsInADeclaredDirectory(t *testing.T) {
	stores, root := memorytest.OpenWithRoot(t)
	administrator := policy.PersonPolicy{PersonID: "person-1", Circles: []string{"sales"}, IsAdmin: true}
	document := policy.CanonicalizePolicyDocument(policy.PolicyDocument{
		People:  []policy.PersonPolicy{administrator},
		Circles: []policy.CirclePolicy{{CircleID: "sales"}},
	})
	declared := map[string]bool{}
	const hostRoot = "/workspace"
	for _, directory := range security.POSIXStateForPolicy(document, hostRoot).Directories {
		declared[directory.Path] = true
	}
	personAccess := policy.PolicyProjectionService{}.ReplacePolicyProjectionTransactionally(document).PersonAccessByPersonID["person-1"]

	for _, scope := range memory.ScopesToSearch(personAccess, nil) {
		path, errorValue := stores.Path(scope)
		if errorValue != nil {
			t.Fatalf("path for %+v: %v", scope, errorValue)
		}
		directory := strings.Replace(filepath.Dir(path), root, hostRoot, 1)
		if !declared[directory] {
			t.Fatalf("memory for %s %q sits in %s, which no POSIX declaration sets up, so the person cannot open it", scope.Kind, scope.ID, directory)
		}
	}
}