<commit_before>package todolist

import (
	"fmt"
	"strconv"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
)

func TestParseSubject(t *testing.T) {
	parser := &Parser{}
	todo := parser.ParseNewTodo("do this thing")
	if todo.Subject != "do this thing" {
		t.Error("Expected todo.Subject to equal 'do this thing'")
	}
}

func TestParseSubjectWithDue(t *testing.T) {
	parser := &Parser{}
	todo := parser.ParseNewTodo("do this thing due tomorrow")
	if todo.Subject != "do this thing" {
		t.Error("Expected todo.Subject to equal 'do this thing', got ", todo.Subject)
	}
}

func TestParseExpandProjects(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	correctFormat := parser.ExpandProject("ex 113 +meeting: figures, slides, coffee, suger")
	assert.Equal("+meeting", correctFormat)
	wrongFormat1 := parser.ExpandProject("ex 114 +meeting figures, slides, coffee, suger")
	assert.Equal("", wrongFormat1)
	wrongFormat2 := parser.ExpandProject("ex 115 meeting: figures, slides, coffee, suger")
	assert.Equal("", wrongFormat2)
	wrongFormat3 := parser.ExpandProject("ex 116 meeting figures, slides, coffee, suger")
	assert.Equal("", wrongFormat3)
	wrongFormat4 := parser.ExpandProject("ex 117 +重要な會議: 図, コーヒー, 砂糖")
	assert.Equal("+重要な會議", wrongFormat4)
}

func TestParseProjects(t *testing.T) {
	parser := &Parser{}
	todo := parser.ParseNewTodo("do this thing +proj1 +proj2 +專案3 +proj-name due tomorrow")
	if len(todo.Projects) != 4 {
		t.Error("Expected Projects length to be 3")
	}
	if todo.Projects[0] != "proj1" {
		t.Error("todo.Projects[0] should equal 'proj1' but got", todo.Projects[0])
	}
	if todo.Projects[1] != "proj2" {
		t.Error("todo.Projects[1] should equal 'proj2' but got", todo.Projects[1])
	}
	if todo.Projects[2] != "專案3" {
		t.Error("todo.Projects[2] should equal '專案3' but got", todo.Projects[2])
	}
	if todo.Projects[3] != "proj-name" {
		t.Error("todo.Projects[3] should equal 'proj-name' but got", todo.Projects[3])
	}
}

func TestParseContexts(t *testing.T) {
	parser := &Parser{}
	todo := parser.ParseNewTodo("do this thing with @bob and @mary due tomorrow")
	if len(todo.Contexts) != 2 {
		t.Error("Expected Projects length to be 2")
	}
	if todo.Contexts[0] != "bob" {
		t.Error("todo.Contexts[0] should equal 'mary' but got", todo.Contexts[0])
	}
	if todo.Contexts[1] != "mary" {
		t.Error("todo.Contexts[1] should equal 'mary' but got", todo.Contexts[1])
	}
}

func TestDueToday(t *testing.T) {
	parser := &Parser{}
	todo := parser.ParseNewTodo("do this thing with @bob and @mary due today")
	if todo.Due != bod(time.Now()).Format("2006-01-02") {
		fmt.Println("Date is different", todo.Due, time.Now())
	}
	todo = parser.ParseNewTodo("do this thing with @bob and @mary due tod")
	if todo.Due != bod(time.Now()).Format("2006-01-02") {
		fmt.Println("Date is different", todo.Due, time.Now())
	}
}

func TestDueTomorrow(t *testing.T) {
	parser := &Parser{}
	todo := parser.ParseNewTodo("do this thing with @bob and @mary due tomorrow")
	if todo.Due != bod(time.Now()).AddDate(0, 0, 1).Format("2006-01-02") {
		fmt.Println("Date is different", todo.Due, time.Now())
	}
	todo = parser.ParseNewTodo("do this thing with @bob and @mary due tom")
	if todo.Due != bod(time.Now()).AddDate(0, 0, 1).Format("2006-01-02") {
		fmt.Println("Date is different", todo.Due, time.Now())
	}
}

func TestDueSpecific(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	todo := parser.ParseNewTodo("do this thing with @bob and @mary due jun 1")
	year := strconv.Itoa(time.Now().Year())
	assert.Equal(fmt.Sprintf("%s-06-01", year), todo.Due)
}

func TestMondayOnSunday(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	now, _ := time.Parse("2006-01-02", "2016-04-24")
	assert.Equal("2016-04-25", parser.monday(now))
}

func TestMondayOnMonday(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	now, _ := time.Parse("2006-01-02", "2016-04-25")
	assert.Equal("2016-04-25", parser.monday(now))
}

func TestMondayOnTuesday(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	now, _ := time.Parse("2006-01-02", "2016-04-26")
	assert.Equal("2016-05-02", parser.monday(now))
}

func TestTuesdayOnMonday(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	now, _ := time.Parse("2006-01-02", "2016-04-25")
	assert.Equal("2016-04-26", parser.tuesday(now))
}

func TestTuesdayOnWednesday(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	now, _ := time.Parse("2006-01-02", "2016-04-27")
	assert.Equal("2016-05-03", parser.tuesday(now))
}

func TestDueOnSpecificDate(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	year := strconv.Itoa(time.Now().Year())
	assert.Equal(fmt.Sprintf("%s-05-02", year), parser.Due("due may 2", time.Now()))
	assert.Equal(fmt.Sprintf("%s-06-01", year), parser.Due("due jun 1", time.Now()))
}

func TestDueOnSpecificDateEuropean(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	year := strconv.Itoa(time.Now().Year())
	assert.Equal(fmt.Sprintf("%s-05-02", year), parser.Due("due 2 may", time.Now()))
}

func TestDueIntelligentlyChoosesCorrectYear(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	marchTime, _ := time.Parse("2006-01-02", "2016-03-25")
	januaryTime, _ := time.Parse("2006-01-02", "2016-01-05")
	septemberTime, _ := time.Parse("2006-01-02", "2016-09-25")
	decemberTime, _ := time.Parse("2006-01-02", "2016-12-25")

	assert.Equal("2016-01-10", parser.parseArbitraryDate("jan 10", januaryTime))
	assert.Equal("2016-01-10", parser.parseArbitraryDate("jan 10", marchTime))
	assert.Equal("2017-01-10", parser.parseArbitraryDate("jan 10", septemberTime))
	assert.Equal("2017-01-10", parser.parseArbitraryDate("jan 10", decemberTime))
}

func TestParseCommandIdSubject(t *testing.T) {
	assert := assert.New(t)
	parser := Parser{"es 24 a new subject"}
	command, id, subject := parser.Parse()

	assert.Equal("es", command)
	assert.Equal(24, id)
	assert.Equal("a new subject", subject)
}

func TestParseInvalidCommandIdSubject(t *testing.T) {
	assert := assert.New(t)
	input := "es a new project"
	parser := Parser{input}
	command, id, subject := parser.Parse()

	assert.Equal("", command)
	assert.Equal(-1, id)
	assert.Equal(input, subject)
}
<commit_msg>no longer expecting 3 return values<commit_after>package todolist

import (
	"fmt"
	"strconv"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
)

func TestParseSubject(t *testing.T) {
	parser := &Parser{}
	todo := parser.ParseNewTodo("do this thing")
	if todo.Subject != "do this thing" {
		t.Error("Expected todo.Subject to equal 'do this thing'")
	}
}

func TestParseSubjectWithDue(t *testing.T) {
	parser := &Parser{}
	todo := parser.ParseNewTodo("do this thing due tomorrow")
	if todo.Subject != "do this thing" {
		t.Error("Expected todo.Subject to equal 'do this thing', got ", todo.Subject)
	}
}

func TestParseExpandProjects(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	correctFormat := parser.ExpandProject("ex 113 +meeting: figures, slides, coffee, suger")
	assert.Equal("+meeting", correctFormat)
	wrongFormat1 := parser.ExpandProject("ex 114 +meeting figures, slides, coffee, suger")
	assert.Equal("", wrongFormat1)
	wrongFormat2 := parser.ExpandProject("ex 115 meeting: figures, slides, coffee, suger")
	assert.Equal("", wrongFormat2)
	wrongFormat3 := parser.ExpandProject("ex 116 meeting figures, slides, coffee, suger")
	assert.Equal("", wrongFormat3)
	wrongFormat4 := parser.ExpandProject("ex 117 +重要な會議: 図, コーヒー, 砂糖")
	assert.Equal("+重要な會議", wrongFormat4)
}

func TestParseProjects(t *testing.T) {
	parser := &Parser{}
	todo := parser.ParseNewTodo("do this thing +proj1 +proj2 +專案3 +proj-name due tomorrow")
	if len(todo.Projects) != 4 {
		t.Error("Expected Projects length to be 3")
	}
	if todo.Projects[0] != "proj1" {
		t.Error("todo.Projects[0] should equal 'proj1' but got", todo.Projects[0])
	}
	if todo.Projects[1] != "proj2" {
		t.Error("todo.Projects[1] should equal 'proj2' but got", todo.Projects[1])
	}
	if todo.Projects[2] != "專案3" {
		t.Error("todo.Projects[2] should equal '專案3' but got", todo.Projects[2])
	}
	if todo.Projects[3] != "proj-name" {
		t.Error("todo.Projects[3] should equal 'proj-name' but got", todo.Projects[3])
	}
}

func TestParseContexts(t *testing.T) {
	parser := &Parser{}
	todo := parser.ParseNewTodo("do this thing with @bob and @mary due tomorrow")
	if len(todo.Contexts) != 2 {
		t.Error("Expected Projects length to be 2")
	}
	if todo.Contexts[0] != "bob" {
		t.Error("todo.Contexts[0] should equal 'mary' but got", todo.Contexts[0])
	}
	if todo.Contexts[1] != "mary" {
		t.Error("todo.Contexts[1] should equal 'mary' but got", todo.Contexts[1])
	}
}

func TestDueToday(t *testing.T) {
	parser := &Parser{}
	todo := parser.ParseNewTodo("do this thing with @bob and @mary due today")
	if todo.Due != bod(time.Now()).Format("2006-01-02") {
		fmt.Println("Date is different", todo.Due, time.Now())
	}
	todo = parser.ParseNewTodo("do this thing with @bob and @mary due tod")
	if todo.Due != bod(time.Now()).Format("2006-01-02") {
		fmt.Println("Date is different", todo.Due, time.Now())
	}
}

func TestDueTomorrow(t *testing.T) {
	parser := &Parser{}
	todo := parser.ParseNewTodo("do this thing with @bob and @mary due tomorrow")
	if todo.Due != bod(time.Now()).AddDate(0, 0, 1).Format("2006-01-02") {
		fmt.Println("Date is different", todo.Due, time.Now())
	}
	todo = parser.ParseNewTodo("do this thing with @bob and @mary due tom")
	if todo.Due != bod(time.Now()).AddDate(0, 0, 1).Format("2006-01-02") {
		fmt.Println("Date is different", todo.Due, time.Now())
	}
}

func TestDueSpecific(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	todo := parser.ParseNewTodo("do this thing with @bob and @mary due jun 1")
	year := strconv.Itoa(time.Now().Year())
	assert.Equal(fmt.Sprintf("%s-06-01", year), todo.Due)
}

func TestMondayOnSunday(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	now, _ := time.Parse("2006-01-02", "2016-04-24")
	assert.Equal("2016-04-25", parser.monday(now))
}

func TestMondayOnMonday(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	now, _ := time.Parse("2006-01-02", "2016-04-25")
	assert.Equal("2016-04-25", parser.monday(now))
}

func TestMondayOnTuesday(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	now, _ := time.Parse("2006-01-02", "2016-04-26")
	assert.Equal("2016-05-02", parser.monday(now))
}

func TestTuesdayOnMonday(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	now, _ := time.Parse("2006-01-02", "2016-04-25")
	assert.Equal("2016-04-26", parser.tuesday(now))
}

func TestTuesdayOnWednesday(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	now, _ := time.Parse("2006-01-02", "2016-04-27")
	assert.Equal("2016-05-03", parser.tuesday(now))
}

