mirror of
https://github.com/getcompanion-ai/computer-host.git
synced 2026-04-15 09:01:12 +00:00
host daemon (#2)
* feat: host daemon api scaffold * fix: use sparse writes * fix: unix socket length (<108 bytes)
This commit is contained in:
parent
4028bb5a1d
commit
e2f9e54970
21 changed files with 2111 additions and 372 deletions
94
internal/daemon/files_test.go
Normal file
94
internal/daemon/files_test.go
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
package daemon
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCloneFilePreservesSparseDiskUsage(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
sourcePath := filepath.Join(root, "source.img")
|
||||
targetPath := filepath.Join(root, "target.img")
|
||||
|
||||
sourceFile, err := os.OpenFile(sourcePath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0o644)
|
||||
if err != nil {
|
||||
t.Fatalf("open source file: %v", err)
|
||||
}
|
||||
if _, err := sourceFile.Write([]byte("head")); err != nil {
|
||||
sourceFile.Close()
|
||||
t.Fatalf("write source prefix: %v", err)
|
||||
}
|
||||
if _, err := sourceFile.Seek(32<<20, io.SeekStart); err != nil {
|
||||
sourceFile.Close()
|
||||
t.Fatalf("seek source hole: %v", err)
|
||||
}
|
||||
if _, err := sourceFile.Write([]byte("tail")); err != nil {
|
||||
sourceFile.Close()
|
||||
t.Fatalf("write source suffix: %v", err)
|
||||
}
|
||||
if err := sourceFile.Close(); err != nil {
|
||||
t.Fatalf("close source file: %v", err)
|
||||
}
|
||||
|
||||
sourceInfo, err := os.Stat(sourcePath)
|
||||
if err != nil {
|
||||
t.Fatalf("stat source file: %v", err)
|
||||
}
|
||||
sourceUsage, err := allocatedBytes(sourcePath)
|
||||
if err != nil {
|
||||
t.Fatalf("allocated bytes for source: %v", err)
|
||||
}
|
||||
if sourceUsage >= sourceInfo.Size()/2 {
|
||||
t.Skip("temp filesystem does not expose sparse allocation savings")
|
||||
}
|
||||
|
||||
if err := cloneFile(sourcePath, targetPath); err != nil {
|
||||
t.Fatalf("clone sparse file: %v", err)
|
||||
}
|
||||
|
||||
targetInfo, err := os.Stat(targetPath)
|
||||
if err != nil {
|
||||
t.Fatalf("stat target file: %v", err)
|
||||
}
|
||||
if targetInfo.Size() != sourceInfo.Size() {
|
||||
t.Fatalf("target size mismatch: got %d want %d", targetInfo.Size(), sourceInfo.Size())
|
||||
}
|
||||
|
||||
targetUsage, err := allocatedBytes(targetPath)
|
||||
if err != nil {
|
||||
t.Fatalf("allocated bytes for target: %v", err)
|
||||
}
|
||||
if targetUsage >= targetInfo.Size()/2 {
|
||||
t.Fatalf("target file is not sparse enough: allocated=%d size=%d", targetUsage, targetInfo.Size())
|
||||
}
|
||||
|
||||
targetData, err := os.ReadFile(targetPath)
|
||||
if err != nil {
|
||||
t.Fatalf("read target file: %v", err)
|
||||
}
|
||||
if !bytes.Equal(targetData[:4], []byte("head")) {
|
||||
t.Fatalf("target prefix mismatch: %q", string(targetData[:4]))
|
||||
}
|
||||
if !bytes.Equal(targetData[len(targetData)-4:], []byte("tail")) {
|
||||
t.Fatalf("target suffix mismatch: %q", string(targetData[len(targetData)-4:]))
|
||||
}
|
||||
if !bytes.Equal(targetData[4:4+(1<<20)], make([]byte, 1<<20)) {
|
||||
t.Fatal("target hole contents were not zeroed")
|
||||
}
|
||||
}
|
||||
|
||||
func allocatedBytes(path string) (int64, error) {
|
||||
info, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
stat, ok := info.Sys().(*syscall.Stat_t)
|
||||
if !ok {
|
||||
return 0, syscall.EINVAL
|
||||
}
|
||||
return stat.Blocks * 512, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue