<commit_before>/*Blacksheepwall is a hostname reconnaissance tool, it is similar to other
tools, but has a focus on speed.*/

package main

import (
	"bufio"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"github.com/tomsteele/blacksheepwall/bsw"
	"log"
	"net"
	"os"
	"sort"
	"text/tabwriter"
)

const usage = `
  Usage: blacksheepwall [options] <ip address or CIDR>

  Options:
  -h, --help            Show Usage and exit.
  -version              Show version and exit.
  -debug                Enable debugging and show errors returned from tasks.
  -concurrency <int>    Max amount of concurrent tasks.    [default: 100]
  -server <string>      DNS server address.    [default: "8.8.8.8"]
  -input <string>       Line separated file of networks (CIDR) or
                        IP Addresses.
  -ipv6	                Look for additional AAAA records where applicable.
  -domain <string>      Target domain to use for certain tasks.
  -dictionary <string>  Attempt to retrieve the CNAME and A record for
                        each subdomain in the line separated file.
  -yandex <string>      Provided a Yandex search XML API url. Use the Yandex
                        search 'rhost:' operator to find subdomains of a
                        provided domain..
  -bing	<string>        Provided a base64 encoded API key. Use the Bing search
                        API's 'ip:' operator to lookup hostnames for each host.
  -headers              Perform HTTP(s) requests to each host and look for
                        hostnames in a possible Location header.
  -reverse              Retrieve the PTR for each host.
  -tls                  Attempt to retrieve names from TLS certificates
                        (CommonName and Subject Alternative Name).
  -viewdns              Lookup each host using viewdns.info's Reverse IP
                        Lookup function.
  -srv 					Find DNS SRV record and retrieve associated hostname/IP info.
  -fcrdns               Verify results by attempting to retrieve the A or AAAA record for
                        each result previously identified hostname.
  -clean                Print results as unique hostnames for each host.
  -csv                  Print results in csv format.
  -json                 Print results as JSON.

`

// Processes a list of IP addresses or networks in CIDR format.
// Returning a list of all possible IP addresses.
func linesToIpList(lines []string) ([]string, error) {
	ipList := []string{}
	for _, line := range lines {
		if net.ParseIP(line) != nil {
			ipList = append(ipList, line)
		} else if ip, network, err := net.ParseCIDR(line); err == nil {
			for ip := ip.Mask(network.Mask); network.Contains(ip); increaseIp(ip) {
				ipList = append(ipList, ip.String())
			}
		} else {
			return ipList, errors.New("\"" + line + "\" is not an IP Address or CIDR Network")
		}
	}
	return ipList, nil
}

// Increases an IP by a single address.
func increaseIp(ip net.IP) {
	for j := len(ip) - 1; j >= 0; j-- {
		ip[j]++
		if ip[j] > 0 {
			break
		}
	}
}

// Reads lines from a file and return as a slice.
func readFileLines(path string) ([]string, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	lines := []string{}
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		lines = append(lines, scanner.Text())
	}
	return lines, scanner.Err()
}

type task func() (bsw.Results, error)
type empty struct{}

func main() {
	// Command line options. For usage information see the
	// usage variable above.
	var (
		flVersion     = flag.Bool("version", false, "")
		flConcurrency = flag.Int("concurrency", 100, "")
		flDebug       = flag.Bool("debug", false, "")
		flipv6        = flag.Bool("ipv6", false, "")
		flServerAddr  = flag.String("server", "8.8.8.8", "")
		flIpFile      = flag.String("input", "", "")
		flReverse     = flag.Bool("reverse", false, "")
		flHeader      = flag.Bool("headers", false, "")
		flTLS         = flag.Bool("tls", false, "")
		flViewDnsInfo = flag.Bool("viewdns", false, "")
		flSRV         = flag.Bool("srv", false, "")
		flBing        = flag.String("bing", "", "")
		flYandex      = flag.String("yandex", "", "")
		flDomain      = flag.String("domain", "", "")
		flDictFile    = flag.String("dictionary", "", "")
		flFcrdns      = flag.Bool("fcrdns", false, "")
		flClean       = flag.Bool("clean", false, "")
		flCsv         = flag.Bool("csv", false, "")
		flJson        = flag.Bool("json", false, "")
	)
	flag.Usage = func() { fmt.Print(usage) }
	flag.Parse()

	if *flVersion {
		fmt.Println("blacksheepwall version ", bsw.VERSION)
		os.Exit(0)
	}

	// Holds all IP addresses for testing.
	ipAddrList := []string{}

	// Used to hold a ip or CIDR range passed as fl.Arg(0).
	var flNetwork string

	// Verify that some sort of work load was given in commands.
	if *flIpFile == "" && *flDomain == "" && len(flag.Args()) < 1 {
		log.Fatal("You didn't provide any work for me to do")
	}
	if *flYandex != "" && *flDomain == "" {
		log.Fatal("Yandex API requires domain set with -domain")
	}
	if *flDictFile != "" && *flDomain == "" {
		log.Fatal("Dictionary lookup requires domain set with -domain")
	}
	if *flDomain == "" && *flSRV == true {
		log.Fatal("SRV lookup requires domain set with -domain")
	}
	if *flDomain != "" && *flYandex == "" && *flDictFile == "" && *flSRV == false {
		log.Fatal("-domain provided but no methods provided that use it")
	}

	// Get first argument that is not an option and turn it into a list of IPs.
	if len(flag.Args()) > 0 {
		flNetwork = flag.Arg(0)
		list, err := linesToIpList([]string{flNetwork})
		if err != nil {
			log.Fatal(err.Error())
		}
		ipAddrList = append(ipAddrList, list...)
	}

	// If file given as -input, read lines and turn each possible IP or network into
	// a list of IPs. Appends list to ipAddrList. Will fail fatally if line in file
	// is not a valid IP or CIDR range.
	if *flIpFile != "" {
		lines, err := readFileLines(*flIpFile)
		if err != nil {
			log.Fatal("Error reading " + *flIpFile + " " + err.Error())
		}
		list, err := linesToIpList(lines)
		if err != nil {
			log.Fatal(err.Error())
		}
		ipAddrList = append(ipAddrList, list...)
	}

	// tracker: Chanel uses an empty struct to track when all goroutines in the pool
	//          have completed as well as a single call from the gatherer.
	//
	// tasks:   Chanel used in the goroutine pool to manage incoming work. A task is
	//          a function wrapper that returns a slice of results and a possible error.
	//
	// res:     When each task is called in the pool, it will send valid results to
	//          the res channel.
	tracker := make(chan empty)
	tasks := make(chan task, *flConcurrency)
	res := make(chan bsw.Results, *flConcurrency)
	// Use a map that acts like a set to store only unique results.
	resMap := make(map[bsw.Result]bool)

	// Start up *flConcurrency amount of goroutines.
	log.Printf("Spreading tasks across %d goroutines", *flConcurrency)
	for i := 0; i < *flConcurrency; i++ {
		go func() {
			var c = 0
			for def := range tasks {
				result, err := def()
				if m := c % 2; m == 0 {
					c = 3
					os.Stderr.WriteString("\rWorking \\")
				} else {
					c = 2
					os.Stderr.WriteString("\rWorking /")
				}
				if err != nil && *flDebug {
					log.Println(err.Error())
				}
				if err == nil {
					res <- result
				}
			}
			tracker <- empty{}
		}()
	}

	// Ingest incoming results.
	go func() {
		for result := range res {
			if len(result) < 1 {
				continue
			}
			if *flFcrdns {
				for _, r := range result {
					ip, err := bsw.LookupName(r.Hostname, *flServerAddr)
					if err == nil && len(ip) > 0 {
						resMap[bsw.Result{Source: "fcrdns", IP: ip, Hostname: r.Hostname}] = true
					}
					ip, err = bsw.LookupName6(r.Hostname, *flServerAddr)
					if err == nil && len(ip) > 0 {
						resMap[bsw.Result{Source: "fcrdns", IP: ip, Hostname: r.Hostname}] = true
					}
				}
			} else {
				for _, r := range result {
					resMap[r] = true
				}
			}
		}
		tracker <- empty{}
	}()

	// Bing has two possible search paths. We need to find which one is valid.
	var bingPath string
	if *flBing != "" {
		p, err := bsw.FindBingSearchPath(*flBing)
		if err != nil {
			log.Fatal(err.Error())
		}
		bingPath = p
	}

	// IP based functionality should be added to the pool here.
	for _, h := range ipAddrList {
		host := h
		if *flReverse {
			tasks <- func() (bsw.Results, error) { return bsw.Reverse(host, *flServerAddr) }
		}
		if *flTLS {
			tasks <- func() (bsw.Results, error) { return bsw.TLS(host) }
		}
		if *flViewDnsInfo {
			tasks <- func() (bsw.Results, error) { return bsw.ViewDnsInfo(host) }
		}
		if *flBing != "" && bingPath != "" {
			tasks <- func() (bsw.Results, error) { return bsw.BingAPI(host, *flBing, bingPath) }
		}
		if *flHeader {
			tasks <- func() (bsw.Results, error) { return bsw.Headers(host) }
		}
	}

	// Domain based functions will likely require separate blocks and should be added below.

	// Subdomain dictionary guessing.
	if *flDictFile != "" && *flDomain != "" {
		nameList, err := readFileLines(*flDictFile)
		if err != nil {
			log.Fatal("Error reading " + *flDictFile + " " + err.Error())
		}
		// Get an IP for a possible wildcard domain and use it as a blacklist.
		blacklist := bsw.GetWildCard(*flDomain, *flServerAddr)
		var blacklist6 string
		if *flipv6 {
			blacklist6 = bsw.GetWildCard6(*flDomain, *flServerAddr)
		}
		for _, n := range nameList {
			sub := n
			tasks <- func() (bsw.Results, error) { return bsw.Dictionary(*flDomain, sub, blacklist, *flServerAddr) }
			if *flipv6 {
				tasks <- func() (bsw.Results, error) { return bsw.Dictionary6(*flDomain, sub, blacklist6, *flServerAddr) }
			}
		}
	}

	if *flSRV != false && *flDomain != "" {
		tasks <- func() (bsw.Results, error) { return bsw.LookupSRV(*flDomain, *flServerAddr) }
	}

	if *flYandex != "" && *flDomain != "" {
		tasks <- func() (bsw.Results, error) { return bsw.YandexAPI(*flDomain, *flYandex, *flServerAddr) }
	}

	// Close the tasks channel after all jobs have completed and for each
	// goroutine in the pool receive an empty message from  tracker.
	close(tasks)
	for i := 0; i < *flConcurrency; i++ {
		<-tracker
	}
	close(res)
	// Receive and empty message from the result gatherer.
	<-tracker
	os.Stderr.WriteString("\r")
	log.Println("All tasks completed\n")

	// Create a results slice from the unique set in resMap. Allows for sorting.
	results := bsw.Results{}
	for k, _ := range resMap {
		results = append(results, k)
	}
	sort.Sort(results)

	switch {
	case *flJson:
		j, _ := json.MarshalIndent(results, "", "    ")
		fmt.Println(string(j))
	case *flCsv:
		for _, r := range results {
			fmt.Printf("%s,%s,%s\n", r.Hostname, r.IP, r.Source)
		}
	case *flClean:
		cleanSet := make(map[string][]string)
		for _, r := range results {
			cleanSet[r.IP] = append(cleanSet[r.IP], r.Hostname)
		}
		for k, v := range cleanSet {
			fmt.Printf("%s:\n", k)
			for _, h := range v {
				fmt.Printf("\t%s\n", h)
			}
		}
	default:
		w := tabwriter.NewWriter(os.Stdout, 0, 8, 4, ' ', 0)
		fmt.Fprintln(w, "IP\tHostname\tSource")
		for _, r := range results {
			fmt.Fprintf(w, "%s\t%s\t%s\n", r.IP, r.Hostname, r.Source)
		}
		w.Flush()
	}
}
<commit_msg>Update spacing for SRV option<commit_after>/*Blacksheepwall is a hostname reconnaissance tool, it is similar to other
tools, but has a focus on speed.*/

package main

import (
	"bufio"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"github.com/tomsteele/blacksheepwall/bsw"
	"log"
	"net"
	"os"
	"sort"
	"text/tabwriter"
)

const usage = `
  Usage: blacksheepwall [options] <ip address or CIDR>

  Options:
  -h, --help            Show Usage and exit.
  -version              Show version and exit.
  -debug                Enable debugging and show errors returned from tasks.
  -concurrency <int>    Max amount of concurrent tasks.    [default: 100]
  -server <string>      DNS server address.    [default: "8.8.8.8"]
  -input <string>       Line separated file of networks (CIDR) or
                        IP Addresses.
  -ipv6	                Look for additional AAAA records where applicable.
  -domain <string>      Target domain to use for certain tasks.
  -dictionary <string>  Attempt to retrieve the CNAME and A record for
                        each subdomain in the line separated file.
  -yandex <string>      Provided a Yandex search XML API url. Use the Yandex
                        search 'rhost:' operator to find subdomains of a
                        provided domain..
  -bing	<string>        Provided a base64 encoded API key. Use the Bing search
                        API's 'ip:' operator to lookup hostnames for each host.
  -headers              Perform HTTP(s) requests to each host and look for
                        hostnames in a possible Location header.
  -reverse              Retrieve the PTR for each host.
  -tls                  Attempt to retrieve names from TLS certificates
                        (CommonName and Subject Alternative Name).
  -viewdns              Lookup each host using viewdns.info's Reverse IP
                        Lookup function.
  -srv 			Find DNS SRV record and retrieve associated hostname/IP info.
  -fcrdns               Verify results by attempting to retrieve the A or AAAA record for
                        each result previously identified hostname.
  -clean                Print results as unique hostnames for each host.
  -csv                  Print results in csv format.
  -json                 Print results as JSON.

`

