<commit_before>package vegeta

import (
	"bytes"
	"encoding/json"
	"fmt"
	"strconv"
	"strings"
	"text/tabwriter"
	"time"
)

// Reporter is an interface defining Report computation.
type Reporter interface {
	Report(Results) ([]byte, error)
}

// ReporterFunc is an adapter to allow the use of ordinary functions as
// Reporters. If f is a function with the appropriate signature, ReporterFunc(f)
// is a Reporter object that calls f.
type ReporterFunc func(Results) ([]byte, error)

// Report implements the Reporter interface.
func (f ReporterFunc) Report(r Results) ([]byte, error) { return f(r) }

// HistogramReporter is a reporter that computes latency histograms with the
// given buckets.
type HistogramReporter []time.Duration

// Report implements the Reporter interface.
func (h HistogramReporter) Report(r Results) ([]byte, error) {
	var buf bytes.Buffer
	w := tabwriter.NewWriter(&buf, 0, 8, 2, ' ', tabwriter.StripEscape)

	bucket := func(i int) string {
		if i+1 >= len(h) {
			return fmt.Sprintf("[%s,\t+Inf]", h[i])
		}
		return fmt.Sprintf("[%s,\t%s]", h[i], h[i+1])
	}

	fmt.Fprintf(w, "Bucket\t\t#\t%%\tHistogram\n")
	for i, count := range Histogram(h, r) {
		ratio := float64(count) / float64(len(r))
		fmt.Fprintf(w, "%s\t%d\t%.2f%%\t%s\n",
			bucket(i),
			count,
			ratio*100,
			strings.Repeat("#", int(ratio*75)),
		)
	}

	err := w.Flush()
	return buf.Bytes(), err
}

// Set implements the flag.Value interface.
func (h *HistogramReporter) Set(value string) error {
	if len(value) < 2 || value[0] != '[' || value[len(value)-1] != ']' {
		return fmt.Errorf("bad buckets: %s", value)
	}
	for _, v := range strings.Split(value[1:len(value)-1], ",") {
		d, err := time.ParseDuration(strings.TrimSpace(v))
		if err != nil {
			return err
		}
		*h = append(*h, d)
	}
	if len(*h) == 0 {
		return fmt.Errorf("bad buckets: %s", value)
	}
	return nil
}

// String implements the fmt.Stringer interface.
func (h HistogramReporter) String() string {
	strs := make([]string, len(h))
	for i := range strs {
		strs[i] = strconv.FormatInt(int64(h[i]), 10)
	}
	return "[" + strings.Join(strs, ",") + "]"
}

// ReportText returns a computed Metrics struct as aligned, formatted text.
var ReportText ReporterFunc = func(r Results) ([]byte, error) {
	m := NewMetrics(r)
	out := &bytes.Buffer{}

	w := tabwriter.NewWriter(out, 0, 8, 2, '\t', tabwriter.StripEscape)
	fmt.Fprintf(w, "Requests\t[total]\t%d\n", m.Requests)
	fmt.Fprintf(w, "Duration\t[total, attack, wait]\t%s, %s, %s\n", m.Duration+m.Wait, m.Duration, m.Wait)
	fmt.Fprintf(w, "Latencies\t[mean, 50, 95, 99, max]\t%s, %s, %s, %s, %s\n",
		m.Latencies.Mean, m.Latencies.P50, m.Latencies.P95, m.Latencies.P99, m.Latencies.Max)
	fmt.Fprintf(w, "Bytes In\t[total, mean]\t%d, %.2f\n", m.BytesIn.Total, m.BytesIn.Mean)
	fmt.Fprintf(w, "Bytes Out\t[total, mean]\t%d, %.2f\n", m.BytesOut.Total, m.BytesOut.Mean)
	fmt.Fprintf(w, "Success\t[ratio]\t%.2f%%\n", m.Success*100)
	fmt.Fprintf(w, "Status Codes\t[code:count]\t")
	for code, count := range m.StatusCodes {
		fmt.Fprintf(w, "%s:%d  ", code, count)
	}
	fmt.Fprintln(w, "\nError Set:")
	for _, err := range m.Errors {
		fmt.Fprintln(w, err)
	}

	if err := w.Flush(); err != nil {
		return []byte{}, err
	}
	return out.Bytes(), nil
}

// ReportJSON writes a computed Metrics struct to as JSON
var ReportJSON ReporterFunc = func(r Results) ([]byte, error) {
	return json.Marshal(NewMetrics(r))
}

// ReportPlot builds up a self contained HTML page with an interactive plot
// of the latencies of the requests. Built with http://dygraphs.com/
var ReportPlot ReporterFunc = func(r Results) ([]byte, error) {
	var series []byte
	for i := range r {
		series = append(series, '[')
		series = append(series, strconv.FormatFloat(
			r[i].Timestamp.Sub(r[0].Timestamp).Seconds(), 'f', -1, 32)...)
		series = append(series, ',')

		latency := strconv.FormatFloat(r[i].Latency.Seconds()*1000, 'f', -1, 32)
		if r[i].Error == "" {
			series = append(series, "NaN,"...)
			series = append(series, latency...)
			series = append(series, ']', ',')
		} else {
			series = append(series, latency...)
			series = append(series, ",NaN],"...)
		}
	}
	// Remove trailing commas
	if len(series) > 0 {
		series = series[:len(series)-1]
	}
	return []byte(fmt.Sprintf(plotsTemplate, dygraphJSLibSrc(), series)), nil
}

const plotsTemplate = `<!doctype>

  <title>Vegeta Plots</title>

  Download as PNG

`
<commit_msg>Fix plot reporter HTML page doctype<commit_after>package vegeta

import (
	"bytes"
	"encoding/json"
	"fmt"
	"strconv"
	"strings"
	"text/tabwriter"
	"time"
)

// Reporter is an interface defining Report computation.
type Reporter interface {
	Report(Results) ([]byte, error)
}

// ReporterFunc is an adapter to allow the use of ordinary functions as
// Reporters. If f is a function with the appropriate signature, ReporterFunc(f)
// is a Reporter object that calls f.
type ReporterFunc func(Results) ([]byte, error)

// Report implements the Reporter interface.
func (f ReporterFunc) Report(r Results) ([]byte, error) { return f(r) }

// HistogramReporter is a reporter that computes latency histograms with the
// given buckets.
type HistogramReporter []time.Duration

// Report implements the Reporter interface.
func (h HistogramReporter) Report(r Results) ([]byte, error) {
	var buf bytes.Buffer
	w := tabwriter.NewWriter(&buf, 0, 8, 2, ' ', tabwriter.StripEscape)

	bucket := func(i int) string {
		if i+1 >= len(h) {
			return fmt.Sprintf("[%s,\t+Inf]", h[i])
		}
		return fmt.Sprintf("[%s,\t%s]", h[i], h[i+1])
	}

	fmt.Fprintf(w, "Bucket\t\t#\t%%\tHistogram\n")
	for i, count := range Histogram(h, r) {
		ratio := float64(count) / float64(len(r))
		fmt.Fprintf(w, "%s\t%d\t%.2f%%\t%s\n",
			bucket(i),
			count,
			ratio*100,
			strings.Repeat("#", int(ratio*75)),
		)
	}

	err := w.Flush()
	return buf.Bytes(), err
}

// Set implements the flag.Value interface.
func (h *HistogramReporter) Set(value string) error {
	if len(value) < 2 || value[0] != '[' || value[len(value)-1] != ']' {
		return fmt.Errorf("bad buckets: %s", value)
	}
	for _, v := range strings.Split(value[1:len(value)-1], ",") {
		d, err := time.ParseDuration(strings.TrimSpace(v))
		if err != nil {
			return err
		}
		*h = append(*h, d)
	}
	if len(*h) == 0 {
		return fmt.Errorf("bad buckets: %s", value)
	}
	return nil
}

// String implements the fmt.Stringer interface.
func (h HistogramReporter) String() string {
	strs := make([]string, len(h))
	for i := range strs {
		strs[i] = strconv.FormatInt(int64(h[i]), 10)
	}
	return "[" + strings.Join(strs, ",") + "]"
}

// ReportText returns a computed Metrics struct as aligned, formatted text.
var ReportText ReporterFunc = func(r Results) ([]byte, error) {
	m := NewMetrics(r)
	out := &bytes.Buffer{}

	w := tabwriter.NewWriter(out, 0, 8, 2, '\t', tabwriter.StripEscape)
	fmt.Fprintf(w, "Requests\t[total]\t%d\n", m.Requests)
	fmt.Fprintf(w, "Duration\t[total, attack, wait]\t%s, %s, %s\n", m.Duration+m.Wait, m.Duration, m.Wait)
	fmt.Fprintf(w, "Latencies\t[mean, 50, 95, 99, max]\t%s, %s, %s, %s, %s\n",
		m.Latencies.Mean, m.Latencies.P50, m.Latencies.P95, m.Latencies.P99, m.Latencies.Max)
	fmt.Fprintf(w, "Bytes In\t[total, mean]\t%d, %.2f\n", m.BytesIn.Total, m.BytesIn.Mean)
	fmt.Fprintf(w, "Bytes Out\t[total, mean]\t%d, %.2f\n", m.BytesOut.Total, m.BytesOut.Mean)
	fmt.Fprintf(w, "Success\t[ratio]\t%.2f%%\n", m.Success*100)
	fmt.Fprintf(w, "Status Codes\t[code:count]\t")
	for code, count := range m.StatusCodes {
		fmt.Fprintf(w, "%s:%d  ", code, count)
	}
	fmt.Fprintln(w, "\nError Set:")
	for _, err := range m.Errors {
		fmt.Fprintln(w, err)
	}

	if err := w.Flush(); err != nil {
		return []byte{}, err
	}
	return out.Bytes(), nil
}

// ReportJSON writes a computed Metrics struct to as JSON
var ReportJSON ReporterFunc = func(r Results) ([]byte, error) {
	return json.Marshal(NewMetrics(r))
}

// ReportPlot builds up a self contained HTML page with an interactive plot
// of the latencies of the requests. Built with http://dygraphs.com/
var ReportPlot ReporterFunc = func(r Results) ([]byte, error) {
	var series []byte
	for i := range r {
		series = append(series, '[')
		series = append(series, strconv.FormatFloat(
			r[i].Timestamp.Sub(r[0].Timestamp).Seconds(), 'f', -1, 32)...)
		series = append(series, ',')

		latency := strconv.FormatFloat(r[i].Latency.Seconds()*1000, 'f', -1, 32)
		if r[i].Error == "" {
			series = append(series, "NaN,"...)
			series = append(series, latency...)
			series = append(series, ']', ',')
		} else {
			series = append(series, latency...)
			series = append(series, ",NaN],"...)
		}
	}
	// Remove trailing commas
	if len(series) > 0 {
		series = series[:len(series)-1]
	}
	return []byte(fmt.Sprintf(plotsTemplate, dygraphJSLibSrc(), series)), nil
}

const plotsTemplate = `<!doctype html>

  <title>Vegeta Plots</title>

  Download as PNG

`
<|endoftext|>


<commit_before>package main

/*
 * 1. Fresh installation
 * => replace.exe <sample.conf> <conf> ___YOUR_API_KEY___ <apikey>
 *	Substitute ___YOUR_API_KEY___ by <apikey> in <sample.conf> then it write to <conf>.
 *
 * 2. Upgrade to x64 from x86
 * => replace.exe <sample.conf> <conf> ___YOUR_API_KEY___ '' (empty string)
 *	Just copy <conf> from under ProgramFiles(x86)\Mackerel folder to <conf> if it exists.
 *	Otherwise completely same as the case of fresh installation.
 *
 * 3. Upgrade from same architecture
 * => replace.exe <sample.conf> <conf> ___YOUR_API_KEY___ '' (empty string)
 *	Do nothing.
 *
 * Currently it is impossible to distinguish between the case 2 and 3 from the arguments.
 * Therefore replace.exe looks <conf> on the location of mackerel-agent.exe,
 * if exists, it will judge the state is in the case of 3.
 */

import (
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"
)

func main() {
	if len(os.Args) < 5 {
		log.Fatal("Usage: replace [in file] [out file] [old string] [new string]")
	}
	inFile := os.Args[1]
	outFile := os.Args[2]
	oldStr := os.Args[3]
	newStr := os.Args[4]

	if newStr == "" { // upgrade
		if !filepath.IsAbs(outFile) {
			// This program is usually called by the installer; safe.
			log.Fatalf("%q: it must be an absolute path", outFile)
		}
		dir := filepath.Dir(outFile)
		name := filepath.Base(outFile)
		if oldDir := FallbackConfigDir(dir); oldDir != "" {
			oldFile := filepath.Join(oldDir, name)
			if err := migrateConfig(outFile, oldFile); err != nil {
				if !os.IsNotExist(err) {
					log.Fatalf("migrate %q to %q: %v", oldFile, outFile, err)
				}
				// Don't fallback; continue to the case 1.
				goto out
			}
			idFile := filepath.Join(dir, "id")
			oldIDFile := filepath.Join(oldDir, "id")
			if err := migrateConfig(idFile, oldIDFile); err != nil {
				if !os.IsNotExist(err) {
					log.Fatalf("migrate %q to %q: %v", oldIDFile, idFile, err)
				}
			}
			os.Exit(0)
		}
	}

out:
	content, err := ioutil.ReadFile(inFile)
	if err != nil {
		log.Fatal(err)
	}

	_, err = os.Stat(outFile)
	outFileIsExists := err == nil
	if !(outFileIsExists) {
		err = ioutil.WriteFile(outFile, []byte(strings.Replace(string(content), oldStr, newStr, -1)), 0644)
		if err != nil {
			log.Fatal(err)
		}
	}
}