func TestDueOnSpecificDate(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	year := strconv.Itoa(time.Now().Year())
	assert.Equal(fmt.Sprintf("%s-05-02", year), parser.Due("due may 2", time.Now()))
	assert.Equal(fmt.Sprintf("%s-06-01", year), parser.Due("due jun 1", time.Now()))
}

func TestDueOnSpecificDateEuropean(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	year := strconv.Itoa(time.Now().Year())
	assert.Equal(fmt.Sprintf("%s-05-02", year), parser.Due("due 2 may", time.Now()))
}

func TestDueIntelligentlyChoosesCorrectYear(t *testing.T) {
	assert := assert.New(t)
	parser := &Parser{}
	marchTime, _ := time.Parse("2006-01-02", "2016-03-25")
	januaryTime, _ := time.Parse("2006-01-02", "2016-01-05")
	septemberTime, _ := time.Parse("2006-01-02", "2016-09-25")
	decemberTime, _ := time.Parse("2006-01-02", "2016-12-25")

	assert.Equal("2016-01-10", parser.parseArbitraryDate("jan 10", januaryTime))
	assert.Equal("2016-01-10", parser.parseArbitraryDate("jan 10", marchTime))
	assert.Equal("2017-01-10", parser.parseArbitraryDate("jan 10", septemberTime))
	assert.Equal("2017-01-10", parser.parseArbitraryDate("jan 10", decemberTime))
}

func TestParseCommandIdSubject(t *testing.T) {
	assert := assert.New(t)
	parser := Parser{"es 24 a new subject"}
	id, subject := parser.Parse()

	assert.Equal(24, id)
	assert.Equal("a new subject", subject)
}

func TestParseInvalidCommandIdSubject(t *testing.T) {
	assert := assert.New(t)
	input := "es a new project"
	parser := Parser{input}
	id, subject := parser.Parse()

	assert.Equal(-1, id)
	assert.Equal("", subject)
}
<|endoftext|>


<commit_before>package paxos

//
// Paxos library, to be included in an application.
// Multiple applications will run, each including
// a Paxos peer.
//
// Manages a sequence of agreed-on values.
// The set of peers is fixed.
// Copes with network failures (partition, msg loss, &c).
// Does not store anything persistently, so cannot handle crash+restart.
//
// The application interface:
//
// px = paxos.Make(peers []string, me string)
// px.Start(seq int, v interface{}) -- start agreement on new instance
// px.Status(seq int) (Fate, v interface{}) -- get info about an instance
// px.Done(seq int) -- ok to forget all instances <= seq
// px.Max() int -- highest instance seq known, or -1
// px.Min() int -- instances before this seq have been forgotten
//

import "net"
import "net/rpc"
import "log"

import "os"
import "syscall"
import "sync"
import "sync/atomic"
import "fmt"
import "math/rand"

// px.Status() return values, indicating
// whether an agreement has been decided,
// or Paxos has not yet reached agreement,
// or it was agreed but forgotten (i.e. < Min()).
type Fate int

const (
	Decided   Fate = iota + 1
	Pending        // not yet decided.
	Forgotten      // decided but forgotten.
)

type Paxos struct {
	mu         sync.Mutex
	l          net.Listener
	dead       int32 // for testing
	unreliable int32 // for testing
	rpcCount   int32 // for testing
	peers      []string
	me         int // index into peers[]

	// Your data here.
}

//
// call() sends an RPC to the rpcname handler on server srv
// with arguments args, waits for the reply, and leaves the
// reply in reply. the reply argument should be a pointer
// to a reply structure.
//
// the return value is true if the server responded, and false
// if call() was not able to contact the server. in particular,
// the replys contents are only valid if call() returned true.
//
// you should assume that call() will time out and return an
// error after a while if it does not get a reply from the server.
//
// please use call() to send all RPCs, in client.go and server.go.
// please do not change this function.
//
func call(srv string, name string, args interface{}, reply interface{}) bool {
	c, err := rpc.Dial("unix", srv)
	if err != nil {
		err1 := err.(*net.OpError)
		if err1.Err != syscall.ENOENT && err1.Err != syscall.ECONNREFUSED {
			fmt.Printf("paxos Dial() failed: %v\n", err1)
		}
		return false
	}
	defer c.Close()

	err = c.Call(name, args, reply)
	if err == nil {
		return true
	}

	fmt.Println(err)
	return false
}

//
// the application wants paxos to start agreement on
// instance seq, with proposed value v.
// Start() returns right away; the application will
// call Status() to find out if/when agreement
// is reached.
//
func (px *Paxos) Start(seq int, v interface{}) {
	// Your code here.
}

//
// the application on this machine is done with
// all instances <= seq.
//
// see the comments for Min() for more explanation.
//
func (px *Paxos) Done(seq int) {
	// Your code here.
}

//
// the application wants to know the
// highest instance sequence known to
// this peer.
//
func (px *Paxos) Max() int {
	// Your code here.
	return 0
}

//
// Min() should return one more than the minimum among z_i,
// where z_i is the highest number ever passed
// to Done() on peer i. A peers z_i is -1 if it has
// never called Done().
//
// Paxos is required to have forgotten all information
// about any instances it knows that are < Min().
// The point is to free up memory in long-running
// Paxos-based servers.
//
// Paxos peers need to exchange their highest Done()
// arguments in order to implement Min(). These
// exchanges can be piggybacked on ordinary Paxos
// agreement protocol messages, so it is OK if one
// peers Min does not reflect another Peers Done()
// until after the next instance is agreed to.
//
// The fact that Min() is defined as a minimum over
// *all* Paxos peers means that Min() cannot increase until
// all peers have been heard from. So if a peer is dead
// or unreachable, other peers Min()s will not increase
// even if all reachable peers call Done. The reason for
// this is that when the unreachable peer comes back to
// life, it will need to catch up on instances that it
// missed -- the other peers therefor cannot forget these
// instances.
//
func (px *Paxos) Min() int {
	// You code here.
	return 0
}

//
// the application wants to know whether this
// peer thinks an instance has been decided,
// and if so what the agreed value is. Status()
// should just inspect the local peer state;
// it should not contact other Paxos peers.
//
func (px *Paxos) Status(seq int) (Fate, interface{}) {
	// Your code here.
	return Pending, nil
}

//
// tell the peer to shut itself down.
// for testing.
// please do not change these two functions.
//
func (px *Paxos) Kill() {
	atomic.StoreInt32(&px.dead, 1)
	if px.l != nil {
		px.l.Close()
	}
}

//
// has this peer been asked to shut down?
//
func (px *Paxos) isdead() bool {
	return atomic.LoadInt32(&px.dead) != 0
}

// please do not change these two functions.
func (px *Paxos) setunreliable(what bool) {
	if what {
		atomic.StoreInt32(&px.unreliable, 1)
	} else {
		atomic.StoreInt32(&px.unreliable, 0)
	}
}

func (px *Paxos) isunreliable() bool {
	return atomic.LoadInt32(&px.unreliable) != 0
}

//
// the application wants to create a paxos peer.
// the ports of all the paxos peers (including this one)
// are in peers[]. this servers port is peers[me].
//
func Make(peers []string, me int, rpcs *rpc.Server) *Paxos {
	px := &Paxos{}
	px.peers = peers
	px.me = me

	// Your initialization code here.

	if rpcs != nil {
		// caller will create socket &c
		rpcs.Register(px)
	} else {
		rpcs = rpc.NewServer()
		rpcs.Register(px)

		// prepare to receive connections from clients.
		// change "unix" to "tcp" to use over a network.
		os.Remove(peers[me]) // only needed for "unix"
		l, e := net.Listen("unix", peers[me])
		if e != nil {
			log.Fatal("listen error: ", e)
		}
		px.l = l

		// please do not change any of the following code,
		// or do anything to subvert it.

		// create a thread to accept RPC connections
		go func() {
			for px.isdead() == false {
				conn, err := px.l.Accept()
				if err == nil && px.isdead() == false {
					if px.isunreliable() && (rand.Int63()%1000) < 100 {
						// discard the request.
						conn.Close()
					} else if px.isunreliable() && (rand.Int63()%1000) < 200 {
						// process the request but force discard of reply.
						c1 := conn.(*net.UnixConn)
						f, _ := c1.File()
						err := syscall.Shutdown(int(f.Fd()), syscall.SHUT_WR)
						if err != nil {
							fmt.Printf("shutdown: %v\n", err)
						}
						atomic.AddInt32(&px.rpcCount, 1)
						go rpcs.ServeConn(conn)
					} else {
						atomic.AddInt32(&px.rpcCount, 1)
						go rpcs.ServeConn(conn)
					}
				} else if err == nil {
					conn.Close()
				}
				if err != nil && px.isdead() == false {
					fmt.Printf("Paxos(%v) accept: %v\n", me, err.Error())
				}
			}
		}()
	}

	return px
}
<commit_msg>done in read https://github.com/lichuang/MIT6.824-golabs-2015<commit_after>package paxos

//
// Paxos library, to be included in an application.
// Multiple applications will run, each including
// a Paxos peer.
//
// Manages a sequence of agreed-on values.
// The set of peers is fixed.
// Copes with network failures (partition, msg loss, &c).
// Does not store anything persistently, so cannot handle crash+restart.
//
// The application interface:
//
// px = paxos.Make(peers []string, me string)
// px.Start(seq int, v interface{}) -- start agreement on new instance
// px.Status(seq int) (Fate, v interface{}) -- get info about an instance
// px.Done(seq int) -- ok to forget all instances <= seq
// px.Max() int -- highest instance seq known, or -1
// px.Min() int -- instances before this seq have been forgotten
//

import "net"
import "net/rpc"
import "log"

import "os"
import "syscall"
import "sync"
import "sync/atomic"
import "fmt"
import "math/rand"
import "time"
import "strconv"

// px.Status() return values, indicating
// whether an agreement has been decided,
// or Paxos has not yet reached agreement,
// or it was agreed but forgotten (i.e. < Min()).
type Fate int

const (
	OK = "OK"
	Reject = "REJECT"
)

const (
	Decided   Fate = iota + 1
	Pending        // not yet decided.
	Forgotten      // decided but forgotten.
)

type DecideArgs struct {
	Seq 	int
	PNum 	string
	Value 	interface{}
	Me 		int
	Done 	int
}

type DecideReply struct {}

type AcceptArgs struct {
	Seq 	int
	PNum 	string
	Value 	interface{}
}

type AcceptReply struct {
	Err 	string
}

type PrepareArgs struct {
	Seq 	int
	PNum 	string
}

type PrepareReply struct {
	Err 	string
	A_num 	string
	A_value	interface{}
}

type State struct {
	state 	Fate
	n_p   	string 	// 提出的
	n_a   	string 	// 建议的
	n_v   	interface{}
}

type Paxos struct {
	mu         sync.Mutex
	l          net.Listener
	dead       int32 // for testing
	unreliable int32 // for testing
	rpcCount   int32 // for testing
	peers      []string
	me         int // index into peers[]

	// Your data here.
	dones 		[]int
	instances 	map[int]*State
}

//
// call() sends an RPC to the rpcname handler on server srv
// with arguments args, waits for the reply, and leaves the
// reply in reply. the reply argument should be a pointer
// to a reply structure.
//
// the return value is true if the server responded, and false
// if call() was not able to contact the server. in particular,
// the replys contents are only valid if call() returned true.
//
// you should assume that call() will time out and return an
// error after a while if it does not get a reply from the server.
//
// please use call() to send all RPCs, in client.go and server.go.
// please do not change this function.
//
func call(srv string, name string, args interface{}, reply interface{}) bool {
	c, err := rpc.Dial("unix", srv)
	if err != nil {
		err1 := err.(*net.OpError)
		if err1.Err != syscall.ENOENT && err1.Err != syscall.ECONNREFUSED {
			fmt.Printf("paxos Dial() failed: %v\n", err1)
		}
		return false
	}
	defer c.Close()

	err = c.Call(name, args, reply)
	if err == nil {
		return true
	}

	fmt.Println(err)
	return false
}