// Processes a list of IP addresses or networks in CIDR format.
// Returning a list of all possible IP addresses.
func linesToIpList(lines []string) ([]string, error) {
	ipList := []string{}
	for _, line := range lines {
		if net.ParseIP(line) != nil {
			ipList = append(ipList, line)
		} else if ip, network, err := net.ParseCIDR(line); err == nil {
			for ip := ip.Mask(network.Mask); network.Contains(ip); increaseIp(ip) {
				ipList = append(ipList, ip.String())
			}
		} else {
			return ipList, errors.New("\"" + line + "\" is not an IP Address or CIDR Network")
		}
	}
	return ipList, nil
}

// Increases an IP by a single address.
func increaseIp(ip net.IP) {
	for j := len(ip) - 1; j >= 0; j-- {
		ip[j]++
		if ip[j] > 0 {
			break
		}
	}
}

// Reads lines from a file and return as a slice.
func readFileLines(path string) ([]string, error) {
	file, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	lines := []string{}
	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		lines = append(lines, scanner.Text())
	}
	return lines, scanner.Err()
}

type task func() (bsw.Results, error)
type empty struct{}

func main() {
	// Command line options. For usage information see the
	// usage variable above.
	var (
		flVersion     = flag.Bool("version", false, "")
		flConcurrency = flag.Int("concurrency", 100, "")
		flDebug       = flag.Bool("debug", false, "")
		flipv6        = flag.Bool("ipv6", false, "")
		flServerAddr  = flag.String("server", "8.8.8.8", "")
		flIpFile      = flag.String("input", "", "")
		flReverse     = flag.Bool("reverse", false, "")
		flHeader      = flag.Bool("headers", false, "")
		flTLS         = flag.Bool("tls", false, "")
		flViewDnsInfo = flag.Bool("viewdns", false, "")
		flSRV         = flag.Bool("srv", false, "")
		flBing        = flag.String("bing", "", "")
		flYandex      = flag.String("yandex", "", "")
		flDomain      = flag.String("domain", "", "")
		flDictFile    = flag.String("dictionary", "", "")
		flFcrdns      = flag.Bool("fcrdns", false, "")
		flClean       = flag.Bool("clean", false, "")
		flCsv         = flag.Bool("csv", false, "")
		flJson        = flag.Bool("json", false, "")
	)
	flag.Usage = func() { fmt.Print(usage) }
	flag.Parse()

	if *flVersion {
		fmt.Println("blacksheepwall version ", bsw.VERSION)
		os.Exit(0)
	}

	// Holds all IP addresses for testing.
	ipAddrList := []string{}

	// Used to hold a ip or CIDR range passed as fl.Arg(0).
	var flNetwork string

	// Verify that some sort of work load was given in commands.
	if *flIpFile == "" && *flDomain == "" && len(flag.Args()) < 1 {
		log.Fatal("You didn't provide any work for me to do")
	}
	if *flYandex != "" && *flDomain == "" {
		log.Fatal("Yandex API requires domain set with -domain")
	}
	if *flDictFile != "" && *flDomain == "" {
		log.Fatal("Dictionary lookup requires domain set with -domain")
	}
	if *flDomain == "" && *flSRV == true {
		log.Fatal("SRV lookup requires domain set with -domain")
	}
	if *flDomain != "" && *flYandex == "" && *flDictFile == "" && *flSRV == false {
		log.Fatal("-domain provided but no methods provided that use it")
	}

	// Get first argument that is not an option and turn it into a list of IPs.
	if len(flag.Args()) > 0 {
		flNetwork = flag.Arg(0)
		list, err := linesToIpList([]string{flNetwork})
		if err != nil {
			log.Fatal(err.Error())
		}
		ipAddrList = append(ipAddrList, list...)
	}

	// If file given as -input, read lines and turn each possible IP or network into
	// a list of IPs. Appends list to ipAddrList. Will fail fatally if line in file
	// is not a valid IP or CIDR range.
	if *flIpFile != "" {
		lines, err := readFileLines(*flIpFile)
		if err != nil {
			log.Fatal("Error reading " + *flIpFile + " " + err.Error())
		}
		list, err := linesToIpList(lines)
		if err != nil {
			log.Fatal(err.Error())
		}
		ipAddrList = append(ipAddrList, list...)
	}

	// tracker: Chanel uses an empty struct to track when all goroutines in the pool
	//          have completed as well as a single call from the gatherer.
	//
	// tasks:   Chanel used in the goroutine pool to manage incoming work. A task is
	//          a function wrapper that returns a slice of results and a possible error.
	//
	// res:     When each task is called in the pool, it will send valid results to
	//          the res channel.
	tracker := make(chan empty)
	tasks := make(chan task, *flConcurrency)
	res := make(chan bsw.Results, *flConcurrency)
	// Use a map that acts like a set to store only unique results.
	resMap := make(map[bsw.Result]bool)

	// Start up *flConcurrency amount of goroutines.
	log.Printf("Spreading tasks across %d goroutines", *flConcurrency)
	for i := 0; i < *flConcurrency; i++ {
		go func() {
			var c = 0
			for def := range tasks {
				result, err := def()
				if m := c % 2; m == 0 {
					c = 3
					os.Stderr.WriteString("\rWorking \\")
				} else {
					c = 2
					os.Stderr.WriteString("\rWorking /")
				}
				if err != nil && *flDebug {
					log.Println(err.Error())
				}
				if err == nil {
					res <- result
				}
			}
			tracker <- empty{}
		}()
	}

	// Ingest incoming results.
	go func() {
		for result := range res {
			if len(result) < 1 {
				continue
			}
			if *flFcrdns {
				for _, r := range result {
					ip, err := bsw.LookupName(r.Hostname, *flServerAddr)
					if err == nil && len(ip) > 0 {
						resMap[bsw.Result{Source: "fcrdns", IP: ip, Hostname: r.Hostname}] = true
					}
					ip, err = bsw.LookupName6(r.Hostname, *flServerAddr)
					if err == nil && len(ip) > 0 {
						resMap[bsw.Result{Source: "fcrdns", IP: ip, Hostname: r.Hostname}] = true
					}
				}
			} else {
				for _, r := range result {
					resMap[r] = true
				}
			}
		}
		tracker <- empty{}
	}()

	// Bing has two possible search paths. We need to find which one is valid.
	var bingPath string
	if *flBing != "" {
		p, err := bsw.FindBingSearchPath(*flBing)
		if err != nil {
			log.Fatal(err.Error())
		}
		bingPath = p
	}

	// IP based functionality should be added to the pool here.
	for _, h := range ipAddrList {
		host := h
		if *flReverse {
			tasks <- func() (bsw.Results, error) { return bsw.Reverse(host, *flServerAddr) }
		}
		if *flTLS {
			tasks <- func() (bsw.Results, error) { return bsw.TLS(host) }
		}
		if *flViewDnsInfo {
			tasks <- func() (bsw.Results, error) { return bsw.ViewDnsInfo(host) }
		}
		if *flBing != "" && bingPath != "" {
			tasks <- func() (bsw.Results, error) { return bsw.BingAPI(host, *flBing, bingPath) }
		}
		if *flHeader {
			tasks <- func() (bsw.Results, error) { return bsw.Headers(host) }
		}
	}

	// Domain based functions will likely require separate blocks and should be added below.

	// Subdomain dictionary guessing.
	if *flDictFile != "" && *flDomain != "" {
		nameList, err := readFileLines(*flDictFile)
		if err != nil {
			log.Fatal("Error reading " + *flDictFile + " " + err.Error())
		}
		// Get an IP for a possible wildcard domain and use it as a blacklist.
		blacklist := bsw.GetWildCard(*flDomain, *flServerAddr)
		var blacklist6 string
		if *flipv6 {
			blacklist6 = bsw.GetWildCard6(*flDomain, *flServerAddr)
		}
		for _, n := range nameList {
			sub := n
			tasks <- func() (bsw.Results, error) { return bsw.Dictionary(*flDomain, sub, blacklist, *flServerAddr) }
			if *flipv6 {
				tasks <- func() (bsw.Results, error) { return bsw.Dictionary6(*flDomain, sub, blacklist6, *flServerAddr) }
			}
		}
	}

	if *flSRV != false && *flDomain != "" {
		tasks <- func() (bsw.Results, error) { return bsw.LookupSRV(*flDomain, *flServerAddr) }
	}

	if *flYandex != "" && *flDomain != "" {
		tasks <- func() (bsw.Results, error) { return bsw.YandexAPI(*flDomain, *flYandex, *flServerAddr) }
	}

	// Close the tasks channel after all jobs have completed and for each
	// goroutine in the pool receive an empty message from  tracker.
	close(tasks)
	for i := 0; i < *flConcurrency; i++ {
		<-tracker
	}
	close(res)
	// Receive and empty message from the result gatherer.
	<-tracker
	os.Stderr.WriteString("\r")
	log.Println("All tasks completed\n")

	// Create a results slice from the unique set in resMap. Allows for sorting.
	results := bsw.Results{}
	for k, _ := range resMap {
		results = append(results, k)
	}
	sort.Sort(results)

	switch {
	case *flJson:
		j, _ := json.MarshalIndent(results, "", "    ")
		fmt.Println(string(j))
	case *flCsv:
		for _, r := range results {
			fmt.Printf("%s,%s,%s\n", r.Hostname, r.IP, r.Source)
		}
	case *flClean:
		cleanSet := make(map[string][]string)
		for _, r := range results {
			cleanSet[r.IP] = append(cleanSet[r.IP], r.Hostname)
		}
		for k, v := range cleanSet {
			fmt.Printf("%s:\n", k)
			for _, h := range v {
				fmt.Printf("\t%s\n", h)
			}
		}
	default:
		w := tabwriter.NewWriter(os.Stdout, 0, 8, 4, ' ', 0)
		fmt.Fprintln(w, "IP\tHostname\tSource")
		for _, r := range results {
			fmt.Fprintf(w, "%s\t%s\t%s\n", r.IP, r.Hostname, r.Source)
		}
		w.Flush()
	}
}
<|endoftext|>


<commit_before>//+build !no_Pseudohsm

package core

import (
	"context"
	"github.com/bytom/blockchain/pseudohsm"
	"github.com/bytom/blockchain/txbuilder"
	"github.com/bytom/crypto/ed25519/chainkd"
	"github.com/bytom/net/http/httperror"
	"github.com/bytom/net/http/httpjson"
)

func init() {
	errorFormatter.Errors[Pseudohsm.ErrDuplicateKeyAlias] = httperror.Info{400, "BTM050", "Alias already exists"}
	errorFormatter.Errors[Pseudohsm.ErrInvalidAfter] = httperror.Info{400, "BTM801", "Invalid `after` in query"}
	errorFormatter.Errors[Pseudohsm.ErrTooManyAliasesToList] = httperror.Info{400, "BTM802", "Too many aliases to list"}
}

// PseudoHSM configures the Core to expose the PseudoHSM endpoints. It
// is only included in non-production builds.
/*
func PseudoHSM(hsm *Pseudohsm.HSM) RunOption {
	return func(api *API) {

		h := &pseudoHSMHandler{PseudoHSM: hsm}
		needConfig := api.needConfig()
		api.mux.Handle("/hsm/create-key", needConfig(h.pseudohsmCreateKey))
		api.mux.Handle("/hsm/list-keys", needConfig(h.pseudohsmListKeys))
		api.mux.Handle("/hsm/delete-key", needConfig(h.pseudohsmDeleteKey))
		api.mux.Handle("/hsm/sign-transaction", needConfig(h.pseudohsmSignTemplates))
		api.mux.Handle("/hsm/reset-password", needConfig(h.pseudohsmResetPassword))
		api.mux.Handle("/hsm/update-alias", needConfig(h.pseudohsmUpdateAlias))
	}
}

type pseudoHSMHandler struct {
	PseudoHSM *Pseudohsm.HSM
}
*/

func (a *BlockchainReactor) pseudohsmCreateKey(ctx context.Context, password string, in struct{ Alias string }) (result *Pseudohsm.XPub, err error) {
	return a.hsm.XCreate(password, in.Alias)
}

func (a *BlockchainReactor)) pseudohsmListKeys(ctx context.Context, query requestQuery) (page, error) {
	limit := query.PageSize
	if limit == 0 {
		limit = defGenericPageSize  // defGenericPageSize = 100
	}

	xpubs, after, err := h.PseudoHSM.ListKeys(query.After, limit)
	if err != nil {
		return page{}, err
	}

	var items []interface{}
	for _, xpub := range xpubs {
		items = append(items, xpub)
	}

	query.After = after

	return page{
		Items:    httpjson.Array(items),
		LastPage: len(xpubs) < limit,
		Next:     query,
	}, nil
}

func (a *BlockchainReactor) pseudohsmDeleteKey(ctx context.Context, xpub chainkd.XPub, password string) error {
	return a.hsm.XDelete(xpub, password)
}

func (a *BlockchainReactor) pseudohsmSignTemplates(ctx context.Context, x struct {
	Txs   []*txbuilder.Template `json:"transactions"`
	XPubs []chainkd.XPub        `json:"xpubs"`
}) []interface{} {
	resp := make([]interface{}, 0, len(x.Txs))
	for _, tx := range x.Txs {
		err := txbuilder.Sign(ctx, tx, x.XPubs, a.hsm.pseudohsmSignTemplate)
		if err != nil {
			info := errorFormatter.Format(err)
			response = append(resp, info)
		} else {
			resp = append(resp, tx)
		}
	}
	return resp
}