// migrateConfig copies inFile to outFile if needed.
// If inFile is not exist, this will return os.ErrNotExist or its variants.
func migrateConfig(outFile, inFile string) error {
	w, err := os.OpenFile(outFile, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0666)
	if err != nil {
		if os.IsExist(err) {
			return nil
		}
		return err
	}
	r, err := os.Open(inFile)
	if os.IsNotExist(err) {
		return err
	}
	_, err = io.Copy(w, r)
	return err
}

func isExist(file string) (bool, error) {
	f, err := os.Open(file)
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil
		}
		return false, err
	}
	f.Close()
	return true, nil
}
<commit_msg>replace: rename migrateConfig -> migrateFile<commit_after>package main

/*
 * 1. Fresh installation
 * => replace.exe <sample.conf> <conf> ___YOUR_API_KEY___ <apikey>
 *	Substitute ___YOUR_API_KEY___ by <apikey> in <sample.conf> then it write to <conf>.
 *
 * 2. Upgrade to x64 from x86
 * => replace.exe <sample.conf> <conf> ___YOUR_API_KEY___ '' (empty string)
 *	Just copy <conf> from under ProgramFiles(x86)\Mackerel folder to <conf> if it exists.
 *	Otherwise completely same as the case of fresh installation.
 *
 * 3. Upgrade from same architecture
 * => replace.exe <sample.conf> <conf> ___YOUR_API_KEY___ '' (empty string)
 *	Do nothing.
 *
 * Currently it is impossible to distinguish between the case 2 and 3 from the arguments.
 * Therefore replace.exe looks <conf> on the location of mackerel-agent.exe,
 * if exists, it will judge the state is in the case of 3.
 */

import (
	"io"
	"io/ioutil"
	"log"
	"os"
	"path/filepath"
	"strings"
)

func main() {
	if len(os.Args) < 5 {
		log.Fatal("Usage: replace [in file] [out file] [old string] [new string]")
	}
	inFile := os.Args[1]
	outFile := os.Args[2]
	oldStr := os.Args[3]
	newStr := os.Args[4]

	if newStr == "" { // upgrade
		if !filepath.IsAbs(outFile) {
			// This program is usually called by the installer; safe.
			log.Fatalf("%q: it must be an absolute path", outFile)
		}
		dir := filepath.Dir(outFile)
		name := filepath.Base(outFile)
		if oldDir := FallbackConfigDir(dir); oldDir != "" {
			oldFile := filepath.Join(oldDir, name)
			if err := migrateFile(outFile, oldFile); err != nil {
				if !os.IsNotExist(err) {
					log.Fatalf("migrate %q to %q: %v", oldFile, outFile, err)
				}
				// Don't fallback; continue to the case 1.
				goto out
			}
			idFile := filepath.Join(dir, "id")
			oldIDFile := filepath.Join(oldDir, "id")
			if err := migrateFile(idFile, oldIDFile); err != nil {
				if !os.IsNotExist(err) {
					log.Fatalf("migrate %q to %q: %v", oldIDFile, idFile, err)
				}
			}
			os.Exit(0)
		}
	}

out:
	content, err := ioutil.ReadFile(inFile)
	if err != nil {
		log.Fatal(err)
	}

	_, err = os.Stat(outFile)
	outFileIsExists := err == nil
	if !(outFileIsExists) {
		err = ioutil.WriteFile(outFile, []byte(strings.Replace(string(content), oldStr, newStr, -1)), 0644)
		if err != nil {
			log.Fatal(err)
		}
	}
}

// migrateFile copies inFile to outFile if needed.
// If inFile is not exist, this will return os.ErrNotExist or its variants.
func migrateFile(outFile, inFile string) error {
	w, err := os.OpenFile(outFile, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0666)
	if err != nil {
		if os.IsExist(err) {
			return nil
		}
		return err
	}
	r, err := os.Open(inFile)
	if os.IsNotExist(err) {
		return err
	}
	_, err = io.Copy(w, r)
	return err
}

func isExist(file string) (bool, error) {
	f, err := os.Open(file)
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil
		}
		return false, err
	}
	f.Close()
	return true, nil
}
<|endoftext|>


<commit_before>package command

import (
	"strings"
	"sync"

	"github.com/igungor/tlbot"
)

// A Command is an implementation of a bot command.
type Command struct {
	// Name of the command
	Name string

	// Short description of the command
	ShortLine string

	// Some commands would like to stay private, such as easter eggs or
	// built-in commands. Respect to their choices.
	Private bool

	// Run runs the command.
	Run func(bot *tlbot.Bot, msg *tlbot.Message)
}

var (
	mu       sync.Mutex
	commands = make(map[string]*Command)
)

func register(cmd *Command) {
	mu.Lock()
	defer mu.Unlock()

	commands[cmd.Name] = cmd
}

// Lookup looks-up name from registered commands and returns
// corresponding Command if any.
func Lookup(cmdname string) *Command {
	mu.Lock()
	defer mu.Unlock()

	cmdname = strings.TrimSuffix(cmdname, "@ilberbot")
	cmd, ok := commands[cmdname]
	if !ok {
		return nil
	}
	return cmd
}
<commit_msg>Add a TODO<commit_after>package command

import (
	"strings"
	"sync"

	"github.com/igungor/tlbot"
)

// A Command is an implementation of a bot command.
type Command struct {
	// Name of the command
	Name string

	// Short description of the command
	ShortLine string

	// Some commands would like to stay private, such as easter eggs or
	// built-in commands. Respect to their choices.
	Private bool

	// Run runs the command.
	Run func(bot *tlbot.Bot, msg *tlbot.Message)
}

var (
	mu       sync.Mutex
	commands = make(map[string]*Command)
)

func register(cmd *Command) {
	mu.Lock()
	defer mu.Unlock()

	commands[cmd.Name] = cmd
}

// Lookup looks-up name from registered commands and returns
// corresponding Command if any.
func Lookup(cmdname string) *Command {
	mu.Lock()
	defer mu.Unlock()

	cmdname = strings.TrimSuffix(cmdname, "@ilberbot")
	cmd, ok := commands[cmdname]
	if !ok {
		// TODO: may be add an autocorrect mechanism here? /idbm -> /imdb
		return nil
	}
	return cmd
}
<|endoftext|>


<commit_before>package command

import (
	"fmt"
	"net"
	"regexp"
	"sort"
	"strings"

	consulapi "github.com/hashicorp/consul/api"
	"github.com/hashicorp/serf/serf"
	"github.com/ryanuber/columnize"
)

// MembersCommand is a Command implementation that queries a running
// Consul agent what members are part of the cluster currently.
type MembersCommand struct {
	BaseCommand
}

func (c *MembersCommand) Help() string {
	helpText := `
Usage: consul members [options]

  Outputs the members of a running Consul agent.

` + c.BaseCommand.Help()

	return strings.TrimSpace(helpText)
}

func (c *MembersCommand) Run(args []string) int {
	var detailed bool
	var wan bool
	var statusFilter string
	var segment string

	f := c.BaseCommand.NewFlagSet(c)
	f.BoolVar(&detailed, "detailed", false,
		"Provides detailed information about nodes.")
	f.BoolVar(&wan, "wan", false,
		"If the agent is in server mode, this can be used to return the other "+
			"peers in the WAN pool.")
	f.StringVar(&statusFilter, "status", ".*",
		"If provided, output is filtered to only nodes matching the regular "+
			"expression for status.")
	f.StringVar(&segment, "segment", consulapi.AllSegments,
		"(Enterprise-only) If provided, output is filtered to only nodes in"+
			"the given segment.")

	if err := c.BaseCommand.Parse(args); err != nil {
		return 1
	}

	// Compile the regexp
	statusRe, err := regexp.Compile(statusFilter)
	if err != nil {
		c.UI.Error(fmt.Sprintf("Failed to compile status regexp: %v", err))
		return 1
	}

	client, err := c.BaseCommand.HTTPClient()
	if err != nil {
		c.UI.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
		return 1
	}

	// Make the request.
	opts := consulapi.MembersOpts{
		Segment: segment,
		WAN:     wan,
	}
	members, err := client.Agent().MembersOpts(opts)
	if err != nil {
		c.UI.Error(fmt.Sprintf("Error retrieving members: %s", err))
		return 1
	}

	// Filter the results
	n := len(members)
	for i := 0; i < n; i++ {
		member := members[i]
		if member.Tags["segment"] == "" {
			member.Tags["segment"] = "<default>"
		}
		if member.Tags["role"] == "consul" {
			member.Tags["segment"] = "<all>"
		}
		statusString := serf.MemberStatus(member.Status).String()
		if !statusRe.MatchString(statusString) {
			members[i], members[n-1] = members[n-1], members[i]
			i--
			n--
			continue
		}
	}
	members = members[:n]

	// No matching members
	if len(members) == 0 {
		return 2
	}

	sort.Sort(ByMemberNameAndSegment(members))

	// Generate the output
	var result []string
	if detailed {
		result = c.detailedOutput(members)
	} else {
		result = c.standardOutput(members)
	}

	// Generate the columnized version
	output := columnize.SimpleFormat(result)
	c.UI.Output(output)

	return 0
}

// so we can sort members by name
type ByMemberNameAndSegment []*consulapi.AgentMember

func (m ByMemberNameAndSegment) Len() int      { return len(m) }
func (m ByMemberNameAndSegment) Swap(i, j int) { m[i], m[j] = m[j], m[i] }
func (m ByMemberNameAndSegment) Less(i, j int) bool {
	switch {
	case m[i].Tags["segment"] < m[j].Tags["segment"]:
		return true
	case m[i].Tags["segment"] > m[j].Tags["segment"]:
		return false
	default:
		return m[i].Name < m[j].Name
	}
}

// standardOutput is used to dump the most useful information about nodes
// in a more human-friendly format
func (c *MembersCommand) standardOutput(members []*consulapi.AgentMember) []string {
	result := make([]string, 0, len(members))
	header := "Node|Address|Status|Type|Build|Protocol|DC|Segment"
	result = append(result, header)
	for _, member := range members {
		addr := net.TCPAddr{IP: net.ParseIP(member.Addr), Port: int(member.Port)}
		protocol := member.Tags["vsn"]
		build := member.Tags["build"]
		if build == "" {
			build = "< 0.3"
		} else if idx := strings.Index(build, ":"); idx != -1 {
			build = build[:idx]
		}
		dc := member.Tags["dc"]
		segment := member.Tags["segment"]

		statusString := serf.MemberStatus(member.Status).String()
		switch member.Tags["role"] {
		case "node":
			line := fmt.Sprintf("%s|%s|%s|client|%s|%s|%s|%s",
				member.Name, addr.String(), statusString, build, protocol, dc, segment)
			result = append(result, line)
		case "consul":
			line := fmt.Sprintf("%s|%s|%s|server|%s|%s|%s|%s",
				member.Name, addr.String(), statusString, build, protocol, dc, segment)
			result = append(result, line)
		default:
			line := fmt.Sprintf("%s|%s|%s|unknown||||",
				member.Name, addr.String(), statusString)
			result = append(result, line)
		}
	}
	return result
}

// detailedOutput is used to dump all known information about nodes in
// their raw format
func (c *MembersCommand) detailedOutput(members []*consulapi.AgentMember) []string {
	result := make([]string, 0, len(members))
	header := "Node|Address|Status|Tags"
	result = append(result, header)
	for _, member := range members {
		// Get the tags sorted by key
		tagKeys := make([]string, 0, len(member.Tags))
		for key := range member.Tags {
			tagKeys = append(tagKeys, key)
		}
		sort.Strings(tagKeys)

		// Format the tags as tag1=v1,tag2=v2,...
		var tagPairs []string
		for _, key := range tagKeys {
			tagPairs = append(tagPairs, fmt.Sprintf("%s=%s", key, member.Tags[key]))
		}

		tags := strings.Join(tagPairs, ",")

		addr := net.TCPAddr{IP: net.ParseIP(member.Addr), Port: int(member.Port)}
		line := fmt.Sprintf("%s|%s|%s|%s",
			member.Name, addr.String(), serf.MemberStatus(member.Status).String(), tags)
		result = append(result, line)
	}
	return result
}

func (c *MembersCommand) Synopsis() string {
	return "Lists the members of a Consul cluster"
}
<commit_msg>Remaps servers to "<all>" only when listing multiple segments.<commit_after>package command

import (
	"fmt"
	"net"
	"regexp"
	"sort"
	"strings"

	consulapi "github.com/hashicorp/consul/api"
	"github.com/hashicorp/serf/serf"
	"github.com/ryanuber/columnize"
)

// MembersCommand is a Command implementation that queries a running
// Consul agent what members are part of the cluster currently.
type MembersCommand struct {
	BaseCommand
}

func (c *MembersCommand) Help() string {
	helpText := `
Usage: consul members [options]

  Outputs the members of a running Consul agent.

` + c.BaseCommand.Help()

	return strings.TrimSpace(helpText)
}

