<commit_before>// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

// Package minterm implements minimal terminal functions.
package minterm

import (
	"errors"
	"fmt"
	"github.com/keybase/go-crypto/ssh/terminal"
	"io"
	"os"
	"strings"
)

// MinTerm is a minimal terminal interface.
type MinTerm struct {
	termIn       *os.File
	termOut      *os.File
	closeTermOut bool
	width        int
	height       int
}

var ErrPromptInterrupted = errors.New("prompt interrupted")

// New creates a new MinTerm and opens the terminal file.  Any
// errors that happen while opening or getting the terminal size
// are returned.
func New() (*MinTerm, error) {
	m := &MinTerm{}
	if err := m.open(); err != nil {
		return nil, err
	}
	return m, nil
}

// Shutdown closes the terminal.
func (m *MinTerm) Shutdown() error {
	// this can hang waiting for newline, so do it in a goroutine.
	// application shutting down, so will get closed by os anyway...
	if m.termIn != nil {
		go m.termIn.Close()
	}
	if m.termOut != nil && m.closeTermOut {
		go m.termOut.Close()
	}
	return nil
}

// Size returns the width and height of the terminal.
func (m *MinTerm) Size() (int, int) {
	return m.width, m.height
}

// Write writes a string to the terminal.
func (m *MinTerm) Write(s string) error {
	_, err := fmt.Fprint(m.getReadWriter(), s)
	return err
}

// Prompt gets a line of input from the terminal.  It displays the text in
// the prompt parameter first.
func (m *MinTerm) Prompt(prompt string) (string, error) {
	m.Write(prompt)
	return m.readLine()
}

// PromptPassword gets a line of input from the terminal, but
// nothing is echoed to the terminal to hide the text.
func (m *MinTerm) PromptPassword(prompt string) (string, error) {
	m.Write(prompt)
	if !strings.HasSuffix(prompt, ": ") {
		m.Write(": ")
	}
	return m.readSecret()
}

func (m *MinTerm) fdIn() int { return int(m.termIn.Fd()) }

func (m *MinTerm) readLine() (string, error) {
	fd := int(m.fdIn())
	oldState, err := terminal.MakeRaw(fd)
	if err != nil {
		return "", err
	}
	defer terminal.Restore(fd, oldState)
	var ret string
	ret, err = terminal.NewTerminal(m.getReadWriter(), "").ReadLine()
	return ret, convertErr(err)
}

func (m *MinTerm) readSecret() (string, error) {
	fd := int(m.fdIn())
	oldState, err := terminal.MakeRaw(fd)
	if err != nil {
		return "", err
	}
	defer terminal.Restore(fd, oldState)
	var ret string
	ret, err = terminal.NewTerminal(m.getReadWriter(), "").ReadPassword("")
	return ret, convertErr(err)
}

func convertErr(e error) error {
	if e == io.ErrUnexpectedEOF {
		e = ErrPromptInterrupted
	}
	return e
}
<commit_msg>Restore out of raw mode on shutdown<commit_after>// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

// Package minterm implements minimal terminal functions.
package minterm

import (
	"errors"
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/keybase/go-crypto/ssh/terminal"
)

// MinTerm is a minimal terminal interface.
type MinTerm struct {
	termIn       *os.File
	termOut      *os.File
	closeTermOut bool
	width        int
	height       int
	raw          bool
	oldState     *terminal.State
}

var ErrPromptInterrupted = errors.New("prompt interrupted")

// New creates a new MinTerm and opens the terminal file.  Any
// errors that happen while opening or getting the terminal size
// are returned.
func New() (*MinTerm, error) {
	m := &MinTerm{}
	if err := m.open(); err != nil {
		return nil, err
	}
	return m, nil
}

// Shutdown closes the terminal.
func (m *MinTerm) Shutdown() error {
	m.restore()
	// this can hang waiting for newline, so do it in a goroutine.
	// application shutting down, so will get closed by os anyway...
	if m.termIn != nil {
		go m.termIn.Close()
	}
	if m.termOut != nil && m.closeTermOut {
		go m.termOut.Close()
	}
	return nil
}

// Size returns the width and height of the terminal.
func (m *MinTerm) Size() (int, int) {
	return m.width, m.height
}

// Write writes a string to the terminal.
func (m *MinTerm) Write(s string) error {
	_, err := fmt.Fprint(m.getReadWriter(), s)
	return err
}

// Prompt gets a line of input from the terminal.  It displays the text in
// the prompt parameter first.
func (m *MinTerm) Prompt(prompt string) (string, error) {
	m.Write(prompt)
	return m.readLine()
}

// PromptPassword gets a line of input from the terminal, but
// nothing is echoed to the terminal to hide the text.
func (m *MinTerm) PromptPassword(prompt string) (string, error) {
	m.Write(prompt)
	if !strings.HasSuffix(prompt, ": ") {
		m.Write(": ")
	}
	return m.readSecret()
}

func (m *MinTerm) fdIn() int { return int(m.termIn.Fd()) }

func (m *MinTerm) readLine() (string, error) {
	m.makeRaw()
	defer m.restore()
	ret, err := terminal.NewTerminal(m.getReadWriter(), "").ReadLine()
	return ret, convertErr(err)
}

func (m *MinTerm) readSecret() (string, error) {
	m.makeRaw()
	defer m.restore()
	ret, err := terminal.NewTerminal(m.getReadWriter(), "").ReadPassword("")
	return ret, convertErr(err)
}

func (m *MinTerm) makeRaw() error {
	fd := int(m.fdIn())
	oldState, err := terminal.MakeRaw(fd)
	if err != nil {
		return err
	}
	m.raw = true
	m.oldState = oldState
	return nil
}

func (m *MinTerm) restore() {
	if !m.raw {
		return
	}
	fd := int(m.fdIn())
	terminal.Restore(fd, m.oldState)
	m.raw = false
	m.oldState = nil
}

func convertErr(e error) error {
	if e == io.ErrUnexpectedEOF {
		e = ErrPromptInterrupted
	}
	return e
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/northbright/createzip"
	"io"
	"net/http"
)

type MyHandler struct{}

var (
	mux = make(map[string]func(http.ResponseWriter, *http.Request))
)

func hello(w http.ResponseWriter, r *http.Request) {
	// Create zip file for HTTP server
	zf := createzip.NewForHTTP(w, "new.zip")
	// Add file into zip file. 1st param is the real file path, 2nd param is the file name in the zip file.
	// If file name in the zip file is empty, it will put the file in the root dir of the zip.
	zf.AddFile("./README.md", "")
	zf.AddFile("./main.go", "example/main.go")
	zf.Close()
}

func (*MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	url := r.URL.String()
	if h, ok := mux[url]; ok {
		h(w, r)
		return
	}
	io.WriteString(w, "URL can not found: "+r.URL.String())
}

func main() {
	mux["/"] = hello

	server := http.Server{
		Addr:    ":8080",
		Handler: &MyHandler{},
	}

	err := server.ListenAndServe()
	if err != nil {
		fmt.Printf("ListenAndServe: %v", err)
	}

	// Output:
}
<commit_msg>Import non-standard packages after standard ones.<commit_after>package main

import (
	"fmt"
	"io"
	"net/http"

	"github.com/northbright/createzip"
)

type MyHandler struct{}

var (
	mux = make(map[string]func(http.ResponseWriter, *http.Request))
)

func hello(w http.ResponseWriter, r *http.Request) {
	// Create zip file for HTTP server
	zf := createzip.NewForHTTP(w, "new.zip")
	// Add file into zip file. 1st param is the real file path, 2nd param is the file name in the zip file.
	// If file name in the zip file is empty, it will put the file in the root dir of the zip.
	zf.AddFile("./README.md", "")
	zf.AddFile("./main.go", "example/main.go")
	zf.Close()
}

func (*MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	url := r.URL.String()
	if h, ok := mux[url]; ok {
		h(w, r)
		return
	}
	io.WriteString(w, "URL can not found: "+r.URL.String())
}

func main() {
	mux["/"] = hello

	server := http.Server{
		Addr:    ":8080",
		Handler: &MyHandler{},
	}

	err := server.ListenAndServe()
	if err != nil {
		fmt.Printf("ListenAndServe: %v", err)
	}

	// Output:
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"gnl2go/gnl2go"
)

/* we can ran this as binary for unit tests (for example build it on
   on one machine(mac or win) and run on other(linux), probably
   later will convert into ipvs_test.go */
func main() {
	fmt.Println("Start Test/Example Run")
	ipvs := new(gnl2go.IpvsClient)
	err := ipvs.Init()
	if err != nil {
		fmt.Printf("Cant initialize client, erro is %#v\n", err)
		return
	}
	err = ipvs.Flush()
	if err != nil {
		fmt.Printf("Error while running Flush method %#v\n", err)
		return
	}
	defer ipvs.Exit()
	p, err := ipvs.GetPools()
	if err != nil {
		fmt.Printf("Error while running GetPools method %#v\n", err)
		return
	}
	if len(p) != 0 {
		fmt.Printf("Flush method havent cleared all the data\n")
		return
	}
	noIPv6 := false
	//Testing IPv6 AddService
	err = ipvs.AddService("2a02::33", 80, uint16(gnl2go.ToProtoNum("tcp")), "wlc")
	if err != nil {
		fmt.Printf("Error while adding IPv6 Service w/ AddService: %#v\n",
			" could be because of lack ipv6 support in compiled ipvs (default in",
			" rasberian)\n")
		noIPv6 = true
	}

	//Testing IPv4 AddService
	err = ipvs.AddService("192.168.1.1", 80, uint16(gnl2go.ToProtoNum("tcp")), "wrr")
	if err != nil {
		fmt.Printf("cant add ipv4 service w/ AddService; err is : %#v\n", err)
		return
	}

	//Testing AddDest for IPv4
	err = ipvs.AddDest("192.168.1.1", 80, "127.0.0.11", uint16(gnl2go.ToProtoNum("tcp")), 10)
	if err != nil {
		fmt.Printf("cant add ipv4 with AddDest; err is : %#v\n", err)
		return
	}

	//10 - syscall.AF_INET6, 2 - syscall.AF_INET
	//Testing AddFWMService for IPv6
	if !noIPv6 {
		err = ipvs.AddFWMService(1, "wrr", 10)
		if err != nil {
			fmt.Printf("cant add ipv6 service w/ AddFWMService; err is : %#v\n", err)
			return
		}
		err = ipvs.AddFWMService(1, "wrr", 10)
		//This is expected error because we already have this service
		if err != nil {
			fmt.Println(err)
		}
	}

	//Testing AddFWMService for IPv4
	err = ipvs.AddFWMService(2, "rr", 2)
	if err != nil {
		fmt.Printf("cant add ipv4 service w/ AddFWMService; err is : %#v\n", err)
		return
	}
	p, _ = ipvs.GetPools()
	if !noIPv6 {
		if len(p) != 4 {
			fmt.Printf("Something wrong, len of pool not equal",
				" to 4 but %v instead\n", len(p))
			return
		}
	} else {
		if len(p) != 2 {
			fmt.Printf("Something wrong, len of pool not equal",
				" to 2 but %v instead\n", len(p))
			return
		}
	}
	//Testing deleitation of the ipv4 service
	err = ipvs.DelService("192.168.1.1", 80, uint16(gnl2go.ToProtoNum("tcp")))
	if err != nil {
		fmt.Printf("error while running DelService for ipv4: %#v\n", err)
		return
	}
	if !noIPv6 {
		err = ipvs.DelService("2a02::33", 80, uint16(gnl2go.ToProtoNum("tcp")))
		if err != nil {
			fmt.Printf("error while deleting ipv6 service: %#v\n", err)
			return
		}
		err = ipvs.DelFWMService(1, 10)
		if err != nil {
			fmt.Printf("error while deleting ipv6 fwmark service: %#v\n", err)
			return
		}
	}
	err = ipvs.DelFWMService(2, 2)
	if err != nil {
		fmt.Printf("error while delete ipv4 fwmark service: %#v\n", err)
		return
	}
	/* AddService and AddDest already covered */
	ipvs.AddService("192.168.1.1", 80, uint16(gnl2go.ToProtoNum("tcp")), "wrr")
	ipvs.AddDest("192.168.1.1", 80, "127.0.0.11", uint16(gnl2go.ToProtoNum("tcp")), 10)
	/* Testing AddDestPort */
	err = ipvs.AddDestPort("192.168.1.1", 80, "127.0.0.11", 8080,
		uint16(gnl2go.ToProtoNum("tcp")),
		10, gnl2go.IPVS_MASQUERADING)
	if err != nil {
		fmt.Printf("error while running AddDestPort for ipv4: %#v\n", err)
		return
	}
	ipvs.AddDest("192.168.1.1", 80, "127.0.0.12", uint16(gnl2go.ToProtoNum("tcp")), 10)
	ipvs.AddDest("192.168.1.1", 80, "127.0.0.13", uint16(gnl2go.ToProtoNum("tcp")), 10)
	/* Testing Update Dest */
	err = ipvs.UpdateDest("192.168.1.1", 80, "127.0.0.13", uint16(gnl2go.ToProtoNum("tcp")), 20)
	if err != nil {
		fmt.Printf("error while running UpdateDest for ipv4: %#v\n", err)
		return
	}
	/* Testing DelDest */
	err = ipvs.DelDest("192.168.1.1", 80, "127.0.0.12", uint16(gnl2go.ToProtoNum("tcp")))
	if err != nil {
		fmt.Printf("error while running DelDest for ipv4: %#v\n", err)
	}
	if !noIPv6 {
		ipvs.AddFWMService(1, "wrr", 10)
		err = ipvs.AddFWMDestFWD(1, "fc00:1::12", 10, 0, 10, gnl2go.IPVS_MASQUERADING)
		if err != nil {
			fmt.Printf("error while running AddFWMDestFWD for ipv6: %#v\n", err)
			return
		}
		err = ipvs.AddFWMDest(10, "fc00:1::12", 10, 0, 10)
		//Expected: there is no service with fwmark 10
		if err != nil {
			fmt.Printf("expected error coz of lack fwmark 10: %#v\n", err)
		}

		ipvs.AddFWMDest(1, "fc00:2::12", 10, 0, 20)
		ipvs.AddFWMDest(1, "fc00:2:3::12", 10, 0, 30)
		/* Testing UpdateFWMDest */
		err = ipvs.UpdateFWMDest(1, "fc00:2:3::12", 10, 0, 33)
		if err != nil {
			fmt.Printf("error while running UpdateFWMDest : %#v\n", err)
			return
		}
		/* Testing DelFWMDest */
		err = ipvs.DelFWMDest(1, "fc00:2::12", 10, 0)
		if err != nil {
			fmt.Printf("error while running UpdateFWMDest: %#v\n", err)
			return
		}
	}
	fmt.Println("done")
}
<commit_msg>changelog: fix few tupos in example file<commit_after>package main

