<commit_before>// [ $GOOS != nacl ] || exit 0  # no network
// $G $D/$F.go && $L $F.$A && ./$A.out

// Copyright 2010 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 main

import (
	"fmt"
	"net"
)

func main() {
	var listen, _ = net.Listen("tcp", "127.0.0.1:0")

	go func() {
		for {
			var conn, _ = listen.Accept()
		}
	}()

	var conn, _ = net.Dial("tcp", "", listen.Addr().String())
}
<commit_msg>fix build<commit_after>// [ $GOOS != nacl ] || exit 0  # no network
// $G $D/$F.go && $L $F.$A && ./$A.out

// Copyright 2010 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 main

import (
	"net"
)

func main() {
	var listen, _ = net.Listen("tcp", "127.0.0.1:0")

	go func() {
		for {
			var conn, _ = listen.Accept()
			_ = conn
		}
	}()

	var conn, _ = net.Dial("tcp", "", listen.Addr().String())
	_ = conn
}
<|endoftext|>


<commit_before>package Amqp

import (
	"flag"
	"fmt"
	"github.com/streadway/amqp"
)

var (
	flgPrefetch = flag.Int("prefetch", 64, "prefetch message from mq")
)

func ConnectMq(url string) (conn *amqp.Connection, channel *amqp.Channel, err error) {
	conn, err = amqp.Dial(url)
	if err == nil {
		channel, err = conn.Channel()
	}

	return
}

func NewMqExchange(channel *amqp.Channel, name, _type string, durable bool) error {
	return channel.ExchangeDeclare(
		name,    // name
		_type,   // type
		durable, // durable
		true,    // auto-delete
		false,   // internal
		false,   // nowait
		nil,     // args
	)
}

func Publish(channel *amqp.Channel, exchange, rkey string, msg []byte) error {
	if channel == nil {
		return fmt.Errorf("channel is nil")
	}

	return channel.Publish(exchange, rkey, false, false,
		amqp.Publishing{ContentType: "application/octet-stream", Body: msg})
}

func newMqConsumer(url, exchange, queue, rkey, ctag string, ack, durable, exclusive bool) (
	conn *amqp.Connection, channel *amqp.Channel, deliveries <-chan amqp.Delivery, err error) {

	conn, channel, err = ConnectMq(url)
	if err != nil {
		return
	}

	channel.QueueDeclare(
		queue,     // name of the queue
		durable,   // durable
		exclusive, // delete when usused
		exclusive, // exclusive
		false,     // noWait
		nil,       // arguments
	)

	if err = channel.QueueBind(
		queue,    // name of the queue
		rkey,     // bindingKey
		exchange, // sourceExchange
		false,    // noWait
		nil,      // arguments
	); err != nil {
		conn.Close()
		return
	}

	deliveries, err = channel.Consume(
		queue,     // name
		ctag,      // consumerTag,
		!ack,      // noAck
		exclusive, // exclusive
		false,     // noLocal
		false,     // noWait
		nil,       // arguments
	)
	if err != nil {
		conn.Close()
		return
	}

	if ack {
		channel.Qos(*flgPrefetch, 0, true)
	}
	return
}

func NewMqConsumer(url, exchange, queue, rkey, ctag string, ack, durable bool) (
	conn *amqp.Connection, channel *amqp.Channel, deliveries <-chan amqp.Delivery, err error) {

	return newMqConsumer(url, exchange, queue, rkey, ctag, ack, durable, false)
}

func NewExclusiveMqConsumer(url, exchange, queue, rkey, ctag string) (
	conn *amqp.Connection, channel *amqp.Channel, deliveries <-chan amqp.Delivery, err error) {

	return newMqConsumer(url, exchange, queue, rkey, ctag, false, false, true)
}
<commit_msg>remove auto delete flag<commit_after>package Amqp

import (
	"flag"
	"fmt"
	"github.com/streadway/amqp"
)

var (
	flgPrefetch = flag.Int("prefetch", 64, "prefetch message from mq")
)

func ConnectMq(url string) (conn *amqp.Connection, channel *amqp.Channel, err error) {
	conn, err = amqp.Dial(url)
	if err == nil {
		channel, err = conn.Channel()
	}

	return
}

func NewMqExchange(channel *amqp.Channel, name, _type string, durable bool) error {
	return channel.ExchangeDeclare(
		name,    // name
		_type,   // type
		durable, // durable
		false,    // auto-delete
		false,   // internal
		false,   // nowait
		nil,     // args
	)
}

func Publish(channel *amqp.Channel, exchange, rkey string, msg []byte) error {
	if channel == nil {
		return fmt.Errorf("channel is nil")
	}

	return channel.Publish(exchange, rkey, false, false,
		amqp.Publishing{ContentType: "application/octet-stream", Body: msg})
}

func newMqConsumer(url, exchange, queue, rkey, ctag string, ack, durable, exclusive bool) (
	conn *amqp.Connection, channel *amqp.Channel, deliveries <-chan amqp.Delivery, err error) {

	conn, channel, err = ConnectMq(url)
	if err != nil {
		return
	}

	channel.QueueDeclare(
		queue,     // name of the queue
		durable,   // durable
		exclusive, // delete when usused
		exclusive, // exclusive
		false,     // noWait
		nil,       // arguments
	)

	if err = channel.QueueBind(
		queue,    // name of the queue
		rkey,     // bindingKey
		exchange, // sourceExchange
		false,    // noWait
		nil,      // arguments
	); err != nil {
		conn.Close()
		return
	}

	deliveries, err = channel.Consume(
		queue,     // name
		ctag,      // consumerTag,
		!ack,      // noAck
		exclusive, // exclusive
		false,     // noLocal
		false,     // noWait
		nil,       // arguments
	)
	if err != nil {
		conn.Close()
		return
	}

	if ack {
		channel.Qos(*flgPrefetch, 0, true)
	}
	return
}

func NewMqConsumer(url, exchange, queue, rkey, ctag string, ack, durable bool) (
	conn *amqp.Connection, channel *amqp.Channel, deliveries <-chan amqp.Delivery, err error) {

	return newMqConsumer(url, exchange, queue, rkey, ctag, ack, durable, false)
}

func NewExclusiveMqConsumer(url, exchange, queue, rkey, ctag string) (
	conn *amqp.Connection, channel *amqp.Channel, deliveries <-chan amqp.Delivery, err error) {

	return newMqConsumer(url, exchange, queue, rkey, ctag, false, false, true)
}
<|endoftext|>


<commit_before>package torrent

import (
	"strings"

	torrentapi "github.com/qopher/go-torrentapi"
)

func filterMovies(torrents torrentapi.TorrentResults) string {
	var moviesextended torrentapi.TorrentResults
	// Search for extended version
	for _, t := range torrents {
		var filename = strings.ToLower(t.Filename)
		if strings.Contains(filename, "extended") {
			moviesextended = append(moviesextended, t)
		}
	}
	var results torrentapi.TorrentResults
	results = filteraudioQuality("DTS-HD", moviesextended)
	//log.Printf("For quality %s the number of result if %d", "DTS-HD", len(results))
	if len(results) > 0 {
		return results[0].Download
	}
	results = filteraudioQuality("DTS-HD.MA.7.1", moviesextended)
	//log.Printf("For quality %s the number of result if %d", "DTS-HD.MA.7.1", len(results))
	if len(results) > 0 {
		return results[0].Download
	}
	results = filteraudioQuality("TrueHD.7.1Atmos", moviesextended)
	//log.Printf("For quality %s the number of result if %d", "TrueHD.7.1Atmos", len(results))
	if len(results) > 0 {
		return results[0].Download
	}
	results = filteraudioQuality("DTS", moviesextended)
	//log.Printf("For quality %s the number of result if %d", "DTS", len(results))
	if len(results) > 0 {
		return results[0].Download
	}

	results = filteraudioQuality("DTS-HD", torrents)
	//log.Printf("For quality %s the number of result if %d", "DTS-HD", len(results))
	if len(results) > 0 {
		return results[0].Download
	}
	results = filteraudioQuality("DTS-HD.MA.7.1", torrents)
	//log.Printf("For quality %s the number of result if %d", "DTS-HD.MA.7.1", len(results))
	if len(results) > 0 {
		return results[0].Download
	}
	results = filteraudioQuality("TrueHD.7.1Atmos", torrents)
	//log.Printf("For quality %s the number of result if %d", "TrueHD.7.1Atmos", len(results))
	if len(results) > 0 {
		return results[0].Download
	}
	results = filteraudioQuality("DTS", torrents)
	//log.Printf("For quality %s the number of result if %d", "DTS", len(results))
	if len(results) > 0 {
		return results[0].Download
	}

	return ""

}

func filteraudioQuality(quality string, torrents torrentapi.TorrentResults) torrentapi.TorrentResults {
	var movies torrentapi.TorrentResults
	for _, t := range torrents {
		var filename = strings.ToLower(t.Download)
		quality = strings.ToLower(quality)
		if strings.Contains(filename, quality) && t.Seeders > 0 {
			movies = append(movies, t)
		}
	}
	return movies
}

func Search(movieIMBDID, quality string) (string, error) {
	api, err := torrentapi.Init()
	if err != nil {
		return "", err
	}
	api.Format("json_extended")
	api.Category(44)
	api.SearchImDB(movieIMBDID)
	results, err := api.Search()
	if err != nil {
		return "", err
	}

	if len(results) == 0 {
		return "", nil
	}
	return filterMovies(results), nil
}
<commit_msg>Exclude 3D movies<commit_after>package torrent

import (
	"strings"

	torrentapi "github.com/qopher/go-torrentapi"
)

func filterMovies(torrents torrentapi.TorrentResults) string {
	torrents = exlucde3DMovies(torrents)
	var moviesextended torrentapi.TorrentResults
	// Search for extended version
	for _, t := range torrents {
		var filename = strings.ToLower(t.Filename)
		if strings.Contains(filename, "extended") {
			moviesextended = append(moviesextended, t)
		}
	}
	var results torrentapi.TorrentResults
	results = filteraudioQuality("DTS-HD", moviesextended)
	//log.Printf("For quality %s the number of result if %d", "DTS-HD", len(results))
	if len(results) > 0 {
		return results[0].Download
	}
	results = filteraudioQuality("DTS-HD.MA.7.1", moviesextended)
	//log.Printf("For quality %s the number of result if %d", "DTS-HD.MA.7.1", len(results))
	if len(results) > 0 {
		return results[0].Download
	}
	results = filteraudioQuality("TrueHD.7.1Atmos", moviesextended)
	//log.Printf("For quality %s the number of result if %d", "TrueHD.7.1Atmos", len(results))
	if len(results) > 0 {
		return results[0].Download
	}
	results = filteraudioQuality("DTS", moviesextended)
	//log.Printf("For quality %s the number of result if %d", "DTS", len(results))
	if len(results) > 0 {
		return results[0].Download
	}

	results = filteraudioQuality("DTS-HD", torrents)
	//log.Printf("For quality %s the number of result if %d", "DTS-HD", len(results))
	if len(results) > 0 {
		return results[0].Download
	}
	results = filteraudioQuality("DTS-HD.MA.7.1", torrents)
	//log.Printf("For quality %s the number of result if %d", "DTS-HD.MA.7.1", len(results))
	if len(results) > 0 {
		return results[0].Download
	}
	results = filteraudioQuality("TrueHD.7.1Atmos", torrents)
	//log.Printf("For quality %s the number of result if %d", "TrueHD.7.1Atmos", len(results))
	if len(results) > 0 {
		return results[0].Download
	}
	results = filteraudioQuality("DTS", torrents)
	//log.Printf("For quality %s the number of result if %d", "DTS", len(results))
	if len(results) > 0 {
		return results[0].Download
	}

	return ""

}

func exlucde3DMovies(torrents torrentapi.TorrentResults) torrentapi.TorrentResults {
	var movies torrentapi.TorrentResults
	for _, t := range torrents {
		var filename = strings.ToLower(t.Download)
		if !strings.Contains(filename, "3d") {
			movies = append(movies, t)
		}
	}
	return movies
}

func filteraudioQuality(quality string, torrents torrentapi.TorrentResults) torrentapi.TorrentResults {
	var movies torrentapi.TorrentResults
	for _, t := range torrents {
		var filename = strings.ToLower(t.Download)
		quality = strings.ToLower(quality)
		if strings.Contains(filename, quality) && t.Seeders > 0 {
			movies = append(movies, t)
		}
	}
	return movies
}

func Search(movieIMBDID, quality string) (string, error) {
	api, err := torrentapi.Init()
	if err != nil {
		return "", err
	}
	api.Format("json_extended")
	api.Category(44)
	api.SearchImDB(movieIMBDID)
	results, err := api.Search()
	if err != nil {
		return "", err
	}

	if len(results) == 0 {
		return "", nil
	}
	return filterMovies(results), nil
}
<|endoftext|>


<commit_before>package matrix

import (
	"github.com/husl-colors/husl-go"
	"math/rand"
)

func (matrix *matrix) InitFlame() {
	matrix.flame_palette = make([][3]byte, 256)
	matrix.flame_buffer = make([][]byte, matrix.rows)
	for r, _ := range matrix.flame_buffer {
		matrix.flame_buffer[r] = make([]byte, matrix.columns)
	}

	var color [3]byte
	for i, _ := range matrix.flame_palette {
		l := float64(i) / 256.0 * 100.0
		if l > 50 {
			l = 50
		}
		r, g, b := husl.HuslToRGB(float64(i)/4.0, 100, l)
		color[0] = byte(r * 255.0)
		color[1] = byte(g * 255.0)
		color[2] = byte(b * 255.0)
		matrix.flame_palette[i] = color
	}
}