func (c *MembersCommand) Run(args []string) int {
	var detailed bool
	var wan bool
	var statusFilter string
	var segment string

	f := c.BaseCommand.NewFlagSet(c)
	f.BoolVar(&detailed, "detailed", false,
		"Provides detailed information about nodes.")
	f.BoolVar(&wan, "wan", false,
		"If the agent is in server mode, this can be used to return the other "+
			"peers in the WAN pool.")
	f.StringVar(&statusFilter, "status", ".*",
		"If provided, output is filtered to only nodes matching the regular "+
			"expression for status.")
	f.StringVar(&segment, "segment", consulapi.AllSegments,
		"(Enterprise-only) If provided, output is filtered to only nodes in"+
			"the given segment.")

	if err := c.BaseCommand.Parse(args); err != nil {
		return 1
	}

	// Compile the regexp
	statusRe, err := regexp.Compile(statusFilter)
	if err != nil {
		c.UI.Error(fmt.Sprintf("Failed to compile status regexp: %v", err))
		return 1
	}

	client, err := c.BaseCommand.HTTPClient()
	if err != nil {
		c.UI.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err))
		return 1
	}

	// Make the request.
	opts := consulapi.MembersOpts{
		Segment: segment,
		WAN:     wan,
	}
	members, err := client.Agent().MembersOpts(opts)
	if err != nil {
		c.UI.Error(fmt.Sprintf("Error retrieving members: %s", err))
		return 1
	}

	// Filter the results
	n := len(members)
	for i := 0; i < n; i++ {
		member := members[i]
		if member.Tags["segment"] == "" {
			member.Tags["segment"] = "<default>"
		}
		if segment == consulapi.AllSegments && member.Tags["role"] == "consul" {
			member.Tags["segment"] = "<all>"
		}
		statusString := serf.MemberStatus(member.Status).String()
		if !statusRe.MatchString(statusString) {
			members[i], members[n-1] = members[n-1], members[i]
			i--
			n--
			continue
		}
	}
	members = members[:n]

	// No matching members
	if len(members) == 0 {
		return 2
	}

	sort.Sort(ByMemberNameAndSegment(members))

	// Generate the output
	var result []string
	if detailed {
		result = c.detailedOutput(members)
	} else {
		result = c.standardOutput(members)
	}

	// Generate the columnized version
	output := columnize.SimpleFormat(result)
	c.UI.Output(output)

	return 0
}

// so we can sort members by name
type ByMemberNameAndSegment []*consulapi.AgentMember

func (m ByMemberNameAndSegment) Len() int      { return len(m) }
func (m ByMemberNameAndSegment) Swap(i, j int) { m[i], m[j] = m[j], m[i] }
func (m ByMemberNameAndSegment) Less(i, j int) bool {
	switch {
	case m[i].Tags["segment"] < m[j].Tags["segment"]:
		return true
	case m[i].Tags["segment"] > m[j].Tags["segment"]:
		return false
	default:
		return m[i].Name < m[j].Name
	}
}

// standardOutput is used to dump the most useful information about nodes
// in a more human-friendly format
func (c *MembersCommand) standardOutput(members []*consulapi.AgentMember) []string {
	result := make([]string, 0, len(members))
	header := "Node|Address|Status|Type|Build|Protocol|DC|Segment"
	result = append(result, header)
	for _, member := range members {
		addr := net.TCPAddr{IP: net.ParseIP(member.Addr), Port: int(member.Port)}
		protocol := member.Tags["vsn"]
		build := member.Tags["build"]
		if build == "" {
			build = "< 0.3"
		} else if idx := strings.Index(build, ":"); idx != -1 {
			build = build[:idx]
		}
		dc := member.Tags["dc"]
		segment := member.Tags["segment"]

		statusString := serf.MemberStatus(member.Status).String()
		switch member.Tags["role"] {
		case "node":
			line := fmt.Sprintf("%s|%s|%s|client|%s|%s|%s|%s",
				member.Name, addr.String(), statusString, build, protocol, dc, segment)
			result = append(result, line)
		case "consul":
			line := fmt.Sprintf("%s|%s|%s|server|%s|%s|%s|%s",
				member.Name, addr.String(), statusString, build, protocol, dc, segment)
			result = append(result, line)
		default:
			line := fmt.Sprintf("%s|%s|%s|unknown||||",
				member.Name, addr.String(), statusString)
			result = append(result, line)
		}
	}
	return result
}

// detailedOutput is used to dump all known information about nodes in
// their raw format
func (c *MembersCommand) detailedOutput(members []*consulapi.AgentMember) []string {
	result := make([]string, 0, len(members))
	header := "Node|Address|Status|Tags"
	result = append(result, header)
	for _, member := range members {
		// Get the tags sorted by key
		tagKeys := make([]string, 0, len(member.Tags))
		for key := range member.Tags {
			tagKeys = append(tagKeys, key)
		}
		sort.Strings(tagKeys)

		// Format the tags as tag1=v1,tag2=v2,...
		var tagPairs []string
		for _, key := range tagKeys {
			tagPairs = append(tagPairs, fmt.Sprintf("%s=%s", key, member.Tags[key]))
		}

		tags := strings.Join(tagPairs, ",")

		addr := net.TCPAddr{IP: net.ParseIP(member.Addr), Port: int(member.Port)}
		line := fmt.Sprintf("%s|%s|%s|%s",
			member.Name, addr.String(), serf.MemberStatus(member.Status).String(), tags)
		result = append(result, line)
	}
	return result
}

func (c *MembersCommand) Synopsis() string {
	return "Lists the members of a Consul cluster"
}
<|endoftext|>


<commit_before>package buf

import (
	"io"

	"v2ray.com/core/common/errors"
	"v2ray.com/core/common/signal"
)

type errorHandler func(error) error
type dataHandler func(MultiBuffer)

type copyHandler struct {
	onReadError  []errorHandler
	onData       []dataHandler
	onWriteError []errorHandler
}

func (h *copyHandler) readFrom(reader Reader) (MultiBuffer, error) {
	mb, err := reader.ReadMultiBuffer()
	if err != nil {
		for _, handler := range h.onReadError {
			err = handler(err)
		}
	}
	return mb, err
}

func (h *copyHandler) writeTo(writer Writer, mb MultiBuffer) error {
	err := writer.WriteMultiBuffer(mb)
	if err != nil {
		for _, handler := range h.onWriteError {
			err = handler(err)
		}
	}
	return err
}

// SizeCounter is for counting bytes copied by Copy().
type SizeCounter struct {
	Size int64
}

// CopyOption is an option for copying data.
type CopyOption func(*copyHandler)

// IgnoreReaderError is a CopyOption that ignores errors from reader. Copy will continue in such case.
func IgnoreReaderError() CopyOption {
	return func(handler *copyHandler) {
		handler.onReadError = append(handler.onReadError, func(err error) error {
			return nil
		})
	}
}

// IgnoreWriterError is a CopyOption that ignores errors from writer. Copy will continue in such case.
func IgnoreWriterError() CopyOption {
	return func(handler *copyHandler) {
		handler.onWriteError = append(handler.onWriteError, func(err error) error {
			return nil
		})
	}
}

// UpdateActivity is a CopyOption to update activity on each data copy operation.
func UpdateActivity(timer signal.ActivityUpdater) CopyOption {
	return func(handler *copyHandler) {
		handler.onData = append(handler.onData, func(MultiBuffer) {
			timer.Update()
		})
	}
}

// CountSize is a CopyOption that sums the total size of data copied into the given SizeCounter.
func CountSize(sc *SizeCounter) CopyOption {
	return func(handler *copyHandler) {
		handler.onData = append(handler.onData, func(b MultiBuffer) {
			sc.Size += int64(b.Len())
		})
	}
}

func copyInternal(reader Reader, writer Writer, handler *copyHandler) error {
	for {
		buffer, err := handler.readFrom(reader)
		if !buffer.IsEmpty() {
			for _, handler := range handler.onData {
				handler(buffer)
			}

			if werr := handler.writeTo(writer, buffer); werr != nil {
				buffer.Release()
				return werr
			}
		} else if err != nil {
			return err
		}
	}
}

// Copy dumps all payload from reader to writer or stops when an error occurs. It returns nil when EOF.
func Copy(reader Reader, writer Writer, options ...CopyOption) error {
	handler := new(copyHandler)
	for _, option := range options {
		option(handler)
	}
	err := copyInternal(reader, writer, handler)
	if err != nil && errors.Cause(err) != io.EOF {
		return err
	}
	return nil
}
<commit_msg>fix error handling in buf.Copy<commit_after>package buf

import (
	"io"

	"v2ray.com/core/common/errors"
	"v2ray.com/core/common/signal"
)

type errorHandler func(error) error
type dataHandler func(MultiBuffer)

type copyHandler struct {
	onReadError  []errorHandler
	onData       []dataHandler
	onWriteError []errorHandler
}

func (h *copyHandler) readFrom(reader Reader) (MultiBuffer, error) {
	mb, err := reader.ReadMultiBuffer()
	if err != nil {
		for _, handler := range h.onReadError {
			err = handler(err)
		}
	}
	return mb, err
}

func (h *copyHandler) writeTo(writer Writer, mb MultiBuffer) error {
	err := writer.WriteMultiBuffer(mb)
	if err != nil {
		for _, handler := range h.onWriteError {
			err = handler(err)
		}
	}
	return err
}

// SizeCounter is for counting bytes copied by Copy().
type SizeCounter struct {
	Size int64
}

// CopyOption is an option for copying data.
type CopyOption func(*copyHandler)

// IgnoreReaderError is a CopyOption that ignores errors from reader. Copy will continue in such case.
func IgnoreReaderError() CopyOption {
	return func(handler *copyHandler) {
		handler.onReadError = append(handler.onReadError, func(err error) error {
			return nil
		})
	}
}

// IgnoreWriterError is a CopyOption that ignores errors from writer. Copy will continue in such case.
func IgnoreWriterError() CopyOption {
	return func(handler *copyHandler) {
		handler.onWriteError = append(handler.onWriteError, func(err error) error {
			return nil
		})
	}
}

// UpdateActivity is a CopyOption to update activity on each data copy operation.
func UpdateActivity(timer signal.ActivityUpdater) CopyOption {
	return func(handler *copyHandler) {
		handler.onData = append(handler.onData, func(MultiBuffer) {
			timer.Update()
		})
	}
}

// CountSize is a CopyOption that sums the total size of data copied into the given SizeCounter.
func CountSize(sc *SizeCounter) CopyOption {
	return func(handler *copyHandler) {
		handler.onData = append(handler.onData, func(b MultiBuffer) {
			sc.Size += int64(b.Len())
		})
	}
}

func copyInternal(reader Reader, writer Writer, handler *copyHandler) error {
	for {
		buffer, err := handler.readFrom(reader)
		if !buffer.IsEmpty() {
			for _, handler := range handler.onData {
				handler(buffer)
			}

			if werr := handler.writeTo(writer, buffer); werr != nil {
				buffer.Release()
				return werr
			}
		}

		if err != nil {
			return err
		}
	}
}

