<commit_before>package wkhtmltopdf

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
)

type jsonPDFGenerator struct {
	GlobalOptions  globalOptions
	OutlineOptions outlineOptions
	Cover          cover
	TOC            toc
	Pages          []jsonPage
}

type jsonPage struct {
	PageOptions    PageOptions
	InputFile      string
	Base64PageData string
}

// ToJSON creates JSON of the complete representation of the PDFGenerator.
// It also saves all pages, for a PageReader page, the content is stored as a Base64 string in the JSON.
func (pdfg *PDFGenerator) ToJSON() ([]byte, error) {

	jpdf := &jsonPDFGenerator{
		TOC:            pdfg.TOC,
		Cover:          pdfg.Cover,
		GlobalOptions:  pdfg.globalOptions,
		OutlineOptions: pdfg.outlineOptions,
	}

	for _, p := range pdfg.pages {
		jp := jsonPage{
			InputFile: p.InputFile(),
		}
		switch tp := p.(type) {
		case *Page:
			jp.PageOptions = tp.PageOptions
		case *PageReader:
			jp.PageOptions = tp.PageOptions
		}
		if p.Reader() != nil {
			buf, err := ioutil.ReadAll(p.Reader())
			if err != nil {
				return nil, err
			}
			jp.Base64PageData = base64.StdEncoding.EncodeToString(buf)
		}
		jpdf.Pages = append(jpdf.Pages, jp)
	}
	return json.Marshal(jpdf)
}

// NewPDFGeneratorFromJSON creates a new PDFGenerator and restores all the settings and pages
// from a JSON byte slice which should be created using PDFGenerator.ToJSON().
func NewPDFGeneratorFromJSON(jsonReader io.Reader) (*PDFGenerator, error) {

	jp := new(jsonPDFGenerator)

	err := json.NewDecoder(jsonReader).Decode(jp)
	if err != nil {
		return nil, fmt.Errorf("error unmarshaling JSON: %s", err)
	}

	pdfg, err := NewPDFGenerator()
	if err != nil {
		return nil, fmt.Errorf("error creating PDF generator: %s", err)
	}

	pdfg.TOC = jp.TOC
	pdfg.Cover = jp.Cover
	pdfg.globalOptions = jp.GlobalOptions
	pdfg.outlineOptions = jp.OutlineOptions

	for i, p := range jp.Pages {
		if p.Base64PageData == "" {
			pdfg.AddPage(&Page{
				Input:       p.InputFile,
				PageOptions: p.PageOptions,
			})
			continue
		}
		buf, err := base64.StdEncoding.DecodeString(p.Base64PageData)
		if err != nil {
			return nil, fmt.Errorf("error decoding base 64 input on page %d: %s", i, err)
		}
		pdfg.AddPage(&PageReader{
			Input:       bytes.NewReader(buf),
			PageOptions: p.PageOptions,
		})
	}

	return pdfg, nil
}

type jsonBoolOption struct {
	Option string
	Value  bool
}

func (bo *boolOption) MarshalJSON() ([]byte, error) {
	return json.Marshal(&jsonBoolOption{bo.option, bo.value})
}

func (bo *boolOption) UnmarshalJSON(b []byte) error {
	jbo := new(jsonBoolOption)
	err := json.Unmarshal(b, jbo)
	if err != nil {
		return err
	}
	bo.value = jbo.Value
	bo.option = jbo.Option
	return nil
}

type jsonStringOption struct {
	Option string
	Value  string
}

func (so *stringOption) MarshalJSON() ([]byte, error) {
	return json.Marshal(&jsonStringOption{so.option, so.value})
}

func (so *stringOption) UnmarshalJSON(b []byte) error {
	jso := new(jsonStringOption)
	err := json.Unmarshal(b, jso)
	if err != nil {
		return err
	}
	so.value = jso.Value
	so.option = jso.Option
	return nil
}

type jsonUintOption struct {
	Option string
	IsSet  bool
	Value  uint
}

func (io *uintOption) MarshalJSON() ([]byte, error) {
	return json.Marshal(&jsonUintOption{io.option, io.isSet, io.value})
}

func (io *uintOption) UnmarshalJSON(b []byte) error {
	jio := new(jsonUintOption)
	err := json.Unmarshal(b, jio)
	if err != nil {
		return err
	}
	io.value = jio.Value
	io.isSet = jio.IsSet
	io.option = jio.Option
	return nil
}

type jsonFloatOption struct {
	Option string
	IsSet  bool
	Value  float64
}

func (fo *floatOption) MarshalJSON() ([]byte, error) {
	return json.Marshal(&jsonFloatOption{fo.option, fo.isSet, fo.value})
}

func (fo *floatOption) UnmarshalJSON(b []byte) error {
	jfo := new(jsonFloatOption)
	err := json.Unmarshal(b, jfo)
	if err != nil {
		return err
	}
	fo.value = jfo.Value
	fo.isSet = jfo.IsSet
	fo.option = jfo.Option
	return nil
}

type jsonMapOption struct {
	Option string
	Value  map[string]string
}

func (mo *mapOption) MarshalJSON() ([]byte, error) {
	return json.Marshal(&jsonMapOption{mo.option, mo.value})
}

func (mo *mapOption) UnmarshalJSON(b []byte) error {
	jmo := new(jsonMapOption)
	err := json.Unmarshal(b, jmo)
	if err != nil {
		return err
	}
	mo.value = jmo.Value
	mo.option = jmo.Option
	return nil
}

type jsonSliceOption struct {
	Option string
	Value  []string
}

func (so *sliceOption) MarshalJSON() ([]byte, error) {
	return json.Marshal(&jsonSliceOption{so.option, so.value})
}

func (so *sliceOption) UnmarshalJSON(b []byte) error {
	jso := new(jsonSliceOption)
	err := json.Unmarshal(b, jso)
	if err != nil {
		return err
	}
	so.value = jso.Value
	so.option = jso.Option
	return nil
}
<commit_msg>update comment<commit_after>package wkhtmltopdf

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
)

type jsonPDFGenerator struct {
	GlobalOptions  globalOptions
	OutlineOptions outlineOptions
	Cover          cover
	TOC            toc
	Pages          []jsonPage
}

type jsonPage struct {
	PageOptions    PageOptions
	InputFile      string
	Base64PageData string
}

// ToJSON creates JSON of the complete representation of the PDFGenerator.
// It also saves all pages. For a PageReader page, the content is stored as a Base64 string in the JSON.
func (pdfg *PDFGenerator) ToJSON() ([]byte, error) {

	jpdf := &jsonPDFGenerator{
		TOC:            pdfg.TOC,
		Cover:          pdfg.Cover,
		GlobalOptions:  pdfg.globalOptions,
		OutlineOptions: pdfg.outlineOptions,
	}

	for _, p := range pdfg.pages {
		jp := jsonPage{
			InputFile: p.InputFile(),
		}
		switch tp := p.(type) {
		case *Page:
			jp.PageOptions = tp.PageOptions
		case *PageReader:
			jp.PageOptions = tp.PageOptions
		}
		if p.Reader() != nil {
			buf, err := ioutil.ReadAll(p.Reader())
			if err != nil {
				return nil, err
			}
			jp.Base64PageData = base64.StdEncoding.EncodeToString(buf)
		}
		jpdf.Pages = append(jpdf.Pages, jp)
	}
	return json.Marshal(jpdf)
}

// NewPDFGeneratorFromJSON creates a new PDFGenerator and restores all the settings and pages
// from a JSON byte slice which should be created using PDFGenerator.ToJSON().
func NewPDFGeneratorFromJSON(jsonReader io.Reader) (*PDFGenerator, error) {

	jp := new(jsonPDFGenerator)

	err := json.NewDecoder(jsonReader).Decode(jp)
	if err != nil {
		return nil, fmt.Errorf("error unmarshaling JSON: %s", err)
	}

	pdfg, err := NewPDFGenerator()
	if err != nil {
		return nil, fmt.Errorf("error creating PDF generator: %s", err)
	}

	pdfg.TOC = jp.TOC
	pdfg.Cover = jp.Cover
	pdfg.globalOptions = jp.GlobalOptions
	pdfg.outlineOptions = jp.OutlineOptions

	for i, p := range jp.Pages {
		if p.Base64PageData == "" {
			pdfg.AddPage(&Page{
				Input:       p.InputFile,
				PageOptions: p.PageOptions,
			})
			continue
		}
		buf, err := base64.StdEncoding.DecodeString(p.Base64PageData)
		if err != nil {
			return nil, fmt.Errorf("error decoding base 64 input on page %d: %s", i, err)
		}
		pdfg.AddPage(&PageReader{
			Input:       bytes.NewReader(buf),
			PageOptions: p.PageOptions,
		})
	}

	return pdfg, nil
}

type jsonBoolOption struct {
	Option string
	Value  bool
}

func (bo *boolOption) MarshalJSON() ([]byte, error) {
	return json.Marshal(&jsonBoolOption{bo.option, bo.value})
}

func (bo *boolOption) UnmarshalJSON(b []byte) error {
	jbo := new(jsonBoolOption)
	err := json.Unmarshal(b, jbo)
	if err != nil {
		return err
	}
	bo.value = jbo.Value
	bo.option = jbo.Option
	return nil
}

type jsonStringOption struct {
	Option string
	Value  string
}

func (so *stringOption) MarshalJSON() ([]byte, error) {
	return json.Marshal(&jsonStringOption{so.option, so.value})
}

func (so *stringOption) UnmarshalJSON(b []byte) error {
	jso := new(jsonStringOption)
	err := json.Unmarshal(b, jso)
	if err != nil {
		return err
	}
	so.value = jso.Value
	so.option = jso.Option
	return nil
}

type jsonUintOption struct {
	Option string
	IsSet  bool
	Value  uint
}

func (io *uintOption) MarshalJSON() ([]byte, error) {
	return json.Marshal(&jsonUintOption{io.option, io.isSet, io.value})
}

func (io *uintOption) UnmarshalJSON(b []byte) error {
	jio := new(jsonUintOption)
	err := json.Unmarshal(b, jio)
	if err != nil {
		return err
	}
	io.value = jio.Value
	io.isSet = jio.IsSet
	io.option = jio.Option
	return nil
}

type jsonFloatOption struct {
	Option string
	IsSet  bool
	Value  float64
}

func (fo *floatOption) MarshalJSON() ([]byte, error) {
	return json.Marshal(&jsonFloatOption{fo.option, fo.isSet, fo.value})
}

func (fo *floatOption) UnmarshalJSON(b []byte) error {
	jfo := new(jsonFloatOption)
	err := json.Unmarshal(b, jfo)
	if err != nil {
		return err
	}
	fo.value = jfo.Value
	fo.isSet = jfo.IsSet
	fo.option = jfo.Option
	return nil
}

type jsonMapOption struct {
	Option string
	Value  map[string]string
}

func (mo *mapOption) MarshalJSON() ([]byte, error) {
	return json.Marshal(&jsonMapOption{mo.option, mo.value})
}