import (
	"fmt"
	"gnl2go/gnl2go"
)

/* we can ran this as binary for unit tests (for example build it on
   on one machine(mac or win) and run on other(linux), probably
   later will convert into ipvs_test.go */
func main() {
	fmt.Println("Start Test/Example Run")
	ipvs := new(gnl2go.IpvsClient)
	err := ipvs.Init()
	if err != nil {
		fmt.Printf("Cant initialize client, erro is %#v\n", err)
		return
	}
	err = ipvs.Flush()
	if err != nil {
		fmt.Printf("Error while running Flush method %#v\n", err)
		return
	}
	defer ipvs.Exit()
	p, err := ipvs.GetPools()
	if err != nil {
		fmt.Printf("Error while running GetPools method %#v\n", err)
		return
	}
	if len(p) != 0 {
		fmt.Printf("Flush method havent cleared all the data\n")
		return
	}
	noIPv6 := false
	//Testing IPv6 AddService
	err = ipvs.AddService("2a02::33", 80, uint16(gnl2go.ToProtoNum("tcp")), "wlc")
	if err != nil {
		fmt.Printf(`
			Error while adding IPv6 Service w/ AddService: %#v
			could be because of lack ipv6 support in compiled ipvs
			(default in rasberian)
			`, err)
		noIPv6 = true
	}

	//Testing IPv4 AddService
	err = ipvs.AddService("192.168.1.1", 80, uint16(gnl2go.ToProtoNum("tcp")), "wrr")
	if err != nil {
		fmt.Printf("cant add ipv4 service w/ AddService; err is : %#v\n", err)
		return
	}

	//Testing AddDest for IPv4
	err = ipvs.AddDest("192.168.1.1", 80, "127.0.0.11", uint16(gnl2go.ToProtoNum("tcp")), 10)
	if err != nil {
		fmt.Printf("cant add ipv4 with AddDest; err is : %#v\n", err)
		return
	}

	//10 - syscall.AF_INET6, 2 - syscall.AF_INET
	//Testing AddFWMService for IPv6
	if !noIPv6 {
		err = ipvs.AddFWMService(1, "wrr", 10)
		if err != nil {
			fmt.Printf("cant add ipv6 service w/ AddFWMService; err is : %#v\n", err)
			return
		}
		err = ipvs.AddFWMService(1, "wrr", 10)
		//This is expected error because we already have this service
		if err != nil {
			fmt.Println(err)
		}
	}

	//Testing AddFWMService for IPv4
	err = ipvs.AddFWMService(2, "rr", 2)
	if err != nil {
		fmt.Printf("cant add ipv4 service w/ AddFWMService; err is : %#v\n", err)
		return
	}
	p, _ = ipvs.GetPools()
	if !noIPv6 {
		if len(p) != 4 {
			fmt.Printf("Something wrong, len of pool not equal",
				" to 4 but %v instead\n", len(p))
			return
		}
	} else {
		if len(p) != 2 {
			fmt.Printf("Something wrong, len of pool not equal",
				" to 2 but %v instead\n", len(p))
			return
		}
	}
	//Testing deleitation of the ipv4 service
	err = ipvs.DelService("192.168.1.1", 80, uint16(gnl2go.ToProtoNum("tcp")))
	if err != nil {
		fmt.Printf("error while running DelService for ipv4: %#v\n", err)
		return
	}
	if !noIPv6 {
		err = ipvs.DelService("2a02::33", 80, uint16(gnl2go.ToProtoNum("tcp")))
		if err != nil {
			fmt.Printf("error while deleting ipv6 service: %#v\n", err)
			return
		}
		err = ipvs.DelFWMService(1, 10)
		if err != nil {
			fmt.Printf("error while deleting ipv6 fwmark service: %#v\n", err)
			return
		}
	}
	err = ipvs.DelFWMService(2, 2)
	if err != nil {
		fmt.Printf("error while delete ipv4 fwmark service: %#v\n", err)
		return
	}
	/* AddService and AddDest already covered */
	ipvs.AddService("192.168.1.1", 80, uint16(gnl2go.ToProtoNum("tcp")), "wrr")
	ipvs.AddDest("192.168.1.1", 80, "127.0.0.11", uint16(gnl2go.ToProtoNum("tcp")), 10)
	/* Testing AddDestPort */
	err = ipvs.AddDestPort("192.168.1.1", 80, "127.0.0.11", 8080,
		uint16(gnl2go.ToProtoNum("tcp")),
		10, gnl2go.IPVS_MASQUERADING)
	if err != nil {
		fmt.Printf("error while running AddDestPort for ipv4: %#v\n", err)
		return
	}
	ipvs.AddDest("192.168.1.1", 80, "127.0.0.12", uint16(gnl2go.ToProtoNum("tcp")), 10)
	ipvs.AddDest("192.168.1.1", 80, "127.0.0.13", uint16(gnl2go.ToProtoNum("tcp")), 10)
	/* Testing Update Dest */
	err = ipvs.UpdateDest("192.168.1.1", 80, "127.0.0.13", uint16(gnl2go.ToProtoNum("tcp")), 20)
	if err != nil {
		fmt.Printf("error while running UpdateDest for ipv4: %#v\n", err)
		return
	}
	/* Testing DelDest */
	err = ipvs.DelDest("192.168.1.1", 80, "127.0.0.12", uint16(gnl2go.ToProtoNum("tcp")))
	if err != nil {
		fmt.Printf("error while running DelDest for ipv4: %#v\n", err)
	}
	if !noIPv6 {
		ipvs.AddFWMService(1, "wrr", 10)
		err = ipvs.AddFWMDestFWD(1, "fc00:1::12", 10, 0, 10, gnl2go.IPVS_MASQUERADING)
		if err != nil {
			fmt.Printf("error while running AddFWMDestFWD for ipv6: %#v\n", err)
			return
		}
		err = ipvs.AddFWMDest(10, "fc00:1::12", 10, 0, 10)
		//Expected: there is no service with fwmark 10
		if err != nil {
			fmt.Printf("expected error coz of lack fwmark 10: %#v\n", err)
		}

		ipvs.AddFWMDest(1, "fc00:2::12", 10, 0, 20)
		ipvs.AddFWMDest(1, "fc00:2:3::12", 10, 0, 30)
		/* Testing UpdateFWMDest */
		err = ipvs.UpdateFWMDest(1, "fc00:2:3::12", 10, 0, 33)
		if err != nil {
			fmt.Printf("error while running UpdateFWMDest : %#v\n", err)
			return
		}
		/* Testing DelFWMDest */
		err = ipvs.DelFWMDest(1, "fc00:2::12", 10, 0)
		if err != nil {
			fmt.Printf("error while running UpdateFWMDest: %#v\n", err)
			return
		}
	}
	fmt.Println("done")
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"net/http"

	"github.com/kavehmz/short"
)

func main() {
	site := short.Site{Host: "https://short.kaveh.me/"}
	http.HandleFunc("/", site.Redirect)
	http.HandleFunc("/post", site.Post)
	log.Fatal(http.ListenAndServe(":8080", nil))
}
<commit_msg>adding profiling to example<commit_after>package main

import (
	"log"
	"net/http"

	_ "net/http/pprof"

	"github.com/kavehmz/short"
)

func main() {
	site := short.Site{Host: "https://short.kaveh.me/"}
	http.HandleFunc("/", site.Redirect)
	http.HandleFunc("/post", site.Post)
	log.Fatal(http.ListenAndServe(":8080", nil))
}
<|endoftext|>


<commit_before>package main

import (
	"runtime"

	"github.com/smartystreets/go-disruptor"
)

const (
	MaxConsumersPerGroup = 1
	MaxConsumerGroups    = 2
	MaxProducers         = 2
	ItemsToPublish       = 2
	ReportingFrequency   = 1000000 * 1 // 1 million * N
	RingSize             = 1024 * 16
	RingMask             = RingSize - 1
)

var ringBuffer [RingSize]int64

func main() {
	runtime.GOMAXPROCS(MaxConsumerGroups*MaxConsumersPerGroup + MaxProducers)

	writerCursor := disruptor.NewCursor()
	writerBarrier := disruptor.NewSharedWriterBarrier(writerCursor, RingSize)
	readerBarrier := startConsumerGroups(writerBarrier, writerCursor)
	writer := disruptor.NewSharedWriter(writerBarrier, readerBarrier)

	startProducers(writer)
}
func startProducers(writer *disruptor.SharedWriter) {
	for i := 0; i < MaxProducers-1; i++ {
		go publish(writer)
	}

	publish(writer)
}

func startConsumerGroups(upstream disruptor.Barrier, writer *disruptor.Cursor) disruptor.Barrier {
	for i := 0; i < MaxConsumerGroups; i++ {
		upstream = startConsumerGroup(i, upstream, writer)
	}

	return upstream
}
func startConsumerGroup(group int, upstreamBarrier disruptor.Barrier, writerCursor *disruptor.Cursor) disruptor.Barrier {
	readerCursors := []*disruptor.Cursor{}

	for i := 0; i < MaxConsumersPerGroup; i++ {
		readerCursor := disruptor.NewCursor()
		readerCursors = append(readerCursors, readerCursor)
		reader := disruptor.NewReader(upstreamBarrier, writerCursor, readerCursor)

		// constant time regardless of the number of items
		//go consume0(disruptor.NewSimpleReader(reader, NewExampleConsumerHandler()))

		// wildly sporadic latency for single-item publish, e.g. 2 seconds, 65 ms, etc.
		// faster for 2-3+ items per publish
		// go consume1(reader)

		if group == 0 {
			go consume1(reader)
		} else if group == 1 {
			go consume2(reader)
		} else {
			panic("only two consumer groups currently supported.")
		}
	}

	return disruptor.NewBarrier(readerCursors...)
}
<commit_msg>More TODOs.<commit_after>package main

import (
	"runtime"

	"github.com/smartystreets/go-disruptor"
)

const (
	MaxConsumersPerGroup = 1
	MaxConsumerGroups    = 2
	MaxProducers         = 2
	ItemsToPublish       = 2
	ReportingFrequency   = 1000000 * 1 // 1 million * N
	RingSize             = 1024 * 16
	RingMask             = RingSize - 1
)

var ringBuffer [RingSize]int64

func main() {
	runtime.GOMAXPROCS(MaxConsumerGroups*MaxConsumersPerGroup + MaxProducers)

	writerCursor := disruptor.NewCursor()
	writerBarrier := disruptor.NewSharedWriterBarrier(writerCursor, RingSize)
	readerBarrier := startConsumerGroups(writerBarrier, writerCursor)
	writer := disruptor.NewSharedWriter(writerBarrier, readerBarrier)

	startProducers(writer)
}
func startProducers(writer *disruptor.SharedWriter) {
	for i := 0; i < MaxProducers-1; i++ {
		go publish(writer)
	}

	publish(writer)
}