// Copy dumps all payload from reader to writer or stops when an error occurs. It returns nil when EOF.
func Copy(reader Reader, writer Writer, options ...CopyOption) error {
	handler := new(copyHandler)
	for _, option := range options {
		option(handler)
	}
	err := copyInternal(reader, writer, handler)
	if err != nil && errors.Cause(err) != io.EOF {
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>package concourse

type Request struct {
	Source  Source            `json:"source"`
	Version map[string]string `json:"version"`
}

type Response []Release

// TODO: Rename to Version
type Release struct {
	ProductVersion string `json:"product_version"`
}

type Source struct {
	APIToken        string `json:"api_token"`
	ProductName     string `json:"product_name"`
	AccessKeyID     string `json:"access_key_id"`
	SecretAccessKey string `json:"secret_access_key"`
}

type InResponse struct {
	Version  Release    `json:"version"`
	Metadata []Metadata `json:"metadata"`
}

type Metadata struct {
	Name  string `json:"name"`
	Value string `json:"value"`
}

type OutRequest struct {
	Params OutParams `json:"params"`
	Source Source    `json:"source"`
}

type OutParams struct {
	File            string `json:"file"`
	FilepathPrefix  string `json:"s3_filepath_prefix"`
	VersionFile     string `json:"version_file"`
	ReleaseTypeFile string `json:"release_type_file"`
	ReleaseDateFile string `json:"release_date_file"`
	EulaSlugFile    string `json:"eula_slug_file"`
}

type OutResponse struct {
	Version  Release  `json:"version"`
	Metadata []string `json:"metadata"`
}
<commit_msg>Omit empty metadata.<commit_after>package concourse

type Request struct {
	Source  Source            `json:"source"`
	Version map[string]string `json:"version"`
}

type Response []Release

// TODO: Rename to Version
type Release struct {
	ProductVersion string `json:"product_version"`
}

type Source struct {
	APIToken        string `json:"api_token"`
	ProductName     string `json:"product_name"`
	AccessKeyID     string `json:"access_key_id"`
	SecretAccessKey string `json:"secret_access_key"`
}

type InResponse struct {
	Version  Release    `json:"version"`
	Metadata []Metadata `json:"metadata,omitempty"`
}

type Metadata struct {
	Name  string `json:"name,omitempty"`
	Value string `json:"value,omitempty"`
}

type OutRequest struct {
	Params OutParams `json:"params"`
	Source Source    `json:"source"`
}

type OutParams struct {
	File            string `json:"file"`
	FilepathPrefix  string `json:"s3_filepath_prefix"`
	VersionFile     string `json:"version_file"`
	ReleaseTypeFile string `json:"release_type_file"`
	ReleaseDateFile string `json:"release_date_file"`
	EulaSlugFile    string `json:"eula_slug_file"`
}

type OutResponse struct {
	Version  Release  `json:"version"`
	Metadata []string `json:"metadata,omitempty"`
}
<|endoftext|>


<commit_before>package twitter

import (
	"encoding/gob"
	"encoding/json"
	"io"
	"net/http"
	"os"
	"psychic-rat/log"
	"psychic-rat/types"

	"github.com/gorilla/sessions"
	"github.com/mrjones/oauth"
)

const (
	requestURL      = "https://api.twitter.com/oauth/request_token"
	authorizeURL    = "https://api.twitter.com/oauth/authorize"
	authenticateURL = "https://api.twitter.com/oauth/authenticate"
	tokenURL        = "https://api.twitter.com/oauth/access_token"
	endpointProfile = "https://api.twitter.com/1.1/account/verify_credentials.json"
	tokenCookie     = "oauth-twitter"
)

type handler struct {
	callbackURL  string
	clientID     string
	clientSecret string
}

var (
	clientID     = os.Getenv("TWITTER_CLIENT_ID")
	clientSecret = os.Getenv("TWITTER_CLIENT_SECRET")
	cookieStore  = sessions.NewCookieStore([]byte(os.Getenv("COOKIE_KEYS")))
)

func init() {
	gob.Register(&oauth.RequestToken{})
}

func BeginAuth(w http.ResponseWriter, r *http.Request) {
	consumer := newConsumer()
	requestToken, url, err := consumer.GetRequestTokenAndUrl("http://localhost:8080/auth/twitter/callback")
	if err != nil {
		log.Errorf(r.Context(), "unable to get token from twitter: %v", err)
		http.Error(w, "twitter token error", http.StatusInternalServerError)
		return
	}

	session, err := cookieStore.Get(r, tokenCookie)
	session.Values["token"] = *requestToken
	err = session.Save(r, w)
	if err != nil {
		log.Errorf(r.Context(), "unable to save session: %v", err)
		http.Error(w, "twitter token error", http.StatusInternalServerError)
		return
	}

	log.Logf(r.Context(), "stored token: %v", requestToken)
	http.Redirect(w, r, url, http.StatusTemporaryRedirect)
	return
}

func CallbackHandler(w http.ResponseWriter, r *http.Request) {
	sess, err := cookieStore.Get(r, tokenCookie)
	if err != nil {
		log.Errorf(r.Context(), "unable to get twitter cookie from user session: %v", err)
		http.Error(w, "twitter token error", http.StatusInternalServerError)
		return
	}
	log.Logf(r.Context(), "session: %+v", sess.Values)
	token, tokenOK := sess.Values["token"].(*oauth.RequestToken)
	if !tokenOK {
		log.Errorf(r.Context(), "unable to get token (%s)", token)
		http.Error(w, "token process error", http.StatusInternalServerError)
		return
	}

	values := r.URL.Query()
	verificationCode := values.Get("oauth_verifier")
	tokenKey := values.Get("oauth_token")

	log.Logf(r.Context(), "token: %s, tokenKey: %s", token.Token, tokenKey)

	c := newConsumer()
	accessToken, err := c.AuthorizeToken(token, verificationCode)
	if err != nil {
		log.Errorf(r.Context(), "unable to authorize token: %v", err)
		http.Error(w, "token process error", http.StatusInternalServerError)
		return
	}

	/*client, err := c.MakeHttpClient(accessToken)
	if err != nil {
		log.Errorf(r.Context(), "unable to make client: %v", err)
		http.Error(w, "token process error", http.StatusInternalServerError)
		return
	}
	*/

	response, err := c.Get(
		endpointProfile,
		map[string]string{"include_entities": "false", "skip_status": "true", "include_email": "true"},
		accessToken)
	if err != nil {
		log.Errorf(r.Context(), "profile error: %v", err)
		http.Error(w, "token process error", http.StatusInternalServerError)
		return
	}
	defer response.Body.Close()

	if response.StatusCode != http.StatusOK {
		log.Errorf(r.Context(), "profile error: %v", err)
		http.Error(w, "token process error", http.StatusInternalServerError)
		return
	}
	user, err := userFromReader(response.Body)
	log.Logf(r.Context(), "user: %v", user)
	return
}

func newConsumer() *oauth.Consumer {
	return oauth.NewConsumer(
		clientID,
		clientSecret,
		oauth.ServiceProvider{
			RequestTokenUrl:   requestURL,
			AuthorizeTokenUrl: authorizeURL,
			AccessTokenUrl:    tokenURL,
		})
}

func userFromReader(reader io.Reader) (*types.User, error) {
	u := struct {
		ID       string `json:"id_str"`
		Email    string `json:"email"`
		Name     string `json:"name"`
		Location string `json:"location"`
	}{}

	err := json.NewDecoder(reader).Decode(&u)
	if err != nil {
		return nil, err
	}

	user := &types.User{}
	user.Fullname = u.Name
	user.Email = u.Email
	user.ID = "twitter" + u.ID
	user.Country = u.Location

	return user, err
}
<commit_msg>get user<commit_after>package twitter

import (
	"encoding/gob"
	"encoding/json"
	"io"
	"net/http"
	"os"
	"psychic-rat/log"
	"psychic-rat/types"

	"github.com/gorilla/sessions"
	"github.com/mrjones/oauth"
)

const (
	requestURL      = "https://api.twitter.com/oauth/request_token"
	authorizeURL    = "https://api.twitter.com/oauth/authorize"
	authenticateURL = "https://api.twitter.com/oauth/authenticate"
	tokenURL        = "https://api.twitter.com/oauth/access_token"
	endpointProfile = "https://api.twitter.com/1.1/account/verify_credentials.json"
	tokenCookie     = "oauth-twitter"
)

type handler struct {
	callbackURL  string
	clientID     string
	clientSecret string
}

var (
	clientID     = os.Getenv("TWITTER_CLIENT_ID")
	clientSecret = os.Getenv("TWITTER_CLIENT_SECRET")
	cookieStore  = sessions.NewCookieStore([]byte(os.Getenv("COOKIE_KEYS")))
)

func init() {
	gob.Register(&oauth.RequestToken{})
}

func BeginAuth(w http.ResponseWriter, r *http.Request) {
	consumer := newConsumer()
	requestToken, url, err := consumer.GetRequestTokenAndUrl("http://localhost:8080/auth/twitter/callback")
	if err != nil {
		log.Errorf(r.Context(), "unable to get token from twitter: %v", err)
		http.Error(w, "twitter token error", http.StatusInternalServerError)
		return
	}

	session, err := cookieStore.Get(r, tokenCookie)
	session.Values["token"] = *requestToken
	err = session.Save(r, w)
	if err != nil {
		log.Errorf(r.Context(), "unable to save session: %v", err)
		http.Error(w, "twitter token error", http.StatusInternalServerError)
		return
	}

	log.Logf(r.Context(), "stored token: %v", requestToken)
	http.Redirect(w, r, url, http.StatusTemporaryRedirect)
	return
}

func CallbackHandler(w http.ResponseWriter, r *http.Request) {
	sess, err := cookieStore.Get(r, tokenCookie)
	if err != nil {
		log.Errorf(r.Context(), "unable to get twitter cookie from user session: %v", err)
		http.Error(w, "twitter token error", http.StatusInternalServerError)
		return
	}
	token, tokenOK := sess.Values["token"].(*oauth.RequestToken)
	if !tokenOK {
		log.Errorf(r.Context(), "unable to get token (%s)", token)
		http.Error(w, "token process error", http.StatusInternalServerError)
		return
	}

	values := r.URL.Query()
	verificationCode := values.Get("oauth_verifier")
	//tokenKey := values.Get("oauth_token")

	//log.Logf(r.Context(), "token: %s, tokenKey: %s", token.Token, tokenKey)

	c := newConsumer()
	accessToken, err := c.AuthorizeToken(token, verificationCode)
	if err != nil {
		log.Errorf(r.Context(), "unable to authorize token: %v", err)
		http.Error(w, "token process error", http.StatusInternalServerError)
		return
	}

	/*client, err := c.MakeHttpClient(accessToken)
	if err != nil {
		log.Errorf(r.Context(), "unable to make client: %v", err)
		http.Error(w, "token process error", http.StatusInternalServerError)
		return
	}
	*/

	// todo: Get is deprecated
	response, err := c.Get(
		endpointProfile,
		map[string]string{"include_entities": "false", "skip_status": "true", "include_email": "true"},
		accessToken)
	if err != nil {
		log.Errorf(r.Context(), "profile error: %v", err)
		http.Error(w, "token process error", http.StatusInternalServerError)
		return
	}
	defer response.Body.Close()

	if response.StatusCode != http.StatusOK {
		log.Errorf(r.Context(), "profile error: %v", err)
		http.Error(w, "token process error", http.StatusInternalServerError)
		return
	}
	user, err := userFromReader(response.Body)
	log.Logf(r.Context(), "user: %v", user)
	return
}

func newConsumer() *oauth.Consumer {
	return oauth.NewConsumer(
		clientID,
		clientSecret,
		oauth.ServiceProvider{
			RequestTokenUrl:   requestURL,
			AuthorizeTokenUrl: authorizeURL,
			AccessTokenUrl:    tokenURL,
		})
}

func userFromReader(reader io.Reader) (*types.User, error) {
	u := struct {
		ID       string `json:"id_str"`
		Email    string `json:"email"`
		Name     string `json:"name"`
		Location string `json:"location"`
	}{}

	err := json.NewDecoder(reader).Decode(&u)
	if err != nil {
		return nil, err
	}

	user := &types.User{}
	user.Fullname = u.Name
	user.Email = u.Email
	user.ID = "twitter" + u.ID
	user.Country = u.Location

	return user, err
}
<|endoftext|>


<commit_before>package autopilot

import (
	prand "math/rand"
	"net"
	"time"

	"github.com/btcsuite/btcd/btcec"
	"github.com/btcsuite/btcutil"
)

// ConstrainedPrefAttachment is an implementation of the AttachmentHeuristic
// interface that implement a constrained non-linear preferential attachment
// heuristic. This means that given a threshold to allocate to automatic
// channel establishment, the heuristic will attempt to favor connecting to
// nodes which already have a set amount of links, selected by sampling from a
// power law distribution. The attachment is non-linear in that it favors
// nodes with a higher in-degree but less so that regular linear preferential
// attachment. As a result, this creates smaller and less clusters than regular
// linear preferential attachment.
//
// TODO(roasbeef): BA, with k=-3
type ConstrainedPrefAttachment struct {
	constraints *HeuristicConstraints
}

// NewConstrainedPrefAttachment creates a new instance of a
// ConstrainedPrefAttachment heuristics given bounds on allowed channel sizes,
// and an allocation amount which is interpreted as a percentage of funds that
// is to be committed to channels at all times.
func NewConstrainedPrefAttachment(
	cfg *HeuristicConstraints) *ConstrainedPrefAttachment {

	prand.Seed(time.Now().Unix())

	return &ConstrainedPrefAttachment{
		constraints: cfg,
	}
}

// A compile time assertion to ensure ConstrainedPrefAttachment meets the
// AttachmentHeuristic interface.
var _ AttachmentHeuristic = (*ConstrainedPrefAttachment)(nil)

// NeedMoreChans is a predicate that should return true if, given the passed
// parameters, and its internal state, more channels should be opened within
// the channel graph. If the heuristic decides that we do indeed need more
// channels, then the second argument returned will represent the amount of
// additional funds to be used towards creating channels.
//
// NOTE: This is a part of the AttachmentHeuristic interface.
func (p *ConstrainedPrefAttachment) NeedMoreChans(channels []Channel,
	funds btcutil.Amount) (btcutil.Amount, uint32, bool) {

	// We'll try to open more channels as long as the constraints allow it.
	availableFunds, availableChans := p.constraints.availableChans(
		channels, funds,
	)
	return availableFunds, availableChans, availableChans > 0
}

// NodeID is a simple type that holds an EC public key serialized in compressed
// format.
type NodeID [33]byte

// NewNodeID creates a new nodeID from a passed public key.
func NewNodeID(pub *btcec.PublicKey) NodeID {
	var n NodeID
	copy(n[:], pub.SerializeCompressed())
	return n
}

// NodeScores is a method that given the current channel graph, current set of
// local channels and funds available, scores the given nodes according the the
// preference of opening a channel with them.
//
// The heuristic employed by this method is one that attempts to promote a
// scale-free network globally, via local attachment preferences for new nodes
// joining the network with an amount of available funds to be allocated to
// channels. Specifically, we consider the degree of each node (and the flow
// in/out of the node available via its open channels) and utilize the
// Barabási–Albert model to drive our recommended attachment heuristics. If
// implemented globally for each new participant, this results in a channel
// graph that is scale-free and follows a power law distribution with k=-3.
//
// The returned scores will be in the range [0.0, 1.0], where higher scores are
// given to nodes already having high connectivity in the graph.
//
// NOTE: This is a part of the AttachmentHeuristic interface.
func (p *ConstrainedPrefAttachment) NodeScores(g ChannelGraph, chans []Channel,
	fundsAvailable btcutil.Amount, nodes map[NodeID]struct{}) (
	map[NodeID]*AttachmentDirective, error) {

	// Count the number of channels in the graph. We'll also count the
	// number of channels as we go for the nodes we are interested in, and
	// record their addresses found in the db.
	var graphChans int
	nodeChanNum := make(map[NodeID]int)
	addresses := make(map[NodeID][]net.Addr)
	if err := g.ForEachNode(func(n Node) error {
		var nodeChans int
		err := n.ForEachChannel(func(_ ChannelEdge) error {
			nodeChans++
			graphChans++
			return nil
		})
		if err != nil {
			return err
		}

		// If this node is not among our nodes to score, we can return
		// early.
		nID := NodeID(n.PubKey())
		if _, ok := nodes[nID]; !ok {
			return nil
		}

		// Otherwise we'll record the number of channels, and also
		// populate the address in our channel candidates map.
		nodeChanNum[nID] = nodeChans
		addresses[nID] = n.Addrs()

		return nil
	}); err != nil {
		return nil, err
	}

	// If there are no channels in the graph we cannot determine any
	// preferences, so we return, indicating all candidates get a score of
	// zero.
	if graphChans == 0 {
		return nil, nil
	}

	existingPeers := make(map[NodeID]struct{})
	for _, c := range chans {
		existingPeers[c.Node] = struct{}{}
	}

	// For each node in the set of nodes, count their fraction of channels
	// in the graph, and use that as the score.
	candidates := make(map[NodeID]*AttachmentDirective)
	for nID, nodeChans := range nodeChanNum {
		// As channel size we'll use the maximum channel size available.
		chanSize := p.constraints.MaxChanSize
		if fundsAvailable-chanSize < 0 {
			chanSize = fundsAvailable
		}

		_, ok := existingPeers[nID]

		switch {

		// If the node is among or existing channel peers, we don't
		// need another channel.
		case ok:
			continue

		// If the amount is too small, we don't want to attempt opening
		// another channel.
		case chanSize == 0 || chanSize < p.constraints.MinChanSize:
			continue
		}

		// Otherwise we score the node according to its fraction of
		// channels in the graph.
		score := float64(nodeChans) / float64(graphChans)
		candidates[nID] = &AttachmentDirective{
			NodeID:  nID,
			ChanAmt: chanSize,
			Score:   score,
		}
	}

	return candidates, nil
}
<commit_msg>autopilot/prefattach: populate Addrs field<commit_after>package autopilot

import (
	prand "math/rand"
	"net"
	"time"

	"github.com/btcsuite/btcd/btcec"
	"github.com/btcsuite/btcutil"
)

// ConstrainedPrefAttachment is an implementation of the AttachmentHeuristic
// interface that implement a constrained non-linear preferential attachment
// heuristic. This means that given a threshold to allocate to automatic
// channel establishment, the heuristic will attempt to favor connecting to
// nodes which already have a set amount of links, selected by sampling from a
// power law distribution. The attachment is non-linear in that it favors
// nodes with a higher in-degree but less so that regular linear preferential
// attachment. As a result, this creates smaller and less clusters than regular
// linear preferential attachment.
//
// TODO(roasbeef): BA, with k=-3
type ConstrainedPrefAttachment struct {
	constraints *HeuristicConstraints
}

// NewConstrainedPrefAttachment creates a new instance of a
// ConstrainedPrefAttachment heuristics given bounds on allowed channel sizes,
// and an allocation amount which is interpreted as a percentage of funds that
// is to be committed to channels at all times.
func NewConstrainedPrefAttachment(
	cfg *HeuristicConstraints) *ConstrainedPrefAttachment {

	prand.Seed(time.Now().Unix())

	return &ConstrainedPrefAttachment{
		constraints: cfg,
	}
}

// A compile time assertion to ensure ConstrainedPrefAttachment meets the
// AttachmentHeuristic interface.
var _ AttachmentHeuristic = (*ConstrainedPrefAttachment)(nil)

// NeedMoreChans is a predicate that should return true if, given the passed
// parameters, and its internal state, more channels should be opened within
// the channel graph. If the heuristic decides that we do indeed need more
// channels, then the second argument returned will represent the amount of
// additional funds to be used towards creating channels.
//
// NOTE: This is a part of the AttachmentHeuristic interface.
func (p *ConstrainedPrefAttachment) NeedMoreChans(channels []Channel,
	funds btcutil.Amount) (btcutil.Amount, uint32, bool) {

	// We'll try to open more channels as long as the constraints allow it.
	availableFunds, availableChans := p.constraints.availableChans(
		channels, funds,
	)
	return availableFunds, availableChans, availableChans > 0
}

// NodeID is a simple type that holds an EC public key serialized in compressed
// format.
type NodeID [33]byte

// NewNodeID creates a new nodeID from a passed public key.
func NewNodeID(pub *btcec.PublicKey) NodeID {
	var n NodeID
	copy(n[:], pub.SerializeCompressed())
	return n
}

// NodeScores is a method that given the current channel graph, current set of
// local channels and funds available, scores the given nodes according the the
// preference of opening a channel with them.
//
// The heuristic employed by this method is one that attempts to promote a
// scale-free network globally, via local attachment preferences for new nodes
// joining the network with an amount of available funds to be allocated to
// channels. Specifically, we consider the degree of each node (and the flow
// in/out of the node available via its open channels) and utilize the
// Barabási–Albert model to drive our recommended attachment heuristics. If
// implemented globally for each new participant, this results in a channel
// graph that is scale-free and follows a power law distribution with k=-3.
//
// The returned scores will be in the range [0.0, 1.0], where higher scores are
// given to nodes already having high connectivity in the graph.
//
// NOTE: This is a part of the AttachmentHeuristic interface.
func (p *ConstrainedPrefAttachment) NodeScores(g ChannelGraph, chans []Channel,
	fundsAvailable btcutil.Amount, nodes map[NodeID]struct{}) (
	map[NodeID]*AttachmentDirective, error) {

	// Count the number of channels in the graph. We'll also count the
	// number of channels as we go for the nodes we are interested in, and
	// record their addresses found in the db.
	var graphChans int
	nodeChanNum := make(map[NodeID]int)
	addresses := make(map[NodeID][]net.Addr)
	if err := g.ForEachNode(func(n Node) error {
		var nodeChans int
		err := n.ForEachChannel(func(_ ChannelEdge) error {
			nodeChans++
			graphChans++
			return nil
		})
		if err != nil {
			return err
		}

		// If this node is not among our nodes to score, we can return
		// early.
		nID := NodeID(n.PubKey())
		if _, ok := nodes[nID]; !ok {
			return nil
		}

		// Otherwise we'll record the number of channels, and also
		// populate the address in our channel candidates map.
		nodeChanNum[nID] = nodeChans
		addresses[nID] = n.Addrs()

		return nil
	}); err != nil {
		return nil, err
	}

	// If there are no channels in the graph we cannot determine any
	// preferences, so we return, indicating all candidates get a score of
	// zero.
	if graphChans == 0 {
		return nil, nil
	}

	existingPeers := make(map[NodeID]struct{})
	for _, c := range chans {
		existingPeers[c.Node] = struct{}{}
	}

	// For each node in the set of nodes, count their fraction of channels
	// in the graph, and use that as the score.
	candidates := make(map[NodeID]*AttachmentDirective)
	for nID, nodeChans := range nodeChanNum {
		// As channel size we'll use the maximum channel size available.
		chanSize := p.constraints.MaxChanSize
		if fundsAvailable-chanSize < 0 {
			chanSize = fundsAvailable
		}

		_, ok := existingPeers[nID]
		addrs := addresses[nID]

		switch {

		// If the node is among or existing channel peers, we don't
		// need another channel.
		case ok:
			continue

		// If the amount is too small, we don't want to attempt opening
		// another channel.
		case chanSize == 0 || chanSize < p.constraints.MinChanSize:
			continue

		// If the node has no addresses, we cannot connect to it, so we
		// skip it for now, which implicitly gives it a score of 0.
		case len(addrs) == 0:
			continue
		}

		// Otherwise we score the node according to its fraction of
		// channels in the graph.
		score := float64(nodeChans) / float64(graphChans)
		candidates[nID] = &AttachmentDirective{
			NodeID:  nID,
			ChanAmt: chanSize,
			Addrs:   addrs,
			Score:   score,
		}
	}

	return candidates, nil
}
<|endoftext|>


<commit_before>package typed

import (
	"github.com/karlseguin/gspec"
	"testing"
)

func Test_Json(t *testing.T) {
	spec := gspec.New(t)
	typed, err := Json([]byte(`{"power": 9002}`))
	spec.Expect(typed.Int("power")).ToEqual(9002)
	spec.Expect(err).ToBeNil()
}

func Test_JsonFile(t *testing.T) {
	spec := gspec.New(t)
	typed, err := JsonFile("test.json")
	spec.Expect(typed.String("name")).ToEqual("leto")
	spec.Expect(err).ToBeNil()
}

func Test_Bool(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("log", true))
	spec.Expect(typed.Bool("log")).ToEqual(true)
	spec.Expect(typed.BoolOr("log", false)).ToEqual(true)
	spec.Expect(typed.Bool("other")).ToEqual(false)
	spec.Expect(typed.BoolOr("other", true)).ToEqual(true)
}

func Test_Int(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("port", 84))
	spec.Expect(typed.Int("port")).ToEqual(84)
	spec.Expect(typed.IntOr("port", 11)).ToEqual(84)
	spec.Expect(typed.Int("other")).ToEqual(0)
	spec.Expect(typed.IntOr("other", 33)).ToEqual(33)
}