func (mo *mapOption) UnmarshalJSON(b []byte) error {
	jmo := new(jsonMapOption)
	err := json.Unmarshal(b, jmo)
	if err != nil {
		return err
	}
	mo.value = jmo.Value
	mo.option = jmo.Option
	return nil
}

type jsonSliceOption struct {
	Option string
	Value  []string
}

func (so *sliceOption) MarshalJSON() ([]byte, error) {
	return json.Marshal(&jsonSliceOption{so.option, so.value})
}

func (so *sliceOption) UnmarshalJSON(b []byte) error {
	jso := new(jsonSliceOption)
	err := json.Unmarshal(b, jso)
	if err != nil {
		return err
	}
	so.value = jso.Value
	so.option = jso.Option
	return nil
}
<|endoftext|>


<commit_before>// Gone-lib email "one" liners
package email
<commit_msg>Updated comment.<commit_after>// Gone-lib email "one" liners.
package email
<|endoftext|>


<commit_before>package empire

import (
	"database/sql/driver"
	"fmt"
	"time"

	"github.com/remind101/empire/empire/pkg/container"
	"gopkg.in/gorp.v1"
)

// JobID represents a unique identifier for a Job.
type JobID string

// Scan implements the sql.Scanner interface.
func (id *JobID) Scan(src interface{}) error {
	if src, ok := src.([]byte); ok {
		*id = JobID(src)
	}

	return nil
}

// Value implements the driver.Value interface.
func (id JobID) Value() (driver.Value, error) {
	return driver.Value(string(id)), nil
}

// Job represents a Job that was submitted to the scheduler.
type Job struct {
	ID JobID `db:"id"`

	AppName        string `db:"app_id"`
	ReleaseVersion `db:"release_version"`
	ProcessType    `db:"process_type"`
	Instance       int `db:"instance"`

	Environment Vars  `db:"environment"`
	Image       Image `db:"image"`
	Command     `db:"command"`

	// UpdatedAt indicates when this job last changed state.
	UpdatedAt time.Time `db:"updated_at"`
}

// PreInsert implements a pre insert hook for the db interface
func (j *Job) PreInsert(s gorp.SqlExecutor) error {
	j.UpdatedAt = Now()
	return nil
}

func (j *Job) ContainerName() string {
	return newContainerName(
		j.AppName,
		j.ReleaseVersion,
		j.ProcessType,
		j.Instance,
	)
}

// JobState represents the state of a submitted job.
type JobState struct {
	Job       *Job
	MachineID string
	Name      string
	State     string
}

// Schedule is an interface that represents something that can schedule jobs
// onto the cluster.
type Scheduler interface {
	Schedule(...*Job) error
	Unschedule(...*Job) error
}

type JobsFinder interface {
	JobsList(JobsListQuery) ([]*Job, error)
}

type JobsService interface {
	Scheduler
	JobsFinder
}

type jobsService struct {
	DB
	scheduler container.Scheduler
}

func (s *jobsService) JobsList(q JobsListQuery) ([]*Job, error) {
	return JobsList(s.DB, q)
}

func (s *jobsService) Schedule(jobs ...*Job) error {
	for _, j := range jobs {
		if _, err := Schedule(s.DB, s.scheduler, j); err != nil {
			return err
		}
	}

	return nil
}

func (s *jobsService) Unschedule(jobs ...*Job) error {
	for _, j := range jobs {
		if err := Unschedule(s.DB, s.scheduler, j); err != nil {
			return err
		}
	}

	return nil
}

// JobsCreate inserts the Job into the database.
func JobsCreate(db Inserter, job *Job) (*Job, error) {
	return job, db.Insert(job)
}

// JobsDestroy removes a Job from the database.
func JobsDestroy(db Deleter, job *Job) error {
	_, err := db.Delete(job)
	return err
}

// JobsListQuery is a query object to filter results from JobsRepository List.
type JobsListQuery struct {
	App     string
	Release ReleaseVersion
}

// JobsList returns a filtered list of Jobs.
func JobsList(db Queryier, q JobsListQuery) ([]*Job, error) {
	var jobs []*Job
	query := `select * from jobs where (app_id = $1 OR $1 = '') and (release_version = $2 OR $2 = 0)`
	return jobs, db.Select(&jobs, query, string(q.App), int(q.Release))
}

// Schedule schedules to job onto the cluster, then persists it to the database.
func Schedule(db Inserter, s container.Scheduler, j *Job) (*Job, error) {
	env := environment(j.Environment)
	env["SERVICE_NAME"] = fmt.Sprintf("%s/%s", j.ProcessType, j.AppName)

	container := &container.Container{
		Name:    j.ContainerName(),
		Env:     env,
		Command: string(j.Command),
		Image: container.Image{
			Repo: string(j.Image.Repo),
			ID:   j.Image.ID,
		},
	}

	// Schedule the container onto the cluster.
	if err := s.Schedule(container); err != nil {
		return nil, err
	}

	return JobsCreate(db, j)
}

func Unschedule(db Deleter, s container.Scheduler, j *Job) error {
	if err := s.Unschedule(j.ContainerName()); err != nil {
		return err
	}

	return JobsDestroy(db, j)
}

type JobStatesFinder interface {
	JobStatesByApp(*App) ([]*JobState, error)
}

type JobStatesService interface {
	JobStatesFinder
}

type jobStatesService struct {
	DB
	JobsService
	scheduler container.Scheduler
}

func (s *jobStatesService) JobStatesByApp(app *App) ([]*JobState, error) {
	// Jobs expected to be running
	jobs, err := s.JobsService.JobsList(JobsListQuery{
		App: app.Name,
	})
	if err != nil {
		return nil, err
	}

	// Job states for all existing jobs
	sjs, err := s.scheduler.ContainerStates()
	if err != nil {
		return nil, err
	}

	// Create a map for easy lookups
	jsm := make(map[string]*container.ContainerState, len(sjs))
	for _, js := range sjs {
		jsm[js.Name] = js
	}

	// Create JobState based on Jobs and container.ContainerStates
	js := make([]*JobState, len(jobs))
	for i, j := range jobs {
		s, ok := jsm[j.ContainerName()]

		machineID := "unknown"
		state := "unknown"
		if ok {
			machineID = s.MachineID
			state = s.State
		}

		js[i] = &JobState{
			Job:       j,
			Name:      j.ContainerName(),
			MachineID: machineID,
			State:     state,
		}
	}

	return js, nil
}
<commit_msg>JobID.<commit_after>package empire

import (
	"fmt"
	"time"

	"github.com/remind101/empire/empire/pkg/container"
	"gopkg.in/gorp.v1"
)

// Job represents a Job that was submitted to the scheduler.
type Job struct {
	ID string `db:"id"`

	AppName        string `db:"app_id"`
	ReleaseVersion `db:"release_version"`
	ProcessType    `db:"process_type"`
	Instance       int `db:"instance"`

	Environment Vars  `db:"environment"`
	Image       Image `db:"image"`
	Command     `db:"command"`

	// UpdatedAt indicates when this job last changed state.
	UpdatedAt time.Time `db:"updated_at"`
}

// PreInsert implements a pre insert hook for the db interface
func (j *Job) PreInsert(s gorp.SqlExecutor) error {
	j.UpdatedAt = Now()
	return nil
}

func (j *Job) ContainerName() string {
	return newContainerName(
		j.AppName,
		j.ReleaseVersion,
		j.ProcessType,
		j.Instance,
	)
}

// JobState represents the state of a submitted job.
type JobState struct {
	Job       *Job
	MachineID string
	Name      string
	State     string
}

// Schedule is an interface that represents something that can schedule jobs
// onto the cluster.
type Scheduler interface {
	Schedule(...*Job) error
	Unschedule(...*Job) error
}

type JobsFinder interface {
	JobsList(JobsListQuery) ([]*Job, error)
}

type JobsService interface {
	Scheduler
	JobsFinder
}

type jobsService struct {
	DB
	scheduler container.Scheduler
}

func (s *jobsService) JobsList(q JobsListQuery) ([]*Job, error) {
	return JobsList(s.DB, q)
}

func (s *jobsService) Schedule(jobs ...*Job) error {
	for _, j := range jobs {
		if _, err := Schedule(s.DB, s.scheduler, j); err != nil {
			return err
		}
	}

	return nil
}

func (s *jobsService) Unschedule(jobs ...*Job) error {
	for _, j := range jobs {
		if err := Unschedule(s.DB, s.scheduler, j); err != nil {
			return err
		}
	}

	return nil
}

// JobsCreate inserts the Job into the database.
func JobsCreate(db Inserter, job *Job) (*Job, error) {
	return job, db.Insert(job)
}

// JobsDestroy removes a Job from the database.
func JobsDestroy(db Deleter, job *Job) error {
	_, err := db.Delete(job)
	return err
}

// JobsListQuery is a query object to filter results from JobsRepository List.
type JobsListQuery struct {
	App     string
	Release ReleaseVersion
}

// JobsList returns a filtered list of Jobs.
func JobsList(db Queryier, q JobsListQuery) ([]*Job, error) {
	var jobs []*Job
	query := `select * from jobs where (app_id = $1 OR $1 = '') and (release_version = $2 OR $2 = 0)`
	return jobs, db.Select(&jobs, query, string(q.App), int(q.Release))
}

// Schedule schedules to job onto the cluster, then persists it to the database.
func Schedule(db Inserter, s container.Scheduler, j *Job) (*Job, error) {
	env := environment(j.Environment)
	env["SERVICE_NAME"] = fmt.Sprintf("%s/%s", j.ProcessType, j.AppName)

	container := &container.Container{
		Name:    j.ContainerName(),
		Env:     env,
		Command: string(j.Command),
		Image: container.Image{
			Repo: string(j.Image.Repo),
			ID:   j.Image.ID,
		},
	}

	// Schedule the container onto the cluster.
	if err := s.Schedule(container); err != nil {
		return nil, err
	}

	return JobsCreate(db, j)
}

func Unschedule(db Deleter, s container.Scheduler, j *Job) error {
	if err := s.Unschedule(j.ContainerName()); err != nil {
		return err
	}

	return JobsDestroy(db, j)
}

type JobStatesFinder interface {
	JobStatesByApp(*App) ([]*JobState, error)
}

type JobStatesService interface {
	JobStatesFinder
}

type jobStatesService struct {
	DB
	JobsService
	scheduler container.Scheduler
}

func (s *jobStatesService) JobStatesByApp(app *App) ([]*JobState, error) {
	// Jobs expected to be running
	jobs, err := s.JobsService.JobsList(JobsListQuery{
		App: app.Name,
	})
	if err != nil {
		return nil, err
	}

	// Job states for all existing jobs
	sjs, err := s.scheduler.ContainerStates()
	if err != nil {
		return nil, err
	}

	// Create a map for easy lookups
	jsm := make(map[string]*container.ContainerState, len(sjs))
	for _, js := range sjs {
		jsm[js.Name] = js
	}

	// Create JobState based on Jobs and container.ContainerStates
	js := make([]*JobState, len(jobs))
	for i, j := range jobs {
		s, ok := jsm[j.ContainerName()]

		machineID := "unknown"
		state := "unknown"
		if ok {
			machineID = s.MachineID
			state = s.State
		}

		js[i] = &JobState{
			Job:       j,
			Name:      j.ContainerName(),
			MachineID: machineID,
			State:     state,
		}
	}

	return js, nil
}
<|endoftext|>