func (matrix *matrix) FlameFill() {
	// Seed the bottom row
	for c, _ := range matrix.flame_buffer[matrix.rows-1] {
		matrix.flame_buffer[matrix.rows-1][c] = byte(rand.Float32() * 255.0)
	}

	for r, row := range matrix.flame_buffer {
		for c, _ := range row {
			y := (r + 1) % matrix.rows
			x := (c - 1 + matrix.columns) % matrix.columns
			value := int(matrix.flame_buffer[y][x])
			value += int(matrix.flame_buffer[(r+1)%matrix.rows][c])
			value += int(matrix.flame_buffer[(r+1)%matrix.rows][(c+1)%matrix.columns])
			value *= 40
			value /= 129
			matrix.flame_buffer[r][c] = byte(value)
		}
	}

	for r, row := range matrix.bitmap {
		for c, _ := range row {
			matrix.bitmap[r][c] = matrix.flame_palette[matrix.flame_buffer[r][c]]
		}
	}
}
<commit_msg>Slightly brighter palette<commit_after>package matrix

import (
	"github.com/husl-colors/husl-go"
	"math/rand"
)

func (matrix *matrix) InitFlame() {
	matrix.flame_palette = make([][3]byte, 256)
	matrix.flame_buffer = make([][]byte, matrix.rows)
	for r, _ := range matrix.flame_buffer {
		matrix.flame_buffer[r] = make([]byte, matrix.columns)
	}

	var color [3]byte
	for i, _ := range matrix.flame_palette {
		l := float64(i) / 256.0 * 100.0
		if l > 50 {
			l = 50
		}
		r, g, b := husl.HuslToRGB(float64(i)/2.0, 100, l)
		color[0] = byte(r * 255.0)
		color[1] = byte(g * 255.0)
		color[2] = byte(b * 255.0)
		matrix.flame_palette[i] = color
	}
}

func (matrix *matrix) FlameFill() {
	// Seed the bottom row
	for c, _ := range matrix.flame_buffer[matrix.rows-1] {
		matrix.flame_buffer[matrix.rows-1][c] = byte(rand.Float32() * 255.0)
	}

	for r, row := range matrix.flame_buffer {
		for c, _ := range row {
			y := (r + 1) % matrix.rows
			x := (c - 1 + matrix.columns) % matrix.columns
			value := int(matrix.flame_buffer[y][x])
			value += int(matrix.flame_buffer[(r+1)%matrix.rows][c])
			value += int(matrix.flame_buffer[(r+1)%matrix.rows][(c+1)%matrix.columns])
			value *= 40
			value /= 129
			matrix.flame_buffer[r][c] = byte(value)
		}
	}

	for r, row := range matrix.bitmap {
		for c, _ := range row {
			matrix.bitmap[r][c] = matrix.flame_palette[matrix.flame_buffer[r][c]]
		}
	}
}
<|endoftext|>


<commit_before>package delaunay

import (
	"fmt"
	"math"
	"sort"
)

type Triangulation struct {
	Points     []Point
	ConvexHull []Point
	Triangles  []int
	Halfedges  []int
}

func Triangulate(points []Point) (*Triangulation, error) {
	t := newTriangulator(points)
	if err := t.triangulate(); err != nil {
		return nil, err
	}
	return &Triangulation{points, t.convexHull(), t.triangles, t.halfedges}, nil
}

func (t *Triangulation) area() float64 {
	var result float64
	points := t.Points
	ts := t.Triangles
	for i := 0; i < len(ts); i += 3 {
		p0 := points[ts[i+0]]
		p1 := points[ts[i+1]]
		p2 := points[ts[i+2]]
		result += area(p0, p1, p2)
	}
	return result / 2
}

type triangulator struct {
	points       []Point
	distances    []float64
	ids          []int
	center       Point
	triangles    []int
	halfedges    []int
	trianglesLen int
	hull         *node
	hash         []*node
}

func newTriangulator(points []Point) *triangulator {
	return &triangulator{points: points}
}

// sorting a triangulator sorts the `ids` such that the referenced points
// are in order by their distance to `center`
func (a *triangulator) Len() int {
	return len(a.points)
}

func (a *triangulator) Swap(i, j int) {
	a.ids[i], a.ids[j] = a.ids[j], a.ids[i]
}

func (a *triangulator) Less(i, j int) bool {
	d1 := a.distances[a.ids[i]]
	d2 := a.distances[a.ids[j]]
	if d1 != d2 {
		return d1 < d2
	}
	p1 := a.points[a.ids[i]]
	p2 := a.points[a.ids[j]]
	if p1.X != p2.X {
		return p1.X < p2.X
	}
	return p1.Y < p2.Y
}

func (tri *triangulator) triangulate() error {
	points := tri.points

	n := len(points)
	if n == 0 {
		return nil
	}

	tri.ids = make([]int, n)

	// compute bounds
	x0 := points[0].X
	y0 := points[0].Y
	x1 := points[0].X
	y1 := points[0].Y
	for i, p := range points {
		if p.X < x0 {
			x0 = p.X
		}
		if p.X > x1 {
			x1 = p.X
		}
		if p.Y < y0 {
			y0 = p.Y
		}
		if p.Y > y1 {
			y1 = p.Y
		}
		tri.ids[i] = i
	}

	var i0, i1, i2 int

	// pick a seed point close to midpoint
	m := Point{(x0 + x1) / 2, (y0 + y1) / 2}
	minDist := infinity
	for i, p := range points {
		d := p.distance(m)
		if d < minDist {
			i0 = i
			minDist = d
		}
	}

	// find point closest to seed point
	minDist = infinity
	for i, p := range points {
		if i == i0 {
			continue
		}
		d := p.distance(points[i0])
		if d > 0 && d < minDist {
			i1 = i
			minDist = d
		}
	}

	// find the third point which forms the smallest circumcircle
	minRadius := infinity
	for i, p := range points {
		if i == i0 || i == i1 {
			continue
		}
		r := circumradius(points[i0], points[i1], p)
		if r < minRadius {
			i2 = i
			minRadius = r
		}
	}
	if minRadius == infinity {
		return fmt.Errorf("No Delaunay triangulation exists for this input.")
	}

	// swap the order of the seed points for counter-clockwise orientation
	if area(points[i0], points[i1], points[i2]) < 0 {
		i1, i2 = i2, i1
	}

	tri.center = circumcenter(points[i0], points[i1], points[i2])

	// sort the points by distance from the seed triangle circumcenter
	tri.distances = make([]float64, n)
	for i, p := range points {
		tri.distances[i] = p.distance(tri.center)
	}
	sort.Sort(tri)

	// initialize a hash table for storing edges of the advancing convex hull
	hashSize := int(math.Ceil(math.Sqrt(float64(n))))
	tri.hash = make([]*node, hashSize)

	// initialize a circular doubly-linked list that will hold an advancing convex hull
	e := newNode(points[i0], i0, nil)
	e.t = 0
	tri.hashEdge(e)

	e = newNode(points[i1], i1, e)
	e.t = 1
	tri.hashEdge(e)

	e = newNode(points[i2], i2, e)
	e.t = 2
	tri.hashEdge(e)

	tri.hull = e

	maxTriangles := 2*n - 5
	tri.triangles = make([]int, maxTriangles*3)
	tri.halfedges = make([]int, maxTriangles*3)

	tri.addTriangle(i0, i1, i2, -1, -1, -1)

	pp := Point{infinity, infinity}
	for k := 0; k < n; k++ {
		i := tri.ids[k]
		p := points[i]

		// skip duplicate points
		if p == pp {
			continue
		}
		pp = p

		// skip seed triangle points
		if i == i0 || i == i1 || i == i2 {
			continue
		}

		// find a visible edge on the convex hull using edge hash
		var start *node
		key := tri.hashKey(p)
		for j := 0; j < len(tri.hash); j++ {
			start = tri.hash[key]
			if start != nil && !start.removed {
				break
			}
			key++
			if key >= len(tri.hash) {
				key = 0
			}
		}
		start = start.prev

		e := start
		for area(p, e.p, e.next.p) >= 0 {
			e = e.next
			if e == start {
				return fmt.Errorf("Something is wrong with the input points.")
			}
		}
		walkBack := e == start

		// add the first triangle from the point
		t := tri.addTriangle(e.i, i, e.next.i, -1, -1, e.t)
		e.t = t // keep track of boundary triangles on the hull
		e = newNode(points[i], i, e)

		// recursively flip triangles from the point until they satisfy the Delaunay condition
		e.t = tri.legalize(t + 2)

		// walk forward through the hull, adding more triangles and flipping recursively
		q := e.next
		for area(p, q.p, q.next.p) < 0 {
			t = tri.addTriangle(q.i, i, q.next.i, q.prev.t, -1, q.t)
			q.prev.t = tri.legalize(t + 2)
			tri.hull = q.remove()
			q = q.next
		}

		if walkBack {
			// walk backward from the other side, adding more triangles and flipping
			q := e.prev
			for area(p, q.prev.p, q.p) < 0 {
				t = tri.addTriangle(q.prev.i, i, q.i, -1, q.t, q.prev.t)
				tri.legalize(t + 2)
				q.prev.t = t
				tri.hull = q.remove()
				q = q.prev
			}
		}

		// save the two new edges in the hash table
		tri.hashEdge(e)
		tri.hashEdge(e.prev)
	}

	tri.triangles = tri.triangles[:tri.trianglesLen]
	tri.halfedges = tri.halfedges[:tri.trianglesLen]

	return nil
}

func (t *triangulator) hashKey(point Point) int {
	d := point.sub(t.center)
	return int(pseudoAngle(d.X, d.Y) * float64(len(t.hash)))
}

func (t *triangulator) hashEdge(e *node) {
	t.hash[t.hashKey(e.p)] = e
}

func (t *triangulator) addTriangle(i0, i1, i2, a, b, c int) int {
	i := t.trianglesLen
	t.triangles[i] = i0
	t.triangles[i+1] = i1
	t.triangles[i+2] = i2
	t.link(i, a)
	t.link(i+1, b)
	t.link(i+2, c)
	t.trianglesLen += 3
	return i
}

func (t *triangulator) link(a, b int) {
	t.halfedges[a] = b
	if b >= 0 {
		t.halfedges[b] = a
	}
}

func (t *triangulator) legalize(a int) int {
	// if the pair of triangles doesn't satisfy the Delaunay condition
	// (p1 is inside the circumcircle of [p0, pl, pr]), flip them,
	// then do the same check/flip recursively for the new pair of triangles
	//
	//           pl                    pl
	//          /||\                  /  \
	//       al/ || \bl            al/    \a
	//        /  ||  \              /      \
	//       /  a||b  \    flip    /___ar___\
	//     p0\   ||   /p1   =>   p0\---bl---/p1
	//        \  ||  /              \      /
	//       ar\ || /br             b\    /br
	//          \||/                  \  /
	//           pr                    pr

	b := t.halfedges[a]

	a0 := a - a%3
	b0 := b - b%3

	al := a0 + (a+1)%3
	ar := a0 + (a+2)%3
	bl := b0 + (b+2)%3

	if b < 0 {
		return ar
	}

	p0 := t.triangles[ar]
	pr := t.triangles[a]
	pl := t.triangles[al]
	p1 := t.triangles[bl]

	illegal := inCircle(t.points[p0], t.points[pr], t.points[pl], t.points[p1])

	if illegal {
		t.triangles[a] = p1
		t.triangles[b] = p0

		// edge swapped on the other side of the hull (rare)
		// fix the halfedge reference
		if t.halfedges[bl] == -1 {
			e := t.hull.next
			for e != t.hull {
				if e.t == bl {
					e.t = a
					break
				}
				e = e.next
			}
		}

		t.link(a, t.halfedges[bl])
		t.link(b, t.halfedges[ar])
		t.link(ar, bl)

		br := b0 + (b+1)%3

		t.legalize(a)
		return t.legalize(br)
	}

	return ar
}

func (t *triangulator) convexHull() []Point {
	var result []Point
	e := t.hull
	for {
		result = append(result, e.p)
		e = e.prev
		if e == t.hull {
			break
		}
	}
	return result
}
<commit_msg>Add doc.<commit_after>package delaunay

import (
	"fmt"
	"math"
	"sort"
)

type Triangulation struct {
	Points     []Point
	ConvexHull []Point
	Triangles  []int
	Halfedges  []int
}

// Triangulate returns a Delaunay triangulation of the provided points.
func Triangulate(points []Point) (*Triangulation, error) {
	t := newTriangulator(points)
	if err := t.triangulate(); err != nil {
		return nil, err
	}
	return &Triangulation{points, t.convexHull(), t.triangles, t.halfedges}, nil
}

func (t *Triangulation) area() float64 {
	var result float64
	points := t.Points
	ts := t.Triangles
	for i := 0; i < len(ts); i += 3 {
		p0 := points[ts[i+0]]
		p1 := points[ts[i+1]]
		p2 := points[ts[i+2]]
		result += area(p0, p1, p2)
	}
	return result / 2
}

type triangulator struct {
	points       []Point
	distances    []float64
	ids          []int
	center       Point
	triangles    []int
	halfedges    []int
	trianglesLen int
	hull         *node
	hash         []*node
}

func newTriangulator(points []Point) *triangulator {
	return &triangulator{points: points}
}

// sorting a triangulator sorts the `ids` such that the referenced points
// are in order by their distance to `center`
func (a *triangulator) Len() int {
	return len(a.points)
}

func (a *triangulator) Swap(i, j int) {
	a.ids[i], a.ids[j] = a.ids[j], a.ids[i]
}