func Test_Float(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("pi", 3.14))
	spec.Expect(typed.Float("pi")).ToEqual(3.14)
	spec.Expect(typed.FloatOr("pi", 11.3)).ToEqual(3.14)
	spec.Expect(typed.Float("other")).ToEqual(0.0)
	spec.Expect(typed.FloatOr("other", 11.3)).ToEqual(11.3)
}

func Test_String(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("host", "localhost"))
	spec.Expect(typed.String("host")).ToEqual("localhost")
	spec.Expect(typed.StringOr("host", "openmymind.net")).ToEqual("localhost")
	spec.Expect(typed.String("other")).ToEqual("")
	spec.Expect(typed.StringOr("other", "openmymind.net")).ToEqual("openmymind.net")

}

func Test_Object(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("server", build("port", 32)))
	spec.Expect(typed.Object("server").Int("port")).ToEqual(32)
	spec.Expect(typed.ObjectOr("server", build("a", "b")).Int("port")).ToEqual(32)
	spec.Expect(len(typed.Object("other"))).ToEqual(0)
	spec.Expect(typed.ObjectOr("other", build("x", "y")).String("x")).ToEqual("y")
}

func Test_Bools(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("boring", []interface{}{true, false}))
	spec.Expect(typed.Bools("boring")).ToEqual([]bool{true, false})
	spec.Expect(typed.Bools("other")).ToEqual([]bool{})
	spec.Expect(typed.BoolsOr("boring", []bool{false, true})).ToEqual([]bool{true, false})
	spec.Expect(typed.BoolsOr("other", []bool{false, true})).ToEqual([]bool{false, true})
}

func Test_Ints(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("scores", []interface{}{2, 1}))
	spec.Expect(typed.Ints("scores")).ToEqual([]int{2, 1})
	spec.Expect(typed.Ints("other")).ToEqual([]int{})
}

func Test_Ints_WithFloats(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("scores", []interface{}{2.1, 7.39}))
	spec.Expect(typed.Ints("scores")).ToEqual([]int{2, 7})
}

func Test_Floats(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("ranks", []interface{}{2.1, 1.2}))
	spec.Expect(typed.Floats("ranks")).ToEqual([]float64{2.1, 1.2})
	spec.Expect(typed.Floats("other")).ToEqual([]float64{})
}

func Test_Strings(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("names", []interface{}{"a", "b"}))
	spec.Expect(typed.Strings("names")).ToEqual([]string{"a", "b"})
	spec.Expect(typed.Strings("other")).ToEqual([]string{})
	spec.Expect(typed.StringsOr("names", []string{"c", "d"})).ToEqual([]string{"a", "b"})
	spec.Expect(typed.StringsOr("other", []string{"c", "d"})).ToEqual([]string{"c", "d"})
}

func Test_Objects(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("names", []interface{}{build("first", 1), build("second", 2)}))
	spec.Expect(typed.Objects("names")[0].Int("first")).ToEqual(1)
}

func Test_Maps(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("names", []interface{}{build("first", 1), build("second", 2)}))
	spec.Expect(typed.Maps("names")[1]["second"]).ToEqual(2)
}

func Test_StringBool(t *testing.T) {
	spec := gspec.New(t)
	typed, _ := JsonString(`{"blocked":{"a":true,"b":false}}`)
	m := typed.StringBool("blocked")
	spec.Expect(m["a"]).ToEqual(true)
	spec.Expect(m["b"]).ToEqual(false)
}

func Test_StringInt(t *testing.T) {
	spec := gspec.New(t)
	typed, _ := JsonString(`{"count":{"a":123,"b":43}}`)
	m := typed.StringInt("count")
	spec.Expect(m["a"]).ToEqual(123)
	spec.Expect(m["b"]).ToEqual(43)
	spec.Expect(m["xxz"]).ToEqual(0)
}

func Test_StringFloat(t *testing.T) {
	spec := gspec.New(t)
	typed, _ := JsonString(`{"rank":{"aa":3.4,"bz":4.2}}`)
	m := typed.StringFloat("rank")
	spec.Expect(m["aa"]).ToEqual(3.4)
	spec.Expect(m["bz"]).ToEqual(4.2)
	spec.Expect(m["xx"]).ToEqual(0.0)
}

func Test_StringString(t *testing.T) {
	spec := gspec.New(t)
	typed, _ := JsonString(`{"atreides":{"leto":"ghanima","paul":"alia"}}`)
	m := typed.StringString("atreides")
	spec.Expect(m["leto"]).ToEqual("ghanima")
	spec.Expect(m["paul"]).ToEqual("alia")
	spec.Expect(m["vladimir"]).ToEqual("")
}

func Test_StringObject(t *testing.T) {
	spec := gspec.New(t)
	typed, _ := JsonString(`{"atreides":{"leto":{"sister": "ghanima"}, "goku": {"power": 9001}}}`)
	m := typed.StringObject("atreides")
	spec.Expect(m["leto"].String("sister")).ToEqual("ghanima")
	spec.Expect(m["goku"].Int("power")).ToEqual(9001)
}