<commit_before>package engine

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

// Game represents a gochess game
type Game struct {
	board *Board
}

// NewGame creates a new gochess game and returns a reference
func NewGame() *Game {
	g := new(Game)
	g.board = NewBoard(defaultFEN)

	return g
}

// Run a given game
func (g *Game) Run() {

	scanner := bufio.NewScanner(os.Stdin)
	fmt.Printf("> ")

	for scanner.Scan() {

		in := scanner.Text()

		if in == "quit" || in == "q" {
			break

		} else if in == "moves" || in == "m" {
			gen := NewGenerator(g.board)
			printMoves(gen.GenerateMoves())

		} else if in == "perft" {
			Perft(position1FEN, position1Table)

		} else if in == "perft2" {
			Perft(position2FEN, position2Table)

		} else if in == "new" || in == "n" {
			g.board = NewBoard(defaultFEN)

		} else if in == "fen" || in == "f" {
			fmt.Printf("%s\n", generateFEN(g.board))

		} else if in == "undo" || in == "u" {
			g.board.UndoMove()

		} else if strings.HasPrefix(in, "fen ") {
			g.board = NewBoard(in[3:])

		} else if in == "print" || in == "p" {
			fmt.Printf("%s\n", g.board.String())

		} else if in == "search" || in == "s" {
			Search(g.board)

		} else if in == "do" || in == "d" {
			g.board.MakeMove(Search(g.board))

		} else if in == "eval" || in == "e" {
			fmt.Printf("Score: %d\n", Evaluate(g.board))

		} else if in == "auto" {
			for g.board.status == statusNormal {
				g.board.MakeMove(Search(g.board))
				fmt.Printf("%s\n", g.board.String())
			}

		} else if m, err := createMove(in); err == nil {
			gen := NewGenerator(g.board)
			moves := gen.GenerateMoves()

			found := Move{From: Invalid}

			for _, move := range moves {
				if move.From == m.From && move.To == m.To {
					found = move
					break
				}
			}

			if found.From != Invalid {
				g.board.MakeMove(found)
			} else {
				fmt.Printf("illegal move\n")
			}

		} else {
			fmt.Printf("invalid input\n")
		}

		fmt.Printf("> ")
	}
}
<commit_msg>Add "a" as alias for "auto"<commit_after>package engine

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

// Game represents a gochess game
type Game struct {
	board *Board
}

// NewGame creates a new gochess game and returns a reference
func NewGame() *Game {
	g := new(Game)
	g.board = NewBoard(defaultFEN)

	return g
}

// Run a given game
func (g *Game) Run() {

	scanner := bufio.NewScanner(os.Stdin)
	fmt.Printf("> ")

	for scanner.Scan() {

		in := scanner.Text()

		if in == "quit" || in == "q" {
			break

		} else if in == "moves" || in == "m" {
			gen := NewGenerator(g.board)
			printMoves(gen.GenerateMoves())

		} else if in == "perft" {
			Perft(position1FEN, position1Table)

		} else if in == "perft2" {
			Perft(position2FEN, position2Table)

		} else if in == "new" || in == "n" {
			g.board = NewBoard(defaultFEN)

		} else if in == "fen" || in == "f" {
			fmt.Printf("%s\n", generateFEN(g.board))

		} else if in == "undo" || in == "u" {
			g.board.UndoMove()

		} else if strings.HasPrefix(in, "fen ") {
			g.board = NewBoard(in[3:])

		} else if in == "print" || in == "p" {
			fmt.Printf("%s\n", g.board.String())

		} else if in == "search" || in == "s" {
			Search(g.board)

		} else if in == "do" || in == "d" {
			g.board.MakeMove(Search(g.board))

		} else if in == "eval" || in == "e" {
			fmt.Printf("Score: %d\n", Evaluate(g.board))

		} else if in == "auto" || in == "a" {
			for g.board.status == statusNormal {
				g.board.MakeMove(Search(g.board))
				fmt.Printf("%s\n", g.board.String())
			}

		} else if m, err := createMove(in); err == nil {
			gen := NewGenerator(g.board)
			moves := gen.GenerateMoves()

			found := Move{From: Invalid}

			for _, move := range moves {
				if move.From == m.From && move.To == m.To {
					found = move
					break
				}
			}

			if found.From != Invalid {
				g.board.MakeMove(found)
			} else {
				fmt.Printf("illegal move\n")
			}

		} else {
			fmt.Printf("invalid input\n")
		}

		fmt.Printf("> ")
	}
}
<|endoftext|>


<commit_before>package petsounds_scrapers

import (
	"github.com/PuerkitoBio/goquery"
	"io"
	"log"
	"net/http"
	"net/url"
	"os"
	"strings"
)

type Scraper interface {
	Search() string
}

func BuildTorrentFilenameFromMagnet(dest string, magnet string) string {
	u, err := url.Parse(magnet)

	if err != nil {
		log.Fatal(err)
	}

	name := strings.Replace(u.Query()["xt"][0], "urn:btih:", "", -1)

	return dest + name + ".torrent"
}

func MagnetToTorrent(magnet string, destination string) string {

	resp, err := http.PostForm("http://magnet2torrent.com/upload/", url.Values{"magnet": {magnet}})
	defer resp.Body.Close()
	if err != nil {
		log.Fatal(err)
	}

	filename := BuildTorrentFilenameFromMagnet(destination, magnet)

	out, err := os.Create(filename)
	defer out.Close()
	if err != nil {
		log.Fatal(err)
	}

	io.Copy(out, resp.Body)

	return filename
}

type PirateBay struct {
	ProxyUrl string
}

func NewPirateBay(proxyUrl string) *PirateBay {
	return &PirateBay{ProxyUrl: proxyUrl}
}

func (pb PirateBay) Search(term string) string {
	doc, _ := goquery.NewDocument(pb.ProxyUrl + "/search/" + url.QueryEscape(term) + "/0/7/0")

	// find the first tr of the #search results then get the <a> where the href starts with "magnet"
	sel := "#searchResult tbody tr:first-child a[href^=magnet]"

	log.Printf("doc: %v", doc)

	result, _ := doc.Find(sel).Attr("href")

	return result
}

func (pb PirateBay) SearchAndSave(term string, dest string) string {
	magnet := pb.Search(term)
	return MagnetToTorrent(magnet, dest)
}
<commit_msg>Make saving a torrent a single event, rather than create + modify<commit_after>package petsounds_scrapers

import (
	"github.com/PuerkitoBio/goquery"
	"log"
	"net/http"
	"net/url"
	"strings"
	"io/ioutil"
)

type Scraper interface {
	Search() string
}

func BuildTorrentFilenameFromMagnet(dest string, magnet string) string {
	u, err := url.Parse(magnet)

	if err != nil {
		log.Fatal(err)
	}

	name := strings.Replace(u.Query()["xt"][0], "urn:btih:", "", -1)

	return dest + name + ".torrent"
}

func MagnetToTorrent(magnet string, destination string) string {

	resp, err := http.PostForm("http://magnet2torrent.com/upload/", url.Values{"magnet": {magnet}})
	defer resp.Body.Close()
	if err != nil {
		log.Fatal(err)
	}

	filename := BuildTorrentFilenameFromMagnet(destination, magnet)

	body, err := ioutil.ReadAll(resp.Body)

	err = ioutil.WriteFile(filename, body, 0644)

	return filename
}

type PirateBay struct {
	ProxyUrl string
}

func NewPirateBay(proxyUrl string) *PirateBay {
	return &PirateBay{ProxyUrl: proxyUrl}
}

func (pb PirateBay) Search(term string) string {
	doc, _ := goquery.NewDocument(pb.ProxyUrl + "/search/" + url.QueryEscape(term) + "/0/7/0")

	// find the first tr of the #search results then get the <a> where the href starts with "magnet"
	sel := "#searchResult tbody tr:first-child a[href^=magnet]"

	log.Printf("doc: %v", doc)

	result, _ := doc.Find(sel).Attr("href")

	return result
}

func (pb PirateBay) SearchAndSave(term string, dest string) string {
	magnet := pb.Search(term)
	return MagnetToTorrent(magnet, dest)
}
<|endoftext|>


<commit_before>package life

import(
	"fmt"
	"crypto/md5"
	"bytes"
)

const(
	StateSame State = 0
	StateAlive = 1
	StateDead = -1
)

type State int

type Bounds struct {
	W, H int
}

type Pos struct {
	X, Y int
}

type Env struct {
	Dead bool
	Generation int64
	Bounds Bounds
	Cells map[Pos]*Cell
	HashCache [][md5.Size]byte
}

func NewEnv(bounds Bounds) *Env {
	env := &Env{
		Dead: false,
		Generation: 0,
		Bounds: bounds,
		Cells: make(map[Pos]*Cell),

		//initialize these so they don't match
		HashCache: [][md5.Size]byte{
			md5.Sum([]byte("hello")),
			md5.Sum([]byte("goodbye")),
			md5.Sum([]byte("asshole")),
		},
	}

	for x := 1; x <= bounds.W; x++ {
		for y := 1; y <= bounds.H; y++ {
			p := Pos{x, y}
			c := &Cell{
				Pos: p,
				Alive: false,
				NextState: StateSame,
				Neighbors: make([]*Cell, 8),
			}
			env.Cells[p] = c
		}
	}

	for _, cell := range env.Cells {
		cell.init(env)
	}

	return env
}

func (e *Env) SetLivingCells(p ...Pos) {
	for _, pos := range p{
		if pos.X < 1 || pos.X > e.Bounds.W || pos.Y < 1 || pos.Y > e.Bounds.H {
			continue
		}
		e.Cells[pos].Alive = true
	}
}

func (e *Env) PrintLife() {
	var buf bytes.Buffer
	buf.WriteString(fmt.Sprintf("Generation: %d\n", e.Generation))
	for y := 1; y <= e.Bounds.H; y++ {
		for x := 1; x <= e.Bounds.W; x++ {
			if x == 1{
				buf.WriteByte(' ')
			}

			p := Pos{x, y}
			buf.WriteString(e.Cells[p].String())
			buf.WriteByte(' ')
		}
		buf.WriteByte('\n')
	}
	buf.WriteByte('\n')
	fmt.Print(buf.String())
}

func (e *Env) Next() {
	generationSum := make([]byte, e.Bounds.W*e.Bounds.H)
	for _, c := range e.Cells{
		c.CalcNextState()
	}
	i := 0
	for x := 1; x <= e.Bounds.W; x++{
		for y := 1; y <= e.Bounds.H; y++{
			c := e.Cells[Pos{x, y}]
			c.SetNextState()
			generationSum[i] = '0'
			if c.Alive{
				generationSum[i] = '1'
			}
			i++
		}
	}

	sum := md5.Sum(generationSum)
	setSum(e.HashCache, sum)
	e.Dead = checkSums(e.HashCache)

	e.Generation++
}

