summaryrefslogtreecommitdiff
path: root/test/chan/select5.go
diff options
context:
space:
mode:
Diffstat (limited to 'test/chan/select5.go')
-rw-r--r--test/chan/select5.go482
1 files changed, 0 insertions, 482 deletions
diff --git a/test/chan/select5.go b/test/chan/select5.go
deleted file mode 100644
index e7ca9e015..000000000
--- a/test/chan/select5.go
+++ /dev/null
@@ -1,482 +0,0 @@
-// $G $D/$F.go && $L $F.$A && ./$A.out >tmp.go &&
-// $G tmp.go && $L tmp.$A && ./$A.out || echo BUG: select5
-// rm -f tmp.go
-
-// Copyright 2011 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.
-
-// Generate test of channel operations and simple selects.
-// Only doing one real send or receive at a time, but phrased
-// in various ways that the compiler may or may not rewrite
-// into simpler expressions.
-
-package main
-
-import (
- "bufio"
- "fmt"
- "io"
- "os"
- "template"
-)
-
-func main() {
- out := bufio.NewWriter(os.Stdout)
- fmt.Fprintln(out, header)
- a := new(arg)
-
- // Generate each kind of test as a separate function to avoid
- // hitting the 6g optimizer with one enormous function.
- // If we name all the functions init we don't have to
- // maintain a list of which ones to run.
- do := func(t *template.Template) {
- fmt.Fprintln(out, `func init() {`)
- for ; next(); a.reset() {
- run(t, a, out)
- }
- fmt.Fprintln(out, `}`)
- }
-
- do(recv)
- do(send)
- do(recvOrder)
- do(sendOrder)
- do(nonblock)
-
- fmt.Fprintln(out, "//", a.nreset, "cases")
- out.Flush()
-}
-
-func run(t *template.Template, a interface{}, out io.Writer) {
- if err := t.Execute(out, a); err != nil {
- panic(err)
- }
-}
-
-type arg struct{
- def bool
- nreset int
-}
-
-func (a *arg) Maybe() bool {
- return maybe()
-}
-
-func (a *arg) MaybeDefault() bool {
- if a.def {
- return false
- }
- a.def = maybe()
- return a.def
-}
-
-func (a *arg) MustDefault() bool {
- return !a.def
-}
-
-func (a *arg) reset() {
- a.def = false
- a.nreset++
-}
-
-const header = `// GENERATED BY select5.go; DO NOT EDIT
-
-package main
-
-// channel is buffered so test is single-goroutine.
-// we are not interested in the concurrency aspects
-// of select, just testing that the right calls happen.
-var c = make(chan int, 1)
-var nilch chan int
-var n = 1
-var x int
-var i interface{}
-var dummy = make(chan int)
-var m = make(map[int]int)
-var order = 0
-
-func f(p *int) *int {
- return p
-}
-
-// check order of operations by ensuring that
-// successive calls to checkorder have increasing o values.
-func checkorder(o int) {
- if o <= order {
- println("invalid order", o, "after", order)
- panic("order")
- }
- order = o
-}
-
-func fc(c chan int, o int) chan int {
- checkorder(o)
- return c
-}
-
-func fp(p *int, o int) *int {
- checkorder(o)
- return p
-}
-
-func fn(n, o int) int {
- checkorder(o)
- return n
-}
-
-func die(x int) {
- println("have", x, "want", n)
- panic("chan")
-}
-
-func main() {
- // everything happens in init funcs
-}
-`
-
-func parse(s string) *template.Template {
- t := template.New(nil)
- t.SetDelims("〈", "〉")
- if err := t.Parse(s); err != nil {
- panic(s)
- }
- return t
-}
-
-var recv = parse(`
- 〈# Send n, receive it one way or another into x, check that they match.〉
- c <- n
- 〈.section Maybe〉
- x = <-c
- 〈.or〉
- select {
- 〈# Blocking or non-blocking, before the receive.〉
- 〈# The compiler implements two-case select where one is default with custom code,〉
- 〈# so test the default branch both before and after the send.〉
- 〈.section MaybeDefault〉
- default:
- panic("nonblock")
- 〈.end〉
- 〈# Receive from c. Different cases are direct, indirect, :=, interface, and map assignment.〉
- 〈.section Maybe〉
- case x = <-c:
- 〈.or〉〈.section Maybe〉
- case *f(&x) = <-c:
- 〈.or〉〈.section Maybe〉
- case y := <-c:
- x = y
- 〈.or〉〈.section Maybe〉
- case i = <-c:
- x = i.(int)
- 〈.or〉
- case m[13] = <-c:
- x = m[13]
- 〈.end〉〈.end〉〈.end〉〈.end〉
- 〈# Blocking or non-blocking again, after the receive.〉
- 〈.section MaybeDefault〉
- default:
- panic("nonblock")
- 〈.end〉
- 〈# Dummy send, receive to keep compiler from optimizing select.〉
- 〈.section Maybe〉
- case dummy <- 1:
- panic("dummy send")
- 〈.end〉
- 〈.section Maybe〉
- case <-dummy:
- panic("dummy receive")
- 〈.end〉
- 〈# Nil channel send, receive to keep compiler from optimizing select.〉
- 〈.section Maybe〉
- case nilch <- 1:
- panic("nilch send")
- 〈.end〉
- 〈.section Maybe〉
- case <-nilch:
- panic("nilch recv")
- 〈.end〉
- }
- 〈.end〉
- if x != n {
- die(x)
- }
- n++
-`)
-
-var recvOrder = parse(`
- 〈# Send n, receive it one way or another into x, check that they match.〉
- 〈# Check order of operations along the way by calling functions that check〉
- 〈# that the argument sequence is strictly increasing.〉
- order = 0
- c <- n
- 〈.section Maybe〉
- 〈# Outside of select, left-to-right rule applies.〉
- 〈# (Inside select, assignment waits until case is chosen,〉
- 〈# so right hand side happens before anything on left hand side.〉
- *fp(&x, 1) = <-fc(c, 2)
- 〈.or〉〈.section Maybe〉
- m[fn(13, 1)] = <-fc(c, 2)
- x = m[13]
- 〈.or〉
- select {
- 〈# Blocking or non-blocking, before the receive.〉
- 〈# The compiler implements two-case select where one is default with custom code,〉
- 〈# so test the default branch both before and after the send.〉
- 〈.section MaybeDefault〉
- default:
- panic("nonblock")
- 〈.end〉
- 〈# Receive from c. Different cases are direct, indirect, :=, interface, and map assignment.〉
- 〈.section Maybe〉
- case *fp(&x, 100) = <-fc(c, 1):
- 〈.or〉〈.section Maybe〉
- case y := <-fc(c, 1):
- x = y
- 〈.or〉〈.section Maybe〉
- case i = <-fc(c, 1):
- x = i.(int)
- 〈.or〉
- case m[fn(13, 100)] = <-fc(c, 1):
- x = m[13]
- 〈.end〉〈.end〉〈.end〉
- 〈# Blocking or non-blocking again, after the receive.〉
- 〈.section MaybeDefault〉
- default:
- panic("nonblock")
- 〈.end〉
- 〈# Dummy send, receive to keep compiler from optimizing select.〉
- 〈.section Maybe〉
- case fc(dummy, 2) <- fn(1, 3):
- panic("dummy send")
- 〈.end〉
- 〈.section Maybe〉
- case <-fc(dummy, 4):
- panic("dummy receive")
- 〈.end〉
- 〈# Nil channel send, receive to keep compiler from optimizing select.〉
- 〈.section Maybe〉
- case fc(nilch, 5) <- fn(1, 6):
- panic("nilch send")
- 〈.end〉
- 〈.section Maybe〉
- case <-fc(nilch, 7):
- panic("nilch recv")
- 〈.end〉
- }
- 〈.end〉〈.end〉
- if x != n {
- die(x)
- }
- n++
-`)
-
-var send = parse(`
- 〈# Send n one way or another, receive it into x, check that they match.〉
- 〈.section Maybe〉
- c <- n
- 〈.or〉
- select {
- 〈# Blocking or non-blocking, before the receive (same reason as in recv).〉
- 〈.section MaybeDefault〉
- default:
- panic("nonblock")
- 〈.end〉
- 〈# Send c <- n. No real special cases here, because no values come back〉
- 〈# from the send operation.〉
- case c <- n:
- 〈# Blocking or non-blocking.〉
- 〈.section MaybeDefault〉
- default:
- panic("nonblock")
- 〈.end〉
- 〈# Dummy send, receive to keep compiler from optimizing select.〉
- 〈.section Maybe〉
- case dummy <- 1:
- panic("dummy send")
- 〈.end〉
- 〈.section Maybe〉
- case <-dummy:
- panic("dummy receive")
- 〈.end〉
- 〈# Nil channel send, receive to keep compiler from optimizing select.〉
- 〈.section Maybe〉
- case nilch <- 1:
- panic("nilch send")
- 〈.end〉
- 〈.section Maybe〉
- case <-nilch:
- panic("nilch recv")
- 〈.end〉
- }
- 〈.end〉
- x = <-c
- if x != n {
- die(x)
- }
- n++
-`)
-
-var sendOrder = parse(`
- 〈# Send n one way or another, receive it into x, check that they match.〉
- 〈# Check order of operations along the way by calling functions that check〉
- 〈# that the argument sequence is strictly increasing.〉
- order = 0
- 〈.section Maybe〉
- fc(c, 1) <- fn(n, 2)
- 〈.or〉
- select {
- 〈# Blocking or non-blocking, before the receive (same reason as in recv).〉
- 〈.section MaybeDefault〉
- default:
- panic("nonblock")
- 〈.end〉
- 〈# Send c <- n. No real special cases here, because no values come back〉
- 〈# from the send operation.〉
- case fc(c, 1) <- fn(n, 2):
- 〈# Blocking or non-blocking.〉
- 〈.section MaybeDefault〉
- default:
- panic("nonblock")
- 〈.end〉
- 〈# Dummy send, receive to keep compiler from optimizing select.〉
- 〈.section Maybe〉
- case fc(dummy, 3) <- fn(1, 4):
- panic("dummy send")
- 〈.end〉
- 〈.section Maybe〉
- case <-fc(dummy, 5):
- panic("dummy receive")
- 〈.end〉
- 〈# Nil channel send, receive to keep compiler from optimizing select.〉
- 〈.section Maybe〉
- case fc(nilch, 6) <- fn(1, 7):
- panic("nilch send")
- 〈.end〉
- 〈.section Maybe〉
- case <-fc(nilch, 8):
- panic("nilch recv")
- 〈.end〉
- }
- 〈.end〉
- x = <-c
- if x != n {
- die(x)
- }
- n++
-`)
-
-var nonblock = parse(`
- x = n
- 〈# Test various combinations of non-blocking operations.〉
- 〈# Receive assignments must not edit or even attempt to compute the address of the lhs.〉
- select {
- 〈.section MaybeDefault〉
- default:
- 〈.end〉
- 〈.section Maybe〉
- case dummy <- 1:
- panic("dummy <- 1")
- 〈.end〉
- 〈.section Maybe〉
- case nilch <- 1:
- panic("nilch <- 1")
- 〈.end〉
- 〈.section Maybe〉
- case <-dummy:
- panic("<-dummy")
- 〈.end〉
- 〈.section Maybe〉
- case x = <-dummy:
- panic("<-dummy x")
- 〈.end〉
- 〈.section Maybe〉
- case **(**int)(nil) = <-dummy:
- panic("<-dummy (and didn't crash saving result!)")
- 〈.end〉
- 〈.section Maybe〉
- case <-nilch:
- panic("<-nilch")
- 〈.end〉
- 〈.section Maybe〉
- case x = <-nilch:
- panic("<-nilch x")
- 〈.end〉
- 〈.section Maybe〉
- case **(**int)(nil) = <-nilch:
- panic("<-nilch (and didn't crash saving result!)")
- 〈.end〉
- 〈.section MustDefault〉
- default:
- 〈.end〉
- }
- if x != n {
- die(x)
- }
- n++
-`)
-
-// Code for enumerating all possible paths through
-// some logic. The logic should call choose(n) when
-// it wants to choose between n possibilities.
-// On successive runs through the logic, choose(n)
-// will return 0, 1, ..., n-1. The helper maybe() is
-// similar but returns true and then false.
-//
-// Given a function gen that generates an output
-// using choose and maybe, code can generate all
-// possible outputs using
-//
-// for next() {
-// gen()
-// }
-
-type choice struct {
- i, n int
-}
-
-var choices []choice
-var cp int = -1
-
-func maybe() bool {
- return choose(2) == 0
-}
-
-func choose(n int) int {
- if cp >= len(choices) {
- // never asked this before: start with 0.
- choices = append(choices, choice{0, n})
- cp = len(choices)
- return 0
- }
- // otherwise give recorded answer
- if n != choices[cp].n {
- panic("inconsistent choices")
- }
- i := choices[cp].i
- cp++
- return i
-}
-
-func next() bool {
- if cp < 0 {
- // start a new round
- cp = 0
- return true
- }
-
- // increment last choice sequence
- cp = len(choices)-1
- for cp >= 0 && choices[cp].i == choices[cp].n-1 {
- cp--
- }
- if cp < 0 {
- choices = choices[:0]
- return false
- }
- choices[cp].i++
- choices = choices[:cp+1]
- cp = 0
- return true
-}
-