func (a *triangulator) Less(i, j int) bool {
	d1 := a.distances[a.ids[i]]
	d2 := a.distances[a.ids[j]]
	if d1 != d2 {
		return d1 < d2
	}
	p1 := a.points[a.ids[i]]
	p2 := a.points[a.ids[j]]
	if p1.X != p2.X {
		return p1.X < p2.X
	}
	return p1.Y < p2.Y
}

func (tri *triangulator) triangulate() error {
	points := tri.points

	n := len(points)
	if n == 0 {
		return nil
	}

	tri.ids = make([]int, n)

	// compute bounds
	x0 := points[0].X
	y0 := points[0].Y
	x1 := points[0].X
	y1 := points[0].Y
	for i, p := range points {
		if p.X < x0 {
			x0 = p.X
		}
		if p.X > x1 {
			x1 = p.X
		}
		if p.Y < y0 {
			y0 = p.Y
		}
		if p.Y > y1 {
			y1 = p.Y
		}
		tri.ids[i] = i
	}

	var i0, i1, i2 int

	// pick a seed point close to midpoint
	m := Point{(x0 + x1) / 2, (y0 + y1) / 2}
	minDist := infinity
	for i, p := range points {
		d := p.distance(m)
		if d < minDist {
			i0 = i
			minDist = d
		}
	}

	// find point closest to seed point
	minDist = infinity
	for i, p := range points {
		if i == i0 {
			continue
		}
		d := p.distance(points[i0])
		if d > 0 && d < minDist {
			i1 = i
			minDist = d
		}
	}

	// find the third point which forms the smallest circumcircle
	minRadius := infinity
	for i, p := range points {
		if i == i0 || i == i1 {
			continue
		}
		r := circumradius(points[i0], points[i1], p)
		if r < minRadius {
			i2 = i
			minRadius = r
		}
	}
	if minRadius == infinity {
		return fmt.Errorf("No Delaunay triangulation exists for this input.")
	}

	// swap the order of the seed points for counter-clockwise orientation
	if area(points[i0], points[i1], points[i2]) < 0 {
		i1, i2 = i2, i1
	}

	tri.center = circumcenter(points[i0], points[i1], points[i2])

	// sort the points by distance from the seed triangle circumcenter
	tri.distances = make([]float64, n)
	for i, p := range points {
		tri.distances[i] = p.distance(tri.center)
	}
	sort.Sort(tri)

	// initialize a hash table for storing edges of the advancing convex hull
	hashSize := int(math.Ceil(math.Sqrt(float64(n))))
	tri.hash = make([]*node, hashSize)

	// initialize a circular doubly-linked list that will hold an advancing convex hull
	e := newNode(points[i0], i0, nil)
	e.t = 0
	tri.hashEdge(e)

	e = newNode(points[i1], i1, e)
	e.t = 1
	tri.hashEdge(e)

	e = newNode(points[i2], i2, e)
	e.t = 2
	tri.hashEdge(e)

	tri.hull = e

	maxTriangles := 2*n - 5
	tri.triangles = make([]int, maxTriangles*3)
	tri.halfedges = make([]int, maxTriangles*3)

	tri.addTriangle(i0, i1, i2, -1, -1, -1)

	pp := Point{infinity, infinity}
	for k := 0; k < n; k++ {
		i := tri.ids[k]
		p := points[i]

		// skip duplicate points
		if p == pp {
			continue
		}
		pp = p

		// skip seed triangle points
		if i == i0 || i == i1 || i == i2 {
			continue
		}

		// find a visible edge on the convex hull using edge hash
		var start *node
		key := tri.hashKey(p)
		for j := 0; j < len(tri.hash); j++ {
			start = tri.hash[key]
			if start != nil && !start.removed {
				break
			}
			key++
			if key >= len(tri.hash) {
				key = 0
			}
		}
		start = start.prev

		e := start
		for area(p, e.p, e.next.p) >= 0 {
			e = e.next
			if e == start {
				return fmt.Errorf("Something is wrong with the input points.")
			}
		}
		walkBack := e == start

		// add the first triangle from the point
		t := tri.addTriangle(e.i, i, e.next.i, -1, -1, e.t)
		e.t = t // keep track of boundary triangles on the hull
		e = newNode(points[i], i, e)

		// recursively flip triangles from the point until they satisfy the Delaunay condition
		e.t = tri.legalize(t + 2)

		// walk forward through the hull, adding more triangles and flipping recursively
		q := e.next
		for area(p, q.p, q.next.p) < 0 {
			t = tri.addTriangle(q.i, i, q.next.i, q.prev.t, -1, q.t)
			q.prev.t = tri.legalize(t + 2)
			tri.hull = q.remove()
			q = q.next
		}

		if walkBack {
			// walk backward from the other side, adding more triangles and flipping
			q := e.prev
			for area(p, q.prev.p, q.p) < 0 {
				t = tri.addTriangle(q.prev.i, i, q.i, -1, q.t, q.prev.t)
				tri.legalize(t + 2)
				q.prev.t = t
				tri.hull = q.remove()
				q = q.prev
			}
		}

		// save the two new edges in the hash table
		tri.hashEdge(e)
		tri.hashEdge(e.prev)
	}

	tri.triangles = tri.triangles[:tri.trianglesLen]
	tri.halfedges = tri.halfedges[:tri.trianglesLen]

	return nil
}

func (t *triangulator) hashKey(point Point) int {
	d := point.sub(t.center)
	return int(pseudoAngle(d.X, d.Y) * float64(len(t.hash)))
}

func (t *triangulator) hashEdge(e *node) {
	t.hash[t.hashKey(e.p)] = e
}

func (t *triangulator) addTriangle(i0, i1, i2, a, b, c int) int {
	i := t.trianglesLen
	t.triangles[i] = i0
	t.triangles[i+1] = i1
	t.triangles[i+2] = i2
	t.link(i, a)
	t.link(i+1, b)
	t.link(i+2, c)
	t.trianglesLen += 3
	return i
}

func (t *triangulator) link(a, b int) {
	t.halfedges[a] = b
	if b >= 0 {
		t.halfedges[b] = a
	}
}

func (t *triangulator) legalize(a int) int {
	// if the pair of triangles doesn't satisfy the Delaunay condition
	// (p1 is inside the circumcircle of [p0, pl, pr]), flip them,
	// then do the same check/flip recursively for the new pair of triangles
	//
	//           pl                    pl
	//          /||\                  /  \
	//       al/ || \bl            al/    \a
	//        /  ||  \              /      \
	//       /  a||b  \    flip    /___ar___\
	//     p0\   ||   /p1   =>   p0\---bl---/p1
	//        \  ||  /              \      /
	//       ar\ || /br             b\    /br
	//          \||/                  \  /
	//           pr                    pr

	b := t.halfedges[a]

	a0 := a - a%3
	b0 := b - b%3

	al := a0 + (a+1)%3
	ar := a0 + (a+2)%3
	bl := b0 + (b+2)%3

	if b < 0 {
		return ar
	}

	p0 := t.triangles[ar]
	pr := t.triangles[a]
	pl := t.triangles[al]
	p1 := t.triangles[bl]

	illegal := inCircle(t.points[p0], t.points[pr], t.points[pl], t.points[p1])

	if illegal {
		t.triangles[a] = p1
		t.triangles[b] = p0

		// edge swapped on the other side of the hull (rare)
		// fix the halfedge reference
		if t.halfedges[bl] == -1 {
			e := t.hull.next
			for e != t.hull {
				if e.t == bl {
					e.t = a
					break
				}
				e = e.next
			}
		}

		t.link(a, t.halfedges[bl])
		t.link(b, t.halfedges[ar])
		t.link(ar, bl)

		br := b0 + (b+1)%3

		t.legalize(a)
		return t.legalize(br)
	}

	return ar
}

func (t *triangulator) convexHull() []Point {
	var result []Point
	e := t.hull
	for {
		result = append(result, e.p)
		e = e.prev
		if e == t.hull {
			break
		}
	}
	return result
}
<|endoftext|>


<commit_before>package mantle

import (
	"fmt"
	"github.com/bradfitz/gomemcache/memcache"
	"github.com/vireshas/minimal_vitess_pool/pools"
	"strings"
	"time"
)

var MemcachePoolSize = 10
var DefaultMemcacheIpAndHost = []string{"localhost:11211"}

func MConnect(Instance interface{}) (pools.Resource, error) {
	mcInstance := Instance.(*Memcache)
	hostNPorts := mcInstance.Settings.HostAndPorts
	servers := strings.Join(hostNPorts, ",")
	fmt.Println("connecting to ", hostNPorts)
	cli := memcache.New(hostNPorts)
	return &MemConn{cli}, nil
}

type MemConn struct {
	*memcache.Client
}

func (m *MemConn) Close() {
}

type Memcache struct {
	Settings PoolSettings
	pool     *ResourcePool
}

func (m *Memcache) GetClient() *MemConn {
	connection, err := m.pool.GetConn(m.Settings.Timeout)
	if err != nil {
		panic(err)
	}
	return connection.(*MemConn)
}

func (m *Memcache) PutClient(c *MemConn) {
	m.pool.PutConn(c)
}

func (m *Memcache) SetDefaults() {
	if len(m.Settings.HostAndPorts) == 0 {
		m.Settings.HostAndPorts = DefaultMemcacheIpAndHost
	}
	if m.Settings.Capacity == 0 {
		m.Settings.Capacity = PoolSize
	}
	if m.Settings.MaxCapacity == 0 {
		m.Settings.MaxCapacity = PoolSize
	}
	m.Settings.Timeout = time.Minute
	m.pool = NewPool(MConnect, m, m.Settings)
}

func (m *Memcache) Configure(settings PoolSettings) {
	m.Settings = settings
	m.SetDefaults()
}

func (m *Memcache) Execute(cmd string, args ...interface{}) (interface{}, error) {
	return "inside GEt", nil
}

func (m *Memcache) Delete(keys ...interface{}) int {
	return 1
}

func (m *Memcache) Get(key string) string {
	mc := m.GetClient()
	it, erm := mc.Get(key)
	m.PutClient(mc)
	if erm != nil {
		errMsg := fmt.Sprintf("Errom getting key %s", key)
		return errMsg
	}
	return string(it.Value)
}

func (m *Memcache) Set(key string, value interface{}) bool {
	mc := m.GetClient()
	newVal := value.(string)
	erm := mc.Set(&memcache.Item{Key: key, Value: []byte(newVal)})
	m.PutClient(mc)
	if erm != nil {
		return false
	}
	return true
}

func (m *Memcache) MGet(keys ...interface{}) []string {
	return []string{"hello world"}
}

func (m *Memcache) MSet(mapOfKeyVal map[string]interface{}) bool {
	return true
}

func (m *Memcache) Expire(key string, duration int) bool {
	return true
}

func (m *Memcache) Setex(key string, duration int, val interface{}) bool {
	return true
}
<commit_msg>bug bug bug<commit_after>package mantle

import (
	"fmt"
	"github.com/bradfitz/gomemcache/memcache"
	"github.com/vireshas/minimal_vitess_pool/pools"
	"strings"
	"time"
)

var MemcachePoolSize = 10
var DefaultMemcacheIpAndHost = []string{"localhost:11211"}

func MConnect(Instance interface{}) (pools.Resource, error) {
	mcInstance := Instance.(*Memcache)
	hostNPorts := mcInstance.Settings.HostAndPorts
	servers := strings.Join(hostNPorts, ",")
	fmt.Println("connecting to ", servers)
	cli := memcache.New(servers)
	return &MemConn{cli}, nil
}

type MemConn struct {
	*memcache.Client
}

func (m *MemConn) Close() {
}

type Memcache struct {
	Settings PoolSettings
	pool     *ResourcePool
}

func (m *Memcache) GetClient() *MemConn {
	connection, err := m.pool.GetConn(m.Settings.Timeout)
	if err != nil {
		panic(err)
	}
	return connection.(*MemConn)
}

func (m *Memcache) PutClient(c *MemConn) {
	m.pool.PutConn(c)
}

func (m *Memcache) SetDefaults() {
	if len(m.Settings.HostAndPorts) == 0 {
		m.Settings.HostAndPorts = DefaultMemcacheIpAndHost
	}
	if m.Settings.Capacity == 0 {
		m.Settings.Capacity = PoolSize
	}
	if m.Settings.MaxCapacity == 0 {
		m.Settings.MaxCapacity = PoolSize
	}
	m.Settings.Timeout = time.Minute
	m.pool = NewPool(MConnect, m, m.Settings)
}

func (m *Memcache) Configure(settings PoolSettings) {
	m.Settings = settings
	m.SetDefaults()
}

func (m *Memcache) Execute(cmd string, args ...interface{}) (interface{}, error) {
	return "inside GEt", nil
}

func (m *Memcache) Delete(keys ...interface{}) int {
	return 1
}

func (m *Memcache) Get(key string) string {
	mc := m.GetClient()
	it, erm := mc.Get(key)
	m.PutClient(mc)
	if erm != nil {
		errMsg := fmt.Sprintf("Errom getting key %s", key)
		return errMsg
	}
	return string(it.Value)
}

func (m *Memcache) Set(key string, value interface{}) bool {
	mc := m.GetClient()
	newVal := value.(string)
	erm := mc.Set(&memcache.Item{Key: key, Value: []byte(newVal)})
	m.PutClient(mc)
	if erm != nil {
		return false
	}
	return true
}

func (m *Memcache) MGet(keys ...interface{}) []string {
	return []string{"hello world"}
}

func (m *Memcache) MSet(mapOfKeyVal map[string]interface{}) bool {
	return true
}