//
// the application wants paxos to start agreement on
// instance seq, with proposed value v.
// Start() returns right away; the application will
// call Status() to find out if/when agreement
// is reached.
//
func (px *Paxos) Start(seq int, v interface{}) {
	// Your code here.
	px.proposer(seq, v)
}

func (px *Paxos) generatePNum() string {
	begin := time.Date(2015, time.May, 6, 22, 0, 0, 0, time.UTC)
	duration := time.Now().Sub(begin)
	return strconv.FormatInt(duration.Nanoseconds(), 10) + "-" + strconv.Itoa(px.me)
}

func (px *Paxos) proposer(seq int, v interface{}) {
	var replyPnum string
	var replyValue interface{}

	for {
		num := 0
		replyPnum = ""
		replyValue = v
		for i := 0; i < len(px.peers); i++ {
			// send prepare
			reply, _ := px.prepare(i, seq, v)
			if reply.Err == OK {
				num += 1
				if reply.A_num > replyPnum  {
					replyPnum = reply.A_num
					replyValue = reply.A_value
				}
			}
		}
		if num >= (len(px.peers)/2 + 1) {
			break
		}
	}
	// go accept

	ok := px.accept(seq, replyPnum, replyValue)
	if ok == true {
		px.decide(seq, replyPnum, replyValue)
	}
}

func (px *Paxos) decide(seq int, pnum string, v interface{}) {
	args := &DecideArgs {
		Seq: seq,
		PNum: pnum,
		Value: v,
		Me: px.me,
		Done: px.dones[px.me],
	}
	for i := 0; i < len(px.peers); i++ {
		var reply DecideReply
		call(px.peers[i], "Paxos.DecideHandler", args, &reply)
	}
}

func (px *Paxos) DecideHandler(args *DecideArgs, repl *DecideReply) error {
	px.mu.Lock()
	defer px.mu.Unlock()

	_, ok := px.instances[args.Seq]
	if !ok {
		state := &State{
			state: Pending,
			n_p: "",
			n_v: "",
			n_a: "",
		}
		px.instances[args.Seq] = state
	}
	px.instances[args.Seq].state = Decided
	px.instances[args.Seq].n_p = args.PNum
	px.instances[args.Seq].n_a = args.PNum
	px.instances[args.Seq].n_v = args.Value
	px.dones[args.Me] = args.Done

	return nil
}

func (px *Paxos) accept(seq int, pnum string, v interface{}) bool {
	args := &AcceptArgs{
		Seq: seq,
		PNum: pnum,
		Value: v,
	}
	num := 0
	for i := 0; i < len(px.peers); i++ {
		var reply AcceptReply
		ok := call(px.peers[i], "Paxos.AcceptHandler", args, &reply)
		if ok == true && reply.Err == OK {
			num += 1
		}
	}

	return num >= (len(px.peers)/2+1)
}

func (px *Paxos) AcceptHandler(args *AcceptArgs, reply *AcceptReply) error {
	px.mu.Lock()
	defer px.mu.Unlock()

	state, ok := px.instances[args.Seq]
	if !ok {
		state = &State{
			state: Pending,
			n_p: "",
			n_v: "",
			n_a: "",
		}
		px.instances[args.Seq] = state
		reply.Err = OK
	} else {
		if args.PNum >= state.n_p {
			reply.Err = OK
		} else {
			reply.Err = Reject
		}
	}
	if reply.Err == OK {
		px.instances[args.Seq].n_a = args.PNum
		px.instances[args.Seq].n_p = args.PNum
		px.instances[args.Seq].n_v = args.Value
	}

	return nil
}

func (px *Paxos) prepare(me int, seq int, v interface{}) (PrepareReply, error) {
	pnum := px.generatePNum()

	args := &PrepareArgs{
		Seq: seq,
		PNum: pnum,
	}

	var reply PrepareReply

	ok := call(px.peers[me], "Paxos.PrepareHandler", args, &reply)
	if ok == false {
		return PrepareReply{Err: Reject}, nil
	}
	return reply, nil
}

func (px *Paxos) PrepareHandler(args *PrepareArgs, reply *PrepareReply) error {
	px.mu.Lock()
	defer px.mu.Unlock()

	state, ok := px.instances[args.Seq]
	if !ok {
		state = &State{
			state: Pending,
			n_p: args.PNum,
			n_a: args.PNum,
			n_v: nil,
		}
		px.instances[args.Seq] = state
		reply.Err = OK
	} else {
		if args.PNum > state.n_p {
			reply.Err = OK
		 } else {
			reply.Err = Reject
		 }
	}

	if reply.Err == OK {
		reply.A_num = state.n_a
		reply.A_value = state.n_v
		px.instances[args.Seq].n_p = args.PNum
	}
	return nil
}

//
// the application on this machine is done with
// all instances <= seq.
//
// see the comments for Min() for more explanation.
//
func (px *Paxos) Done(seq int) {
	// Your code here.
	px.mu.Lock()
	defer px.mu.Unlock()

	if seq > px.dones[px.me] {
		px.dones[px.me] = seq
	}
}

//
// the application wants to know the
// highest instance sequence known to
// this peer.
//
func (px *Paxos) Max() int {
	// Your code here.
	px.mu.Lock()
	defer px.mu.Unlock()

	max := 0
	for k, _ := range px.instances {
		if k > max {
			max = k
		}
	}
	return max
}

//
// Min() should return one more than the minimum among z_i,
// where z_i is the highest number ever passed
// to Done() on peer i. A peers z_i is -1 if it has
// never called Done().
//
// Paxos is required to have forgotten all information
// about any instances it knows that are < Min().
// The point is to free up memory in long-running
// Paxos-based servers.
//
// Paxos peers need to exchange their highest Done()
// arguments in order to implement Min(). These
// exchanges can be piggybacked on ordinary Paxos
// agreement protocol messages, so it is OK if one
// peers Min does not reflect another Peers Done()
// until after the next instance is agreed to.
//
// The fact that Min() is defined as a minimum over
// *all* Paxos peers means that Min() cannot increase until
// all peers have been heard from. So if a peer is dead
// or unreachable, other peers Min()s will not increase
// even if all reachable peers call Done. The reason for
// this is that when the unreachable peer comes back to
// life, it will need to catch up on instances that it
// missed -- the other peers therefor cannot forget these
// instances.
//
func (px *Paxos) Min() int {
	// You code here.
	px.mu.Lock()
	defer px.mu.Unlock()

	min := px.dones[px.me]
	for i := range px.dones {
		if px.dones[i] < min {
			min = px.dones[i]
		}
	}

	for k, instance := range px.instances {
		if k > min {
			continue
		}
		if instance.state != Decided {
			continue
		}
		delete(px.instances, k)
	}

	return min + 1
}

//
// the application wants to know whether this
// peer thinks an instance has been decided,
// and if so what the agreed value is. Status()
// should just inspect the local peer state;
// it should not contact other Paxos peers.
//
func (px *Paxos) Status(seq int) (Fate, interface{}) {
	// Your code here.
	if seq < px.Min() {
		return Forgotten, nil
	}
	px.mu.Lock()
	defer px.mu.Unlock()

	instance, ok := px.instances[seq]
	if ok == false {
		return Pending, nil
	}

	return instance.state, instance.n_v
}

//
// tell the peer to shut itself down.
// for testing.
// please do not change these two functions.
//
func (px *Paxos) Kill() {
	atomic.StoreInt32(&px.dead, 1)
	if px.l != nil {
		px.l.Close()
	}
}

//
// has this peer been asked to shut down?
//
func (px *Paxos) isdead() bool {
	return atomic.LoadInt32(&px.dead) != 0
}

// please do not change these two functions.
func (px *Paxos) setunreliable(what bool) {
	if what {
		atomic.StoreInt32(&px.unreliable, 1)
	} else {
		atomic.StoreInt32(&px.unreliable, 0)
	}
}

func (px *Paxos) isunreliable() bool {
	return atomic.LoadInt32(&px.unreliable) != 0
}

//
// the application wants to create a paxos peer.
// the ports of all the paxos peers (including this one)
// are in peers[]. this servers port is peers[me].
//
func Make(peers []string, me int, rpcs *rpc.Server) *Paxos {
	px := &Paxos{}
	px.peers = peers
	px.me = me

	// Your initialization code here.
	px.instances = make(map[int]*State)
	px.dones = make([]int, len(peers))
	for i := 0; i < len(peers); i++ {
		px.dones[i] = -1
	}

	if rpcs != nil {
		// caller will create socket &c
		rpcs.Register(px)
	} else {
		rpcs = rpc.NewServer()
		rpcs.Register(px)

		// prepare to receive connections from clients.
		// change "unix" to "tcp" to use over a network.
		os.Remove(peers[me]) // only needed for "unix"
		l, e := net.Listen("unix", peers[me])
		if e != nil {
			log.Fatal("listen error: ", e)
		}
		px.l = l

		// please do not change any of the following code,
		// or do anything to subvert it.

		// create a thread to accept RPC connections
		go func() {
			for px.isdead() == false {
				conn, err := px.l.Accept()
				if err == nil && px.isdead() == false {
					if px.isunreliable() && (rand.Int63()%1000) < 100 {
						// discard the request.
						conn.Close()
					} else if px.isunreliable() && (rand.Int63()%1000) < 200 {
						// process the request but force discard of reply.
						c1 := conn.(*net.UnixConn)
						f, _ := c1.File()
						err := syscall.Shutdown(int(f.Fd()), syscall.SHUT_WR)
						if err != nil {
							fmt.Printf("shutdown: %v\n", err)
						}
						atomic.AddInt32(&px.rpcCount, 1)
						go rpcs.ServeConn(conn)
					} else {
						atomic.AddInt32(&px.rpcCount, 1)
						go rpcs.ServeConn(conn)
					}
				} else if err == nil {
					conn.Close()
				}
				if err != nil && px.isdead() == false {
					fmt.Printf("Paxos(%v) accept: %v\n", me, err.Error())
				}
			}
		}()
	}

	return px
}
<|endoftext|>


<commit_before>package parse

import (
	"fmt"
	"os"
	"reflect"
	"testing"

	"github.com/xiaq/elvish/util"
)

func compoundOfOnePrimary(p *PrimaryNode) *CompoundNode {
	return newCompound(p.Pos, NoSigil, &SubscriptNode{p.Pos, p, nil})
}

func compoundOfBare(p Pos, s string) *CompoundNode {
	return compoundOfOnePrimary(
		&PrimaryNode{p, StringPrimary, newString(p, s, s)})
}

// formWithRedir returns the expected FormNode of a "a" command followed by
// status and output redirections.
func formWithRedir(sr string, rs ...Redir) *FormNode {
	return &FormNode{0, compoundOfBare(0, "a"), newSpaced(1), rs, sr}
}

// formWithOnePrimary returns the expected FormNode of a "a" command followed
// by exactly one primary expression.
func formWithOnePrimary(p *PrimaryNode) *FormNode {
	return &FormNode{0,
		compoundOfBare(0, "a"),
		newSpaced(2, compoundOfOnePrimary(p)), nil, ""}
}

func chunkOfOneForm(f *FormNode) *ChunkNode {
	return newChunk(f.Pos, newPipeline(f.Pos, f))
}

func chunkOfFormWithRedir(sr string, rs ...Redir) *ChunkNode {
	return chunkOfOneForm(formWithRedir(sr, rs...))
}

func chunkOfFormWithOnePrimary(p *PrimaryNode) *ChunkNode {
	return chunkOfOneForm(formWithOnePrimary(p))
}

