casecheck_test.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package blob
  2. import (
  3. "fmt"
  4. "os"
  5. "path/filepath"
  6. "runtime"
  7. "strings"
  8. "testing"
  9. )
  10. func isCaseSensitive(dir string) bool {
  11. defer func() {
  12. os.Remove(filepath.Join(dir, "_casecheck"))
  13. }()
  14. exists := func(file string) bool {
  15. _, err := os.Stat(file)
  16. return err == nil
  17. }
  18. file := filepath.Join(dir, "_casecheck")
  19. FILE := filepath.Join(dir, "_CASECHECK")
  20. if exists(file) || exists(FILE) {
  21. panic(fmt.Sprintf("_casecheck already exists in %q; remove and try again.", dir))
  22. }
  23. err := os.WriteFile(file, nil, 0o666)
  24. if err != nil {
  25. panic(err)
  26. }
  27. return !exists(FILE)
  28. }
  29. func isCI() bool {
  30. return os.Getenv("CI") != ""
  31. }
  32. const volumeHint = `
  33. Unable to locate case-insensitive TMPDIR on darwin.
  34. To run tests, create the case-insensitive volume /Volumes/data:
  35. $ sudo diskutil apfs addVolume disk1 APFSX data -mountpoint /Volumes/data
  36. or run with:
  37. CI=1 go test ./...
  38. `
  39. // useCaseInsensitiveTempDir sets TMPDIR to a case-insensitive directory
  40. // can find one, otherwise it skips the test if the CI environment variable is
  41. // set, or GOOS is not darwin.
  42. func useCaseInsensitiveTempDir(t *testing.T) bool {
  43. if isCaseSensitive(os.TempDir()) {
  44. // Use the default temp dir if it is already case-sensitive.
  45. return true
  46. }
  47. if runtime.GOOS == "darwin" {
  48. // If darwin, check for the special case-sensitive volume and
  49. // use it if available.
  50. const volume = "/Volumes/data"
  51. _, err := os.Stat(volume)
  52. if err == nil {
  53. tmpdir := filepath.Join(volume, "tmp")
  54. os.MkdirAll(tmpdir, 0o700)
  55. t.Setenv("TMPDIR", tmpdir)
  56. return true
  57. }
  58. if isCI() {
  59. // Special case darwin in CI; it is not case-sensitive
  60. // by default, and we will be testing other platforms
  61. // that are case-sensitive, so we'll have the test
  62. // being skipped covered there.
  63. t.Skip("Skipping test in CI for darwin; TMPDIR is not case-insensitive.")
  64. }
  65. }
  66. if !isCI() {
  67. // Require devs to always tests with a case-insensitive TMPDIR.
  68. // TODO(bmizerany): Print platform-specific instructions or
  69. // link to docs on that topic.
  70. lines := strings.Split(volumeHint, "\n")
  71. for _, line := range lines {
  72. t.Log(line)
  73. }
  74. }
  75. return false
  76. }