func (p Pos) Neighbor(xDir, yDir int, b Bounds) Pos {
	x, y := p.X, p.Y

	if xDir > 1{
		xDir = 1
	}
	if xDir < -1{
		xDir = -1
	}
	if yDir > 1{
		yDir = 1
	}
	if yDir < -1{
		yDir = -1
	}

	x += xDir
	y += yDir

	if x > b.W{
		x = 1
	}
	if x < 1{
		x = b.W
	}
	if y > b.H{
		y = 1
	}
	if y < 1{
		y = b.H
	}

	return Pos{x,y}
}

func setSum(sums [][md5.Size]byte, newSum [md5.Size]byte){
	sums[0] = sums[1]
	sums[1] = sums[2]
	sums[2] = newSum
}

func checkSums(sums [][md5.Size]byte) bool {
	matches := 0

	if sums[0] == sums[1]{
		matches++
	}
	if sums[0] == sums[2] {
		matches++
	}
	if sums[1] == sums[2] {
		matches++
	}

	return matches >= 1
}<commit_msg>I guess we really don't need to involve crypto<commit_after>package life

import(
	"fmt"
	"bytes"
)

const(
	StateSame State = 0
	StateAlive = 1
	StateDead = -1
)

type State int

type Bounds struct {
	W, H int
}

type Pos struct {
	X, Y int
}

type Env struct {
	Dead bool
	Generation int64
	Bounds Bounds
	Cells map[Pos]*Cell
	HashCache []string
}

func NewEnv(bounds Bounds) *Env {
	env := &Env{
		Dead: false,
		Generation: 0,
		Bounds: bounds,
		Cells: make(map[Pos]*Cell),

		//initialize these so they don't match
		HashCache: []string{
			"hello",
			"goodbye",
			"asshole",
		},
	}

	for x := 1; x <= bounds.W; x++ {
		for y := 1; y <= bounds.H; y++ {
			p := Pos{x, y}
			c := &Cell{
				Pos: p,
				Alive: false,
				NextState: StateSame,
				Neighbors: make([]*Cell, 8),
			}
			env.Cells[p] = c
		}
	}

	for _, cell := range env.Cells {
		cell.init(env)
	}

	return env
}

func (e *Env) SetLivingCells(p ...Pos) {
	for _, pos := range p{
		if pos.X < 1 || pos.X > e.Bounds.W || pos.Y < 1 || pos.Y > e.Bounds.H {
			continue
		}
		e.Cells[pos].Alive = true
	}
}

func (e *Env) PrintLife() {
	var buf bytes.Buffer
	buf.WriteString(fmt.Sprintf("Generation: %d\n", e.Generation))
	for y := 1; y <= e.Bounds.H; y++ {
		for x := 1; x <= e.Bounds.W; x++ {
			if x == 1{
				buf.WriteByte(' ')
			}

			p := Pos{x, y}
			buf.WriteString(e.Cells[p].String())
			buf.WriteByte(' ')
		}
		buf.WriteByte('\n')
	}
	buf.WriteByte('\n')
	fmt.Print(buf.String())
}

func (e *Env) Next() {
	for _, c := range e.Cells{
		c.CalcNextState()
	}
	var buf bytes.Buffer
	for x := 1; x <= e.Bounds.W; x++{
		for y := 1; y <= e.Bounds.H; y++{
			c := e.Cells[Pos{x, y}]
			c.SetNextState()
			if c.Alive{
				buf.WriteByte('1')
			}else{
				buf.WriteByte('0')
			}
		}
	}

	setSum(e.HashCache, buf.String())
	e.Dead = checkSums(e.HashCache)

	e.Generation++
}

func (p Pos) Neighbor(xDir, yDir int, b Bounds) Pos {
	x, y := p.X, p.Y

	if xDir > 1{
		xDir = 1
	}
	if xDir < -1{
		xDir = -1
	}
	if yDir > 1{
		yDir = 1
	}
	if yDir < -1{
		yDir = -1
	}

	x += xDir
	y += yDir

	if x > b.W{
		x = 1
	}
	if x < 1{
		x = b.W
	}
	if y > b.H{
		y = 1
	}
	if y < 1{
		y = b.H
	}

	return Pos{x,y}
}

func setSum(sums []string, newSum string){
	sums[0] = sums[1]
	sums[1] = sums[2]
	sums[2] = newSum
}

func checkSums(sums []string) bool {
	matches := 0

	if sums[0] == sums[1]{
		matches++
	}
	if sums[0] == sums[2] {
		matches++
	}
	if sums[1] == sums[2] {
		matches++
	}

	return matches >= 1
}<|endoftext|>


<commit_before>package plaid

import (
	"encoding/json"
	"errors"
)

type Item struct {
	AvailableProducts []string `json:"available_products"`
	BilledProducts    []string `json:"billed_products"`
	Error             Error    `json:"error"`
	InstitutionID     string   `json:"institution_id"`
	ItemID            string   `json:"item_id"`
	Webhook           string   `json:"webhook"`
}

type getItemRequest struct {
	ClientID    string `json:"client_id"`
	Secret      string `json:"secret"`
	AccessToken string `json:"access_token"`
}

type GetItemResponse struct {
	APIResponse
	Item Item `json:"item"`
}

type removeItemRequest struct {
	ClientID    string `json:"client_id"`
	Secret      string `json:"secret"`
	AccessToken string `json:"access_token"`
}

type RemoveItemResponse struct {
	APIResponse
	Removed bool `json:"removed"`
}

type updateItemWebhookRequest struct {
	ClientID    string `json:"client_id"`
	Secret      string `json:"secret"`
	AccessToken string `json:"access_token"`
	Webhook     string `json:"webhook"`
}

type UpdateItemWebhookResponse struct {
	APIResponse
	Item Item `json:"item"`
}

type invalidateAccessTokenRequest struct {
	ClientID    string `json:"client_id"`
	Secret      string `json:"secret"`
	AccessToken string `json:"access_token"`
}

type InvalidateAccessTokenResponse struct {
	APIResponse
	NewAccessToken string `json:"new_access_token"`
}

type updateAccessTokenVersionRequest struct {
	ClientID    string `json:"client_id"`
	Secret      string `json:"secret"`
	AccessToken string `json:"access_token_v1"`
}

type UpdateAccessTokenVersionResponse struct {
	APIResponse
	NewAccessToken string `json:"access_token"`
	ItemID         string `json:"item_id"`
}

type createPublicTokenRequest struct {
	ClientID    string `json:"client_id"`
	Secret      string `json:"secret"`
	AccessToken string `json:"access_token"`
}

type CreatePublicTokenResponse struct {
	APIResponse
	PublicToken string `json:"public_token"`
}

type exchangePublicTokenRequest struct {
	ClientID    string `json:"client_id"`
	Secret      string `json:"secret"`
	PublicToken string `json:"public_token"`
}

type ExchangePublicTokenResponse struct {
	APIResponse
	AccessToken string `json:"access_token"`
	ItemID      string `json:"item_id"`
}

// GetItem retrieves an item associated with an access token.
// See https://plaid.com/docs/api/#retrieve-item.
func (c *Client) GetItem(accessToken string) (resp GetItemResponse, err error) {
	if accessToken == "" {
		return resp, errors.New("/item/get - access token must be specified")
	}

	jsonBody, err := json.Marshal(getItemRequest{
		ClientID:    c.clientID,
		Secret:      c.secret,
		AccessToken: accessToken,
	})

	if err != nil {
		return resp, err
	}

	err = c.Call("/item/get", jsonBody, &resp)
	return resp, err
}

// RemoveItem removes an item associated with an access token.
// See https://plaid.com/docs/api/#remove-an-item.
func (c *Client) RemoveItem(accessToken string) (resp RemoveItemResponse, err error) {
	if accessToken == "" {
		return resp, errors.New("/item/remove - access token must be specified")
	}

	jsonBody, err := json.Marshal(removeItemRequest{
		ClientID:    c.clientID,
		Secret:      c.secret,
		AccessToken: accessToken,
	})

	if err != nil {
		return resp, err
	}

	err = c.Call("/item/remove", jsonBody, &resp)
	return resp, err
}

// UpdateItemWebhook updates the webhook associated with an Item.
// See https://plaid.com/docs/api/#update-webhook.
func (c *Client) UpdateItemWebhook(accessToken, webhook string) (resp UpdateItemWebhookResponse, err error) {
	if accessToken == "" || webhook == "" {
		return resp, errors.New("/item/webhook/update - access token and webhook must be specified")
	}

	jsonBody, err := json.Marshal(updateItemWebhookRequest{
		ClientID:    c.clientID,
		Secret:      c.secret,
		AccessToken: accessToken,
		Webhook:     webhook,
	})

	if err != nil {
		return resp, err
	}

	err = c.Call("/item/webhook/update", jsonBody, &resp)
	return resp, err
}

// InvalidateAccessToken invalidates and rotates an access token.
// See https://plaid.com/docs/api/#rotate-access-token.
func (c *Client) InvalidateAccessToken(accessToken string) (resp InvalidateAccessTokenResponse, err error) {
	if accessToken == "" {
		return resp, errors.New("/item/access_token/invalidate - access token must be specified")
	}

	jsonBody, err := json.Marshal(invalidateAccessTokenRequest{
		ClientID:    c.clientID,
		Secret:      c.secret,
		AccessToken: accessToken,
	})

	if err != nil {
		return resp, err
	}

	err = c.Call("/item/access_token/invalidate", jsonBody, &resp)
	return resp, err
}

// UpdateAccessTokenVersion generates an updated access token associated with
// the legacy version of Plaid's API.
// See https://plaid.com/docs/api/#update-access-token-version.
func (c *Client) UpdateAccessTokenVersion(accessToken string) (resp UpdateAccessTokenVersionResponse, err error) {
	if accessToken == "" {
		return resp, errors.New("/item/access_token/update_version - access token must be specified")
	}

	jsonBody, err := json.Marshal(updateAccessTokenVersionRequest{
		ClientID:    c.clientID,
		Secret:      c.secret,
		AccessToken: accessToken,
	})

	if err != nil {
		return resp, err
	}

	err = c.Call("/item/access_token/update_version", jsonBody, &resp)
	return resp, err
}

// CreatePublicToken generates a one-time use public token which expires in
// 30 minutes to update an Item.
// See https://plaid.com/docs/api/#creating-public-tokens.
func (c *Client) CreatePublicToken(accessToken string) (resp CreatePublicTokenResponse, err error) {
	if accessToken == "" {
		return resp, errors.New("/item/public_token/create - access token must be specified")
	}

	jsonBody, err := json.Marshal(createPublicTokenRequest{
		ClientID:    c.clientID,
		Secret:      c.secret,
		AccessToken: accessToken,
	})

	if err != nil {
		return resp, err
	}

	err = c.Call("/item/public_token/create", jsonBody, &resp)
	return resp, err
}