var parseTests = []struct {
	in     string
	wanted Node
}{
	// Empty chunk
	{"", newChunk(0)},

	// Command with arguments
	{"ls x y", chunkOfOneForm(
		&FormNode{0,
			compoundOfBare(0, "ls"),
			newSpaced(3,
				compoundOfBare(3, "x"),
				compoundOfBare(5, "y")),
			nil, ""})},

	// Multiple pipelines, multiple commands
	{"a;b|c\n;d", newChunk(0,
		newPipeline(0,
			&FormNode{0,
				compoundOfBare(0, "a"),
				newSpaced(1), nil, ""}),
		newPipeline(2,
			&FormNode{2,
				compoundOfBare(2, "b"),
				newSpaced(3), nil, ""},
			&FormNode{4,
				compoundOfBare(4, "c"),
				newSpaced(5), nil, ""}),
		newPipeline(7,
			&FormNode{7,
				compoundOfBare(7, "d"),
				newSpaced(8), nil, ""}))},

	// Redirections
	//
	// Output and status redir
	{"a>b?>$c", chunkOfFormWithRedir("c",
		&FilenameRedir{
			RedirBase{1, 1}, os.O_WRONLY | os.O_CREATE,
			compoundOfBare(2, "b")})},
	// Different direction
	{"a>>b", chunkOfFormWithRedir("",
		&FilenameRedir{
			RedirBase{1, 1}, os.O_WRONLY | os.O_CREATE | os.O_APPEND,
			compoundOfBare(3, "b")})},
	// FilenameRedir with custom fd
	{"a>[2]b", chunkOfFormWithRedir("",
		&FilenameRedir{
			RedirBase{1, 2}, os.O_WRONLY | os.O_CREATE,
			compoundOfBare(5, "b")})},
	// FdRedir
	{"a>[2=33]", chunkOfFormWithRedir("", &FdRedir{RedirBase{1, 2}, 33})},
	// CloseRedir
	{"a>[2=]", chunkOfFormWithRedir("", &CloseRedir{RedirBase{1, 2}})},

	// Compound with sigil
	{"a =b$c", chunkOfOneForm(
		&FormNode{0,
			compoundOfBare(0, "a"),
			newSpaced(2,
				newCompound(2, '=',
					&SubscriptNode{3,
						&PrimaryNode{3, StringPrimary,
							newString(3, "b", "b")},
						nil},
					&SubscriptNode{4,
						&PrimaryNode{4, VariablePrimary,
							newString(5, "c", "c")},
						nil})),
			nil, ""})},

	// Subscript
	{"a $b[c]", chunkOfOneForm(
		&FormNode{0,
			compoundOfBare(0, "a"),
			newSpaced(2,
				newCompound(2, NoSigil,
					&SubscriptNode{2,
						&PrimaryNode{2, VariablePrimary,
							newString(3, "b", "b")},
						compoundOfBare(5, "c")})),
			nil, ""})},

	// Primary
	//
	// Single quote
	{"a `b`", chunkOfFormWithOnePrimary(
		&PrimaryNode{2, StringPrimary, newString(2, "`b`", "b")})},
	// Double quote
	{`a "b"`, chunkOfFormWithOnePrimary(
		&PrimaryNode{2, StringPrimary, newString(2, `"b"`, "b")})},
	// TODO(xiaq): Other types of primary expressions
}

func TestParse(t *testing.T) {
	for i, tt := range parseTests {
		out, err := Parse(fmt.Sprintf("<test %d>", i), tt.in)
		if !reflect.DeepEqual(out, tt.wanted) || err != nil {
			t.Errorf("Parse(*, %q) =>\n(%s, %v), want\n(%s, <nil>) (up to DeepEqual)", tt.in, util.DeepPrint(out), err, util.DeepPrint(tt.wanted))
		}
	}
}

var completeTests = []struct {
	in        string
	wantedTyp ContextType
}{
	{"", CommandContext},
	{"l", CommandContext},
	{"ls ", NewArgContext},
	{"ls a", ArgContext},
	{"ls $a", ArgContext},
}

func TestComplete(t *testing.T) {
	for i, tt := range completeTests {
		out, err := Complete(fmt.Sprintf("<test %d>", i), tt.in)
		if out.Typ != tt.wantedTyp || err != nil {
			t.Errorf("Complete(*, %q) => (Context{Typ: %v, ...}, %v), want (Context{Typ: %v, ...}, <nil>)", tt.in, out.Typ, err, tt.wantedTyp)
		}
	}
}
<commit_msg>Add a parse test case<commit_after>package parse

import (
	"fmt"
	"os"
	"reflect"
	"testing"

	"github.com/xiaq/elvish/util"
)

func compoundOfOnePrimary(p *PrimaryNode) *CompoundNode {
	return newCompound(p.Pos, NoSigil, &SubscriptNode{p.Pos, p, nil})
}

func compoundOfBare(p Pos, s string) *CompoundNode {
	return compoundOfOnePrimary(
		&PrimaryNode{p, StringPrimary, newString(p, s, s)})
}

// formWithRedir returns the expected FormNode of a "a" command followed by
// status and output redirections.
func formWithRedir(sr string, rs ...Redir) *FormNode {
	return &FormNode{0, compoundOfBare(0, "a"), newSpaced(1), rs, sr}
}

// formWithOnePrimary returns the expected FormNode of a "a" command followed
// by exactly one primary expression.
func formWithOnePrimary(p *PrimaryNode) *FormNode {
	return &FormNode{0,
		compoundOfBare(0, "a"),
		newSpaced(2, compoundOfOnePrimary(p)), nil, ""}
}

func chunkOfOneForm(f *FormNode) *ChunkNode {
	return newChunk(f.Pos, newPipeline(f.Pos, f))
}

func chunkOfFormWithRedir(sr string, rs ...Redir) *ChunkNode {
	return chunkOfOneForm(formWithRedir(sr, rs...))
}

func chunkOfFormWithOnePrimary(p *PrimaryNode) *ChunkNode {
	return chunkOfOneForm(formWithOnePrimary(p))
}

var parseTests = []struct {
	in     string
	wanted Node
}{
	// Empty chunk
	{"", newChunk(0)},

	// Command with arguments
	{"ls x y", chunkOfOneForm(
		&FormNode{0,
			compoundOfBare(0, "ls"),
			newSpaced(3,
				compoundOfBare(3, "x"),
				compoundOfBare(5, "y")),
			nil, ""})},

	// Wow... such whitespace, much unnecessary, so valid
	{"  ;\n\n  ls   ;\n", newChunk(0,
		newPipeline(7,
			&FormNode{7, compoundOfBare(7, "ls"), newSpaced(12), nil, ""}))},

	// Multiple pipelines, multiple commands
	{"a;b|c\n;d", newChunk(0,
		newPipeline(0,
			&FormNode{0,
				compoundOfBare(0, "a"),
				newSpaced(1), nil, ""}),
		newPipeline(2,
			&FormNode{2,
				compoundOfBare(2, "b"),
				newSpaced(3), nil, ""},
			&FormNode{4,
				compoundOfBare(4, "c"),
				newSpaced(5), nil, ""}),
		newPipeline(7,
			&FormNode{7,
				compoundOfBare(7, "d"),
				newSpaced(8), nil, ""}))},

	// Redirections
	//
	// Output and status redir
	{"a>b?>$c", chunkOfFormWithRedir("c",
		&FilenameRedir{
			RedirBase{1, 1}, os.O_WRONLY | os.O_CREATE,
			compoundOfBare(2, "b")})},
	// Different direction
	{"a>>b", chunkOfFormWithRedir("",
		&FilenameRedir{
			RedirBase{1, 1}, os.O_WRONLY | os.O_CREATE | os.O_APPEND,
			compoundOfBare(3, "b")})},
	// FilenameRedir with custom fd
	{"a>[2]b", chunkOfFormWithRedir("",
		&FilenameRedir{
			RedirBase{1, 2}, os.O_WRONLY | os.O_CREATE,
			compoundOfBare(5, "b")})},
	// FdRedir
	{"a>[2=33]", chunkOfFormWithRedir("", &FdRedir{RedirBase{1, 2}, 33})},
	// CloseRedir
	{"a>[2=]", chunkOfFormWithRedir("", &CloseRedir{RedirBase{1, 2}})},

	// Compound with sigil
	{"a =b$c", chunkOfOneForm(
		&FormNode{0,
			compoundOfBare(0, "a"),
			newSpaced(2,
				newCompound(2, '=',
					&SubscriptNode{3,
						&PrimaryNode{3, StringPrimary,
							newString(3, "b", "b")},
						nil},
					&SubscriptNode{4,
						&PrimaryNode{4, VariablePrimary,
							newString(5, "c", "c")},
						nil})),
			nil, ""})},

	// Subscript
	{"a $b[c]", chunkOfOneForm(
		&FormNode{0,
			compoundOfBare(0, "a"),
			newSpaced(2,
				newCompound(2, NoSigil,
					&SubscriptNode{2,
						&PrimaryNode{2, VariablePrimary,
							newString(3, "b", "b")},
						compoundOfBare(5, "c")})),
			nil, ""})},

	// Primary
	//
	// Single quote
	{"a `b`", chunkOfFormWithOnePrimary(
		&PrimaryNode{2, StringPrimary, newString(2, "`b`", "b")})},
	// Double quote
	{`a "b"`, chunkOfFormWithOnePrimary(
		&PrimaryNode{2, StringPrimary, newString(2, `"b"`, "b")})},
	// TODO(xiaq): Other types of primary expressions
}

func TestParse(t *testing.T) {
	for i, tt := range parseTests {
		out, err := Parse(fmt.Sprintf("<test %d>", i), tt.in)
		if !reflect.DeepEqual(out, tt.wanted) || err != nil {
			t.Errorf("Parse(*, %q) =>\n(%s, %v), want\n(%s, <nil>) (up to DeepEqual)", tt.in, util.DeepPrint(out), err, util.DeepPrint(tt.wanted))
		}
	}
}

var completeTests = []struct {
	in        string
	wantedTyp ContextType
}{
	{"", CommandContext},
	{"l", CommandContext},
	{"ls ", NewArgContext},
	{"ls a", ArgContext},
	{"ls $a", ArgContext},
}

func TestComplete(t *testing.T) {
	for i, tt := range completeTests {
		out, err := Complete(fmt.Sprintf("<test %d>", i), tt.in)
		if out.Typ != tt.wantedTyp || err != nil {
			t.Errorf("Complete(*, %q) => (Context{Typ: %v, ...}, %v), want (Context{Typ: %v, ...}, <nil>)", tt.in, out.Typ, err, tt.wantedTyp)
		}
	}
}
<|endoftext|>


<commit_before>package service_test