func (a *BlockchainReactor) pseudohsmSignTemplate(ctx context.Context, xpub chainkd.XPub, path [][]byte, data [32]byte) ([]byte, error) {
	sigBytes, err := a.hsm.XSign(ctx, xpub, path, data[:])
	if err == Pseudohsm.ErrNoKey {
		return nil, nil
	}
	return sigBytes, err
}

// remote hsm used
/*
func RemoteHSM(hsm *remoteHSM) RunOption {
	return func(api *API) {
		h := &retmoteHSMHandler{RemoteHSM: hsm}
		needConfig := api.needConfig()
		api.mux.Handle("/hsm/sign-transaction", needConfig(h.Sign))
	}
}

type remoteHSM struct {
	Client *rpc.Client
}

func remoteHSMHandler struct {
	RemoteHSM  *remoteHSM
}

func New(conf *config.Config) *HSM {

	httpClient := new(http.Client)
	httpClient.Transport = &http.Transport{
		TLSClientConfig: tlsConfig,
		// The following fields are default values
		// copied from DefaultTransport.
		// (When you change them, be sure to move them
		// above this line so this comment stays true.)
		DialContext: (&net.Dialer{
			Timeout:   30 * time.Second,
			KeepAlive: 30 * time.Second,
			DualStack: true,
		}).DialContext,
		MaxIdleConns:          100,
		IdleConnTimeout:       90 * time.Second,
		TLSHandshakeTimeout:   10 * time.Second,
		ExpectContinueTimeout: 1 * time.Second,
	}

	return &remoteHSM{Client: &rpc.Client{
			BaseURL:      conf.HsmUrl,
			AccessToken:  conf.HsmAccessToken,
			Username:     conf.processID,
			CoreID:       conf.Id,
			Version:      conf.version,
			BlockchainID: conf.BlockchainId.String(),
			Client:       httpClient,
		}}
}

func (h *remoteHSM) Sign(ctx context.Context, pk ed25519.PublicKey, date [32]byte)([]byte, err error) {
	body := struct {
		Block *legacy.TxHeader 	  `json:"txheader"`
		Pub   json.HexBytes       `json:"pubkey"`
	}{data, json.HexBytes(pk[:])}

	err = h.Client.Call(ctx, "/sign-transaction", body, &sigBytes)
	return sigBytes
}
*/<commit_msg>delete remote<commit_after>//+build !no_Pseudohsm

package core

import (
	"context"
	"github.com/bytom/blockchain/pseudohsm"
	"github.com/bytom/blockchain/txbuilder"
	"github.com/bytom/crypto/ed25519/chainkd"
	"github.com/bytom/net/http/httperror"
	"github.com/bytom/net/http/httpjson"
)

func init() {
	errorFormatter.Errors[Pseudohsm.ErrDuplicateKeyAlias] = httperror.Info{400, "BTM050", "Alias already exists"}
	errorFormatter.Errors[Pseudohsm.ErrInvalidAfter] = httperror.Info{400, "BTM801", "Invalid `after` in query"}
	errorFormatter.Errors[Pseudohsm.ErrTooManyAliasesToList] = httperror.Info{400, "BTM802", "Too many aliases to list"}
}

// PseudoHSM configures the Core to expose the PseudoHSM endpoints. It
// is only included in non-production builds.
/*
func PseudoHSM(hsm *Pseudohsm.HSM) RunOption {
	return func(api *API) {

		h := &pseudoHSMHandler{PseudoHSM: hsm}
		needConfig := api.needConfig()
		api.mux.Handle("/hsm/create-key", needConfig(h.pseudohsmCreateKey))
		api.mux.Handle("/hsm/list-keys", needConfig(h.pseudohsmListKeys))
		api.mux.Handle("/hsm/delete-key", needConfig(h.pseudohsmDeleteKey))
		api.mux.Handle("/hsm/sign-transaction", needConfig(h.pseudohsmSignTemplates))
		api.mux.Handle("/hsm/reset-password", needConfig(h.pseudohsmResetPassword))
		api.mux.Handle("/hsm/update-alias", needConfig(h.pseudohsmUpdateAlias))
	}
}

type pseudoHSMHandler struct {
	PseudoHSM *Pseudohsm.HSM
}
*/

func (a *BlockchainReactor) pseudohsmCreateKey(ctx context.Context, password string, in struct{ Alias string }) (result *Pseudohsm.XPub, err error) {
	return a.hsm.XCreate(password, in.Alias)
}

func (a *BlockchainReactor)) pseudohsmListKeys(ctx context.Context, query requestQuery) (page, error) {
	limit := query.PageSize
	if limit == 0 {
		limit = defGenericPageSize  // defGenericPageSize = 100
	}

	xpubs, after, err := h.PseudoHSM.ListKeys(query.After, limit)
	if err != nil {
		return page{}, err
	}

	var items []interface{}
	for _, xpub := range xpubs {
		items = append(items, xpub)
	}

	query.After = after

	return page{
		Items:    httpjson.Array(items),
		LastPage: len(xpubs) < limit,
		Next:     query,
	}, nil
}

func (a *BlockchainReactor) pseudohsmDeleteKey(ctx context.Context, xpub chainkd.XPub, password string) error {
	return a.hsm.XDelete(xpub, password)
}

func (a *BlockchainReactor) pseudohsmSignTemplates(ctx context.Context, x struct {
	Txs   []*txbuilder.Template `json:"transactions"`
	XPubs []chainkd.XPub        `json:"xpubs"`
}) []interface{} {
	resp := make([]interface{}, 0, len(x.Txs))
	for _, tx := range x.Txs {
		err := txbuilder.Sign(ctx, tx, x.XPubs, a.hsm.pseudohsmSignTemplate)
		if err != nil {
			info := errorFormatter.Format(err)
			response = append(resp, info)
		} else {
			resp = append(resp, tx)
		}
	}
	return resp
}

func (a *BlockchainReactor) pseudohsmSignTemplate(ctx context.Context, xpub chainkd.XPub, path [][]byte, data [32]byte) ([]byte, error) {
	sigBytes, err := a.hsm.XSign(ctx, xpub, path, data[:])
	if err == Pseudohsm.ErrNoKey {
		return nil, nil
	}
	return sigBytes, err
}
<|endoftext|>


<commit_before><commit_msg>internal/go/gcimporter: avoid expensive call to (*token.File).SetLines<commit_after><|endoftext|>


<commit_before><commit_msg>repository: don't crash if blob size is too short<commit_after><|endoftext|>


<commit_before>package apidApigeeSync

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"io/ioutil"
	"net/http/httptest"
	"os"
	"testing"
	"time"

	"github.com/30x/apid-core"

	"github.com/30x/apid-core/factory"
)

var (
	tmpDir         string
	testServer     *httptest.Server
	testRouter     apid.Router
	testMock       *MockServer
	wipeDBAferTest bool
)

const dummyConfigValue string = "placeholder"

var _ = BeforeSuite(func() {
	wipeDBAferTest = true
})

var _ = BeforeEach(func(done Done) {
	apid.Initialize(factory.DefaultServicesFactory())

	config = apid.Config()

	var err error
	tmpDir, err = ioutil.TempDir("", "api_test")
	Expect(err).NotTo(HaveOccurred())
	config.Set("local_storage_path", tmpDir)

	config.Set(configProxyServerBaseURI, dummyConfigValue)
	config.Set(configSnapServerBaseURI, dummyConfigValue)
	config.Set(configChangeServerBaseURI, dummyConfigValue)
	config.Set(configSnapshotProtocol, "json")
	config.Set(configPollInterval, 10*time.Millisecond)

	config.Set(configName, "testhost")
	config.Set(configApidClusterId, "bootstrap")
	config.Set(configConsumerKey, "XXXXXXX")
	config.Set(configConsumerSecret, "YYYYYYY")

	block = "0"
	log = apid.Log()

	_initPlugin(apid.AllServices())
	close(done)
})

var _ = AfterEach(func() {
	apid.Events().Close()

	lastSequence = ""

	if wipeDBAferTest {
		_, err := getDB().Exec("DELETE FROM APID_CLUSTER")
		Expect(err).NotTo(HaveOccurred())
		_, err = getDB().Exec("DELETE FROM DATA_SCOPE")
		Expect(err).NotTo(HaveOccurred())

		db, err := dataService.DB()
		Expect(err).NotTo(HaveOccurred())
		_, err = db.Exec("DELETE FROM APID")
		Expect(err).NotTo(HaveOccurred())
	}
	wipeDBAferTest = true
})

var _ = AfterSuite(func() {
	apid.Events().Close()
	if testServer != nil {
		testServer.Close()
	}
	os.RemoveAll(tmpDir)
})

func TestApigeeSync(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "ApigeeSync Suite")
}
<commit_msg>add timeout<commit_after>package apidApigeeSync

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"io/ioutil"
	"net/http/httptest"
	"os"
	"testing"
	"time"

	"github.com/30x/apid-core"

	"github.com/30x/apid-core/factory"
)

var (
	tmpDir         string
	testServer     *httptest.Server
	testRouter     apid.Router
	testMock       *MockServer
	wipeDBAferTest bool
)

const dummyConfigValue string = "placeholder"

var _ = BeforeSuite(func() {
	wipeDBAferTest = true
})

var _ = BeforeEach(func(done Done) {
	apid.Initialize(factory.DefaultServicesFactory())

	config = apid.Config()

	var err error
	tmpDir, err = ioutil.TempDir("", "api_test")
	Expect(err).NotTo(HaveOccurred())
	config.Set("local_storage_path", tmpDir)

	config.Set(configProxyServerBaseURI, dummyConfigValue)
	config.Set(configSnapServerBaseURI, dummyConfigValue)
	config.Set(configChangeServerBaseURI, dummyConfigValue)
	config.Set(configSnapshotProtocol, "json")
	config.Set(configPollInterval, 10*time.Millisecond)

	config.Set(configName, "testhost")
	config.Set(configApidClusterId, "bootstrap")
	config.Set(configConsumerKey, "XXXXXXX")
	config.Set(configConsumerSecret, "YYYYYYY")

	block = "0"
	log = apid.Log()

	_initPlugin(apid.AllServices())
	close(done)
}, 3)

var _ = AfterEach(func() {
	apid.Events().Close()

	lastSequence = ""

	if wipeDBAferTest {
		_, err := getDB().Exec("DELETE FROM APID_CLUSTER")
		Expect(err).NotTo(HaveOccurred())
		_, err = getDB().Exec("DELETE FROM DATA_SCOPE")
		Expect(err).NotTo(HaveOccurred())

		db, err := dataService.DB()
		Expect(err).NotTo(HaveOccurred())
		_, err = db.Exec("DELETE FROM APID")
		Expect(err).NotTo(HaveOccurred())
	}
	wipeDBAferTest = true
})

var _ = AfterSuite(func() {
	apid.Events().Close()
	if testServer != nil {
		testServer.Close()
	}
	os.RemoveAll(tmpDir)
})

func TestApigeeSync(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "ApigeeSync Suite")
}
<|endoftext|>


<commit_before>package timeparser

