mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 19:17:10 +00:00
test(ioscompanion): cover companion stub and embedded extraction
This commit is contained in:
1 parent
6c4f00abad
commit
f67cb8a00c
2 files changed
+173
No files matched your search
@@ -0,0 +1,27 @@
|
||||
//go:build !withcompanion
|
||||
|
||||
package companionassets
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestStubBuild_IsPlaceholder(t *testing.T) {
|
||||
if !IsPlaceholder() {
|
||||
t.Error("default build (no -tags withcompanion) must report a placeholder")
|
||||
}
|
||||
if EmbeddedSize() != 0 {
|
||||
t.Errorf("placeholder build must embed no archive, got %d bytes", EmbeddedSize())
|
||||
}
|
||||
}
|
||||
|
||||
func TestStubBuild_ExtractErrors(t *testing.T) {
|
||||
_, err := Extract(t.TempDir())
|
||||
if err == nil {
|
||||
t.Fatal("Extract must fail when no archive is embedded")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "withcompanion") {
|
||||
t.Errorf("error should tell the user to rebuild with -tags withcompanion, got %v", err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
//go:build withcompanion
|
||||
|
||||
package companionassets
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEmbeddedNonZero(t *testing.T) {
|
||||
if EmbeddedSize() == 0 {
|
||||
t.Errorf("expected embedded companion archive to be non-empty")
|
||||
}
|
||||
if IsPlaceholder() {
|
||||
t.Errorf("withcompanion build should not be a placeholder")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmbeddedSHA256Matches(t *testing.T) {
|
||||
sum := sha256.Sum256(embeddedArchive)
|
||||
if hex.EncodeToString(sum[:]) != EmbeddedSHA256() {
|
||||
t.Errorf("EmbeddedSHA256 does not match a fresh hash of the archive")
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtract_WritesBinaryAndChecksum(t *testing.T) {
|
||||
directory := t.TempDir()
|
||||
path, err := Extract(directory)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expected, err := filepath.Abs(filepath.Join(directory, "bin", companionBinaryName))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if path != expected {
|
||||
t.Errorf("unexpected binary path: got %s want %s", path, expected)
|
||||
}
|
||||
checksum, err := os.ReadFile(filepath.Join(directory, "companion.sha256"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(checksum) != EmbeddedSHA256() {
|
||||
t.Errorf("checksum file content wrong: %q", checksum)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtract_LayoutAndSymlinks(t *testing.T) {
|
||||
directory := t.TempDir()
|
||||
binaryPath, err := Extract(directory)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
info, err := os.Stat(binaryPath)
|
||||
if err != nil {
|
||||
t.Fatalf("companion binary missing: %v", err)
|
||||
}
|
||||
if info.Mode().Perm()&0o111 == 0 {
|
||||
t.Errorf("companion binary is not executable, mode=%v", info.Mode())
|
||||
}
|
||||
|
||||
frameworksDir := filepath.Join(directory, "Frameworks")
|
||||
if stat, err := os.Stat(frameworksDir); err != nil || !stat.IsDir() {
|
||||
t.Fatalf("Frameworks directory missing: %v", err)
|
||||
}
|
||||
|
||||
expectedFrameworks := []string{
|
||||
"FBControlCore.framework",
|
||||
"FBDeviceControl.framework",
|
||||
"FBSimulatorControl.framework",
|
||||
"IDBCompanionUtilities.framework",
|
||||
"IDBGRPCSwift.framework",
|
||||
"XCTestBootstrap.framework",
|
||||
}
|
||||
for _, name := range expectedFrameworks {
|
||||
if stat, err := os.Stat(filepath.Join(frameworksDir, name)); err != nil || !stat.IsDir() {
|
||||
t.Errorf("expected framework %s missing: %v", name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// The Versions/Current symlink must resolve to a real directory, proving
|
||||
// symlinks survived extraction.
|
||||
current := filepath.Join(frameworksDir, "FBControlCore.framework", "Versions", "Current")
|
||||
linkInfo, err := os.Lstat(current)
|
||||
if err != nil {
|
||||
t.Fatalf("Versions/Current missing: %v", err)
|
||||
}
|
||||
if linkInfo.Mode()&os.ModeSymlink == 0 {
|
||||
t.Errorf("Versions/Current is not a symlink")
|
||||
}
|
||||
resolved, err := os.Stat(current)
|
||||
if err != nil || !resolved.IsDir() {
|
||||
t.Errorf("Versions/Current does not resolve to a directory: %v", err)
|
||||
}
|
||||
|
||||
// A runtime dylib that must be preserved inside FBControlCore Resources.
|
||||
dylib := filepath.Join(frameworksDir, "FBControlCore.framework", "Versions", "A", "Resources", "libMaculator.dylib")
|
||||
if _, err := os.Stat(dylib); err != nil {
|
||||
t.Errorf("expected runtime dylib preserved: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtract_ReusesWhenChecksumMatches(t *testing.T) {
|
||||
directory := t.TempDir()
|
||||
binaryPath, err := Extract(directory)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
sentinel := []byte("SENTINEL-do-not-rewrite")
|
||||
if err := os.WriteFile(binaryPath, sentinel, 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := Extract(directory); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
after, err := os.ReadFile(binaryPath)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if string(after) != string(sentinel) {
|
||||
t.Errorf("second extract rewrote the binary; reuse branch should have skipped extraction")
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtract_RewritesIfChecksumMissing(t *testing.T) {
|
||||
directory := t.TempDir()
|
||||
if _, err := Extract(directory); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
checksumPath := filepath.Join(directory, "companion.sha256")
|
||||
if err := os.Remove(checksumPath); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := Extract(directory); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := os.Stat(checksumPath); err != nil {
|
||||
t.Errorf("checksum should have been rewritten: %v", err)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user