import (
	"testing"

	"github.com/cloudfoundry-incubator/cf-test-helpers/services/context_setup"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

type redisTestConfig struct {
	context_setup.IntegrationConfig

	appsDomain  string
	brokerHost  string
	serviceName string
	planNames   []string
}

func loadConfig() redisTestConfig {
	return redisTestConfig{
		IntegrationConfig: context_setup.IntegrationConfig{
			ApiEndpoint:                   "api.10.244.0.34.xip.io",
			AppsDomain:                    "10.244.0.34.xip.io",
			AdminUser:                     "admin",
			AdminPassword:                 "admin",
			CreatePermissiveSecurityGroup: true,
			SkipSSLValidation:             true,
		},
		brokerHost:  "10.244.3.46",
		serviceName: "p-redis",
		planNames:   []string{"shared-vm", "dedicated-vm"},
	}
}

var config = loadConfig()

func TestService(t *testing.T) {
	context_setup.TimeoutScale = 1
	context_setup.SetupEnvironment(context_setup.NewContext(config.IntegrationConfig, "redis"))
	RegisterFailHandler(Fail)
	RunSpecs(t, "P-Redis Smoke Tests")
}
<commit_msg>remove unused fields from redisTestConfig<commit_after>package service_test

import (
	"testing"

	"github.com/cloudfoundry-incubator/cf-test-helpers/services/context_setup"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

type redisTestConfig struct {
	context_setup.IntegrationConfig

	serviceName string
	planNames   []string
}

func loadConfig() redisTestConfig {
	return redisTestConfig{
		IntegrationConfig: context_setup.IntegrationConfig{
			ApiEndpoint:                   "api.10.244.0.34.xip.io",
			AppsDomain:                    "10.244.0.34.xip.io",
			AdminUser:                     "admin",
			AdminPassword:                 "admin",
			CreatePermissiveSecurityGroup: true,
			SkipSSLValidation:             true,
		},
		serviceName: "p-redis",
		planNames:   []string{"shared-vm", "dedicated-vm"},
	}
}

var config = loadConfig()

func TestService(t *testing.T) {
	context_setup.TimeoutScale = 1
	context_setup.SetupEnvironment(context_setup.NewContext(config.IntegrationConfig, "redis"))
	RegisterFailHandler(Fail)
	RunSpecs(t, "P-Redis Smoke Tests")
}
<|endoftext|>


<commit_before>package goyesql

import (
	"testing"
)

func TestParseLine(t *testing.T) {
	tests := map[string]parsedLine{
		" ":              parsedLine{lineBlank, ""},
		" SELECT * ":     parsedLine{lineQuery, "SELECT *"},
		" -- name: tag ": parsedLine{lineTag, "tag"},
		" -- comment ":   parsedLine{lineComment, "comment"},
	}

	for line, expected := range tests {
		parsed := parseLine(line)

		if parsed != expected {
			t.Errorf("Invalid line parsing. Expected '%v', got '%v'", expected, parsed)
		}
	}
}
<commit_msg>gofmt -s, remove redundant parsedLine structs<commit_after>package goyesql

import (
	"testing"
)

func TestParseLine(t *testing.T) {
	tests := map[string]parsedLine{
		" ":              {lineBlank, ""},
		" SELECT * ":     {lineQuery, "SELECT *"},
		" -- name: tag ": {lineTag, "tag"},
		" -- comment ":   {lineComment, "comment"},
	}

	for line, expected := range tests {
		parsed := parseLine(line)

		if parsed != expected {
			t.Errorf("Invalid line parsing. Expected '%v', got '%v'", expected, parsed)
		}
	}
}
<|endoftext|>


<commit_before>package requestresults

import (
	"encoding/json"
	"fmt"
	"strconv"
	"strings"
	"time"

	"chkit-v2/chlib"
	"github.com/olekukonko/tablewriter"
)

type singlePodResult []struct {
	Data struct {
		chlib.Pod
	} `json:"data"`
}

type podListResult []struct {
	Data struct {
		Items []chlib.Pod `json:"items"`
	} `json:"data"`
}

func (p podListResult) formatPrettyPrint() (ppc prettyPrintConfig) {
	ppc.Columns = []string{"NAME", "READY", "STATUS", "RESTARTS", "AGE", "IP"}
	for _, item := range p[0].Data.Items {
		restarts := 0
		var podStatus string
		for _, containerStatus := range item.Status.ContainerStatuses {
			restarts += containerStatus.RestartCount
			var status string
			for k := range containerStatus.State {
				status = k
				break
			}
			if podStatus == "" || podStatus == "running" {
				podStatus = status
			}
			if podStatus == "waiting" && status == "terminated" {
				podStatus = status
			}
		}
		podStatus = strings.Title(podStatus)
		ipStr := item.Status.PodIP.String()
		if item.Status.PodIP == nil {
			ipStr = "None"
		}
		row := []string{
			item.Metadata.Name,
			podStatus,
			item.Status.Phase,
			fmt.Sprintf("%d", restarts),
			ageFormat(time.Now().Sub(item.Status.StartTime)),
			ipStr,
		}
		ppc.Data = append(ppc.Data, row)
	}
	ppc.Align = tablewriter.ALIGN_LEFT
	return
}

func (p singlePodResult) Print() (err error) {
	metadata := p[0].Data.Metadata
	containers := p[0].Data.Spec.Containers
	restartPolicy := p[0].Data.Spec.RestartPolicy
	termination := time.Duration(p[0].Data.Spec.TerminationGracePeriodSeconds) * time.Second
	system := p[0].Data.Status
	containerStatuses := p[0].Data.Status.ContainerStatuses
	status := p[0].Data.Status.Conditions

	fmt.Println("Pod:")
	fmt.Printf("\t%-20s %s\n", "UserId:", metadata.CreationTimestamp.Format(time.RFC1123))
	fmt.Println("\tLabel:")
	fmt.Printf("\t\t%-20s %s\n", "App:", metadata.Labels["app"])
	fmt.Printf("\t\t%-20s %s\n", "PodTemplateHash:", metadata.Labels["pod-template-hash"])
	fmt.Printf("\t\t%-20s %s\n", "Role", metadata.Labels["role"])
	fmt.Println("Containers:")
	for _, c := range containers {
		fmt.Printf("\t%s\n", c.Name)
		if len(c.Command) != 0 {
			fmt.Println("\t\t%-20s %s\n", "Command:", strings.Join(c.Command, ""))
		}
		fmt.Println("\t\tPorts:")
		if len(c.Ports) != 0 {
			ppc := prettyPrintConfig{
				Columns: []string{"Name", "Protocol", "ContPort"},
			}
			for _, p := range c.Ports {
				row := []string{
					p.Name,
					p.Protocol,
					strconv.Itoa(p.ContainerPort),
				}
				ppc.Data = append(ppc.Data, row)
			}
			ppc.Print()
		}
		if len(c.Env) != 0 {
			fmt.Println("\t\tEnvironment:")
			ppc := prettyPrintConfig{
				Columns: []string{"Name", "Value"},
			}
			for _, e := range c.Env {
				ppc.Data = append(ppc.Data, []string{e.Name, e.Value})
			}
		}
		fmt.Println("\t\tResourceLimit:")
		fmt.Printf("\t\t\t%-10s %s\n", "CPU:", c.Resources.Limits.CPU)
		fmt.Printf("\t\t\t%-10s %s\n", "Memory:", c.Resources.Limits.Memory)
		fmt.Printf("\t\t%-20s %s\n", "Image:", c.Image)
		fmt.Printf("\t\t%-20s %s\n", "ImagePullPolicy:", c.ImagePullPolicy)
		fmt.Println("System:")
		fmt.Printf("\t%-30s %s\n", "PodIP:", system.PodIP)
		fmt.Printf("\t%-30s %s\n", "Phase:", system.Phase)
		if !system.StartTime.Equal(time.Time{}) {
			fmt.Printf("\t%-30s %s\n", "StartTime:", system.StartTime)
		}
		fmt.Printf("\t%-30s %ds\n", "TerminationGracePeriod:", int(termination.Seconds()))
		fmt.Printf("\t%-30s %s\n", "RestartPolicy:", restartPolicy)
		fmt.Println("Container Statuses:")
		if len(containerStatuses) != 0 {
			ppc := prettyPrintConfig{
				Columns: []string{"Name", "Ready", "Restart count"},
			}
			for _, cs := range containerStatuses {
				row := []string{
					cs.Name,
					fmt.Sprint(cs.Ready),
					fmt.Sprint(cs.RestartCount),
				}
				ppc.Data = append(ppc.Data, row)
			}
			ppc.Print()
		}
		fmt.Println("Status:")
		ppc := prettyPrintConfig{
			Columns: []string{"Type", "LastTransitionTime", "Status"},
		}
		for _, s := range status {
			row := []string{
				s.Type,
				s.LastTransitionTime.Format(time.RFC1123),
				s.Status,
			}
			ppc.Data = append(ppc.Data, row)
		}
		ppc.Print()
	}
	return
}

func init() {
	resultKinds["Pod"] = func(resp []chlib.GenericJson) (ResultPrinter, error) {
		var res singlePodResult
		b, _ := json.Marshal(resp)
		if err := json.Unmarshal(b, &res); err != nil {
			return nil, fmt.Errorf("invalid pod response: %s", err)
		}
		return res, nil
	}
	resultKinds["PodList"] = func(resp []chlib.GenericJson) (ResultPrinter, error) {
		var res podListResult
		b, _ := json.Marshal(resp)
		if err := json.Unmarshal(b, &res); err != nil {
			return nil, fmt.Errorf("invalid pod list response: %s", err)
		}
		return res.formatPrettyPrint(), nil
	}
}
<commit_msg>Fix pod status printing and READY column<commit_after>package requestresults

import (
	"encoding/json"
	"fmt"
	"strconv"
	"strings"
	"time"

	"chkit-v2/chlib"
	"github.com/olekukonko/tablewriter"
)

type singlePodResult []struct {
	Data struct {
		chlib.Pod
	} `json:"data"`
}

type podListResult []struct {
	Data struct {
		Items []chlib.Pod `json:"items"`
	} `json:"data"`
}

func (p podListResult) formatPrettyPrint() (ppc prettyPrintConfig) {
	ppc.Columns = []string{"NAME", "READY", "STATUS", "RESTARTS", "AGE", "IP"}
	for _, item := range p[0].Data.Items {
		restarts := 0
		var podStatus string
		var containersRunning int
		for _, containerStatus := range item.Status.ContainerStatuses {
			restarts += containerStatus.RestartCount
			var status string
			for k := range containerStatus.State {
				status = k
				break
			}
			if status == "running" {
				containersRunning++
			}
			if podStatus == "" || podStatus == "running" {
				podStatus = status
			}
			if podStatus == "waiting" && status == "terminated" {
				podStatus = status
			}
		}
		podStatus = strings.Title(podStatus)
		ipStr := item.Status.PodIP.String()
		if item.Status.PodIP == nil {
			ipStr = "None"
		}
		row := []string{
			item.Metadata.Name,
			fmt.Sprintf("%d/%d", containersRunning, len(item.Status.ContainerStatuses)),
			podStatus,
			fmt.Sprintf("%d", restarts),
			ageFormat(time.Now().Sub(item.Status.StartTime)),
			ipStr,
		}
		ppc.Data = append(ppc.Data, row)
	}
	ppc.Align = tablewriter.ALIGN_LEFT
	return
}

func (p singlePodResult) Print() (err error) {
	metadata := p[0].Data.Metadata
	containers := p[0].Data.Spec.Containers
	restartPolicy := p[0].Data.Spec.RestartPolicy
	termination := time.Duration(p[0].Data.Spec.TerminationGracePeriodSeconds) * time.Second
	system := p[0].Data.Status
	containerStatuses := p[0].Data.Status.ContainerStatuses
	status := p[0].Data.Status.Conditions

	fmt.Println("Pod:")
	fmt.Printf("\t%-20s %s\n", "UserId:", metadata.CreationTimestamp.Format(time.RFC1123))
	fmt.Println("\tLabel:")
	fmt.Printf("\t\t%-20s %s\n", "App:", metadata.Labels["app"])
	fmt.Printf("\t\t%-20s %s\n", "PodTemplateHash:", metadata.Labels["pod-template-hash"])
	fmt.Printf("\t\t%-20s %s\n", "Role", metadata.Labels["role"])
	fmt.Println("Containers:")
	for _, c := range containers {
		fmt.Printf("\t%s\n", c.Name)
		if len(c.Command) != 0 {
			fmt.Println("\t\t%-20s %s\n", "Command:", strings.Join(c.Command, ""))
		}
		fmt.Println("\t\tPorts:")
		if len(c.Ports) != 0 {
			ppc := prettyPrintConfig{
				Columns: []string{"Name", "Protocol", "ContPort"},
			}
			for _, p := range c.Ports {
				row := []string{
					p.Name,
					p.Protocol,
					strconv.Itoa(p.ContainerPort),
				}
				ppc.Data = append(ppc.Data, row)
			}
			ppc.Print()
		}
		if len(c.Env) != 0 {
			fmt.Println("\t\tEnvironment:")
			ppc := prettyPrintConfig{
				Columns: []string{"Name", "Value"},
			}
			for _, e := range c.Env {
				ppc.Data = append(ppc.Data, []string{e.Name, e.Value})
			}
		}
		fmt.Println("\t\tResourceLimit:")
		fmt.Printf("\t\t\t%-10s %s\n", "CPU:", c.Resources.Limits.CPU)
		fmt.Printf("\t\t\t%-10s %s\n", "Memory:", c.Resources.Limits.Memory)
		fmt.Printf("\t\t%-20s %s\n", "Image:", c.Image)
		fmt.Printf("\t\t%-20s %s\n", "ImagePullPolicy:", c.ImagePullPolicy)
		fmt.Println("System:")
		fmt.Printf("\t%-30s %s\n", "PodIP:", system.PodIP)
		fmt.Printf("\t%-30s %s\n", "Phase:", system.Phase)
		if !system.StartTime.Equal(time.Time{}) {
			fmt.Printf("\t%-30s %s\n", "StartTime:", system.StartTime)
		}
		fmt.Printf("\t%-30s %ds\n", "TerminationGracePeriod:", int(termination.Seconds()))
		fmt.Printf("\t%-30s %s\n", "RestartPolicy:", restartPolicy)
		fmt.Println("Container Statuses:")
		if len(containerStatuses) != 0 {
			ppc := prettyPrintConfig{
				Columns: []string{"Name", "Ready", "Restart count"},
			}
			for _, cs := range containerStatuses {
				row := []string{
					cs.Name,
					fmt.Sprint(cs.Ready),
					fmt.Sprint(cs.RestartCount),
				}
				ppc.Data = append(ppc.Data, row)
			}
			ppc.Print()
		}
		fmt.Println("Status:")
		ppc := prettyPrintConfig{
			Columns: []string{"Type", "LastTransitionTime", "Status"},
		}
		for _, s := range status {
			row := []string{
				s.Type,
				s.LastTransitionTime.Format(time.RFC1123),
				s.Status,
			}
			ppc.Data = append(ppc.Data, row)
		}
		ppc.Print()
	}
	return
}

func init() {
	resultKinds["Pod"] = func(resp []chlib.GenericJson) (ResultPrinter, error) {
		var res singlePodResult
		b, _ := json.Marshal(resp)
		if err := json.Unmarshal(b, &res); err != nil {
			return nil, fmt.Errorf("invalid pod response: %s", err)
		}
		return res, nil
	}
	resultKinds["PodList"] = func(resp []chlib.GenericJson) (ResultPrinter, error) {
		var res podListResult
		b, _ := json.Marshal(resp)
		if err := json.Unmarshal(b, &res); err != nil {
			return nil, fmt.Errorf("invalid pod list response: %s", err)
		}
		return res.formatPrettyPrint(), nil
	}
}
<|endoftext|>


<commit_before>package marathon

import (
	"encoding/json"
	"github.com/QubitProducts/bamboo/configuration"
	"io/ioutil"
	"net/http"
	"sort"
	"strings"
)

// Describes an app process running
type Task struct {
	Host string
	Port int
}

// An app may have multiple processes
type App struct {
	Id              string
	EscapedId       string
	HealthCheckPath string
	Tasks           []Task
	ServicePorts    []int
	Env             map[string]string
}

type AppList []App

func (slice AppList) Len() int {
	return len(slice)
}

func (slice AppList) Less(i, j int) bool {
	return slice[i].Id < slice[j].Id
}

func (slice AppList) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}

type MarathonTaskList []MarathonTask

type MarathonTasks struct {
	Tasks MarathonTaskList `json:tasks`
}

type MarathonTask struct {
	AppId        string
	Id           string
	Host         string
	Ports        []int
	ServicePorts []int
	StartedAt    string
	StagedAt     string
	Version      string
}

func (slice MarathonTaskList) Len() int {
	return len(slice)
}

func (slice MarathonTaskList) Less(i, j int) bool {
	return slice[i].StagedAt < slice[j].StagedAt
}

func (slice MarathonTaskList) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}