func startConsumerGroups(upstream disruptor.Barrier, writer *disruptor.Cursor) disruptor.Barrier {
	for i := 0; i < MaxConsumerGroups; i++ {
		upstream = startConsumerGroup(i, upstream, writer)
	}

	return upstream
}
func startConsumerGroup(group int, upstreamBarrier disruptor.Barrier, writerCursor *disruptor.Cursor) disruptor.Barrier {
	readerCursors := []*disruptor.Cursor{}

	for i := 0; i < MaxConsumersPerGroup; i++ {
		readerCursor := disruptor.NewCursor()
		readerCursors = append(readerCursors, readerCursor)
		reader := disruptor.NewReader(upstreamBarrier, writerCursor, readerCursor)

		// constant time regardless of the number of items
		//go consume0(disruptor.NewSimpleReader(reader, NewExampleConsumerHandler()))

		// TODO: wildly sporadic latency for single-item publish, e.g. 2 seconds, 65 ms, etc.
		// faster for 2-3+ items per publish
		// go consume1(reader)

		if group == 0 {
			go consume1(reader)
		} else if group == 1 {
			go consume2(reader)
		} else {
			panic("only two consumer groups currently supported.")
		}
	}

	return disruptor.NewBarrier(readerCursors...)
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/henrylee2cn/pholcus/exec"
	_ "github.com/pholcus/spider_lib"     // 此为公开维护的spider规则库
	_ "github.com/pholcus/spider_lib_pte" // 同样你也可以自由添加自己的规则库
)

func main() {
	// 设置运行时默认操作界面，并开始运行
	// 运行软件前，可设置 -a_ui 参数为"web"、"gui"或"cmd"，指定本次运行的操作界面
	// 其中"gui"仅支持Windows系统
	exec.DefaultRun("web")
}
<commit_msg>Comment out the private library connection<commit_after>package main

import (
	"github.com/henrylee2cn/pholcus/exec"
	_ "github.com/pholcus/spider_lib" // 此为公开维护的spider规则库
	// _ "github.com/pholcus/spider_lib_pte" // 同样你也可以自由添加自己的规则库
)

func main() {
	// 设置运行时默认操作界面，并开始运行
	// 运行软件前，可设置 -a_ui 参数为"web"、"gui"或"cmd"，指定本次运行的操作界面
	// 其中"gui"仅支持Windows系统
	exec.DefaultRun("web")
}
<|endoftext|>


<commit_before>package patch_test

import (
	"fmt"
	"github.com/smagch/patch"
	"strings"
)

func ExamplePatcher_Unmarshal() {
	type User struct {
		ID     int
		Name   string
		Email  string
		Active bool
	}
	p := patch.New(User{})
	data, err := p.Unmarshal([]byte(`{"Name": "gopher", "Active": true}`))
	if err != nil {
		fmt.Println(err.Error())
	}
	keys := data.Keys()
	fmt.Println(strings.Join(keys, ","))
	// Output:
	// Name,Active
}

func ExamplePatcher_Remove() {
	type User struct {
		ID    int    `json:"id"`
		Name  string `json:"name"`
		Email string `json:"email"`
	}
	p := patch.New(User{})
	data, err := p.Unmarshal([]byte(`{"name": "gopher", "email": "golang@hoge.hoge"}`))
	if err != nil {
		fmt.Println(err.Error())
	}
	email, found := data.Get("email")
	if found {
		data.Remove("email")
	}
	fmt.Println(email)
	fmt.Printf("%v", data.Values())
	// Output:
	// golang@hoge.hoge
	// [gopher]
}

func ExamplePatcher_Set() {
	type Article struct {
		ID     int    `json:"id"`
		UserID int    `json:"user_id"`
		Title  string `json:"title"`
		Desc   string `json:"desc"`
		Body   string `json:"body"`
	}
	p := patch.New(Article{})
	f, err := p.Unmarshal([]byte(`{"title": "the gopher", "desc": "description"}`))
	if err != nil {
		fmt.Println(err.Error())
	}
	f.Set("desc", "goggles its eyes")
	f.Set("body", "with deadly pale body")
	fmt.Printf("%v", f.Values())
	// Output:
	// [the gopher goggles its eyes with deadly pale body]
}

func ExampleSQL_Query() {
	type Post struct {
		ID          int    `json:"id"`
		UserId      int    `json:"user_id"`
		Title       string `json:"title"`
		Description string `json:"description"`
		Body        string `json:"body"`
	}
	p := patch.New(Post{})
	data, err := p.Unmarshal([]byte(`{"title": "Space Gopher", "body": "The body"}`))
	if err != nil {
		fmt.Println(err.Error())
	}
	id := 947
	q, args := data.SQL().Query(id)
	fmt.Println(q)
	query := fmt.Sprintf(`UPDATE posts SET %s WHERE id = ?`, q)
	fmt.Println(query)
	fmt.Printf("%#v", args)
	// Output:
	// title=?,body=?
	// UPDATE posts SET title=?,body=? WHERE id = ?
	// []interface {}{"Space Gopher", "The body", 947}
}

func ExampleSQL_QueryPostgres() {
	type Post struct {
		ID          int    `json:"id"`
		UserId      int    `json:"user_id"`
		Title       string `json:"title"`
		Description string `json:"description"`
		Body        string `json:"body"`
	}
	p := patch.New(Post{})
	data, err := p.Unmarshal([]byte(`{"title": "Space Gopher", "body": "The body"}`))
	if err != nil {
		fmt.Println(err.Error())
	}
	id := 947
	q, args := data.SQL().QueryPostgres(id)
	fmt.Println(q)
	query := fmt.Sprintf(`UPDATE posts SET %s WHERE id = $1`, q)
	fmt.Println(query)
	fmt.Printf("%#v", args)
	// Output:
	// title=$2,body=$3
	// UPDATE posts SET title=$2,body=$3 WHERE id = $1
	// []interface {}{947, "Space Gopher", "The body"}
}
<commit_msg>fix example names<commit_after>package patch_test

import (
	"fmt"
	"github.com/smagch/patch"
	"strings"
)

func ExamplePatcher_Unmarshal() {
	type User struct {
		ID     int
		Name   string
		Email  string
		Active bool
	}
	p := patch.New(User{})
	data, err := p.Unmarshal([]byte(`{"Name": "gopher", "Active": true}`))
	if err != nil {
		fmt.Println(err.Error())
	}
	keys := data.Keys()
	fmt.Println(strings.Join(keys, ","))
	// Output:
	// Name,Active
}

func ExampleFields_Remove() {
	type User struct {
		ID    int    `json:"id"`
		Name  string `json:"name"`
		Email string `json:"email"`
	}
	p := patch.New(User{})
	data, err := p.Unmarshal([]byte(`{"name": "gopher", "email": "golang@hoge.hoge"}`))
	if err != nil {
		fmt.Println(err.Error())
	}
	email, found := data.Get("email")
	if found {
		data.Remove("email")
	}
	fmt.Println(email)
	fmt.Printf("%v", data.Values())
	// Output:
	// golang@hoge.hoge
	// [gopher]
}

func ExampleFields_Set() {
	type Article struct {
		ID     int    `json:"id"`
		UserID int    `json:"user_id"`
		Title  string `json:"title"`
		Desc   string `json:"desc"`
		Body   string `json:"body"`
	}
	p := patch.New(Article{})
	f, err := p.Unmarshal([]byte(`{"title": "the gopher", "desc": "description"}`))
	if err != nil {
		fmt.Println(err.Error())
	}
	f.Set("desc", "goggles its eyes")
	f.Set("body", "with deadly pale body")
	fmt.Printf("%v", f.Values())
	// Output:
	// [the gopher goggles its eyes with deadly pale body]
}

func ExampleSQL_Query() {
	type Post struct {
		ID          int    `json:"id"`
		UserId      int    `json:"user_id"`
		Title       string `json:"title"`
		Description string `json:"description"`
		Body        string `json:"body"`
	}
	p := patch.New(Post{})
	data, err := p.Unmarshal([]byte(`{"title": "Space Gopher", "body": "The body"}`))
	if err != nil {
		fmt.Println(err.Error())
	}
	id := 947
	q, args := data.SQL().Query(id)
	fmt.Println(q)
	query := fmt.Sprintf(`UPDATE posts SET %s WHERE id = ?`, q)
	fmt.Println(query)
	fmt.Printf("%#v", args)
	// Output:
	// title=?,body=?
	// UPDATE posts SET title=?,body=? WHERE id = ?
	// []interface {}{"Space Gopher", "The body", 947}
}

func ExampleSQL_QueryPostgres() {
	type Post struct {
		ID          int    `json:"id"`
		UserId      int    `json:"user_id"`
		Title       string `json:"title"`
		Description string `json:"description"`
		Body        string `json:"body"`
	}
	p := patch.New(Post{})
	data, err := p.Unmarshal([]byte(`{"title": "Space Gopher", "body": "The body"}`))
	if err != nil {
		fmt.Println(err.Error())
	}
	id := 947
	q, args := data.SQL().QueryPostgres(id)
	fmt.Println(q)
	query := fmt.Sprintf(`UPDATE posts SET %s WHERE id = $1`, q)
	fmt.Println(query)
	fmt.Printf("%#v", args)
	// Output:
	// title=$2,body=$3
	// UPDATE posts SET title=$2,body=$3 WHERE id = $1
	// []interface {}{947, "Space Gopher", "The body"}
}
<|endoftext|>


<commit_before>package fitz

import (
	"fmt"
	"image/jpeg"
	"io/ioutil"
	"os"
	"path/filepath"
)

func ExampleNew() {
	doc, err := New("test.pdf")
	if err != nil {
		panic(err)
	}

	defer doc.Close()

	tmpDir, err := ioutil.TempDir(os.TempDir(), "fitz")
	if err != nil {
		panic(err)
	}

	// Extract pages as images
	for n := 0; n < doc.NumPage(); n++ {
		img, err := doc.Image(n)
		if err != nil {
			panic(err)
		}

		f, err := os.Create(filepath.Join(tmpDir, fmt.Sprintf("test%03d.jpg", n)))
		if err != nil {
			panic(err)
		}

		err = jpeg.Encode(f, img, &jpeg.Options{jpeg.DefaultQuality})
		if err != nil {
			panic(err)
		}

		f.Close()
	}

	// Extract pages as text
	for n := 0; n < doc.NumPage(); n++ {
		text, err := doc.Text(n)
		if err != nil {
			panic(err)
		}

		f, err := os.Create(filepath.Join(tmpDir, fmt.Sprintf("test%03d.txt", n)))
		if err != nil {
			panic(err)
		}

		_, err = f.WriteString(text)
		if err != nil {
			panic(err)
		}

		f.Close()
	}
}
<commit_msg>Update example<commit_after>package fitz

import (
	"fmt"
	"image/jpeg"
	"io/ioutil"
	"os"
	"path/filepath"
)

func ExampleNew() {
	doc, err := New("test.pdf")
	if err != nil {
		panic(err)
	}

	defer doc.Close()

	tmpDir, err := ioutil.TempDir(os.TempDir(), "fitz")
	if err != nil {
		panic(err)
	}

	// Extract pages as images
	for n := 0; n < doc.NumPage(); n++ {
		img, err := doc.Image(n)
		if err != nil {
			panic(err)
		}

		f, err := os.Create(filepath.Join(tmpDir, fmt.Sprintf("test%03d.jpg", n)))
		if err != nil {
			panic(err)
		}

		err = jpeg.Encode(f, img, &jpeg.Options{Quality: jpeg.DefaultQuality})
		if err != nil {
			panic(err)
		}

		f.Close()
	}

	// Extract pages as text
	for n := 0; n < doc.NumPage(); n++ {
		text, err := doc.Text(n)
		if err != nil {
			panic(err)
		}

		f, err := os.Create(filepath.Join(tmpDir, fmt.Sprintf("test%03d.txt", n)))
		if err != nil {
			panic(err)
		}

		_, err = f.WriteString(text)
		if err != nil {
			panic(err)
		}

		f.Close()
	}
}
<|endoftext|>


<commit_before>package browser

import "strings"

func ExampleOpenFile() {
	OpenFile("index.html")
}

func ExampleOpenReader() {
	// https://github.com/rust-lang/rust/issues/13871
	const quote = `There was a night when winds from unknown spaces
whirled us irresistibly into limitless vacum beyond all thought and entity.
Perceptions of the most maddeningly untransmissible sort thronged upon us;
perceptions of infinity which at the time convulsed us with joy, yet which
are now partly lost to my memory and partly incapable of presentation to others.`
	r := strings.NewReader(quote)
	OpenReader(r)
}

func ExampleOpenURL() {
	const url = "http://golang.org/"
	OpenURL(url)
}
<commit_msg>fix quote layout<commit_after>package browser

import "strings"

func ExampleOpenFile() {
	OpenFile("index.html")
}

func ExampleOpenReader() {
	// https://github.com/rust-lang/rust/issues/13871
	const quote = `There was a night when winds from unknown spaces
whirled us irresistibly into limitless vacum beyond all thought and entity.
Perceptions of the most maddeningly untransmissible sort thronged upon us;
perceptions of infinity which at the time convulsed us with joy, yet which
are now partly lost to my memory and partly incapable of presentation to others.`
	r := strings.NewReader(quote)
	OpenReader(r)
}

func ExampleOpenURL() {
	const url = "http://golang.org/"
	OpenURL(url)
}
<|endoftext|>


<commit_before>package consuloretcd

func ExampleNewClient_consul() {
	consul, err := consuloretcd.NewClient(
		"consul",
		consuloretcd.Config{
			Endpoint: "http://127.0.0.1",
			Client:   http.Client{},
			Port:     8500})
}

func ExampleNewClient_etcd() {
	etcd, err := consuloretcd.NewClient(
		"etcd",
		consuloretcd.Config{
			Endpoint: "http://127.0.0.1",
			Client:   http.Client{},
			Port:     4001})
}

