<commit_before>package again

import (
	"fmt"
	"io"
	"reflect"
)

func jsonToJson(r io.Reader, w io.Writer) {
	turnBothCranks(
		NewJsonDecoder(r),
		NewJsonEncoder(w),
	)
}

func turnBothCranks(tokenSrc TokenSrc, tokenSink TokenSink) error {
	var tok Token
	var srcDone, sinkDone bool
	var err error
	for {
		srcDone, err = tokenSrc.Step(&tok)
		if err != nil {
			return err
		}
		sinkDone, err = tokenSink.Step(&tok)
		if err != nil {
			return err
		}
		if srcDone {
			if sinkDone {
				return nil
			}
			return fmt.Errorf("src at end of item but sink expects more")
		}
	}
}

/*
	Fill with address of primitive (or []byte), or the magic const tokens
	for beginning and ending of maps and arrays.

	Decoder implementations are encouraged to use `util.DecodeBag` to contain
	primitives during decode, then return the address of the relevant
	primitive field from the `DecodeBag` as a `Token`.  This avoids repeated
	pointer allocations.
*/
type Token interface{}

const (
	Token_MapOpen  = '{'
	Token_MapClose = '}'
	Token_ArrOpen  = '['
	Token_ArrClose = ']'
)

type TokenSrc interface {
	Step(fillme *Token) (done bool, err error)
	Reset()
}

type TokenSink interface {
	Step(consume *Token) (done bool, err error)
	Reset()
}

//
// Constructors
//

func NewJsonDecoder(r io.Reader /* optional *JsonSchemaNotes */) TokenSrc  { return nil }
func NewJsonEncoder(w io.Writer /* optional *JsonSchemaNotes */) TokenSink { return nil }

func NewVarTokenizer(v interface{} /* TODO visitmagicks */) TokenSrc { return nil }
func NewVarReceiver(v interface{} /* TODO visitmagicks */) TokenSink { return nil }

type varReceiver struct {
	step func(*Token)
	done bool
	err  error
}

// used at initialization to figure out the first step given the type of var
//
func (vr *varReceiver) stepFor(v interface{}) func(*Token) {
	switch v.(type) {
	case *interface{}:
		return vr.step_AcceptAny // pick between a literal, and `map[string]interface{}` and `[]interface{}` based on the next token to come in.
	case *string, *[]byte:
		return vr.step_AcceptLiteral
	case *int, *int8, *int16, *int32, *int64:
		return vr.step_AcceptLiteral
	case *uint, *uint8, *uint16, *uint32, *uint64:
		return vr.step_AcceptLiteral
	default:
		// TODO mustAddressable check goes here.
		if reflect.TypeOf(v).Kind() == reflect.Interface {
			// special path because we can recycle the decoder machines, if they implement resettable.
		}
		// any other concrete type or particular interface:
		//  must have its own visit func defined.
		//  we don't know if it expects to be a map, lit, arr, etc until it takes over.
		//  (the rest of our functions here are the exception: they're half inlined here -- TODO maybe don't be like that; this lookup only makes sense for top level wtf-is-this'es)
		panic("TODO mappersuite lookup")
	}
}

func (vr *varReceiver) step_AcceptAny(tok *Token) {
	// If it's a special state, start an object.
	//  (Or, blow up if its a special state that's silly).
	switch *tok {
	case Token_MapOpen:
		var v map[string]interface{} // FIXME this should still be being pushed into top ref
		step := vr.stepFor(v)        // Get the step.
		step(tok)                    // Call it (with the same token, so it can consume it); it will set the next `vr.step`.
		return
	case Token_ArrOpen:
		var v []interface{}   // FIXME this should still be being pushed into top ref
		step := vr.stepFor(v) // Get the step.
		step(tok)             // Call it (with the same token, so it can consume it); it will set the next `vr.step`.
		return
	case Token_MapClose:
		panic("unexpected mapClose; expected start of value")
	case Token_ArrClose:
		panic("unexpected arrClose; expected start of value")
	}
	// If it wasn't the start of composite, check for a literal of understood kind.
	vr.step_AcceptLiteral(tok)
}

func (vr *varReceiver) step_AcceptLiteral(tok *Token) {
	acceptLiteral(nil /* ???*/, tok)
}

func acceptLiteral(v interface{}, tok *Token) {
	switch v2 := v.(type) {
	case *string:
		*v2 = (*tok).(string)
	case *[]byte:
		// FIXME again, need the top ref to push into
	case *int, *int8, *int16, *int32, *int64:
		// FIXME again, need the top ref to push into
	case *uint, *uint8, *uint16, *uint32, *uint64:
		// FIXME again, need the top ref to push into
	default:
		panic(fmt.Errorf("unexpected literal token of unknown type %T", *tok))
	}
}

/*
	Suppose we have the following var to unmarshal into:

		var thingy SomeType

	Where SomeType is defined as:

		type SomeType struct {
			AnInt int
			Something interface{}
		}

	The flow of a VarReciever working on this will be something like the following:

		- Begin handling a var of type `SomeType`.
		- Look up the hander for that type info.
		- The handler is accepts the val ref, and returns a step function.
		- The step function is called with the token.
		- [Much work ensues.]
		- If the step function returns done, we return entirely;
		  otherwise we hang onto the next stepFunc, and return.

	The flow of the specific handler for SomeType will look like this:

		- Expect a MapOpen token.
		- Expect a MapKey token.  Return a step func expecting that matching value.
		  - When called with the next token, this step func grabs the ref
		    of the struct field matching the name we were primed with...
		  - And calls dispatch on the whole thing.
		  - (Generally this func looks like it needs {fillingName string, rest},
		    so it can tell what value grab the ref to fill, and decide whether
			to return "expect all done" step.)
		- At any point, it may receive MapClose, which will jump to a check
		  that all fields are either noted as filled (requires sidebar) or
		  are tagged as omitEmpty.
*/

// Returns an atlas so we can use this to build the contin-passing machine without bothering you.
func HandleMe(vreal interface{}) (
	vmediate interface{},
	atl *Atlas,
	after func(), /* closure, already has vreal and vmediate refs */
) {
	return nil, nil, nil
}

type Atlas struct{}

type atlasDecoderMachine struct {
	val      reflect.Value // We're filling this.
	atl      *Atlas        // Our directions.
	step     func(*Token)  // The next step.
	key      string        // The key consumed by the prev `step_AcceptKey`.
	keysDone []string      // List of keys we've completed already (repeats aren't wanted).
}

func NewAtlasDecoderMachine(into reflect.Value, atl *Atlas) *atlasDecoderMachine {
	// TODO this return type should prob have some interface that covers it sufficiently.
	dm := &atlasDecoderMachine{
		atl: atl,
	}
	dm.Reset(into)
	return dm
}

func (dm *atlasDecoderMachine) Reset(into reflect.Value) {
	dm.val = into
	dm.step = dm.step_Initial
	dm.key = ""
	dm.keysDone = dm.keysDone[0:0]
}

func (dm *atlasDecoderMachine) step_Initial(tok *Token) {
	switch *tok {
	case Token_MapOpen:
		// Great.  Consumed.
		dm.step = dm.step_AcceptKey
	case Token_ArrOpen:
		panic("unexpected arrOpen; expected start of struct")
	case Token_MapClose:
		panic("unexpected mapClose; expected start of struct")
	case Token_ArrClose:
		panic("unexpected arrClose; expected start of struct")
	default:
		panic(fmt.Errorf("unexpected literal of type %T; expected start of struct", *tok))
	}
}

func (dm *atlasDecoderMachine) step_AcceptKey(tok *Token) {
	switch *tok {
	case Token_MapOpen:
		panic("unexpected mapOpen; expected map key")
	case Token_ArrOpen:
		panic("unexpected arrOpen; expected map key")
	case Token_MapClose:
		dm.handleEnd()
	case Token_ArrClose:
		panic("unexpected arrClose; expected map key")
	}
	switch k := (*tok).(type) {
	case *string:
		dm.key = *k
		dm.mustAcceptKey(*k)
		//dm.step = dm.step_AcceptValue
		// actually we might wanna just push up our plea now --
		//  this saves us from having to see and forward the token at all,
		//  and makes the pattern of fab-var-filler, ret step func(token) consistent.
		//  if you *really* wanted to implement a breakout for known prims, you could still do that branch here.
		//  HANG ON, nope: keep it in the value step and keep the tok passdown.
		//   do it for parity with arrays, which must have that step
		//   and accept that token during it so they can check for end there.
		/*
			driver.Fill(
				tok, // still meant for next person and the real step is to come; we just had to figure out types, here.
				dm.Addr(dm.key),
				dm.step_postValue(), // driver returns to us after the value is done by calling this.
				    // may actually be that we stash that stepfunc, and give driver more general self pointer and Resume func in interface.
			)
		*/
	default:
		panic(fmt.Errorf("unexpected literal of type %T; expected start of struct", *tok))
	}
}
func (dm *atlasDecoderMachine) mustAcceptKey(k string) {
	for _, x := range dm.keysDone {
		if x == k {
			panic(fmt.Errorf("repeated key %q", k))
		}
	}
	dm.keysDone = append(dm.keysDone, k)
}
func (dm *atlasDecoderMachine) addr(k string) interface{} {
	_ = dm.atl
	return nil // TODO
	// n.b. this is one of the spots where i can't decide if &thing or reflect.Value is better
	// but either way we may want to define a `Slot` type alias to make it readable
}

func (dm *atlasDecoderMachine) step_AcceptValue(tok *Token) {
}

func (dm *atlasDecoderMachine) handleEnd() {
	// TODO check for all filled, etc.  then set terminal states.
}
<commit_msg>Factor apart the wildcard machines.<commit_after>package again

import (
	"fmt"
	"io"
	"reflect"
)

func jsonToJson(r io.Reader, w io.Writer) {
	turnBothCranks(
		NewJsonDecoder(r),
		NewJsonEncoder(w),
	)
}

func turnBothCranks(tokenSrc TokenSrc, tokenSink TokenSink) error {
	var tok Token
	var srcDone, sinkDone bool
	var err error
	for {
		srcDone, err = tokenSrc.Step(&tok)
		if err != nil {
			return err
		}
		sinkDone, err = tokenSink.Step(&tok)
		if err != nil {
			return err
		}
		if srcDone {
			if sinkDone {
				return nil
			}
			return fmt.Errorf("src at end of item but sink expects more")
		}
	}
}

/*
	Fill with address of primitive (or []byte), or the magic const tokens
	for beginning and ending of maps and arrays.

	Decoder implementations are encouraged to use `util.DecodeBag` to contain
	primitives during decode, then return the address of the relevant
	primitive field from the `DecodeBag` as a `Token`.  This avoids repeated
	pointer allocations.
*/
type Token interface{}

const (
	Token_MapOpen  = '{'
	Token_MapClose = '}'
	Token_ArrOpen  = '['
	Token_ArrClose = ']'
)

type TokenSrc interface {
	Step(fillme *Token) (done bool, err error)
	Reset()
}

type TokenSink interface {
	Step(consume *Token) (done bool, err error)
	Reset()
}

//
// Constructors
//

func NewJsonDecoder(r io.Reader /* optional *JsonSchemaNotes */) TokenSrc  { return nil }
func NewJsonEncoder(w io.Writer /* optional *JsonSchemaNotes */) TokenSink { return nil }

func NewVarTokenizer(v interface{} /* TODO visitmagicks */) TokenSrc { return nil }
func NewVarReceiver(v interface{} /* TODO visitmagicks */) TokenSink { return nil }

type varReceiver struct {
	step func(*Token) (done bool, err error)
	done bool
	err  error
}

// used at initialization to figure out the first step given the type of var
//
func (vr *varReceiver) stepFor(v interface{}) func(*Token) (done bool, err error) {
	switch v.(type) {
	// For total wildcards:
	//  Return a machine that will pick between a literal or `map[string]interface{}`
	//  or `[]interface{}` based on the next token.
	case *interface{}:
		return wildcardStep(v)
	// For single literals:
	//  we have a single machine that handles all these.
	case *string, *[]byte,
		*int, *int8, *int16, *int32, *int64,
		*uint, *uint8, *uint16, *uint32, *uint64:
		dec := &literalDecoderMachine{}
		dec.Reset(v)
		return dec.Step
	// Anything that has real type info:
	//  ... Plaaaay ball!
	default:
		// TODO mustAddressable check goes here.
		if reflect.TypeOf(v).Kind() == reflect.Interface {
			// special path because we can recycle the decoder machines, if they implement resettable.
		}
		// any other concrete type or particular interface:
		//  must have its own visit func defined.
		//  we don't know if it expects to be a map, lit, arr, etc until it takes over.
		//  (the rest of our functions here are the exception: they're half inlined here -- TODO maybe don't be like that; this lookup only makes sense for top level wtf-is-this'es)
		panic("TODO mappersuite lookup")
	}
}