func build(values ...interface{}) map[string]interface{} {
	m := make(map[string]interface{}, len(values))
	for i := 0; i < len(values); i += 2 {
		m[values[i].(string)] = values[i+1]
	}
	return m
}
<commit_msg>Written tests for IntsOr<commit_after>package typed

import (
	"github.com/karlseguin/gspec"
	"testing"
)

func Test_Json(t *testing.T) {
	spec := gspec.New(t)
	typed, err := Json([]byte(`{"power": 9002}`))
	spec.Expect(typed.Int("power")).ToEqual(9002)
	spec.Expect(err).ToBeNil()
}

func Test_JsonFile(t *testing.T) {
	spec := gspec.New(t)
	typed, err := JsonFile("test.json")
	spec.Expect(typed.String("name")).ToEqual("leto")
	spec.Expect(err).ToBeNil()
}

func Test_Bool(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("log", true))
	spec.Expect(typed.Bool("log")).ToEqual(true)
	spec.Expect(typed.BoolOr("log", false)).ToEqual(true)
	spec.Expect(typed.Bool("other")).ToEqual(false)
	spec.Expect(typed.BoolOr("other", true)).ToEqual(true)
}

func Test_Int(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("port", 84))
	spec.Expect(typed.Int("port")).ToEqual(84)
	spec.Expect(typed.IntOr("port", 11)).ToEqual(84)
	spec.Expect(typed.Int("other")).ToEqual(0)
	spec.Expect(typed.IntOr("other", 33)).ToEqual(33)
}

func Test_Float(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("pi", 3.14))
	spec.Expect(typed.Float("pi")).ToEqual(3.14)
	spec.Expect(typed.FloatOr("pi", 11.3)).ToEqual(3.14)
	spec.Expect(typed.Float("other")).ToEqual(0.0)
	spec.Expect(typed.FloatOr("other", 11.3)).ToEqual(11.3)
}

func Test_String(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("host", "localhost"))
	spec.Expect(typed.String("host")).ToEqual("localhost")
	spec.Expect(typed.StringOr("host", "openmymind.net")).ToEqual("localhost")
	spec.Expect(typed.String("other")).ToEqual("")
	spec.Expect(typed.StringOr("other", "openmymind.net")).ToEqual("openmymind.net")

}

func Test_Object(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("server", build("port", 32)))
	spec.Expect(typed.Object("server").Int("port")).ToEqual(32)
	spec.Expect(typed.ObjectOr("server", build("a", "b")).Int("port")).ToEqual(32)
	spec.Expect(len(typed.Object("other"))).ToEqual(0)
	spec.Expect(typed.ObjectOr("other", build("x", "y")).String("x")).ToEqual("y")
}

func Test_Bools(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("boring", []interface{}{true, false}))
	spec.Expect(typed.Bools("boring")).ToEqual([]bool{true, false})
	spec.Expect(typed.Bools("other")).ToEqual([]bool{})
	spec.Expect(typed.BoolsOr("boring", []bool{false, true})).ToEqual([]bool{true, false})
	spec.Expect(typed.BoolsOr("other", []bool{false, true})).ToEqual([]bool{false, true})
}

func Test_Ints(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("scores", []interface{}{2, 1}))
	spec.Expect(typed.Ints("scores")).ToEqual([]int{2, 1})
	spec.Expect(typed.Ints("other")).ToEqual([]int{})
	spec.Expect(typed.IntsOr("scores", []int{3, 4})).ToEqual([]int{2, 1})
	spec.Expect(typed.IntsOr("other", []int{3, 4})).ToEqual([]int{3, 4})
}

func Test_Ints_WithFloats(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("scores", []interface{}{2.1, 7.39}))
	spec.Expect(typed.Ints("scores")).ToEqual([]int{2, 7})
}

func Test_Floats(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("ranks", []interface{}{2.1, 1.2}))
	spec.Expect(typed.Floats("ranks")).ToEqual([]float64{2.1, 1.2})
	spec.Expect(typed.Floats("other")).ToEqual([]float64{})
}

func Test_Strings(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("names", []interface{}{"a", "b"}))
	spec.Expect(typed.Strings("names")).ToEqual([]string{"a", "b"})
	spec.Expect(typed.Strings("other")).ToEqual([]string{})
	spec.Expect(typed.StringsOr("names", []string{"c", "d"})).ToEqual([]string{"a", "b"})
	spec.Expect(typed.StringsOr("other", []string{"c", "d"})).ToEqual([]string{"c", "d"})
}

func Test_Objects(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("names", []interface{}{build("first", 1), build("second", 2)}))
	spec.Expect(typed.Objects("names")[0].Int("first")).ToEqual(1)
}

func Test_Maps(t *testing.T) {
	spec := gspec.New(t)
	typed := New(build("names", []interface{}{build("first", 1), build("second", 2)}))
	spec.Expect(typed.Maps("names")[1]["second"]).ToEqual(2)
}

func Test_StringBool(t *testing.T) {
	spec := gspec.New(t)
	typed, _ := JsonString(`{"blocked":{"a":true,"b":false}}`)
	m := typed.StringBool("blocked")
	spec.Expect(m["a"]).ToEqual(true)
	spec.Expect(m["b"]).ToEqual(false)
}

func Test_StringInt(t *testing.T) {
	spec := gspec.New(t)
	typed, _ := JsonString(`{"count":{"a":123,"b":43}}`)
	m := typed.StringInt("count")
	spec.Expect(m["a"]).ToEqual(123)
	spec.Expect(m["b"]).ToEqual(43)
	spec.Expect(m["xxz"]).ToEqual(0)
}

func Test_StringFloat(t *testing.T) {
	spec := gspec.New(t)
	typed, _ := JsonString(`{"rank":{"aa":3.4,"bz":4.2}}`)
	m := typed.StringFloat("rank")
	spec.Expect(m["aa"]).ToEqual(3.4)
	spec.Expect(m["bz"]).ToEqual(4.2)
	spec.Expect(m["xx"]).ToEqual(0.0)
}

func Test_StringString(t *testing.T) {
	spec := gspec.New(t)
	typed, _ := JsonString(`{"atreides":{"leto":"ghanima","paul":"alia"}}`)
	m := typed.StringString("atreides")
	spec.Expect(m["leto"]).ToEqual("ghanima")
	spec.Expect(m["paul"]).ToEqual("alia")
	spec.Expect(m["vladimir"]).ToEqual("")
}

func Test_StringObject(t *testing.T) {
	spec := gspec.New(t)
	typed, _ := JsonString(`{"atreides":{"leto":{"sister": "ghanima"}, "goku": {"power": 9001}}}`)
	m := typed.StringObject("atreides")
	spec.Expect(m["leto"].String("sister")).ToEqual("ghanima")
	spec.Expect(m["goku"].Int("power")).ToEqual(9001)
}

func build(values ...interface{}) map[string]interface{} {
	m := make(map[string]interface{}, len(values))
	for i := 0; i < len(values); i += 2 {
		m[values[i].(string)] = values[i+1]
	}
	return m
}
<|endoftext|>


<commit_before>package struc

import (
	"bytes"
	"testing"
)

func TestBadType(t *testing.T) {
	defer func() { recover() }()
	Type(-1).Size()
	t.Fatal("failed to panic for invalid Type.Size()")
}

func TestTypeString(t *testing.T) {
	if Pad.String() != "pad" {
		t.Fatal("type string representation failed")
	}
}

type sizeOffTest struct {
	Size Size_t
	Off  Off_t
}

func TestSizeOffTypes(t *testing.T) {
	bits := []int{8, 16, 32, 64}
	var buf bytes.Buffer
	test := &sizeOffTest{1, 2}
	for _, b := range bits {
		if err := PackWithOptions(&buf, test, &Options{PtrSize: b}); err != nil {
			t.Fatal(err)
		}
	}
	reference := []byte{
		1, 2,
		0, 1, 0, 2,
		0, 0, 0, 1, 0, 0, 0, 2,
		0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2,
	}
	if !bytes.Equal(reference, buf.Bytes()) {
		t.Errorf("reference != bytes: %v", reference, buf.Bytes())
	}
	reader := bytes.NewReader(buf.Bytes())
	for _, b := range bits {
		out := &sizeOffTest{}
		if err := UnpackWithOptions(reader, out, &Options{PtrSize: b}); err != nil {
			t.Fatal(err)
		}
		if out.Size != 1 || out.Off != 2 {
			t.Errorf("Size_t/Off_t mismatch: {%d, %d}\n%v", out.Size, out.Off, buf.Bytes())
		}
	}
}
<commit_msg>fix go vet issue<commit_after>package struc

import (
	"bytes"
	"testing"
)

func TestBadType(t *testing.T) {
	defer func() { recover() }()
	Type(-1).Size()
	t.Fatal("failed to panic for invalid Type.Size()")
}

func TestTypeString(t *testing.T) {
	if Pad.String() != "pad" {
		t.Fatal("type string representation failed")
	}
}

type sizeOffTest struct {
	Size Size_t
	Off  Off_t
}

func TestSizeOffTypes(t *testing.T) {
	bits := []int{8, 16, 32, 64}
	var buf bytes.Buffer
	test := &sizeOffTest{1, 2}
	for _, b := range bits {
		if err := PackWithOptions(&buf, test, &Options{PtrSize: b}); err != nil {
			t.Fatal(err)
		}
	}
	reference := []byte{
		1, 2,
		0, 1, 0, 2,
		0, 0, 0, 1, 0, 0, 0, 2,
		0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2,
	}
	if !bytes.Equal(reference, buf.Bytes()) {
		t.Errorf("reference: %v != bytes: %v", reference, buf.Bytes())
	}
	reader := bytes.NewReader(buf.Bytes())
	for _, b := range bits {
		out := &sizeOffTest{}
		if err := UnpackWithOptions(reader, out, &Options{PtrSize: b}); err != nil {
			t.Fatal(err)
		}
		if out.Size != 1 || out.Off != 2 {
			t.Errorf("Size_t/Off_t mismatch: {%d, %d}\n%v", out.Size, out.Off, buf.Bytes())
		}
	}
}
<|endoftext|>


<commit_before>package pgsql

import (
	"fmt"
	"github.com/metakeule/typeconverter"
	"testing"
	"time"
)

func err(t *testing.T, msg string, is interface{}, shouldbe interface{}) {
	t.Errorf(msg+": is %#v, should be %#v\n", is, shouldbe)
}

var _ = fmt.Errorf
var ti, _ = time.Parse(time.RFC3339, "2011-01-26T18:53:18+01:00")
var timeString = ti.Format(time.RFC3339)
var timeUnix = ti.Unix()
var timeFloat = float64(1010000000)
var tiFloat = time.Unix(1010000000, 0)
var tiFloatString = tiFloat.Format(time.RFC3339)

var toTypedValueTests = map[interface{}]Type{
	1:            IntType,
	int32(2):     IntType,
	int64(2):     IntType,
	float64(3.0): FloatType,
	float32(3.0): FloatType,
	`3.0`:        TextType,
	true:         BoolType,
	ti:           TimeStampTZType,
	typeconverter.Json(`{"a": 4}`): TextType,
}

func TestToTypedValue(t *testing.T) {
	for in, out := range toTypedValueTests {
		r := TypedValue{}
		Convert(in, &r)
		if r.Type() != out {
			err(t, "Convert to typed value, wrong type", r.Type().String(), out.String())
		}

		inStr := ""
		typeconverter.Convert(in, &inStr)

		if r.Value.String() != inStr {
			err(t, "Convert to typed value changed input", r.Value.String(), inStr)
		}
	}
}

func TestToInt(t *testing.T) {
	var r int

	out := int(1)

	if Convert(out, &r); r != out {
		err(t, "Convert int", r, out)
	}

	if Convert(int32(1), &r); r != out {
		err(t, "Convert int", r, out)
	}

	if Convert(int64(1), &r); r != out {
		err(t, "Convert int", r, out)
	}

	if Convert(float64(1.0), &r); r != out {
		err(t, "Convert int", r, out)
	}

	if Convert(float32(1.0), &r); r != out {
		err(t, "Convert int", r, out)
	}

	if Convert("1", &r); r != out {
		err(t, "Convert int", r, out)
	}

	var tv TypedValue
	Convert(1, &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert int", r, out)
	}

	Convert(1.0, &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert int", r, out)
	}

	Convert("1", &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert int", r, out)
	}

	var i64 int64
	if Convert(int64(1), &i64); i64 != int64(1) {
		err(t, "Convert int", i64, int64(1))
	}

}

func TestToFloat(t *testing.T) {
	var r float64

	out := float64(1.0)

	if Convert(out, &r); r != out {
		err(t, "Convert Float", r, out)
	}

	if Convert(int32(1), &r); r != out {
		err(t, "Convert Float", r, out)
	}

	if Convert(int64(1), &r); r != out {
		err(t, "Convert Float", r, out)
	}

	if Convert(float64(1.0), &r); r != out {
		err(t, "Convert Float", r, out)
	}

	if Convert(float32(1.0), &r); r != out {
		err(t, "Convert Float", r, out)
	}

	if Convert("1", &r); r != out {
		err(t, "Convert Float", r, out)
	}

	var tv TypedValue
	Convert(1, &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert Float", r, out)
	}

	Convert(1.0, &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert Float", r, out)
	}

	Convert("1.0", &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert Float", r, out)
	}

	var f32 float32
	if Convert(float32(1), &f32); f32 != float32(1) {
		err(t, "Convert Float", f32, float32(1))
	}
}