func ExampleEtcd_GetKey() {
	keyval, err := consul.GetKey("keyname")
}

func ExampleEtcd_PutKey() {
	keyval, err := etcd.PutKey("keyname", "a value")
}

func ExampleEtcd_DeleteKey() {
	err := consul.DeleteKey("keyname")
}

func ExampleConsul_GetKey() {
	keyval, err := consul.GetKey("keyname")
}

func ExampleConsul_PutKey() {
	keyval, err := consul.PutKey("keyname", "a value")
}

func ExampleConsul_DeleteKey() {
	err := consul.DeleteKey("keyname")
}
<commit_msg>Updated examples for test execution.<commit_after>package consuloretcd

import (
    "net/http"
    "fmt"
    "reflect"
    "testing"
)

func ExampleNewClient_consul() {
    // error checking omitted
	consul, _ := NewClient(
		"consul",
		Config{
			Endpoint: "http://127.0.0.1",
			Client:   http.Client{},
			Port:     8500})
    fmt.Println(reflect.TypeOf(consul))
    // Output: consuloretcd.Consul
}

func ExampleNewClient_etcd() {
    // error checking omitted
	etcd, _ := NewClient(
		"etcd",
		Config{
			Endpoint: "http://127.0.0.1",
			Client:   http.Client{},
			Port:     4001})
    fmt.Println(reflect.TypeOf(etcd))
    // Output: consuloretcd.Etcd
}

func TestNewClient_default(t *testing.T) {
    unknown, err := NewClient(
        "unknown",
        Config{})
    if unknown != nil || err == nil {
        t.FailNow()
    }
}

func ExampleEtcd_GetKey() {
    // error checking omitted
	etcd, _ := NewClient(
		"etcd",
		Config{
			Endpoint: "http://127.0.0.1",
			Client:   http.Client{},
			Port:     4001})

	keyval, _ := etcd.GetKey("keyname")

    fmt.Println(reflect.TypeOf(keyval))
    // Output: consuloretcd.KeyValue
}

func ExampleEtcd_PutKey() {
    // error checking omitted
	etcd, _ := NewClient(
		"etcd",
		Config{
			Endpoint: "http://127.0.0.1",
			Client:   http.Client{},
			Port:     4001})

	keyval, _ := etcd.PutKey("keyname", "a value")

    fmt.Println(reflect.TypeOf(keyval))
    // Output: consuloretcd.KeyValue
}

func ExampleEtcd_DeleteKey() {
    // error checking omitted
	etcd, _ := NewClient(
		"etcd",
		Config{
			Endpoint: "http://127.0.0.1",
			Client:   http.Client{},
			Port:     4001})

	etcd.DeleteKey("keyname")
}

func ExampleConsul_GetKey() {
    // error checking omitted
	consul, _ := NewClient(
		"consul",
		Config{
			Endpoint: "http://127.0.0.1",
			Client:   http.Client{},
			Port:     8500})

	keyval, _ := consul.GetKey("keyname")

    fmt.Println(reflect.TypeOf(keyval))
    // Output: consuloretcd.KeyValue
}

func ExampleConsul_PutKey() {
    // error checking omitted
	consul, _ := NewClient(
		"consul",
		Config{
			Endpoint: "http://127.0.0.1",
			Client:   http.Client{},
			Port:     8500})

	keyval, _ := consul.PutKey("keyname", "a value")

    fmt.Println(reflect.TypeOf(keyval))
    // Output: consuloretcd.KeyValue
}

func ExampleConsul_DeleteKey() {
    // error checking omitted
	consul, _ := NewClient(
		"consul",
		Config{
			Endpoint: "http://127.0.0.1",
			Client:   http.Client{},
			Port:     8500})

	consul.DeleteKey("keyname")
}
<|endoftext|>


<commit_before><commit_msg>update<commit_after><|endoftext|>


<commit_before>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"go/build"
	"path/filepath"
	"strings"
	"testing"
)

func runTest(t *testing.T, path string) {
	errorCount = 0

	*recursive = false
	*allErrors = true
	ctxt := build.Default
	if suffix := ".go"; strings.HasSuffix(path, suffix) {
		// single file, part of this package so on GOPATH.
		path = filepath.Join(ctxt.GOPATH, "/src/", path)
		path, file := filepath.Split(path)
		*pkgName = file[:len(file)-len(suffix)]
		processFiles([]string{path}, true)
	} else {
		// package directory
		// TODO(gri) gotype should use the build package instead
		ctxt.CgoEnabled = false
		pkg, err := ctxt.Import(path, "", 0)
		if err != nil {
			t.Errorf("build.Import error for path = %s: %s", path, err)
			return
		}
		// TODO(gri) there ought to be a more direct way using the build package...
		files := make([]string, len(pkg.GoFiles))
		for i, file := range pkg.GoFiles {
			files[i] = filepath.Join(pkg.Dir, file)
		}
		*pkgName = pkg.Name
		processFiles(files, true)
	}

	if errorCount > 0 {
		t.Errorf("processing %s failed: %d errors", path, errorCount)
	}
}

var tests = []string{
	// individual files, part of this package.
	"code.google.com/p/go.exp/gotype/testdata/test1.go",

	// directories
	// Note: Packages that don't typecheck yet are commented out.
	// Unless there is a comment next to the commented out packages,
	// the package doesn't typecheck due to errors in the shift
	// expression checker.
	"archive/tar",
	"archive/zip",

	"bufio",
	"bytes",

	"compress/bzip2",
	"compress/flate",
	"compress/gzip",
	"compress/lzw",
	"compress/zlib",

	"container/heap",
	"container/list",
	"container/ring",

	"crypto",
	"crypto/aes",
	"crypto/cipher",
	"crypto/des",
	"crypto/dsa",
	"crypto/ecdsa",
	"crypto/elliptic",
	"crypto/hmac",
	"crypto/md5",
	"crypto/rand",
	"crypto/rc4",
	"crypto/rsa",
	"crypto/sha1",
	"crypto/sha256",
	"crypto/sha512",
	"crypto/subtle",
	"crypto/tls",
	"crypto/x509",
	"crypto/x509/pkix",

	"database/sql",
	"database/sql/driver",

	"debug/dwarf",
	"debug/elf",
	"debug/gosym",
	"debug/macho",
	"debug/pe",

	"encoding/ascii85",
	"encoding/asn1",
	"encoding/base32",
	"encoding/base64",
	"encoding/binary",
	"encoding/csv",
	"encoding/gob",
	"encoding/hex",
	"encoding/json",
	"encoding/pem",
	"encoding/xml",

	"errors",
	"expvar",
	"flag",
	"fmt",

	"code.google.com/p/go.exp/go/types",
	"code.google.com/p/go.exp/gotype",

	"go/ast",
	"go/build",
	"go/doc",
	"go/format",
	"go/parser",
	"go/printer",
	"go/scanner",
	"go/token",

	"hash/adler32",
	"hash/crc32",
	"hash/crc64",
	"hash/fnv",

	"image",
	"image/color",
	"image/draw",
	"image/gif",
	"image/jpeg",
	"image/png",

	"index/suffixarray",

	"io",
	"io/ioutil",

	"log",
	"log/syslog",

	"math",
	"math/big",
	"math/cmplx",
	"math/rand",

	"mime",
	"mime/multipart",

	"net",
	"net/http",
	"net/http/cgi",
	"net/http/fcgi",
	"net/http/httptest",
	"net/http/httputil",
	"net/http/pprof",
	"net/mail",
	"net/rpc",
	"net/rpc/jsonrpc",
	"net/smtp",
	"net/textproto",
	"net/url",

	"path",
	"path/filepath",

	"reflect",

	"regexp",
	"regexp/syntax",

	"runtime",
	"runtime/cgo",
	"runtime/debug",
	"runtime/pprof",

	"sort",
	"strconv",
	"strings",

	"sync",
	"sync/atomic",

	"syscall",

	"testing",
	"testing/iotest",
	"testing/quick",

	"text/scanner",
	"text/tabwriter",
	"text/template",
	"text/template/parse",

	"time",
	"unicode",
	"unicode/utf16",
	"unicode/utf8",
}

func Test(t *testing.T) {
	for _, test := range tests {
		runTest(t, test)
	}
}
<commit_msg>go.exp/gotype: fix build The builders do not run go install, only go test. Thus the gotype test cannot import any packages other than the ones in the standard repo. This is a workaround to get the build working by commenting out the offending packages but a nicer fix would be welcome.<commit_after>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"go/build"
	"path/filepath"
	"strings"
	"testing"
)

func runTest(t *testing.T, path string) {
	errorCount = 0

	*recursive = false
	*allErrors = true
	ctxt := build.Default
	if suffix := ".go"; strings.HasSuffix(path, suffix) {
		// single file, part of this package so on GOPATH.
		path = filepath.Join(ctxt.GOPATH, "/src/", path)
		path, file := filepath.Split(path)
		*pkgName = file[:len(file)-len(suffix)]
		processFiles([]string{path}, true)
	} else {
		// package directory
		// TODO(gri) gotype should use the build package instead
		ctxt.CgoEnabled = false
		pkg, err := ctxt.Import(path, "", 0)
		if err != nil {
			t.Errorf("build.Import error for path = %s: %s", path, err)
			return
		}
		// TODO(gri) there ought to be a more direct way using the build package...
		files := make([]string, len(pkg.GoFiles))
		for i, file := range pkg.GoFiles {
			files[i] = filepath.Join(pkg.Dir, file)
		}
		*pkgName = pkg.Name
		processFiles(files, true)
	}

	if errorCount > 0 {
		t.Errorf("processing %s failed: %d errors", path, errorCount)
	}
}

var tests = []string{
	// individual files, part of this package.
	"code.google.com/p/go.exp/gotype/testdata/test1.go",

	// directories
	// Note: Packages that don't typecheck yet are commented out.
	// Unless there is a comment next to the commented out packages,
	// the package doesn't typecheck due to errors in the shift
	// expression checker.
	"archive/tar",
	"archive/zip",

	"bufio",
	"bytes",

	"compress/bzip2",
	"compress/flate",
	"compress/gzip",
	"compress/lzw",
	"compress/zlib",

	"container/heap",
	"container/list",
	"container/ring",

	"crypto",
	"crypto/aes",
	"crypto/cipher",
	"crypto/des",
	"crypto/dsa",
	"crypto/ecdsa",
	"crypto/elliptic",
	"crypto/hmac",
	"crypto/md5",
	"crypto/rand",
	"crypto/rc4",
	"crypto/rsa",
	"crypto/sha1",
	"crypto/sha256",
	"crypto/sha512",
	"crypto/subtle",
	"crypto/tls",
	"crypto/x509",
	"crypto/x509/pkix",

	"database/sql",
	"database/sql/driver",

	"debug/dwarf",
	"debug/elf",
	"debug/gosym",
	"debug/macho",
	"debug/pe",

	"encoding/ascii85",
	"encoding/asn1",
	"encoding/base32",
	"encoding/base64",
	"encoding/binary",
	"encoding/csv",
	"encoding/gob",
	"encoding/hex",
	"encoding/json",
	"encoding/pem",
	"encoding/xml",

	"errors",
	"expvar",
	"flag",
	"fmt",

	// TODO: Since the builders do not install these packages, this test cannot use them.
	//	"code.google.com/p/go.exp/go/types",
	//	"code.google.com/p/go.exp/gotype",

	"go/ast",
	"go/build",
	"go/doc",
	"go/format",
	"go/parser",
	"go/printer",
	"go/scanner",
	"go/token",

	"hash/adler32",
	"hash/crc32",
	"hash/crc64",
	"hash/fnv",

	"image",
	"image/color",
	"image/draw",
	"image/gif",
	"image/jpeg",
	"image/png",

	"index/suffixarray",

	"io",
	"io/ioutil",

	"log",
	"log/syslog",

	"math",
	"math/big",
	"math/cmplx",
	"math/rand",

	"mime",
	"mime/multipart",

	"net",
	"net/http",
	"net/http/cgi",
	"net/http/fcgi",
	"net/http/httptest",
	"net/http/httputil",
	"net/http/pprof",
	"net/mail",
	"net/rpc",
	"net/rpc/jsonrpc",
	"net/smtp",
	"net/textproto",
	"net/url",

	"path",
	"path/filepath",

	"reflect",

	"regexp",
	"regexp/syntax",

	"runtime",
	"runtime/cgo",
	"runtime/debug",
	"runtime/pprof",

	"sort",
	"strconv",
	"strings",

	"sync",
	"sync/atomic",

	"syscall",

	"testing",
	"testing/iotest",
	"testing/quick",

	"text/scanner",
	"text/tabwriter",
	"text/template",
	"text/template/parse",

	"time",
	"unicode",
	"unicode/utf16",
	"unicode/utf8",
}

func Test(t *testing.T) {
	for _, test := range tests {
		runTest(t, test)
	}
}
<|endoftext|>