import (
	"fmt"
	"testing"
	"time"

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

func TestParseAtTime_Empty(t *testing.T) {
	got, err := ParseAtTime("")
	if assert.NoError(t, err) {
		expected := time.Now()
		gy, gm, gd := got.Date()
		gh, _, _ := got.Clock()
		ey, em, ed := expected.Date()
		eh, _, _ := expected.Clock()

		assert.Exactly(t, gy, ey)
		assert.Exactly(t, gm, em)
		assert.Exactly(t, gd, ed)
		assert.Exactly(t, gh, eh)
	}
}

func TestParseAtTime_UnixTime(t *testing.T) {
	got, err := ParseAtTime("1444508126")
	if assert.NoError(t, err) {
		expected := time.Unix(1444508126, 0)
		assert.Exactly(t, expected, got)
	}
}

func TestParseAtTime_CurrentTime(t *testing.T) {
	got, err := ParseAtTime("now")
	if assert.NoError(t, err) {
		expected := time.Now()
		gy, gm, gd := got.Date()
		gh, _, _ := got.Clock()
		ey, em, ed := expected.Date()
		eh, _, _ := expected.Clock()

		assert.Exactly(t, gy, ey)
		assert.Exactly(t, gm, em)
		assert.Exactly(t, gd, ed)
		assert.Exactly(t, gh, eh)
	}
}

func TestParseAtTime_RelativePlus(t *testing.T) {
	got, err := ParseAtTime("now+3d")
	if assert.NoError(t, err) {
		expected := time.Now().AddDate(0, 0, 3)
		gy, gm, gd := got.Date()
		gh, _, _ := got.Clock()
		ey, em, ed := expected.Date()
		eh, _, _ := expected.Clock()

		assert.Exactly(t, gy, ey)
		assert.Exactly(t, gm, em)
		assert.Exactly(t, gd, ed)
		assert.Exactly(t, gh, eh)
	}
}

func TestParseAtTime_RelativeMinus(t *testing.T) {
	got, err := ParseAtTime("now-30d")
	if assert.NoError(t, err) {
		expected := time.Now().AddDate(0, 0, -30)
		gy, gm, gd := got.Date()
		gh, _, _ := got.Clock()
		ey, em, ed := expected.Date()
		eh, _, _ := expected.Clock()

		assert.Exactly(t, gy, ey)
		assert.Exactly(t, gm, em)
		assert.Exactly(t, gd, ed)
		assert.Exactly(t, gh, eh)
	}
}

func TestParseAtTime_Absolute(t *testing.T) {
	got, err := ParseAtTime("19:22_20161010")
	if assert.NoError(t, err) {
		expected := time.Date(2016, 10, 10, 19, 22, 0, 0, time.UTC)
		assert.Exactly(t, expected, got)
	}
}

type parseOffsetTest struct {
	offset   string
	duration time.Duration
}

var parseOffsetTests = []parseOffsetTest{
	{"", time.Duration(0)},
	{"-", time.Duration(0)},
	{"+", time.Duration(0)},
	{"10days", time.Duration(10 * 24 * time.Hour)},
	{"0days", time.Duration(0)},
	{"-10days", time.Duration(-10 * 24 * time.Hour)},
	{"5seconds", time.Duration(5 * time.Second)},
	{"5minutes", time.Duration(5 * time.Minute)},
	{"5hours", time.Duration(5 * time.Hour)},
	{"5weeks", time.Duration(5 * 7 * 24 * time.Hour)},
	{"1month", time.Duration(30 * 24 * time.Hour)},
	{"2months", time.Duration(60 * 24 * time.Hour)},
	{"12months", time.Duration(360 * 24 * time.Hour)},
	{"1year", time.Duration(365 * 24 * time.Hour)},
	{"2years", time.Duration(730 * 24 * time.Hour)},
}

func TestParseTimeOffset(t *testing.T) {
	for i, test := range parseOffsetTests {
		got, err := parseTimeOffset(test.offset)
		if assert.NoError(t, err) {
			assert.Exactly(t, test.duration, got, fmt.Sprintf("#%d", i))
		}
	}
}
<commit_msg>Remove assert from lib/timeparser<commit_after>package timeparser

import (
	"testing"
	"time"
)

func TestParseAtTime_Empty(t *testing.T) {
	got, err := ParseAtTime("")
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	TestTimeNearlyEqual(t, got, time.Now())
}

func TestParseAtTime_UnixTime(t *testing.T) {
	got, err := ParseAtTime("100")
	if err != nil {
		t.Fatalf("err: %s", err)
	}
	if got != time.Unix(100, 0) {
		t.Fatalf("\nExpected: %+v\nActual:   %+v", time.Unix(100, 0), got)
	}
}

func TestParseAtTime_CurrentTime(t *testing.T) {
	got, err := ParseAtTime("now")
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	TestTimeNearlyEqual(t, got, time.Now())
}

func TestParseAtTime_RelativePlus(t *testing.T) {
	got, err := ParseAtTime("now+3d")
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	TestTimeNearlyEqual(t, got, time.Now().AddDate(0, 0, 3))
}

func TestParseAtTime_RelativeMinus(t *testing.T) {
	got, err := ParseAtTime("now-30d")
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	TestTimeNearlyEqual(t, got, time.Now().AddDate(0, 0, -30))
}

func TestParseAtTime_Absolute(t *testing.T) {
	got, err := ParseAtTime("19:22_20161010")
	if err != nil {
		t.Fatalf("err: %s", err)
	}

	expected := time.Date(2016, 10, 10, 19, 22, 0, 0, time.UTC)
	if expected != got {
		t.Fatalf("\nExpected: %+v\nActual:   %+v", expected, got)
	}
}

var parseOffsetTests = []struct {
	offset   string
	duration time.Duration
}{
	{"", time.Duration(0)},
	{"-", time.Duration(0)},
	{"+", time.Duration(0)},
	{"10days", time.Duration(10 * 24 * time.Hour)},
	{"0days", time.Duration(0)},
	{"-10days", time.Duration(-10 * 24 * time.Hour)},
	{"5seconds", time.Duration(5 * time.Second)},
	{"5minutes", time.Duration(5 * time.Minute)},
	{"5hours", time.Duration(5 * time.Hour)},
	{"5weeks", time.Duration(5 * 7 * 24 * time.Hour)},
	{"1month", time.Duration(30 * 24 * time.Hour)},
	{"2months", time.Duration(60 * 24 * time.Hour)},
	{"12months", time.Duration(360 * 24 * time.Hour)},
	{"1year", time.Duration(365 * 24 * time.Hour)},
	{"2years", time.Duration(730 * 24 * time.Hour)},
}

func TestParseTimeOffset(t *testing.T) {
	for i, tc := range parseOffsetTests {
		got, err := parseTimeOffset(tc.offset)
		if err != nil {
			t.Fatalf("err: %s", err)
		}
		if tc.duration != got {
			t.Fatalf("\nExpected: %+v\nActual:   %+v (#%d)", tc.duration, got, i)
		}
	}
}
<|endoftext|>


<commit_before>package rest

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"strings"
	"text/template"
	"time"
)

// TODO Future improvements:
// * support %{strftime}t ?
// * support %{<header>}o to print headers

// AccessLogFormat defines the format of the access log record.
// This implementation is a subset of Apache mod_log_config.
// (See http://httpd.apache.org/docs/2.0/mod/mod_log_config.html)
//
//   %b content length in bytes, - if 0
//   %B content length in bytes
//   %D response elapsed time in microseconds
//   %h remote address
//   %H server protocol
//   %l identd logname, not supported, -
//   %m http method
//   %P process id
//   %q query string
//   %r first line of the request
//   %s status code
//   %S status code preceeded by a terminal color
//   %t time of the request
//   %T response elapsed time in seconds, 3 decimals
//   %u remote user, - if missing
//   %{User-Agent}i user agent, - if missing
//   %{Referer}i referer, - is missing
//
// Some predefined formats are provided as contants.
type AccessLogFormat string

const (
	// CommonLogFormat is the Common Log Format (CLF).
	CommonLogFormat = "%h %l %u %t \"%r\" %s %b"

	// CombinedLogFormat is the NCSA extended/combined log format.
	CombinedLogFormat = "%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-Agent}i\""

	// DefaultLogFormat is the default format, colored output and response time, convenient for development.
	DefaultLogFormat = "%t %S\033[0m \033[36;1m%Dμs\033[0m \"%r\" \033[1;30m%u \"%{User-Agent}i\"\033[0m"
)

// AccessLogApacheMiddleware produces the access log following a format inspired by Apache
// mod_log_config. It depends on TimerMiddleware and RecorderMiddleware that should be in the wrapped
// middlewares. It also uses request.Env["REMOTE_USER"].(string) set by the auth middlewares.
type AccessLogApacheMiddleware struct {

	// Logger points to the logger object used by this middleware, it defaults to
	// log.New(os.Stderr, "", 0).
	Logger *log.Logger

	// Format defines the format of the access log record. See AccessLogFormat for the details.
	// It defaults to DefaultLogFormat.
	Format AccessLogFormat

	textTemplate *template.Template
}