func wildcardStep(target interface{}) func(*Token) (bool, error) {
	return func(tok *Token) (done bool, err error) {
		// If it's a special state, start an object.
		//  (Or, blow up if its a special state that's silly).
		switch *tok {
		case Token_MapOpen:
			// Fill in our wildcard ref with a blank map,
			//  and make a new machine for it; hand off everything.
			target = make(map[string]interface{})
			dec := &wildcardMapDecoderMachine{}
			dec.Reset(target)
			return dec.Step(tok)
		case Token_ArrOpen:
			// TODO same as maps, but with a machine for arrays
			panic("NYI")
		case Token_MapClose:
			return true, fmt.Errorf("unexpected mapClose; expected start of value")
		case Token_ArrClose:
			return true, fmt.Errorf("unexpected arrClose; expected start of value")
		default:
			// If it wasn't the start of composite, shell out to the machine for literals.
			dec := &literalDecoderMachine{}
			dec.Reset(target)
			return dec.Step(tok)
		}
	}
}

type wildcardMapDecoderMachine struct {
	target map[string]interface{}
	step   func(*Token) (done bool, err error)
	key    string // The key consumed by the prev `step_AcceptKey`.
}

func (dm *wildcardMapDecoderMachine) Reset(target interface{}) {
	dm.target = target.(map[string]interface{})
	dm.step = dm.step_Initial
	dm.key = ""
}

func (dm *wildcardMapDecoderMachine) Step(tok *Token) (done bool, err error) {
	return dm.step(tok)
}

func (dm *wildcardMapDecoderMachine) step_Initial(tok *Token) (done bool, err error) {
	// If it's a special state, start an object.
	//  (Or, blow up if its a special state that's silly).
	switch *tok {
	case Token_MapOpen:
		// Great.  Consumed.
		dm.step = dm.step_AcceptKey
		return false, nil
	case Token_ArrOpen:
		return true, fmt.Errorf("unexpected arrOpen; expected start of map")
	case Token_MapClose:
		return true, fmt.Errorf("unexpected mapClose; expected start of map")
	case Token_ArrClose:
		return true, fmt.Errorf("unexpected arrClose; expected start of map")
	default:
		panic(fmt.Errorf("unexpected literal of type %T; expected start of map", *tok))
	}
}
func (dm *wildcardMapDecoderMachine) step_AcceptKey(tok *Token) (done bool, err error) {
	switch *tok {
	case Token_MapOpen:
		return true, fmt.Errorf("unexpected mapOpen; expected map key")
	case Token_ArrOpen:
		return true, fmt.Errorf("unexpected arrOpen; expected map key")
	case Token_MapClose:
		// no special checks for ends of wildcard map; no such thing as incomplete.
		return true, nil
	case Token_ArrClose:
		return true, fmt.Errorf("unexpected arrClose; expected map key")
	}
	switch k := (*tok).(type) {
	case *string:
		if err = dm.mustAcceptKey(*k); err != nil {
			return true, err
		}
		dm.key = *k
		dm.step = dm.step_AcceptValue
		return false, nil
	default:
		panic(fmt.Errorf("unexpected literal of type %T; expected start of struct", *tok))
	}
}
func (dm *wildcardMapDecoderMachine) mustAcceptKey(k string) error {
	if _, exists := dm.target[k]; exists {
		return fmt.Errorf("repeated key %q", k)
	}
	return nil
}

func (dm *wildcardMapDecoderMachine) step_AcceptValue(tok *Token) (done bool, err error) {
	/*
		driver.Fill(
			tok, // still meant for next person and the real step is to come; we just had to figure out types, here.
			dm.Addr(dm.key),
			dm.step_postValue(), // driver returns to us after the value is done by calling this.
			    // may actually be that we stash that stepfunc, and give driver more general self pointer and Resume func in interface.
		)
	*/
	return false, nil // TODO
}

type literalDecoderMachine struct {
	target interface{}
}

func (dm *literalDecoderMachine) Reset(target interface{}) {
	dm.target = target
}

func (dm *literalDecoderMachine) Step(tok *Token) (done bool, err error) {
	var ok bool
	switch v2 := dm.target.(type) {
	case *string:
		*v2, ok = (*tok).(string)
	case *[]byte:
		panic("TODO")
	case *int, *int8, *int16, *int32, *int64:
		panic("TODO")
	case *uint, *uint8, *uint16, *uint32, *uint64:
		panic("TODO")
	default:
		panic(fmt.Errorf("cannot unmarshall into unhandled type %T", dm.target))
	}
	if ok {
		return true, nil
	}
	return true, fmt.Errorf("unexpected token of type %T, expected literal of type %T", *tok, dm.target)
}

/*
	Suppose we have the following var to unmarshal into:

		var thingy SomeType

	Where SomeType is defined as:

		type SomeType struct {
			AnInt int
			Something interface{}
		}

	The flow of a VarReciever working on this will be something like the following:

		- Begin handling a var of type `SomeType`.
		- Look up the hander for that type info.
		- The handler is accepts the val ref, and returns a step function.
		- The step function is called with the token.
		- [Much work ensues.]
		- If the step function returns done, we return entirely;
		  otherwise we hang onto the next stepFunc, and return.

	The flow of the specific handler for SomeType will look like this:

		- Expect a MapOpen token.
		- Expect a MapKey token.  Return a step func expecting that matching value.
		  - When called with the next token, this step func grabs the ref
		    of the struct field matching the name we were primed with...
		  - And calls dispatch on the whole thing.
		  - (Generally this func looks like it needs {fillingName string, rest},
		    so it can tell what value grab the ref to fill, and decide whether
			to return "expect all done" step.)
		- At any point, it may receive MapClose, which will jump to a check
		  that all fields are either noted as filled (requires sidebar) or
		  are tagged as omitEmpty.
*/

// Returns an atlas so we can use this to build the contin-passing machine without bothering you.
func HandleMe(vreal interface{}) (
	vmediate interface{},
	atl *Atlas,
	after func(), /* closure, already has vreal and vmediate refs */
) {
	return nil, nil, nil
}

type Atlas struct{}

type atlasDecoderMachine struct {
	val      reflect.Value // We're filling this.
	atl      *Atlas        // Our directions.
	step     func(*Token)  // The next step.
	key      string        // The key consumed by the prev `step_AcceptKey`.
	keysDone []string      // List of keys we've completed already (repeats aren't wanted).
}

func NewAtlasDecoderMachine(into reflect.Value, atl *Atlas) *atlasDecoderMachine {
	// TODO this return type should prob have some interface that covers it sufficiently.
	dm := &atlasDecoderMachine{
		atl: atl,
	}
	dm.Reset(into)
	return dm
}

func (dm *atlasDecoderMachine) Reset(into reflect.Value) {
	dm.val = into
	dm.step = dm.step_Initial
	dm.key = ""
	dm.keysDone = dm.keysDone[0:0]
}

func (dm *atlasDecoderMachine) step_Initial(tok *Token) {
	switch *tok {
	case Token_MapOpen:
		// Great.  Consumed.
		dm.step = dm.step_AcceptKey
	case Token_ArrOpen:
		panic("unexpected arrOpen; expected start of struct")
	case Token_MapClose:
		panic("unexpected mapClose; expected start of struct")
	case Token_ArrClose:
		panic("unexpected arrClose; expected start of struct")
	default:
		panic(fmt.Errorf("unexpected literal of type %T; expected start of struct", *tok))
	}
}

func (dm *atlasDecoderMachine) step_AcceptKey(tok *Token) {
	switch *tok {
	case Token_MapOpen:
		panic("unexpected mapOpen; expected map key")
	case Token_ArrOpen:
		panic("unexpected arrOpen; expected map key")
	case Token_MapClose:
		dm.handleEnd()
	case Token_ArrClose:
		panic("unexpected arrClose; expected map key")
	}
	switch k := (*tok).(type) {
	case *string:
		dm.key = *k
		dm.mustAcceptKey(*k)
		//dm.step = dm.step_AcceptValue
		// actually we might wanna just push up our plea now --
		//  this saves us from having to see and forward the token at all,
		//  and makes the pattern of fab-var-filler, ret step func(token) consistent.
		//  if you *really* wanted to implement a breakout for known prims, you could still do that branch here.
		//  HANG ON, nope: keep it in the value step and keep the tok passdown.
		//   do it for parity with arrays, which must have that step
		//   and accept that token during it so they can check for end there.
		/*
			driver.Fill(
				tok, // still meant for next person and the real step is to come; we just had to figure out types, here.
				dm.Addr(dm.key),
				dm.step_postValue(), // driver returns to us after the value is done by calling this.
				    // may actually be that we stash that stepfunc, and give driver more general self pointer and Resume func in interface.
			)
		*/
	default:
		panic(fmt.Errorf("unexpected literal of type %T; expected start of struct", *tok))
	}
}
func (dm *atlasDecoderMachine) mustAcceptKey(k string) {
	for _, x := range dm.keysDone {
		if x == k {
			panic(fmt.Errorf("repeated key %q", k))
		}
	}
	dm.keysDone = append(dm.keysDone, k)
}
func (dm *atlasDecoderMachine) addr(k string) interface{} {
	_ = dm.atl
	return nil // TODO
	// n.b. this is one of the spots where i can't decide if &thing or reflect.Value is better
	// but either way we may want to define a `Slot` type alias to make it readable
}

func (dm *atlasDecoderMachine) step_AcceptValue(tok *Token) {
}

func (dm *atlasDecoderMachine) handleEnd() {
	// TODO check for all filled, etc.  then set terminal states.
}
<|endoftext|>


<commit_before>// Copyright 2016 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 agent provides hooks programs can register to retrieve
// diagnostics data by using gops.
package agent

import (
	"fmt"
	"hello/gops/agent/signal"
	"log"
	"net"
	"os"
	"runtime"
)

func init() {
	sock := fmt.Sprintf("/tmp/gops%d.sock", os.Getpid())
	l, err := net.Listen("unix", sock)
	if err != nil {
		log.Fatal(err)
	}
	// TODO(jbd): cleanup the socket on shutdown.
	go func() {
		buf := make([]byte, 1)
		for {
			fd, err := l.Accept()
			if err != nil {
				fmt.Fprintf(os.Stderr, "gops: %v", err)
				continue
			}
			if _, err := fd.Read(buf); err != nil {
				fmt.Fprintf(os.Stderr, "gops: %v", err)
				continue
			}
			if err := handle(fd, buf); err != nil {
				fmt.Fprintf(os.Stderr, "gops: %v", err)
				continue
			}
			fd.Close()
		}
	}()
}

func handle(conn net.Conn, msg []byte) error {
	switch msg[0] {
	case signal.Stack:
		buf := make([]byte, 1<<16)
		n := runtime.Stack(buf, true)
		_, err := conn.Write(buf[:n])
		return err
	case signal.GC:
		runtime.GC()
		_, err := conn.Write([]byte("ok"))
		return err
	case signal.MemStats:
		var s runtime.MemStats
		runtime.ReadMemStats(&s)
		fmt.Fprintf(conn, "alloc: %v\n", s.Alloc)
		fmt.Fprintf(conn, "total-alloc: %v\n", s.TotalAlloc)
		fmt.Fprintf(conn, "sys: %v\n", s.Sys)
		fmt.Fprintf(conn, "lookups: %v\n", s.Lookups)
		fmt.Fprintf(conn, "mallocs: %v\n", s.Mallocs)
		fmt.Fprintf(conn, "frees: %v\n", s.Frees)
		fmt.Fprintf(conn, "heap-alloc: %v\n", s.HeapAlloc)
		fmt.Fprintf(conn, "heap-sys: %v\n", s.HeapSys)
		fmt.Fprintf(conn, "heap-idle: %v\n", s.HeapIdle)
		fmt.Fprintf(conn, "heap-in-use: %v\n", s.HeapInuse)
		fmt.Fprintf(conn, "heap-released: %v\n", s.HeapReleased)
		fmt.Fprintf(conn, "heap-objects: %v\n", s.HeapObjects)
		fmt.Fprintf(conn, "stack-in-use: %v\n", s.StackInuse)
		fmt.Fprintf(conn, "stack-sys: %v\n", s.StackSys)
		fmt.Fprintf(conn, "next-gc: %v\n", s.NextGC)
		fmt.Fprintf(conn, "last-gc: %v ns ago\n", s.LastGC)
		fmt.Fprintf(conn, "gc-pause: %v ns\n", s.PauseTotalNs)
		fmt.Fprintf(conn, "num-gc: %v\n", s.NumGC)
		fmt.Fprintf(conn, "enable-gc: %v\n", s.EnableGC)
		fmt.Fprintf(conn, "debug-gc: %v\n", s.DebugGC)
	case signal.Version:
		fmt.Fprintf(conn, "%v\n", runtime.Version())

	}
	return nil
}
<commit_msg>cleanup socket on shutdown<commit_after>// Copyright 2016 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 agent provides hooks programs can register to retrieve
// diagnostics data by using gops.
package agent