func (m *Memcache) Expire(key string, duration int) bool {
	return true
}

func (m *Memcache) Setex(key string, duration int, val interface{}) bool {
	return true
}
<|endoftext|>


<commit_before>// Copyright 2012 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 backup

import (
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
	"bytes"
	"errors"
	"github.com/jacobsa/comeback/blob"
	"github.com/jacobsa/comeback/blob/mock"
	"github.com/jacobsa/comeback/io/mock"
	"github.com/jacobsa/oglemock"
	"io"
	"testing"
	"testing/iotest"
)

const (
	expectedChunkSize = 1<<24
)

func TestRegister(t *testing.T) { RunTests(t) }

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

func makeChunk(char int) []byte {
	charStr := string(char)
	AssertEq(1, len(charStr), "Invalid character: %d", char)
	return bytes.Repeat([]byte(charStr), expectedChunkSize)
}

func returnStoreError(err string) oglemock.Action {
	f := func(b []byte) (blob.Score, error) { return nil, errors.New(err) }
	return oglemock.Invoke(f)
}

type FileSaverTest struct {
	blobStore mock_blob.MockStore
	mockReader mock_io.MockReader
	fileSaver FileSaver

	// Will be used instead of mockReader if non-nil.
	reader io.Reader

	scores []blob.Score
	err error
}

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

func (t *FileSaverTest) SetUp(i *TestInfo) {
	t.blobStore = mock_blob.NewMockStore(i.MockController, "blobStore")
	t.mockReader = mock_io.NewMockReader(i.MockController, "reader")
	t.fileSaver, _ = NewFileSaver(t.blobStore)
}

func (t *FileSaverTest) callSaver() {
	var reader io.Reader = t.mockReader
	if t.reader != nil {
		reader = t.reader
	}

	t.scores, t.err = t.fileSaver.Save(reader)
}

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

func (t *FileSaverTest) NoDataInReader() {
	// Reader
	t.reader = new(bytes.Buffer)

	// Call
	t.callSaver()

	AssertEq(nil, t.err)
	ExpectThat(t.scores, ElementsAre())
}

func (t *FileSaverTest) ReadErrorInFirstChunk() {
	// Chunks
	chunk0 := makeChunk('a')

	// Reader
	t.reader = io.MultiReader(
		iotest.TimeoutReader(bytes.NewReader(chunk0)),
	)

	// Call
	t.callSaver()

	ExpectThat(t.err, Error(HasSubstr("Reading")))
	ExpectThat(t.err, Error(HasSubstr("chunk")))
	ExpectThat(t.err, Error(HasSubstr(iotest.ErrTimeout.Error())))
}

func (t *FileSaverTest) ReadErrorInSecondChunk() {
	// Chunks
	chunk0 := makeChunk('a')
	chunk1 := makeChunk('b')

	// Reader
	t.reader = io.MultiReader(
		bytes.NewReader(chunk0),
		iotest.TimeoutReader(bytes.NewReader(chunk1)),
	)

	// Blob store
	ExpectCall(t.blobStore, "Store")(Any()).Times(1)

	// Call
	t.callSaver()

	ExpectThat(t.err, Error(HasSubstr("Reading")))
	ExpectThat(t.err, Error(HasSubstr("chunk")))
	ExpectThat(t.err, Error(HasSubstr(iotest.ErrTimeout.Error())))
}

func (t *FileSaverTest) CopesWithShortReadsWithinFullSizeChunks() {
	// Chunks
	chunk0 := makeChunk('a')

	// Reader
	t.reader = io.MultiReader(
		iotest.OneByteReader(bytes.NewReader(chunk0)),
	)

	// Blob store
	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk0)).
		WillOnce(returnStoreError(""))

	// Call
	t.callSaver()
}

func (t *FileSaverTest) CopesWithEofAndNonZeroData() {
	// Chunks
	chunk0 := makeChunk('a')

	// Reader
	t.reader = io.MultiReader(
		iotest.DataErrReader(bytes.NewReader(chunk0)),
	)

	// Blob store
	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk0)).
		WillOnce(returnStoreError(""))

	// Call
	t.callSaver()
}

func (t *FileSaverTest) OneSmallerSizedChunk() {
	// Chunks
	chunk0 := makeChunk('a')
	chunk0 = chunk0[0:len(chunk0)-10]

	// Reader
	t.reader = io.MultiReader(
		bytes.NewReader(chunk0),
	)

	// Blob store
	score0 := blob.ComputeScore([]byte(""))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk0)).
		WillOnce(oglemock.Return(score0, nil))

	// Call
	t.callSaver()
}

func (t *FileSaverTest) OneFullSizedChunk() {
	// Chunks
	chunk0 := makeChunk('a')

	// Reader
	t.reader = io.MultiReader(
		bytes.NewReader(chunk0),
	)

	// Blob store
	score0 := blob.ComputeScore([]byte(""))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk0)).
		WillOnce(oglemock.Return(score0, nil))

	// Call
	t.callSaver()
}

func (t *FileSaverTest) OneFullSizedChunkPlusOneByte() {
	// Chunks
	chunk0 := makeChunk('a')
	chunk1 := []byte{0xde}

	// Reader
	t.reader = io.MultiReader(
		bytes.NewReader(chunk0),
		bytes.NewReader(chunk1),
	)

	// Blob store
	score0 := blob.ComputeScore([]byte(""))
	score1 := blob.ComputeScore([]byte(""))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk0)).
		WillOnce(oglemock.Return(score0, nil))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk1)).
		WillOnce(oglemock.Return(score1, nil))

	// Call
	t.callSaver()
}

func (t *FileSaverTest) MultipleChunksWithNoRemainder() {
	// Chunks
	chunk0 := makeChunk('a')
	chunk1 := makeChunk('b')
	chunk2 := makeChunk('c')

	// Reader
	t.reader = io.MultiReader(
		bytes.NewReader(chunk0),
		bytes.NewReader(chunk1),
		bytes.NewReader(chunk2),
	)

	// Blob store
	score0 := blob.ComputeScore([]byte(""))
	score1 := blob.ComputeScore([]byte(""))
	score2 := blob.ComputeScore([]byte(""))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk0)).
		WillOnce(oglemock.Return(score0, nil))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk1)).
		WillOnce(oglemock.Return(score1, nil))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk2)).
		WillOnce(oglemock.Return(score2, nil))

	// Call
	t.callSaver()
}

func (t *FileSaverTest) MultipleChunksWithSmallRemainder() {
	ExpectEq("TODO", "")
}

func (t *FileSaverTest) MultipleChunksWithLargeRemainder() {
	ExpectEq("TODO", "")
}

func (t *FileSaverTest) ErrorStoringOneChunk() {
	ExpectEq("TODO", "")
}

func (t *FileSaverTest) ResultForEmptyReader() {
	ExpectEq("TODO", "")
}

func (t *FileSaverTest) AllStoresSuccessful() {
	ExpectEq("TODO", "")
}
<commit_msg>FileSaverTest.MultipleChunksWithLargeRemainder<commit_after>// Copyright 2012 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 backup

import (
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
	"bytes"
	"errors"
	"github.com/jacobsa/comeback/blob"
	"github.com/jacobsa/comeback/blob/mock"
	"github.com/jacobsa/comeback/io/mock"
	"github.com/jacobsa/oglemock"
	"io"
	"testing"
	"testing/iotest"
)

const (
	expectedChunkSize = 1<<24
)

func TestRegister(t *testing.T) { RunTests(t) }

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

func makeChunk(char int) []byte {
	charStr := string(char)
	AssertEq(1, len(charStr), "Invalid character: %d", char)
	return bytes.Repeat([]byte(charStr), expectedChunkSize)
}

func returnStoreError(err string) oglemock.Action {
	f := func(b []byte) (blob.Score, error) { return nil, errors.New(err) }
	return oglemock.Invoke(f)
}

type FileSaverTest struct {
	blobStore mock_blob.MockStore
	mockReader mock_io.MockReader
	fileSaver FileSaver

	// Will be used instead of mockReader if non-nil.
	reader io.Reader

	scores []blob.Score
	err error
}

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

func (t *FileSaverTest) SetUp(i *TestInfo) {
	t.blobStore = mock_blob.NewMockStore(i.MockController, "blobStore")
	t.mockReader = mock_io.NewMockReader(i.MockController, "reader")
	t.fileSaver, _ = NewFileSaver(t.blobStore)
}

func (t *FileSaverTest) callSaver() {
	var reader io.Reader = t.mockReader
	if t.reader != nil {
		reader = t.reader
	}

	t.scores, t.err = t.fileSaver.Save(reader)
}

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

func (t *FileSaverTest) NoDataInReader() {
	// Reader
	t.reader = new(bytes.Buffer)

	// Call
	t.callSaver()

	AssertEq(nil, t.err)
	ExpectThat(t.scores, ElementsAre())
}

func (t *FileSaverTest) ReadErrorInFirstChunk() {
	// Chunks
	chunk0 := makeChunk('a')

	// Reader
	t.reader = io.MultiReader(
		iotest.TimeoutReader(bytes.NewReader(chunk0)),
	)

	// Call
	t.callSaver()

	ExpectThat(t.err, Error(HasSubstr("Reading")))
	ExpectThat(t.err, Error(HasSubstr("chunk")))
	ExpectThat(t.err, Error(HasSubstr(iotest.ErrTimeout.Error())))
}

func (t *FileSaverTest) ReadErrorInSecondChunk() {
	// Chunks
	chunk0 := makeChunk('a')
	chunk1 := makeChunk('b')

	// Reader
	t.reader = io.MultiReader(
		bytes.NewReader(chunk0),
		iotest.TimeoutReader(bytes.NewReader(chunk1)),
	)

	// Blob store
	ExpectCall(t.blobStore, "Store")(Any()).Times(1)

	// Call
	t.callSaver()

	ExpectThat(t.err, Error(HasSubstr("Reading")))
	ExpectThat(t.err, Error(HasSubstr("chunk")))
	ExpectThat(t.err, Error(HasSubstr(iotest.ErrTimeout.Error())))
}

func (t *FileSaverTest) CopesWithShortReadsWithinFullSizeChunks() {
	// Chunks
	chunk0 := makeChunk('a')

	// Reader
	t.reader = io.MultiReader(
		iotest.OneByteReader(bytes.NewReader(chunk0)),
	)

	// Blob store
	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk0)).
		WillOnce(returnStoreError(""))

	// Call
	t.callSaver()
}

func (t *FileSaverTest) CopesWithEofAndNonZeroData() {
	// Chunks
	chunk0 := makeChunk('a')

	// Reader
	t.reader = io.MultiReader(
		iotest.DataErrReader(bytes.NewReader(chunk0)),
	)

	// Blob store
	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk0)).
		WillOnce(returnStoreError(""))

	// Call
	t.callSaver()
}

func (t *FileSaverTest) OneSmallerSizedChunk() {
	// Chunks
	chunk0 := makeChunk('a')
	chunk0 = chunk0[0:len(chunk0)-10]

	// Reader
	t.reader = io.MultiReader(
		bytes.NewReader(chunk0),
	)

	// Blob store
	score0 := blob.ComputeScore([]byte(""))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk0)).
		WillOnce(oglemock.Return(score0, nil))

	// Call
	t.callSaver()
}

func (t *FileSaverTest) OneFullSizedChunk() {
	// Chunks
	chunk0 := makeChunk('a')

	// Reader
	t.reader = io.MultiReader(
		bytes.NewReader(chunk0),
	)

	// Blob store
	score0 := blob.ComputeScore([]byte(""))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk0)).
		WillOnce(oglemock.Return(score0, nil))

	// Call
	t.callSaver()
}

func (t *FileSaverTest) OneFullSizedChunkPlusOneByte() {
	// Chunks
	chunk0 := makeChunk('a')
	chunk1 := []byte{0xde}

	// Reader
	t.reader = io.MultiReader(
		bytes.NewReader(chunk0),
		bytes.NewReader(chunk1),
	)

	// Blob store
	score0 := blob.ComputeScore([]byte(""))
	score1 := blob.ComputeScore([]byte(""))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk0)).
		WillOnce(oglemock.Return(score0, nil))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk1)).
		WillOnce(oglemock.Return(score1, nil))

	// Call
	t.callSaver()
}

func (t *FileSaverTest) MultipleChunksWithNoRemainder() {
	// Chunks
	chunk0 := makeChunk('a')
	chunk1 := makeChunk('b')
	chunk2 := makeChunk('c')

	// Reader
	t.reader = io.MultiReader(
		bytes.NewReader(chunk0),
		bytes.NewReader(chunk1),
		bytes.NewReader(chunk2),
	)

	// Blob store
	score0 := blob.ComputeScore([]byte(""))
	score1 := blob.ComputeScore([]byte(""))
	score2 := blob.ComputeScore([]byte(""))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk0)).
		WillOnce(oglemock.Return(score0, nil))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk1)).
		WillOnce(oglemock.Return(score1, nil))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk2)).
		WillOnce(oglemock.Return(score2, nil))

	// Call
	t.callSaver()
}

func (t *FileSaverTest) MultipleChunksWithSmallRemainder() {
	// Chunks
	chunk0 := makeChunk('a')
	chunk1 := makeChunk('b')
	chunk2 := []byte{0xde, 0xad}

	// Reader
	t.reader = io.MultiReader(
		bytes.NewReader(chunk0),
		bytes.NewReader(chunk1),
		bytes.NewReader(chunk2),
	)

	// Blob store
	score0 := blob.ComputeScore([]byte(""))
	score1 := blob.ComputeScore([]byte(""))
	score2 := blob.ComputeScore([]byte(""))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk0)).
		WillOnce(oglemock.Return(score0, nil))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk1)).
		WillOnce(oglemock.Return(score1, nil))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk2)).
		WillOnce(oglemock.Return(score2, nil))

	// Call
	t.callSaver()
}