func TestToBool(t *testing.T) {
	var r bool

	out := true

	if Convert(out, &r); r != out {
		err(t, "Convert Bool", r, out)
	}

	if Convert("true", &r); r != out {
		err(t, "Convert Bool", r, out)
	}

	if Convert(typeconverter.Json("true"), &r); r != out {
		err(t, "Convert Bool", r, out)
	}

	var tv TypedValue
	Convert(true, &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert Bool", r, out)
	}

	Convert("true", &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert Bool", r, out)
	}

	Convert(typeconverter.Json("true"), &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert Bool", r, out)
	}
}

func TestToString(t *testing.T) {
	var r string

	out := "1"

	if Convert(out, &r); r != out {
		err(t, "Convert String", r, out)
	}

	if Convert(int32(1), &r); r != out {
		err(t, "Convert String", r, out)
	}

	if Convert(int64(1), &r); r != out {
		err(t, "Convert String", r, out)
	}

	if Convert(float64(1.0), &r); r != out {
		err(t, "Convert String", r, out)
	}

	if Convert(float32(1.0), &r); r != out {
		err(t, "Convert String", r, out)
	}

	if Convert("1", &r); r != out {
		err(t, "Convert String", r, out)
	}

	if Convert(typeconverter.Json(`1`), &r); r != out {
		err(t, "Convert String", r, out)
	}

	sql := Sql("Select 1")

	if Convert(sql, &r); r != sql.Sql().String() {
		err(t, "Convert String", r, sql.Sql())
	}

	var tv TypedValue
	Convert(1, &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert String", r, out)
	}

	Convert(1.0, &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert String", r, out)
	}

	Convert("1", &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert String", r, out)
	}

	Convert(typeconverter.Json(`1`), &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert String", r, out)
	}

	tv = TypedValue{}

	Convert(sql, &tv)

	if Convert(&tv, &r); r != sql.Sql().String() {
		err(t, "Convert String", r, sql.Sql())
	}
}

func TestToTime(t *testing.T) {
	var r time.Time

	out := ti

	if Convert(out, &r); r != out {
		err(t, "Convert time", r, out)
	}

	if Convert(int32(timeUnix), &r); r != out {
		err(t, "Convert time", r, out)
	}
	if Convert(int64(timeUnix), &r); r != out {
		err(t, "Convert time", r, out)
	}

	/*
		Does not work: check!
		if Convert(timeFloat, &r); r.Format(time.RFC3339) != tiFloatString {
			err(t, "Convert time", r.Format(time.RFC3339), tiFloatString)
		}
	*/

	if Convert(timeString, &r); r != out {
		err(t, "Convert time", r, out)
	}

	if Convert(typeconverter.Json(timeString), &r); r != out {
		err(t, "Convert time", r, out)
	}

	var tv TypedValue
	Convert(timeUnix, &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert time", r, out)
	}

	Convert(int32(timeUnix), &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert time", r, out)
	}

	Convert(timeString, &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert time", r, out)
	}

	Convert(typeconverter.Json(timeString), &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert time", r, out)
	}
}

func TestToType(t *testing.T) {
	for in, out := range toTypedValueTests {
		r := Type(0)
		Convert(in, &r)
		if r.String() != out.String() {
			err(t, "Convert to type wrong type", r.String(), out.String())

		}
	}
}

type MyInt int

func (ø MyInt) Sql() SqlType { return Sql(fmt.Sprintf("select %v", ø)) }

var toSqlTests = map[interface{}]string{
	1:            `'1'::int`,
	int32(2):     `'2'::int`,
	int64(2):     `'2'::int`,
	float64(3.5): `'3.5'::float`,
	float32(3.5): `'3.5'::float`,
	`3.0`:        `'3.0'::text`,
	true:         `'true'::bool`,
	ti:           `'` + timeString + `'::timestamptz`,
	typeconverter.Json(`{"a":4}`): `'{"a":4}'::text`,
	Sql("select * from person"):   `select * from person`,
	MyInt(4):                      `select 4`,
}

func TestToSql(t *testing.T) {
	for in, out := range toSqlTests {
		r := Sql("")
		Convert(in, &r)
		if r.Sql().String() != out {
			err(t, "Convert to Sql", r, out)
		}
	}
}
<commit_msg>try to fix time tests on travis<commit_after>package pgsql

import (
	"fmt"
	"github.com/metakeule/typeconverter"
	"testing"
	"time"
)

func err(t *testing.T, msg string, is interface{}, shouldbe interface{}) {
	t.Errorf(msg+": is %#v, should be %#v\n", is, shouldbe)
}

var _ = fmt.Errorf
var ti, _ = time.Parse(time.RFC3339, "2011-01-26T18:53:18+01:00")
var timeString = ti.Format(time.RFC3339)
var timeUnix = ti.Unix()
var timeFloat = float64(1010000000)
var tiFloat = time.Unix(1010000000, 0)
var tiFloatString = tiFloat.Format(time.RFC3339)

var toTypedValueTests = map[interface{}]Type{
	1:            IntType,
	int32(2):     IntType,
	int64(2):     IntType,
	float64(3.0): FloatType,
	float32(3.0): FloatType,
	`3.0`:        TextType,
	true:         BoolType,
	ti:           TimeStampTZType,
	typeconverter.Json(`{"a": 4}`): TextType,
}

func TestToTypedValue(t *testing.T) {
	for in, out := range toTypedValueTests {
		r := TypedValue{}
		Convert(in, &r)
		if r.Type() != out {
			err(t, "Convert to typed value, wrong type", r.Type().String(), out.String())
		}

		inStr := ""
		typeconverter.Convert(in, &inStr)

		if r.Value.String() != inStr {
			err(t, "Convert to typed value changed input", r.Value.String(), inStr)
		}
	}
}

func TestToInt(t *testing.T) {
	var r int

	out := int(1)

	if Convert(out, &r); r != out {
		err(t, "Convert int", r, out)
	}

	if Convert(int32(1), &r); r != out {
		err(t, "Convert int", r, out)
	}

	if Convert(int64(1), &r); r != out {
		err(t, "Convert int", r, out)
	}

	if Convert(float64(1.0), &r); r != out {
		err(t, "Convert int", r, out)
	}

	if Convert(float32(1.0), &r); r != out {
		err(t, "Convert int", r, out)
	}

	if Convert("1", &r); r != out {
		err(t, "Convert int", r, out)
	}

	var tv TypedValue
	Convert(1, &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert int", r, out)
	}

	Convert(1.0, &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert int", r, out)
	}

	Convert("1", &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert int", r, out)
	}

	var i64 int64
	if Convert(int64(1), &i64); i64 != int64(1) {
		err(t, "Convert int", i64, int64(1))
	}

}

func TestToFloat(t *testing.T) {
	var r float64

	out := float64(1.0)

	if Convert(out, &r); r != out {
		err(t, "Convert Float", r, out)
	}

	if Convert(int32(1), &r); r != out {
		err(t, "Convert Float", r, out)
	}

	if Convert(int64(1), &r); r != out {
		err(t, "Convert Float", r, out)
	}

	if Convert(float64(1.0), &r); r != out {
		err(t, "Convert Float", r, out)
	}

	if Convert(float32(1.0), &r); r != out {
		err(t, "Convert Float", r, out)
	}

	if Convert("1", &r); r != out {
		err(t, "Convert Float", r, out)
	}

	var tv TypedValue
	Convert(1, &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert Float", r, out)
	}

	Convert(1.0, &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert Float", r, out)
	}

	Convert("1.0", &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert Float", r, out)
	}

	var f32 float32
	if Convert(float32(1), &f32); f32 != float32(1) {
		err(t, "Convert Float", f32, float32(1))
	}
}

func TestToBool(t *testing.T) {
	var r bool

	out := true

	if Convert(out, &r); r != out {
		err(t, "Convert Bool", r, out)
	}

	if Convert("true", &r); r != out {
		err(t, "Convert Bool", r, out)
	}

	if Convert(typeconverter.Json("true"), &r); r != out {
		err(t, "Convert Bool", r, out)
	}

	var tv TypedValue
	Convert(true, &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert Bool", r, out)
	}

	Convert("true", &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert Bool", r, out)
	}

	Convert(typeconverter.Json("true"), &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert Bool", r, out)
	}
}

func TestToString(t *testing.T) {
	var r string

	out := "1"

	if Convert(out, &r); r != out {
		err(t, "Convert String", r, out)
	}

	if Convert(int32(1), &r); r != out {
		err(t, "Convert String", r, out)
	}

	if Convert(int64(1), &r); r != out {
		err(t, "Convert String", r, out)
	}

	if Convert(float64(1.0), &r); r != out {
		err(t, "Convert String", r, out)
	}

	if Convert(float32(1.0), &r); r != out {
		err(t, "Convert String", r, out)
	}

	if Convert("1", &r); r != out {
		err(t, "Convert String", r, out)
	}

	if Convert(typeconverter.Json(`1`), &r); r != out {
		err(t, "Convert String", r, out)
	}

	sql := Sql("Select 1")

	if Convert(sql, &r); r != sql.Sql().String() {
		err(t, "Convert String", r, sql.Sql())
	}

	var tv TypedValue
	Convert(1, &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert String", r, out)
	}

	Convert(1.0, &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert String", r, out)
	}

	Convert("1", &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert String", r, out)
	}

	Convert(typeconverter.Json(`1`), &tv)

	if Convert(&tv, &r); r != out {
		err(t, "Convert String", r, out)
	}

	tv = TypedValue{}

	Convert(sql, &tv)

	if Convert(&tv, &r); r != sql.Sql().String() {
		err(t, "Convert String", r, sql.Sql())
	}
}

func TestToTime(t *testing.T) {
	var r time.Time

	out := ti

	if Convert(out, &r); r.UTC().Format(time.RFC3339) != out.UTC().Format(time.RFC3339) {
		err(t, "Convert time", r, out)
	}

	if Convert(int32(timeUnix), &r); r.UTC().Format(time.RFC3339) != out.UTC().Format(time.RFC3339) {
		err(t, "Convert time", r, out)
	}
	if Convert(int64(timeUnix), &r); r.UTC().Format(time.RFC3339) != out.UTC().Format(time.RFC3339) {
		err(t, "Convert time", r, out)
	}

	/*
		Does not work: check!
		if Convert(timeFloat, &r); r.Format(time.RFC3339) != tiFloatString {
			err(t, "Convert time", r.Format(time.RFC3339), tiFloatString)
		}
	*/

	if Convert(timeString, &r); r.UTC().Format(time.RFC3339) != out.UTC().Format(time.RFC3339) {
		err(t, "Convert time", r, out)
	}

	if Convert(typeconverter.Json(timeString), &r); r.UTC().Format(time.RFC3339) != out.UTC().Format(time.RFC3339) {
		err(t, "Convert time", r, out)
	}

	var tv TypedValue
	Convert(timeUnix, &tv)

	if Convert(&tv, &r); r.UTC().Format(time.RFC3339) != out.UTC().Format(time.RFC3339) {
		err(t, "Convert time", r, out)
	}

	Convert(int32(timeUnix), &tv)

	if Convert(&tv, &r); r.UTC().Format(time.RFC3339) != out.UTC().Format(time.RFC3339) {
		err(t, "Convert time", r, out)
	}

	Convert(timeString, &tv)

	if Convert(&tv, &r); r.UTC().Format(time.RFC3339) != out.UTC().Format(time.RFC3339) {
		err(t, "Convert time", r, out)
	}

	Convert(typeconverter.Json(timeString), &tv)

	if Convert(&tv, &r); r.UTC().Format(time.RFC3339) != out.UTC().Format(time.RFC3339) {
		err(t, "Convert time", r, out)
	}
}

func TestToType(t *testing.T) {
	for in, out := range toTypedValueTests {
		r := Type(0)
		Convert(in, &r)
		if r.String() != out.String() {
			err(t, "Convert to type wrong type", r.String(), out.String())

		}
	}
}

type MyInt int

func (ø MyInt) Sql() SqlType { return Sql(fmt.Sprintf("select %v", ø)) }

var toSqlTests = map[interface{}]string{
	1:            `'1'::int`,
	int32(2):     `'2'::int`,
	int64(2):     `'2'::int`,
	float64(3.5): `'3.5'::float`,
	float32(3.5): `'3.5'::float`,
	`3.0`:        `'3.0'::text`,
	true:         `'true'::bool`,
	ti:           `'` + timeString + `'::timestamptz`,
	typeconverter.Json(`{"a":4}`): `'{"a":4}'::text`,
	Sql("select * from person"):   `select * from person`,
	MyInt(4):                      `select 4`,
}

func TestToSql(t *testing.T) {
	for in, out := range toSqlTests {
		r := Sql("")
		Convert(in, &r)
		if r.Sql().String() != out {
			err(t, "Convert to Sql", r, out)
		}
	}
}
<|endoftext|>


<commit_before>// +build !windows

// Copyright 2015 flannel authors
//
// 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.
// +build !windows

package vxlan

import (
	"fmt"
	"net"
	"syscall"

	log "github.com/golang/glog"
	"github.com/vishvananda/netlink"

	"github.com/coreos/flannel/pkg/ip"
        "github.com/containernetworking/plugins/pkg/utils/sysctl"
)

type vxlanDeviceAttrs struct {
	vni       uint32
	name      string
	vtepIndex int
	vtepAddr  net.IP
	vtepPort  int
	gbp       bool
	learning  bool
}

type vxlanDevice struct {
	link          *netlink.Vxlan
	directRouting bool
}

