errors_test.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // Copyright 2017 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package errorstest
  5. import (
  6. "bytes"
  7. "fmt"
  8. "os"
  9. "os/exec"
  10. "path/filepath"
  11. "regexp"
  12. "strconv"
  13. "strings"
  14. "testing"
  15. )
  16. func path(file string) string {
  17. return filepath.Join("testdata", file)
  18. }
  19. func check(t *testing.T, file string) {
  20. t.Run(file, func(t *testing.T) {
  21. t.Parallel()
  22. contents, err := os.ReadFile(path(file))
  23. if err != nil {
  24. t.Fatal(err)
  25. }
  26. var errors []*regexp.Regexp
  27. for i, line := range bytes.Split(contents, []byte("\n")) {
  28. if bytes.HasSuffix(line, []byte("ERROR HERE")) {
  29. re := regexp.MustCompile(regexp.QuoteMeta(fmt.Sprintf("%s:%d:", file, i+1)))
  30. errors = append(errors, re)
  31. continue
  32. }
  33. _, frag, ok := bytes.Cut(line, []byte("ERROR HERE: "))
  34. if !ok {
  35. continue
  36. }
  37. re, err := regexp.Compile(fmt.Sprintf(":%d:.*%s", i+1, frag))
  38. if err != nil {
  39. t.Errorf("Invalid regexp after `ERROR HERE: `: %#q", frag)
  40. continue
  41. }
  42. errors = append(errors, re)
  43. }
  44. if len(errors) == 0 {
  45. t.Fatalf("cannot find ERROR HERE")
  46. }
  47. expect(t, file, errors)
  48. })
  49. }
  50. func expect(t *testing.T, file string, errors []*regexp.Regexp) {
  51. dir, err := os.MkdirTemp("", filepath.Base(t.Name()))
  52. if err != nil {
  53. t.Fatal(err)
  54. }
  55. defer os.RemoveAll(dir)
  56. dst := filepath.Join(dir, strings.TrimSuffix(file, ".go"))
  57. cmd := exec.Command("go", "build", "-gcflags=-L -e", "-o="+dst, path(file)) // TODO(gri) no need for -gcflags=-L if go tool is adjusted
  58. out, err := cmd.CombinedOutput()
  59. if err == nil {
  60. t.Errorf("expected cgo to fail but it succeeded")
  61. }
  62. lines := bytes.Split(out, []byte("\n"))
  63. for _, re := range errors {
  64. found := false
  65. for _, line := range lines {
  66. if re.Match(line) {
  67. t.Logf("found match for %#q: %q", re, line)
  68. found = true
  69. break
  70. }
  71. }
  72. if !found {
  73. t.Errorf("expected error output to contain %#q", re)
  74. }
  75. }
  76. if t.Failed() {
  77. t.Logf("actual output:\n%s", out)
  78. }
  79. }
  80. func sizeofLongDouble(t *testing.T) int {
  81. cmd := exec.Command("go", "run", path("long_double_size.go"))
  82. out, err := cmd.CombinedOutput()
  83. if err != nil {
  84. t.Fatalf("%#q: %v:\n%s", strings.Join(cmd.Args, " "), err, out)
  85. }
  86. i, err := strconv.Atoi(strings.TrimSpace(string(out)))
  87. if err != nil {
  88. t.Fatalf("long_double_size.go printed invalid size: %s", out)
  89. }
  90. return i
  91. }
  92. func TestReportsTypeErrors(t *testing.T) {
  93. for _, file := range []string{
  94. "err1.go",
  95. "err2.go",
  96. "issue11097a.go",
  97. "issue11097b.go",
  98. "issue18452.go",
  99. "issue18889.go",
  100. "issue28721.go",
  101. "issue33061.go",
  102. } {
  103. check(t, file)
  104. }
  105. if sizeofLongDouble(t) > 8 {
  106. for _, file := range []string{
  107. "err4.go",
  108. "issue28069.go",
  109. } {
  110. check(t, file)
  111. }
  112. }
  113. }
  114. func TestToleratesOptimizationFlag(t *testing.T) {
  115. for _, cflags := range []string{
  116. "",
  117. "-O",
  118. } {
  119. cflags := cflags
  120. t.Run(cflags, func(t *testing.T) {
  121. t.Parallel()
  122. cmd := exec.Command("go", "build", path("issue14669.go"))
  123. cmd.Env = append(os.Environ(), "CGO_CFLAGS="+cflags)
  124. out, err := cmd.CombinedOutput()
  125. if err != nil {
  126. t.Errorf("%#q: %v:\n%s", strings.Join(cmd.Args, " "), err, out)
  127. }
  128. })
  129. }
  130. }
  131. func TestMallocCrashesOnNil(t *testing.T) {
  132. t.Parallel()
  133. cmd := exec.Command("go", "run", path("malloc.go"))
  134. out, err := cmd.CombinedOutput()
  135. if err == nil {
  136. t.Logf("%#q:\n%s", strings.Join(cmd.Args, " "), out)
  137. t.Fatalf("succeeded unexpectedly")
  138. }
  139. }