func (t *FileSaverTest) MultipleChunksWithLargeRemainder() {
	// Chunks
	chunk0 := makeChunk('a')
	chunk1 := makeChunk('b')
	chunk2 := makeChunk('c')
	chunk2 = chunk2[0:len(chunk2)-1]

	// Reader
	t.reader = io.MultiReader(
		bytes.NewReader(chunk0),
		bytes.NewReader(chunk1),
		bytes.NewReader(chunk2),
	)

	// Blob store
	score0 := blob.ComputeScore([]byte(""))
	score1 := blob.ComputeScore([]byte(""))
	score2 := blob.ComputeScore([]byte(""))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk0)).
		WillOnce(oglemock.Return(score0, nil))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk1)).
		WillOnce(oglemock.Return(score1, nil))

	ExpectCall(t.blobStore, "Store")(DeepEquals(chunk2)).
		WillOnce(oglemock.Return(score2, nil))

	// Call
	t.callSaver()
}

func (t *FileSaverTest) ErrorStoringOneChunk() {
	ExpectEq("TODO", "")
}

func (t *FileSaverTest) ResultForEmptyReader() {
	ExpectEq("TODO", "")
}

func (t *FileSaverTest) AllStoresSuccessful() {
	ExpectEq("TODO", "")
}
<|endoftext|>


<commit_before>package backup

type JsonObject struct {
	Infrastructure Infrastructure `json:"infrastructure"`
	Products       []Products     `json:"products"`
}

type Infrastructure struct {
	Type string `json:"type"`
}

type Products struct {
	Type string              `json:"type"`
	IPS  map[string][]string `json:"ips"`
	Jobs []Jobs              `json:"jobs"`
}

type IPS struct {
	identifier string
	value      []string
}

type Jobs struct {
	Type       string       `json:"type"`
	Properties []Properties `json:"properties"`
}

type Properties struct {
	Definition string `json:"definition"`
	Value      Value  `json:"value"`
}

type Value interface {
}
<commit_msg>removed unwanted file<commit_after><|endoftext|>


<commit_before>// Copyright 2014 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 runtime

import "unsafe"

var indexError = error(errorString("index out of range"))

func panicindex() {
	panic(indexError)
}

var sliceError = error(errorString("slice bounds out of range"))

func panicslice() {
	panic(sliceError)
}

var divideError = error(errorString("integer divide by zero"))

func panicdivide() {
	panic(divideError)
}

var overflowError = error(errorString("integer overflow"))

func panicoverflow() {
	panic(overflowError)
}

var floatError = error(errorString("floating point error"))

func panicfloat() {
	panic(floatError)
}

var memoryError = error(errorString("invalid memory address or nil pointer dereference"))

func panicmem() {
	panic(memoryError)
}

func throwreturn() {
	gothrow("no return at end of a typed function - compiler is broken")
}

func throwinit() {
	gothrow("recursive call during initialization - linker skew")
}

// Create a new deferred function fn with siz bytes of arguments.
// The compiler turns a defer statement into a call to this.
//go:nosplit
func deferproc(siz int32, fn *funcval) { // arguments of fn follow fn
	// the arguments of fn are in a perilous state.  The stack map
	// for deferproc does not describe them.  So we can't let garbage
	// collection or stack copying trigger until we've copied them out
	// to somewhere safe.  deferproc_m does that.  Until deferproc_m,
	// we can only call nosplit routines.
	argp := uintptr(unsafe.Pointer(&fn))
	argp += unsafe.Sizeof(fn)
	if GOARCH == "arm" {
		argp += ptrSize // skip caller's saved link register
	}
	mp := acquirem()
	mp.scalararg[0] = uintptr(siz)
	mp.ptrarg[0] = unsafe.Pointer(fn)
	mp.scalararg[1] = argp
	mp.scalararg[2] = getcallerpc(unsafe.Pointer(&siz))

	if mp.curg != getg() {
		// go code on the m stack can't defer
		gothrow("defer on m")
	}

	onM(deferproc_m)

	releasem(mp)

	// deferproc returns 0 normally.
	// a deferred func that stops a panic
	// makes the deferproc return 1.
	// the code the compiler generates always
	// checks the return value and jumps to the
	// end of the function if deferproc returns != 0.
	return0()
	// No code can go here - the C return register has
	// been set and must not be clobbered.
}

// Each P holds pool for defers with arg sizes 8, 24, 40, 56 and 72 bytes.
// Memory block is 40 (24 for 32 bits) bytes larger due to Defer header.
// This maps exactly to malloc size classes.

// defer size class for arg size sz
func deferclass(siz uintptr) uintptr {
	return (siz + 7) >> 4
}

// total size of memory block for defer with arg size sz
func totaldefersize(siz uintptr) uintptr {
	return (unsafe.Sizeof(_defer{}) - unsafe.Sizeof(_defer{}.args)) + round(siz, ptrSize)
}

// Ensure that defer arg sizes that map to the same defer size class
// also map to the same malloc size class.
func testdefersizes() {
	var m [len(p{}.deferpool)]int32

	for i := range m {
		m[i] = -1
	}
	for i := uintptr(0); ; i++ {
		defersc := deferclass(i)
		if defersc >= uintptr(len(m)) {
			break
		}
		siz := goroundupsize(totaldefersize(i))
		if m[defersc] < 0 {
			m[defersc] = int32(siz)
			continue
		}
		if m[defersc] != int32(siz) {
			print("bad defer size class: i=", i, " siz=", siz, " defersc=", defersc, "\n")
			gothrow("bad defer size class")
		}
	}
}

// Allocate a Defer, usually using per-P pool.
// Each defer must be released with freedefer.
// Note: runs on M stack
func newdefer(siz int32) *_defer {
	var d *_defer
	sc := deferclass(uintptr(siz))
	mp := acquirem()
	if sc < uintptr(len(p{}.deferpool)) {
		pp := mp.p
		d = pp.deferpool[sc]
		if d != nil {
			pp.deferpool[sc] = d.link
		}
	}
	if d == nil {
		// deferpool is empty or just a big defer
		total := goroundupsize(totaldefersize(uintptr(siz)))
		d = (*_defer)(gomallocgc(total, conservative, 0))
	}
	d.siz = siz
	d.special = false
	gp := mp.curg
	d.link = gp._defer
	gp._defer = d
	releasem(mp)
	return d
}

// Free the given defer.
// The defer cannot be used after this call.
func freedefer(d *_defer) {
	if d.special {
		return
	}
	sc := deferclass(uintptr(d.siz))
	if sc < uintptr(len(p{}.deferpool)) {
		mp := acquirem()
		pp := mp.p
		d.link = pp.deferpool[sc]
		pp.deferpool[sc] = d
		releasem(mp)
		// No need to wipe out pointers in argp/pc/fn/args,
		// because we empty the pool before GC.
	}
}

// Run a deferred function if there is one.
// The compiler inserts a call to this at the end of any
// function which calls defer.
// If there is a deferred function, this will call runtime·jmpdefer,
// which will jump to the deferred function such that it appears
// to have been called by the caller of deferreturn at the point
// just before deferreturn was called.  The effect is that deferreturn
// is called again and again until there are no more deferred functions.
// Cannot split the stack because we reuse the caller's frame to
// call the deferred function.

// The single argument isn't actually used - it just has its address
// taken so it can be matched against pending defers.
//go:nosplit
func deferreturn(arg0 uintptr) {
	gp := getg()
	d := gp._defer
	if d == nil {
		return
	}
	argp := uintptr(unsafe.Pointer(&arg0))
	if d.argp != argp {
		return
	}

	// Moving arguments around.
	// Do not allow preemption here, because the garbage collector
	// won't know the form of the arguments until the jmpdefer can
	// flip the PC over to fn.
	mp := acquirem()
	memmove(unsafe.Pointer(argp), unsafe.Pointer(&d.args), uintptr(d.siz))
	fn := d.fn
	gp._defer = d.link
	freedefer(d)
	releasem(mp)
	jmpdefer(fn, argp)
}

// Goexit terminates the goroutine that calls it.  No other goroutine is affected.
// Goexit runs all deferred calls before terminating the goroutine.
//
// Calling Goexit from the main goroutine terminates that goroutine
// without func main returning. Since func main has not returned,
// the program continues execution of other goroutines.
// If all other goroutines exit, the program crashes.
func Goexit() {
	// Run all deferred functions for the current goroutine.
	gp := getg()
	for gp._defer != nil {
		d := gp._defer
		gp._defer = d.link
		reflectcall(unsafe.Pointer(d.fn), unsafe.Pointer(&d.args), uint32(d.siz), uint32(d.siz))
		freedefer(d)
		// Note: we ignore recovers here because Goexit isn't a panic
	}
	goexit()
}

func canpanic(*g) bool

// Print all currently active panics.  Used when crashing.
func printpanics(p *_panic) {
	if p.link != nil {
		printpanics(p.link)
		print("\t")
	}
	print("panic: ")
	printany(p.arg)
	if p.recovered {
		print(" [recovered]")
	}
	print("\n")
}

// The implementation of the predeclared function panic.
func gopanic(e interface{}) {
	gp := getg()
	if gp.m.curg != gp {
		gothrow("panic on m stack")
	}
	var p _panic
	var dabort _defer
	p.arg = e
	p.link = gp._panic
	gp._panic = (*_panic)(noescape(unsafe.Pointer(&p)))

	fn := abortpanic
	dabort.fn = *(**funcval)(unsafe.Pointer(&fn))
	dabort.siz = ptrSize
	dabort.args[0] = noescape((unsafe.Pointer)(&p)) // TODO(khr): why do I need noescape here?
	dabort.argp = _NoArgs
	dabort.special = true

	for {
		d := gp._defer
		if d == nil {
			break
		}
		// take defer off list in case of recursive panic
		gp._defer = d.link
		argp := unsafe.Pointer(d.argp) // must be pointer so it gets adjusted during stack copy
		pc := d.pc

		// The deferred function may cause another panic,
		// so reflectcall may not return. Set up a defer
		// to mark this panic aborted if that happens.
		dabort.link = gp._defer
		gp._defer = (*_defer)(noescape(unsafe.Pointer(&dabort)))
		p._defer = d

		p.argp = getargp(0)
		reflectcall(unsafe.Pointer(d.fn), unsafe.Pointer(&d.args), uint32(d.siz), uint32(d.siz))
		p.argp = 0

		// reflectcall did not panic. Remove dabort.
		if gp._defer != &dabort {
			gothrow("bad defer entry in panic")
		}
		gp._defer = dabort.link

		// trigger shrinkage to test stack copy.  See stack_test.go:TestStackPanic
		//GC()

		freedefer(d)
		if p.recovered {
			gp._panic = p.link
			// Aborted panics are marked but remain on the g.panic list.
			// Remove them from the list and free the associated defers.
			for gp._panic != nil && gp._panic.aborted {
				freedefer(gp._panic._defer)
				gp._panic = gp._panic.link
			}
			if gp._panic == nil { // must be done with signal
				gp.sig = 0
			}
			// Pass information about recovering frame to recovery.
			gp.sigcode0 = uintptr(argp)
			gp.sigcode1 = pc
			mcall(recovery_m)
			gothrow("recovery failed") // mcall should not return
		}
	}

	// ran out of deferred calls - old-school panic now
	startpanic()
	printpanics(gp._panic)
	dopanic(0)       // should not return
	*(*int)(nil) = 0 // not reached
}

// getargp returns the location where the caller
// writes outgoing function call arguments.
//go:nosplit
func getargp(x int) uintptr {
	// x is an argument mainly so that we can return its address.
	// However, we need to make the function complex enough
	// that it won't be inlined. We always pass x = 0, so this code
	// does nothing other than keep the compiler from thinking
	// the function is simple enough to inline.
	if x > 0 {
		return getcallersp(unsafe.Pointer(&x)) * 0
	}
	return uintptr(noescape(unsafe.Pointer(&x)))
}

func abortpanic(p *_panic) {
	p.aborted = true
}

// The implementation of the predeclared function recover.
// Cannot split the stack because it needs to reliably
// find the stack segment of its caller.
//
// TODO(rsc): Once we commit to CopyStackAlways,
// this doesn't need to be nosplit.
//go:nosplit
func gorecover(argp uintptr) interface{} {
	// Must be in a function running as part of a deferred call during the panic.
	// Must be called from the topmost function of the call
	// (the function used in the defer statement).
	// p.argp is the argument pointer of that topmost deferred function call.
	// Compare against argp reported by caller.
	// If they match, the caller is the one who can recover.
	gp := getg()
	p := gp._panic
	if p != nil && !p.recovered && argp == p.argp {
		p.recovered = true
		return p.arg
	}
	return nil
}

//go:nosplit
func startpanic() {
	onM(startpanic_m)
}

//go:nosplit
func dopanic(unused int) {
	gp := getg()
	mp := acquirem()
	mp.ptrarg[0] = unsafe.Pointer(gp)
	mp.scalararg[0] = getcallerpc((unsafe.Pointer)(&unused))
	mp.scalararg[1] = getcallersp((unsafe.Pointer)(&unused))
	onM(dopanic_m) // should never return
	*(*int)(nil) = 0
}

//go:nosplit
func throw(s *byte) {
	gp := getg()
	if gp.m.throwing == 0 {
		gp.m.throwing = 1
	}
	startpanic()
	print("fatal error: ", gostringnocopy(s), "\n")
	dopanic(0)
	*(*int)(nil) = 0 // not reached
}