// ExchangePublicToken exchanges a public token for an access token.
// See https://plaid.com/docs/api/#exchange-token-flow.
func (c *Client) ExchangePublicToken(publicToken string) (resp ExchangePublicTokenResponse, err error) {
	if publicToken == "" {
		return resp, errors.New("/item/public_token/exchange - public token must be specified")
	}

	jsonBody, err := json.Marshal(exchangePublicTokenRequest{
		ClientID:    c.clientID,
		Secret:      c.secret,
		PublicToken: publicToken,
	})

	if err != nil {
		return resp, err
	}

	err = c.Call("/item/public_token/exchange", jsonBody, &resp)
	return resp, err
}
<commit_msg>add support for the `status` object in /item/get (#92)<commit_after>package plaid

import (
	"encoding/json"
	"errors"
	"time"
)

type Item struct {
	AvailableProducts []string   `json:"available_products"`
	BilledProducts    []string   `json:"billed_products"`
	Error             Error      `json:"error"`
	InstitutionID     string     `json:"institution_id"`
	ItemID            string     `json:"item_id"`
	Webhook           string     `json:"webhook"`
	Status            ItemStatus `json:"status"`
}

type ItemStatus struct {
	Transactions ProductStatus `json:"transactions,omitempty"`
	Investments  ProductStatus `json:"investments,omitempty"`
	LastWebhook  WebhookStatus `json:"last_webhook,omitempty"`
}

type ProductStatus struct {
	LastFailedUpdate     time.Time `json:"last_failed_update,omitempty"`
	LastSuccessfulUpdate time.Time `json:"last_successful_update,omitempty"`
}

type WebhookStatus struct {
	SentAt   time.Time `json:"sent_at,omitempty"`
	CodeSent string    `json:"code_sent,omitempty"`
}

type getItemRequest struct {
	ClientID    string `json:"client_id"`
	Secret      string `json:"secret"`
	AccessToken string `json:"access_token"`
}

type GetItemResponse struct {
	APIResponse
	Item Item `json:"item"`
}

type removeItemRequest struct {
	ClientID    string `json:"client_id"`
	Secret      string `json:"secret"`
	AccessToken string `json:"access_token"`
}

type RemoveItemResponse struct {
	APIResponse
	Removed bool `json:"removed"`
}

type updateItemWebhookRequest struct {
	ClientID    string `json:"client_id"`
	Secret      string `json:"secret"`
	AccessToken string `json:"access_token"`
	Webhook     string `json:"webhook"`
}

type UpdateItemWebhookResponse struct {
	APIResponse
	Item Item `json:"item"`
}

type invalidateAccessTokenRequest struct {
	ClientID    string `json:"client_id"`
	Secret      string `json:"secret"`
	AccessToken string `json:"access_token"`
}

type InvalidateAccessTokenResponse struct {
	APIResponse
	NewAccessToken string `json:"new_access_token"`
}

type updateAccessTokenVersionRequest struct {
	ClientID    string `json:"client_id"`
	Secret      string `json:"secret"`
	AccessToken string `json:"access_token_v1"`
}

type UpdateAccessTokenVersionResponse struct {
	APIResponse
	NewAccessToken string `json:"access_token"`
	ItemID         string `json:"item_id"`
}

type createPublicTokenRequest struct {
	ClientID    string `json:"client_id"`
	Secret      string `json:"secret"`
	AccessToken string `json:"access_token"`
}

type CreatePublicTokenResponse struct {
	APIResponse
	PublicToken string `json:"public_token"`
}

type exchangePublicTokenRequest struct {
	ClientID    string `json:"client_id"`
	Secret      string `json:"secret"`
	PublicToken string `json:"public_token"`
}

type ExchangePublicTokenResponse struct {
	APIResponse
	AccessToken string `json:"access_token"`
	ItemID      string `json:"item_id"`
}

// GetItem retrieves an item associated with an access token.
// See https://plaid.com/docs/api/#retrieve-item.
func (c *Client) GetItem(accessToken string) (resp GetItemResponse, err error) {
	if accessToken == "" {
		return resp, errors.New("/item/get - access token must be specified")
	}

	jsonBody, err := json.Marshal(getItemRequest{
		ClientID:    c.clientID,
		Secret:      c.secret,
		AccessToken: accessToken,
	})

	if err != nil {
		return resp, err
	}

	err = c.Call("/item/get", jsonBody, &resp)
	return resp, err
}

// RemoveItem removes an item associated with an access token.
// See https://plaid.com/docs/api/#remove-an-item.
func (c *Client) RemoveItem(accessToken string) (resp RemoveItemResponse, err error) {
	if accessToken == "" {
		return resp, errors.New("/item/remove - access token must be specified")
	}

	jsonBody, err := json.Marshal(removeItemRequest{
		ClientID:    c.clientID,
		Secret:      c.secret,
		AccessToken: accessToken,
	})

	if err != nil {
		return resp, err
	}

	err = c.Call("/item/remove", jsonBody, &resp)
	return resp, err
}

// UpdateItemWebhook updates the webhook associated with an Item.
// See https://plaid.com/docs/api/#update-webhook.
func (c *Client) UpdateItemWebhook(accessToken, webhook string) (resp UpdateItemWebhookResponse, err error) {
	if accessToken == "" || webhook == "" {
		return resp, errors.New("/item/webhook/update - access token and webhook must be specified")
	}

	jsonBody, err := json.Marshal(updateItemWebhookRequest{
		ClientID:    c.clientID,
		Secret:      c.secret,
		AccessToken: accessToken,
		Webhook:     webhook,
	})

	if err != nil {
		return resp, err
	}

	err = c.Call("/item/webhook/update", jsonBody, &resp)
	return resp, err
}

// InvalidateAccessToken invalidates and rotates an access token.
// See https://plaid.com/docs/api/#rotate-access-token.
func (c *Client) InvalidateAccessToken(accessToken string) (resp InvalidateAccessTokenResponse, err error) {
	if accessToken == "" {
		return resp, errors.New("/item/access_token/invalidate - access token must be specified")
	}

	jsonBody, err := json.Marshal(invalidateAccessTokenRequest{
		ClientID:    c.clientID,
		Secret:      c.secret,
		AccessToken: accessToken,
	})

	if err != nil {
		return resp, err
	}

	err = c.Call("/item/access_token/invalidate", jsonBody, &resp)
	return resp, err
}

// UpdateAccessTokenVersion generates an updated access token associated with
// the legacy version of Plaid's API.
// See https://plaid.com/docs/api/#update-access-token-version.
func (c *Client) UpdateAccessTokenVersion(accessToken string) (resp UpdateAccessTokenVersionResponse, err error) {
	if accessToken == "" {
		return resp, errors.New("/item/access_token/update_version - access token must be specified")
	}

	jsonBody, err := json.Marshal(updateAccessTokenVersionRequest{
		ClientID:    c.clientID,
		Secret:      c.secret,
		AccessToken: accessToken,
	})

	if err != nil {
		return resp, err
	}

	err = c.Call("/item/access_token/update_version", jsonBody, &resp)
	return resp, err
}

// CreatePublicToken generates a one-time use public token which expires in
// 30 minutes to update an Item.
// See https://plaid.com/docs/api/#creating-public-tokens.
func (c *Client) CreatePublicToken(accessToken string) (resp CreatePublicTokenResponse, err error) {
	if accessToken == "" {
		return resp, errors.New("/item/public_token/create - access token must be specified")
	}

	jsonBody, err := json.Marshal(createPublicTokenRequest{
		ClientID:    c.clientID,
		Secret:      c.secret,
		AccessToken: accessToken,
	})

	if err != nil {
		return resp, err
	}

	err = c.Call("/item/public_token/create", jsonBody, &resp)
	return resp, err
}

// ExchangePublicToken exchanges a public token for an access token.
// See https://plaid.com/docs/api/#exchange-token-flow.
func (c *Client) ExchangePublicToken(publicToken string) (resp ExchangePublicTokenResponse, err error) {
	if publicToken == "" {
		return resp, errors.New("/item/public_token/exchange - public token must be specified")
	}

	jsonBody, err := json.Marshal(exchangePublicTokenRequest{
		ClientID:    c.clientID,
		Secret:      c.secret,
		PublicToken: publicToken,
	})

	if err != nil {
		return resp, err
	}

	err = c.Call("/item/public_token/exchange", jsonBody, &resp)
	return resp, err
}
<|endoftext|>


<commit_before>package treerack

import (
	"bytes"
	"reflect"
	"testing"
)

func checkParseError(left, right ParseError) bool {
	left.registry = nil
	right.registry = nil
	return reflect.DeepEqual(left, right)
}

func TestError(t *testing.T) {
	type testItem struct {
		title  string
		syntax string
		text   string
		perr   ParseError
	}

	for _, test := range []testItem{{
		title:  "single def, empty text",
		syntax: `a = "a"`,
		perr: ParseError{
			Definition: "a",
		},
	}, {
		title:  "single def, wrong text",
		syntax: `a = "a"`,
		text:   "b",
		perr: ParseError{
			Definition: "a",
		},
	}, {
		title:  "single optional def, wrong text",
		syntax: `a = "a"?`,
		text:   "b",
		perr: ParseError{
			Definition: "a",
		},
	}, {
		title:  "error on second line, second column",
		syntax: `a = [a\n]*`,
		text:   "aa\nabaa\naa",
		perr: ParseError{
			Offset:     4,
			Line:       1,
			Column:     1,
			Definition: "a",
		},
	}, {
		title:  "multiple definitions",
		syntax: `a = "aa"; A:root = a`,
		text:   "ab",
		perr: ParseError{
			Offset:     1,
			Column:     1,
			Definition: "a",
		},
	}, {
		title:  "choice, options succeed",
		syntax: `a = "12"; b = "1"; c:root = a | b`,
		text:   "123",
		perr: ParseError{
			Offset:     2,
			Column:     2,
			Definition: "c",
		},
	}, {
		title:  "choice succeeds, document fails",
		syntax: `a = "12"; b = "1"; c:root = a | b`,
		text:   "13",
		perr: ParseError{
			Offset:     1,
			Column:     1,
			Definition: "c",
		},
	}, {
		title:  "choice fails",
		syntax: `a = "12"; b = "2"; c:root = a | b`,
		text:   "13",
		perr: ParseError{
			Offset:     1,
			Column:     1,
			Definition: "a",
		},
	}, {
		title:  "choice fails, longer option reported",
		syntax: `a = "12"; b = "134"; c:root = a | b`,
		text:   "135",
		perr: ParseError{
			Offset:     2,
			Column:     2,
			Definition: "b",
		},
	}, {
		title:  "failing choice on the failing branch",
		syntax: `a = "123"; b:root = a | "13"`,
		text:   "124",
		perr: ParseError{
			Offset:     2,
			Column:     2,
			Definition: "a",
		},
	}, {
		title:  "failing choice on a shorter branch",
		syntax: `a = "13"; b:root = "123" | a`,
		text:   "124",
		perr: ParseError{
			Offset:     2,
			Column:     2,
			Definition: "b",
		},
	}, {
		title:  "longer failure on a later pass",
		syntax: `a = "12"; b = "34"; c = "1" b; d:root = a | c`,
		text:   "135",
		perr: ParseError{
			Offset:     2,
			Column:     2,
			Definition: "b",
		},
	}, {
		title:  "char as a choice option",
		syntax: `a = "12"; b = [a] | [b]; c = a b`,
		text:   "12c",
		perr: ParseError{
			Offset:     2,
			Column:     2,
			Definition: "b",
		},
	}} {
		t.Run(test.title, func(t *testing.T) {
			s, err := openSyntaxString(test.syntax)
			if err != nil {
				t.Error(err)
				return
			}

			_, err = s.Parse(bytes.NewBufferString(test.text))
			if err == nil {
				t.Error("failed to fail")
				return
			}

			perr, ok := err.(*ParseError)
			if !ok {
				t.Error("invalid error returned", err)
				return
			}

			if perr.Input != "<input>" {
				t.Error("invalid default input name")
				return
			}

			perr.Input = ""
			if !checkParseError(*perr, test.perr) {
				t.Error("failed to return the right error")
			}
		})
	}
}

func TestErrorRecursive(t *testing.T) {
	const syntax = `
		ws:ws = " ";
		symbol = [a-z]+;
		function-application = expression "(" expression? ")";
		expression = function-application | symbol;
		doc:root = (expression (";" expression)*)+;
	`

	s, err := openSyntaxString(syntax)
	if err != nil {
		t.Fatal(err)
	}

	for _, test := range []struct {
		title string
		doc   string
		perr  ParseError
	}{{
		title: "simple, open",
		doc:   "a(",
		perr: ParseError{
			Offset:     1,
			Column:     1,
			Definition: "function-application",
		},
	}, {
		title: "simple, close",
		doc:   "a)",
		perr: ParseError{
			Offset:     1,
			Column:     1,
			Definition: "function-application",
		},
	}, {
		title: "inner, open",
		doc:   "a(b()",
		perr: ParseError{
			Offset:     1,
			Column:     1,
			Definition: "function-application",
		},
	}, {
		title: "inner, close",
		doc:   "a(b))",
		perr: ParseError{
			Offset:     4,
			Column:     4,
			Definition: "function-application",
		},
	}, {
		title: "outer, open",
		doc:   "a()b(",
		perr: ParseError{
			Offset:     4,
			Column:     4,
			Definition: "function-application",
		},
	}, {
		title: "outer, close",
		doc:   "a()b)",
		perr: ParseError{
			Offset:     4,
			Column:     4,
			Definition: "function-application",
		},
	}} {
		t.Run(test.title, func(t *testing.T) {
			_, err := s.Parse(bytes.NewBufferString(test.doc))
			if err == nil {
				t.Fatal("failed to fail")
			}

			perr, ok := err.(*ParseError)
			if !ok {
				t.Fatal("invalid error type")
			}

			perr.Input = ""

			if !checkParseError(*perr, test.perr) {
				t.Error("failed to return the right error")
				t.Log("got:     ", *perr)
				t.Log("expected:", test.perr)
			}
		})
	}
}

func TestErrorMessage(t *testing.T) {
	const expected = "foo:4:10:parse failed, parsing: bar"

	perr := &ParseError{
		Input:      "foo",
		Offset:     42,
		Line:       3,
		Column:     9,
		Definition: "bar",
	}

	message := perr.Error()
	if message != expected {
		t.Error("failed to return the right error message")
		t.Log("got:     ", message)
		t.Log("expected:", expected)
	}
}

func TestErrorVerbose(t *testing.T) {
	const expected = `
`

	const doc = `{
		"a":1,
		"b":2,
		"c":3,
	}`

	s, err := openSyntaxFile("examples/json.treerack")
	if err != nil {
		t.Error(err)
		return
	}

	_, err = s.Parse(bytes.NewBufferString(doc))
	perr, ok := err.(*ParseError)
	if !ok {
		t.Error("failed to return parse error")
		return
	}

	t.Log(perr.Error())
}
<commit_msg>test verbose error message<commit_after>package treerack

import (
	"bytes"
	"reflect"
	"testing"
)

func checkParseError(left, right ParseError) bool {
	left.registry = nil
	right.registry = nil
	return reflect.DeepEqual(left, right)
}

func TestError(t *testing.T) {
	type testItem struct {
		title  string
		syntax string
		text   string
		perr   ParseError
	}

	for _, test := range []testItem{{
		title:  "single def, empty text",
		syntax: `a = "a"`,
		perr: ParseError{
			Definition: "a",
		},
	}, {
		title:  "single def, wrong text",
		syntax: `a = "a"`,
		text:   "b",
		perr: ParseError{
			Definition: "a",
		},
	}, {
		title:  "single optional def, wrong text",
		syntax: `a = "a"?`,
		text:   "b",
		perr: ParseError{
			Definition: "a",
		},
	}, {
		title:  "error on second line, second column",
		syntax: `a = [a\n]*`,
		text:   "aa\nabaa\naa",
		perr: ParseError{
			Offset:     4,
			Line:       1,
			Column:     1,
			Definition: "a",
		},
	}, {
		title:  "multiple definitions",
		syntax: `a = "aa"; A:root = a`,
		text:   "ab",
		perr: ParseError{
			Offset:     1,
			Column:     1,
			Definition: "a",
		},
	}, {
		title:  "choice, options succeed",
		syntax: `a = "12"; b = "1"; c:root = a | b`,
		text:   "123",
		perr: ParseError{
			Offset:     2,
			Column:     2,
			Definition: "c",
		},
	}, {
		title:  "choice succeeds, document fails",
		syntax: `a = "12"; b = "1"; c:root = a | b`,
		text:   "13",
		perr: ParseError{
			Offset:     1,
			Column:     1,
			Definition: "c",
		},
	}, {
		title:  "choice fails",
		syntax: `a = "12"; b = "2"; c:root = a | b`,
		text:   "13",
		perr: ParseError{
			Offset:     1,
			Column:     1,
			Definition: "a",
		},
	}, {
		title:  "choice fails, longer option reported",
		syntax: `a = "12"; b = "134"; c:root = a | b`,
		text:   "135",
		perr: ParseError{
			Offset:     2,
			Column:     2,
			Definition: "b",
		},
	}, {
		title:  "failing choice on the failing branch",
		syntax: `a = "123"; b:root = a | "13"`,
		text:   "124",
		perr: ParseError{
			Offset:     2,
			Column:     2,
			Definition: "a",
		},
	}, {
		title:  "failing choice on a shorter branch",
		syntax: `a = "13"; b:root = "123" | a`,
		text:   "124",
		perr: ParseError{
			Offset:     2,
			Column:     2,
			Definition: "b",
		},
	}, {
		title:  "longer failure on a later pass",
		syntax: `a = "12"; b = "34"; c = "1" b; d:root = a | c`,
		text:   "135",
		perr: ParseError{
			Offset:     2,
			Column:     2,
			Definition: "b",
		},
	}, {
		title:  "char as a choice option",
		syntax: `a = "12"; b = [a] | [b]; c = a b`,
		text:   "12c",
		perr: ParseError{
			Offset:     2,
			Column:     2,
			Definition: "b",
		},
	}} {
		t.Run(test.title, func(t *testing.T) {
			s, err := openSyntaxString(test.syntax)
			if err != nil {
				t.Error(err)
				return
			}

			_, err = s.Parse(bytes.NewBufferString(test.text))
			if err == nil {
				t.Error("failed to fail")
				return
			}

			perr, ok := err.(*ParseError)
			if !ok {
				t.Error("invalid error returned", err)
				return
			}

			if perr.Input != "<input>" {
				t.Error("invalid default input name")
				return
			}

			perr.Input = ""
			if !checkParseError(*perr, test.perr) {
				t.Error("failed to return the right error")
			}
		})
	}
}

func TestErrorRecursive(t *testing.T) {
	const syntax = `
		ws:ws = " ";
		symbol = [a-z]+;
		function-application = expression "(" expression? ")";
		expression = function-application | symbol;
		doc:root = (expression (";" expression)*)+;
	`

	s, err := openSyntaxString(syntax)
	if err != nil {
		t.Fatal(err)
	}

	for _, test := range []struct {
		title string
		doc   string
		perr  ParseError
	}{{
		title: "simple, open",
		doc:   "a(",
		perr: ParseError{
			Offset:     1,
			Column:     1,
			Definition: "function-application",
		},
	}, {
		title: "simple, close",
		doc:   "a)",
		perr: ParseError{
			Offset:     1,
			Column:     1,
			Definition: "function-application",
		},
	}, {
		title: "inner, open",
		doc:   "a(b()",
		perr: ParseError{
			Offset:     1,
			Column:     1,
			Definition: "function-application",
		},
	}, {
		title: "inner, close",
		doc:   "a(b))",
		perr: ParseError{
			Offset:     4,
			Column:     4,
			Definition: "function-application",
		},
	}, {
		title: "outer, open",
		doc:   "a()b(",
		perr: ParseError{
			Offset:     4,
			Column:     4,
			Definition: "function-application",
		},
	}, {
		title: "outer, close",
		doc:   "a()b)",
		perr: ParseError{
			Offset:     4,
			Column:     4,
			Definition: "function-application",
		},
	}} {
		t.Run(test.title, func(t *testing.T) {
			_, err := s.Parse(bytes.NewBufferString(test.doc))
			if err == nil {
				t.Fatal("failed to fail")
			}

			perr, ok := err.(*ParseError)
			if !ok {
				t.Fatal("invalid error type")
			}

			perr.Input = ""

			if !checkParseError(*perr, test.perr) {
				t.Error("failed to return the right error")
				t.Log("got:     ", *perr)
				t.Log("expected:", test.perr)
			}
		})
	}
}

func TestErrorMessage(t *testing.T) {
	const expected = "foo:4:10:parse failed, parsing: bar"

	perr := &ParseError{
		Input:      "foo",
		Offset:     42,
		Line:       3,
		Column:     9,
		Definition: "bar",
	}

	message := perr.Error()
	if message != expected {
		t.Error("failed to return the right error message")
		t.Log("got:     ", message)
		t.Log("expected:", expected)
	}
}

func TestErrorVerbose(t *testing.T) {
	const expected = `<input>:5:2:parse failed, parsing: string`

	const doc = `{
		"a":1,
		"b":2,
		"c":3,
	}`

	s, err := openSyntaxFile("examples/json.treerack")
	if err != nil {
		t.Error(err)
		return
	}

	_, err = s.Parse(bytes.NewBufferString(doc))
	perr, ok := err.(*ParseError)
	if !ok {
		t.Error("failed to return parse error")
		return
	}

	if perr.Error() != expected {
		t.Error("failed to get the right error message")
		t.Log("got:     ", perr.Error())
		t.Log("expected:", expected)
	}
}
<|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.

// +build appengine

package build

// TODO(adg): test authentication

import (
	"appengine"
	"appengine/datastore"
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"
	"net/url"
	"strings"
	"time"
)

func init() {
	http.HandleFunc("/buildtest", testHandler)
}

var testEntityKinds = []string{
	"Package",
	"Commit",
	"Result",
	"Log",
}

const testPkg = "code.google.com/p/go.test"

var testPackage = &Package{Name: "Test", Kind: "subrepo", Path: testPkg}

var testPackages = []*Package{
	{Name: "Go", Path: ""},
	testPackage,
}

var tCommitTime = time.Now().Add(-time.Hour * 24 * 7)

func tCommit(hash, parentHash, path string) *Commit {
	tCommitTime.Add(time.Hour) // each commit should have a different time
	return &Commit{
		PackagePath: path,
		Hash:        hash,
		ParentHash:  parentHash,
		Time:        tCommitTime,
		User:        "adg",
		Desc:        "change description " + hash,
	}
}

var testRequests = []struct {
	path string
	vals url.Values
	req  interface{}
	res  interface{}
}{
	// Packages
	{"/packages?kind=subrepo", nil, nil, []*Package{testPackage}},

	// Go repo
	{"/commit", nil, tCommit("0001", "0000", ""), nil},
	{"/commit", nil, tCommit("0002", "0001", ""), nil},
	{"/commit", nil, tCommit("0003", "0002", ""), nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-amd64"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0001", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0002", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},

	// multiple builders
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-amd64"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/result", nil, &Result{Builder: "linux-amd64", Hash: "0003", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-amd64"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0002"}}},

	// branches
	{"/commit", nil, tCommit("0004", "0003", ""), nil},
	{"/commit", nil, tCommit("0005", "0002", ""), nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0005"}}},
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0005", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0004"}}},
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0004", OK: false}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},

	// logs
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0003", OK: false, Log: "test"}, nil},
	{"/log/a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", nil, nil, "test"},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, nil},

	// repeat failure (shouldn't re-send mail)
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0003", OK: false, Log: "test"}, nil},

	// non-Go repos
	{"/commit", nil, tCommit("1001", "1000", testPkg), nil},
	{"/commit", nil, tCommit("1002", "1001", testPkg), nil},
	{"/commit", nil, tCommit("1003", "1002", testPkg), nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1003"}}},
	{"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1003", GoHash: "0001", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1002"}}},
	{"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1002", GoHash: "0001", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1001"}}},
	{"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1001", GoHash: "0001", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0002"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1003"}}},

	// re-build Go revision for stale subrepos
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0005"}}},
	{"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1001", GoHash: "0005", OK: false, Log: "boo"}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, nil},
}