<commit_before>package gqt_test

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"

	"github.com/cloudfoundry-incubator/garden"
	"github.com/cloudfoundry-incubator/guardian/gqt/runner"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Port Pool", func() {

	Context("when the port pool is exhausted by container creation", func() {
		const (
			numContainers int = 5
			portPoolStart int = 50000
		)
		var (
			containers   []garden.Container
			client       *runner.RunningGarden
			expectedPort uint32
			args         []string
			propsPoolDir string
		)

		BeforeEach(func() {
			var err error
			propsPoolDir, err = ioutil.TempDir("", "portpool")
			Expect(err).NotTo(HaveOccurred())
			args = []string{
				"--port-pool-size", strconv.Itoa(numContainers),
				"--port-pool-properties-path", filepath.Join(propsPoolDir, "props.json"),
				"--port-pool-start", strconv.Itoa(portPoolStart),
			}
			containers = []garden.Container{}
			client = startGarden(args...)

			// Create containers and NetIn
			for i := 0; i < numContainers; i++ {
				container, err := client.Create(garden.ContainerSpec{})
				Expect(err).NotTo(HaveOccurred())

				hostPort, _, err := container.NetIn(0, 0)
				if i == numContainers-1 {
					expectedPort = hostPort
				}
				Expect(err).NotTo(HaveOccurred())

				containers = append(containers, container)
			}

		})

		AfterEach(func() {
			Expect(client.DestroyAndStop()).To(Succeed())
			Expect(os.RemoveAll(propsPoolDir)).To(Succeed())
		})

		It("releases ports after the container is destroyed", func() {
			_, _, err := containers[0].NetIn(0, 0)
			Expect(err).To(HaveOccurred())

			Expect(client.Destroy(containers[0].Handle())).To(Succeed())

			_, _, err = containers[1].NetIn(0, 0)
			Expect(err).NotTo(HaveOccurred())
		})

		Context("and then all containers are destroyed", func() {

			BeforeEach(func() {
				// Destroy containers in reverse order
				for i := numContainers - 1; i >= 0; i-- {
					Expect(client.Destroy(containers[i].Handle())).To(Succeed())
				}
			})

			It("should FIFO released/allocated ports", func() {
				for i := 0; i < numContainers; i++ {
					container, err := client.Create(garden.ContainerSpec{})
					Expect(err).NotTo(HaveOccurred())

					hostPort, _, err := container.NetIn(0, 0)
					Expect(err).NotTo(HaveOccurred())
					Expect(hostPort).To(Equal(uint32(portPoolStart + (numContainers - 1) - i)))
				}
			})

			Context("when guardian is restarted", func() {
				BeforeEach(func() {
					client.Stop()
					client = startGarden(args...)
				})

				It("should persist the head of the port allocation queue", func() {
					container, err := client.Create(garden.ContainerSpec{})
					Expect(err).NotTo(HaveOccurred())

					hostPort, _, err := container.NetIn(0, 0)
					Expect(err).NotTo(HaveOccurred())
					Expect(expectedPort).To(Equal(uint32(hostPort)))
				})

				It("should arrange the ports in increasing order starting with the head", func() {
					for i := 0; i < numContainers; i++ {
						container, err := client.Create(garden.ContainerSpec{})
						Expect(err).NotTo(HaveOccurred())

						hostPort, _, err := container.NetIn(0, 0)
						Expect(err).NotTo(HaveOccurred())
						if i == 0 {
							Expect(expectedPort).To(Equal(uint32(hostPort)))
						} else {
							Expect(uint32(portPoolStart + i - 1)).To(Equal(hostPort))
						}
					}
				})

			})
		})

	})
})
<commit_msg>Isolate port pools in different workers<commit_after>package gqt_test

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"

	"github.com/cloudfoundry-incubator/garden"
	"github.com/cloudfoundry-incubator/guardian/gqt/runner"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Port Pool", func() {

	Context("when the port pool is exhausted by container creation", func() {
		const (
			numContainers int = 5
		)

		var (
			portPoolStart int
			containers    []garden.Container
			client        *runner.RunningGarden
			expectedPort  uint32
			args          []string
			propsPoolDir  string
		)

		BeforeEach(func() {
			var err error
			portPoolStart = GinkgoParallelNode() * 10000
			propsPoolDir, err = ioutil.TempDir("", "portpool")
			Expect(err).NotTo(HaveOccurred())
			args = []string{
				"--port-pool-size", strconv.Itoa(numContainers),
				"--port-pool-properties-path", filepath.Join(propsPoolDir, "props.json"),
				"--port-pool-start", strconv.Itoa(portPoolStart),
			}
			containers = []garden.Container{}
			client = startGarden(args...)

			// Create containers and NetIn
			for i := 0; i < numContainers; i++ {
				container, err := client.Create(garden.ContainerSpec{})
				Expect(err).NotTo(HaveOccurred())

				hostPort, _, err := container.NetIn(0, 0)
				if i == numContainers-1 {
					expectedPort = hostPort
				}
				Expect(err).NotTo(HaveOccurred())

				containers = append(containers, container)
			}

		})

		AfterEach(func() {
			Expect(client.DestroyAndStop()).To(Succeed())
			Expect(os.RemoveAll(propsPoolDir)).To(Succeed())
		})

		It("releases ports after the container is destroyed", func() {
			_, _, err := containers[0].NetIn(0, 0)
			Expect(err).To(HaveOccurred())

			Expect(client.Destroy(containers[0].Handle())).To(Succeed())

			_, _, err = containers[1].NetIn(0, 0)
			Expect(err).NotTo(HaveOccurred())
		})

		Context("and then all containers are destroyed", func() {

			BeforeEach(func() {
				// Destroy containers in reverse order
				for i := numContainers - 1; i >= 0; i-- {
					Expect(client.Destroy(containers[i].Handle())).To(Succeed())
				}
			})

			It("should FIFO released/allocated ports", func() {
				for i := 0; i < numContainers; i++ {
					container, err := client.Create(garden.ContainerSpec{})
					Expect(err).NotTo(HaveOccurred())

					hostPort, _, err := container.NetIn(0, 0)
					Expect(err).NotTo(HaveOccurred())
					Expect(hostPort).To(Equal(uint32(portPoolStart + (numContainers - 1) - i)))
				}
			})

			Context("when guardian is restarted", func() {
				BeforeEach(func() {
					client.Stop()
					client = startGarden(args...)
				})

				It("should persist the head of the port allocation queue", func() {
					container, err := client.Create(garden.ContainerSpec{})
					Expect(err).NotTo(HaveOccurred())

					hostPort, _, err := container.NetIn(0, 0)
					Expect(err).NotTo(HaveOccurred())
					Expect(expectedPort).To(Equal(uint32(hostPort)))
				})

				It("should arrange the ports in increasing order starting with the head", func() {
					for i := 0; i < numContainers; i++ {
						container, err := client.Create(garden.ContainerSpec{})
						Expect(err).NotTo(HaveOccurred())

						hostPort, _, err := container.NetIn(0, 0)
						Expect(err).NotTo(HaveOccurred())
						if i == 0 {
							Expect(expectedPort).To(Equal(uint32(hostPort)))
						} else {
							Expect(uint32(portPoolStart + i - 1)).To(Equal(hostPort))
						}
					}
				})

			})
		})

	})
})
<|endoftext|>


<commit_before>// +build linux
// +build cgo

package idmap

import (
	"fmt"
	"os"
	"unsafe"
)

// #cgo LDFLAGS: -lacl
/*
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/acl.h>

int shiftowner(char *basepath, char *path, int uid, int gid) {
	struct stat sb;
	int fd, r;
	char fdpath[PATH_MAX];
	char realpath[PATH_MAX];

	fd = open(path, O_PATH|O_NOFOLLOW);
	if (fd < 0 ) {
		perror("Failed open");
		return 1;
	}

	r = sprintf(fdpath, "/proc/self/fd/%d", fd);
	if (r < 0) {
		perror("Failed sprintf");
		close(fd);
		return 1;
	}

	r = readlink(fdpath, realpath, PATH_MAX);
	if (r < 0) {
		perror("Failed readlink");
		close(fd);
		return 1;
	}

	if (strlen(realpath) < strlen(basepath)) {
		printf("Invalid path, source (%s) is outside of basepath (%s).\n", realpath, basepath);
		close(fd);
		return 1;
	}

	if (strncmp(realpath, basepath, strlen(basepath))) {
		printf("Invalid path, source (%s) is outside of basepath (%s).\n", realpath, basepath);
		close(fd);
		return 1;
	}

	r = fstat(fd, &sb);
	if (r < 0) {
		perror("Failed fstat");
		close(fd);
		return 1;
	}

	r = fchownat(fd, "", uid, gid, AT_EMPTY_PATH|AT_SYMLINK_NOFOLLOW);
	if (r < 0) {
		perror("Failed chown");
		close(fd);
		return 1;
	}

	if (!S_ISLNK(sb.st_mode)) {
		r = chmod(fdpath, sb.st_mode);
		if (r < 0) {
			perror("Failed chmod");
			close(fd);
			return 1;
		}
	}

	close(fd);
	return 0;
}
*/
import "C"

// ShiftOwner updates uid and gid for a file when entering/exiting a namespace
func ShiftOwner(basepath string, path string, uid int, gid int) error {
	cbasepath := C.CString(basepath)
	defer C.free(unsafe.Pointer(cbasepath))

	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	r := C.shiftowner(cbasepath, cpath, C.int(uid), C.int(gid))
	if r != 0 {
		return fmt.Errorf("Failed to change ownership of: %s", path)
	}
	return nil
}

// ShiftACL updates uid and gid for file ACLs when entering/exiting a namespace
func ShiftACL(path string, shiftIds func(uid int64, gid int64) (int64, int64)) error {
	finfo, err := os.Lstat(path)
	if err != nil {
		return err
	}
	if finfo.Mode()&os.ModeSymlink != 0 {
		return nil
	}

	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	acl := C.acl_get_file(cpath, C.ACL_TYPE_ACCESS)
	if acl == nil {
		return nil
	}
	defer C.acl_free(unsafe.Pointer(acl))

	for entryId := C.ACL_FIRST_ENTRY; ; entryId = C.ACL_NEXT_ENTRY {
		var ent C.acl_entry_t
		var tag C.acl_tag_t
		updateACL := false

		ret := C.acl_get_entry(acl, C.int(entryId), &ent)
		if ret != 1 {
			break
		}

		ret = C.acl_get_tag_type(ent, &tag)
		if ret == -1 {
			return fmt.Errorf("Failed to change ACLs on %s", path)
		}

		idp := (*C.id_t)(C.acl_get_qualifier(ent))
		if idp == nil {
			continue
		}

		var newId int64
		switch tag {
		case C.ACL_USER:
			newId, _ = shiftIds((int64)(*idp), -1)
			updateACL = true

		case C.ACL_GROUP:
			_, newId = shiftIds(-1, (int64)(*idp))
			updateACL = true
		}

		if updateACL {
			ret = C.acl_set_qualifier(ent, unsafe.Pointer(&newId))
			if ret == -1 {
				return fmt.Errorf("Failed to change ACLs on %s", path)
			}
			ret = C.acl_set_file(cpath, C.ACL_TYPE_ACCESS, acl)
			if ret == -1 {
				return fmt.Errorf("Failed to change ACLs on %s", path)
			}
		}
	}
	return nil
}
<commit_msg>shared/idmap: Make ACL failures more verbose<commit_after>// +build linux
// +build cgo

package idmap

import (
	"fmt"
	"os"
	"unsafe"
)

// #cgo LDFLAGS: -lacl
/*
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/acl.h>

int shiftowner(char *basepath, char *path, int uid, int gid) {
	struct stat sb;
	int fd, r;
	char fdpath[PATH_MAX];
	char realpath[PATH_MAX];

	fd = open(path, O_PATH|O_NOFOLLOW);
	if (fd < 0 ) {
		perror("Failed open");
		return 1;
	}

	r = sprintf(fdpath, "/proc/self/fd/%d", fd);
	if (r < 0) {
		perror("Failed sprintf");
		close(fd);
		return 1;
	}

	r = readlink(fdpath, realpath, PATH_MAX);
	if (r < 0) {
		perror("Failed readlink");
		close(fd);
		return 1;
	}

	if (strlen(realpath) < strlen(basepath)) {
		printf("Invalid path, source (%s) is outside of basepath (%s).\n", realpath, basepath);
		close(fd);
		return 1;
	}

	if (strncmp(realpath, basepath, strlen(basepath))) {
		printf("Invalid path, source (%s) is outside of basepath (%s).\n", realpath, basepath);
		close(fd);
		return 1;
	}

	r = fstat(fd, &sb);
	if (r < 0) {
		perror("Failed fstat");
		close(fd);
		return 1;
	}

	r = fchownat(fd, "", uid, gid, AT_EMPTY_PATH|AT_SYMLINK_NOFOLLOW);
	if (r < 0) {
		perror("Failed chown");
		close(fd);
		return 1;
	}

	if (!S_ISLNK(sb.st_mode)) {
		r = chmod(fdpath, sb.st_mode);
		if (r < 0) {
			perror("Failed chmod");
			close(fd);
			return 1;
		}
	}

	close(fd);
	return 0;
}
*/
import "C"