func newVXLANDevice(devAttrs *vxlanDeviceAttrs) (*vxlanDevice, error) {
	link := &netlink.Vxlan{
		LinkAttrs: netlink.LinkAttrs{
			Name: devAttrs.name,
		},
		VxlanId:      int(devAttrs.vni),
		VtepDevIndex: devAttrs.vtepIndex,
		SrcAddr:      devAttrs.vtepAddr,
		Port:         devAttrs.vtepPort,
		Learning:     devAttrs.learning,
		GBP:          devAttrs.gbp,
	}

	link, err := ensureLink(link)
	if err != nil {
		return nil, err
	}

        _, _ = sysctl.Sysctl(fmt.Sprintf("net/ipv6/conf/%s/accept_ra", devAttrs.name), "0")

	return &vxlanDevice{
		link: link,
	}, nil
}

func ensureLink(vxlan *netlink.Vxlan) (*netlink.Vxlan, error) {
	err := netlink.LinkAdd(vxlan)
	if err == syscall.EEXIST {
		// it's ok if the device already exists as long as config is similar
		log.V(1).Infof("VXLAN device already exists")
		existing, err := netlink.LinkByName(vxlan.Name)
		if err != nil {
			return nil, err
		}

		incompat := vxlanLinksIncompat(vxlan, existing)
		if incompat == "" {
			log.V(1).Infof("Returning existing device")
			return existing.(*netlink.Vxlan), nil
		}

		// delete existing
		log.Warningf("%q already exists with incompatable configuration: %v; recreating device", vxlan.Name, incompat)
		if err = netlink.LinkDel(existing); err != nil {
			return nil, fmt.Errorf("failed to delete interface: %v", err)
		}

		// create new
		if err = netlink.LinkAdd(vxlan); err != nil {
			return nil, fmt.Errorf("failed to create vxlan interface: %v", err)
		}
	} else if err != nil {
		return nil, err
	}

	ifindex := vxlan.Index
	link, err := netlink.LinkByIndex(vxlan.Index)
	if err != nil {
		return nil, fmt.Errorf("can't locate created vxlan device with index %v", ifindex)
	}

	var ok bool
	if vxlan, ok = link.(*netlink.Vxlan); !ok {
		return nil, fmt.Errorf("created vxlan device with index %v is not vxlan", ifindex)
	}

	return vxlan, nil
}

func (dev *vxlanDevice) Configure(ipn ip.IP4Net) error {
	if err := ip.EnsureV4AddressOnLink(ipn, dev.link); err != nil {
		return fmt.Errorf("failed to ensure address of interface %s: %s", dev.link.Attrs().Name, err)
	}

	if err := netlink.LinkSetUp(dev.link); err != nil {
		return fmt.Errorf("failed to set interface %s to UP state: %s", dev.link.Attrs().Name, err)
	}

	return nil
}

func (dev *vxlanDevice) MACAddr() net.HardwareAddr {
	return dev.link.HardwareAddr
}

type neighbor struct {
	MAC net.HardwareAddr
	IP  ip.IP4
}

func (dev *vxlanDevice) AddFDB(n neighbor) error {
	log.V(4).Infof("calling AddFDB: %v, %v", n.IP, n.MAC)
	return netlink.NeighSet(&netlink.Neigh{
		LinkIndex:    dev.link.Index,
		State:        netlink.NUD_PERMANENT,
		Family:       syscall.AF_BRIDGE,
		Flags:        netlink.NTF_SELF,
		IP:           n.IP.ToIP(),
		HardwareAddr: n.MAC,
	})
}

func (dev *vxlanDevice) DelFDB(n neighbor) error {
	log.V(4).Infof("calling DelFDB: %v, %v", n.IP, n.MAC)
	return netlink.NeighDel(&netlink.Neigh{
		LinkIndex:    dev.link.Index,
		Family:       syscall.AF_BRIDGE,
		Flags:        netlink.NTF_SELF,
		IP:           n.IP.ToIP(),
		HardwareAddr: n.MAC,
	})
}

func (dev *vxlanDevice) AddARP(n neighbor) error {
	log.V(4).Infof("calling AddARP: %v, %v", n.IP, n.MAC)
	return netlink.NeighSet(&netlink.Neigh{
		LinkIndex:    dev.link.Index,
		State:        netlink.NUD_PERMANENT,
		Type:         syscall.RTN_UNICAST,
		IP:           n.IP.ToIP(),
		HardwareAddr: n.MAC,
	})
}

func (dev *vxlanDevice) DelARP(n neighbor) error {
	log.V(4).Infof("calling DelARP: %v, %v", n.IP, n.MAC)
	return netlink.NeighDel(&netlink.Neigh{
		LinkIndex:    dev.link.Index,
		State:        netlink.NUD_PERMANENT,
		Type:         syscall.RTN_UNICAST,
		IP:           n.IP.ToIP(),
		HardwareAddr: n.MAC,
	})
}

func vxlanLinksIncompat(l1, l2 netlink.Link) string {
	if l1.Type() != l2.Type() {
		return fmt.Sprintf("link type: %v vs %v", l1.Type(), l2.Type())
	}

	v1 := l1.(*netlink.Vxlan)
	v2 := l2.(*netlink.Vxlan)

	if v1.VxlanId != v2.VxlanId {
		return fmt.Sprintf("vni: %v vs %v", v1.VxlanId, v2.VxlanId)
	}

	if v1.VtepDevIndex > 0 && v2.VtepDevIndex > 0 && v1.VtepDevIndex != v2.VtepDevIndex {
		return fmt.Sprintf("vtep (external) interface: %v vs %v", v1.VtepDevIndex, v2.VtepDevIndex)
	}

	if len(v1.SrcAddr) > 0 && len(v2.SrcAddr) > 0 && !v1.SrcAddr.Equal(v2.SrcAddr) {
		return fmt.Sprintf("vtep (external) IP: %v vs %v", v1.SrcAddr, v2.SrcAddr)
	}

	if len(v1.Group) > 0 && len(v2.Group) > 0 && !v1.Group.Equal(v2.Group) {
		return fmt.Sprintf("group address: %v vs %v", v1.Group, v2.Group)
	}

	if v1.L2miss != v2.L2miss {
		return fmt.Sprintf("l2miss: %v vs %v", v1.L2miss, v2.L2miss)
	}

	if v1.Port > 0 && v2.Port > 0 && v1.Port != v2.Port {
		return fmt.Sprintf("port: %v vs %v", v1.Port, v2.Port)
	}

	if v1.GBP != v2.GBP {
		return fmt.Sprintf("gbp: %v vs %v", v1.GBP, v2.GBP)
	}

	return ""
}
<commit_msg>Run gofmt -w on backend/vxlan/device.go to pass CI<commit_after>// +build !windows

// Copyright 2015 flannel authors
//
// 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.
// +build !windows

package vxlan

import (
	"fmt"
	"net"
	"syscall"

	log "github.com/golang/glog"
	"github.com/vishvananda/netlink"

	"github.com/containernetworking/plugins/pkg/utils/sysctl"
	"github.com/coreos/flannel/pkg/ip"
)

type vxlanDeviceAttrs struct {
	vni       uint32
	name      string
	vtepIndex int
	vtepAddr  net.IP
	vtepPort  int
	gbp       bool
	learning  bool
}

type vxlanDevice struct {
	link          *netlink.Vxlan
	directRouting bool
}

func newVXLANDevice(devAttrs *vxlanDeviceAttrs) (*vxlanDevice, error) {
	link := &netlink.Vxlan{
		LinkAttrs: netlink.LinkAttrs{
			Name: devAttrs.name,
		},
		VxlanId:      int(devAttrs.vni),
		VtepDevIndex: devAttrs.vtepIndex,
		SrcAddr:      devAttrs.vtepAddr,
		Port:         devAttrs.vtepPort,
		Learning:     devAttrs.learning,
		GBP:          devAttrs.gbp,
	}

	link, err := ensureLink(link)
	if err != nil {
		return nil, err
	}

	_, _ = sysctl.Sysctl(fmt.Sprintf("net/ipv6/conf/%s/accept_ra", devAttrs.name), "0")

	return &vxlanDevice{
		link: link,
	}, nil
}

func ensureLink(vxlan *netlink.Vxlan) (*netlink.Vxlan, error) {
	err := netlink.LinkAdd(vxlan)
	if err == syscall.EEXIST {
		// it's ok if the device already exists as long as config is similar
		log.V(1).Infof("VXLAN device already exists")
		existing, err := netlink.LinkByName(vxlan.Name)
		if err != nil {
			return nil, err
		}

		incompat := vxlanLinksIncompat(vxlan, existing)
		if incompat == "" {
			log.V(1).Infof("Returning existing device")
			return existing.(*netlink.Vxlan), nil
		}

		// delete existing
		log.Warningf("%q already exists with incompatable configuration: %v; recreating device", vxlan.Name, incompat)
		if err = netlink.LinkDel(existing); err != nil {
			return nil, fmt.Errorf("failed to delete interface: %v", err)
		}

		// create new
		if err = netlink.LinkAdd(vxlan); err != nil {
			return nil, fmt.Errorf("failed to create vxlan interface: %v", err)
		}
	} else if err != nil {
		return nil, err
	}

	ifindex := vxlan.Index
	link, err := netlink.LinkByIndex(vxlan.Index)
	if err != nil {
		return nil, fmt.Errorf("can't locate created vxlan device with index %v", ifindex)
	}

	var ok bool
	if vxlan, ok = link.(*netlink.Vxlan); !ok {
		return nil, fmt.Errorf("created vxlan device with index %v is not vxlan", ifindex)
	}

	return vxlan, nil
}

func (dev *vxlanDevice) Configure(ipn ip.IP4Net) error {
	if err := ip.EnsureV4AddressOnLink(ipn, dev.link); err != nil {
		return fmt.Errorf("failed to ensure address of interface %s: %s", dev.link.Attrs().Name, err)
	}

	if err := netlink.LinkSetUp(dev.link); err != nil {
		return fmt.Errorf("failed to set interface %s to UP state: %s", dev.link.Attrs().Name, err)
	}

	return nil
}

func (dev *vxlanDevice) MACAddr() net.HardwareAddr {
	return dev.link.HardwareAddr
}

type neighbor struct {
	MAC net.HardwareAddr
	IP  ip.IP4
}

func (dev *vxlanDevice) AddFDB(n neighbor) error {
	log.V(4).Infof("calling AddFDB: %v, %v", n.IP, n.MAC)
	return netlink.NeighSet(&netlink.Neigh{
		LinkIndex:    dev.link.Index,
		State:        netlink.NUD_PERMANENT,
		Family:       syscall.AF_BRIDGE,
		Flags:        netlink.NTF_SELF,
		IP:           n.IP.ToIP(),
		HardwareAddr: n.MAC,
	})
}

func (dev *vxlanDevice) DelFDB(n neighbor) error {
	log.V(4).Infof("calling DelFDB: %v, %v", n.IP, n.MAC)
	return netlink.NeighDel(&netlink.Neigh{
		LinkIndex:    dev.link.Index,
		Family:       syscall.AF_BRIDGE,
		Flags:        netlink.NTF_SELF,
		IP:           n.IP.ToIP(),
		HardwareAddr: n.MAC,
	})
}

func (dev *vxlanDevice) AddARP(n neighbor) error {
	log.V(4).Infof("calling AddARP: %v, %v", n.IP, n.MAC)
	return netlink.NeighSet(&netlink.Neigh{
		LinkIndex:    dev.link.Index,
		State:        netlink.NUD_PERMANENT,
		Type:         syscall.RTN_UNICAST,
		IP:           n.IP.ToIP(),
		HardwareAddr: n.MAC,
	})
}

func (dev *vxlanDevice) DelARP(n neighbor) error {
	log.V(4).Infof("calling DelARP: %v, %v", n.IP, n.MAC)
	return netlink.NeighDel(&netlink.Neigh{
		LinkIndex:    dev.link.Index,
		State:        netlink.NUD_PERMANENT,
		Type:         syscall.RTN_UNICAST,
		IP:           n.IP.ToIP(),
		HardwareAddr: n.MAC,
	})
}

func vxlanLinksIncompat(l1, l2 netlink.Link) string {
	if l1.Type() != l2.Type() {
		return fmt.Sprintf("link type: %v vs %v", l1.Type(), l2.Type())
	}

	v1 := l1.(*netlink.Vxlan)
	v2 := l2.(*netlink.Vxlan)

	if v1.VxlanId != v2.VxlanId {
		return fmt.Sprintf("vni: %v vs %v", v1.VxlanId, v2.VxlanId)
	}

	if v1.VtepDevIndex > 0 && v2.VtepDevIndex > 0 && v1.VtepDevIndex != v2.VtepDevIndex {
		return fmt.Sprintf("vtep (external) interface: %v vs %v", v1.VtepDevIndex, v2.VtepDevIndex)
	}

	if len(v1.SrcAddr) > 0 && len(v2.SrcAddr) > 0 && !v1.SrcAddr.Equal(v2.SrcAddr) {
		return fmt.Sprintf("vtep (external) IP: %v vs %v", v1.SrcAddr, v2.SrcAddr)
	}

	if len(v1.Group) > 0 && len(v2.Group) > 0 && !v1.Group.Equal(v2.Group) {
		return fmt.Sprintf("group address: %v vs %v", v1.Group, v2.Group)
	}

	if v1.L2miss != v2.L2miss {
		return fmt.Sprintf("l2miss: %v vs %v", v1.L2miss, v2.L2miss)
	}

	if v1.Port > 0 && v2.Port > 0 && v1.Port != v2.Port {
		return fmt.Sprintf("port: %v vs %v", v1.Port, v2.Port)
	}

	if v1.GBP != v2.GBP {
		return fmt.Sprintf("gbp: %v vs %v", v1.GBP, v2.GBP)
	}

	return ""
}
<|endoftext|>