func testHandler(w http.ResponseWriter, r *http.Request) {
	if !appengine.IsDevAppServer() {
		fmt.Fprint(w, "These tests must be run under the dev_appserver.")
		return
	}
	c := appengine.NewContext(r)
	if err := nukeEntities(c, testEntityKinds); err != nil {
		logErr(w, r, err)
		return
	}
	if r.FormValue("nukeonly") != "" {
		fmt.Fprint(w, "OK")
		return
	}

	for _, p := range testPackages {
		if _, err := datastore.Put(c, p.Key(c), p); err != nil {
			logErr(w, r, err)
			return
		}
	}

	for i, t := range testRequests {
		c.Infof("running test %d %s", i, t.path)
		errorf := func(format string, args ...interface{}) {
			fmt.Fprintf(w, "%d %s: ", i, t.path)
			fmt.Fprintf(w, format, args...)
			fmt.Fprintln(w)
		}
		var body io.ReadWriter
		if t.req != nil {
			body = new(bytes.Buffer)
			json.NewEncoder(body).Encode(t.req)
		}
		url := "http://" + domain + t.path
		if t.vals != nil {
			url += "?" + t.vals.Encode()
		}
		req, err := http.NewRequest("POST", url, body)
		if err != nil {
			logErr(w, r, err)
			return
		}
		if t.req != nil {
			req.Method = "POST"
		}
		req.Header = r.Header
		rec := httptest.NewRecorder()

		// Make the request
		http.DefaultServeMux.ServeHTTP(rec, req)

		if rec.Code != 0 && rec.Code != 200 {
			errorf(rec.Body.String())
			return
		}
		resp := new(dashResponse)

		// If we're expecting a *Todo value,
		// prime the Response field with a Todo and a Commit inside it.
		if _, ok := t.res.(*Todo); ok {
			resp.Response = &Todo{Data: &Commit{}}
		}

		if strings.HasPrefix(t.path, "/log/") {
			resp.Response = rec.Body.String()
		} else {
			err := json.NewDecoder(rec.Body).Decode(resp)
			if err != nil {
				errorf("decoding response: %v", err)
				return
			}
		}
		if e, ok := t.res.(string); ok {
			g, ok := resp.Response.(string)
			if !ok {
				errorf("Response not string: %T", resp.Response)
				return
			}
			if g != e {
				errorf("response mismatch: got %q want %q", g, e)
				return
			}
		}
		if e, ok := t.res.(*Todo); ok {
			g, ok := resp.Response.(*Todo)
			if !ok {
				errorf("Response not *Todo: %T", resp.Response)
				return
			}
			if e.Data == nil && g.Data != nil {
				errorf("Response.Data should be nil, got: %v", g.Data)
				return
			}
			if g.Data == nil {
				errorf("Response.Data is nil, want: %v", e.Data)
				return
			}
			gd, ok := g.Data.(*Commit)
			if !ok {
				errorf("Response.Data not *Commit: %T", g.Data)
				return
			}
			if eh := e.Data.(*Commit).Hash; eh != gd.Hash {
				errorf("hashes don't match: got %q, want %q", gd.Hash, eh)
				return
			}
		}
		if t.res == nil && resp.Response != nil {
			errorf("response mismatch: got %q expected <nil>",
				resp.Response)
			return
		}
	}
	fmt.Fprint(w, "PASS\nYou should see only one mail notification (for 0003/linux-386) in the dev_appserver logs.")
}