//go:nosplit
func gothrow(s string) {
	gp := getg()
	if gp.m.throwing == 0 {
		gp.m.throwing = 1
	}
	startpanic()
	print("fatal error: ", s, "\n")
	dopanic(0)
	*(*int)(nil) = 0 // not reached
}

func panicstring(s *int8) {
	// m.softfloat is set during software floating point,
	// which might cause a fault during a memory load.
	// It increments m.locks to avoid preemption.
	// If we're panicking, the software floating point frames
	// will be unwound, so decrement m.locks as they would.
	gp := getg()
	if gp.m.softfloat != 0 {
		gp.m.locks--
		gp.m.softfloat = 0
	}

	if gp.m.mallocing != 0 {
		print("panic: ", s, "\n")
		gothrow("panic during malloc")
	}
	if gp.m.gcing != 0 {
		print("panic: ", s, "\n")
		gothrow("panic during gc")
	}
	if gp.m.locks != 0 {
		print("panic: ", s, "\n")
		gothrow("panic holding locks")
	}

	var err interface{}
	newErrorCString(unsafe.Pointer(s), &err)
	gopanic(err)
}
<commit_msg>runtime: mark freedefer and deferclass go:nosplit<commit_after>// Copyright 2014 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 runtime

import "unsafe"

var indexError = error(errorString("index out of range"))

func panicindex() {
	panic(indexError)
}

var sliceError = error(errorString("slice bounds out of range"))

func panicslice() {
	panic(sliceError)
}

var divideError = error(errorString("integer divide by zero"))

func panicdivide() {
	panic(divideError)
}

var overflowError = error(errorString("integer overflow"))

func panicoverflow() {
	panic(overflowError)
}

var floatError = error(errorString("floating point error"))

func panicfloat() {
	panic(floatError)
}

var memoryError = error(errorString("invalid memory address or nil pointer dereference"))

func panicmem() {
	panic(memoryError)
}

func throwreturn() {
	gothrow("no return at end of a typed function - compiler is broken")
}

func throwinit() {
	gothrow("recursive call during initialization - linker skew")
}

// Create a new deferred function fn with siz bytes of arguments.
// The compiler turns a defer statement into a call to this.
//go:nosplit
func deferproc(siz int32, fn *funcval) { // arguments of fn follow fn
	// the arguments of fn are in a perilous state.  The stack map
	// for deferproc does not describe them.  So we can't let garbage
	// collection or stack copying trigger until we've copied them out
	// to somewhere safe.  deferproc_m does that.  Until deferproc_m,
	// we can only call nosplit routines.
	argp := uintptr(unsafe.Pointer(&fn))
	argp += unsafe.Sizeof(fn)
	if GOARCH == "arm" {
		argp += ptrSize // skip caller's saved link register
	}
	mp := acquirem()
	mp.scalararg[0] = uintptr(siz)
	mp.ptrarg[0] = unsafe.Pointer(fn)
	mp.scalararg[1] = argp
	mp.scalararg[2] = getcallerpc(unsafe.Pointer(&siz))

	if mp.curg != getg() {
		// go code on the m stack can't defer
		gothrow("defer on m")
	}

	onM(deferproc_m)

	releasem(mp)

	// deferproc returns 0 normally.
	// a deferred func that stops a panic
	// makes the deferproc return 1.
	// the code the compiler generates always
	// checks the return value and jumps to the
	// end of the function if deferproc returns != 0.
	return0()
	// No code can go here - the C return register has
	// been set and must not be clobbered.
}

// Each P holds pool for defers with arg sizes 8, 24, 40, 56 and 72 bytes.
// Memory block is 40 (24 for 32 bits) bytes larger due to Defer header.
// This maps exactly to malloc size classes.

// defer size class for arg size sz
//go:nosplit
func deferclass(siz uintptr) uintptr {
	return (siz + 7) >> 4
}

// total size of memory block for defer with arg size sz
func totaldefersize(siz uintptr) uintptr {
	return (unsafe.Sizeof(_defer{}) - unsafe.Sizeof(_defer{}.args)) + round(siz, ptrSize)
}

// Ensure that defer arg sizes that map to the same defer size class
// also map to the same malloc size class.
func testdefersizes() {
	var m [len(p{}.deferpool)]int32

	for i := range m {
		m[i] = -1
	}
	for i := uintptr(0); ; i++ {
		defersc := deferclass(i)
		if defersc >= uintptr(len(m)) {
			break
		}
		siz := goroundupsize(totaldefersize(i))
		if m[defersc] < 0 {
			m[defersc] = int32(siz)
			continue
		}
		if m[defersc] != int32(siz) {
			print("bad defer size class: i=", i, " siz=", siz, " defersc=", defersc, "\n")
			gothrow("bad defer size class")
		}
	}
}

// Allocate a Defer, usually using per-P pool.
// Each defer must be released with freedefer.
// Note: runs on M stack
func newdefer(siz int32) *_defer {
	var d *_defer
	sc := deferclass(uintptr(siz))
	mp := acquirem()
	if sc < uintptr(len(p{}.deferpool)) {
		pp := mp.p
		d = pp.deferpool[sc]
		if d != nil {
			pp.deferpool[sc] = d.link
		}
	}
	if d == nil {
		// deferpool is empty or just a big defer
		total := goroundupsize(totaldefersize(uintptr(siz)))
		d = (*_defer)(gomallocgc(total, conservative, 0))
	}
	d.siz = siz
	d.special = false
	gp := mp.curg
	d.link = gp._defer
	gp._defer = d
	releasem(mp)
	return d
}

// Free the given defer.
// The defer cannot be used after this call.
//go:nosplit
func freedefer(d *_defer) {
	if d.special {
		return
	}
	sc := deferclass(uintptr(d.siz))
	if sc < uintptr(len(p{}.deferpool)) {
		mp := acquirem()
		pp := mp.p
		d.link = pp.deferpool[sc]
		pp.deferpool[sc] = d
		releasem(mp)
		// No need to wipe out pointers in argp/pc/fn/args,
		// because we empty the pool before GC.
	}
}

// Run a deferred function if there is one.
// The compiler inserts a call to this at the end of any
// function which calls defer.
// If there is a deferred function, this will call runtime·jmpdefer,
// which will jump to the deferred function such that it appears
// to have been called by the caller of deferreturn at the point
// just before deferreturn was called.  The effect is that deferreturn
// is called again and again until there are no more deferred functions.
// Cannot split the stack because we reuse the caller's frame to
// call the deferred function.

// The single argument isn't actually used - it just has its address
// taken so it can be matched against pending defers.
//go:nosplit
func deferreturn(arg0 uintptr) {
	gp := getg()
	d := gp._defer
	if d == nil {
		return
	}
	argp := uintptr(unsafe.Pointer(&arg0))
	if d.argp != argp {
		return
	}

	// Moving arguments around.
	// Do not allow preemption here, because the garbage collector
	// won't know the form of the arguments until the jmpdefer can
	// flip the PC over to fn.
	mp := acquirem()
	memmove(unsafe.Pointer(argp), unsafe.Pointer(&d.args), uintptr(d.siz))
	fn := d.fn
	gp._defer = d.link
	freedefer(d)
	releasem(mp)
	jmpdefer(fn, argp)
}

// Goexit terminates the goroutine that calls it.  No other goroutine is affected.
// Goexit runs all deferred calls before terminating the goroutine.
//
// Calling Goexit from the main goroutine terminates that goroutine
// without func main returning. Since func main has not returned,
// the program continues execution of other goroutines.
// If all other goroutines exit, the program crashes.
func Goexit() {
	// Run all deferred functions for the current goroutine.
	gp := getg()
	for gp._defer != nil {
		d := gp._defer
		gp._defer = d.link
		reflectcall(unsafe.Pointer(d.fn), unsafe.Pointer(&d.args), uint32(d.siz), uint32(d.siz))
		freedefer(d)
		// Note: we ignore recovers here because Goexit isn't a panic
	}
	goexit()
}

func canpanic(*g) bool

// Print all currently active panics.  Used when crashing.
func printpanics(p *_panic) {
	if p.link != nil {
		printpanics(p.link)
		print("\t")
	}
	print("panic: ")
	printany(p.arg)
	if p.recovered {
		print(" [recovered]")
	}
	print("\n")
}

// The implementation of the predeclared function panic.
func gopanic(e interface{}) {
	gp := getg()
	if gp.m.curg != gp {
		gothrow("panic on m stack")
	}
	var p _panic
	var dabort _defer
	p.arg = e
	p.link = gp._panic
	gp._panic = (*_panic)(noescape(unsafe.Pointer(&p)))

	fn := abortpanic
	dabort.fn = *(**funcval)(unsafe.Pointer(&fn))
	dabort.siz = ptrSize
	dabort.args[0] = noescape((unsafe.Pointer)(&p)) // TODO(khr): why do I need noescape here?
	dabort.argp = _NoArgs
	dabort.special = true

	for {
		d := gp._defer
		if d == nil {
			break
		}
		// take defer off list in case of recursive panic
		gp._defer = d.link
		argp := unsafe.Pointer(d.argp) // must be pointer so it gets adjusted during stack copy
		pc := d.pc

		// The deferred function may cause another panic,
		// so reflectcall may not return. Set up a defer
		// to mark this panic aborted if that happens.
		dabort.link = gp._defer
		gp._defer = (*_defer)(noescape(unsafe.Pointer(&dabort)))
		p._defer = d

		p.argp = getargp(0)
		reflectcall(unsafe.Pointer(d.fn), unsafe.Pointer(&d.args), uint32(d.siz), uint32(d.siz))
		p.argp = 0

		// reflectcall did not panic. Remove dabort.
		if gp._defer != &dabort {
			gothrow("bad defer entry in panic")
		}
		gp._defer = dabort.link

		// trigger shrinkage to test stack copy.  See stack_test.go:TestStackPanic
		//GC()

		freedefer(d)
		if p.recovered {
			gp._panic = p.link
			// Aborted panics are marked but remain on the g.panic list.
			// Remove them from the list and free the associated defers.
			for gp._panic != nil && gp._panic.aborted {
				freedefer(gp._panic._defer)
				gp._panic = gp._panic.link
			}
			if gp._panic == nil { // must be done with signal
				gp.sig = 0
			}
			// Pass information about recovering frame to recovery.
			gp.sigcode0 = uintptr(argp)
			gp.sigcode1 = pc
			mcall(recovery_m)
			gothrow("recovery failed") // mcall should not return
		}
	}

	// ran out of deferred calls - old-school panic now
	startpanic()
	printpanics(gp._panic)
	dopanic(0)       // should not return
	*(*int)(nil) = 0 // not reached
}

// getargp returns the location where the caller
// writes outgoing function call arguments.
//go:nosplit
func getargp(x int) uintptr {
	// x is an argument mainly so that we can return its address.
	// However, we need to make the function complex enough
	// that it won't be inlined. We always pass x = 0, so this code
	// does nothing other than keep the compiler from thinking
	// the function is simple enough to inline.
	if x > 0 {
		return getcallersp(unsafe.Pointer(&x)) * 0
	}
	return uintptr(noescape(unsafe.Pointer(&x)))
}

func abortpanic(p *_panic) {
	p.aborted = true
}

// The implementation of the predeclared function recover.
// Cannot split the stack because it needs to reliably
// find the stack segment of its caller.
//
// TODO(rsc): Once we commit to CopyStackAlways,
// this doesn't need to be nosplit.
//go:nosplit
func gorecover(argp uintptr) interface{} {
	// Must be in a function running as part of a deferred call during the panic.
	// Must be called from the topmost function of the call
	// (the function used in the defer statement).
	// p.argp is the argument pointer of that topmost deferred function call.
	// Compare against argp reported by caller.
	// If they match, the caller is the one who can recover.
	gp := getg()
	p := gp._panic
	if p != nil && !p.recovered && argp == p.argp {
		p.recovered = true
		return p.arg
	}
	return nil
}

//go:nosplit
func startpanic() {
	onM(startpanic_m)
}

//go:nosplit
func dopanic(unused int) {
	gp := getg()
	mp := acquirem()
	mp.ptrarg[0] = unsafe.Pointer(gp)
	mp.scalararg[0] = getcallerpc((unsafe.Pointer)(&unused))
	mp.scalararg[1] = getcallersp((unsafe.Pointer)(&unused))
	onM(dopanic_m) // should never return
	*(*int)(nil) = 0
}

//go:nosplit
func throw(s *byte) {
	gp := getg()
	if gp.m.throwing == 0 {
		gp.m.throwing = 1
	}
	startpanic()
	print("fatal error: ", gostringnocopy(s), "\n")
	dopanic(0)
	*(*int)(nil) = 0 // not reached
}

//go:nosplit
func gothrow(s string) {
	gp := getg()
	if gp.m.throwing == 0 {
		gp.m.throwing = 1
	}
	startpanic()
	print("fatal error: ", s, "\n")
	dopanic(0)
	*(*int)(nil) = 0 // not reached
}

func panicstring(s *int8) {
	// m.softfloat is set during software floating point,
	// which might cause a fault during a memory load.
	// It increments m.locks to avoid preemption.
	// If we're panicking, the software floating point frames
	// will be unwound, so decrement m.locks as they would.
	gp := getg()
	if gp.m.softfloat != 0 {
		gp.m.locks--
		gp.m.softfloat = 0
	}

	if gp.m.mallocing != 0 {
		print("panic: ", s, "\n")
		gothrow("panic during malloc")
	}
	if gp.m.gcing != 0 {
		print("panic: ", s, "\n")
		gothrow("panic during gc")
	}
	if gp.m.locks != 0 {
		print("panic: ", s, "\n")
		gothrow("panic holding locks")
	}

	var err interface{}
	newErrorCString(unsafe.Pointer(s), &err)
	gopanic(err)
}
<|endoftext|>