// ShiftOwner updates uid and gid for a file when entering/exiting a namespace
func ShiftOwner(basepath string, path string, uid int, gid int) error {
	cbasepath := C.CString(basepath)
	defer C.free(unsafe.Pointer(cbasepath))

	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	r := C.shiftowner(cbasepath, cpath, C.int(uid), C.int(gid))
	if r != 0 {
		return fmt.Errorf("Failed to change ownership of: %s", path)
	}
	return nil
}

// ShiftACL updates uid and gid for file ACLs when entering/exiting a namespace
func ShiftACL(path string, shiftIds func(uid int64, gid int64) (int64, int64)) error {
	finfo, err := os.Lstat(path)
	if err != nil {
		return err
	}
	if finfo.Mode()&os.ModeSymlink != 0 {
		return nil
	}

	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	acl := C.acl_get_file(cpath, C.ACL_TYPE_ACCESS)
	if acl == nil {
		return nil
	}
	defer C.acl_free(unsafe.Pointer(acl))

	for entryId := C.ACL_FIRST_ENTRY; ; entryId = C.ACL_NEXT_ENTRY {
		var ent C.acl_entry_t
		var tag C.acl_tag_t
		updateACL := false

		ret := C.acl_get_entry(acl, C.int(entryId), &ent)
		if ret != 1 {
			break
		}

		ret = C.acl_get_tag_type(ent, &tag)
		if ret == -1 {
			return fmt.Errorf("Failed to get ACLs for %s", path)
		}

		idp := (*C.id_t)(C.acl_get_qualifier(ent))
		if idp == nil {
			continue
		}

		var newId int64
		switch tag {
		case C.ACL_USER:
			newId, _ = shiftIds((int64)(*idp), -1)
			updateACL = true

		case C.ACL_GROUP:
			_, newId = shiftIds(-1, (int64)(*idp))
			updateACL = true
		}

		if updateACL {
			ret = C.acl_set_qualifier(ent, unsafe.Pointer(&newId))
			if ret == -1 {
				return fmt.Errorf("Failed to set ACL qualifier on %s", path)
			}

			ret = C.acl_set_file(cpath, C.ACL_TYPE_ACCESS, acl)
			if ret == -1 {
				return fmt.Errorf("Failed to change ACLs on %s", path)
			}
		}
	}
	return nil
}
<|endoftext|>


<commit_before>// Copyright © 2016 Jip J. Dekker <jip@dekker.li>
//
// 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 helpers

import (
	"os"
	"path/filepath"

	log "github.com/Sirupsen/logrus"
)

// CleanPath returns a cleaned path from a given string relative
// to the working directory unless explicitly absolute
func CleanPath(path string) (string, error) {
	if path == "" {
		// No given path, use working directory
		return os.Getwd()
	} else if filepath.IsAbs(path) {
		// Given path is absolute
		return filepath.Clean(path), nil
	} else {
		// Given path is a relative path
		dir, err := os.Getwd()
		if err == nil {
			return filepath.Join(dir, path), nil
		}
		return "", err
	}
}

// Exists checks if a file or directory exists.
func Exists(path string) bool {
	_, err := os.Stat(path)
	if err == nil {
		return true
	}
	if !os.IsNotExist(err) {
		log.WithFields(log.Fields{"error": err, "path": path}).
			Panic("Unable to check path")
	}
	return false
}
<commit_msg>Adds function to find directory of file on working path<commit_after>// Copyright © 2016 Jip J. Dekker <jip@dekker.li>
//
// 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 helpers

import (
	"errors"
	"os"
	"path/filepath"

	log "github.com/Sirupsen/logrus"
)

// CleanPath returns a cleaned path from a given string relative
// to the working directory unless explicitly absolute
func CleanPath(path string) (string, error) {
	if path == "" {
		// No given path, use working directory
		return os.Getwd()
	} else if filepath.IsAbs(path) {
		// Given path is absolute
		return filepath.Clean(path), nil
	} else {
		// Given path is a relative path
		dir, err := os.Getwd()
		if err == nil {
			return filepath.Join(dir, path), nil
		}
		return "", err
	}
}

// Exists checks if a file or directory exists.
func Exists(path string) bool {
	_, err := os.Stat(path)
	if err == nil {
		return true
	}
	if !os.IsNotExist(err) {
		log.WithFields(log.Fields{"error": err, "path": path}).
			Panic("Unable to check path")
	}
	return false
}

// FindFileDir returns the path of the
func FindFileDir(file string) (string, error) {
	wd, err := os.Getwd()
	if err != nil {
		return "", nil
	}
	for path := wd; path != "."; path = filepath.Dir(path) {
		if Exists(filepath.Join(path, file)) {
			return path, nil
		}
	}
	return "", errors.New("directory not found")
}
<|endoftext|>


<commit_before>package hstore

import (
	"database/sql"
	"os"
	"testing"

	_ "github.com/lib/pq"
)

type Fatalistic interface {
	Fatal(args ...interface{})
}

func openTestConn(t Fatalistic) *sql.DB {
	datname := os.Getenv("PGDATABASE")
	sslmode := os.Getenv("PGSSLMODE")

	if datname == "" {
		os.Setenv("PGDATABASE", "pqgotest")
	}

	if sslmode == "" {
		os.Setenv("PGSSLMODE", "disable")
	}

	conn, err := sql.Open("postgres", "")
	if err != nil {
		t.Fatal(err)
	}

	return conn
}

func TestHstore(t *testing.T) {
	db := openTestConn(t)
	defer db.Close()

	// quitely create hstore if it doesn't exist
	_, err := db.Exec("CREATE EXTENSION IF NOT EXISTS hstore")
	if err != nil {
		t.Skipf("Skipping hstore tests - hstore extension create failed: %s", err.Error())
	}

	hs := Hstore{}

	// test for null-valued hstores
	err = db.QueryRow("SELECT NULL::hstore").Scan(&hs)
	if err != nil {
		t.Fatal(err)
	}
	if hs.Map != nil {
		t.Fatalf("expected null map")
	}

	err = db.QueryRow("SELECT $1::hstore", hs).Scan(&hs)
	if err != nil {
		t.Fatalf("re-query null map failed: %s", err.Error())
	}
	if hs.Map != nil {
		t.Fatalf("expected null map")
	}

	// test for empty hstores
	err = db.QueryRow("SELECT ''::hstore").Scan(&hs)
	if err != nil {
		t.Fatal(err)
	}
	if hs.Map == nil {
		t.Fatalf("expected empty map, got null map")
	}
	if len(hs.Map) != 0 {
		t.Fatalf("expected empty map, got len(map)=%d", len(hs.Map))
	}

	err = db.QueryRow("SELECT $1::hstore", hs).Scan(&hs)
	if err != nil {
		t.Fatalf("re-query empty map failed: %s", err.Error())
	}
	if hs.Map == nil {
		t.Fatalf("expected empty map, got null map")
	}
	if len(hs.Map) != 0 {
		t.Fatalf("expected empty map, got len(map)=%d", len(hs.Map))
	}

	// a few example maps to test out
	hsOnePair := Hstore{
		Map: map[string]sql.NullString{
			"key1": {"value1", true},
		},
	}

	hsThreePairs := Hstore{
		Map: map[string]sql.NullString{
			"key1": {"value1", true},
			"key2": {"value2", true},
			"key3": {"value3", true},
		},
	}

	hsSmorgasbord := Hstore{
		Map: map[string]sql.NullString{
			"nullstring":             {"NULL", true},
			"actuallynull":           {"", false},
			"NULL":                   {"NULL string key", true},
			"withbracket":            {"value>42", true},
			"withequal":              {"value=42", true},
			`"withquotes1"`:          {`this "should" be fine`, true},
			`"withquotes"2"`:         {`this "should\" also be fine`, true},
			"embedded1":              {"value1=>x1", true},
			"embedded2":              {`"value2"=>x2`, true},
			"withnewlines":           {"\n\nvalue\t=>2", true},
			"<<all sorts of crazy>>": {`this, "should,\" also, => be fine`, true},
		},
	}

	// test encoding in query params, then decoding during Scan
	testBidirectional := func(h Hstore) {
		err = db.QueryRow("SELECT $1::hstore", h).Scan(&hs)
		if err != nil {
			t.Fatalf("re-query %d-pair map failed: %s", len(h.Map), err.Error())
		}
		if hs.Map == nil {
			t.Fatalf("expected %d-pair map, got null map", len(h.Map))
		}
		if len(hs.Map) != len(h.Map) {
			t.Fatalf("expected %d-pair map, got len(map)=%d", len(h.Map), len(hs.Map))
		}

		for key, val := range hs.Map {
			otherval, found := h.Map[key]
			if !found {
				t.Fatalf("  key '%v' not found in %d-pair map", key, len(h.Map))
			}
			if otherval.Valid != val.Valid {
				t.Fatalf("  value %v <> %v in %d-pair map", otherval, val, len(h.Map))
			}
			if otherval.String != val.String {
				t.Fatalf("  value '%v' <> '%v' in %d-pair map", otherval.String, val.String, len(h.Map))
			}
		}
	}

	testBidirectional(hsOnePair)
	testBidirectional(hsThreePairs)
	testBidirectional(hsSmorgasbord)
}
<commit_msg>Fix go vet lint even though it's kinda dumb here<commit_after>package hstore

import (
	"database/sql"
	"os"
	"testing"

	_ "github.com/lib/pq"
)

type Fatalistic interface {
	Fatal(args ...interface{})
}

func openTestConn(t Fatalistic) *sql.DB {
	datname := os.Getenv("PGDATABASE")
	sslmode := os.Getenv("PGSSLMODE")

	if datname == "" {
		os.Setenv("PGDATABASE", "pqgotest")
	}

	if sslmode == "" {
		os.Setenv("PGSSLMODE", "disable")
	}

	conn, err := sql.Open("postgres", "")
	if err != nil {
		t.Fatal(err)
	}

	return conn
}

func TestHstore(t *testing.T) {
	db := openTestConn(t)
	defer db.Close()

	// quitely create hstore if it doesn't exist
	_, err := db.Exec("CREATE EXTENSION IF NOT EXISTS hstore")
	if err != nil {
		t.Skipf("Skipping hstore tests - hstore extension create failed: %s", err.Error())
	}

	hs := Hstore{}

	// test for null-valued hstores
	err = db.QueryRow("SELECT NULL::hstore").Scan(&hs)
	if err != nil {
		t.Fatal(err)
	}
	if hs.Map != nil {
		t.Fatalf("expected null map")
	}

	err = db.QueryRow("SELECT $1::hstore", hs).Scan(&hs)
	if err != nil {
		t.Fatalf("re-query null map failed: %s", err.Error())
	}
	if hs.Map != nil {
		t.Fatalf("expected null map")
	}

	// test for empty hstores
	err = db.QueryRow("SELECT ''::hstore").Scan(&hs)
	if err != nil {
		t.Fatal(err)
	}
	if hs.Map == nil {
		t.Fatalf("expected empty map, got null map")
	}
	if len(hs.Map) != 0 {
		t.Fatalf("expected empty map, got len(map)=%d", len(hs.Map))
	}

	err = db.QueryRow("SELECT $1::hstore", hs).Scan(&hs)
	if err != nil {
		t.Fatalf("re-query empty map failed: %s", err.Error())
	}
	if hs.Map == nil {
		t.Fatalf("expected empty map, got null map")
	}
	if len(hs.Map) != 0 {
		t.Fatalf("expected empty map, got len(map)=%d", len(hs.Map))
	}

	// a few example maps to test out
	hsOnePair := Hstore{
		Map: map[string]sql.NullString{
			"key1": {String: "value1", Valid: true},
		},
	}

	hsThreePairs := Hstore{
		Map: map[string]sql.NullString{
			"key1": {String: "value1", Valid: true},
			"key2": {String: "value2", Valid: true},
			"key3": {String: "value3", Valid: true},
		},
	}

	hsSmorgasbord := Hstore{
		Map: map[string]sql.NullString{
			"nullstring":             {String: "NULL", Valid: true},
			"actuallynull":           {String: "", Valid: false},
			"NULL":                   {String: "NULL string key", Valid: true},
			"withbracket":            {String: "value>42", Valid: true},
			"withequal":              {String: "value=42", Valid: true},
			`"withquotes1"`:          {String: `this "should" be fine`, Valid: true},
			`"withquotes"2"`:         {String: `this "should\" also be fine`, Valid: true},
			"embedded1":              {String: "value1=>x1", Valid: true},
			"embedded2":              {String: `"value2"=>x2`, Valid: true},
			"withnewlines":           {String: "\n\nvalue\t=>2", Valid: true},
			"<<all sorts of crazy>>": {String: `this, "should,\" also, => be fine`, Valid: true},
		},
	}

	// test encoding in query params, then decoding during Scan
	testBidirectional := func(h Hstore) {
		err = db.QueryRow("SELECT $1::hstore", h).Scan(&hs)
		if err != nil {
			t.Fatalf("re-query %d-pair map failed: %s", len(h.Map), err.Error())
		}
		if hs.Map == nil {
			t.Fatalf("expected %d-pair map, got null map", len(h.Map))
		}
		if len(hs.Map) != len(h.Map) {
			t.Fatalf("expected %d-pair map, got len(map)=%d", len(h.Map), len(hs.Map))
		}

		for key, val := range hs.Map {
			otherval, found := h.Map[key]
			if !found {
				t.Fatalf("  key '%v' not found in %d-pair map", key, len(h.Map))
			}
			if otherval.Valid != val.Valid {
				t.Fatalf("  value %v <> %v in %d-pair map", otherval, val, len(h.Map))
			}
			if otherval.String != val.String {
				t.Fatalf("  value '%v' <> '%v' in %d-pair map", otherval.String, val.String, len(h.Map))
			}
		}
	}

	testBidirectional(hsOnePair)
	testBidirectional(hsThreePairs)
	testBidirectional(hsSmorgasbord)
}
<|endoftext|>