func nukeEntities(c appengine.Context, kinds []string) error {
	if !appengine.IsDevAppServer() {
		return errors.New("can't nuke production data")
	}
	var keys []*datastore.Key
	for _, kind := range kinds {
		q := datastore.NewQuery(kind).KeysOnly()
		for t := q.Run(c); ; {
			k, err := t.Next(nil)
			if err == datastore.Done {
				break
			}
			if err != nil {
				return err
			}
			keys = append(keys, k)
		}
	}
	return datastore.DeleteMulti(c, keys)
}
<commit_msg>go.tools/dashboard/app: fix tests and add TODO to reall fix them<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.

// +build appengine

package build

// TODO(adg): test authentication
// TODO(adg): refactor to use appengine/aetest instead

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"
	"net/url"
	"strings"
	"time"

	"appengine"
	"appengine/datastore"
)

func init() {
	http.HandleFunc("/buildtest", testHandler)
}

var testEntityKinds = []string{
	"Package",
	"Commit",
	"Result",
	"Log",
}

const testPkg = "code.google.com/p/go.test"

var testPackage = &Package{Name: "Test", Kind: "subrepo", Path: testPkg}

var testPackages = []*Package{
	{Name: "Go", Path: ""},
	testPackage,
}

var tCommitTime = time.Now().Add(-time.Hour * 24 * 7)

func tCommit(hash, parentHash, path string) *Commit {
	tCommitTime.Add(time.Hour) // each commit should have a different time
	return &Commit{
		PackagePath: path,
		Hash:        hash,
		ParentHash:  parentHash,
		Time:        tCommitTime,
		User:        "adg",
		Desc:        "change description " + hash,
	}
}