import (
	"fmt"
	"log"
	"net"
	"os"
	gosignal "os/signal"
	"runtime"

	"hello/gops/agent/signal"
)

func init() {
	sock := fmt.Sprintf("/tmp/gops%d.sock", os.Getpid())
	l, err := net.Listen("unix", sock)
	if err != nil {
		log.Fatal(err)
	}

	c := make(chan os.Signal, 1)
	gosignal.Notify(c, os.Interrupt)
	go func() {
		// cleanup the socket on shutdown.
		<-c
		os.Remove(sock)
		os.Exit(1)
	}()

	go func() {
		buf := make([]byte, 1)
		for {
			fd, err := l.Accept()
			if err != nil {
				fmt.Fprintf(os.Stderr, "gops: %v", err)
				continue
			}
			if _, err := fd.Read(buf); err != nil {
				fmt.Fprintf(os.Stderr, "gops: %v", err)
				continue
			}
			if err := handle(fd, buf); err != nil {
				fmt.Fprintf(os.Stderr, "gops: %v", err)
				continue
			}
			fd.Close()
		}
	}()
}

func handle(conn net.Conn, msg []byte) error {
	switch msg[0] {
	case signal.Stack:
		buf := make([]byte, 1<<16)
		n := runtime.Stack(buf, true)
		_, err := conn.Write(buf[:n])
		return err
	case signal.GC:
		runtime.GC()
		_, err := conn.Write([]byte("ok"))
		return err
	case signal.MemStats:
		var s runtime.MemStats
		runtime.ReadMemStats(&s)
		fmt.Fprintf(conn, "alloc: %v\n", s.Alloc)
		fmt.Fprintf(conn, "total-alloc: %v\n", s.TotalAlloc)
		fmt.Fprintf(conn, "sys: %v\n", s.Sys)
		fmt.Fprintf(conn, "lookups: %v\n", s.Lookups)
		fmt.Fprintf(conn, "mallocs: %v\n", s.Mallocs)
		fmt.Fprintf(conn, "frees: %v\n", s.Frees)
		fmt.Fprintf(conn, "heap-alloc: %v\n", s.HeapAlloc)
		fmt.Fprintf(conn, "heap-sys: %v\n", s.HeapSys)
		fmt.Fprintf(conn, "heap-idle: %v\n", s.HeapIdle)
		fmt.Fprintf(conn, "heap-in-use: %v\n", s.HeapInuse)
		fmt.Fprintf(conn, "heap-released: %v\n", s.HeapReleased)
		fmt.Fprintf(conn, "heap-objects: %v\n", s.HeapObjects)
		fmt.Fprintf(conn, "stack-in-use: %v\n", s.StackInuse)
		fmt.Fprintf(conn, "stack-sys: %v\n", s.StackSys)
		fmt.Fprintf(conn, "next-gc: %v\n", s.NextGC)
		fmt.Fprintf(conn, "last-gc: %v ns ago\n", s.LastGC)
		fmt.Fprintf(conn, "gc-pause: %v ns\n", s.PauseTotalNs)
		fmt.Fprintf(conn, "num-gc: %v\n", s.NumGC)
		fmt.Fprintf(conn, "enable-gc: %v\n", s.EnableGC)
		fmt.Fprintf(conn, "debug-gc: %v\n", s.DebugGC)
	case signal.Version:
		fmt.Fprintf(conn, "%v\n", runtime.Version())

	}
	return nil
}
<|endoftext|>


<commit_before>package baggageclaimcmd

import (
	"fmt"
	"os"
	"runtime"
	"time"

	"code.cloudfoundry.org/clock"
	"code.cloudfoundry.org/lager"
	"github.com/concourse/baggageclaim/api"
	"github.com/concourse/baggageclaim/reaper"
	"github.com/concourse/baggageclaim/uidgid"
	"github.com/concourse/baggageclaim/volume"
	"github.com/concourse/baggageclaim/volume/driver"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/grouper"
	"github.com/tedsuo/ifrit/http_server"
	"github.com/tedsuo/ifrit/sigmon"
	"github.com/xoebus/zest"
)

type BaggageclaimCommand struct {
	Logger LagerFlag

	BindIP   IPFlag `long:"bind-ip"   default:"127.0.0.1" description:"IP address on which to listen for API traffic."`
	BindPort uint16 `long:"bind-port" default:"7788"      description:"Port on which to listen for API traffic."`

	VolumesDir DirFlag `long:"volumes" required:"true" description:"Directory in which to place volume data."`

	Driver   string `long:"driver" default:"naive" choice:"naive" choice:"btrfs" description:"Driver to use for managing volumes."`
	BtrfsBin string `long:"btrfs-bin" default:"btrfs" description:"Path to btrfs binary"`
	MkfsBin  string `long:"mkfs-bin" default:"mkfs.btrfs" description:"Path to mkfs.btrfs binary"`

	ReapInterval time.Duration `long:"reap-interval" default:"10s" description:"Interval on which to reap expired volumes."`

	Metrics struct {
		YellerAPIKey      string `long:"yeller-api-key"     description:"Yeller API key. If specified, all errors logged will be emitted."`
		YellerEnvironment string `long:"yeller-environment" description:"Environment to tag on all Yeller events emitted."`
	} `group:"Metrics & Diagnostics"`
}

func (cmd *BaggageclaimCommand) Execute(args []string) error {
	runner, err := cmd.Runner(args)
	if err != nil {
		return err
	}

	return <-ifrit.Invoke(sigmon.New(runner)).Wait()
}

func (cmd *BaggageclaimCommand) Runner(args []string) (ifrit.Runner, error) {
	logger, _ := cmd.constructLogger()

	listenAddr := fmt.Sprintf("%s:%d", cmd.BindIP.IP(), cmd.BindPort)

	var volumeDriver volume.Driver

	if cmd.Driver == "btrfs" {
		volumeDriver = driver.NewBtrFSDriver(
			logger.Session("driver"),
			string(cmd.VolumesDir),
			cmd.BtrfsBin,
		)
	} else {
		volumeDriver = &driver.NaiveDriver{}
	}

	var namespacer uidgid.Namespacer

	maxUID, maxUIDErr := uidgid.DefaultUIDMap.MaxValid()
	maxGID, maxGIDErr := uidgid.DefaultGIDMap.MaxValid()

	if runtime.GOOS == "linux" && maxUIDErr == nil && maxGIDErr == nil {
		maxId := uidgid.Min(maxUID, maxGID)
		Translator := uidgid.NewTranslator(maxId)

		namespacer = &uidgid.UidNamespacer{
			Translator: Translator,
			Logger:     logger.Session("uid-namespacer"),
		}
	} else {
		namespacer = uidgid.NoopNamespacer{}
	}

	locker := volume.NewLockManager()

	filesystem, err := volume.NewFilesystem(volumeDriver, string(cmd.VolumesDir))
	if err != nil {
		logger.Fatal("failed-to-initialize-filesystem", err)
	}

	volumeRepo := volume.NewRepository(
		logger.Session("repository"),
		filesystem,
		locker,
	)

	strategerizer := volume.NewStrategerizer(namespacer)

	apiHandler, err := api.NewHandler(
		logger.Session("api"),
		strategerizer,
		namespacer,
		volumeRepo,
	)
	if err != nil {
		logger.Fatal("failed-to-create-handler", err)
	}

	clock := clock.NewClock()

	morbidReality := reaper.NewReaper(clock, volumeRepo)

	members := []grouper.Member{
		{"api", http_server.New(listenAddr, apiHandler)},
		{"reaper", reaper.NewRunner(logger, clock, cmd.ReapInterval, morbidReality.Reap)},
	}

	return onReady(grouper.NewParallel(os.Interrupt, members), func() {
		logger.Info("listening", lager.Data{
			"addr": listenAddr,
		})
	}), nil
}

func (cmd *BaggageclaimCommand) constructLogger() (lager.Logger, *lager.ReconfigurableSink) {
	logger, reconfigurableSink := cmd.Logger.Logger("baggageclaim")

	if cmd.Metrics.YellerAPIKey != "" {
		yellerSink := zest.NewYellerSink(cmd.Metrics.YellerAPIKey, cmd.Metrics.YellerEnvironment)
		logger.RegisterSink(yellerSink)
	}

	return logger, reconfigurableSink
}

func onReady(runner ifrit.Runner, cb func()) ifrit.Runner {
	return ifrit.RunFunc(func(signals <-chan os.Signal, ready chan<- struct{}) error {
		process := ifrit.Background(runner)

		subExited := process.Wait()
		subReady := process.Ready()

		for {
			select {
			case <-subReady:
				cb()
				subReady = nil
			case err := <-subExited:
				return err
			case sig := <-signals:
				process.Signal(sig)
			}
		}
	})
}
<commit_msg>use .Path<commit_after>package baggageclaimcmd

import (
	"fmt"
	"os"
	"runtime"
	"time"

	"code.cloudfoundry.org/clock"
	"code.cloudfoundry.org/lager"
	"github.com/concourse/baggageclaim/api"
	"github.com/concourse/baggageclaim/reaper"
	"github.com/concourse/baggageclaim/uidgid"
	"github.com/concourse/baggageclaim/volume"
	"github.com/concourse/baggageclaim/volume/driver"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/grouper"
	"github.com/tedsuo/ifrit/http_server"
	"github.com/tedsuo/ifrit/sigmon"
	"github.com/xoebus/zest"
)

type BaggageclaimCommand struct {
	Logger LagerFlag

	BindIP   IPFlag `long:"bind-ip"   default:"127.0.0.1" description:"IP address on which to listen for API traffic."`
	BindPort uint16 `long:"bind-port" default:"7788"      description:"Port on which to listen for API traffic."`

	VolumesDir DirFlag `long:"volumes" required:"true" description:"Directory in which to place volume data."`

	Driver   string `long:"driver" default:"naive" choice:"naive" choice:"btrfs" description:"Driver to use for managing volumes."`
	BtrfsBin string `long:"btrfs-bin" default:"btrfs" description:"Path to btrfs binary"`
	MkfsBin  string `long:"mkfs-bin" default:"mkfs.btrfs" description:"Path to mkfs.btrfs binary"`

	ReapInterval time.Duration `long:"reap-interval" default:"10s" description:"Interval on which to reap expired volumes."`

	Metrics struct {
		YellerAPIKey      string `long:"yeller-api-key"     description:"Yeller API key. If specified, all errors logged will be emitted."`
		YellerEnvironment string `long:"yeller-environment" description:"Environment to tag on all Yeller events emitted."`
	} `group:"Metrics & Diagnostics"`
}

func (cmd *BaggageclaimCommand) Execute(args []string) error {
	runner, err := cmd.Runner(args)
	if err != nil {
		return err
	}

	return <-ifrit.Invoke(sigmon.New(runner)).Wait()
}

func (cmd *BaggageclaimCommand) Runner(args []string) (ifrit.Runner, error) {
	logger, _ := cmd.constructLogger()

	listenAddr := fmt.Sprintf("%s:%d", cmd.BindIP.IP(), cmd.BindPort)

	var volumeDriver volume.Driver

	if cmd.Driver == "btrfs" {
		volumeDriver = driver.NewBtrFSDriver(
			logger.Session("driver"),
			string(cmd.VolumesDir),
			cmd.BtrfsBin,
		)
	} else {
		volumeDriver = &driver.NaiveDriver{}
	}

	var namespacer uidgid.Namespacer

	maxUID, maxUIDErr := uidgid.DefaultUIDMap.MaxValid()
	maxGID, maxGIDErr := uidgid.DefaultGIDMap.MaxValid()

	if runtime.GOOS == "linux" && maxUIDErr == nil && maxGIDErr == nil {
		maxId := uidgid.Min(maxUID, maxGID)
		Translator := uidgid.NewTranslator(maxId)

		namespacer = &uidgid.UidNamespacer{
			Translator: Translator,
			Logger:     logger.Session("uid-namespacer"),
		}
	} else {
		namespacer = uidgid.NoopNamespacer{}
	}

	locker := volume.NewLockManager()

	filesystem, err := volume.NewFilesystem(volumeDriver, cmd.VolumesDir.Path())
	if err != nil {
		logger.Fatal("failed-to-initialize-filesystem", err)
	}

	volumeRepo := volume.NewRepository(
		logger.Session("repository"),
		filesystem,
		locker,
	)

	strategerizer := volume.NewStrategerizer(namespacer)

	apiHandler, err := api.NewHandler(
		logger.Session("api"),
		strategerizer,
		namespacer,
		volumeRepo,
	)
	if err != nil {
		logger.Fatal("failed-to-create-handler", err)
	}

	clock := clock.NewClock()

	morbidReality := reaper.NewReaper(clock, volumeRepo)

	members := []grouper.Member{
		{"api", http_server.New(listenAddr, apiHandler)},
		{"reaper", reaper.NewRunner(logger, clock, cmd.ReapInterval, morbidReality.Reap)},
	}

	return onReady(grouper.NewParallel(os.Interrupt, members), func() {
		logger.Info("listening", lager.Data{
			"addr": listenAddr,
		})
	}), nil
}