<commit_before>package http

import (
	"github.com/geodan/gost/sensorthings/models"
	"github.com/stretchr/testify/assert"
	"sort"
	"testing"
)

func TestEndPointLength(t *testing.T) {
	// arrange
	ep1 := &Endpoint{}
	ep2 := &Endpoint{}
	eps := Endpoints{}
	eps = append(eps, ep1)
	eps = append(eps, ep2)

	// act
	l := eps.Len()

	// assert
	assert.True(t, l == 2, "Number of Endpoints should be 2")
}

func TestIsDynamic(t *testing.T) {
	// arrange
	urlDynamic := "http://www.{}.nl"
	urlNotDynamic := "http://www.nu.nl"

	// act
	resultNotDynamic := isDynamic(urlNotDynamic)
	resultDynamic := isDynamic(urlDynamic)

	// assert
	assert.False(t, resultNotDynamic)
	assert.True(t, resultDynamic)
}

func TestEndPointSort(t *testing.T) {
	// arrange
	ep1 := &Endpoint{}
	ep1.Operation.Path = "ep1"
	ep1.Operation.OperationType = models.HTTPOperationGet
	ep2 := &Endpoint{}
	ep2.Operation.Path = "ep2"
	ep2.Operation.OperationType = models.HTTPOperationPost

	eps := Endpoints{ep1, ep2}

	// act
	sort.Sort(eps)

	// assert
	assert.True(t, len(eps) == 2, "Number of Endpoints should be 2")
	// post becomes first after sorting
	assert.True(t, eps[0].Operation.Path == "ep2")
	assert.True(t, eps[1].Operation.Path == "ep1")
}

func TestEndPointSortDynamic(t *testing.T) {
	// arrange
	httpep1 := &Endpoint{}
	httpep1.Operation.Path = "ep1{}"
	httpep1.Operation.OperationType = models.HTTPOperationGet
	httpep2 := &Endpoint{}
	httpep2.Operation.Path = "ep2{}longer"
	httpep2.Operation.OperationType = models.HTTPOperationPost

	eps := Endpoints{httpep1, httpep2}

	// act
	sort.Sort(eps)

	// assert
	assert.True(t, len(eps) == 2, "Number of Endpoints should be 2")
	// when both urls are dynamic, the longer path comes first
	assert.True(t, eps[0].Operation.Path == "ep2{}longer")
	assert.True(t, eps[1].Operation.Path == "ep1{}")
}

func TestEndPointSortlength(t *testing.T) {
	// arrange
	httpep1 := &Endpoint{}
	httpep1.Operation.Path = "ep1"
	httpep1.Operation.OperationType = models.HTTPOperationGet
	httpep2 := &Endpoint{}
	httpep2.Operation.Path = "ep2longer"
	httpep2.Operation.OperationType = models.HTTPOperationPost

	eps := Endpoints{httpep1, httpep2}

	// act
	sort.Sort(eps)

	// assert
	assert.True(t, len(eps) == 2, "Number of Endpoints should be 2")
	// when both urls are dynamic, the longer path comes first
	assert.True(t, eps[0].Operation.Path == "ep2longer")
	assert.True(t, eps[1].Operation.Path == "ep1")
}

func TestEndPointNotDynamic(t *testing.T) {
	// arrange
	httpep1 := &Endpoint{}
	httpep1.Operation.Path = "ep1 {c:.*}"
	httpep1.Operation.OperationType = models.HTTPOperationGet
	httpep2 := &Endpoint{}
	httpep2.Operation.Path = "ep2longer"
	httpep2.Operation.OperationType = models.HTTPOperationGet
	eps := Endpoints{httpep1, httpep2}

	// act
	sort.Sort(eps)

	// assert
	assert.True(t, eps[0].Operation.Path == "ep2longer")
	assert.True(t, eps[1].Operation.Path == "ep1 {c:.*}")

}
<commit_msg>Removed useless test + better checking on dynamic urls (100% hit)<commit_after>package http

import (
	"github.com/geodan/gost/sensorthings/models"
	"github.com/stretchr/testify/assert"
	"sort"
	"testing"
)

func TestIsDynamic(t *testing.T) {
	// arrange
	urlDynamic := "http://www.{}.nl"
	urlNotDynamic := "http://www.nu.nl"

	// act
	resultNotDynamic := isDynamic(urlNotDynamic)
	resultDynamic := isDynamic(urlDynamic)

	// assert
	assert.False(t, resultNotDynamic)
	assert.True(t, resultDynamic)
}

func TestEndPointSortDuplicate(t *testing.T) {
	// arrange
	ep1 := &Endpoint{Operation: models.EndpointOperation{Path: "ep1", OperationType: models.HTTPOperationGet}}
	ep2 := &Endpoint{Operation: models.EndpointOperation{Path: "ep1", OperationType: models.HTTPOperationGet}}
	eps := Endpoints{ep1, ep2}

	// assert
	assert.Panics(t, func() { sort.Sort(eps) })
}

func TestEndPointSort(t *testing.T) {
	// arrange
	ep1 := &Endpoint{}
	ep1.Operation.Path = "ep1"
	ep1.Operation.OperationType = models.HTTPOperationGet
	ep2 := &Endpoint{}
	ep2.Operation.Path = "ep2"
	ep2.Operation.OperationType = models.HTTPOperationPost
	ep3 := &Endpoint{}
	ep3.Operation.Path = "{c:.*}ep3"
	ep3.Operation.OperationType = models.HTTPOperationGet
	ep4 := &Endpoint{}
	ep4.Operation.Path = "ep4{c:.*}"
	ep4.Operation.OperationType = models.HTTPOperationGet
	ep5 := &Endpoint{}
	ep5.Operation.Path = "{c:.*}ep5{test}"
	ep5.Operation.OperationType = models.HTTPOperationGet
	ep6 := &Endpoint{}
	ep6.Operation.Path = "ep6{test}"
	ep6.Operation.OperationType = models.HTTPOperationGet
	ep7 := &Endpoint{}
	ep7.Operation.Path = "ep7"
	ep7.Operation.OperationType = models.HTTPOperationGet

	eps := Endpoints{ep1, ep2, ep3, ep4, ep5, ep6, ep7}

	// act
	sort.Sort(eps)

	// assert
	assert.True(t, len(eps) == 7, "Number of Endpoints should be 7")
	// post becomes first after sorting
	assert.True(t, eps[0].Operation.Path == "ep2")
	assert.True(t, eps[1].Operation.Path == "ep1")
	assert.True(t, eps[2].Operation.Path == "ep7")
	assert.True(t, eps[3].Operation.Path == "ep6{test}")
	assert.True(t, eps[4].Operation.Path == "{c:.*}ep3")
	assert.True(t, eps[5].Operation.Path == "ep4{c:.*}")
	assert.True(t, eps[6].Operation.Path == "{c:.*}ep5{test}")
}

func TestEndPointSortDynamic(t *testing.T) {
	// arrange
	httpep1 := &Endpoint{}
	httpep1.Operation.Path = "ep1{}"
	httpep1.Operation.OperationType = models.HTTPOperationGet
	httpep2 := &Endpoint{}
	httpep2.Operation.Path = "ep2{}longer"
	httpep2.Operation.OperationType = models.HTTPOperationPost

	eps := Endpoints{httpep1, httpep2}

	// act
	sort.Sort(eps)

	// assert
	assert.True(t, len(eps) == 2, "Number of Endpoints should be 2")
	// when both urls are dynamic, the longer path comes first
	assert.True(t, eps[0].Operation.Path == "ep2{}longer")
	assert.True(t, eps[1].Operation.Path == "ep1{}")
}

func TestEndPointSortlength(t *testing.T) {
	// arrange
	httpep1 := &Endpoint{}
	httpep1.Operation.Path = "ep1"
	httpep1.Operation.OperationType = models.HTTPOperationGet
	httpep2 := &Endpoint{}
	httpep2.Operation.Path = "ep2longer"
	httpep2.Operation.OperationType = models.HTTPOperationPost

	eps := Endpoints{httpep1, httpep2}

	// act
	sort.Sort(eps)

	// assert
	assert.True(t, len(eps) == 2, "Number of Endpoints should be 2")
	// when both urls are dynamic, the longer path comes first
	assert.True(t, eps[0].Operation.Path == "ep2longer")
	assert.True(t, eps[1].Operation.Path == "ep1")
}

func TestEndPointNotDynamic(t *testing.T) {
	// arrange
	httpep1 := &Endpoint{}
	httpep1.Operation.Path = "ep1 {c:.*}"
	httpep1.Operation.OperationType = models.HTTPOperationGet
	httpep2 := &Endpoint{}
	httpep2.Operation.Path = "ep2longer"
	httpep2.Operation.OperationType = models.HTTPOperationGet
	eps := Endpoints{httpep1, httpep2}

	// act
	sort.Sort(eps)

	// assert
	assert.True(t, eps[0].Operation.Path == "ep2longer")
	assert.True(t, eps[1].Operation.Path == "ep1 {c:.*}")

}
<|endoftext|>


<commit_before>package httpctx

import (
	"encoding/json"
	"net/http"
	"strconv"
	"strings"
)

// shouldSendJson decides whether it is appropriate to send a JSON
// error response to the HTTP client.
func shouldSendJson(r *http.Request) bool {
	accept := r.Header.Get("Accept")

	// TODO: this is a very weak interpretation of the
	// HTTP Accept header, but in practice it works fine.
	// Note also the hack that if the url starts with "/api", we
	// will return any error as a JSON. In practice this is useful
	// enough when working with a web browser during development.
	return strings.Contains(accept, "application/json") ||
		strings.HasPrefix(r.URL.Path, "/api/")
}

// sendError sends an error message back to the client.
// Note that the error returned to the client contains the
// message returned by err.Error(). It is the calling program's
// responsibility not to return sensitive information in this
// error message.
func sendError(w http.ResponseWriter, r *http.Request, err error) {
	statusCode := http.StatusInternalServerError
	type Error interface {
		StatusCode() int
	}
	if errWithStatusCode, ok := err.(Error); ok {
		if errWithStatusCode.StatusCode() != 0 {
			statusCode = errWithStatusCode.StatusCode()
		}
	}

	var code string
	type ErrorWithCode interface {
		Code() string
	}
	if errWithCode, ok := err.(ErrorWithCode); ok {
		code = errWithCode.Code()
	}

	// remove headers that might have been set upstream
	w.Header().Del("Content-Encoding")

	if shouldSendJson(r) {
		var b []byte

		// if the error object can marshal itself, let it do so
		if _, ok := err.(json.Marshaler); ok {
			b, _ = json.Marshal(err)
		} else {
			// the error object does not know how to marshal itself,
			// so put the relevant information into a map and marshal
			// that. The Result will look like:
			// {"error":{"message":"message-here","code":"xyz123","status":400}}
			resp := map[string]map[string]interface{}{
				"error": {
					"message": err.Error(),
					"status":  statusCode,
				},
			}

			if code != "" {
				resp["error"]["code"] = code
			}

			b, _ = json.Marshal(resp)
		}
		w.Header().Set("Content-Type", "application/json")
		w.Header().Set("X-Content-Type-Options", "nosniff")
		w.Header().Set("Content-Length", strconv.Itoa(len(b)))
		w.WriteHeader(statusCode)
		w.Write(b)
	} else {
		http.Error(w, err.Error(), statusCode)
	}
}
<commit_msg>More error checking in, er, error checking<commit_after>package httpctx

import (
	"encoding/json"
	"net/http"
	"strconv"
	"strings"
)

// shouldSendJson decides whether it is appropriate to send a JSON
// error response to the HTTP client.
func shouldSendJson(r *http.Request) bool {
	accept := r.Header.Get("Accept")

	// TODO: this is a very weak interpretation of the
	// HTTP Accept header, but in practice it works fine.
	// Note also the hack that if the url starts with "/api", we
	// will return any error as a JSON. In practice this is useful
	// enough when working with a web browser during development.
	return strings.Contains(accept, "application/json") ||
		strings.HasPrefix(r.URL.Path, "/api/")
}