<commit_before>package main

import (
    "fmt"
    "net/http"
    "encoding/json"
    "golang.org/x/net/websocket"
)

type UserInfo struct {
    Hostname string
    Port     int
    Username string
    Password string
}

func handler(socket *websocket.Conn) {
    fmt.Println("- - - - - - - - - - - - - - - - - -")
    fmt.Println("Client has connected to the server!")

    var msg = make([]byte, 512)
    _, _ = socket.Read(msg)
    fmt.Println(string(msg))

    var data = make([]byte, 512)
    _, _ = socket.Read(data)
    var auth UserInfo
    err := json.Unmarshal(data, auth)
    if err != nil {
        fmt.Println("Error decoding json: ", err)
    }
}

func main() {
    http.Handle("/connect", websocket.Handler(handler))
    http.Handle("/", http.FileServer(http.Dir("../../")))
    http.ListenAndServe("localhost:1337", nil)
}
<commit_msg>Globally mapped key values to specific functions to determine ui actions and resolved json parsing issues<commit_after>package main

import (
    "fmt"
    "net/http"
    "encoding/json"
    "golang.org/x/net/websocket"

    // "github.com/askwon/Filet-Manager/sftp"
)

// Parse a json string into a hashmap
func parse(jsonStr string) (map[string]string) {
    obj := make(map[string]string)

    err := json.Unmarshal([]byte(jsonStr), &obj)
    if err != nil {
        panic(err)
    }

    return obj
}

// Simply print contents of a json map
func printJSON(json map[string]string) {
    for i := range json {
        fmt.Println(i, ":", json[i])
    }
}

// Start the sftp connection
func sftpConnect(data string) {
    auth := parse(data)
    printJSON(auth)
}

// Map of functions to determine ui actions
var fxns = map[string]func(data string) {
    "sftpConnect"   : sftpConnect,
}

func handler(socket *websocket.Conn) {
    fmt.Println("- - - - - - - - - - - - - - - - - -")
    fmt.Println("Client has connected to the server!")

    // Read the message that a client was connected
    var msg = make([]byte, 512)
    _, _ = socket.Read(msg)
    fmt.Println(string(msg))

    for {
	    // Receive the sftp auth information and store in a map
        data := make(map[string]string)
	    websocket.JSON.Receive(socket, &data)
	    if(len(data) != 0) {
	        fmt.Println("Received data from the client:")
            fxns[data["key"]](data["data"])
	    }
    }
}

func main() {
    http.Handle("/connect", websocket.Handler(handler))
    http.Handle("/", http.FileServer(http.Dir("../../")))
    http.ListenAndServe("localhost:1337", nil)
}
<|endoftext|>


<commit_before>package tutum

import "encoding/json"

type SListResponse struct {
	Objects []Service `json: "objects"`
}

type Service struct {
	Autodestroy            string    `json:"autodestroy"`
	Autoreplace            string    `json:"autoreplace"`
	Autoredeploy           bool      `json:"autoredeploy"`
	Autorestart            string    `json:"autorestart"`
	Containers             []string  `json:"containers"`
	Container_ports        []SCPInfo `json:"container_ports"`
	Container_size         string    `json:"container_size"`
	Current_num_containers int       `json:"current_num_containers"`
	Deployed_datetime      string    `json:"deployed_datetime"`
	Destroyed_datetime     string    `json:"destroyed_datetime"`
	Entrypoint             string    `json:"entrypoint"`
	Exit_code              int       `json:"exit_code"`
	Exit_code_message      string    `json:"exit_code_message"`
	Image_name             string    `json:"image_name"`
	Image_tag              string    `json:"image_tag"`
	Name                   string    `json:"name"`
	Public_dns             string    `json:"public_dns"`
	Resource_uri           string    `json:"resource_uri"`
	Run_command            string    `json:"run_command"`
	Started_datetime       string    `json:"started_datetime"`
	State                  string    `json:"state"`
	Stack                  string    `json:"stack"`
	Stopped_datetime       string    `json:"stopped_datetime"`
	Unique_name            string    `json:"unique_name"`
	Uuid                   string    `json:"uuid"`
}

type SCPInfo struct {
	Container  string `json:"container"`
	Inner_port int    `json:"inner_port"`
	Outer_port int    `json:"outer_port"`
	Protocol   string `json:"protocol"`
}

func ListServices() ([]Service, error) {
	url := "service/"
	request := "GET"

	var response SListResponse
	data, err := TutumCall(url, request)
	if err != nil {
		return nil, err
	}
	err = json.Unmarshal(data, &response)
	if err != nil {
		return nil, err
	}
	return response.Objects, nil

}

func GetService(uuid string) (Service, error) {

	url := "service/" + uuid + "/"
	request := "GET"

	var response Service

	data, err := TutumCall(url, request)
	if err != nil {
		panic(err)
	}

	err = json.Unmarshal(data, &response)
	if err != nil {
		panic(err)
	}

	return response, nil

}
<commit_msg>add log support for services<commit_after>package tutum

import "encoding/json"

type SListResponse struct {
	Objects []Service `json: "objects"`
}

type Service struct {
	Autodestroy            string       `json:"autodestroy"`
	Autoreplace            string       `json:"autoreplace"`
	Autoredeploy           bool         `json:"autoredeploy"`
	Autorestart            string       `json:"autorestart"`
	Containers             []string     `json:"containers"`
	Container_ports        []SCPInfo    `json:"container_ports"`
	Container_size         string       `json:"container_size"`
	Current_num_containers int          `json:"current_num_containers"`
	Deployed_datetime      string       `json:"deployed_datetime"`
	Destroyed_datetime     string       `json:"destroyed_datetime"`
	Entrypoint             string       `json:"entrypoint"`
	Exit_code              int          `json:"exit_code"`
	Exit_code_message      string       `json:"exit_code_message"`
	Image_name             string       `json:"image_name"`
	Image_tag              string       `json:"image_tag"`
	Linked_to_service      []LinkToInfo `json:"linked_to_service"`
	Name                   string       `json:"name"`
	Public_dns             string       `json:"public_dns"`
	Resource_uri           string       `json:"resource_uri"`
	Run_command            string       `json:"run_command"`
	Started_datetime       string       `json:"started_datetime"`
	State                  string       `json:"state"`
	Stack                  string       `json:"stack"`
	Stopped_datetime       string       `json:"stopped_datetime"`
	Target_num_containers  int          `json:"target_num_containers"`
	Unique_name            string       `json:"unique_name"`
	Uuid                   string       `json:"uuid"`
}

type SCPInfo struct {
	Container  string `json:"container"`
	Inner_port int    `json:"inner_port"`
	Outer_port int    `json:"outer_port"`
	Protocol   string `json:"protocol"`
}

type LinkToInfo struct {
	From_service string `json:"from_service"`
	Name         string `json:"name"`
	To_service   string `json:"to_service"`
}

type BasicService struct {
	Image                 string `json:"image"`
	Name                  string `json:"name"`
	Target_num_containers int    `json:"target_num_containers"`
}

func ListServices() ([]Service, error) {
	url := "service/"
	request := "GET"

	var response SListResponse
	data, err := TutumCall(url, request)
	if err != nil {
		return nil, err
	}
	err = json.Unmarshal(data, &response)
	if err != nil {
		return nil, err
	}
	return response.Objects, nil

}

func GetService(uuid string) (Service, error) {

	url := "service/" + uuid + "/"
	request := "GET"

	var response Service

	data, err := TutumCall(url, request)
	if err != nil {
		panic(err)
	}

	err = json.Unmarshal(data, &response)
	if err != nil {
		panic(err)
	}

	return response, nil

}

func CreateService(newService BasicService) (Service, error) {

	/*url := "service/"
	request := "POST"*/
	//TUTUM CALL WITH BYTE BODY REQUEST
	var response Service

	return response, nil

}

func GetServiceLogs(uuid string) (string, error) {

	url := "service/" + uuid + "/logs/"
	request := "GET"

	data, err := TutumCall(url, request)
	if err != nil {
		return "", err
	}

	s := string(data)

	return s, nil

}
<|endoftext|>


<commit_before>// Copyright 2014 Google Inc. All rights reserved.
//
// 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 bootstrap

import (
	"runtime"

	"github.com/google/blueprint"
)

func bootstrapVariable(name string, value func() string) blueprint.Variable {
	return pctx.VariableFunc(name, func(config interface{}) (string, error) {
		return value(), nil
	})
}

var (
	// These variables are the only configuration needed by the boostrap
	// modules.
	srcDir = bootstrapVariable("srcDir", func() string {
		return SrcDir
	})
	buildDir = bootstrapVariable("buildDir", func() string {
		return BuildDir
	})
	ninjaBuildDir = bootstrapVariable("ninjaBuildDir", func() string {
		return NinjaBuildDir
	})
	goRoot = bootstrapVariable("goRoot", func() string {
		return runtime.GOROOT()
	})
	compileCmd = bootstrapVariable("compileCmd", func() string {
		return "$goRoot/pkg/tool/" + runtime.GOOS + "_" + runtime.GOARCH + "/compile"
	})
	linkCmd = bootstrapVariable("linkCmd", func() string {
		return "$goRoot/pkg/tool/" + runtime.GOOS + "_" + runtime.GOARCH + "/link"
	})
)

type ConfigInterface interface {
	// GeneratingPrimaryBuilder should return true if this build invocation is
	// creating a .bootstrap/build.ninja file to be used to build the
	// primary builder
	GeneratingPrimaryBuilder() bool
}

type ConfigRemoveAbandonedFilesUnder interface {
	// RemoveAbandonedFilesUnder should return a slice of path prefixes that
	// will be cleaned of files that are no longer active targets, but are
	// listed in the .ninja_log.
	RemoveAbandonedFilesUnder() []string
}

type ConfigBlueprintToolLocation interface {
	// BlueprintToolLocation can return a path name to install blueprint tools
	// designed for end users (bpfmt, bpmodify, and anything else using
	// blueprint_go_binary).
	BlueprintToolLocation() string
}

type StopBefore int

const (
	StopBeforePrepareBuildActions StopBefore = 1
)

type ConfigStopBefore interface {
	StopBefore() StopBefore
}

type Stage int

const (
	StagePrimary Stage = iota
	StageMain
)

type Config struct {
	stage Stage

	topLevelBlueprintsFile string

	runGoTests     bool
	moduleListFile string
}
<commit_msg>Try to make GOROOT relative in Go 1.10<commit_after>// Copyright 2014 Google Inc. All rights reserved.
//
// 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 bootstrap

import (
	"os"
	"path/filepath"
	"runtime"
	"strings"

	"github.com/google/blueprint"
)

func bootstrapVariable(name string, value func() string) blueprint.Variable {
	return pctx.VariableFunc(name, func(config interface{}) (string, error) {
		return value(), nil
	})
}

var (
	// These variables are the only configuration needed by the boostrap
	// modules.
	srcDir = bootstrapVariable("srcDir", func() string {
		return SrcDir
	})
	buildDir = bootstrapVariable("buildDir", func() string {
		return BuildDir
	})
	ninjaBuildDir = bootstrapVariable("ninjaBuildDir", func() string {
		return NinjaBuildDir
	})
	goRoot = bootstrapVariable("goRoot", func() string {
		goroot := runtime.GOROOT()
		// Prefer to omit absolute paths from the ninja file
		if cwd, err := os.Getwd(); err == nil {
			if relpath, err := filepath.Rel(cwd, goroot); err == nil {
				if !strings.HasPrefix(relpath, "../") {
					goroot = relpath
				}
			}
		}
		return goroot
	})
	compileCmd = bootstrapVariable("compileCmd", func() string {
		return "$goRoot/pkg/tool/" + runtime.GOOS + "_" + runtime.GOARCH + "/compile"
	})
	linkCmd = bootstrapVariable("linkCmd", func() string {
		return "$goRoot/pkg/tool/" + runtime.GOOS + "_" + runtime.GOARCH + "/link"
	})
)

type ConfigInterface interface {
	// GeneratingPrimaryBuilder should return true if this build invocation is
	// creating a .bootstrap/build.ninja file to be used to build the
	// primary builder
	GeneratingPrimaryBuilder() bool
}

type ConfigRemoveAbandonedFilesUnder interface {
	// RemoveAbandonedFilesUnder should return a slice of path prefixes that
	// will be cleaned of files that are no longer active targets, but are
	// listed in the .ninja_log.
	RemoveAbandonedFilesUnder() []string
}

type ConfigBlueprintToolLocation interface {
	// BlueprintToolLocation can return a path name to install blueprint tools
	// designed for end users (bpfmt, bpmodify, and anything else using
	// blueprint_go_binary).
	BlueprintToolLocation() string
}

type StopBefore int

const (
	StopBeforePrepareBuildActions StopBefore = 1
)

type ConfigStopBefore interface {
	StopBefore() StopBefore
}

type Stage int

const (
	StagePrimary Stage = iota
	StageMain
)

type Config struct {
	stage Stage

	topLevelBlueprintsFile string

	runGoTests     bool
	moduleListFile string
}
<|endoftext|>


<commit_before>package parser

import (
	"reflect"
	"testing"

	"github.com/chris-ramon/graphql-go/language/ast"
	"github.com/chris-ramon/graphql-go/language/od"
)