func (cmd *BaggageclaimCommand) constructLogger() (lager.Logger, *lager.ReconfigurableSink) {
	logger, reconfigurableSink := cmd.Logger.Logger("baggageclaim")

	if cmd.Metrics.YellerAPIKey != "" {
		yellerSink := zest.NewYellerSink(cmd.Metrics.YellerAPIKey, cmd.Metrics.YellerEnvironment)
		logger.RegisterSink(yellerSink)
	}

	return logger, reconfigurableSink
}

func onReady(runner ifrit.Runner, cb func()) ifrit.Runner {
	return ifrit.RunFunc(func(signals <-chan os.Signal, ready chan<- struct{}) error {
		process := ifrit.Background(runner)

		subExited := process.Wait()
		subReady := process.Ready()

		for {
			select {
			case <-subReady:
				cb()
				subReady = nil
			case err := <-subExited:
				return err
			case sig := <-signals:
				process.Signal(sig)
			}
		}
	})
}
<|endoftext|>


<commit_before>// Copyright 2013 The Walk 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 walk

type TableViewColumnList struct {
	tv    *TableView
	items []*TableViewColumn
}

func newTableViewColumnList(tv *TableView) *TableViewColumnList {
	return &TableViewColumnList{tv: tv}
}

// Add adds a TableViewColumn to the end of the list.
func (l *TableViewColumnList) Add(item *TableViewColumn) error {
	return l.Insert(len(l.items), item)
}

// At returns the TableViewColumn as the specified index.
//
// Bounds are not checked.
func (l *TableViewColumnList) At(index int) *TableViewColumn {
	return l.items[index]
}

func (l *TableViewColumnList) atInListView(index int) *TableViewColumn {
	var idx int

	for _, item := range l.items {
		if item.visible {
			if idx == index {
				return item
			}

			idx++
		}
	}

	return nil
}

// Clear removes all TableViewColumns from the list.
func (l *TableViewColumnList) Clear() error {
	for _ = range l.items {
		if err := l.RemoveAt(0); err != nil {
			return err
		}
	}

	return nil
}

// Index returns the index of the specified TableViewColumn or -1 if it is not
// found.
func (l *TableViewColumnList) Index(item *TableViewColumn) int {
	for i, lvi := range l.items {
		if lvi == item {
			return i
		}
	}

	return -1
}

// Contains returns whether the specified TableViewColumn is found in the list.
func (l *TableViewColumnList) Contains(item *TableViewColumn) bool {
	return l.Index(item) > -1
}

// Insert inserts TableViewColumn item at position index.
//
// A TableViewColumn cannot be contained in multiple TableViewColumnLists at the
// same time.
func (l *TableViewColumnList) Insert(index int, item *TableViewColumn) error {
	if item.tv != nil {
		return newError("duplicate insert")
	}

	item.tv = l.tv

	if err := item.create(); err != nil {
		item.tv = nil
		return err
	}

	l.items = append(l.items, nil)
	copy(l.items[index+1:], l.items[index:])
	l.items[index] = item

	return nil
}

// Len returns the number of TableViewColumns in  the list.
func (l *TableViewColumnList) Len() int {
	return len(l.items)
}

// Remove removes the specified TableViewColumn from the list.
func (l *TableViewColumnList) Remove(item *TableViewColumn) error {
	index := l.Index(item)
	if index == -1 {
		return nil
	}

	return l.RemoveAt(index)
}

// RemoveAt removes the TableViewColumn at position index.
func (l *TableViewColumnList) RemoveAt(index int) error {
	tvc := l.items[index]

	if err := tvc.destroy(); err != nil {
		return err
	}

	tvc.tv = nil

	l.items = append(l.items[:index], l.items[index+1:]...)

	return nil
}

func (l *TableViewColumnList) unsetColumnsTV() {
	for _, tvc := range l.items {
		tvc.tv = nil
	}
}
<commit_msg>TableViewColumnList: In Insert, only call item.create if the column is visible<commit_after>// Copyright 2013 The Walk 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 walk

type TableViewColumnList struct {
	tv    *TableView
	items []*TableViewColumn
}

func newTableViewColumnList(tv *TableView) *TableViewColumnList {
	return &TableViewColumnList{tv: tv}
}

// Add adds a TableViewColumn to the end of the list.
func (l *TableViewColumnList) Add(item *TableViewColumn) error {
	return l.Insert(len(l.items), item)
}

// At returns the TableViewColumn as the specified index.
//
// Bounds are not checked.
func (l *TableViewColumnList) At(index int) *TableViewColumn {
	return l.items[index]
}

func (l *TableViewColumnList) atInListView(index int) *TableViewColumn {
	var idx int

	for _, item := range l.items {
		if item.visible {
			if idx == index {
				return item
			}

			idx++
		}
	}

	return nil
}

// Clear removes all TableViewColumns from the list.
func (l *TableViewColumnList) Clear() error {
	for _ = range l.items {
		if err := l.RemoveAt(0); err != nil {
			return err
		}
	}

	return nil
}

// Index returns the index of the specified TableViewColumn or -1 if it is not
// found.
func (l *TableViewColumnList) Index(item *TableViewColumn) int {
	for i, lvi := range l.items {
		if lvi == item {
			return i
		}
	}

	return -1
}

// Contains returns whether the specified TableViewColumn is found in the list.
func (l *TableViewColumnList) Contains(item *TableViewColumn) bool {
	return l.Index(item) > -1
}

// Insert inserts TableViewColumn item at position index.
//
// A TableViewColumn cannot be contained in multiple TableViewColumnLists at the
// same time.
func (l *TableViewColumnList) Insert(index int, item *TableViewColumn) error {
	if item.tv != nil {
		return newError("duplicate insert")
	}

	item.tv = l.tv

	if item.visible {
		if err := item.create(); err != nil {
			item.tv = nil
			return err
		}
	}

	l.items = append(l.items, nil)
	copy(l.items[index+1:], l.items[index:])
	l.items[index] = item

	return nil
}

// Len returns the number of TableViewColumns in  the list.
func (l *TableViewColumnList) Len() int {
	return len(l.items)
}

// Remove removes the specified TableViewColumn from the list.
func (l *TableViewColumnList) Remove(item *TableViewColumn) error {
	index := l.Index(item)
	if index == -1 {
		return nil
	}

	return l.RemoveAt(index)
}

// RemoveAt removes the TableViewColumn at position index.
func (l *TableViewColumnList) RemoveAt(index int) error {
	tvc := l.items[index]

	if err := tvc.destroy(); err != nil {
		return err
	}

	tvc.tv = nil

	l.items = append(l.items[:index], l.items[index+1:]...)

	return nil
}

func (l *TableViewColumnList) unsetColumnsTV() {
	for _, tvc := range l.items {
		tvc.tv = nil
	}
}
<|endoftext|>


<commit_before>package gothumb

import (
	"github.com/rwcarlsen/goexif/exif"
	"io"
)

func Orientation(reader io.Reader) (orientation int, err error) {
	orientation = 1

	info, err := exif.Decode(reader)

	if err != nil {
		return
	}

	orientTag, err := info.Get(exif.Orientation)

	if err != nil {
		return 1, nil
	}

	orientation = int(orientTag.Int(0))

	return
}
<commit_msg>copiles with updated dependencies again<commit_after>package gothumb

import (
	"github.com/rwcarlsen/goexif/exif"
	"io"
)

func Orientation(reader io.Reader) (orientation int, err error) {
	orientation = 1

	info, err := exif.Decode(reader)

	if err != nil {
		return
	}

	orientTag, err := info.Get(exif.Orientation)

	if err != nil {
		return 1, nil
	}

	orientation, err = orientTag.Int(0)
	if err != nil {
		return
	}

	return
}
<|endoftext|>


<commit_before>// 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.

package net

import (
	"flag"
	"fmt"
	"io"
	"os"
	"reflect"
	"regexp"
	"runtime"
	"testing"
	"time"
)

func newLocalListener(t *testing.T) Listener {
	ln, err := Listen("tcp", "127.0.0.1:0")
	if err != nil {
		ln, err = Listen("tcp6", "[::1]:0")
	}
	if err != nil {
		t.Fatal(err)
	}
	return ln
}

func TestDialTimeout(t *testing.T) {
	origBacklog := listenerBacklog
	defer func() {
		listenerBacklog = origBacklog
	}()
	listenerBacklog = 1

	ln := newLocalListener(t)
	defer ln.Close()

	errc := make(chan error)

	numConns := listenerBacklog + 100

	// TODO(bradfitz): It's hard to test this in a portable
	// way. This is unfortunate, but works for now.
	switch runtime.GOOS {
	case "linux":
		// The kernel will start accepting TCP connections before userspace
		// gets a chance to not accept them, so fire off a bunch to fill up
		// the kernel's backlog.  Then we test we get a failure after that.
		for i := 0; i < numConns; i++ {
			go func() {
				_, err := DialTimeout("tcp", ln.Addr().String(), 200*time.Millisecond)
				errc <- err
			}()
		}
	case "darwin", "windows":
		// At least OS X 10.7 seems to accept any number of
		// connections, ignoring listen's backlog, so resort
		// to connecting to a hopefully-dead 127/8 address.
		// Same for windows.
		//
		// Use an IANA reserved port (49151) instead of 80, because
		// on our 386 builder, this Dial succeeds, connecting
		// to an IIS web server somewhere.  The data center
		// or VM or firewall must be stealing the TCP connection.
		//
		// IANA Service Name and Transport Protocol Port Number Registry
		// <http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml>
		go func() {
			c, err := DialTimeout("tcp", "127.0.71.111:49151", 200*time.Millisecond)
			if err == nil {
				err = fmt.Errorf("unexpected: connected to %s!", c.RemoteAddr())
				c.Close()
			}
			errc <- err
		}()
	default:
		// TODO(bradfitz):
		// OpenBSD may have a reject route to 127/8 except 127.0.0.1/32
		// by default. FreeBSD likely works, but is untested.
		// TODO(rsc):
		// The timeout never happens on Windows.  Why?  Issue 3016.
		t.Skipf("skipping test on %q; untested.", runtime.GOOS)
	}

	connected := 0
	for {
		select {
		case <-time.After(15 * time.Second):
			t.Fatal("too slow")
		case err := <-errc:
			if err == nil {
				connected++
				if connected == numConns {
					t.Fatal("all connections connected; expected some to time out")
				}
			} else {
				terr, ok := err.(timeout)
				if !ok {
					t.Fatalf("got error %q; want error with timeout interface", err)
				}
				if !terr.Timeout() {
					t.Fatalf("got error %q; not a timeout", err)
				}
				// Pass. We saw a timeout error.
				return
			}
		}
	}
}

func TestSelfConnect(t *testing.T) {
	if runtime.GOOS == "windows" {
		// TODO(brainman): do not know why it hangs.
		t.Skip("skipping known-broken test on windows")
	}
	// Test that Dial does not honor self-connects.
	// See the comment in DialTCP.

	// Find a port that would be used as a local address.
	l, err := Listen("tcp", "127.0.0.1:0")
	if err != nil {
		t.Fatal(err)
	}
	c, err := Dial("tcp", l.Addr().String())
	if err != nil {
		t.Fatal(err)
	}
	addr := c.LocalAddr().String()
	c.Close()
	l.Close()

	// Try to connect to that address repeatedly.
	n := 100000
	if testing.Short() {
		n = 1000
	}
	switch runtime.GOOS {
	case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd", "plan9", "windows":
		// Non-Linux systems take a long time to figure
		// out that there is nothing listening on localhost.
		n = 100
	}
	for i := 0; i < n; i++ {
		c, err := Dial("tcp", addr)
		if err == nil {
			c.Close()
			t.Errorf("#%d: Dial %q succeeded", i, addr)
		}
	}
}

var runErrorTest = flag.Bool("run_error_test", false, "let TestDialError check for dns errors")

type DialErrorTest struct {
	Net     string
	Raddr   string
	Pattern string
}