// sendError sends an error message back to the client.
// Note that the error returned to the client contains the
// message returned by err.Error(). It is the calling program's
// responsibility not to return sensitive information in this
// error message.
func sendError(w http.ResponseWriter, r *http.Request, err error) {
	statusCode := http.StatusInternalServerError
	type ErrorWithStatusCode interface {
		StatusCode() int
	}
	if errWithStatusCode, ok := err.(ErrorWithStatusCode); ok {
		if errWithStatusCode.StatusCode() != 0 {
			statusCode = errWithStatusCode.StatusCode()
		}
	}

	var code string
	type ErrorWithCode interface {
		Code() string
	}
	if errWithCode, ok := err.(ErrorWithCode); ok {
		code = errWithCode.Code()
	}

	// remove headers that might have been set upstream
	w.Header().Del("Content-Encoding")

	if shouldSendJson(r) {
		var b []byte

		// Put the relevant information into a map and marshal it.
		// The Result will look like:
		// {"error":{"message":"message-here","code":"xyz123","status":400}}
		resp := map[string]map[string]interface{}{
			"error": {
				"message": err.Error(),
				"status":  statusCode,
			},
		}
		if code != "" {
			resp["error"]["code"] = code
		}

		// If this does not succeed, then all we can do is to
		// send back the status code to the client, but cannot
		// send any payload.
		b, err = json.Marshal(resp)
		if err != nil {
			b = nil
		}

		w.Header().Set("Content-Type", "application/json")
		w.Header().Set("X-Content-Type-Options", "nosniff")
		w.Header().Set("Content-Length", strconv.Itoa(len(b)))
		w.WriteHeader(statusCode)
		if b != nil {
			w.Write(b)
		}
	} else {
		http.Error(w, err.Error(), statusCode)
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 Vadim Kravcenko
//
// 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.

// Gopencils is a Golang REST Client with which you can easily consume REST API's. Supported Response formats: JSON
package gopencils

import (
	"bytes"
	"encoding/json"
	"io"
	"net/http"
	"net/url"
	"strconv"
)

// Resource is basically an url relative to given API Baseurl.
type Resource struct {
	Api         *ApiStruct
	Url         string
	id          string
	QueryValues url.Values
	Payload     io.Reader
	Headers     http.Header
	Response    interface{}
	Raw         *http.Response
}

// Creates a new Resource.
func (r *Resource) Res(options ...interface{}) *Resource {
	if len(options) > 0 {
		var u string
		if len(r.Url) > 0 {
			u = r.Url + "/" + options[0].(string)
		} else {
			u = options[0].(string)
		}

		r.Api.Methods[u] = &Resource{Url: u, Api: r.Api, Headers: http.Header{}, QueryValues: make(url.Values)}

		if len(options) > 1 {
			r.Api.Methods[u].Response = options[1]
		}

		return r.Api.Methods[u]
	}
	return r
}

// Same as Res() Method, but returns a Resource with url resource/:id
func (r *Resource) Id(options ...interface{}) *Resource {
	if len(options) > 0 {
		id := ""
		switch v := options[0].(type) {
		default:
			id = v.(string)
		case int:
			id = strconv.Itoa(v)
		}
		url := r.Url + "/" + id
		r.Api.Methods[url] = &Resource{id: id, Url: url, Api: r.Api, Headers: http.Header{}}

		if len(options) > 1 {
			r.Api.Methods[url].Response = options[1]
		} else {
			r.Api.Methods[url].Response = &r.Api.Methods[r.Url].Response
		}
		return r.Api.Methods[url]
	}
	return r
}

// Sets QueryValues for current Resource
func (r *Resource) SetQuery(querystring map[string]string) *Resource {
	for k, v := range querystring {
		r.QueryValues.Set(k, v)
	}
	return r
}

// Performs a GET request on given Resource
// Accepts map[string]string as parameter, will be used as querystring.
func (r *Resource) Get(options ...interface{}) (*Resource, error) {
	if len(options) > 0 {
		if qry, ok := options[0].(map[string]string); ok {
			for k, v := range qry {
				r.QueryValues.Set(k, v)
			}
		} // else { panic ? }

	}
	return r.do("GET")
}

// Performs a HEAD request on given Resource
// Accepts map[string]string as parameter, will be used as querystring.
func (r *Resource) Head(options ...interface{}) (*Resource, error) {
	if len(options) > 0 {
		if qry, ok := options[0].(map[string]string); ok {
			for k, v := range qry {
				r.QueryValues.Set(k, v)
			}
		} // else { panic ? }
	}
	return r.do("HEAD")
}

// Performs a PUT request on given Resource.
// Accepts interface{} as parameter, will be used as payload.
func (r *Resource) Put(options ...interface{}) (*Resource, error) {
	if len(options) > 0 {
		r.Payload = r.SetPayload(options[0])
	}
	return r.do("PUT")
}

// Performs a POST request on given Resource.
// Accepts interface{} as parameter, will be used as payload.
func (r *Resource) Post(options ...interface{}) (*Resource, error) {
	if len(options) > 0 {
		r.Payload = r.SetPayload(options[0])
	}
	return r.do("POST")
}

// Performs a Delete request on given Resource.
// Accepts map[string]string as parameter, will be used as querystring.
func (r *Resource) Delete(options ...interface{}) (*Resource, error) {
	if len(options) > 0 {
		if qry, ok := options[0].(map[string]string); ok {
			for k, v := range qry {
				r.QueryValues.Set(k, v)
			}
		} // else { panic ? }
	}
	return r.do("DELETE")
}

// Performs a Delete request on given Resource.
// Accepts map[string]string as parameter, will be used as querystring.
func (r *Resource) Options(options ...interface{}) (*Resource, error) {
	if len(options) > 0 {
		if qry, ok := options[0].(map[string]string); ok {
			for k, v := range qry {
				r.QueryValues.Set(k, v)
			}
		} // else { panic ? }
	}
	return r.do("OPTIONS")
}

// Performs a PATCH request on given Resource.
// Accepts interface{} as parameter, will be used as payload.
func (r *Resource) Patch(options ...interface{}) (*Resource, error) {
	if len(options) > 0 {
		r.Payload = r.SetPayload(options[0])
	}
	return r.do("PATCH")
}

// Main method, opens the connection, sets basic auth, applies headers,
// parses response json.
func (r *Resource) do(method string) (*Resource, error) {
	r.Api.BaseUrl.Path = r.Url
	r.Api.BaseUrl.RawQuery = r.QueryValues.Encode()
	url := r.Api.BaseUrl.String()
	req, err := http.NewRequest(method, url, r.Payload)
	if err != nil {
		return r, err
	}

	if r.Api.BasicAuth != nil {
		req.SetBasicAuth(r.Api.BasicAuth.Username, r.Api.BasicAuth.Password)
	}

	if r.Headers != nil {
		for k, _ := range r.Headers {
			req.Header.Set(k, r.Headers.Get(k))
		}
	}

	resp, err := r.Api.Client.Do(req)
	if err != nil {
		return r, err
	}

	r.Raw = resp

	defer resp.Body.Close()

	err = json.NewDecoder(resp.Body).Decode(r.Api.Methods[r.Url].Response)
	if err != nil {
		return r, err
	}

	return r, nil
}

// Sets Payload for current Resource
func (r *Resource) SetPayload(args interface{}) io.Reader {
	var b []byte
	b, _ = json.Marshal(args)
	r.SetHeader("Content-Type", "application/json")
	return bytes.NewBuffer(b)
}

// Sets Headers
func (r *Resource) SetHeader(key string, value string) {
	r.Headers.Add(key, value)
}

// Overwrites the client that will be used for requests.
// For example if you want to use your own client with OAuth2
func (r *Resource) SetClient(c *http.Client) {
	r.Api.Client = c
}
<commit_msg>Simplify by usung r.SetQuery()<commit_after>// Copyright 2014 Vadim Kravcenko
//
// 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.

// Gopencils is a Golang REST Client with which you can easily consume REST API's. Supported Response formats: JSON
package gopencils

import (
	"bytes"
	"encoding/json"
	"errors"
	"io"
	"net/http"
	"net/url"
	"strconv"
)

var ErrCantUseAsQuery = errors.New("can't use options[0] as Query")

// Resource is basically an url relative to given API Baseurl.
type Resource struct {
	Api         *ApiStruct
	Url         string
	id          string
	QueryValues url.Values
	Payload     io.Reader
	Headers     http.Header
	Response    interface{}
	Raw         *http.Response
}

// Creates a new Resource.
func (r *Resource) Res(options ...interface{}) *Resource {
	if len(options) > 0 {
		var u string
		if len(r.Url) > 0 {
			u = r.Url + "/" + options[0].(string)
		} else {
			u = options[0].(string)
		}

		r.Api.Methods[u] = &Resource{Url: u, Api: r.Api, Headers: http.Header{}, QueryValues: make(url.Values)}

		if len(options) > 1 {
			r.Api.Methods[u].Response = options[1]
		}

		return r.Api.Methods[u]
	}
	return r
}

// Same as Res() Method, but returns a Resource with url resource/:id
func (r *Resource) Id(options ...interface{}) *Resource {
	if len(options) > 0 {
		id := ""
		switch v := options[0].(type) {
		default:
			id = v.(string)
		case int:
			id = strconv.Itoa(v)
		}
		url := r.Url + "/" + id
		r.Api.Methods[url] = &Resource{id: id, Url: url, Api: r.Api, Headers: http.Header{}}

		if len(options) > 1 {
			r.Api.Methods[url].Response = options[1]
		} else {
			r.Api.Methods[url].Response = &r.Api.Methods[r.Url].Response
		}
		return r.Api.Methods[url]
	}
	return r
}

// Sets QueryValues for current Resource
func (r *Resource) SetQuery(querystring map[string]string) *Resource {
	for k, v := range querystring {
		r.QueryValues.Set(k, v)
	}
	return r
}

// Performs a GET request on given Resource
// Accepts map[string]string as parameter, will be used as querystring.
func (r *Resource) Get(options ...interface{}) (*Resource, error) {
	if len(options) > 0 {
		if qry, ok := options[0].(map[string]string); ok {
			r.SetQuery(qry)
		} else {
			return nil, ErrCantUseAsQuery
		}

	}
	return r.do("GET")
}

// Performs a HEAD request on given Resource
// Accepts map[string]string as parameter, will be used as querystring.
func (r *Resource) Head(options ...interface{}) (*Resource, error) {
	if len(options) > 0 {
		if qry, ok := options[0].(map[string]string); ok {
			r.SetQuery(qry)
		} else {
			return nil, ErrCantUseAsQuery
		}
	}
	return r.do("HEAD")
}

// Performs a PUT request on given Resource.
// Accepts interface{} as parameter, will be used as payload.
func (r *Resource) Put(options ...interface{}) (*Resource, error) {
	if len(options) > 0 {
		r.Payload = r.SetPayload(options[0])
	}
	return r.do("PUT")
}

// Performs a POST request on given Resource.
// Accepts interface{} as parameter, will be used as payload.
func (r *Resource) Post(options ...interface{}) (*Resource, error) {
	if len(options) > 0 {
		r.Payload = r.SetPayload(options[0])
	}
	return r.do("POST")
}

// Performs a Delete request on given Resource.
// Accepts map[string]string as parameter, will be used as querystring.
func (r *Resource) Delete(options ...interface{}) (*Resource, error) {
	if len(options) > 0 {
		if qry, ok := options[0].(map[string]string); ok {
			r.SetQuery(qry)
		} else {
			return nil, ErrCantUseAsQuery
		}
	}
	return r.do("DELETE")
}

// Performs a Delete request on given Resource.
// Accepts map[string]string as parameter, will be used as querystring.
func (r *Resource) Options(options ...interface{}) (*Resource, error) {
	if len(options) > 0 {
		if qry, ok := options[0].(map[string]string); ok {
			r.SetQuery(qry)
		} else {
			return nil, ErrCantUseAsQuery
		}
	}
	return r.do("OPTIONS")
}

// Performs a PATCH request on given Resource.
// Accepts interface{} as parameter, will be used as payload.
func (r *Resource) Patch(options ...interface{}) (*Resource, error) {
	if len(options) > 0 {
		r.Payload = r.SetPayload(options[0])
	}
	return r.do("PATCH")
}

// Main method, opens the connection, sets basic auth, applies headers,
// parses response json.
func (r *Resource) do(method string) (*Resource, error) {
	r.Api.BaseUrl.Path = r.Url
	r.Api.BaseUrl.RawQuery = r.QueryValues.Encode()
	url := r.Api.BaseUrl.String()
	req, err := http.NewRequest(method, url, r.Payload)
	if err != nil {
		return r, err
	}

	if r.Api.BasicAuth != nil {
		req.SetBasicAuth(r.Api.BasicAuth.Username, r.Api.BasicAuth.Password)
	}

	if r.Headers != nil {
		for k, _ := range r.Headers {
			req.Header.Set(k, r.Headers.Get(k))
		}
	}

	resp, err := r.Api.Client.Do(req)
	if err != nil {
		return r, err
	}

	r.Raw = resp

	defer resp.Body.Close()

	err = json.NewDecoder(resp.Body).Decode(r.Api.Methods[r.Url].Response)
	if err != nil {
		return r, err
	}

	return r, nil
}

// Sets Payload for current Resource
func (r *Resource) SetPayload(args interface{}) io.Reader {
	var b []byte
	b, _ = json.Marshal(args)
	r.SetHeader("Content-Type", "application/json")
	return bytes.NewBuffer(b)
}

// Sets Headers
func (r *Resource) SetHeader(key string, value string) {
	r.Headers.Add(key, value)
}

// Overwrites the client that will be used for requests.
// For example if you want to use your own client with OAuth2
func (r *Resource) SetClient(c *http.Client) {
	r.Api.Client = c
}
<|endoftext|>