summaryrefslogtreecommitdiffstats
path: root/src/cmd/cgo/internal/teststdio
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 19:19:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 19:19:13 +0000
commitccd992355df7192993c666236047820244914598 (patch)
treef00fea65147227b7743083c6148396f74cd66935 /src/cmd/cgo/internal/teststdio
parentInitial commit. (diff)
downloadgolang-1.21-ccd992355df7192993c666236047820244914598.tar.xz
golang-1.21-ccd992355df7192993c666236047820244914598.zip
Adding upstream version 1.21.8.upstream/1.21.8
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/cmd/cgo/internal/teststdio')
-rw-r--r--src/cmd/cgo/internal/teststdio/stdio_test.go77
-rw-r--r--src/cmd/cgo/internal/teststdio/testdata/chain.go46
-rw-r--r--src/cmd/cgo/internal/teststdio/testdata/chain.out55
-rw-r--r--src/cmd/cgo/internal/teststdio/testdata/fib.go50
-rw-r--r--src/cmd/cgo/internal/teststdio/testdata/fib.out91
-rw-r--r--src/cmd/cgo/internal/teststdio/testdata/hello.go13
-rw-r--r--src/cmd/cgo/internal/teststdio/testdata/hello.out1
-rw-r--r--src/cmd/cgo/internal/teststdio/testdata/stdio/file.go42
-rw-r--r--src/cmd/cgo/internal/teststdio/testdata/stdio/stdio.go20
9 files changed, 395 insertions, 0 deletions
diff --git a/src/cmd/cgo/internal/teststdio/stdio_test.go b/src/cmd/cgo/internal/teststdio/stdio_test.go
new file mode 100644
index 0000000..3883422
--- /dev/null
+++ b/src/cmd/cgo/internal/teststdio/stdio_test.go
@@ -0,0 +1,77 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package stdio_test
+
+import (
+ "bytes"
+ "cmd/cgo/internal/cgotest"
+ "internal/testenv"
+ "log"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "testing"
+)
+
+func TestMain(m *testing.M) {
+ log.SetFlags(log.Lshortfile)
+ os.Exit(testMain(m))
+}
+
+func testMain(m *testing.M) int {
+ GOPATH, err := os.MkdirTemp("", "cgostdio")
+ if err != nil {
+ log.Panic(err)
+ }
+ defer os.RemoveAll(GOPATH)
+ os.Setenv("GOPATH", GOPATH)
+
+ // Copy testdata into GOPATH/src/cgostdio, along with a go.mod file
+ // declaring the same path.
+ modRoot := filepath.Join(GOPATH, "src", "cgostdio")
+ if err := cgotest.OverlayDir(modRoot, "testdata"); err != nil {
+ log.Panic(err)
+ }
+ if err := os.Chdir(modRoot); err != nil {
+ log.Panic(err)
+ }
+ os.Setenv("PWD", modRoot)
+ if err := os.WriteFile("go.mod", []byte("module cgostdio\n"), 0666); err != nil {
+ log.Panic(err)
+ }
+
+ return m.Run()
+}
+
+// TestTestRun runs a cgo test that doesn't depend on non-standard libraries.
+func TestTestRun(t *testing.T) {
+ testenv.MustHaveGoRun(t)
+ testenv.MustHaveCGO(t)
+
+ for _, file := range [...]string{
+ "chain.go",
+ "fib.go",
+ "hello.go",
+ } {
+ file := file
+ wantFile := strings.Replace(file, ".go", ".out", 1)
+ t.Run(file, func(t *testing.T) {
+ cmd := exec.Command("go", "run", file)
+ got, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("%v: %s\n%s", cmd, err, got)
+ }
+ got = bytes.ReplaceAll(got, []byte("\r\n"), []byte("\n"))
+ want, err := os.ReadFile(wantFile)
+ if err != nil {
+ t.Fatal("reading golden output:", err)
+ }
+ if !bytes.Equal(got, want) {
+ t.Errorf("'%v' output does not match expected in %s. Instead saw:\n%s", cmd, wantFile, got)
+ }
+ })
+ }
+}
diff --git a/src/cmd/cgo/internal/teststdio/testdata/chain.go b/src/cmd/cgo/internal/teststdio/testdata/chain.go
new file mode 100644
index 0000000..c7163f5
--- /dev/null
+++ b/src/cmd/cgo/internal/teststdio/testdata/chain.go
@@ -0,0 +1,46 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build test_run
+
+// Pass numbers along a chain of threads.
+
+package main
+
+import (
+ "runtime"
+ "strconv"
+
+ "cgostdio/stdio"
+)
+
+const N = 10
+const R = 5
+
+func link(left chan<- int, right <-chan int) {
+ // Keep the links in dedicated operating system
+ // threads, so that this program tests coordination
+ // between pthreads and not just goroutines.
+ runtime.LockOSThread()
+ for {
+ v := <-right
+ stdio.Stdout.WriteString(strconv.Itoa(v) + "\n")
+ left <- 1 + v
+ }
+}
+
+func main() {
+ leftmost := make(chan int)
+ var left chan int
+ right := leftmost
+ for i := 0; i < N; i++ {
+ left, right = right, make(chan int)
+ go link(left, right)
+ }
+ for i := 0; i < R; i++ {
+ right <- 0
+ x := <-leftmost
+ stdio.Stdout.WriteString(strconv.Itoa(x) + "\n")
+ }
+}
diff --git a/src/cmd/cgo/internal/teststdio/testdata/chain.out b/src/cmd/cgo/internal/teststdio/testdata/chain.out
new file mode 100644
index 0000000..963cf9b
--- /dev/null
+++ b/src/cmd/cgo/internal/teststdio/testdata/chain.out
@@ -0,0 +1,55 @@
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
diff --git a/src/cmd/cgo/internal/teststdio/testdata/fib.go b/src/cmd/cgo/internal/teststdio/testdata/fib.go
new file mode 100644
index 0000000..9617368
--- /dev/null
+++ b/src/cmd/cgo/internal/teststdio/testdata/fib.go
@@ -0,0 +1,50 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build test_run
+
+// Compute Fibonacci numbers with two goroutines
+// that pass integers back and forth. No actual
+// concurrency, just threads and synchronization
+// and foreign code on multiple pthreads.
+
+package main
+
+import (
+ "runtime"
+ "strconv"
+
+ "cgostdio/stdio"
+)
+
+func fibber(c, out chan int64, i int64) {
+ // Keep the fibbers in dedicated operating system
+ // threads, so that this program tests coordination
+ // between pthreads and not just goroutines.
+ runtime.LockOSThread()
+
+ if i == 0 {
+ c <- i
+ }
+ for {
+ j := <-c
+ stdio.Stdout.WriteString(strconv.FormatInt(j, 10) + "\n")
+ out <- j
+ <-out
+ i += j
+ c <- i
+ }
+}
+
+func main() {
+ c := make(chan int64)
+ out := make(chan int64)
+ go fibber(c, out, 0)
+ go fibber(c, out, 1)
+ <-out
+ for i := 0; i < 90; i++ {
+ out <- 1
+ <-out
+ }
+}
diff --git a/src/cmd/cgo/internal/teststdio/testdata/fib.out b/src/cmd/cgo/internal/teststdio/testdata/fib.out
new file mode 100644
index 0000000..17ff503
--- /dev/null
+++ b/src/cmd/cgo/internal/teststdio/testdata/fib.out
@@ -0,0 +1,91 @@
+0
+1
+1
+2
+3
+5
+8
+13
+21
+34
+55
+89
+144
+233
+377
+610
+987
+1597
+2584
+4181
+6765
+10946
+17711
+28657
+46368
+75025
+121393
+196418
+317811
+514229
+832040
+1346269
+2178309
+3524578
+5702887
+9227465
+14930352
+24157817
+39088169
+63245986
+102334155
+165580141
+267914296
+433494437
+701408733
+1134903170
+1836311903
+2971215073
+4807526976
+7778742049
+12586269025
+20365011074
+32951280099
+53316291173
+86267571272
+139583862445
+225851433717
+365435296162
+591286729879
+956722026041
+1548008755920
+2504730781961
+4052739537881
+6557470319842
+10610209857723
+17167680177565
+27777890035288
+44945570212853
+72723460248141
+117669030460994
+190392490709135
+308061521170129
+498454011879264
+806515533049393
+1304969544928657
+2111485077978050
+3416454622906707
+5527939700884757
+8944394323791464
+14472334024676221
+23416728348467685
+37889062373143906
+61305790721611591
+99194853094755497
+160500643816367088
+259695496911122585
+420196140727489673
+679891637638612258
+1100087778366101931
+1779979416004714189
+2880067194370816120
diff --git a/src/cmd/cgo/internal/teststdio/testdata/hello.go b/src/cmd/cgo/internal/teststdio/testdata/hello.go
new file mode 100644
index 0000000..c0b52bf
--- /dev/null
+++ b/src/cmd/cgo/internal/teststdio/testdata/hello.go
@@ -0,0 +1,13 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build test_run
+
+package main
+
+import "cgostdio/stdio"
+
+func main() {
+ stdio.Stdout.WriteString(stdio.Greeting + "\n")
+}
diff --git a/src/cmd/cgo/internal/teststdio/testdata/hello.out b/src/cmd/cgo/internal/teststdio/testdata/hello.out
new file mode 100644
index 0000000..4b5fa63
--- /dev/null
+++ b/src/cmd/cgo/internal/teststdio/testdata/hello.out
@@ -0,0 +1 @@
+hello, world
diff --git a/src/cmd/cgo/internal/teststdio/testdata/stdio/file.go b/src/cmd/cgo/internal/teststdio/testdata/stdio/file.go
new file mode 100644
index 0000000..d97ee4c
--- /dev/null
+++ b/src/cmd/cgo/internal/teststdio/testdata/stdio/file.go
@@ -0,0 +1,42 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+A trivial example of wrapping a C library in Go.
+For a more complex example and explanation,
+see misc/cgo/gmp/gmp.go.
+*/
+
+package stdio
+
+/*
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+char* greeting = "hello, world";
+*/
+import "C"
+import "unsafe"
+
+type File C.FILE
+
+// Test reference to library symbol.
+// Stdout and stderr are too special to be a reliable test.
+//var = C.environ
+
+func (f *File) WriteString(s string) {
+ p := C.CString(s)
+ C.fputs(p, (*C.FILE)(f))
+ C.free(unsafe.Pointer(p))
+ f.Flush()
+}
+
+func (f *File) Flush() {
+ C.fflush((*C.FILE)(f))
+}
+
+var Greeting = C.GoString(C.greeting)
+var Gbytes = C.GoBytes(unsafe.Pointer(C.greeting), C.int(len(Greeting)))
diff --git a/src/cmd/cgo/internal/teststdio/testdata/stdio/stdio.go b/src/cmd/cgo/internal/teststdio/testdata/stdio/stdio.go
new file mode 100644
index 0000000..08286d4
--- /dev/null
+++ b/src/cmd/cgo/internal/teststdio/testdata/stdio/stdio.go
@@ -0,0 +1,20 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package stdio
+
+/*
+#include <stdio.h>
+
+// on mingw, stderr and stdout are defined as &_iob[FILENO]
+// on netbsd, they are defined as &__sF[FILENO]
+// and cgo doesn't recognize them, so write a function to get them,
+// instead of depending on internals of libc implementation.
+FILE *getStdout(void) { return stdout; }
+FILE *getStderr(void) { return stderr; }
+*/
+import "C"
+
+var Stdout = (*File)(C.getStdout())
+var Stderr = (*File)(C.getStderr())