var dialErrorTests = []DialErrorTest{
	{
		"datakit", "mh/astro/r70",
		"dial datakit mh/astro/r70: unknown network datakit",
	},
	{
		"tcp", "127.0.0.1:☺",
		"dial tcp 127.0.0.1:☺: unknown port tcp/☺",
	},
	{
		"tcp", "no-such-name.google.com.:80",
		"dial tcp no-such-name.google.com.:80: lookup no-such-name.google.com.( on .*)?: no (.*)",
	},
	{
		"tcp", "no-such-name.no-such-top-level-domain.:80",
		"dial tcp no-such-name.no-such-top-level-domain.:80: lookup no-such-name.no-such-top-level-domain.( on .*)?: no (.*)",
	},
	{
		"tcp", "no-such-name:80",
		`dial tcp no-such-name:80: lookup no-such-name\.(.*\.)?( on .*)?: no (.*)`,
	},
	{
		"tcp", "mh/astro/r70:http",
		"dial tcp mh/astro/r70:http: lookup mh/astro/r70: invalid domain name",
	},
	{
		"unix", "/etc/file-not-found",
		"dial unix /etc/file-not-found: no such file or directory",
	},
	{
		"unix", "/etc/",
		"dial unix /etc/: (permission denied|socket operation on non-socket|connection refused)",
	},
	{
		"unixpacket", "/etc/file-not-found",
		"dial unixpacket /etc/file-not-found: no such file or directory",
	},
	{
		"unixpacket", "/etc/",
		"dial unixpacket /etc/: (permission denied|socket operation on non-socket|connection refused)",
	},
}

var duplicateErrorPattern = `dial (.*) dial (.*)`

func TestDialError(t *testing.T) {
	if !*runErrorTest {
		t.Logf("test disabled; use -run_error_test to enable")
		return
	}
	for i, tt := range dialErrorTests {
		c, err := Dial(tt.Net, tt.Raddr)
		if c != nil {
			c.Close()
		}
		if err == nil {
			t.Errorf("#%d: nil error, want match for %#q", i, tt.Pattern)
			continue
		}
		s := err.Error()
		match, _ := regexp.MatchString(tt.Pattern, s)
		if !match {
			t.Errorf("#%d: %q, want match for %#q", i, s, tt.Pattern)
		}
		match, _ = regexp.MatchString(duplicateErrorPattern, s)
		if match {
			t.Errorf("#%d: %q, duplicate error return from Dial", i, s)
		}
	}
}

var invalidDialAndListenArgTests = []struct {
	net  string
	addr string
	err  error
}{
	{"foo", "bar", &OpError{Op: "dial", Net: "foo", Addr: nil, Err: UnknownNetworkError("foo")}},
	{"baz", "", &OpError{Op: "listen", Net: "baz", Addr: nil, Err: UnknownNetworkError("baz")}},
	{"tcp", "", &OpError{Op: "dial", Net: "tcp", Addr: nil, Err: errMissingAddress}},
}

func TestInvalidDialAndListenArgs(t *testing.T) {
	for _, tt := range invalidDialAndListenArgTests {
		var err error
		switch tt.err.(*OpError).Op {
		case "dial":
			_, err = Dial(tt.net, tt.addr)
		case "listen":
			_, err = Listen(tt.net, tt.addr)
		}
		if !reflect.DeepEqual(tt.err, err) {
			t.Fatalf("got %#v; expected %#v", err, tt.err)
		}
	}
}

func TestDialTimeoutFDLeak(t *testing.T) {
	if runtime.GOOS != "linux" {
		// TODO(bradfitz): test on other platforms
		t.Skipf("skipping test on %q", runtime.GOOS)
	}

	ln := newLocalListener(t)
	defer ln.Close()

	type connErr struct {
		conn Conn
		err  error
	}
	dials := listenerBacklog + 100
	// used to be listenerBacklog + 5, but was found to be unreliable, issue 4384.
	maxGoodConnect := listenerBacklog + runtime.NumCPU()*10
	resc := make(chan connErr)
	for i := 0; i < dials; i++ {
		go func() {
			conn, err := DialTimeout("tcp", ln.Addr().String(), 500*time.Millisecond)
			resc <- connErr{conn, err}
		}()
	}

	var firstErr string
	var ngood int
	var toClose []io.Closer
	for i := 0; i < dials; i++ {
		ce := <-resc
		if ce.err == nil {
			ngood++
			if ngood > maxGoodConnect {
				t.Errorf("%d good connects; expected at most %d", ngood, maxGoodConnect)
			}
			toClose = append(toClose, ce.conn)
			continue
		}
		err := ce.err
		if firstErr == "" {
			firstErr = err.Error()
		} else if err.Error() != firstErr {
			t.Fatalf("inconsistent error messages: first was %q, then later %q", firstErr, err)
		}
	}
	for _, c := range toClose {
		c.Close()
	}
	for i := 0; i < 100; i++ {
		if got := numFD(); got < dials {
			// Test passes.
			return
		}
		time.Sleep(10 * time.Millisecond)
	}
	if got := numFD(); got >= dials {
		t.Errorf("num fds after %d timeouts = %d; want <%d", dials, got, dials)
	}
}

func numFD() int {
	if runtime.GOOS == "linux" {
		f, err := os.Open("/proc/self/fd")
		if err != nil {
			panic(err)
		}
		defer f.Close()
		names, err := f.Readdirnames(0)
		if err != nil {
			panic(err)
		}
		return len(names)
	}
	// All tests using this should be skipped anyway, but:
	panic("numFDs not implemented on " + runtime.GOOS)
}

var testPoller = flag.Bool("poller", false, "platform supports runtime-integrated poller")

// Assert that a failed Dial attempt does not leak
// runtime.PollDesc structures
func TestDialFailPDLeak(t *testing.T) {
	if !*testPoller {
		t.Skip("test disabled; use -poller to enable")
	}

	const loops = 10
	const count = 20000
	var old runtime.MemStats // used by sysdelta
	runtime.ReadMemStats(&old)
	sysdelta := func() uint64 {
		var new runtime.MemStats
		runtime.ReadMemStats(&new)
		delta := old.Sys - new.Sys
		old = new
		return delta
	}
	d := &Dialer{Timeout: time.Nanosecond} // don't bother TCP with handshaking
	failcount := 0
	for i := 0; i < loops; i++ {
		for i := 0; i < count; i++ {
			conn, err := d.Dial("tcp", "127.0.0.1:1")
			if err == nil {
				t.Error("dial should not succeed")
				conn.Close()
				t.FailNow()
			}
		}
		if delta := sysdelta(); delta > 0 {
			failcount++
		}
		// there are always some allocations on the first loop
		if failcount > 3 {
			t.Error("detected possible memory leak in runtime")
			t.FailNow()
		}
	}
}

func TestDialer(t *testing.T) {
	ln, err := Listen("tcp4", "127.0.0.1:0")
	if err != nil {
		t.Fatalf("Listen failed: %v", err)
	}
	defer ln.Close()
	ch := make(chan error, 1)
	go func() {
		c, err := ln.Accept()
		if err != nil {
			ch <- fmt.Errorf("Accept failed: %v", err)
			return
		}
		defer c.Close()
		ch <- nil
	}()

	laddr, err := ResolveTCPAddr("tcp4", "127.0.0.1:0")
	if err != nil {
		t.Fatalf("ResolveTCPAddr failed: %v", err)
	}
	d := &Dialer{LocalAddr: laddr}
	c, err := d.Dial("tcp4", ln.Addr().String())
	if err != nil {
		t.Fatalf("Dial failed: %v", err)
	}
	defer c.Close()
	c.Read(make([]byte, 1))
	err = <-ch
	if err != nil {
		t.Error(err)
	}
}
<commit_msg>net: allow TestDialFailPDLeak run in long-mode test<commit_after>// 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.

package net

import (
	"flag"
	"fmt"
	"io"
	"os"
	"reflect"
	"regexp"
	"runtime"
	"testing"
	"time"
)

func newLocalListener(t *testing.T) Listener {
	ln, err := Listen("tcp", "127.0.0.1:0")
	if err != nil {
		ln, err = Listen("tcp6", "[::1]:0")
	}
	if err != nil {
		t.Fatal(err)
	}
	return ln
}

func TestDialTimeout(t *testing.T) {
	origBacklog := listenerBacklog
	defer func() {
		listenerBacklog = origBacklog
	}()
	listenerBacklog = 1

	ln := newLocalListener(t)
	defer ln.Close()

	errc := make(chan error)

	numConns := listenerBacklog + 100

	// TODO(bradfitz): It's hard to test this in a portable
	// way. This is unfortunate, but works for now.
	switch runtime.GOOS {
	case "linux":
		// The kernel will start accepting TCP connections before userspace
		// gets a chance to not accept them, so fire off a bunch to fill up
		// the kernel's backlog.  Then we test we get a failure after that.
		for i := 0; i < numConns; i++ {
			go func() {
				_, err := DialTimeout("tcp", ln.Addr().String(), 200*time.Millisecond)
				errc <- err
			}()
		}
	case "darwin", "windows":
		// At least OS X 10.7 seems to accept any number of
		// connections, ignoring listen's backlog, so resort
		// to connecting to a hopefully-dead 127/8 address.
		// Same for windows.
		//
		// Use an IANA reserved port (49151) instead of 80, because
		// on our 386 builder, this Dial succeeds, connecting
		// to an IIS web server somewhere.  The data center
		// or VM or firewall must be stealing the TCP connection.
		//
		// IANA Service Name and Transport Protocol Port Number Registry
		// <http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml>
		go func() {
			c, err := DialTimeout("tcp", "127.0.71.111:49151", 200*time.Millisecond)
			if err == nil {
				err = fmt.Errorf("unexpected: connected to %s!", c.RemoteAddr())
				c.Close()
			}
			errc <- err
		}()
	default:
		// TODO(bradfitz):
		// OpenBSD may have a reject route to 127/8 except 127.0.0.1/32
		// by default. FreeBSD likely works, but is untested.
		// TODO(rsc):
		// The timeout never happens on Windows.  Why?  Issue 3016.
		t.Skipf("skipping test on %q; untested.", runtime.GOOS)
	}

	connected := 0
	for {
		select {
		case <-time.After(15 * time.Second):
			t.Fatal("too slow")
		case err := <-errc:
			if err == nil {
				connected++
				if connected == numConns {
					t.Fatal("all connections connected; expected some to time out")
				}
			} else {
				terr, ok := err.(timeout)
				if !ok {
					t.Fatalf("got error %q; want error with timeout interface", err)
				}
				if !terr.Timeout() {
					t.Fatalf("got error %q; not a timeout", err)
				}
				// Pass. We saw a timeout error.
				return
			}
		}
	}
}

func TestSelfConnect(t *testing.T) {
	if runtime.GOOS == "windows" {
		// TODO(brainman): do not know why it hangs.
		t.Skip("skipping known-broken test on windows")
	}
	// Test that Dial does not honor self-connects.
	// See the comment in DialTCP.

	// Find a port that would be used as a local address.
	l, err := Listen("tcp", "127.0.0.1:0")
	if err != nil {
		t.Fatal(err)
	}
	c, err := Dial("tcp", l.Addr().String())
	if err != nil {
		t.Fatal(err)
	}
	addr := c.LocalAddr().String()
	c.Close()
	l.Close()

	// Try to connect to that address repeatedly.
	n := 100000
	if testing.Short() {
		n = 1000
	}
	switch runtime.GOOS {
	case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd", "plan9", "windows":
		// Non-Linux systems take a long time to figure
		// out that there is nothing listening on localhost.
		n = 100
	}
	for i := 0; i < n; i++ {
		c, err := Dial("tcp", addr)
		if err == nil {
			c.Close()
			t.Errorf("#%d: Dial %q succeeded", i, addr)
		}
	}
}

var runErrorTest = flag.Bool("run_error_test", false, "let TestDialError check for dns errors")

type DialErrorTest struct {
	Net     string
	Raddr   string
	Pattern string
}

var dialErrorTests = []DialErrorTest{
	{
		"datakit", "mh/astro/r70",
		"dial datakit mh/astro/r70: unknown network datakit",
	},
	{
		"tcp", "127.0.0.1:☺",
		"dial tcp 127.0.0.1:☺: unknown port tcp/☺",
	},
	{
		"tcp", "no-such-name.google.com.:80",
		"dial tcp no-such-name.google.com.:80: lookup no-such-name.google.com.( on .*)?: no (.*)",
	},
	{
		"tcp", "no-such-name.no-such-top-level-domain.:80",
		"dial tcp no-such-name.no-such-top-level-domain.:80: lookup no-such-name.no-such-top-level-domain.( on .*)?: no (.*)",
	},
	{
		"tcp", "no-such-name:80",
		`dial tcp no-such-name:80: lookup no-such-name\.(.*\.)?( on .*)?: no (.*)`,
	},
	{
		"tcp", "mh/astro/r70:http",
		"dial tcp mh/astro/r70:http: lookup mh/astro/r70: invalid domain name",
	},
	{
		"unix", "/etc/file-not-found",
		"dial unix /etc/file-not-found: no such file or directory",
	},
	{
		"unix", "/etc/",
		"dial unix /etc/: (permission denied|socket operation on non-socket|connection refused)",
	},
	{
		"unixpacket", "/etc/file-not-found",
		"dial unixpacket /etc/file-not-found: no such file or directory",
	},
	{
		"unixpacket", "/etc/",
		"dial unixpacket /etc/: (permission denied|socket operation on non-socket|connection refused)",
	},
}