func TestAcceptsOptionToNotIncludeSource(t *testing.T) {
	opts := ParseOptions{
		NoSource: true,
	}
	params := ParseParams{
		Source:  "{ field }",
		Options: opts,
	}
	document, err := Parse(params)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	oDef := od.OperationDefinition{
		Kind: "OperationDefinition",
		Loc: ast.Location{
			Start: 0, End: 9,
		},
		Operation:  "query",
		Directives: []ast.Directive{},
		SelectionSet: ast.SelectionSet{
			Kind: "SelectionSet",
			Loc: ast.Location{
				Start: 0, End: 9,
			},
			Selections: []interface{}{
				ast.Field{
					Kind: "Field",
					Loc: ast.Location{
						Start: 2, End: 7,
					},
					Name: ast.Name{
						Kind: "Name",
						Loc: ast.Location{
							Start: 2, End: 7,
						},
						Value: "field",
					},
					Arguments:  []ast.Argument{},
					Directives: []ast.Directive{},
				},
			},
		},
	}
	expectedDocument := ast.Document{
		Kind: "Document",
		Loc: ast.Location{
			Start: 0, End: 9,
		},
		Definitions: []ast.Definition{&oDef},
	}
	if !reflect.DeepEqual(document, expectedDocument) {
		t.Fatalf("unexpected document, expected: %v, got: %v", expectedDocument, document)
	}
}

func TestParseProvidesUsefulErrors(t *testing.T) {
	opts := ParseOptions{
		NoSource: true,
	}
	params := ParseParams{
		Source:  "{",
		Options: opts,
	}
	_, err := Parse(params)
	expectedError := `Syntax Error GraphQL (1:2) Expected Name, found EOF

1: {
    ^
`
	if err == nil {
		t.Fatalf("unexpected nil error\nexpected:\n%v\n\ngot:\n%v", expectedError, err)
	}
	if err.Error() != expectedError {
		t.Fatalf("unexpected error.\nexpected:\n%v\n\ngot:\n%v", expectedError, err.Error())
	}
}
<commit_msg>Unit tests for `parser` based on `graphql-js` parser tests.<commit_after>package parser

import (
	"reflect"
	"testing"

	"github.com/chris-ramon/graphql-go/errors"
	"github.com/chris-ramon/graphql-go/language/ast"
	"github.com/chris-ramon/graphql-go/language/location"
	"github.com/chris-ramon/graphql-go/language/od"
	"strings"
	"github.com/chris-ramon/graphql-go/language/source"
	"io/ioutil"
	"fmt"
)

func TestAcceptsOptionToNotIncludeSource(t *testing.T) {
	opts := ParseOptions{
		NoSource: true,
	}
	params := ParseParams{
		Source:  "{ field }",
		Options: opts,
	}
	document, err := Parse(params)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	oDef := od.OperationDefinition{
		Kind: "OperationDefinition",
		Loc: ast.Location{
			Start: 0, End: 9,
		},
		Operation:  "query",
		Directives: []ast.Directive{},
		SelectionSet: ast.SelectionSet{
			Kind: "SelectionSet",
			Loc: ast.Location{
				Start: 0, End: 9,
			},
			Selections: []interface{}{
				ast.Field{
					Kind: "Field",
					Loc: ast.Location{
						Start: 2, End: 7,
					},
					Name: ast.Name{
						Kind: "Name",
						Loc: ast.Location{
							Start: 2, End: 7,
						},
						Value: "field",
					},
					Arguments:  []ast.Argument{},
					Directives: []ast.Directive{},
				},
			},
		},
	}
	expectedDocument := ast.Document{
		Kind: "Document",
		Loc: ast.Location{
			Start: 0, End: 9,
		},
		Definitions: []ast.Definition{&oDef},
	}
	if !reflect.DeepEqual(document, expectedDocument) {
		t.Fatalf("unexpected document, expected: %v, got: %v", expectedDocument, document)
	}
}

func TestParseProvidesUsefulErrors(t *testing.T) {
	opts := ParseOptions{
		NoSource: true,
	}
	params := ParseParams{
		Source:  "{",
		Options: opts,
	}
	_, err := Parse(params)

	expectedError := &graphqlerrors.GraphQLError{
		Message: `Syntax Error GraphQL (1:2) Expected Name, found EOF

1: {
    ^
`,
		Positions: []int{1},
		Locations: []location.SourceLocation{{1, 2}},
	}
	checkGraphQLError(t, err, expectedError)

	testErrorMessagesTable := []errorMessageTest{
		{
			`{ ...MissingOn }
fragment MissingOn Type
`,
			`Syntax Error GraphQL (2:20) Expected "on", found Name "Type"`,
			false,
		},
		{
			`{ field: {} }`,
			`Syntax Error GraphQL (1:10) Expected Name, found {`,
			false,
		},
		{
			`notanoperation Foo { field }`,
			`Syntax Error GraphQL (1:1) Unexpected Name "notanoperation"`,
			false,
		},
		{
			"...",
			`Syntax Error GraphQL (1:1) Unexpected ...`,
			false,
		},
	}
	for _, test := range testErrorMessagesTable {
		if test.skipped != false {
			t.Skipf("Skipped test: %v", test.source)
		}
		_, err := Parse(ParseParams{Source: test.source})
		checkGraphQLErrorMessage(t, err, test.expectedMessage)
	}

}

func TestParseProvidesUsefulErrorsWhenUsingSource(t *testing.T) {
	test := errorMessageTest{
		source.NewSource("query", "MyQuery.graphql"),
		`Syntax Error MyQuery.graphql (1:6) Expected Name, found EOF`,
		false,
	}
	testGraphQLErrorMessage(t, test)
}

func TestParseVariableInlineValues(t *testing.T) {
	source := `{ field(complex: { a: { b: [ $var ] } }) }`
	// should not return error
	_, err := Parse(ParseParams{Source: source})
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
}

func TestParseConstantDefaultValues(t *testing.T) {
	test := errorMessageTest{
		`query Foo($x: Complex = { a: { b: [ $var ] } }) { field }`,
		`Syntax Error GraphQL (1:37) Unexpected $`,
		false,
	}
	testGraphQLErrorMessage(t, test)
}

func TestParseDuplicatedKeysInInputObject(t *testing.T) {
	test := errorMessageTest{
		`{ field(arg: { a: 1, a: 2 }) }'`,
		`Syntax Error GraphQL (1:22) Duplicate input object field a.`,
		false,
	}
	testGraphQLErrorMessage(t, test)
}

func TestParseFragmentsNameOn(t *testing.T) {
	test := errorMessageTest{
		`fragment on on on { on }`,
		`Syntax Error GraphQL (1:10) Unexpected Name "on"`,
		false,
	}
	testGraphQLErrorMessage(t, test)
}

func TestParseFragmentsSpreadOfOn(t *testing.T) {
	test := errorMessageTest{
		`{ ...on }'`,
		`Syntax Error GraphQL (1:9) Expected Name, found }`,
		false,
	}
	testGraphQLErrorMessage(t, test)
}

func TestParserDoesNotAllowNullAsValue(t *testing.T) {
	test := errorMessageTest{
		`{ fieldWithNullableStringInput(input: null) }'`,
		`Syntax Error GraphQL (1:39) Unexpected Name "null"`,
		false,
	}
	testGraphQLErrorMessage(t, test)
}

func TestParserParsesKitchenSink(t *testing.T) {
	b, err := ioutil.ReadFile("./kitchen-sink.graphql")
	if err != nil {
		t.Fatalf("unable to load kitchen-sink.graphql")
	}
	source := string(b)
	_, err = Parse(ParseParams{Source: source})
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
}

func TestParserAllowsNonKeywordsAnywhereNameIsAllowed(t *testing.T) {
	nonKeywords := []string{
		"on",
		"fragment",
		"query",
		"mutation",
		"true",
		"false",
	}
	for _, keyword := range nonKeywords {
		fragmentName := keyword
		// You can't define or reference a fragment named `on`.
		if keyword == "on" {
			fragmentName = "a"
		}
		source := fmt.Sprintf(`query %v {
			... %v
			... on %v { field }
		}
		fragment %v on Type {
		%v(%v: $%v) @%v(%v: $%v)
		}
		`, keyword, fragmentName, keyword, fragmentName, keyword, keyword, keyword, keyword, keyword, keyword)
		_, err := Parse(ParseParams{Source: source})
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
	}
}

func TestParserParsesExperimentalSubscriptionFeature(t *testing.T) {
	source := `
      subscription Foo {
        subscriptionField
      }
    `
	_, err := Parse(ParseParams{Source: source})
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
}

func TestParserCreatesAst(t *testing.T) {
	source := source.NewSource(`{
  node(id: 4) {
    id,
    name
  }
}
`, "")

	document, err := Parse(
		ParseParams{
			Source: source,
			Options: ParseOptions{
				NoSource: true,
			},
		},
	)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	oDef := od.OperationDefinition{
		Kind: "OperationDefinition",
		Loc: ast.Location{
			Start: 0, End: 40,
		},
		Operation:  "query",
		Directives: []ast.Directive{},
		SelectionSet: ast.SelectionSet{
			Kind: "SelectionSet",
			Loc: ast.Location{
				Start: 0, End: 40,
			},
			Selections: []interface{}{
				ast.Field{
					Kind: "Field",
					Loc: ast.Location{
						Start: 4, End: 38,
					},
					Name: ast.Name{
						Kind: "Name",
						Loc: ast.Location{
							Start: 4, End: 8,
						},
						Value: "node",
					},
					Arguments:  []ast.Argument{
						{
							Kind: "Argument",
							Name: ast.Name{
								Kind: "Name",
								Loc: ast.Location{
									Start: 9, End: 11,
								},
								Value: "id",
							},
							Value: ast.Name{// todo: incorrect value struct
								Kind: "IntValue",
								Loc: ast.Location{
									Start: 13, End: 14,
								},
								Value: "4",
							},
							Loc: ast.Location{
								Start: 9, End: 14,
							},
						},
					},
					Directives: []ast.Directive{},
					SelectionSet: ast.SelectionSet{
						Kind: "SelectionSet",
						Loc: ast.Location{
							Start: 16, End: 38,
						},
						Selections: []interface{}{
							ast.Field{
								Kind: "Field",
								Loc: ast.Location{
									Start: 22, End: 24,
								},
								Name: ast.Name{
									Kind: "Name",
									Loc: ast.Location{
										Start: 22, End: 24,
									},
									Value: "id",
								},
								Arguments:  []ast.Argument{},
								Directives: []ast.Directive{},
								SelectionSet: ast.SelectionSet{},
							},
							ast.Field{
								Kind: "Field",
								Loc: ast.Location{
									Start: 30, End: 34,
								},
								Name: ast.Name{
									Kind: "Name",
									Loc: ast.Location{
										Start: 30, End: 34,
									},
									Value: "name",
								},
								Arguments:  []ast.Argument{},
								Directives: []ast.Directive{},
								SelectionSet: ast.SelectionSet{},
							},
						},
					},
				},
			},
		},
	}
	expectedDocument := ast.Document{
		Kind: "Document",
		Loc: ast.Location{
			Start: 0, End: 41,
		},
		Definitions: []ast.Definition{&oDef},
	}
	if !reflect.DeepEqual(document, expectedDocument) {
		t.Fatalf("unexpected document, expected: %v, got: %v", expectedDocument, document)
	}

}
type errorMessageTest struct {
	source          interface{}
	expectedMessage string
	skipped         bool
}

func testGraphQLErrorMessage(t *testing.T, test errorMessageTest) {
	if test.skipped != false {
		t.Skipf("Skipped test: %v", test.source)
	}
	_, err := Parse(ParseParams{Source: test.source})
	checkGraphQLErrorMessage(t, err, test.expectedMessage)
}

func checkGraphQLError(t *testing.T, err error, expectedError *graphqlerrors.GraphQLError) {
	if expectedError == nil {
		if err != nil {
			t.Fatalf("unexpected error: %v", err)
		}
		return // ok
	}
	// else expectedError != nil
	if err == nil {
		t.Fatalf("unexpected nil error\nexpected:\n%v\n\ngot:\n%v", expectedError, err)
	}
	if err.Error() != expectedError.Message {
		t.Fatalf("unexpected error.\nexpected:\n%v\n\ngot:\n%v", expectedError, err.Error())
	}
	gErr := toGraphQLError(err)
	if gErr == nil {
		t.Fatalf("unexpected nil GraphQLError")
	}
	if len(expectedError.Positions) > 0 && !reflect.DeepEqual(gErr.Positions, expectedError.Positions) {
		t.Fatalf("unexpected GraphQLError.Positions.\nexpected:\n%v\n\ngot:\n%v", expectedError.Positions, gErr.Positions)
	}
	if len(expectedError.Locations) > 0 && !reflect.DeepEqual(gErr.Locations, expectedError.Locations) {
		t.Fatalf("unexpected GraphQLError.Locations.\nexpected:\n%v\n\ngot:\n%v", expectedError.Locations, gErr.Locations)
	}
}

func checkGraphQLErrorMessage(t *testing.T, err error, expectedMessage string) {
	if err == nil {
		t.Fatalf("unexpected nil error\nexpected:\n%v\n\ngot:\n%v", expectedMessage, err)
	}
	if err.Error() != expectedMessage {
		// only check first line of error message
		lines := strings.Split(err.Error(), "\n")
		if lines[0] != expectedMessage {
			t.Fatalf("unexpected error.\nexpected:\n%v\n\ngot:\n%v", expectedMessage, lines[0])
		}
	}
}

func toGraphQLError(err error) *graphqlerrors.GraphQLError {
	if err == nil {
		return nil
	}
	switch err := err.(type) {
	case *graphqlerrors.GraphQLError:
		return err
	default:
		return nil
	}
}
<|endoftext|>