type MarathonApps struct {
	Apps []MarathonApp `json:apps`
}

type MarathonApp struct {
	Id           string            `json:id`
	HealthChecks []HealthChecks    `json:healthChecks`
	Ports        []int             `json:ports`
	Env          map[string]string `json:env`
}

type HealthChecks struct {
	Path string `json:path`
}

func fetchMarathonApps(endpoint string) (map[string]MarathonApp, error) {
	response, err := http.Get(endpoint + "/v2/apps")

	if err != nil {
		return nil, err
	} else {
		defer response.Body.Close()
		var appResponse MarathonApps

		contents, err := ioutil.ReadAll(response.Body)
		if err != nil {
			return nil, err
		}

		err = json.Unmarshal(contents, &appResponse)
		if err != nil {
			return nil, err
		}

		dataById := map[string]MarathonApp{}

		for _, appConfig := range appResponse.Apps {
			dataById[appConfig.Id] = appConfig
		}

		return dataById, nil
	}
}

func fetchTasks(endpoint string) (map[string][]MarathonTask, error) {
	client := &http.Client{}
	req, err := http.NewRequest("GET", endpoint+"/v2/tasks", nil)
	req.Header.Add("Accept", "application/json")
	response, err := client.Do(req)

	var tasks MarathonTasks

	if err != nil {
		return nil, err
	} else {
		contents, err := ioutil.ReadAll(response.Body)
		defer response.Body.Close()
		if err != nil {
			return nil, err
		}

		err = json.Unmarshal(contents, &tasks)
		if err != nil {
			return nil, err
		}

		taskList := tasks.Tasks
		sort.Sort(taskList)

		tasksById := map[string][]MarathonTask{}
		for _, task := range taskList {
			if tasksById[task.AppId] == nil {
				tasksById[task.AppId] = []MarathonTask{}
			}
			tasksById[task.AppId] = append(tasksById[task.AppId], task)
		}

		return tasksById, nil
	}
}

func createApps(tasksById map[string][]MarathonTask, marathonApps map[string]MarathonApp) AppList {

	apps := AppList{}

	for appId, tasks := range tasksById {
		simpleTasks := []Task{}

		for _, task := range tasks {
			if len(task.Ports) > 0 {
				simpleTasks = append(simpleTasks, Task{Host: task.Host, Port: task.Ports[0]})
			}
		}

		// Try to handle old app id format without slashes
		appPath := appId
		if !strings.HasPrefix(appId, "/") {
			appPath = "/" + appId
		}

		app := App{
			// Since Marathon 0.7, apps are namespaced with path
			Id: appPath,
			// Used for template
			EscapedId:       strings.Replace(appId, "/", "::", -1),
			Tasks:           simpleTasks,
			HealthCheckPath: parseHealthCheckPath(marathonApps[appId].HealthChecks),
			Env:             marathonApps[appId].Env,
			ServicePorts:    marathonApps[appId].Ports,
		}

		apps = append(apps, app)
	}
	return apps
}

func parseHealthCheckPath(checks []HealthChecks) string {
	if len(checks) > 0 {
		return checks[0].Path
	}
	return ""
}

/*
	Apps returns a struct that describes Marathon current app and their
	sub tasks information.

	Parameters:
		endpoint: Marathon HTTP endpoint, e.g. http://localhost:8080
*/
func FetchApps(maraconf configuration.Marathon) (AppList, error) {

	var applist AppList
	var err error

	// try all configured endpoints until one succeeds
	for _, url := range maraconf.Endpoints() {
		applist, err = _fetchApps(url)
		if err == nil {
			return applist, err
		}
	}
	// return last error
	return nil, err
}

func _fetchApps(url string) (AppList, error) {
	tasks, err := fetchTasks(url)
	if err != nil {
		return nil, err
	}

	marathonApps, err := fetchMarathonApps(url)
	if err != nil {
		return nil, err
	}

	apps := createApps(tasks, marathonApps)
	sort.Sort(apps)
	return apps, nil
}
<commit_msg>QD-69: marathon task ports<commit_after>package marathon

import (
	"encoding/json"
	"github.com/QubitProducts/bamboo/configuration"
	"io/ioutil"
	"net/http"
	"sort"
	"strings"
)

// Describes an app process running
type Task struct {
	Host string
	Port int
	Ports []int
}

// An app may have multiple processes
type App struct {
	Id              string
	EscapedId       string
	HealthCheckPath string
	Tasks           []Task
	ServicePorts    []int
	Env             map[string]string
}

type AppList []App

func (slice AppList) Len() int {
	return len(slice)
}

func (slice AppList) Less(i, j int) bool {
	return slice[i].Id < slice[j].Id
}

func (slice AppList) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}

type MarathonTaskList []MarathonTask

type MarathonTasks struct {
	Tasks MarathonTaskList `json:tasks`
}

type MarathonTask struct {
	AppId        string
	Id           string
	Host         string
	Ports        []int
	ServicePorts []int
	StartedAt    string
	StagedAt     string
	Version      string
}

func (slice MarathonTaskList) Len() int {
	return len(slice)
}

func (slice MarathonTaskList) Less(i, j int) bool {
	return slice[i].StagedAt < slice[j].StagedAt
}

func (slice MarathonTaskList) Swap(i, j int) {
	slice[i], slice[j] = slice[j], slice[i]
}

type MarathonApps struct {
	Apps []MarathonApp `json:apps`
}

type MarathonApp struct {
	Id           string            `json:id`
	HealthChecks []HealthChecks    `json:healthChecks`
	Ports        []int             `json:ports`
	Env          map[string]string `json:env`
}

type HealthChecks struct {
	Path string `json:path`
}

func fetchMarathonApps(endpoint string) (map[string]MarathonApp, error) {
	response, err := http.Get(endpoint + "/v2/apps")

	if err != nil {
		return nil, err
	} else {
		defer response.Body.Close()
		var appResponse MarathonApps

		contents, err := ioutil.ReadAll(response.Body)
		if err != nil {
			return nil, err
		}

		err = json.Unmarshal(contents, &appResponse)
		if err != nil {
			return nil, err
		}

		dataById := map[string]MarathonApp{}

		for _, appConfig := range appResponse.Apps {
			dataById[appConfig.Id] = appConfig
		}

		return dataById, nil
	}
}

func fetchTasks(endpoint string) (map[string][]MarathonTask, error) {
	client := &http.Client{}
	req, err := http.NewRequest("GET", endpoint+"/v2/tasks", nil)
	req.Header.Add("Accept", "application/json")
	response, err := client.Do(req)

	var tasks MarathonTasks

	if err != nil {
		return nil, err
	} else {
		contents, err := ioutil.ReadAll(response.Body)
		defer response.Body.Close()
		if err != nil {
			return nil, err
		}

		err = json.Unmarshal(contents, &tasks)
		if err != nil {
			return nil, err
		}

		taskList := tasks.Tasks
		sort.Sort(taskList)

		tasksById := map[string][]MarathonTask{}
		for _, task := range taskList {
			if tasksById[task.AppId] == nil {
				tasksById[task.AppId] = []MarathonTask{}
			}
			tasksById[task.AppId] = append(tasksById[task.AppId], task)
		}

		return tasksById, nil
	}
}

func createApps(tasksById map[string][]MarathonTask, marathonApps map[string]MarathonApp) AppList {

	apps := AppList{}

	for appId, tasks := range tasksById {
		simpleTasks := []Task{}

		for _, task := range tasks {
			if len(task.Ports) > 0 {
				simpleTasks = append(simpleTasks, Task{Host: task.Host, Port: task.Ports[0], Ports: task.Ports})
			}
		}

		// Try to handle old app id format without slashes
		appPath := appId
		if !strings.HasPrefix(appId, "/") {
			appPath = "/" + appId
		}

		app := App{
			// Since Marathon 0.7, apps are namespaced with path
			Id: appPath,
			// Used for template
			EscapedId:       strings.Replace(appId, "/", "::", -1),
			Tasks:           simpleTasks,
			HealthCheckPath: parseHealthCheckPath(marathonApps[appId].HealthChecks),
			Env:             marathonApps[appId].Env,
			ServicePorts:    marathonApps[appId].Ports,
		}

		apps = append(apps, app)
	}
	return apps
}

func parseHealthCheckPath(checks []HealthChecks) string {
	if len(checks) > 0 {
		return checks[0].Path
	}
	return ""
}