var duplicateErrorPattern = `dial (.*) dial (.*)`

func TestDialError(t *testing.T) {
	if !*runErrorTest {
		t.Logf("test disabled; use -run_error_test to enable")
		return
	}
	for i, tt := range dialErrorTests {
		c, err := Dial(tt.Net, tt.Raddr)
		if c != nil {
			c.Close()
		}
		if err == nil {
			t.Errorf("#%d: nil error, want match for %#q", i, tt.Pattern)
			continue
		}
		s := err.Error()
		match, _ := regexp.MatchString(tt.Pattern, s)
		if !match {
			t.Errorf("#%d: %q, want match for %#q", i, s, tt.Pattern)
		}
		match, _ = regexp.MatchString(duplicateErrorPattern, s)
		if match {
			t.Errorf("#%d: %q, duplicate error return from Dial", i, s)
		}
	}
}

var invalidDialAndListenArgTests = []struct {
	net  string
	addr string
	err  error
}{
	{"foo", "bar", &OpError{Op: "dial", Net: "foo", Addr: nil, Err: UnknownNetworkError("foo")}},
	{"baz", "", &OpError{Op: "listen", Net: "baz", Addr: nil, Err: UnknownNetworkError("baz")}},
	{"tcp", "", &OpError{Op: "dial", Net: "tcp", Addr: nil, Err: errMissingAddress}},
}

func TestInvalidDialAndListenArgs(t *testing.T) {
	for _, tt := range invalidDialAndListenArgTests {
		var err error
		switch tt.err.(*OpError).Op {
		case "dial":
			_, err = Dial(tt.net, tt.addr)
		case "listen":
			_, err = Listen(tt.net, tt.addr)
		}
		if !reflect.DeepEqual(tt.err, err) {
			t.Fatalf("got %#v; expected %#v", err, tt.err)
		}
	}
}

func TestDialTimeoutFDLeak(t *testing.T) {
	if runtime.GOOS != "linux" {
		// TODO(bradfitz): test on other platforms
		t.Skipf("skipping test on %q", runtime.GOOS)
	}

	ln := newLocalListener(t)
	defer ln.Close()

	type connErr struct {
		conn Conn
		err  error
	}
	dials := listenerBacklog + 100
	// used to be listenerBacklog + 5, but was found to be unreliable, issue 4384.
	maxGoodConnect := listenerBacklog + runtime.NumCPU()*10
	resc := make(chan connErr)
	for i := 0; i < dials; i++ {
		go func() {
			conn, err := DialTimeout("tcp", ln.Addr().String(), 500*time.Millisecond)
			resc <- connErr{conn, err}
		}()
	}

	var firstErr string
	var ngood int
	var toClose []io.Closer
	for i := 0; i < dials; i++ {
		ce := <-resc
		if ce.err == nil {
			ngood++
			if ngood > maxGoodConnect {
				t.Errorf("%d good connects; expected at most %d", ngood, maxGoodConnect)
			}
			toClose = append(toClose, ce.conn)
			continue
		}
		err := ce.err
		if firstErr == "" {
			firstErr = err.Error()
		} else if err.Error() != firstErr {
			t.Fatalf("inconsistent error messages: first was %q, then later %q", firstErr, err)
		}
	}
	for _, c := range toClose {
		c.Close()
	}
	for i := 0; i < 100; i++ {
		if got := numFD(); got < dials {
			// Test passes.
			return
		}
		time.Sleep(10 * time.Millisecond)
	}
	if got := numFD(); got >= dials {
		t.Errorf("num fds after %d timeouts = %d; want <%d", dials, got, dials)
	}
}

func numFD() int {
	if runtime.GOOS == "linux" {
		f, err := os.Open("/proc/self/fd")
		if err != nil {
			panic(err)
		}
		defer f.Close()
		names, err := f.Readdirnames(0)
		if err != nil {
			panic(err)
		}
		return len(names)
	}
	// All tests using this should be skipped anyway, but:
	panic("numFDs not implemented on " + runtime.GOOS)
}

// Assert that a failed Dial attempt does not leak
// runtime.PollDesc structures
func TestDialFailPDLeak(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode")
	}

	const loops = 10
	const count = 20000
	var old runtime.MemStats // used by sysdelta
	runtime.ReadMemStats(&old)
	sysdelta := func() uint64 {
		var new runtime.MemStats
		runtime.ReadMemStats(&new)
		delta := old.Sys - new.Sys
		old = new
		return delta
	}
	d := &Dialer{Timeout: time.Nanosecond} // don't bother TCP with handshaking
	failcount := 0
	for i := 0; i < loops; i++ {
		for i := 0; i < count; i++ {
			conn, err := d.Dial("tcp", "127.0.0.1:1")
			if err == nil {
				t.Error("dial should not succeed")
				conn.Close()
				t.FailNow()
			}
		}
		if delta := sysdelta(); delta > 0 {
			failcount++
		}
		// there are always some allocations on the first loop
		if failcount > 3 {
			t.Error("detected possible memory leak in runtime")
			t.FailNow()
		}
	}
}

func TestDialer(t *testing.T) {
	ln, err := Listen("tcp4", "127.0.0.1:0")
	if err != nil {
		t.Fatalf("Listen failed: %v", err)
	}
	defer ln.Close()
	ch := make(chan error, 1)
	go func() {
		c, err := ln.Accept()
		if err != nil {
			ch <- fmt.Errorf("Accept failed: %v", err)
			return
		}
		defer c.Close()
		ch <- nil
	}()

	laddr, err := ResolveTCPAddr("tcp4", "127.0.0.1:0")
	if err != nil {
		t.Fatalf("ResolveTCPAddr failed: %v", err)
	}
	d := &Dialer{LocalAddr: laddr}
	c, err := d.Dial("tcp4", ln.Addr().String())
	if err != nil {
		t.Fatalf("Dial failed: %v", err)
	}
	defer c.Close()
	c.Read(make([]byte, 1))
	err = <-ch
	if err != nil {
		t.Error(err)
	}
}
<|endoftext|>


<commit_before>// 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 unsafe contains operations that step around the type safety of Go programs.
*/
package unsafe

// ArbitraryType is here for the purposes of documentation only and is not actually
// part of the unsafe package.  It represents the type of an arbitrary Go expression.
type ArbitraryType int

// Pointer represents a pointer to an arbitrary type.  There are three special operations
// available for type Pointer that are not available for other types.
//	1) A pointer value of any type can be converted to a Pointer.
//	2) A Pointer can be converted to a pointer value of any type.
//	3) A uintptr can be converted to a Pointer.
//	4) A Pointer can be converted to a uintptr.
// Pointer therefore allows a program to defeat the type system and read and write
// arbitrary memory. It should be used with extreme care.
type Pointer *ArbitraryType

// Sizeof returns the size in bytes occupied by the value v.  The size is that of the
// "top level" of the value only.  For instance, if v is a slice, it returns the size of
// the slice descriptor, not the size of the memory referenced by the slice.
func Sizeof(v ArbitraryType) uintptr

// Offsetof returns the offset within the struct of the field represented by v,
// which must be of the form struct_value.field.  In other words, it returns the
// number of bytes between the start of the struct and the start of the field.
func Offsetof(v ArbitraryType) uintptr

// Alignof returns the alignment of the value v.  It is the maximum value m such
// that the address of a variable with the type of v will always always be zero mod m.
// If v is of the form obj.f, it returns the alignment of field f within struct object obj.
func Alignof(v ArbitraryType) uintptr

// Typeof returns the type of an interface value, a runtime.Type.
func Typeof(i interface{}) (typ interface{})

// Reflect unpacks an interface value into its type and the address of a copy of the
// internal value.
func Reflect(i interface{}) (typ interface{}, addr Pointer)

// Unreflect inverts Reflect: Given a type and a pointer to a value, it returns an
// empty interface value with contents the type and the value (not the pointer to
// the value).  The typ is assumed to contain a pointer to a runtime type; the type
// information in the interface{} is ignored, so that, for example, both
// *reflect.structType and *runtime.StructType can be passed for typ.
func Unreflect(typ interface{}, addr Pointer) (ret interface{})

// New allocates and returns a pointer to memory for a new value of the given type.
// The typ is assumed to hold a pointer to a runtime type.
// Callers should use reflect.New or reflect.Zero instead of invoking unsafe.New directly.
func New(typ interface{}) Pointer

// NewArray allocates and returns a pointer to an array of n elements of the given type.
// The typ is assumed to hold a pointer to a runtime type.
// Callers should use reflect.MakeSlice instead of invoking unsafe.NewArray directly.
func NewArray(typ interface{}, n int) Pointer
<commit_msg>unsafe: Alignof and Offsetof now use the same style<commit_after>// 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 unsafe contains operations that step around the type safety of Go programs.
*/
package unsafe

// ArbitraryType is here for the purposes of documentation only and is not actually
// part of the unsafe package.  It represents the type of an arbitrary Go expression.
type ArbitraryType int

// Pointer represents a pointer to an arbitrary type.  There are three special operations
// available for type Pointer that are not available for other types.
//	1) A pointer value of any type can be converted to a Pointer.
//	2) A Pointer can be converted to a pointer value of any type.
//	3) A uintptr can be converted to a Pointer.
//	4) A Pointer can be converted to a uintptr.
// Pointer therefore allows a program to defeat the type system and read and write
// arbitrary memory. It should be used with extreme care.
type Pointer *ArbitraryType

// Sizeof returns the size in bytes occupied by the value v.  The size is that of the
// "top level" of the value only.  For instance, if v is a slice, it returns the size of
// the slice descriptor, not the size of the memory referenced by the slice.
func Sizeof(v ArbitraryType) uintptr

// Offsetof returns the offset within the struct of the field represented by v,
// which must be of the form structValue.field.  In other words, it returns the
// number of bytes between the start of the struct and the start of the field.
func Offsetof(v ArbitraryType) uintptr

// Alignof returns the alignment of the value v.  It is the maximum value m such
// that the address of a variable with the type of v will always always be zero mod m.
// If v is of the form structValue.field, it returns the alignment of field f within struct object obj.
func Alignof(v ArbitraryType) uintptr

// Typeof returns the type of an interface value, a runtime.Type.
func Typeof(i interface{}) (typ interface{})

// Reflect unpacks an interface value into its type and the address of a copy of the
// internal value.
func Reflect(i interface{}) (typ interface{}, addr Pointer)

// Unreflect inverts Reflect: Given a type and a pointer to a value, it returns an
// empty interface value with contents the type and the value (not the pointer to
// the value).  The typ is assumed to contain a pointer to a runtime type; the type
// information in the interface{} is ignored, so that, for example, both
// *reflect.structType and *runtime.StructType can be passed for typ.
func Unreflect(typ interface{}, addr Pointer) (ret interface{})

// New allocates and returns a pointer to memory for a new value of the given type.
// The typ is assumed to hold a pointer to a runtime type.
// Callers should use reflect.New or reflect.Zero instead of invoking unsafe.New directly.
func New(typ interface{}) Pointer

// NewArray allocates and returns a pointer to an array of n elements of the given type.
// The typ is assumed to hold a pointer to a runtime type.
// Callers should use reflect.MakeSlice instead of invoking unsafe.NewArray directly.
func NewArray(typ interface{}, n int) Pointer
<|endoftext|>


<commit_before>// 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 xml

import (
	"reflect"
	"testing"
)

// Stripped down Atom feed data structures.

func TestUnmarshalFeed(t *testing.T) {
	var f Feed
	if err := Unmarshal(StringReader(rssFeedString), &f); err != nil {
		t.Fatalf("Unmarshal: %s", err)
	}
	if !reflect.DeepEqual(f, rssFeed) {
		t.Fatalf("have %#v\nwant %#v", f, rssFeed)
	}
}