// MiddlewareFunc makes AccessLogApacheMiddleware implement the Middleware interface.
func (mw *AccessLogApacheMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc {

	// set the default Logger
	if mw.Logger == nil {
		mw.Logger = log.New(os.Stderr, "", 0)
	}

	// set default format
	if mw.Format == "" {
		mw.Format = DefaultLogFormat
	}

	mw.convertFormat()

	return func(w ResponseWriter, r *Request) {

		// call the handler
		h(w, r)

		util := &accessLogUtil{w, r}

		mw.Logger.Print(mw.executeTextTemplate(util))
	}
}

var apacheAdapter = strings.NewReplacer(
	"%b", "{{.BytesWritten | dashIf0}}",
	"%B", "{{.BytesWritten}}",
	"%D", "{{.ResponseTime | microseconds}}",
	"%h", "{{.ApacheRemoteAddr}}",
	"%H", "{{.R.Proto}}",
	"%l", "-",
	"%m", "{{.R.Method}}",
	"%P", "{{.Pid}}",
	"%q", "{{.ApacheQueryString}}",
	"%r", "{{.R.Method}} {{.R.URL.RequestURI}} {{.R.Proto}}",
	"%s", "{{.StatusCode}}",
	"%S", "\033[{{.StatusCode | statusCodeColor}}m{{.StatusCode}}",
	"%t", "{{if .StartTime}}{{.StartTime.Format \"02/Jan/2006:15:04:05 -0700\"}}{{end}}",
	"%T", "{{if .ResponseTime}}{{.ResponseTime.Seconds | printf \"%.3f\"}}{{end}}",
	"%u", "{{.RemoteUser | dashIfEmptyStr}}",
	"%{User-Agent}i", "{{.R.UserAgent | dashIfEmptyStr}}",
	"%{Referer}i", "{{.R.Referer | dashIfEmptyStr}}",
)

// Convert the Apache access log format into a text/template
func (mw *AccessLogApacheMiddleware) convertFormat() {

	tmplText := apacheAdapter.Replace(string(mw.Format))

	funcMap := template.FuncMap{
		"dashIfEmptyStr": func(value string) string {
			if value == "" {
				return "-"
			}
			return value
		},
		"dashIf0": func(value int64) string {
			if value == 0 {
				return "-"
			}
			return fmt.Sprintf("%d", value)
		},
		"microseconds": func(dur *time.Duration) string {
			return fmt.Sprintf("%d", dur.Nanoseconds()/1000)
		},
		"statusCodeColor": func(statusCode int) string {
			if statusCode >= 400 && statusCode < 500 {
				return "1;33"
			} else if statusCode >= 500 {
				return "0;31"
			}
			return "0;32"
		},
	}

	var err error
	mw.textTemplate, err = template.New("accessLog").Funcs(funcMap).Parse(tmplText)
	if err != nil {
		panic(err)
	}
}

// Execute the text template with the data derived from the request, and return a string.
func (mw *AccessLogApacheMiddleware) executeTextTemplate(util *accessLogUtil) string {
	buf := bytes.NewBufferString("")
	err := mw.textTemplate.Execute(buf, util)
	if err != nil {
		panic(err)
	}
	return buf.String()
}

// accessLogUtil provides a collection of utility functions that devrive data from the Request object.
// This object is used to provide data to the Apache Style template and the the JSON log record.
type accessLogUtil struct {
	W ResponseWriter
	R *Request
}

// As stored by the auth middlewares.
func (u *accessLogUtil) RemoteUser() string {
	if u.R.Env["REMOTE_USER"] != nil {
		return u.R.Env["REMOTE_USER"].(string)
	}
	return ""
}

// If qs exists then return it with a leadin "?", apache log style.
func (u *accessLogUtil) ApacheQueryString() string {
	if u.R.URL.RawQuery != "" {
		return "?" + u.R.URL.RawQuery
	}
	return ""
}

// When the request entered the timer middleware.
func (u *accessLogUtil) StartTime() *time.Time {
	if u.R.Env["START_TIME"] != nil {
		return u.R.Env["START_TIME"].(*time.Time)
	}
	return nil
}

// If remoteAddr is set then return is without the port number, apache log style.
func (u *accessLogUtil) ApacheRemoteAddr() string {
	remoteAddr := u.R.RemoteAddr
	if remoteAddr != "" {
		parts := strings.SplitN(remoteAddr, ":", 2)
		return parts[0]
	}
	return ""
}

// As recorded by the recorder middleware.
func (u *accessLogUtil) StatusCode() int {
	if u.R.Env["STATUS_CODE"] != nil {
		return u.R.Env["STATUS_CODE"].(int)
	}
	return 0
}

// As mesured by the timer middleware.
func (u *accessLogUtil) ResponseTime() *time.Duration {
	if u.R.Env["ELAPSED_TIME"] != nil {
		return u.R.Env["ELAPSED_TIME"].(*time.Duration)
	}
	return nil
}

// Process id.
func (u *accessLogUtil) Pid() int {
	return os.Getpid()
}

// As recorded by the recorder middleware.
func (u *accessLogUtil) BytesWritten() int64 {
	if u.R.Env["BYTES_WRITTEN"] != nil {
		return u.R.Env["BYTES_WRITTEN"].(int64)
	}
	return 0
}
<commit_msg>Use net.SplitHostPort so ipv6 addresses get parsed properly<commit_after>package rest

import (
	"bytes"
	"fmt"
	"log"
	"net"
	"os"
	"strings"
	"text/template"
	"time"
)

// TODO Future improvements:
// * support %{strftime}t ?
// * support %{<header>}o to print headers

// AccessLogFormat defines the format of the access log record.
// This implementation is a subset of Apache mod_log_config.
// (See http://httpd.apache.org/docs/2.0/mod/mod_log_config.html)
//
//   %b content length in bytes, - if 0
//   %B content length in bytes
//   %D response elapsed time in microseconds
//   %h remote address
//   %H server protocol
//   %l identd logname, not supported, -
//   %m http method
//   %P process id
//   %q query string
//   %r first line of the request
//   %s status code
//   %S status code preceeded by a terminal color
//   %t time of the request
//   %T response elapsed time in seconds, 3 decimals
//   %u remote user, - if missing
//   %{User-Agent}i user agent, - if missing
//   %{Referer}i referer, - is missing
//
// Some predefined formats are provided as contants.
type AccessLogFormat string

const (
	// CommonLogFormat is the Common Log Format (CLF).
	CommonLogFormat = "%h %l %u %t \"%r\" %s %b"

	// CombinedLogFormat is the NCSA extended/combined log format.
	CombinedLogFormat = "%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-Agent}i\""

	// DefaultLogFormat is the default format, colored output and response time, convenient for development.
	DefaultLogFormat = "%t %S\033[0m \033[36;1m%Dμs\033[0m \"%r\" \033[1;30m%u \"%{User-Agent}i\"\033[0m"
)

// AccessLogApacheMiddleware produces the access log following a format inspired by Apache
// mod_log_config. It depends on TimerMiddleware and RecorderMiddleware that should be in the wrapped
// middlewares. It also uses request.Env["REMOTE_USER"].(string) set by the auth middlewares.
type AccessLogApacheMiddleware struct {

	// Logger points to the logger object used by this middleware, it defaults to
	// log.New(os.Stderr, "", 0).
	Logger *log.Logger

	// Format defines the format of the access log record. See AccessLogFormat for the details.
	// It defaults to DefaultLogFormat.
	Format AccessLogFormat

	textTemplate *template.Template
}

// MiddlewareFunc makes AccessLogApacheMiddleware implement the Middleware interface.
func (mw *AccessLogApacheMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc {

	// set the default Logger
	if mw.Logger == nil {
		mw.Logger = log.New(os.Stderr, "", 0)
	}

	// set default format
	if mw.Format == "" {
		mw.Format = DefaultLogFormat
	}

	mw.convertFormat()

	return func(w ResponseWriter, r *Request) {

		// call the handler
		h(w, r)

		util := &accessLogUtil{w, r}

		mw.Logger.Print(mw.executeTextTemplate(util))
	}
}

var apacheAdapter = strings.NewReplacer(
	"%b", "{{.BytesWritten | dashIf0}}",
	"%B", "{{.BytesWritten}}",
	"%D", "{{.ResponseTime | microseconds}}",
	"%h", "{{.ApacheRemoteAddr}}",
	"%H", "{{.R.Proto}}",
	"%l", "-",
	"%m", "{{.R.Method}}",
	"%P", "{{.Pid}}",
	"%q", "{{.ApacheQueryString}}",
	"%r", "{{.R.Method}} {{.R.URL.RequestURI}} {{.R.Proto}}",
	"%s", "{{.StatusCode}}",
	"%S", "\033[{{.StatusCode | statusCodeColor}}m{{.StatusCode}}",
	"%t", "{{if .StartTime}}{{.StartTime.Format \"02/Jan/2006:15:04:05 -0700\"}}{{end}}",
	"%T", "{{if .ResponseTime}}{{.ResponseTime.Seconds | printf \"%.3f\"}}{{end}}",
	"%u", "{{.RemoteUser | dashIfEmptyStr}}",
	"%{User-Agent}i", "{{.R.UserAgent | dashIfEmptyStr}}",
	"%{Referer}i", "{{.R.Referer | dashIfEmptyStr}}",
)

// Convert the Apache access log format into a text/template
func (mw *AccessLogApacheMiddleware) convertFormat() {

	tmplText := apacheAdapter.Replace(string(mw.Format))

	funcMap := template.FuncMap{
		"dashIfEmptyStr": func(value string) string {
			if value == "" {
				return "-"
			}
			return value
		},
		"dashIf0": func(value int64) string {
			if value == 0 {
				return "-"
			}
			return fmt.Sprintf("%d", value)
		},
		"microseconds": func(dur *time.Duration) string {
			return fmt.Sprintf("%d", dur.Nanoseconds()/1000)
		},
		"statusCodeColor": func(statusCode int) string {
			if statusCode >= 400 && statusCode < 500 {
				return "1;33"
			} else if statusCode >= 500 {
				return "0;31"
			}
			return "0;32"
		},
	}

	var err error
	mw.textTemplate, err = template.New("accessLog").Funcs(funcMap).Parse(tmplText)
	if err != nil {
		panic(err)
	}
}

// Execute the text template with the data derived from the request, and return a string.
func (mw *AccessLogApacheMiddleware) executeTextTemplate(util *accessLogUtil) string {
	buf := bytes.NewBufferString("")
	err := mw.textTemplate.Execute(buf, util)
	if err != nil {
		panic(err)
	}
	return buf.String()
}

// accessLogUtil provides a collection of utility functions that devrive data from the Request object.
// This object is used to provide data to the Apache Style template and the the JSON log record.
type accessLogUtil struct {
	W ResponseWriter
	R *Request
}

// As stored by the auth middlewares.
func (u *accessLogUtil) RemoteUser() string {
	if u.R.Env["REMOTE_USER"] != nil {
		return u.R.Env["REMOTE_USER"].(string)
	}
	return ""
}

// If qs exists then return it with a leadin "?", apache log style.
func (u *accessLogUtil) ApacheQueryString() string {
	if u.R.URL.RawQuery != "" {
		return "?" + u.R.URL.RawQuery
	}
	return ""
}

// When the request entered the timer middleware.
func (u *accessLogUtil) StartTime() *time.Time {
	if u.R.Env["START_TIME"] != nil {
		return u.R.Env["START_TIME"].(*time.Time)
	}
	return nil
}

// If remoteAddr is set then return is without the port number, apache log style.
func (u *accessLogUtil) ApacheRemoteAddr() string {
	remoteAddr := u.R.RemoteAddr
	if remoteAddr != "" {
		if ip, _, err := net.SplitHostPort(remoteAddr); err == nil {
			return ip
		}
	}
	return ""
}

// As recorded by the recorder middleware.
func (u *accessLogUtil) StatusCode() int {
	if u.R.Env["STATUS_CODE"] != nil {
		return u.R.Env["STATUS_CODE"].(int)
	}
	return 0
}

// As mesured by the timer middleware.
func (u *accessLogUtil) ResponseTime() *time.Duration {
	if u.R.Env["ELAPSED_TIME"] != nil {
		return u.R.Env["ELAPSED_TIME"].(*time.Duration)
	}
	return nil
}

// Process id.
func (u *accessLogUtil) Pid() int {
	return os.Getpid()
}

// As recorded by the recorder middleware.
func (u *accessLogUtil) BytesWritten() int64 {
	if u.R.Env["BYTES_WRITTEN"] != nil {
		return u.R.Env["BYTES_WRITTEN"].(int64)
	}
	return 0
}
<|endoftext|>


<commit_before>package detect

import (
	"errors"
	"path"

	"../fileutil"
)

/*
	detect - guess the project type from files present
*/

type Project struct {
	Id       string
	Commands Commands
	Detect   func(string) bool
}

type Commands map[string]string

var ProjectTypes = []*Project{
	&Project{"clojure/leiningen", Commands{"run": "lein run", "test": "lein test"}, clojureLeiningen},
	&Project{"docker/fig", Commands{"run": "fig up"}, dockerFig},
	&Project{"docker/default", Commands{}, dockerDefault},
	&Project{"executable/default", Commands{"run": "{file}"}, executableDefault},
	&Project{"go/default", Commands{"build": "go build {file}", "run": "go build {file} && $(basename {file} .go)"},
		goDefault},
	&Project{"java/maven", Commands{"build": "mvn compile", "test": "mvn compile test"}, javaMaven},
	&Project{"javascript/npm", Commands{}, javascriptNpm},
	&Project{"javascript/meteor", Commands{"run": "meteor"}, javascriptMeteor},
	&Project{"javascript/default", Commands{"run": "node {file}"}, javascriptDefault},
	&Project{"make/default", Commands{"run": "make"}, makeDefault},
	&Project{"procfile/default", Commands{}, procfileDefault},
	&Project{"python/django", Commands{}, pythonDjango},
	&Project{"python/default", Commands{"run": "python {file}"}, pythonDefault},
	&Project{"ruby/rails", Commands{"run": "rails server", "test": "bundle exec rake test"}, rubyRails},
	&Project{"ruby/rake", Commands{"run": "rake"}, rubyRake},
	&Project{"ruby/default", Commands{"run": "ruby {file}"}, rubyDefault},
}

func Detect(file string) (*Project, error) {
	for _, project := range ProjectTypes {
		if project.Detect(file) {
			return project, nil
		}
	}

	return nil, errors.New("no project matches")
}

func DetectAll(file string) []*Project {
	projects := make([]*Project, 0, len(ProjectTypes))

	for _, project := range ProjectTypes {
		if project.Detect(file) {
			n := len(projects)
			projects = projects[0 : n+1]
			projects[n] = project
		}
	}

	return projects
}

func matchingFileOrDir(file string, pattern string) bool {
	if fileutil.IsFile(file) {
		_, f := path.Split(file)
		isMatch, _ := path.Match(pattern, f)
		return isMatch
	} else {
		return fileutil.MatchExists(path.Join(path.Dir(file), pattern))
	}
}

func hasFile(fileOrDir string, file string) bool {
	return fileutil.IsFile(fileutil.Join(fileOrDir, file))
}

func clojureLeiningen(file string) bool {
	return hasFile(file, "project.clj")
}

func dockerFig(file string) bool {
	return hasFile(file, "fig.yml")
}

func dockerDefault(file string) bool {
	return hasFile(file, "Dockerfile")
}

func executableDefault(file string) bool {
	return fileutil.IsExecutable(file)
}

func goDefault(file string) bool {
	return matchingFileOrDir(file, "*.go")
}

func javaMaven(file string) bool {
	return hasFile(file, "pom.xml")
}

func javascriptNpm(file string) bool {
	return hasFile(file, "package.json")
}

func javascriptMeteor(file string) bool {
	return hasFile(file, ".meteor/.id")
}

func javascriptDefault(file string) bool {
	return matchingFileOrDir(file, "*.js")
}

func makeDefault(file string) bool {
	return hasFile(file, "Makefile")
}

func procfileDefault(file string) bool {
	return hasFile(file, "Procfile")
}

func pythonDjango(file string) bool {
	return hasFile(file, "manage.py")
}

func pythonDefault(file string) bool {
	return matchingFileOrDir(file, "*.py")
}

func rubyRails(file string) bool {
	return hasFile(file, "bin/rails")
}

func rubyRake(file string) bool {
	return hasFile(file, "Rakefile")
}

func rubyDefault(file string) bool {
	return matchingFileOrDir(file, "*.rb")
}
<commit_msg>detect procfiles and makefiles later.<commit_after>package detect

import (
	"errors"
	"path"

	"../fileutil"
)

/*
	detect - guess the project type from files present
*/

type Project struct {
	Id       string
	Commands Commands
	Detect   func(string) bool
}

type Commands map[string]string

var ProjectTypes = []*Project{
	&Project{"clojure/leiningen", Commands{"run": "lein run", "test": "lein test"}, clojureLeiningen},
	&Project{"docker/fig", Commands{"run": "fig up"}, dockerFig},
	&Project{"docker/default", Commands{}, dockerDefault},
	&Project{"executable", Commands{"run": "{file}"}, executableDefault},
	&Project{"go/default", Commands{"build": "go build {file}", "run": "go build {file} && $(basename {file} .go)"},
		goDefault},
	&Project{"java/maven", Commands{"build": "mvn compile", "test": "mvn compile test"}, javaMaven},
	&Project{"javascript/npm", Commands{}, javascriptNpm},
	&Project{"javascript/meteor", Commands{"run": "meteor"}, javascriptMeteor},
	&Project{"javascript/default", Commands{"run": "node {file}"}, javascriptDefault},
	&Project{"python/django", Commands{}, pythonDjango},
	&Project{"python/default", Commands{"run": "python {file}"}, pythonDefault},
	&Project{"ruby/rails", Commands{"run": "rails server", "test": "bundle exec rake test"}, rubyRails},
	&Project{"ruby/rake", Commands{"run": "rake"}, rubyRake},
	&Project{"ruby/default", Commands{"run": "ruby {file}"}, rubyDefault},
	&Project{"make", Commands{"run": "make"}, makeDefault},
	&Project{"procfile", Commands{}, procfileDefault},
}

func Detect(file string) (*Project, error) {
	for _, project := range ProjectTypes {
		if project.Detect(file) {
			return project, nil
		}
	}

	return nil, errors.New("no project matches")
}

func DetectAll(file string) []*Project {
	projects := make([]*Project, 0, len(ProjectTypes))

	for _, project := range ProjectTypes {
		if project.Detect(file) {
			n := len(projects)
			projects = projects[0 : n+1]
			projects[n] = project
		}
	}

	return projects
}

func matchingFileOrDir(file string, pattern string) bool {
	if fileutil.IsFile(file) {
		_, f := path.Split(file)
		isMatch, _ := path.Match(pattern, f)
		return isMatch
	} else {
		return fileutil.MatchExists(path.Join(path.Dir(file), pattern))
	}
}

func hasFile(fileOrDir string, file string) bool {
	return fileutil.IsFile(fileutil.Join(fileOrDir, file))
}

func clojureLeiningen(file string) bool {
	return hasFile(file, "project.clj")
}

func dockerFig(file string) bool {
	return hasFile(file, "fig.yml")
}

func dockerDefault(file string) bool {
	return hasFile(file, "Dockerfile")
}

func executableDefault(file string) bool {
	return fileutil.IsExecutable(file)
}

func goDefault(file string) bool {
	return matchingFileOrDir(file, "*.go")
}

func javaMaven(file string) bool {
	return hasFile(file, "pom.xml")
}

func javascriptNpm(file string) bool {
	return hasFile(file, "package.json")
}

func javascriptMeteor(file string) bool {
	return hasFile(file, ".meteor/.id")
}

func javascriptDefault(file string) bool {
	return matchingFileOrDir(file, "*.js")
}

func makeDefault(file string) bool {
	return hasFile(file, "Makefile")
}

func procfileDefault(file string) bool {
	return hasFile(file, "Procfile")
}

func pythonDjango(file string) bool {
	return hasFile(file, "manage.py")
}

func pythonDefault(file string) bool {
	return matchingFileOrDir(file, "*.py")
}

func rubyRails(file string) bool {
	return hasFile(file, "bin/rails")
}

func rubyRake(file string) bool {
	return hasFile(file, "Rakefile")
}

func rubyDefault(file string) bool {
	return matchingFileOrDir(file, "*.rb")
}
<|endoftext|>


<commit_before>package data_test

import (
	"fmt"

	"github.com/dailyburn/ratchet/data"
)

type testStruct struct {
	A int
	B int
}

func ExampleNewJSON() {
	t := testStruct{A: 1, B: 2}

	d, _ := data.NewJSON(t)

	fmt.Println(string(d))
	// Output: {"A":1,"B":2}
}

func ExampleParseJSON() {
	d := []byte(`{"A":1,"B":2}`)
	t := testStruct{}
	data.ParseJSON(d, &t)

	fmt.Println(fmt.Sprintf("%+v", t))
	// Output: {A:1 B:2}
}

func ExampleObjectsFromJSON() {
	d := []byte(`[{"One":1},
		      {"Two":2}]`)

	objects, _ := data.ObjectsFromJSON(d)

	fmt.Println(fmt.Sprintf("%+v", objects))
	// Output: [map[One:1] map[Two:2]]
}

func ExampleJSONFromHeaderAndRows() {
	header := []string{"A", "B", "C"}
	rows := [][]interface{}{
		[]interface{}{1, 2, 3},
		[]interface{}{4, 5, 6},
	}

	d := data.JSONFromHeaderAndRows(header, rows)

	fmt.Println(fmt.Sprintf("%+v", string(d)))
	// Output: [{"A":1,"B":2,"C":3},{"A":4,"B":5,"C":6}]
}
<commit_msg>Fixes unrelated but existing failing test<commit_after>package data_test

import (
	"fmt"

	"github.com/dailyburn/ratchet/data"
)

type testStruct struct {
	A int
	B int
}

func ExampleNewJSON() {
	t := testStruct{A: 1, B: 2}

	d, _ := data.NewJSON(t)

	fmt.Println(string(d))
	// Output: {"A":1,"B":2}
}

func ExampleParseJSON() {
	d := []byte(`{"A":1,"B":2}`)
	t := testStruct{}
	data.ParseJSON(d, &t)

	fmt.Println(fmt.Sprintf("%+v", t))
	// Output: {A:1 B:2}
}

func ExampleObjectsFromJSON() {
	d := []byte(`[{"One":1},
		      {"Two":2}]`)

	objects, _ := data.ObjectsFromJSON(d)

	fmt.Println(fmt.Sprintf("%+v", objects))
	// Output: [map[One:1] map[Two:2]]
}

func ExampleJSONFromHeaderAndRows() {
	header := []string{"A", "B", "C"}
	rows := [][]interface{}{
		[]interface{}{1, 2, 3},
		[]interface{}{4, 5, 6},
	}

	d, _ := data.JSONFromHeaderAndRows(header, rows)

	fmt.Println(fmt.Sprintf("%+v", string(d)))
	// Output: [{"A":1,"B":2,"C":3},{"A":4,"B":5,"C":6}]
}
<|endoftext|>


<commit_before>package kymahelm

import (
	"fmt"
	"log"
	"strings"

	"k8s.io/helm/pkg/chartutil"
	"k8s.io/helm/pkg/helm"
	"k8s.io/helm/pkg/proto/hapi/release"
	rls "k8s.io/helm/pkg/proto/hapi/services"
)

// ClientInterface .
type ClientInterface interface {
	ListReleases() (*rls.ListReleasesResponse, error)
	ReleaseStatus(rname string) (string, error)
	InstallReleaseFromChart(chartdir, ns, releaseName, overrides string) (*rls.InstallReleaseResponse, error)
	InstallRelease(chartdir, ns, releasename, overrides string) (*rls.InstallReleaseResponse, error)
	InstallReleaseWithoutWait(chartdir, ns, releasename, overrides string) (*rls.InstallReleaseResponse, error)
	UpgradeRelease(chartDir, releaseName, overrides string) (*rls.UpdateReleaseResponse, error)
	DeleteRelease(releaseName string) (*rls.UninstallReleaseResponse, error)
	PrintRelease(release *release.Release)
}

// Client .
type Client struct {
	helm *helm.Client
}

// NewClient .
func NewClient(host string) *Client {
	return &Client{
		helm: helm.NewClient(helm.Host(host)),
	}
}

// ListReleases .
func (hc *Client) ListReleases() (*rls.ListReleasesResponse, error) {
	return hc.helm.ListReleases()
}

//ReleaseStatus returns roughly-formatted Release status (columns are separated with blanks but not adjusted)
func (hc *Client) ReleaseStatus(rname string) (string, error) {
	status, err := hc.helm.ReleaseStatus(rname)
	if err != nil {
		return "", err
	}
	statusStr := fmt.Sprintf("%+v\n", status)
	return strings.Replace(statusStr, `\n`, "\n", -1), nil
}

// InstallReleaseFromChart .
func (hc *Client) InstallReleaseFromChart(chartdir, ns, releaseName, overrides string) (*rls.InstallReleaseResponse, error) {
	chart, err := chartutil.Load(chartdir)

	if err != nil {
		return nil, err
	}

	return hc.helm.InstallReleaseFromChart(
		chart,
		ns,
		helm.ReleaseName(string(releaseName)),
		helm.ValueOverrides([]byte(overrides)),
		helm.InstallWait(true),
		helm.InstallTimeout(3600),
	)
}

// InstallRelease .
func (hc *Client) InstallRelease(chartdir, ns, releasename, overrides string) (*rls.InstallReleaseResponse, error) {
	return hc.helm.InstallRelease(
		chartdir,
		ns,
		helm.ReleaseName(releasename),
		helm.ValueOverrides([]byte(overrides)),
		helm.InstallWait(true),
		helm.InstallTimeout(3600),
	)
}

// InstallReleaseWithoutWait .
func (hc *Client) InstallReleaseWithoutWait(chartdir, ns, releasename, overrides string) (*rls.InstallReleaseResponse, error) {
	return hc.helm.InstallRelease(
		chartdir,
		ns,
		helm.ReleaseName(releasename),
		helm.ValueOverrides([]byte(overrides)),
		helm.InstallWait(false),
		helm.InstallTimeout(3600),
	)
}

// UpgradeRelease .
func (hc *Client) UpgradeRelease(chartDir, releaseName, overrides string) (*rls.UpdateReleaseResponse, error) {
	return hc.helm.UpdateRelease(
		releaseName,
		chartDir,
		helm.UpdateValueOverrides([]byte(overrides)),
		helm.ReuseValues(true),
		helm.UpgradeTimeout(3600),
	)
}

// DeleteRelease .
func (hc *Client) DeleteRelease(releaseName string) (*rls.UninstallReleaseResponse, error) {
	return hc.helm.DeleteRelease(
		releaseName,
		helm.DeletePurge(true),
		helm.DeleteTimeout(3600),
	)
}

//PrintRelease .
func (hc *Client) PrintRelease(release *release.Release) {
	log.Printf("Name: %s", release.Name)
	log.Printf("Namespace: %s", release.Namespace)
	log.Printf("Version: %d", release.Version)
	log.Printf("Status: %s", release.Info.Status.Code)
	log.Printf("Description: %s", release.Info.Description)
}
<commit_msg>Installer update action not using reuse values (#1063)<commit_after>package kymahelm

import (
	"fmt"
	"log"
	"strings"

	"k8s.io/helm/pkg/chartutil"
	"k8s.io/helm/pkg/helm"
	"k8s.io/helm/pkg/proto/hapi/release"
	rls "k8s.io/helm/pkg/proto/hapi/services"
)

// ClientInterface .
type ClientInterface interface {
	ListReleases() (*rls.ListReleasesResponse, error)
	ReleaseStatus(rname string) (string, error)
	InstallReleaseFromChart(chartdir, ns, releaseName, overrides string) (*rls.InstallReleaseResponse, error)
	InstallRelease(chartdir, ns, releasename, overrides string) (*rls.InstallReleaseResponse, error)
	InstallReleaseWithoutWait(chartdir, ns, releasename, overrides string) (*rls.InstallReleaseResponse, error)
	UpgradeRelease(chartDir, releaseName, overrides string) (*rls.UpdateReleaseResponse, error)
	DeleteRelease(releaseName string) (*rls.UninstallReleaseResponse, error)
	PrintRelease(release *release.Release)
}

// Client .
type Client struct {
	helm *helm.Client
}

// NewClient .
func NewClient(host string) *Client {
	return &Client{
		helm: helm.NewClient(helm.Host(host)),
	}
}

// ListReleases .
func (hc *Client) ListReleases() (*rls.ListReleasesResponse, error) {
	return hc.helm.ListReleases()
}

//ReleaseStatus returns roughly-formatted Release status (columns are separated with blanks but not adjusted)
func (hc *Client) ReleaseStatus(rname string) (string, error) {
	status, err := hc.helm.ReleaseStatus(rname)
	if err != nil {
		return "", err
	}
	statusStr := fmt.Sprintf("%+v\n", status)
	return strings.Replace(statusStr, `\n`, "\n", -1), nil
}

// InstallReleaseFromChart .
func (hc *Client) InstallReleaseFromChart(chartdir, ns, releaseName, overrides string) (*rls.InstallReleaseResponse, error) {
	chart, err := chartutil.Load(chartdir)

	if err != nil {
		return nil, err
	}

	return hc.helm.InstallReleaseFromChart(
		chart,
		ns,
		helm.ReleaseName(string(releaseName)),
		helm.ValueOverrides([]byte(overrides)),
		helm.InstallWait(true),
		helm.InstallTimeout(3600),
	)
}

// InstallRelease .
func (hc *Client) InstallRelease(chartdir, ns, releasename, overrides string) (*rls.InstallReleaseResponse, error) {
	return hc.helm.InstallRelease(
		chartdir,
		ns,
		helm.ReleaseName(releasename),
		helm.ValueOverrides([]byte(overrides)),
		helm.InstallWait(true),
		helm.InstallTimeout(3600),
	)
}

// InstallReleaseWithoutWait .
func (hc *Client) InstallReleaseWithoutWait(chartdir, ns, releasename, overrides string) (*rls.InstallReleaseResponse, error) {
	return hc.helm.InstallRelease(
		chartdir,
		ns,
		helm.ReleaseName(releasename),
		helm.ValueOverrides([]byte(overrides)),
		helm.InstallWait(false),
		helm.InstallTimeout(3600),
	)
}

// UpgradeRelease .
func (hc *Client) UpgradeRelease(chartDir, releaseName, overrides string) (*rls.UpdateReleaseResponse, error) {
	return hc.helm.UpdateRelease(
		releaseName,
		chartDir,
		helm.UpdateValueOverrides([]byte(overrides)),
		helm.ReuseValues(false),
		helm.UpgradeTimeout(3600),
	)
}

// DeleteRelease .
func (hc *Client) DeleteRelease(releaseName string) (*rls.UninstallReleaseResponse, error) {
	return hc.helm.DeleteRelease(
		releaseName,
		helm.DeletePurge(true),
		helm.DeleteTimeout(3600),
	)
}

//PrintRelease .
func (hc *Client) PrintRelease(release *release.Release) {
	log.Printf("Name: %s", release.Name)
	log.Printf("Namespace: %s", release.Namespace)
	log.Printf("Version: %d", release.Version)
	log.Printf("Status: %s", release.Info.Status.Code)
	log.Printf("Description: %s", release.Info.Description)
}
<|endoftext|>


<commit_before>package client

// TODO implement roster versioning
// TODO implement pre-approval
// TODO handle a roster, that keeps track of presence, the contacts
// who are in it, etc

import (
	"encoding/xml"
	"github.com/davecgh/go-spew/spew"
	"honnef.co/go/xmpp/rfc6120/client"
	"sync"
)

var _ = spew.Dump

type Connection struct {
	*client.Connection
	stanzas            chan client.Stanza
}

}

func Wrap(c *client.Connection) *Connection {
	conn := &Connection{
		Connection: c,
		stanzas:    make(chan client.Stanza, 100),
	}
	go conn.read()
	c.SubscribeStanzas(conn.stanzas)
	return conn
}

func (c *Connection) read() {
	for stanza := range c.stanzas {
		// TODO maybe have a channel for Roster events (roster push)
		// on which to send changes?

		// TODO maybe have a channel for subscription requests?

		switch t := stanza.(type) {
		case *client.IQ:
			if t.Query.Space == "jabber:iq:roster" && t.Type == "set" {
				// TODO should we send this stanza back on the stream?
				// After all the user might be interested in it?

				// TODO check 'from' ("Security Warning:
				// Traditionally, a roster push included no 'from'
				// address")
				c.SendIQReply("", "result", stanza.ID(), nil)
			}
		}
	}
}

type Roster []RosterItem

type RosterItem struct {
	JID  string `xml:"jid,attr"`
	Name string `xml:"name,attr,omitempty"`
	// Groups []string // TODO
	Subscription string `xml:"subscription,attr,omitempty"`
}

type rosterQuery struct {
	XMLName xml.Name    `xml:"jabber:iq:roster query"`
	Item    *RosterItem `xml:"item,omitempty"`
}

func (c *Connection) GetRoster() Roster {
	// TODO implement

	ch, _ := c.SendIQ("", "get", rosterQuery{})
	<-ch

	return nil
}

// AddToRoster adds an item to the roster. If no item with the
// specified JID exists yet, a new one will be created. Otherwise an
// existing one will be updated.
func (c *Connection) AddToRoster(item RosterItem) error {
	ch, _ := c.SendIQ("", "set", rosterQuery{Item: &item})
	// TODO implement error handling
	<-ch
	return nil
}

func (c *Connection) RemoveFromRoster(jid string) error {
	ch, _ := c.SendIQ("", "set", rosterQuery{Item: &RosterItem{
		JID:          jid,
		Subscription: "remove",
	}})
	<-ch
	return nil
	// TODO handle error
}

func (c *Connection) Subscribe(jid string) (cookie string, err error) {
	cookie, err = c.Connection.SendPresence(client.Presence{
		Header: client.Header{
			To:   jid,
			Type: "subscribe",
		},
	})
	return
	// TODO handle error
}

func (c *Connection) Unsubscribe(jid string) (cookie string, err error) {
	cookie, err = c.Connection.SendPresence(client.Presence{
		Header: client.Header{
			To:   jid,
			Type: "unsubscribe",
		},
	})
	return
	// TODO handle error
}

func (c *Connection) ApproveSubscription(jid string) {
	c.Connection.SendPresence(client.Presence{
		Header: client.Header{
			To:   jid,
			Type: "subscribed",
		},
	})
}

func (c *Connection) DenySubscription(jid string) {
	// TODO document that this can also be used to revoke an existing
	// subscription
	c.Connection.SendPresence(client.Presence{
		Header: client.Header{
			To:   jid,
			Type: "unsubscribed",
		},
	})
}

func (c *Connection) SendPresence(p *client.Presence) {
	var pp client.Presence
	if p != nil {
		pp = *p
	}

	xml.NewEncoder(c).Encode(pp)
}

func (c *Connection) BecomeUnavailable(p *client.Presence) {
	var pp client.Presence
	if p != nil {
		pp = *p
	}

	pp.Type = "unavailable"
	pp.Show = ""
	pp.Priority = 0
	// TODO can't be have one global xml encoder?
	xml.NewEncoder(c).Encode(pp)
}

func (c *Connection) SendMessage(typ, to, message string) {
	// TODO support extended items in the mssage
	// TODO if `to` is a bare JID, see if we know about a full JID to
	// use instead
	// TODO actually keep track of JIDs
	// TODO support <thread>
	// TODO support subject

	m := client.Message{
		Header: client.Header{
			From: c.Connection.JID,
			To:   to,
			Type: typ,
		},
		Body: message,
	}

	xml.NewEncoder(c).Encode(m)
}

func (c *Connection) Reply(orig *client.Message, reply string) {
	// TODO threading
	// TODO use bare JID if full JID isn't up to date anymore
	// TODO support subject
	// TODO support extended items
	c.SendMessage(orig.Type, orig.From, reply)
}

// The user's client SHOULD address the initial message in a chat
// session to the bare JID <contact@domainpart> of the contact (rather
// than attempting to guess an appropriate full JID
// <contact@domainpart/resourcepart> based on the <show/>, <status/>,
// or <priority/> value of any presence notifications it might have
// received from the contact). Until and unless the user's client
// receives a reply from the contact, it SHOULD send any further
// messages to the contact's bare JID. The contact's client SHOULD
// address its replies to the user's full JID
// <user@domainpart/resourcepart> as provided in the 'from' address of
// the initial message. Once the user's client receives a reply from
// the contact's full JID, it SHOULD address its subsequent messages
// to the contact's full JID as provided in the 'from' address of the
// contact's replies, thus "locking in" on that full JID. A client
// SHOULD "unlock" after having received a <message/> or <presence/>
// stanza from any other resource controlled by the peer (or a
// presence stanza from the locked resource); as a result, it SHOULD
// address its next message(s) in the chat session to the bare JID of
// the peer (thus "unlocking" the previous "lock") until it receives a
// message from one of the peer's full JIDs.

// When two parties engage in a chat session but do not share presence
// with each other based on a presence subscription, they SHOULD send
// directed presence to each other so that either party can easily
// discover if the peer goes offline during the course of the chat
// session. However, a client MUST provide a way for a user to disable
// such presence sharing globally or to enable it only with particular
// entities. Furthermore, a party SHOULD send directed unavailable
// presence to the peer when it has reason to believe that the chat
// session is over (e.g., if, after some reasonable amount of time, no
// subsequent messages have been exchanged between the parties).
<commit_msg>implement message subscribing<commit_after>package client

// TODO implement roster versioning
// TODO implement pre-approval
// TODO handle a roster, that keeps track of presence, the contacts
// who are in it, etc

import (
	"encoding/xml"
	"github.com/davecgh/go-spew/spew"
	"honnef.co/go/xmpp/rfc6120/client"
	"sync"
)

var _ = spew.Dump

type Connection struct {
	*client.Connection
	stanzas            chan client.Stanza
	messageSubscribers messageSubscribers
}

type messageSubscribers struct {
	sync.RWMutex
	chans []chan<- *client.Message
}

func (s *messageSubscribers) send(stanza *client.Message) {
	s.RLock()
	defer s.RUnlock()
	for _, ch := range s.chans {
		select {
		case ch <- stanza:
		default:
		}
	}
}

func (s *messageSubscribers) subscribe(ch chan<- *client.Message) {
	s.Lock()
	defer s.Unlock()
	s.chans = append(s.chans, ch)
}

func (c *Connection) SubscribeMessages(ch chan<- *client.Message) {
	c.messageSubscribers.subscribe(ch)
}

func Wrap(c *client.Connection) *Connection {
	conn := &Connection{
		Connection: c,
		stanzas:    make(chan client.Stanza, 100),
	}
	go conn.read()
	c.SubscribeStanzas(conn.stanzas)
	return conn
}

func (c *Connection) read() {
	for stanza := range c.stanzas {
		// TODO maybe have a channel for Roster events (roster push)
		// on which to send changes?

		// TODO maybe have a channel for subscription requests?

		switch t := stanza.(type) {
		case *client.IQ:
			if t.Query.Space == "jabber:iq:roster" && t.Type == "set" {
				// TODO should we send this stanza back on the stream?
				// After all the user might be interested in it?

				// TODO check 'from' ("Security Warning:
				// Traditionally, a roster push included no 'from'
				// address")
				c.SendIQReply("", "result", stanza.ID(), nil)
			}
		case *client.Message:
			// TODO track JID etc
			// FIXME what if nobody is listening?
			c.messageSubscribers.send(t)
		}
	}
}

type Roster []RosterItem

type RosterItem struct {
	JID  string `xml:"jid,attr"`
	Name string `xml:"name,attr,omitempty"`
	// Groups []string // TODO
	Subscription string `xml:"subscription,attr,omitempty"`
}

type rosterQuery struct {
	XMLName xml.Name    `xml:"jabber:iq:roster query"`
	Item    *RosterItem `xml:"item,omitempty"`
}

func (c *Connection) GetRoster() Roster {
	// TODO implement

	ch, _ := c.SendIQ("", "get", rosterQuery{})
	<-ch

	return nil
}

// AddToRoster adds an item to the roster. If no item with the
// specified JID exists yet, a new one will be created. Otherwise an
// existing one will be updated.
func (c *Connection) AddToRoster(item RosterItem) error {
	ch, _ := c.SendIQ("", "set", rosterQuery{Item: &item})
	// TODO implement error handling
	<-ch
	return nil
}

func (c *Connection) RemoveFromRoster(jid string) error {
	ch, _ := c.SendIQ("", "set", rosterQuery{Item: &RosterItem{
		JID:          jid,
		Subscription: "remove",
	}})
	<-ch
	return nil
	// TODO handle error
}

func (c *Connection) Subscribe(jid string) (cookie string, err error) {
	cookie, err = c.Connection.SendPresence(client.Presence{
		Header: client.Header{
			To:   jid,
			Type: "subscribe",
		},
	})
	return
	// TODO handle error
}

func (c *Connection) Unsubscribe(jid string) (cookie string, err error) {
	cookie, err = c.Connection.SendPresence(client.Presence{
		Header: client.Header{
			To:   jid,
			Type: "unsubscribe",
		},
	})
	return
	// TODO handle error
}

func (c *Connection) ApproveSubscription(jid string) {
	c.Connection.SendPresence(client.Presence{
		Header: client.Header{
			To:   jid,
			Type: "subscribed",
		},
	})
}

func (c *Connection) DenySubscription(jid string) {
	// TODO document that this can also be used to revoke an existing
	// subscription
	c.Connection.SendPresence(client.Presence{
		Header: client.Header{
			To:   jid,
			Type: "unsubscribed",
		},
	})
}

func (c *Connection) SendPresence(p *client.Presence) {
	var pp client.Presence
	if p != nil {
		pp = *p
	}

	xml.NewEncoder(c).Encode(pp)
}

func (c *Connection) BecomeUnavailable(p *client.Presence) {
	var pp client.Presence
	if p != nil {
		pp = *p
	}

	pp.Type = "unavailable"
	pp.Show = ""
	pp.Priority = 0
	// TODO can't be have one global xml encoder?
	xml.NewEncoder(c).Encode(pp)
}

func (c *Connection) SendMessage(typ, to, message string) {
	// TODO support extended items in the mssage
	// TODO if `to` is a bare JID, see if we know about a full JID to
	// use instead
	// TODO actually keep track of JIDs
	// TODO support <thread>
	// TODO support subject

	m := client.Message{
		Header: client.Header{
			From: c.Connection.JID,
			To:   to,
			Type: typ,
		},
		Body: message,
	}

	xml.NewEncoder(c).Encode(m)
}

func (c *Connection) Reply(orig *client.Message, reply string) {
	// TODO threading
	// TODO use bare JID if full JID isn't up to date anymore
	// TODO support subject
	// TODO support extended items
	c.SendMessage(orig.Type, orig.From, reply)
}

// The user's client SHOULD address the initial message in a chat
// session to the bare JID <contact@domainpart> of the contact (rather
// than attempting to guess an appropriate full JID
// <contact@domainpart/resourcepart> based on the <show/>, <status/>,
// or <priority/> value of any presence notifications it might have
// received from the contact). Until and unless the user's client
// receives a reply from the contact, it SHOULD send any further
// messages to the contact's bare JID. The contact's client SHOULD
// address its replies to the user's full JID
// <user@domainpart/resourcepart> as provided in the 'from' address of
// the initial message. Once the user's client receives a reply from
// the contact's full JID, it SHOULD address its subsequent messages
// to the contact's full JID as provided in the 'from' address of the
// contact's replies, thus "locking in" on that full JID. A client
// SHOULD "unlock" after having received a <message/> or <presence/>
// stanza from any other resource controlled by the peer (or a
// presence stanza from the locked resource); as a result, it SHOULD
// address its next message(s) in the chat session to the bare JID of
// the peer (thus "unlocking" the previous "lock") until it receives a
// message from one of the peer's full JIDs.

// When two parties engage in a chat session but do not share presence
// with each other based on a presence subscription, they SHOULD send
// directed presence to each other so that either party can easily
// discover if the peer goes offline during the course of the chat
// session. However, a client MUST provide a way for a user to disable
// such presence sharing globally or to enable it only with particular
// entities. Furthermore, a party SHOULD send directed unavailable
// presence to the peer when it has reason to believe that the chat
// session is over (e.g., if, after some reasonable amount of time, no
// subsequent messages have been exchanged between the parties).
<|endoftext|>


<commit_before>package status

import (
	"github.com/akhenakh/statgo"
	"github.com/baiyuxiong/gomail/utils"
)

var s *statgo.Stat

func init()  {
	s = statgo.NewStat()
}

func HostInfos() (string) {
	//hi := s.HostInfos()
	return utils.Nl2br("")
}

func CPUStats() (string,string) {
	message := ""
	v := s.CPUStats()
	if v.Idle < 10{
		message = "CPU压力较大"
	}
	return utils.Nl2br(v.String()),message
}

func FSInfos() (string,string) {
	vs := s.FSInfos()

	message := ""
	status := ""
	for _,v := range vs{
		status += "\n"+v.String()
		if v.Free == 0 || (v.Size >0 && v.Free >0 && v.Size/v.Free > 9){
			message = "硬盘空间紧张，请检查"
		}
	}
	return utils.Nl2br(status),message
}

func MemStats() string {
	v := s.MemStats()
	return utils.Nl2br(v.String())
}

func NetIOStats() string {
	vs := s.NetIOStats()

	status := ""
	for _,v := range vs{
		status += "\n"+v.String()
	}
	return utils.Nl2br(status)
}

func ProcessStats() string {
	v := s.ProcessStats()
	return utils.Nl2br(v.String())
}

func PagesStats() string {
	v := s.PageStats()
	return utils.Nl2br(v.String())
}<commit_msg>fix bug<commit_after>package status

import (
	"github.com/akhenakh/statgo"
	"github.com/baiyuxiong/gomail/utils"
)

var s *statgo.Stat

func init()  {
	s = statgo.NewStat()
}

func HostInfos() (string) {
	//hi := s.HostInfos()
	return utils.Nl2br("")
}

func CPUStats() (string,string) {
	message := ""
	v := s.CPUStats()
	if v.Idle < 10{
		message = "CPU压力较大"
	}
	return utils.Nl2br(v.String()),message
}

func FSInfos() (string,string) {
	vs := s.FSInfos()

	message := ""
	status := ""
	for _,v := range vs{
		status += "\n"+v.String()
		if v.Size>0 && (v.Free == 0 || ( v.Free >0 && v.Size/v.Free > 9)){
			message = "硬盘空间紧张，请检查"
		}
	}
	return utils.Nl2br(status),message
}

func MemStats() string {
	v := s.MemStats()
	return utils.Nl2br(v.String())
}

func NetIOStats() string {
	vs := s.NetIOStats()

	status := ""
	for _,v := range vs{
		status += "\n"+v.String()
	}
	return utils.Nl2br(status)
}

func ProcessStats() string {
	v := s.ProcessStats()
	return utils.Nl2br(v.String())
}

func PagesStats() string {
	v := s.PageStats()
	return utils.Nl2br(v.String())
}<|endoftext|>


<commit_before>package stencil

import (
	"path/filepath"
	"testing"

	"io/ioutil"

	"flag"

	"bytes"

	"os"

	"strings"

	"fmt"

	"github.com/pkg/errors"
	"github.com/sridharv/fakegopath"
)

var updateGoldens = flag.Bool("update-goldens", false, "If true, goldens are updated")

type outFile struct {
	path   string
	golden string
}

type testCase struct {
	name    string
	files   []fakegopath.SourceFile
	srcs    []string
	outs    []outFile
	process func([]string) ([]file, error)
}

func (c testCase) run(t *testing.T) {
	t.Run(c.name, func(t *testing.T) {
		tmp, err := fakegopath.NewTemporaryWithFiles("stencil_"+c.name, c.files)
		if err != nil {
			t.Fatalf("%+v", err)
		}
		defer tmp.Reset()

		srcs := make([]string, len(c.srcs))
		for i, s := range c.srcs {
			srcs[i] = filepath.Join(tmp.Src, s)
		}
		proc := c.process
		if proc == nil {
			proc = processStencil
		}
		files, err := proc(srcs)
		if err != nil {
			t.Fatalf("%+v", err)
		}
		if len(c.outs) != len(files) {
			t.Fatalf("expected %d files, got %d", len(c.outs), len(files))
		}
		for i, o := range c.outs {
			out := filepath.Join(tmp.Src, o.path)
			f := files[i]
			if !strings.HasSuffix(f.path, out) {
				t.Errorf("expected file %s, got %s", out, f.path)
			}
			if *updateGoldens {
				if err := ioutil.WriteFile(o.golden, f.data, 0644); err != nil {
					t.Error(o.golden, ": failed to update golden", err)
				}
				continue
			}
			golden, err := ioutil.ReadFile(o.golden)
			if err != nil {
				t.Fatal(o.golden, ": could not read golden", err)
			}
			if !bytes.Equal(golden, f.data) {
				t.Errorf("expected output:\n%s\ngot:\n%s", string(golden), string(f.data))
			}
		}
	})
}

var cases = []testCase{
	{
		name: "Set_String_SingleFile",
		files: []fakegopath.SourceFile{
			{Src: "testdata/set.go", Dest: "collections/set/set.go"},
			{Src: "testdata/set.intersect.go", Dest: "examples/setexamples/intersect.go"},
		},
		srcs: []string{"examples/setexamples/intersect.go"},
		outs: []outFile{
			{
				path:   "examples/setexamples/vendor/collections/set/Element/string/set.go",
				golden: "testdata/set.string.golden",
			},
		},
	},
	{
		name: "Basic_Float32_SingleFile",
		files: []fakegopath.SourceFile{
			{Src: "testdata/basic.go", Dest: "basic/basic.go"},
			{Src: "testdata/basic.use.go", Dest: "use/use.go"},
		},
		srcs: []string{"use/use.go"},
		outs: []outFile{
			{
				path:   "use/vendor/basic/int/float32/basic.go",
				golden: "testdata/basic.float32.golden",
			},
		},
	},
	{
		name: "Set_Interfaces_SingleFile",
		files: []fakegopath.SourceFile{
			{Src: "testdata/interfaces.go", Dest: "ifaces/interfaces.go"},
			{Src: "testdata/interfaces.use.go", Dest: "use/use.go"},
		},
		srcs: []string{"use/use.go"},
		outs: []outFile{
			{
				path:   "use/vendor/ifaces/interface/int/interfaces.go",
				golden: "testdata/interfaces.int.golden",
			},
		},
	},
	{
		name: "Set_Interfaces_MultiFile",
		files: []fakegopath.SourceFile{
			{Src: "testdata/interfaces.go", Dest: "ifaces/interfaces.go"},
			{Src: "testdata/interfacesintersect.go", Dest: "ifaces/interfacesintersect.go"},
			{Src: "testdata/interfaces.use.go", Dest: "use/use.go"},
		},
		srcs: []string{"use/use.go"},
		outs: []outFile{
			{
				path:   "use/vendor/ifaces/interface/int/interfaces.go",
				golden: "testdata/interfaces.int.golden",
			},
			{
				path:   "use/vendor/ifaces/interface/int/interfacesintersect.go",
				golden: "testdata/interfacesintersect.int.golden",
			},
		},
	},
	{
		name: "Set_String_Dir",
		files: []fakegopath.SourceFile{
			{Src: "testdata/set.go", Dest: "collections/set/set.go"},
			{Src: "testdata/set.intersect.go", Dest: "examples/setexamples/intersect.go"},
		},
		srcs: []string{"examples/setexamples/intersect.go"},
		outs: []outFile{
			{
				path:   "examples/setexamples/vendor/collections/set/Element/string/set.go",
				golden: "testdata/set.string.golden",
			},
		},
		process: func(p []string) ([]file, error) {
			d := filepath.Dir(p[0])
			cwd, err := os.Getwd()
			if err != nil {
				return nil, errors.WithStack(err)
			}
			if err = os.Chdir(d); err != nil {
				return nil, errors.WithStack(err)
			}
			defer os.Chdir(cwd)
			return processStencil([]string{})
		},
	},
}

func TestStencil(t *testing.T) {
	for _, c := range cases {
		c.run(t)
	}
}

func TestNewStencil(t *testing.T) {
	tmp, err := fakegopath.NewTemporaryWithFiles("stencil_new", cases[3].files)
	if err != nil {
		t.Fatalf("%+v", err)
	}
	defer tmp.Reset()
	files, err := processStencil([]string{filepath.Join(tmp.Src, "use/use.go")})
	if err != nil {
		t.Fatalf("%+v", err)
	}
	for _, f := range files {
		fmt.Println("\n", f.path)
		fmt.Println("<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>")
		fmt.Println(string(f.data))
		fmt.Println("\n")
	}
}
<commit_msg>Delete redundant test<commit_after>package stencil

import (
	"path/filepath"
	"testing"

	"io/ioutil"

	"flag"

	"bytes"

	"os"

	"strings"

	"github.com/pkg/errors"
	"github.com/sridharv/fakegopath"
)

var updateGoldens = flag.Bool("update-goldens", false, "If true, goldens are updated")

type outFile struct {
	path   string
	golden string
}

type testCase struct {
	name    string
	files   []fakegopath.SourceFile
	srcs    []string
	outs    []outFile
	process func([]string) ([]file, error)
}

func (c testCase) run(t *testing.T) {
	t.Run(c.name, func(t *testing.T) {
		tmp, err := fakegopath.NewTemporaryWithFiles("stencil_"+c.name, c.files)
		if err != nil {
			t.Fatalf("%+v", err)
		}
		defer tmp.Reset()

		srcs := make([]string, len(c.srcs))
		for i, s := range c.srcs {
			srcs[i] = filepath.Join(tmp.Src, s)
		}
		proc := c.process
		if proc == nil {
			proc = processStencil
		}
		files, err := proc(srcs)
		if err != nil {
			t.Fatalf("%+v", err)
		}
		if len(c.outs) != len(files) {
			t.Fatalf("expected %d files, got %d", len(c.outs), len(files))
		}
		for i, o := range c.outs {
			out := filepath.Join(tmp.Src, o.path)
			f := files[i]
			if !strings.HasSuffix(f.path, out) {
				t.Errorf("expected file %s, got %s", out, f.path)
			}
			if *updateGoldens {
				if err := ioutil.WriteFile(o.golden, f.data, 0644); err != nil {
					t.Error(o.golden, ": failed to update golden", err)
				}
				continue
			}
			golden, err := ioutil.ReadFile(o.golden)
			if err != nil {
				t.Fatal(o.golden, ": could not read golden", err)
			}
			if !bytes.Equal(golden, f.data) {
				t.Errorf("expected output:\n%s\ngot:\n%s", string(golden), string(f.data))
			}
		}
	})
}

var cases = []testCase{
	{
		name: "Set_String_SingleFile",
		files: []fakegopath.SourceFile{
			{Src: "testdata/set.go", Dest: "collections/set/set.go"},
			{Src: "testdata/set.intersect.go", Dest: "examples/setexamples/intersect.go"},
		},
		srcs: []string{"examples/setexamples/intersect.go"},
		outs: []outFile{
			{
				path:   "examples/setexamples/vendor/collections/set/Element/string/set.go",
				golden: "testdata/set.string.golden",
			},
		},
	},
	{
		name: "Basic_Float32_SingleFile",
		files: []fakegopath.SourceFile{
			{Src: "testdata/basic.go", Dest: "basic/basic.go"},
			{Src: "testdata/basic.use.go", Dest: "use/use.go"},
		},
		srcs: []string{"use/use.go"},
		outs: []outFile{
			{
				path:   "use/vendor/basic/int/float32/basic.go",
				golden: "testdata/basic.float32.golden",
			},
		},
	},
	{
		name: "Set_Interfaces_SingleFile",
		files: []fakegopath.SourceFile{
			{Src: "testdata/interfaces.go", Dest: "ifaces/interfaces.go"},
			{Src: "testdata/interfaces.use.go", Dest: "use/use.go"},
		},
		srcs: []string{"use/use.go"},
		outs: []outFile{
			{
				path:   "use/vendor/ifaces/interface/int/interfaces.go",
				golden: "testdata/interfaces.int.golden",
			},
		},
	},
	{
		name: "Set_Interfaces_MultiFile",
		files: []fakegopath.SourceFile{
			{Src: "testdata/interfaces.go", Dest: "ifaces/interfaces.go"},
			{Src: "testdata/interfacesintersect.go", Dest: "ifaces/interfacesintersect.go"},
			{Src: "testdata/interfaces.use.go", Dest: "use/use.go"},
		},
		srcs: []string{"use/use.go"},
		outs: []outFile{
			{
				path:   "use/vendor/ifaces/interface/int/interfaces.go",
				golden: "testdata/interfaces.int.golden",
			},
			{
				path:   "use/vendor/ifaces/interface/int/interfacesintersect.go",
				golden: "testdata/interfacesintersect.int.golden",
			},
		},
	},
	{
		name: "Set_String_Dir",
		files: []fakegopath.SourceFile{
			{Src: "testdata/set.go", Dest: "collections/set/set.go"},
			{Src: "testdata/set.intersect.go", Dest: "examples/setexamples/intersect.go"},
		},
		srcs: []string{"examples/setexamples/intersect.go"},
		outs: []outFile{
			{
				path:   "examples/setexamples/vendor/collections/set/Element/string/set.go",
				golden: "testdata/set.string.golden",
			},
		},
		process: func(p []string) ([]file, error) {
			d := filepath.Dir(p[0])
			cwd, err := os.Getwd()
			if err != nil {
				return nil, errors.WithStack(err)
			}
			if err = os.Chdir(d); err != nil {
				return nil, errors.WithStack(err)
			}
			defer os.Chdir(cwd)
			return processStencil([]string{})
		},
	},
}

func TestStencil(t *testing.T) {
	for _, c := range cases {
		c.run(t)
	}
}
<|endoftext|>


<commit_before>// +build !dockerless

/*
Copyright 2020 The Kubernetes 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.
*/

package network

import (
	"strings"
	"testing"
	"time"

	"k8s.io/component-base/metrics/legacyregistry"
	"k8s.io/component-base/metrics/testutil"
	"k8s.io/kubernetes/pkg/kubelet/dockershim/network/metrics"
)

func TestNetworkPluginManagerMetrics(t *testing.T) {
	metrics.Register()

	operation := "test_operation"
	recordOperation(operation, time.Now())
	recordError(operation)

	cases := []struct {
		metricName string
		want       string
	}{
		{
			metricName: "kubelet_network_plugin_operations_total",
			want: `
# HELP kubelet_network_plugin_operations_total [ALPHA] Cumulative number of network plugin operations by operation type.
# TYPE kubelet_network_plugin_operations_total counter
kubelet_network_plugin_operations_total{operation_type="test_operation"} 1
`,
		},
		{
			metricName: "kubelet_network_plugin_operations_errors_total",
			want: `
# HELP kubelet_network_plugin_operations_errors_total [ALPHA] Cumulative number of network plugin operation errors by operation type.
# TYPE kubelet_network_plugin_operations_errors_total counter
kubelet_network_plugin_operations_errors_total{operation_type="test_operation"} 1
`,
		},
	}

	for _, tc := range cases {
		t.Run(tc.metricName, func(t *testing.T) {
			if err := testutil.GatherAndCompare(legacyregistry.DefaultGatherer, strings.NewReader(tc.want), tc.metricName); err != nil {
				t.Fatal(err)
			}
		})
	}
}
<commit_msg>reset metrics on dockerhim unit tests<commit_after>// +build !dockerless

/*
Copyright 2020 The Kubernetes 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.
*/

package network

import (
	"strings"
	"testing"
	"time"

	"k8s.io/component-base/metrics/legacyregistry"
	"k8s.io/component-base/metrics/testutil"
	"k8s.io/kubernetes/pkg/kubelet/dockershim/network/metrics"
)

func TestNetworkPluginManagerMetrics(t *testing.T) {
	metrics.Register()
	defer legacyregistry.Reset()

	operation := "test_operation"
	recordOperation(operation, time.Now())
	recordError(operation)

	cases := []struct {
		metricName string
		want       string
	}{
		{
			metricName: "kubelet_network_plugin_operations_total",
			want: `
# HELP kubelet_network_plugin_operations_total [ALPHA] Cumulative number of network plugin operations by operation type.
# TYPE kubelet_network_plugin_operations_total counter
kubelet_network_plugin_operations_total{operation_type="test_operation"} 1
`,
		},
		{
			metricName: "kubelet_network_plugin_operations_errors_total",
			want: `
# HELP kubelet_network_plugin_operations_errors_total [ALPHA] Cumulative number of network plugin operation errors by operation type.
# TYPE kubelet_network_plugin_operations_errors_total counter
kubelet_network_plugin_operations_errors_total{operation_type="test_operation"} 1
`,
		},
	}

	for _, tc := range cases {
		t.Run(tc.metricName, func(t *testing.T) {
			if err := testutil.GatherAndCompare(legacyregistry.DefaultGatherer, strings.NewReader(tc.want), tc.metricName); err != nil {
				t.Fatal(err)
			}
		})
	}
}
<|endoftext|>