var testRequests = []struct {
	path string
	vals url.Values
	req  interface{}
	res  interface{}
}{
	// Packages
	{"/packages?kind=subrepo", nil, nil, []*Package{testPackage}},

	// Go repo
	{"/commit", nil, tCommit("0001", "0000", ""), nil},
	{"/commit", nil, tCommit("0002", "0001", ""), nil},
	{"/commit", nil, tCommit("0003", "0002", ""), nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-amd64"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0001", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0002", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},

	// multiple builders
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-amd64"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/result", nil, &Result{Builder: "linux-amd64", Hash: "0003", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-amd64"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0002"}}},

	// branches
	{"/commit", nil, tCommit("0004", "0003", ""), nil},
	{"/commit", nil, tCommit("0005", "0002", ""), nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0005"}}},
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0005", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0004"}}},
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0004", OK: false}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},

	// logs
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0003", OK: false, Log: "test"}, nil},
	{"/log/a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", nil, nil, "test"},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, nil},

	// repeat failure (shouldn't re-send mail)
	{"/result", nil, &Result{Builder: "linux-386", Hash: "0003", OK: false, Log: "test"}, nil},

	// non-Go repos
	{"/commit", nil, tCommit("1001", "1000", testPkg), nil},
	{"/commit", nil, tCommit("1002", "1001", testPkg), nil},
	{"/commit", nil, tCommit("1003", "1002", testPkg), nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1003"}}},
	{"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1003", GoHash: "0001", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1002"}}},
	{"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1002", GoHash: "0001", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1001"}}},
	{"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1001", GoHash: "0001", OK: true}, nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, nil},
	{"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0002"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1003"}}},

	// re-build Go revision for stale subrepos
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0005"}}},
	{"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1001", GoHash: "0005", OK: false, Log: "boo"}, nil},
	{"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, nil},
}

func testHandler(w http.ResponseWriter, r *http.Request) {
	if !appengine.IsDevAppServer() {
		fmt.Fprint(w, "These tests must be run under the dev_appserver.")
		return
	}
	c := appengine.NewContext(r)
	if err := nukeEntities(c, testEntityKinds); err != nil {
		logErr(w, r, err)
		return
	}
	if r.FormValue("nukeonly") != "" {
		fmt.Fprint(w, "OK")
		return
	}

	for _, p := range testPackages {
		if _, err := datastore.Put(c, p.Key(c), p); err != nil {
			logErr(w, r, err)
			return
		}
	}

	origReq := *r
	defer func() {
		// HACK: We need to clobber the original request (see below)
		// so make sure we fix it before exiting the handler.
		*r = origReq
	}()
	for i, t := range testRequests {
		c.Infof("running test %d %s", i, t.path)
		errorf := func(format string, args ...interface{}) {
			fmt.Fprintf(w, "%d %s: ", i, t.path)
			fmt.Fprintf(w, format, args...)
			fmt.Fprintln(w)
		}
		var body io.ReadWriter
		if t.req != nil {
			body = new(bytes.Buffer)
			json.NewEncoder(body).Encode(t.req)
		}
		url := "http://" + domain + t.path
		if t.vals != nil {
			url += "?" + t.vals.Encode()
		}
		req, err := http.NewRequest("POST", url, body)
		if err != nil {
			logErr(w, r, err)
			return
		}
		if t.req != nil {
			req.Method = "POST"
		}
		req.Header = origReq.Header
		rec := httptest.NewRecorder()

		// Make the request
		*r = *req // HACK: App Engine uses the request pointer
		// as a map key to resolve Contexts.
		http.DefaultServeMux.ServeHTTP(rec, r)

		if rec.Code != 0 && rec.Code != 200 {
			errorf(rec.Body.String())
			return
		}
		resp := new(dashResponse)

		// If we're expecting a *Todo value,
		// prime the Response field with a Todo and a Commit inside it.
		if _, ok := t.res.(*Todo); ok {
			resp.Response = &Todo{Data: &Commit{}}
		}

		if strings.HasPrefix(t.path, "/log/") {
			resp.Response = rec.Body.String()
		} else {
			err := json.NewDecoder(rec.Body).Decode(resp)
			if err != nil {
				errorf("decoding response: %v", err)
				return
			}
		}
		if e, ok := t.res.(string); ok {
			g, ok := resp.Response.(string)
			if !ok {
				errorf("Response not string: %T", resp.Response)
				return
			}
			if g != e {
				errorf("response mismatch: got %q want %q", g, e)
				return
			}
		}
		if e, ok := t.res.(*Todo); ok {
			g, ok := resp.Response.(*Todo)
			if !ok {
				errorf("Response not *Todo: %T", resp.Response)
				return
			}
			if e.Data == nil && g.Data != nil {
				errorf("Response.Data should be nil, got: %v", g.Data)
				return
			}
			if g.Data == nil {
				errorf("Response.Data is nil, want: %v", e.Data)
				return
			}
			gd, ok := g.Data.(*Commit)
			if !ok {
				errorf("Response.Data not *Commit: %T", g.Data)
				return
			}
			if eh := e.Data.(*Commit).Hash; eh != gd.Hash {
				errorf("hashes don't match: got %q, want %q", gd.Hash, eh)
				return
			}
		}
		if t.res == nil && resp.Response != nil {
			errorf("response mismatch: got %q expected <nil>",
				resp.Response)
			return
		}
	}
	fmt.Fprint(w, "PASS\nYou should see only one mail notification (for 0003/linux-386) in the dev_appserver logs.")
}

func nukeEntities(c appengine.Context, kinds []string) error {
	if !appengine.IsDevAppServer() {
		return errors.New("can't nuke production data")
	}
	var keys []*datastore.Key
	for _, kind := range kinds {
		q := datastore.NewQuery(kind).KeysOnly()
		for t := q.Run(c); ; {
			k, err := t.Next(nil)
			if err == datastore.Done {
				break
			}
			if err != nil {
				return err
			}
			keys = append(keys, k)
		}
	}
	return datastore.DeleteMulti(c, keys)
}
<|endoftext|>


<commit_before>/*
Copyright 2019 The Jetstack cert-manager contributors.

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 helper

import (
	"fmt"
	"time"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/wait"

	"github.com/jetstack/cert-manager/test/e2e/framework/log"
)

// WaitForSecretCertificateData waits for the certificate data to be ready
// inside a Secret created by cert-manager.
func (h *Helper) WaitForSecretCertificateData(ns, name string, timeout time.Duration) (*corev1.Secret, error) {
	var secret *corev1.Secret
	err := wait.PollImmediate(time.Second, timeout,
		func() (bool, error) {
			var err error
			log.Logf("Waiting for Secret %s:%s to contain a certificate", ns, name)
			secret, err = h.KubeClient.CoreV1().Secrets(ns).Get(name, metav1.GetOptions{})
			if err != nil {
				return false, fmt.Errorf("error getting secret %s: %s", name, err)
			}

			if len(secret.Data[corev1.TLSCertKey]) > 0 {
				return true, nil
			}

			log.Logf("Secret still does not contain certificate data %s/%s: %v",
				secret.Namespace, secret.Name, secret.Data)
			return false, nil
		},
	)

	if err != nil {
		return nil, err
	}

	return secret, nil
}
<commit_msg>e2e: remove noisy log message<commit_after>/*
Copyright 2019 The Jetstack cert-manager contributors.

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 helper

import (
	"fmt"
	"time"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/wait"

	"github.com/jetstack/cert-manager/test/e2e/framework/log"
)

// WaitForSecretCertificateData waits for the certificate data to be ready
// inside a Secret created by cert-manager.
func (h *Helper) WaitForSecretCertificateData(ns, name string, timeout time.Duration) (*corev1.Secret, error) {
	var secret *corev1.Secret
	err := wait.PollImmediate(time.Second, timeout,
		func() (bool, error) {
			var err error
			log.Logf("Waiting for Secret %s:%s to contain a certificate", ns, name)
			secret, err = h.KubeClient.CoreV1().Secrets(ns).Get(name, metav1.GetOptions{})
			if err != nil {
				return false, fmt.Errorf("error getting secret %s: %s", name, err)
			}

			if len(secret.Data[corev1.TLSCertKey]) > 0 {
				return true, nil
			}

			log.Logf("Secret still does not contain certificate data %s/%s",
				secret.Namespace, secret.Name)
			return false, nil
		},
	)

	if err != nil {
		return nil, err
	}

	return secret, nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Niklas Wolber
// This file is licensed under the MIT license.
// See the LICENSE file for more information.

package job

import (
	"context"
	"fmt"
	"io"
	"log"
	"net"
	"os"

	"golang.org/x/crypto/ssh"
)

// forwardRemote instructs the connect SSH server to forward all connections attempts
// on remoteAddr to the local client. The client will then establish a connection
// to localAddr and forward any payload exchanged.
//
// Allocated resources will be released, when the context completes.
func forwardRemote(ctx context.Context, client *ssh.Client, remoteAddr string, localAddr string) {
	l, ok := ctx.Value(loggerKey).(Logger)
	if !ok || l == nil {
		l = log.New(os.Stderr, "", log.LstdFlags)
	}

	listener, err := client.Listen("tcp", remoteAddr)
	if err != nil {
		err = fmt.Errorf("unable to listen to %s on remote host %s: %s", remoteAddr, client.RemoteAddr(), err)
		l.Println(err)
		return
	}

	go runTunnel(ctx, listener, net.Dial, localAddr)
}

// forwardLocal forwards all connection attempts on localAddr to the remote host client
// connects to. The remote host will then establish a connection remoteAddr.
//
// Allocated resources will be released, when the context completes.
func forwardLocal(ctx context.Context, client *ssh.Client, remoteAddr string, localAddr string) {
	l, ok := ctx.Value(loggerKey).(Logger)
	if !ok || l == nil {
		l = log.New(os.Stderr, "", log.LstdFlags)
	}

	listener, err := net.Listen("tcp", localAddr)
	if err != nil {
		err = fmt.Errorf("unable to listen to %s: %s", localAddr, err)
		l.Println(err)
		return
	}

	go runTunnel(ctx, listener, client.Dial, remoteAddr)
}

type dial func(network, address string) (net.Conn, error)

func runTunnel(ctx context.Context, listener net.Listener, d dial, addr string) {
	l, ok := ctx.Value(loggerKey).(Logger)
	if !ok || l == nil {
		l = log.New(os.Stderr, "", log.LstdFlags)
	}

	acceptChan := accept(ctx, listener)

	for {
		select {
		case remoteConn, ok := <-acceptChan:
			if !ok {
				l.Println("accept channel closed")
				return
			}

			if remoteConn.error != nil {
				l.Println("error accepting tunnel connection", remoteConn.error)
				return
			}

			go func(conn net.Conn) {
				defer conn.Close()
				l.Println("accepted tunnel connection")

				localConn, err := d("tcp", addr)
				if err != nil {
					l.Println("unable to connect to endpoint", addr, err)
					return
				}
				l.Println("connected to endpoint")

				go copyConn(localConn, conn)
				copyConn(conn, localConn)
				l.Println("tunnel connection closed")
			}(remoteConn)

		case <-ctx.Done():
			l.Println("closing tunnel")
			return
		}
	}
}

func copyConn(writer io.Writer, reader io.Reader) {
	_, err := io.Copy(writer, reader)
	if err != nil {
		log.Println("io.Copy error:", err)
	}
}
<commit_msg>Improve logging on tunnels<commit_after>// Copyright (c) 2016 Niklas Wolber
// This file is licensed under the MIT license.
// See the LICENSE file for more information.

package job

import (
	"context"
	"fmt"
	"io"
	"log"
	"net"
	"os"

	"golang.org/x/crypto/ssh"
)

// forwardRemote instructs the connect SSH server to forward all connections attempts
// on remoteAddr to the local client. The client will then establish a connection
// to localAddr and forward any payload exchanged.
//
// Allocated resources will be released, when the context completes.
func forwardRemote(ctx context.Context, client *ssh.Client, remoteAddr string, localAddr string) {
	l, ok := ctx.Value(loggerKey).(Logger)
	if !ok || l == nil {
		l = log.New(os.Stderr, "", log.LstdFlags)
	}

	listener, err := client.Listen("tcp", remoteAddr)
	if err != nil {
		err = fmt.Errorf("unable to listen to %s on remote host %s: %s", remoteAddr, client.RemoteAddr(), err)
		l.Println(err)
		return
	}

	go runTunnel(ctx, listener, net.Dial, localAddr)
}

// forwardLocal forwards all connection attempts on localAddr to the remote host client
// connects to. The remote host will then establish a connection remoteAddr.
//
// Allocated resources will be released, when the context completes.
func forwardLocal(ctx context.Context, client *ssh.Client, remoteAddr string, localAddr string) {
	l, ok := ctx.Value(loggerKey).(Logger)
	if !ok || l == nil {
		l = log.New(os.Stderr, "", log.LstdFlags)
	}

	listener, err := net.Listen("tcp", localAddr)
	if err != nil {
		err = fmt.Errorf("unable to listen to %s: %s", localAddr, err)
		l.Println(err)
		return
	}

	go runTunnel(ctx, listener, client.Dial, remoteAddr)
}

type dial func(network, address string) (net.Conn, error)

func runTunnel(ctx context.Context, listener net.Listener, d dial, addr string) {
	l, ok := ctx.Value(loggerKey).(Logger)
	if !ok || l == nil {
		l = log.New(os.Stderr, "", log.LstdFlags)
	}

	acceptChan := accept(ctx, listener)

	for {
		select {
		case remoteConn, ok := <-acceptChan:
			if !ok {
				l.Println("accept channel closed")
				return
			}

			if remoteConn.error != nil {
				l.Println("error accepting tunnel connection", remoteConn.error)
				return
			}

			go func(conn net.Conn) {
				defer conn.Close()
				identity := fmt.Sprintf("%s->%s", conn.RemoteAddr(), conn.LocalAddr())

				l.Println("accepted tunnel connection", identity)

				localConn, err := d("tcp", addr)
				if err != nil {
					l.Println(identity, "unable to connect to endpoint", addr, err)
					return
				}
				l.Println(identity, "connected to endpoint")

				go copyConn(identity, localConn, conn)
				copyConn(identity, conn, localConn)
				l.Println(identity, "tunnel connection closed")
			}(remoteConn)

		case <-ctx.Done():
			l.Println("context done, closing tunnel on", listener.Addr())
			return
		}
	}
}

func copyConn(identity string, writer io.Writer, reader io.Reader) {
	_, err := io.Copy(writer, reader)
	if err != nil {
		log.Println(identity, "io.Copy error:", err)
	}
}
<|endoftext|>