// hget http://codereview.appspot.com/rss/mine/rsc
const rssFeedString = `
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-us"><title>Code Review - My issues</title><link href="http://codereview.appspot.com/" rel="alternate"></link><li-nk href="http://codereview.appspot.com/rss/mine/rsc" rel="self"></li-nk><id>http://codereview.appspot.com/</id><updated>2009-10-04T01:35:58+00:00</updated><author><name>rietveld<></name></author><entry><title>rietveld: an attempt at pubsubhubbub
</title><link hre-f="http://codereview.appspot.com/126085" rel="alternate"></link><updated>2009-10-04T01:35:58+00:00</updated><author><name>email-address-removed</name></author><id>urn:md5:134d9179c41f806be79b3a5f7877d19a</id><summary type="html">
  An attempt at adding pubsubhubbub support to Rietveld.
http://code.google.com/p/pubsubhubbub
http://code.google.com/p/rietveld/issues/detail?id=155

The server side of the protocol is trivial:
  1. add a &lt;link rel=&quot;hub&quot; href=&quot;hub-server&quot;&gt; tag to all
     feeds that will be pubsubhubbubbed.
  2. every time one of those feeds changes, tell the hub
     with a simple POST request.

I have tested this by adding debug prints to a local hub
server and checking that the server got the right publish
requests.

I can&#39;t quite get the server to work, but I think the bug
is not in my code.  I think that the server expects to be
able to grab the feed and see the feed&#39;s actual URL in
the link rel=&quot;self&quot;, but the default value for that drops
the :port from the URL, and I cannot for the life of me
figure out how to get the Atom generator deep inside
django not to do that, or even where it is doing that,
or even what code is running to generate the Atom feed.
(I thought I knew but I added some assert False statements
and it kept running!)

Ignoring that particular problem, I would appreciate
feedback on the right way to get the two values at
the top of feeds.py marked NOTE(rsc).

</summary></entry><entry><title>rietveld: correct tab handling
</title><link href="http://codereview.appspot.com/124106" rel="alternate"></link><updated>2009-10-03T23:02:17+00:00</updated><author><name>email-address-removed</name></author><id>urn:md5:0a2a4f19bb815101f0ba2904aed7c35a</id><summary type="html">
  This fixes the buggy tab rendering that can be seen at
http://codereview.appspot.com/116075/diff/1/2

The fundamental problem was that the tab code was
not being told what column the text began in, so it
didn&#39;t know where to put the tab stops.  Another problem
was that some of the code assumed that string byte
offsets were the same as column offsets, which is only
true if there are no tabs.

In the process of fixing this, I cleaned up the arguments
to Fold and ExpandTabs and renamed them Break and
_ExpandTabs so that I could be sure that I found all the
call sites.  I also wanted to verify that ExpandTabs was
not being used from outside intra_region_diff.py.

</summary></entry></feed> 	   `

type Feed struct {
	XMLName Name "http://www.w3.org/2005/Atom feed"
	Title   string
	Id      string
	Link    []Link
	Updated Time
	Author  Person
	Entry   []Entry
}

type Entry struct {
	Title   string
	Id      string
	Link    []Link
	Updated Time
	Author  Person
	Summary Text
}

type Link struct {
	Rel  string "attr"
	Href string "attr"
}

type Person struct {
	Name     string
	URI      string
	Email    string
	InnerXML string "innerxml"
}

type Text struct {
	Type string "attr"
	Body string "chardata"
}

type Time string

var rssFeed = Feed{
	XMLName: Name{"http://www.w3.org/2005/Atom", "feed"},
	Title:   "Code Review - My issues",
	Link: []Link{
		{Rel: "alternate", Href: "http://codereview.appspot.com/"},
		{Rel: "self", Href: "http://codereview.appspot.com/rss/mine/rsc"},
	},
	Id:      "http://codereview.appspot.com/",
	Updated: "2009-10-04T01:35:58+00:00",
	Author: Person{
		Name:     "rietveld<>",
		InnerXML: "<name>rietveld<></name>",
	},
	Entry: []Entry{
		{
			Title: "rietveld: an attempt at pubsubhubbub\n",
			Link: []Link{
				{Rel: "alternate", Href: "http://codereview.appspot.com/126085"},
			},
			Updated: "2009-10-04T01:35:58+00:00",
			Author: Person{
				Name:     "email-address-removed",
				InnerXML: "<name>email-address-removed</name>",
			},
			Id: "urn:md5:134d9179c41f806be79b3a5f7877d19a",
			Summary: Text{
				Type: "html",
				Body: `
  An attempt at adding pubsubhubbub support to Rietveld.
http://code.google.com/p/pubsubhubbub
http://code.google.com/p/rietveld/issues/detail?id=155

The server side of the protocol is trivial:
  1. add a <link rel="hub" href="hub-server"> tag to all
     feeds that will be pubsubhubbubbed.
  2. every time one of those feeds changes, tell the hub
     with a simple POST request.

I have tested this by adding debug prints to a local hub
server and checking that the server got the right publish
requests.

I can't quite get the server to work, but I think the bug
is not in my code.  I think that the server expects to be
able to grab the feed and see the feed's actual URL in
the link rel="self", but the default value for that drops
the :port from the URL, and I cannot for the life of me
figure out how to get the Atom generator deep inside
django not to do that, or even where it is doing that,
or even what code is running to generate the Atom feed.
(I thought I knew but I added some assert False statements
and it kept running!)

Ignoring that particular problem, I would appreciate
feedback on the right way to get the two values at
the top of feeds.py marked NOTE(rsc).

`,
			},
		},
		{
			Title: "rietveld: correct tab handling\n",
			Link: []Link{
				{Rel: "alternate", Href: "http://codereview.appspot.com/124106"},
			},
			Updated: "2009-10-03T23:02:17+00:00",
			Author: Person{
				Name:     "email-address-removed",
				InnerXML: "<name>email-address-removed</name>",
			},
			Id: "urn:md5:0a2a4f19bb815101f0ba2904aed7c35a",
			Summary: Text{
				Type: "html",
				Body: `
  This fixes the buggy tab rendering that can be seen at
http://codereview.appspot.com/116075/diff/1/2

The fundamental problem was that the tab code was
not being told what column the text began in, so it
didn't know where to put the tab stops.  Another problem
was that some of the code assumed that string byte
offsets were the same as column offsets, which is only
true if there are no tabs.

In the process of fixing this, I cleaned up the arguments
to Fold and ExpandTabs and renamed them Break and
_ExpandTabs so that I could be sure that I found all the
call sites.  I also wanted to verify that ExpandTabs was
not being used from outside intra_region_diff.py.

`,
			},
		},
	},
}

type FieldNameTest struct {
	in, out string
}

var FieldNameTests = []FieldNameTest{
	{"Profile-Image", "profileimage"},
	{"_score", "score"},
}

func TestFieldName(t *testing.T) {
	for _, tt := range FieldNameTests {
		a := fieldName(tt.in)
		if a != tt.out {
			t.Fatalf("have %#v\nwant %#v\n\n", a, tt.out)
		}
	}
}

const pathTestString = `
<result>
    <before>1</before>
    <items>
        <item1>
            <value>A</value>
        </item1>
        <item2>
            <value>B</value>
        </item2>
        <Item1>
            <Value>C</Value>
            <Value>D</Value>
        </Item1>
    </items>
    <after>2</after>
</result>
`

type PathTestItem struct {
	Value string
}

type PathTestA struct {
	Items         []PathTestItem ">item1"
	Before, After string
}

type PathTestB struct {
	Other         []PathTestItem "items>Item1"
	Before, After string
}

type PathTestC struct {
	Values1       []string "items>item1>value"
	Values2       []string "items>item2>value"
	Before, After string
}

type PathTestSet struct {
	Item1 []PathTestItem
}

type PathTestD struct {
	Other         PathTestSet "items>"
	Before, After string
}

var pathTests = []interface{}{
	&PathTestA{Items: []PathTestItem{{"A"}, {"D"}}, Before: "1", After: "2"},
	&PathTestB{Other: []PathTestItem{{"A"}, {"D"}}, Before: "1", After: "2"},
	&PathTestC{Values1: []string{"A", "C", "D"}, Values2: []string{"B"}, Before: "1", After: "2"},
	&PathTestD{Other: PathTestSet{Item1: []PathTestItem{{"A"}, {"D"}}}, Before: "1", After: "2"},
}

func TestUnmarshalPaths(t *testing.T) {
	for _, pt := range pathTests {
		p := reflect.MakeZero(reflect.NewValue(pt).Type()).(*reflect.PtrValue)
		p.PointTo(reflect.MakeZero(p.Type().(*reflect.PtrType).Elem()))
		v := p.Interface()
		if err := Unmarshal(StringReader(pathTestString), v); err != nil {
			t.Fatalf("Unmarshal: %s", err)
		}
		if !reflect.DeepEqual(v, pt) {
			t.Fatalf("have %#v\nwant %#v", v, pt)
		}
	}
}

type BadPathTestA struct {
	First  string "items>item1"
	Other  string "items>item2"
	Second string "items>"
}

type BadPathTestB struct {
	Other  string "items>item2>value"
	First  string "items>item1"
	Second string "items>item1>value"
}

var badPathTests = []struct {
	v, e interface{}
}{
	{&BadPathTestA{}, &TagPathError{reflect.Typeof(BadPathTestA{}), "First", "items>item1", "Second", "items>"}},
	{&BadPathTestB{}, &TagPathError{reflect.Typeof(BadPathTestB{}), "First", "items>item1", "Second", "items>item1>value"}},
}

func TestUnmarshalBadPaths(t *testing.T) {
	for _, tt := range badPathTests {
		err := Unmarshal(StringReader(pathTestString), tt.v)
		if !reflect.DeepEqual(err, tt.e) {
			t.Fatalf("Unmarshal with %#v didn't fail properly: %#v", tt.v, err)
		}
	}
}
<commit_msg>xml: fix typo in test.<commit_after>// 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 xml

import (
	"reflect"
	"testing"
)

// Stripped down Atom feed data structures.

func TestUnmarshalFeed(t *testing.T) {
	var f Feed
	if err := Unmarshal(StringReader(atomFeedString), &f); err != nil {
		t.Fatalf("Unmarshal: %s", err)
	}
	if !reflect.DeepEqual(f, atomFeed) {
		t.Fatalf("have %#v\nwant %#v", f, atomFeed)
	}
}

// hget http://codereview.appspot.com/rss/mine/rsc
const atomFeedString = `
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-us"><title>Code Review - My issues</title><link href="http://codereview.appspot.com/" rel="alternate"></link><li-nk href="http://codereview.appspot.com/rss/mine/rsc" rel="self"></li-nk><id>http://codereview.appspot.com/</id><updated>2009-10-04T01:35:58+00:00</updated><author><name>rietveld<></name></author><entry><title>rietveld: an attempt at pubsubhubbub
</title><link hre-f="http://codereview.appspot.com/126085" rel="alternate"></link><updated>2009-10-04T01:35:58+00:00</updated><author><name>email-address-removed</name></author><id>urn:md5:134d9179c41f806be79b3a5f7877d19a</id><summary type="html">
  An attempt at adding pubsubhubbub support to Rietveld.
http://code.google.com/p/pubsubhubbub
http://code.google.com/p/rietveld/issues/detail?id=155

The server side of the protocol is trivial:
  1. add a &lt;link rel=&quot;hub&quot; href=&quot;hub-server&quot;&gt; tag to all
     feeds that will be pubsubhubbubbed.
  2. every time one of those feeds changes, tell the hub
     with a simple POST request.

I have tested this by adding debug prints to a local hub
server and checking that the server got the right publish
requests.

I can&#39;t quite get the server to work, but I think the bug
is not in my code.  I think that the server expects to be
able to grab the feed and see the feed&#39;s actual URL in
the link rel=&quot;self&quot;, but the default value for that drops
the :port from the URL, and I cannot for the life of me
figure out how to get the Atom generator deep inside
django not to do that, or even where it is doing that,
or even what code is running to generate the Atom feed.
(I thought I knew but I added some assert False statements
and it kept running!)

Ignoring that particular problem, I would appreciate
feedback on the right way to get the two values at
the top of feeds.py marked NOTE(rsc).

</summary></entry><entry><title>rietveld: correct tab handling
</title><link href="http://codereview.appspot.com/124106" rel="alternate"></link><updated>2009-10-03T23:02:17+00:00</updated><author><name>email-address-removed</name></author><id>urn:md5:0a2a4f19bb815101f0ba2904aed7c35a</id><summary type="html">
  This fixes the buggy tab rendering that can be seen at
http://codereview.appspot.com/116075/diff/1/2

The fundamental problem was that the tab code was
not being told what column the text began in, so it
didn&#39;t know where to put the tab stops.  Another problem
was that some of the code assumed that string byte
offsets were the same as column offsets, which is only
true if there are no tabs.

In the process of fixing this, I cleaned up the arguments
to Fold and ExpandTabs and renamed them Break and
_ExpandTabs so that I could be sure that I found all the
call sites.  I also wanted to verify that ExpandTabs was
not being used from outside intra_region_diff.py.

</summary></entry></feed> 	   `

type Feed struct {
	XMLName Name "http://www.w3.org/2005/Atom feed"
	Title   string
	Id      string
	Link    []Link
	Updated Time
	Author  Person
	Entry   []Entry
}

type Entry struct {
	Title   string
	Id      string
	Link    []Link
	Updated Time
	Author  Person
	Summary Text
}

type Link struct {
	Rel  string "attr"
	Href string "attr"
}

type Person struct {
	Name     string
	URI      string
	Email    string
	InnerXML string "innerxml"
}