/*
	Apps returns a struct that describes Marathon current app and their
	sub tasks information.

	Parameters:
		endpoint: Marathon HTTP endpoint, e.g. http://localhost:8080
*/
func FetchApps(maraconf configuration.Marathon) (AppList, error) {

	var applist AppList
	var err error

	// try all configured endpoints until one succeeds
	for _, url := range maraconf.Endpoints() {
		applist, err = _fetchApps(url)
		if err == nil {
			return applist, err
		}
	}
	// return last error
	return nil, err
}

func _fetchApps(url string) (AppList, error) {
	tasks, err := fetchTasks(url)
	if err != nil {
		return nil, err
	}

	marathonApps, err := fetchMarathonApps(url)
	if err != nil {
		return nil, err
	}

	apps := createApps(tasks, marathonApps)
	sort.Sort(apps)
	return apps, nil
}
<|endoftext|>


<commit_before>package nsqlookupd

import (
	"io"
	"net"

	"github.com/nsqio/nsq/internal/protocol"
)

type tcpServer struct {
	ctx *Context
}

func (p *tcpServer) Handle(clientConn net.Conn) {
	p.ctx.nsqlookupd.logf(LOG_INFO, "TCP: new client(%s)", clientConn.RemoteAddr())

	// The client should initialize itself by sending a 4 byte sequence indicating
	// the version of the protocol that it intends to communicate, this will allow us
	// to gracefully upgrade the protocol away from text/line oriented to whatever...
	buf := make([]byte, 4)
	_, err := io.ReadFull(clientConn, buf)
	if err != nil {
		p.ctx.nsqlookupd.logf(LOG_ERROR, "failed to read protocol version - %s", err)
		return
	}
	protocolMagic := string(buf)

	p.ctx.nsqlookupd.logf(LOG_INFO, "CLIENT(%s): desired protocol magic '%s'",
		clientConn.RemoteAddr(), protocolMagic)

	var prot protocol.Protocol
	switch protocolMagic {
	case "  V1":
		prot = &LookupProtocolV1{ctx: p.ctx}
	default:
		protocol.SendResponse(clientConn, []byte("E_BAD_PROTOCOL"))
		clientConn.Close()
		p.ctx.nsqlookupd.logf(LOG_ERROR, "client(%s) bad protocol magic '%s'",
			clientConn.RemoteAddr(), protocolMagic)
		return
	}

	err = prot.IOLoop(clientConn)
	if err != nil {
		p.ctx.nsqlookupd.logf(LOG_ERROR, "client(%s) - %s", clientConn.RemoteAddr(), err)
		return
	}
}
<commit_msg>nsqlookupd: close conn when magic read fails<commit_after>package nsqlookupd

import (
	"io"
	"net"

	"github.com/nsqio/nsq/internal/protocol"
)

type tcpServer struct {
	ctx *Context
}

func (p *tcpServer) Handle(clientConn net.Conn) {
	p.ctx.nsqlookupd.logf(LOG_INFO, "TCP: new client(%s)", clientConn.RemoteAddr())

	// The client should initialize itself by sending a 4 byte sequence indicating
	// the version of the protocol that it intends to communicate, this will allow us
	// to gracefully upgrade the protocol away from text/line oriented to whatever...
	buf := make([]byte, 4)
	_, err := io.ReadFull(clientConn, buf)
	if err != nil {
		p.ctx.nsqlookupd.logf(LOG_ERROR, "failed to read protocol version - %s", err)
		clientConn.Close()
		return
	}
	protocolMagic := string(buf)

	p.ctx.nsqlookupd.logf(LOG_INFO, "CLIENT(%s): desired protocol magic '%s'",
		clientConn.RemoteAddr(), protocolMagic)

	var prot protocol.Protocol
	switch protocolMagic {
	case "  V1":
		prot = &LookupProtocolV1{ctx: p.ctx}
	default:
		protocol.SendResponse(clientConn, []byte("E_BAD_PROTOCOL"))
		clientConn.Close()
		p.ctx.nsqlookupd.logf(LOG_ERROR, "client(%s) bad protocol magic '%s'",
			clientConn.RemoteAddr(), protocolMagic)
		return
	}

	err = prot.IOLoop(clientConn)
	if err != nil {
		p.ctx.nsqlookupd.logf(LOG_ERROR, "client(%s) - %s", clientConn.RemoteAddr(), err)
		return
	}
}
<|endoftext|>


<commit_before>package addrs

import (
	"fmt"

	"github.com/hashicorp/terraform/tfdiags"

	"github.com/hashicorp/hcl2/hcl"
)

// ProviderConfig is the address of a provider configuration.
type ProviderConfig struct {
	Type string

	// If not empty, Alias identifies which non-default (aliased) provider
	// configuration this address refers to.
	Alias string
}

// NewDefaultProviderConfig returns the address of the default (un-aliased)
// configuration for the provider with the given type name.
func NewDefaultProviderConfig(typeName string) ProviderConfig {
	return ProviderConfig{
		Type: typeName,
	}
}

// ParseProviderConfigCompact parses the given absolute traversal as a relative
// provider address in compact form. The following are examples of traversals
// that can be successfully parsed as compact relative provider configuration
// addresses:
//
//     aws
//     aws.foo
//
// This function will panic if given a relative traversal.
//
// If the returned diagnostics contains errors then the result value is invalid
// and must not be used.
func ParseProviderConfigCompact(traversal hcl.Traversal) (ProviderConfig, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	ret := ProviderConfig{
		Type: traversal.RootName(),
	}

	if len(traversal) < 2 {
		// Just a type name, then.
		return ret, diags
	}

	aliasStep := traversal[1]
	switch ts := aliasStep.(type) {
	case hcl.TraverseAttr:
		ret.Alias = ts.Name
		return ret, diags
	default:
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "The provider type name must either stand alone or be followed by an alias name separated with a dot.",
			Subject:  aliasStep.SourceRange().Ptr(),
		})
	}

	if len(traversal) > 2 {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "Extraneous extra operators after provider configuration address.",
			Subject:  traversal[2:].SourceRange().Ptr(),
		})
	}

	return ret, diags
}

// Absolute returns an AbsProviderConfig from the receiver and the given module
// instance address.
func (pc ProviderConfig) Absolute(module ModuleInstance) AbsProviderConfig {
	return AbsProviderConfig{
		Module:         module,
		ProviderConfig: pc,
	}
}

func (pc ProviderConfig) String() string {
	if pc.Alias != "" {
		return fmt.Sprintf("provider.%s.%s", pc.Type, pc.Alias)
	}

	return "provider." + pc.Type
}

// StringCompact is an alternative to String that returns the form that can
// be parsed by ParseProviderConfigCompact, without the "provider." prefix.
func (pc ProviderConfig) StringCompact() string {
	if pc.Alias != "" {
		return fmt.Sprintf("%s.%s", pc.Type, pc.Alias)
	}
	return pc.Type
}

// AbsProviderConfig is the absolute address of a provider configuration
// within a particular module instance.
type AbsProviderConfig struct {
	Module         ModuleInstance
	ProviderConfig ProviderConfig
}

// ParseAbsProviderConfig parses the given traversal as an absolute provider
// address. The following are examples of traversals that can be successfully
// parsed as absolute provider configuration addresses:
//
//     provider.aws
//     provider.aws.foo
//     module.bar.provider.aws
//     module.bar.module.baz.provider.aws.foo
//     module.foo[1].provider.aws.foo
//
// This type of address is used, for example, to record the relationships
// between resources and provider configurations in the state structure.
// This type of address is not generally used in the UI, except in error
// messages that refer to provider configurations.
func ParseAbsProviderConfig(traversal hcl.Traversal) (AbsProviderConfig, tfdiags.Diagnostics) {
	modInst, remain, diags := parseModuleInstancePrefix(traversal)
	ret := AbsProviderConfig{
		Module: modInst,
	}
	if len(remain) < 2 || remain.RootName() != "provider" {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "Provider address must begin with \"provider.\", followed by a provider type name.",
			Subject:  remain.SourceRange().Ptr(),
		})
		return ret, diags
	}
	if len(remain) > 3 {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "Extraneous operators after provider configuration alias.",
			Subject:  hcl.Traversal(remain[3:]).SourceRange().Ptr(),
		})
		return ret, diags
	}

	if tt, ok := remain[1].(hcl.TraverseAttr); ok {
		ret.ProviderConfig.Type = tt.Name
	} else {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "The prefix \"provider.\" must be followed by a provider type name.",
			Subject:  remain[1].SourceRange().Ptr(),
		})
		return ret, diags
	}

	if len(remain) == 3 {
		if tt, ok := remain[2].(hcl.TraverseAttr); ok {
			ret.ProviderConfig.Alias = tt.Name
		} else {
			diags = diags.Append(&hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  "Invalid provider configuration address",
				Detail:   "Provider type name must be followed by a configuration alias name.",
				Subject:  remain[2].SourceRange().Ptr(),
			})
			return ret, diags
		}
	}

	return ret, diags
}

// ProviderConfigDefault returns the address of the default provider config
// of the given type inside the recieving module instance.
func (m ModuleInstance) ProviderConfigDefault(name string) AbsProviderConfig {
	return AbsProviderConfig{
		Module: m,
		ProviderConfig: ProviderConfig{
			Type: name,
		},
	}
}

// ProviderConfigAliased returns the address of an aliased provider config
// of with given type and alias inside the recieving module instance.
func (m ModuleInstance) ProviderConfigAliased(name, alias string) AbsProviderConfig {
	return AbsProviderConfig{
		Module: m,
		ProviderConfig: ProviderConfig{
			Type:  name,
			Alias: alias,
		},
	}
}

// Inherited returns an address that the receiving configuration address might
// inherit from in a parent module. The second bool return value indicates if
// such inheritance is possible, and thus whether the returned address is valid.
//
// Inheritance is possible only for default (un-aliased) providers in modules
// other than the root module. Even if a valid address is returned, inheritence
// may not be performed for other reasons, such as if the calling module
// provided explicit provider configurations within the call for this module.
// The ProviderTransformer graph transform in the main terraform module has
// the authoritative logic for provider inheritance, and this method is here
// mainly just for its benefit.
func (pc AbsProviderConfig) Inherited() (AbsProviderConfig, bool) {
	// Can't inherit if we're already in the root.
	if len(pc.Module) == 0 {
		return AbsProviderConfig{}, false
	}

	// Can't inherit if we have an alias.
	if pc.ProviderConfig.Alias != "" {
		return AbsProviderConfig{}, false
	}

	// Otherwise, we might inherit from a configuration with the same
	// provider name in the parent module instance.
	parentMod := pc.Module.Parent()
	return pc.ProviderConfig.Absolute(parentMod), true
}

func (pc AbsProviderConfig) String() string {
	if len(pc.Module) == 0 {
		return pc.ProviderConfig.String()
	}
	return fmt.Sprintf("%s.%s", pc.Module.String(), pc.ProviderConfig.String())
}
<commit_msg>addrs: Generate special string for invalid ProviderConfig<commit_after>package addrs

import (
	"fmt"

	"github.com/hashicorp/terraform/tfdiags"

	"github.com/hashicorp/hcl2/hcl"
)

// ProviderConfig is the address of a provider configuration.
type ProviderConfig struct {
	Type string

	// If not empty, Alias identifies which non-default (aliased) provider
	// configuration this address refers to.
	Alias string
}

// NewDefaultProviderConfig returns the address of the default (un-aliased)
// configuration for the provider with the given type name.
func NewDefaultProviderConfig(typeName string) ProviderConfig {
	return ProviderConfig{
		Type: typeName,
	}
}

// ParseProviderConfigCompact parses the given absolute traversal as a relative
// provider address in compact form. The following are examples of traversals
// that can be successfully parsed as compact relative provider configuration
// addresses:
//
//     aws
//     aws.foo
//
// This function will panic if given a relative traversal.
//
// If the returned diagnostics contains errors then the result value is invalid
// and must not be used.
func ParseProviderConfigCompact(traversal hcl.Traversal) (ProviderConfig, tfdiags.Diagnostics) {
	var diags tfdiags.Diagnostics
	ret := ProviderConfig{
		Type: traversal.RootName(),
	}

	if len(traversal) < 2 {
		// Just a type name, then.
		return ret, diags
	}

	aliasStep := traversal[1]
	switch ts := aliasStep.(type) {
	case hcl.TraverseAttr:
		ret.Alias = ts.Name
		return ret, diags
	default:
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "The provider type name must either stand alone or be followed by an alias name separated with a dot.",
			Subject:  aliasStep.SourceRange().Ptr(),
		})
	}

	if len(traversal) > 2 {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "Extraneous extra operators after provider configuration address.",
			Subject:  traversal[2:].SourceRange().Ptr(),
		})
	}

	return ret, diags
}

