//go:build linux || darwin package modelprojection import ( "os" "path/filepath" "syscall" "testing" "github.com/aritmolab/thothii/tools/tht/internal/config" ) func TestGenerateKeepsProjectionsContainerReadableWithRestrictiveUmask(t *testing.T) { installation := projectionFixture(t) parentBefore, err := os.Stat(filepath.Dir(installation.Path)) if err != nil { t.Fatal(err) } // This test must remain sequential: umask is process-wide. previous := syscall.Umask(0o077) defer syscall.Umask(previous) if err := Generate(installation); err != nil { t.Fatal(err) } assertContainerProjectionModes(t, installation) parentAfter, err := os.Stat(filepath.Dir(installation.Path)) if err != nil || parentAfter.Mode().Perm() != parentBefore.Mode().Perm() { t.Fatalf("generation changed private installation directory permissions: %v", err) } } func TestGenerateRepairsUnreadableProjectionAsANewGeneration(t *testing.T) { installation := projectionFixture(t) if err := Generate(installation); err != nil { t.Fatal(err) } before, err := os.Stat(installation.GeneratedDirectory()) if err != nil { t.Fatal(err) } for path, mode := range map[string]os.FileMode{ installation.GeneratedDirectory(): 0o700, filepath.Dir(installation.GeneratedPiModelsPath()): 0o700, installation.GeneratedFrontendConfigPath(): 0o600, } { if err := os.Chmod(path, mode); err != nil { t.Fatal(err) } } if drift, err := Check(installation); err != nil || len(drift) == 0 { t.Fatalf("unreadable projection drift = %v, %v", drift, err) } if err := Generate(installation); err != nil { t.Fatal(err) } assertContainerProjectionModes(t, installation) after, err := os.Stat(installation.GeneratedDirectory()) if err != nil || os.SameFile(before, after) { t.Fatalf("permissions were not repaired through candidate publication: %v", err) } if drift, err := Check(installation); err != nil || len(drift) != 0 { t.Fatalf("repaired projection drift = %v, %v", drift, err) } } func assertContainerProjectionModes(t *testing.T, installation config.Installation) { t.Helper() for path, mode := range map[string]os.FileMode{ installation.GeneratedDirectory(): 0o755, filepath.Dir(installation.GeneratedFrontendConfigPath()): 0o755, filepath.Dir(installation.GeneratedPiModelsPath()): 0o755, installation.GeneratedFrontendConfigPath(): 0o644, installation.GeneratedModelCatalogPath(): 0o644, installation.GeneratedPiModelsPath(): 0o644, installation.GeneratedPiSettingsPath(): 0o644, installation.ModelProjectionComposePath(): 0o644, } { info, err := os.Stat(path) if err != nil { t.Error(err) continue } if info.Mode().Perm() != mode { t.Errorf("%s mode = %04o, want %04o for container readers", path, info.Mode().Perm(), mode) } } }