type Text struct {
	Type string "attr"
	Body string "chardata"
}

type Time string

var atomFeed = Feed{
	XMLName: Name{"http://www.w3.org/2005/Atom", "feed"},
	Title:   "Code Review - My issues",
	Link: []Link{
		{Rel: "alternate", Href: "http://codereview.appspot.com/"},
		{Rel: "self", Href: "http://codereview.appspot.com/rss/mine/rsc"},
	},
	Id:      "http://codereview.appspot.com/",
	Updated: "2009-10-04T01:35:58+00:00",
	Author: Person{
		Name:     "rietveld<>",
		InnerXML: "<name>rietveld<></name>",
	},
	Entry: []Entry{
		{
			Title: "rietveld: an attempt at pubsubhubbub\n",
			Link: []Link{
				{Rel: "alternate", Href: "http://codereview.appspot.com/126085"},
			},
			Updated: "2009-10-04T01:35:58+00:00",
			Author: Person{
				Name:     "email-address-removed",
				InnerXML: "<name>email-address-removed</name>",
			},
			Id: "urn:md5:134d9179c41f806be79b3a5f7877d19a",
			Summary: Text{
				Type: "html",
				Body: `
  An attempt at adding pubsubhubbub support to Rietveld.
http://code.google.com/p/pubsubhubbub
http://code.google.com/p/rietveld/issues/detail?id=155

The server side of the protocol is trivial:
  1. add a <link rel="hub" href="hub-server"> tag to all
     feeds that will be pubsubhubbubbed.
  2. every time one of those feeds changes, tell the hub
     with a simple POST request.

I have tested this by adding debug prints to a local hub
server and checking that the server got the right publish
requests.

I can't quite get the server to work, but I think the bug
is not in my code.  I think that the server expects to be
able to grab the feed and see the feed's actual URL in
the link rel="self", but the default value for that drops
the :port from the URL, and I cannot for the life of me
figure out how to get the Atom generator deep inside
django not to do that, or even where it is doing that,
or even what code is running to generate the Atom feed.
(I thought I knew but I added some assert False statements
and it kept running!)

Ignoring that particular problem, I would appreciate
feedback on the right way to get the two values at
the top of feeds.py marked NOTE(rsc).

`,
			},
		},
		{
			Title: "rietveld: correct tab handling\n",
			Link: []Link{
				{Rel: "alternate", Href: "http://codereview.appspot.com/124106"},
			},
			Updated: "2009-10-03T23:02:17+00:00",
			Author: Person{
				Name:     "email-address-removed",
				InnerXML: "<name>email-address-removed</name>",
			},
			Id: "urn:md5:0a2a4f19bb815101f0ba2904aed7c35a",
			Summary: Text{
				Type: "html",
				Body: `
  This fixes the buggy tab rendering that can be seen at
http://codereview.appspot.com/116075/diff/1/2

The fundamental problem was that the tab code was
not being told what column the text began in, so it
didn't know where to put the tab stops.  Another problem
was that some of the code assumed that string byte
offsets were the same as column offsets, which is only
true if there are no tabs.

In the process of fixing this, I cleaned up the arguments
to Fold and ExpandTabs and renamed them Break and
_ExpandTabs so that I could be sure that I found all the
call sites.  I also wanted to verify that ExpandTabs was
not being used from outside intra_region_diff.py.

`,
			},
		},
	},
}

type FieldNameTest struct {
	in, out string
}

var FieldNameTests = []FieldNameTest{
	{"Profile-Image", "profileimage"},
	{"_score", "score"},
}

func TestFieldName(t *testing.T) {
	for _, tt := range FieldNameTests {
		a := fieldName(tt.in)
		if a != tt.out {
			t.Fatalf("have %#v\nwant %#v\n\n", a, tt.out)
		}
	}
}

const pathTestString = `
<result>
    <before>1</before>
    <items>
        <item1>
            <value>A</value>
        </item1>
        <item2>
            <value>B</value>
        </item2>
        <Item1>
            <Value>C</Value>
            <Value>D</Value>
        </Item1>
    </items>
    <after>2</after>
</result>
`

type PathTestItem struct {
	Value string
}

type PathTestA struct {
	Items         []PathTestItem ">item1"
	Before, After string
}

type PathTestB struct {
	Other         []PathTestItem "items>Item1"
	Before, After string
}

type PathTestC struct {
	Values1       []string "items>item1>value"
	Values2       []string "items>item2>value"
	Before, After string
}

type PathTestSet struct {
	Item1 []PathTestItem
}

type PathTestD struct {
	Other         PathTestSet "items>"
	Before, After string
}

var pathTests = []interface{}{
	&PathTestA{Items: []PathTestItem{{"A"}, {"D"}}, Before: "1", After: "2"},
	&PathTestB{Other: []PathTestItem{{"A"}, {"D"}}, Before: "1", After: "2"},
	&PathTestC{Values1: []string{"A", "C", "D"}, Values2: []string{"B"}, Before: "1", After: "2"},
	&PathTestD{Other: PathTestSet{Item1: []PathTestItem{{"A"}, {"D"}}}, Before: "1", After: "2"},
}

func TestUnmarshalPaths(t *testing.T) {
	for _, pt := range pathTests {
		p := reflect.MakeZero(reflect.NewValue(pt).Type()).(*reflect.PtrValue)
		p.PointTo(reflect.MakeZero(p.Type().(*reflect.PtrType).Elem()))
		v := p.Interface()
		if err := Unmarshal(StringReader(pathTestString), v); err != nil {
			t.Fatalf("Unmarshal: %s", err)
		}
		if !reflect.DeepEqual(v, pt) {
			t.Fatalf("have %#v\nwant %#v", v, pt)
		}
	}
}

type BadPathTestA struct {
	First  string "items>item1"
	Other  string "items>item2"
	Second string "items>"
}

type BadPathTestB struct {
	Other  string "items>item2>value"
	First  string "items>item1"
	Second string "items>item1>value"
}

var badPathTests = []struct {
	v, e interface{}
}{
	{&BadPathTestA{}, &TagPathError{reflect.Typeof(BadPathTestA{}), "First", "items>item1", "Second", "items>"}},
	{&BadPathTestB{}, &TagPathError{reflect.Typeof(BadPathTestB{}), "First", "items>item1", "Second", "items>item1>value"}},
}

func TestUnmarshalBadPaths(t *testing.T) {
	for _, tt := range badPathTests {
		err := Unmarshal(StringReader(pathTestString), tt.v)
		if !reflect.DeepEqual(err, tt.e) {
			t.Fatalf("Unmarshal with %#v didn't fail properly: %#v", tt.v, err)
		}
	}
}
<|endoftext|>


<commit_before>package brokers

import (
	"github.com/kafkactl/api/client"
)

type BrokerAdd struct{}

func Add(api client.APIClient, in *BrokerAdd) error {}
<commit_msg>brokers: Add minor error fix (imports & return)<commit_after>package brokers

import (
	"github.com/eddyzags/kafkactl/api/client"
)

type BrokerAdd struct{}

func Add(api client.APIClient, in *BrokerAdd) error {
	return nil
}
<|endoftext|>


<commit_before><commit_msg>Force apt-get to use IPv4<commit_after><|endoftext|>


<commit_before>// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package oglematchers_test

import (
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
	"errors"
)

////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////

type allOfFakeMatcher struct {
	desc string
	res  MatchResult
	err  error
}

func (m *allOfFakeMatcher) Matches(c interface{}) (MatchResult, error) {
	return m.res, m.err
}

func (m *allOfFakeMatcher) Description() string {
	return m.desc
}

type AllOfTest struct {
}

func init() { RegisterTestSuite(&AllOfTest{}) }

////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////

func (t *AllOfTest) DescriptionWithEmptySet() {
	m := AllOf()
	ExpectEq("is anything", m.Description())
}

func (t *AllOfTest) DescriptionWithOneMatcher() {
	m := AllOf(&allOfFakeMatcher{"taco", MATCH_FALSE, nil})
	ExpectEq("taco", m.Description())
}

func (t *AllOfTest) DescriptionWithMultipleMatchers() {
	m := AllOf(
		&allOfFakeMatcher{"taco", MATCH_FALSE, nil},
		&allOfFakeMatcher{"burrito", MATCH_FALSE, nil},
		&allOfFakeMatcher{"enchilada", MATCH_FALSE, nil})

	ExpectEq("taco, and burrito, and enchilada", m.Description())
}

func (t *AllOfTest) EmptySet() {
	m := AllOf()
	res, err := m.Matches(17)

	ExpectEq(MATCH_TRUE, res)
	ExpectEq(nil, err)
}

func (t *AllOfTest) OneMatcherSaysUndefinedAndSomeSayFalse() {
	m := AllOf(
		&allOfFakeMatcher{"", MATCH_FALSE, errors.New("")},
		&allOfFakeMatcher{"", MATCH_UNDEFINED, errors.New("taco")},
		&allOfFakeMatcher{"", MATCH_FALSE, errors.New("")},
		&allOfFakeMatcher{"", MATCH_TRUE, nil})

	res, err := m.Matches(17)

	ExpectEq(MATCH_UNDEFINED, res)
	ExpectThat(err, Error(Equals("taco")))
}

func (t *AllOfTest) OneMatcherSaysFalseAndOthersSayTrue() {
	m := AllOf(
		&allOfFakeMatcher{"", MATCH_TRUE, nil},
		&allOfFakeMatcher{"", MATCH_FALSE, errors.New("taco")},
		&allOfFakeMatcher{"", MATCH_TRUE, nil})

	res, err := m.Matches(17)

	ExpectEq(MATCH_FALSE, res)
	ExpectThat(err, Error(Equals("taco")))
}

func (t *AllOfTest) AllMatchersSayTrue() {
	m := AllOf(
		&allOfFakeMatcher{"", MATCH_TRUE, nil},
		&allOfFakeMatcher{"", MATCH_TRUE, nil},
		&allOfFakeMatcher{"", MATCH_TRUE, nil})

	res, err := m.Matches(17)

	ExpectEq(MATCH_TRUE, res)
	ExpectEq(nil, err)
}
<commit_msg>Fixed up all_of_test.go for #20.<commit_after>// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package oglematchers_test

import (
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
	"errors"
)

////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////

type allOfFakeMatcher struct {
	desc string
	res  bool
	err  error
}

func (m *allOfFakeMatcher) Matches(c interface{}) (bool, error) {
	return m.res, m.err
}

func (m *allOfFakeMatcher) Description() string {
	return m.desc
}

type AllOfTest struct {
}

func init() { RegisterTestSuite(&AllOfTest{}) }

////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////

func (t *AllOfTest) DescriptionWithEmptySet() {
	m := AllOf()
	ExpectEq("is anything", m.Description())
}

func (t *AllOfTest) DescriptionWithOneMatcher() {
	m := AllOf(&allOfFakeMatcher{"taco", false, errors.New("")})
	ExpectEq("taco", m.Description())
}

func (t *AllOfTest) DescriptionWithMultipleMatchers() {
	m := AllOf(
		&allOfFakeMatcher{"taco", false, errors.New("")},
		&allOfFakeMatcher{"burrito", false, errors.New("")},
		&allOfFakeMatcher{"enchilada", false, errors.New("")})

	ExpectEq("taco, and burrito, and enchilada", m.Description())
}

func (t *AllOfTest) EmptySet() {
	m := AllOf()
	res, err := m.Matches(17)

	ExpectTrue(res)
	ExpectFalse(isFatal(err))
	ExpectThat(err, Error(Equals("")))
}

func (t *AllOfTest) OneMatcherReturnsFatalErrorAndSomeOthersFail() {
	m := AllOf(
		&allOfFakeMatcher{"", false, errors.New("")},
		&allOfFakeMatcher{"", false, NewFatalError("taco")},
		&allOfFakeMatcher{"", false, errors.New("")},
		&allOfFakeMatcher{"", true, nil})

	res, err := m.Matches(17)

	ExpectFalse(res)
	ExpectTrue(isFatal(err))
	ExpectThat(err, Error(Equals("taco")))
}

func (t *AllOfTest) OneMatcherReturnsNonFatalAndOthersSayTrue() {
	m := AllOf(
		&allOfFakeMatcher{"", true, nil},
		&allOfFakeMatcher{"", false, errors.New("taco")},
		&allOfFakeMatcher{"", true, nil})

	res, err := m.Matches(17)

	ExpectFalse(res)
	ExpectTrue(isFatal(err))
	ExpectThat(err, Error(Equals("taco")))
}

func (t *AllOfTest) AllMatchersSayTrue() {
	m := AllOf(
		&allOfFakeMatcher{"", true, nil},
		&allOfFakeMatcher{"", true, nil},
		&allOfFakeMatcher{"", true, nil})

	res, err := m.Matches(17)

	ExpectTrue(res)
	ExpectEq(nil, err)
}
<|endoftext|>