Source file misc/cgo/errors/errors_test.go

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

View as plain text