// Absolute returns an AbsProviderConfig from the receiver and the given module
// instance address.
func (pc ProviderConfig) Absolute(module ModuleInstance) AbsProviderConfig {
	return AbsProviderConfig{
		Module:         module,
		ProviderConfig: pc,
	}
}

func (pc ProviderConfig) String() string {
	if pc.Type == "" {
		// Should never happen; always indicates a bug
		return "provider.<invalid>"
	}

	if pc.Alias != "" {
		return fmt.Sprintf("provider.%s.%s", pc.Type, pc.Alias)
	}

	return "provider." + pc.Type
}

// StringCompact is an alternative to String that returns the form that can
// be parsed by ParseProviderConfigCompact, without the "provider." prefix.
func (pc ProviderConfig) StringCompact() string {
	if pc.Alias != "" {
		return fmt.Sprintf("%s.%s", pc.Type, pc.Alias)
	}
	return pc.Type
}

// AbsProviderConfig is the absolute address of a provider configuration
// within a particular module instance.
type AbsProviderConfig struct {
	Module         ModuleInstance
	ProviderConfig ProviderConfig
}

// ParseAbsProviderConfig parses the given traversal as an absolute provider
// address. The following are examples of traversals that can be successfully
// parsed as absolute provider configuration addresses:
//
//     provider.aws
//     provider.aws.foo
//     module.bar.provider.aws
//     module.bar.module.baz.provider.aws.foo
//     module.foo[1].provider.aws.foo
//
// This type of address is used, for example, to record the relationships
// between resources and provider configurations in the state structure.
// This type of address is not generally used in the UI, except in error
// messages that refer to provider configurations.
func ParseAbsProviderConfig(traversal hcl.Traversal) (AbsProviderConfig, tfdiags.Diagnostics) {
	modInst, remain, diags := parseModuleInstancePrefix(traversal)
	ret := AbsProviderConfig{
		Module: modInst,
	}
	if len(remain) < 2 || remain.RootName() != "provider" {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "Provider address must begin with \"provider.\", followed by a provider type name.",
			Subject:  remain.SourceRange().Ptr(),
		})
		return ret, diags
	}
	if len(remain) > 3 {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "Extraneous operators after provider configuration alias.",
			Subject:  hcl.Traversal(remain[3:]).SourceRange().Ptr(),
		})
		return ret, diags
	}

	if tt, ok := remain[1].(hcl.TraverseAttr); ok {
		ret.ProviderConfig.Type = tt.Name
	} else {
		diags = diags.Append(&hcl.Diagnostic{
			Severity: hcl.DiagError,
			Summary:  "Invalid provider configuration address",
			Detail:   "The prefix \"provider.\" must be followed by a provider type name.",
			Subject:  remain[1].SourceRange().Ptr(),
		})
		return ret, diags
	}

	if len(remain) == 3 {
		if tt, ok := remain[2].(hcl.TraverseAttr); ok {
			ret.ProviderConfig.Alias = tt.Name
		} else {
			diags = diags.Append(&hcl.Diagnostic{
				Severity: hcl.DiagError,
				Summary:  "Invalid provider configuration address",
				Detail:   "Provider type name must be followed by a configuration alias name.",
				Subject:  remain[2].SourceRange().Ptr(),
			})
			return ret, diags
		}
	}

	return ret, diags
}

// ProviderConfigDefault returns the address of the default provider config
// of the given type inside the recieving module instance.
func (m ModuleInstance) ProviderConfigDefault(name string) AbsProviderConfig {
	return AbsProviderConfig{
		Module: m,
		ProviderConfig: ProviderConfig{
			Type: name,
		},
	}
}

// ProviderConfigAliased returns the address of an aliased provider config
// of with given type and alias inside the recieving module instance.
func (m ModuleInstance) ProviderConfigAliased(name, alias string) AbsProviderConfig {
	return AbsProviderConfig{
		Module: m,
		ProviderConfig: ProviderConfig{
			Type:  name,
			Alias: alias,
		},
	}
}

// Inherited returns an address that the receiving configuration address might
// inherit from in a parent module. The second bool return value indicates if
// such inheritance is possible, and thus whether the returned address is valid.
//
// Inheritance is possible only for default (un-aliased) providers in modules
// other than the root module. Even if a valid address is returned, inheritence
// may not be performed for other reasons, such as if the calling module
// provided explicit provider configurations within the call for this module.
// The ProviderTransformer graph transform in the main terraform module has
// the authoritative logic for provider inheritance, and this method is here
// mainly just for its benefit.
func (pc AbsProviderConfig) Inherited() (AbsProviderConfig, bool) {
	// Can't inherit if we're already in the root.
	if len(pc.Module) == 0 {
		return AbsProviderConfig{}, false
	}

	// Can't inherit if we have an alias.
	if pc.ProviderConfig.Alias != "" {
		return AbsProviderConfig{}, false
	}

	// Otherwise, we might inherit from a configuration with the same
	// provider name in the parent module instance.
	parentMod := pc.Module.Parent()
	return pc.ProviderConfig.Absolute(parentMod), true
}

func (pc AbsProviderConfig) String() string {
	if len(pc.Module) == 0 {
		return pc.ProviderConfig.String()
	}
	return fmt.Sprintf("%s.%s", pc.Module.String(), pc.ProviderConfig.String())
}
<|endoftext|>


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

// Support for test coverage.

package testing

import (
	"fmt"
	"os"
)

// CoverBlock records the coverage data for a single basic block.
// NOTE: This struct is internal to the testing infrastructure and may change.
// It is not covered (yet) by the Go 1 compatibility guidelines.
type CoverBlock struct {
	Line0 uint32
	Col0  uint16
	Line1 uint32
	Col1  uint16
	Stmts uint16
}

var cover Cover

// Cover records information about test coverage checking.
// NOTE: This struct is internal to the testing infrastructure and may change.
// It is not covered (yet) by the Go 1 compatibility guidelines.
type Cover struct {
	Mode            string
	Counters        map[string][]uint32
	Blocks          map[string][]CoverBlock
	CoveredPackages string
}

// Coverage reports the current code coverage as a fraction in the range [0, 1].
// If coverage is not enabled, Coverage returns 0.
//
// When running a large set of sequential test cases, checking Coverage after each one
// can be useful for identifying which test cases exercise new code paths.
// It is not a replacement for the reports generated by 'go test -cover' and
// 'go tool cover'.
func Coverage() float64 {
	var n, d int64
	for _, counters := range cover.Counters {
		for _, c := range counters {
			if c > 0 {
				n++
			}
			d++
		}
	}
	if d == 0 {
		return 0
	}
	return float64(n) / float64(d)
}

// RegisterCover records the coverage data accumulators for the tests.
// NOTE: This function is internal to the testing infrastructure and may change.
// It is not covered (yet) by the Go 1 compatibility guidelines.
func RegisterCover(c Cover) {
	cover = c
}

// mustBeNil checks the error and, if present, reports it and exits.
func mustBeNil(err error) {
	if err != nil {
		fmt.Fprintf(os.Stderr, "testing: %s\n", err)
		os.Exit(2)
	}
}

// coverReport reports the coverage percentage and writes a coverage profile if requested.
func coverReport() {
	var f *os.File
	var err error
	if *coverProfile != "" {
		f, err = os.Create(toOutputDir(*coverProfile))
		mustBeNil(err)
		fmt.Fprintf(f, "mode: %s\n", cover.Mode)
		defer func() { mustBeNil(f.Close()) }()
	}

	var active, total int64
	for name, counts := range cover.Counters {
		blocks := cover.Blocks[name]
		for i, count := range counts {
			stmts := int64(blocks[i].Stmts)
			total += stmts
			if count > 0 {
				active += stmts
			}
			if f != nil {
				_, err := fmt.Fprintf(f, "%s:%d.%d,%d.%d %d %d\n", name,
					blocks[i].Line0, blocks[i].Col0,
					blocks[i].Line1, blocks[i].Col1,
					stmts,
					count)
				mustBeNil(err)
			}
		}
	}
	if total == 0 {
		total = 1
	}
	fmt.Printf("coverage: %.1f%% of statements%s\n", 100*float64(active)/float64(total), cover.CoveredPackages)
}
<commit_msg>testing: read coverage counters atomically For -mode=atomic, we need to read the counters using an atomic load to avoid a race. Not worth worrying about when -mode=atomic is set during generation of the profile, so we use atomic loads always.<commit_after>// Copyright 2013 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.

// Support for test coverage.

package testing

import (
	"fmt"
	"os"
	"sync/atomic"
)

// CoverBlock records the coverage data for a single basic block.
// NOTE: This struct is internal to the testing infrastructure and may change.
// It is not covered (yet) by the Go 1 compatibility guidelines.
type CoverBlock struct {
	Line0 uint32
	Col0  uint16
	Line1 uint32
	Col1  uint16
	Stmts uint16
}

var cover Cover

// Cover records information about test coverage checking.
// NOTE: This struct is internal to the testing infrastructure and may change.
// It is not covered (yet) by the Go 1 compatibility guidelines.
type Cover struct {
	Mode            string
	Counters        map[string][]uint32
	Blocks          map[string][]CoverBlock
	CoveredPackages string
}

// Coverage reports the current code coverage as a fraction in the range [0, 1].
// If coverage is not enabled, Coverage returns 0.
//
// When running a large set of sequential test cases, checking Coverage after each one
// can be useful for identifying which test cases exercise new code paths.
// It is not a replacement for the reports generated by 'go test -cover' and
// 'go tool cover'.
func Coverage() float64 {
	var n, d int64
	for _, counters := range cover.Counters {
		for i := range counters {
			if atomic.LoadUint32(&counters[i]) > 0 {
				n++
			}
			d++
		}
	}
	if d == 0 {
		return 0
	}
	return float64(n) / float64(d)
}

// RegisterCover records the coverage data accumulators for the tests.
// NOTE: This function is internal to the testing infrastructure and may change.
// It is not covered (yet) by the Go 1 compatibility guidelines.
func RegisterCover(c Cover) {
	cover = c
}

// mustBeNil checks the error and, if present, reports it and exits.
func mustBeNil(err error) {
	if err != nil {
		fmt.Fprintf(os.Stderr, "testing: %s\n", err)
		os.Exit(2)
	}
}

// coverReport reports the coverage percentage and writes a coverage profile if requested.
func coverReport() {
	var f *os.File
	var err error
	if *coverProfile != "" {
		f, err = os.Create(toOutputDir(*coverProfile))
		mustBeNil(err)
		fmt.Fprintf(f, "mode: %s\n", cover.Mode)
		defer func() { mustBeNil(f.Close()) }()
	}

	var active, total int64
	var count uint32
	for name, counts := range cover.Counters {
		blocks := cover.Blocks[name]
		for i := range counts {
			stmts := int64(blocks[i].Stmts)
			total += stmts
			count = atomic.LoadUint32(&counts[i]) // For -mode=atomic.
			if count > 0 {
				active += stmts
			}
			if f != nil {
				_, err := fmt.Fprintf(f, "%s:%d.%d,%d.%d %d %d\n", name,
					blocks[i].Line0, blocks[i].Col0,
					blocks[i].Line1, blocks[i].Col1,
					stmts,
					count)
				mustBeNil(err)
			}
		}
	}
	if total == 0 {
		total = 1
	}
	fmt.Printf("coverage: %.1f%% of statements%s\n", 100*float64(active)/float64(total), cover.CoveredPackages)
}
<|endoftext|>