<commit_before>package main

import (
	"compress/gzip"
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"time"

	"github.com/nightlyone/lockfile"
)

var updateTopic = &Topic{
	Name:        "update",
	Description: "update heroku-cli",
}

var updateCmd = &Command{
	Topic:       "update",
	Description: "updates heroku-cli",
	Args:        []Arg{{Name: "channel", Optional: true}},
	Run: func(ctx *Context) {
		channel := ctx.Args.(map[string]string)["channel"]
		if channel == "" {
			channel = "master"
		}
		Errf("updating plugins... ")
		if err := node.UpdatePackages(); err != nil {
			panic(err)
		}
		Errln("done")
		manifest := getUpdateManifest(channel)
		build := manifest.Builds[runtime.GOOS][runtime.GOARCH]
		Errf("updating to %s (%s)... ", manifest.Version, manifest.Channel)
		update(build.URL, build.Sha1)
		Errln("done")
	},
}

var binPath = filepath.Join(AppDir, "heroku-cli")
var updateLockPath = filepath.Join(AppDir, "updating.lock")
var autoupdateFile = filepath.Join(AppDir, "autoupdate")

func init() {
	if runtime.GOOS == "windows" {
		binPath = binPath + ".exe"
	}
}

// UpdateIfNeeded checks for and performs an autoupdate if there is a new version out.
func UpdateIfNeeded() {
	lock := getUpdateLock()
	if !updateNeeded() {
		lock.Unlock()
		return
	}
	doneUpdatingPlugins := make(chan bool)
	go func() {
		node.UpdatePackages()
		doneUpdatingPlugins <- true
	}()
	manifest := getUpdateManifest(Channel)
	if manifest.Version == Version {
		select {
		case <-time.After(time.Second * 30):
			Errln("Timed out while updating")
		case <-doneUpdatingPlugins:
		}
		touchAutoupdateFile()
		lock.Unlock()
		return
	}
	if !updatable() {
		Errf("Out of date: You are running %s but %s is out.\n", Version, manifest.Version)
		<-doneUpdatingPlugins
		lock.Unlock()
		return
	}
	// Leave out updating text until heroku-cli is used in place of ruby cli
	// So it doesn't confuse users with 2 different version numbers
	//Errf("Updating to %s... ", manifest.Version)
	build := manifest.Builds[runtime.GOOS][runtime.GOARCH]
	update(build.URL, build.Sha1)
	select {
	case <-time.After(time.Second * 30):
		Errln("Timed out while updating")
	case <-doneUpdatingPlugins:
	}
	//Errln("done")

	// these are deferred but won't be called because of os.Exit
	touchAutoupdateFile()
	lock.Unlock()
	execBin()
	os.Exit(0)
}

// Attempts to get the lockfile
// Blocks if unavailable
func getUpdateLock() lockfile.Lockfile {
	lock, err := lockfile.New(updateLockPath)
	if err != nil {
		Errln("Cannot initialize update lockfile.")
		panic(err)
	}
	start := time.Now()
	for {
		if lock.TryLock() == nil {
			return lock
		}
		time.Sleep(10 * time.Millisecond)
		if time.Since(start) > 30*time.Second {
			// In a timeout, assume the last updating process timed out
			os.Remove(updateLockPath)
		}
	}
}

func updateNeeded() bool {
	if Version == "dev" {
		return false
	}
	f, err := os.Stat(autoupdateFile)
	if err != nil {
		return true
	}
	return time.Since(f.ModTime()) > 1*time.Hour
}

func touchAutoupdateFile() {
	out, err := os.OpenFile(autoupdateFile, os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		panic(err)
	}
	out.WriteString(time.Now().String())
}

type manifest struct {
	Channel, Version string
	Builds           map[string]map[string]struct {
		URL, Sha1 string
	}
}

func getUpdateManifest(channel string) manifest {
	res, err := http.Get("http://d1gvo455cekpjp.cloudfront.net/" + channel + "/manifest.json")
	if err != nil {
		panic(err)
	}
	var m manifest
	json.NewDecoder(res.Body).Decode(&m)
	return m
}

func updatable() bool {
	path, err := filepath.Abs(os.Args[0])
	if err != nil {
		Errln(err)
	}
	return path == binPath
}

func update(url, sha1 string) {
	// on windows we can't remove an existing file or remove the running binary
	// so we download the file to binName.new
	// move the running binary to binName.old (deleting any existing file first)
	// rename the downloaded file to binName
	if err := downloadBin(binPath+".new", url); err != nil {
		panic(err)
	}
	if fileSha1(binPath+".new") != sha1 {
		panic("SHA mismatch")
	}
	os.Remove(binPath + ".old")
	if err := os.Rename(binPath, binPath+".old"); err != nil {
		panic(err)
	}
	if err := os.Rename(binPath+".new", binPath); err != nil {
		panic(err)
	}
}

func downloadBin(path, url string) error {
	out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
	if err != nil {
		return err
	}
	defer out.Close()
	client := &http.Client{}
	req, err := http.NewRequest("GET", url+".gz", nil)
	if err != nil {
		return err
	}
	req.Header.Add("Accept-Encoding", "gzip")
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	uncompressed, err := gzip.NewReader(resp.Body)
	if err != nil {
		return err
	}
	_, err = io.Copy(out, uncompressed)
	return err
}

func fileSha1(path string) string {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		panic(err)
	}
	return fmt.Sprintf("%x", sha1.Sum(data))
}

func execBin() {
	cmd := exec.Command(binPath, os.Args[1:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Run()
}
<commit_msg>use ssl cloudfront url<commit_after>package main

import (
	"compress/gzip"
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"time"

	"github.com/nightlyone/lockfile"
)

var updateTopic = &Topic{
	Name:        "update",
	Description: "update heroku-cli",
}

var updateCmd = &Command{
	Topic:       "update",
	Description: "updates heroku-cli",
	Args:        []Arg{{Name: "channel", Optional: true}},
	Run: func(ctx *Context) {
		channel := ctx.Args.(map[string]string)["channel"]
		if channel == "" {
			channel = "master"
		}
		Errf("updating plugins... ")
		if err := node.UpdatePackages(); err != nil {
			panic(err)
		}
		Errln("done")
		manifest := getUpdateManifest(channel)
		build := manifest.Builds[runtime.GOOS][runtime.GOARCH]
		Errf("updating to %s (%s)... ", manifest.Version, manifest.Channel)
		update(build.URL, build.Sha1)
		Errln("done")
	},
}

var binPath = filepath.Join(AppDir, "heroku-cli")
var updateLockPath = filepath.Join(AppDir, "updating.lock")
var autoupdateFile = filepath.Join(AppDir, "autoupdate")

func init() {
	if runtime.GOOS == "windows" {
		binPath = binPath + ".exe"
	}
}

// UpdateIfNeeded checks for and performs an autoupdate if there is a new version out.
func UpdateIfNeeded() {
	lock := getUpdateLock()
	if !updateNeeded() {
		lock.Unlock()
		return
	}
	doneUpdatingPlugins := make(chan bool)
	go func() {
		node.UpdatePackages()
		doneUpdatingPlugins <- true
	}()
	manifest := getUpdateManifest(Channel)
	if manifest.Version == Version {
		select {
		case <-time.After(time.Second * 30):
			Errln("Timed out while updating")
		case <-doneUpdatingPlugins:
		}
		touchAutoupdateFile()
		lock.Unlock()
		return
	}
	if !updatable() {
		Errf("Out of date: You are running %s but %s is out.\n", Version, manifest.Version)
		<-doneUpdatingPlugins
		lock.Unlock()
		return
	}
	// Leave out updating text until heroku-cli is used in place of ruby cli
	// So it doesn't confuse users with 2 different version numbers
	//Errf("Updating to %s... ", manifest.Version)
	build := manifest.Builds[runtime.GOOS][runtime.GOARCH]
	update(build.URL, build.Sha1)
	select {
	case <-time.After(time.Second * 30):
		Errln("Timed out while updating")
	case <-doneUpdatingPlugins:
	}
	//Errln("done")

	// these are deferred but won't be called because of os.Exit
	touchAutoupdateFile()
	lock.Unlock()
	execBin()
	os.Exit(0)
}

// Attempts to get the lockfile
// Blocks if unavailable
func getUpdateLock() lockfile.Lockfile {
	lock, err := lockfile.New(updateLockPath)
	if err != nil {
		Errln("Cannot initialize update lockfile.")
		panic(err)
	}
	start := time.Now()
	for {
		if lock.TryLock() == nil {
			return lock
		}
		time.Sleep(10 * time.Millisecond)
		if time.Since(start) > 30*time.Second {
			// In a timeout, assume the last updating process timed out
			os.Remove(updateLockPath)
		}
	}
}

func updateNeeded() bool {
	if Version == "dev" {
		return false
	}
	f, err := os.Stat(autoupdateFile)
	if err != nil {
		return true
	}
	return time.Since(f.ModTime()) > 1*time.Hour
}

func touchAutoupdateFile() {
	out, err := os.OpenFile(autoupdateFile, os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		panic(err)
	}
	out.WriteString(time.Now().String())
}

type manifest struct {
	Channel, Version string
	Builds           map[string]map[string]struct {
		URL, Sha1 string
	}
}

func getUpdateManifest(channel string) manifest {
	res, err := http.Get("https://d1gvo455cekpjp.cloudfront.net/" + channel + "/manifest.json")
	if err != nil {
		panic(err)
	}
	var m manifest
	json.NewDecoder(res.Body).Decode(&m)
	return m
}

func updatable() bool {
	path, err := filepath.Abs(os.Args[0])
	if err != nil {
		Errln(err)
	}
	return path == binPath
}

func update(url, sha1 string) {
	// on windows we can't remove an existing file or remove the running binary
	// so we download the file to binName.new
	// move the running binary to binName.old (deleting any existing file first)
	// rename the downloaded file to binName
	if err := downloadBin(binPath+".new", url); err != nil {
		panic(err)
	}
	if fileSha1(binPath+".new") != sha1 {
		panic("SHA mismatch")
	}
	os.Remove(binPath + ".old")
	if err := os.Rename(binPath, binPath+".old"); err != nil {
		panic(err)
	}
	if err := os.Rename(binPath+".new", binPath); err != nil {
		panic(err)
	}
}

func downloadBin(path, url string) error {
	out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
	if err != nil {
		return err
	}
	defer out.Close()
	client := &http.Client{}
	req, err := http.NewRequest("GET", url+".gz", nil)
	if err != nil {
		return err
	}
	req.Header.Add("Accept-Encoding", "gzip")
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	uncompressed, err := gzip.NewReader(resp.Body)
	if err != nil {
		return err
	}
	_, err = io.Copy(out, uncompressed)
	return err
}

func fileSha1(path string) string {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		panic(err)
	}
	return fmt.Sprintf("%x", sha1.Sum(data))
}

func execBin() {
	cmd := exec.Command(binPath, os.Args[1:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Run()
}
<|endoftext|>


<commit_before>package main

import (
	"compress/gzip"
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"time"

	"github.com/nightlyone/lockfile"
)

var updateTopic = &Topic{
	Name:        "update",
	Description: "update heroku-cli",
}

var updateCmd = &Command{
	Topic:       "update",
	Description: "updates heroku-cli",
	Args:        []Arg{{Name: "channel", Optional: true}},
	Run: func(ctx *Context) {
		channel := ctx.Args.(map[string]string)["channel"]
		if channel == "" {
			channel = "master"
		}
		Errf("updating plugins... ")
		if err := node.UpdatePackages(); err != nil {
			panic(err)
		}
		Errln("done")
		manifest := getUpdateManifest(channel)
		build := manifest.Builds[runtime.GOOS][runtime.GOARCH]
		Errf("updating to %s (%s)... ", manifest.Version, manifest.Channel)
		update(build.URL, build.Sha1)
		Errln("done")
	},
}

var binPath = filepath.Join(AppDir, "heroku-cli")
var updateLockPath = filepath.Join(AppDir, "updating.lock")
var autoupdateFile = filepath.Join(AppDir, "autoupdate")

func init() {
	if runtime.GOOS == "windows" {
		binPath = binPath + ".exe"
	}
}

// UpdateIfNeeded checks for and performs an autoupdate if there is a new version out.
func UpdateIfNeeded() {
	lock := getUpdateLock()
	if !updateNeeded() {
		lock.Unlock()
		return
	}
	doneUpdatingPlugins := make(chan bool)
	go func() {
		node.UpdatePackages()
		doneUpdatingPlugins <- true
	}()
	manifest := getUpdateManifest(Channel)
	if manifest.Version == Version {
		<-doneUpdatingPlugins
		touchAutoupdateFile()
		lock.Unlock()
		return
	}
	if !updatable() {
		Errf("Out of date: You are running %s but %s is out.\n", Version, manifest.Version)
		<-doneUpdatingPlugins
		lock.Unlock()
		return
	}
	// Leave out updating text until heroku-cli is used in place of ruby cli
	// So it doesn't confuse users with 2 different version numbers
	//Errf("Updating to %s... ", manifest.Version)
	build := manifest.Builds[runtime.GOOS][runtime.GOARCH]
	update(build.URL, build.Sha1)
	<-doneUpdatingPlugins
	//Errln("done")

	// these are deferred but won't be called because of os.Exit
	touchAutoupdateFile()
	lock.Unlock()
	execBin()
	os.Exit(0)
}

// Attempts to get the lockfile
// Blocks if unavailable
func getUpdateLock() lockfile.Lockfile {
	lock, err := lockfile.New(updateLockPath)
	if err != nil {
		Errln("Cannot initialize update lockfile.")
		panic(err)
	}
	start := time.Now()
	for {
		if lock.TryLock() == nil {
			return lock
		}
		time.Sleep(10 * time.Millisecond)
		if time.Since(start) > 30*time.Second {
			// In a timeout, assume the last updating process timed out
			os.Remove(updateLockPath)
		}
	}
}

func updateNeeded() bool {
	if Version == "dev" {
		return false
	}
	f, err := os.Stat(autoupdateFile)
	if err != nil {
		return true
	}
	return time.Since(f.ModTime()) > 1*time.Hour
}

func touchAutoupdateFile() {
	out, err := os.OpenFile(autoupdateFile, os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		panic(err)
	}
	out.WriteString(time.Now().String())
}

type manifest struct {
	Channel, Version string
	Builds           map[string]map[string]struct {
		URL, Sha1 string
	}
}

func getUpdateManifest(channel string) manifest {
	res, err := http.Get("http://d1gvo455cekpjp.cloudfront.net/" + channel + "/manifest.json")
	if err != nil {
		panic(err)
	}
	var m manifest
	json.NewDecoder(res.Body).Decode(&m)
	return m
}

func updatable() bool {
	path, err := filepath.Abs(os.Args[0])
	if err != nil {
		Errln(err)
	}
	return path == binPath
}

func update(url, sha1 string) {
	// on windows we can't remove an existing file or remove the running binary
	// so we download the file to binName.new
	// move the running binary to binName.old (deleting any existing file first)
	// rename the downloaded file to binName
	if err := downloadBin(binPath+".new", url); err != nil {
		panic(err)
	}
	if fileSha1(binPath+".new") != sha1 {
		panic("SHA mismatch")
	}
	os.Remove(binPath + ".old")
	if err := os.Rename(binPath, binPath+".old"); err != nil {
		panic(err)
	}
	if err := os.Rename(binPath+".new", binPath); err != nil {
		panic(err)
	}
}

func downloadBin(path, url string) error {
	out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
	if err != nil {
		return err
	}
	defer out.Close()
	client := &http.Client{}
	req, err := http.NewRequest("GET", url+".gz", nil)
	if err != nil {
		return err
	}
	req.Header.Add("Accept-Encoding", "gzip")
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	uncompressed, err := gzip.NewReader(resp.Body)
	if err != nil {
		return err
	}
	_, err = io.Copy(out, uncompressed)
	return err
}

func fileSha1(path string) string {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		panic(err)
	}
	return fmt.Sprintf("%x", sha1.Sum(data))
}

func execBin() {
	cmd := exec.Command(binPath, os.Args[1:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Run()
}
<commit_msg>update timeout<commit_after>package main

import (
	"compress/gzip"
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"time"

	"github.com/nightlyone/lockfile"
)

var updateTopic = &Topic{
	Name:        "update",
	Description: "update heroku-cli",
}

var updateCmd = &Command{
	Topic:       "update",
	Description: "updates heroku-cli",
	Args:        []Arg{{Name: "channel", Optional: true}},
	Run: func(ctx *Context) {
		channel := ctx.Args.(map[string]string)["channel"]
		if channel == "" {
			channel = "master"
		}
		Errf("updating plugins... ")
		if err := node.UpdatePackages(); err != nil {
			panic(err)
		}
		Errln("done")
		manifest := getUpdateManifest(channel)
		build := manifest.Builds[runtime.GOOS][runtime.GOARCH]
		Errf("updating to %s (%s)... ", manifest.Version, manifest.Channel)
		update(build.URL, build.Sha1)
		Errln("done")
	},
}

var binPath = filepath.Join(AppDir, "heroku-cli")
var updateLockPath = filepath.Join(AppDir, "updating.lock")
var autoupdateFile = filepath.Join(AppDir, "autoupdate")

func init() {
	if runtime.GOOS == "windows" {
		binPath = binPath + ".exe"
	}
}

// UpdateIfNeeded checks for and performs an autoupdate if there is a new version out.
func UpdateIfNeeded() {
	lock := getUpdateLock()
	if !updateNeeded() {
		lock.Unlock()
		return
	}
	doneUpdatingPlugins := make(chan bool)
	go func() {
		node.UpdatePackages()
		doneUpdatingPlugins <- true
	}()
	manifest := getUpdateManifest(Channel)
	if manifest.Version == Version {
		select {
		case <-time.After(time.Second * 30):
			Errln("Timed out while updating")
		case <-doneUpdatingPlugins:
		}
		touchAutoupdateFile()
		lock.Unlock()
		return
	}
	if !updatable() {
		Errf("Out of date: You are running %s but %s is out.\n", Version, manifest.Version)
		<-doneUpdatingPlugins
		lock.Unlock()
		return
	}
	// Leave out updating text until heroku-cli is used in place of ruby cli
	// So it doesn't confuse users with 2 different version numbers
	//Errf("Updating to %s... ", manifest.Version)
	build := manifest.Builds[runtime.GOOS][runtime.GOARCH]
	update(build.URL, build.Sha1)
	select {
	case <-time.After(time.Second * 30):
		Errln("Timed out while updating")
	case <-doneUpdatingPlugins:
	}
	//Errln("done")

	// these are deferred but won't be called because of os.Exit
	touchAutoupdateFile()
	lock.Unlock()
	execBin()
	os.Exit(0)
}

// Attempts to get the lockfile
// Blocks if unavailable
func getUpdateLock() lockfile.Lockfile {
	lock, err := lockfile.New(updateLockPath)
	if err != nil {
		Errln("Cannot initialize update lockfile.")
		panic(err)
	}
	start := time.Now()
	for {
		if lock.TryLock() == nil {
			return lock
		}
		time.Sleep(10 * time.Millisecond)
		if time.Since(start) > 30*time.Second {
			// In a timeout, assume the last updating process timed out
			os.Remove(updateLockPath)
		}
	}
}

func updateNeeded() bool {
	if Version == "dev" {
		return false
	}
	f, err := os.Stat(autoupdateFile)
	if err != nil {
		return true
	}
	return time.Since(f.ModTime()) > 1*time.Hour
}

func touchAutoupdateFile() {
	out, err := os.OpenFile(autoupdateFile, os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		panic(err)
	}
	out.WriteString(time.Now().String())
}

type manifest struct {
	Channel, Version string
	Builds           map[string]map[string]struct {
		URL, Sha1 string
	}
}

func getUpdateManifest(channel string) manifest {
	res, err := http.Get("http://d1gvo455cekpjp.cloudfront.net/" + channel + "/manifest.json")
	if err != nil {
		panic(err)
	}
	var m manifest
	json.NewDecoder(res.Body).Decode(&m)
	return m
}

func updatable() bool {
	path, err := filepath.Abs(os.Args[0])
	if err != nil {
		Errln(err)
	}
	return path == binPath
}

func update(url, sha1 string) {
	// on windows we can't remove an existing file or remove the running binary
	// so we download the file to binName.new
	// move the running binary to binName.old (deleting any existing file first)
	// rename the downloaded file to binName
	if err := downloadBin(binPath+".new", url); err != nil {
		panic(err)
	}
	if fileSha1(binPath+".new") != sha1 {
		panic("SHA mismatch")
	}
	os.Remove(binPath + ".old")
	if err := os.Rename(binPath, binPath+".old"); err != nil {
		panic(err)
	}
	if err := os.Rename(binPath+".new", binPath); err != nil {
		panic(err)
	}
}

func downloadBin(path, url string) error {
	out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
	if err != nil {
		return err
	}
	defer out.Close()
	client := &http.Client{}
	req, err := http.NewRequest("GET", url+".gz", nil)
	if err != nil {
		return err
	}
	req.Header.Add("Accept-Encoding", "gzip")
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	uncompressed, err := gzip.NewReader(resp.Body)
	if err != nil {
		return err
	}
	_, err = io.Copy(out, uncompressed)
	return err
}

func fileSha1(path string) string {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		panic(err)
	}
	return fmt.Sprintf("%x", sha1.Sum(data))
}

func execBin() {
	cmd := exec.Command(binPath, os.Args[1:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.Run()
}
<|endoftext|>


<commit_before>package dns

import (
	"crypto/sha1"
	"encoding/hex"
	"hash"
	"strings"
)

// HashName hashes a string (label) according to RFC 5155. It returns the hashed string in uppercase.
func HashName(label string, ha uint8, iter uint16, salt string) string {
	wireSalt := make([]byte, hex.DecodedLen(len(salt)))
	n, err := packStringHex(salt, wireSalt, 0)
	if err != nil {
		return ""
	}
	wireSalt = wireSalt[:n]
	name := make([]byte, 255)
	off, err := PackDomainName(strings.ToLower(label), name, 0, nil, false)
	if err != nil {
		return ""
	}
	name = name[:off]
	var s hash.Hash
	switch ha {
	case SHA1:
		s = sha1.New()
	default:
		return ""
	}

	// k = 0
	s.Write(name)
	s.Write(wireSalt)
	nsec3 := s.Sum(nil)
	// k > 0
	for k := uint16(0); k < iter; k++ {
		s.Reset()
		s.Write(nsec3)
		s.Write(wireSalt)
		nsec3 = s.Sum(nsec3[:0])
	}
	return toBase32(nsec3)
}

// Cover returns true if a name is covered by the NSEC3 record
func (rr *NSEC3) Cover(name string) bool {
	nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
	owner := strings.ToUpper(rr.Hdr.Name)
	labelIndices := Split(owner)
	if len(labelIndices) < 2 {
		return false
	}
	ownerHash := owner[:labelIndices[1]-1]
	ownerZone := owner[labelIndices[1]:]
	if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
		return false
	}

	nextHash := rr.NextDomain

	// if empty interval found, try cover wildcard hashes so nameHash shouldn't match with ownerHash
	if ownerHash == nextHash && nameHash != ownerHash { // empty interval
		return true
	}
	if ownerHash > nextHash { // end of zone
		if nameHash > ownerHash { // covered since there is nothing after ownerHash
			return true
		}
		return nameHash < nextHash // if nameHash is before beginning of zone it is covered
	}
	if nameHash < ownerHash { // nameHash is before ownerHash, not covered
		return false
	}
	return nameHash < nextHash // if nameHash is before nextHash is it covered (between ownerHash and nextHash)
}

// Match returns true if a name matches the NSEC3 record
func (rr *NSEC3) Match(name string) bool {
	nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
	owner := strings.ToUpper(rr.Hdr.Name)
	labelIndices := Split(owner)
	if len(labelIndices) < 2 {
		return false
	}
	ownerHash := owner[:labelIndices[1]-1]
	ownerZone := owner[labelIndices[1]:]
	if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
		return false
	}
	if ownerHash == nameHash {
		return true
	}
	return false
}
<commit_msg>Hoist SHA1 check in HashName<commit_after>package dns

import (
	"crypto/sha1"
	"encoding/hex"
	"strings"
)

// HashName hashes a string (label) according to RFC 5155. It returns the hashed string in uppercase.
func HashName(label string, ha uint8, iter uint16, salt string) string {
	if ha != SHA1 {
		return ""
	}

	wireSalt := make([]byte, hex.DecodedLen(len(salt)))
	n, err := packStringHex(salt, wireSalt, 0)
	if err != nil {
		return ""
	}
	wireSalt = wireSalt[:n]

	name := make([]byte, 255)
	off, err := PackDomainName(strings.ToLower(label), name, 0, nil, false)
	if err != nil {
		return ""
	}
	name = name[:off]

	s := sha1.New()
	// k = 0
	s.Write(name)
	s.Write(wireSalt)
	nsec3 := s.Sum(nil)

	// k > 0
	for k := uint16(0); k < iter; k++ {
		s.Reset()
		s.Write(nsec3)
		s.Write(wireSalt)
		nsec3 = s.Sum(nsec3[:0])
	}

	return toBase32(nsec3)
}

// Cover returns true if a name is covered by the NSEC3 record
func (rr *NSEC3) Cover(name string) bool {
	nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
	owner := strings.ToUpper(rr.Hdr.Name)
	labelIndices := Split(owner)
	if len(labelIndices) < 2 {
		return false
	}
	ownerHash := owner[:labelIndices[1]-1]
	ownerZone := owner[labelIndices[1]:]
	if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
		return false
	}

	nextHash := rr.NextDomain

	// if empty interval found, try cover wildcard hashes so nameHash shouldn't match with ownerHash
	if ownerHash == nextHash && nameHash != ownerHash { // empty interval
		return true
	}
	if ownerHash > nextHash { // end of zone
		if nameHash > ownerHash { // covered since there is nothing after ownerHash
			return true
		}
		return nameHash < nextHash // if nameHash is before beginning of zone it is covered
	}
	if nameHash < ownerHash { // nameHash is before ownerHash, not covered
		return false
	}
	return nameHash < nextHash // if nameHash is before nextHash is it covered (between ownerHash and nextHash)
}

// Match returns true if a name matches the NSEC3 record
func (rr *NSEC3) Match(name string) bool {
	nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
	owner := strings.ToUpper(rr.Hdr.Name)
	labelIndices := Split(owner)
	if len(labelIndices) < 2 {
		return false
	}
	ownerHash := owner[:labelIndices[1]-1]
	ownerZone := owner[labelIndices[1]:]
	if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
		return false
	}
	if ownerHash == nameHash {
		return true
	}
	return false
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/ddollar/dist"
)

var cmdUpdate = &Command{
	Run:   runUpdate,
	Usage: "update [version]",
	Short: "Update forego",
	Long: `
Update forego

Examples:

	forego update
	forego update 0.3.0
`,
}

func init() {
}

func runUpdate(cmd *Command, args []string) {
	if Version == "dev" {
		fmt.Println("ERROR: can't update dev version")
		return
	}
	d := dist.NewDist("ddollar/forego")
	if len(args) > 0 {
		err := d.UpdateTo(Version, args[0])
		if err != nil {
			fmt.Printf("ERROR: %s\n", err)
		} else {
			fmt.Printf("updated to %s\n", args[0])
		}
	} else {
		version, err := d.Update(Version)
		if err != nil {
			fmt.Printf("ERROR: %s\n", err)
		} else {
			fmt.Printf("updated to %s\n", version)
		}
	}
}
<commit_msg>refactor<commit_after>package main

import (
	"fmt"
	"github.com/ddollar/dist"
)

var cmdUpdate = &Command{
	Run:   runUpdate,
	Usage: "update [version]",
	Short: "Update forego",
	Long: `
Update forego

Examples:

	forego update
	forego update 0.3.0
`,
}

func init() {
}

func runUpdate(cmd *Command, args []string) {
	if Version == "dev" {
		fmt.Println("ERROR: can't update dev version")
		return
	}
	d := dist.NewDist("ddollar/forego")
	var err error
	var to string
	if len(args) > 0 {
		err = d.UpdateTo(Version, args[0])
		to = args[0]
	} else {
		to, err = d.Update(Version)
	}
	if err != nil {
		fmt.Printf("ERROR: %s\n", err)
	} else {
		fmt.Printf("updated to %s\n", to)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"os"

	"github.com/codegangsta/cli"
)

func main() {

	app := cli.NewApp()

	app.Name = "Gountries Creator"

	// Create files from data
	//

	app.Commands = []cli.Command{
		{
			Name:   "create",
			Usage:  "Generates all data based on the local files",
			Action: createFiles,
		},
		{
			Name:   "import",
			Usage:  "Imports data from various data sources",
			Action: importFiles,
		},
	}

	app.Run(os.Args)

}
<commit_msg>Removed one comment. :)<commit_after>package main

import (
	"os"

	"github.com/codegangsta/cli"
)

func main() {

	app := cli.NewApp()

	app.Name = "Gountries Creator"

	app.Commands = []cli.Command{
		{
			Name:   "create",
			Usage:  "Generates all data based on the local files",
			Action: createFiles,
		},
		{
			Name:   "import",
			Usage:  "Imports data from various data sources",
			Action: importFiles,
		},
	}

	app.Run(os.Args)

}
<|endoftext|>


<commit_before>package policy

import (
	"github.com/skygeario/skygear-server/pkg/core/auth/authz"
)

var RequireValidUser = AllOf(
	authz.PolicyFunc(requireAuthenticated),
	authz.PolicyFunc(DenyDisabledUser),
)

var RequireVerifiedUser = AllOf(
	authz.PolicyFunc(requireAuthenticated),
	authz.PolicyFunc(DenyDisabledUser),
	authz.PolicyFunc(denyNotVerifiedUser),
)

var RequireValidUserOrMasterKey = AnyOf(
	authz.PolicyFunc(RequireMasterKey),
	AllOf(
		authz.PolicyFunc(DenyNoAccessKey),
		RequireValidUser,
	),
)
<commit_msg>Remove DenyNoAccessKey in RequireValidUserOrMasterKey<commit_after>package policy

import (
	"github.com/skygeario/skygear-server/pkg/core/auth/authz"
)

var RequireValidUser = AllOf(
	authz.PolicyFunc(requireAuthenticated),
	authz.PolicyFunc(DenyDisabledUser),
)

var RequireVerifiedUser = AllOf(
	authz.PolicyFunc(requireAuthenticated),
	authz.PolicyFunc(DenyDisabledUser),
	authz.PolicyFunc(denyNotVerifiedUser),
)

var RequireValidUserOrMasterKey = AnyOf(
	authz.PolicyFunc(RequireMasterKey),
	RequireValidUser,
)
<|endoftext|>


<commit_before>/*
Copyright 2019 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 topologymanager

import (
	"k8s.io/kubernetes/pkg/kubelet/lifecycle"
)

type nonePolicy struct{}

var _ Policy = &nonePolicy{}

// PolicyNone policy name.
const PolicyNone string = "none"

// NewNonePolicy returns none policy.
func NewNonePolicy() Policy {
	return &nonePolicy{}
}

func (p *nonePolicy) Name() string {
	return string(PolicyNone)
}

func (p *nonePolicy) CanAdmitPodResult(admit bool) lifecycle.PodAdmitResult {
	return lifecycle.PodAdmitResult{
		Admit: true,
	}
}
<commit_msg>Remove unnecessary string() from policy_none<commit_after>/*
Copyright 2019 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 topologymanager

import (
	"k8s.io/kubernetes/pkg/kubelet/lifecycle"
)

type nonePolicy struct{}

var _ Policy = &nonePolicy{}

// PolicyNone policy name.
const PolicyNone string = "none"

// NewNonePolicy returns none policy.
func NewNonePolicy() Policy {
	return &nonePolicy{}
}

func (p *nonePolicy) Name() string {
	return PolicyNone
}

func (p *nonePolicy) CanAdmitPodResult(admit bool) lifecycle.PodAdmitResult {
	return lifecycle.PodAdmitResult{
		Admit: true,
	}
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	"os/exec"
	"os/user"
	"runtime"

	"github.com/omakoto/yt-up/oauth"
)

var (
	clientId     = flag.String("clientid", "", "Client ID")
	clientSecret = flag.String("secret", "", "Client secret")
)

// openURL opens a browser window to the specified location.
// This code originally appeared at:
//   http://stackoverflow.com/questions/10377243/how-can-i-launch-a-process-that-is-not-a-file-in-go
func openURL(url string) error {
	var err error
	switch runtime.GOOS {
	case "linux":
		err = exec.Command("xdg-open", url).Start()
	case "windows":
		err = exec.Command("rundll32", "url.dll,FileProtocolHandler", "http://localhost:4001/").Start()
	case "darwin":
		err = exec.Command("open", url).Start()
	default:
		err = fmt.Errorf("Cannot open URL %s on this platform", url)
	}
	return err
}

func getHomeDir() string {
	usr, err := user.Current()
	if err != nil {
		log.Fatal(err)
	}
	return usr.HomeDir
}

func buildConfig(scope string) (*oauth.Config, error) {
	if *clientId == "" {
		log.Fatalf("You must provide an oauth client ID with -clientid")
	}

	if *clientSecret == "" {
		log.Fatalf("You must provide an oauth client secret with -secret")
	}

	return &oauth.Config{
		ClientId:       *clientId,
		ClientSecret:   *clientSecret,
		Scope:          scope,
		AuthURL:        "https://accounts.google.com/o/oauth2/auth",
		TokenURL:       "https://accounts.google.com/o/oauth2/token",
		RedirectURL:    "http://localhost:8080/",
		TokenCache:     oauth.CacheFile(getHomeDir() + "/.yt-up.oauth.cache"),
		AccessType:     "offline",
		ApprovalPrompt: "force",
	}, nil
}

// startWebServer starts a web server that listens on http://localhost:8080.
// The webserver waits for an oauth code in the three-legged auth flow.
func startWebServer() (codeCh chan string, err error) {
	listener, err := net.Listen("tcp", "localhost:8080")
	if err != nil {
		return nil, err
	}
	codeCh = make(chan string)
	go http.Serve(listener, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		code := r.FormValue("code")
		codeCh <- code // send code to OAuth flow
		listener.Close()
		w.Header().Set("Content-Type", "text/plain")
		fmt.Fprintf(w, "Received code: %v\r\nYou can now safely close this browser window.", code)
	}))

	return codeCh, nil
}

// buildOAuthHTTPClient takes the user through the three-legged OAuth flow.
// It opens a browser in the native OS or outputs a URL, then blocks until
// the redirect completes to the /oauth2callback URI.
// It returns an instance of an HTTP client that can be passed to the
// constructor of the YouTube client.
func buildOAuthHTTPClient(scope string) (*http.Client, error) {
	config, err := buildConfig(scope)
	if err != nil {
		msg := fmt.Sprintf("Cannot read configuration file: %v", err)
		return nil, errors.New(msg)
	}

	transport := &oauth.Transport{Config: config}

	// Try to read the token from the cache file.
	// If an error occurs, do the three-legged OAuth flow because
	// the token is invalid or doesn't exist.
	token, err := config.TokenCache.Token()
	if err != nil {
		// Start web server.
		// This is how this program receives the authorization code
		// when the browser redirects.
		codeCh, err := startWebServer()
		if err != nil {
			return nil, err
		}

		// Open url in browser
		url := config.AuthCodeURL("")
		// fmt.Println("URL=" + url)
		err = openURL(url)
		if err != nil {
			log.Println("Visit the URL below to get a code.",
				" This program will pause until the site is visted.")
		} else {
			log.Println("Your browser has been opened to an authorization URL.",
				" This program will resume once authorization has been provided.")
		}
		// fmt.Println(url)

		// Wait for the web server to get the code.
		code := <-codeCh

		// This code caches the authorization code on the local
		// filesystem, if necessary, as long as the TokenCache
		// attribute in the config is set.
		token, err = transport.Exchange(code)
		if err != nil {
			return nil, err
		}
	}

	transport.Token = token
	return transport.Client(), nil
}
<commit_msg>Get env values for client information<commit_after>package main

import (
	"errors"
	"fmt"
	"log"
	"net"
	"net/http"
	"os"
	"os/exec"
	"os/user"
	"runtime"

	"github.com/omakoto/yt-up/oauth"
)

const (
	CLIENT_ID_ENV     = "YT_UP_CLIENT_ID"
	CLIENT_SECRET_ENV = "YT_UP_CLIENT_SECRET"
)

// openURL opens a browser window to the specified location.
// This code originally appeared at:
//   http://stackoverflow.com/questions/10377243/how-can-i-launch-a-process-that-is-not-a-file-in-go
func openURL(url string) error {
	var err error
	switch runtime.GOOS {
	case "linux":
		err = exec.Command("xdg-open", url).Start()
	case "windows":
		err = exec.Command("rundll32", "url.dll,FileProtocolHandler", "http://localhost:4001/").Start()
	case "darwin":
		err = exec.Command("open", url).Start()
	default:
		err = fmt.Errorf("Cannot open URL %s on this platform", url)
	}
	return err
}

func getHomeDir() string {
	usr, err := user.Current()
	if err != nil {
		log.Fatal(err)
	}
	return usr.HomeDir
}

func buildConfig(scope string) (*oauth.Config, error) {
	clientId := os.Getenv(CLIENT_ID_ENV)
	if clientId == "" {
		log.Fatalf("You must provide an oauth client ID via " + CLIENT_ID_ENV)
	}

	clientSecret := os.Getenv(CLIENT_SECRET_ENV)
	if clientSecret == "" {
		log.Fatalf("You must provide an oauth client secret via " + CLIENT_SECRET_ENV)
	}

	return &oauth.Config{
		ClientId:       clientId,
		ClientSecret:   clientSecret,
		Scope:          scope,
		AuthURL:        "https://accounts.google.com/o/oauth2/auth",
		TokenURL:       "https://accounts.google.com/o/oauth2/token",
		RedirectURL:    "http://localhost:8080/",
		TokenCache:     oauth.CacheFile(getHomeDir() + "/.yt-up.oauth.cache"),
		AccessType:     "offline",
		ApprovalPrompt: "force",
	}, nil
}

// startWebServer starts a web server that listens on http://localhost:8080.
// The webserver waits for an oauth code in the three-legged auth flow.
func startWebServer() (codeCh chan string, err error) {
	listener, err := net.Listen("tcp", "localhost:8080")
	if err != nil {
		return nil, err
	}
	codeCh = make(chan string)
	go http.Serve(listener, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		code := r.FormValue("code")
		codeCh <- code // send code to OAuth flow
		listener.Close()
		w.Header().Set("Content-Type", "text/plain")
		fmt.Fprintf(w, "Received code: %v\r\nYou can now safely close this browser window.", code)
	}))

	return codeCh, nil
}

// buildOAuthHTTPClient takes the user through the three-legged OAuth flow.
// It opens a browser in the native OS or outputs a URL, then blocks until
// the redirect completes to the /oauth2callback URI.
// It returns an instance of an HTTP client that can be passed to the
// constructor of the YouTube client.
func buildOAuthHTTPClient(scope string) (*http.Client, error) {
	config, err := buildConfig(scope)
	if err != nil {
		msg := fmt.Sprintf("Cannot read configuration file: %v", err)
		return nil, errors.New(msg)
	}

	transport := &oauth.Transport{Config: config}

	// Try to read the token from the cache file.
	// If an error occurs, do the three-legged OAuth flow because
	// the token is invalid or doesn't exist.
	token, err := config.TokenCache.Token()
	if err != nil {
		// Start web server.
		// This is how this program receives the authorization code
		// when the browser redirects.
		codeCh, err := startWebServer()
		if err != nil {
			return nil, err
		}

		// Open url in browser
		url := config.AuthCodeURL("")
		// fmt.Println("URL=" + url)
		err = openURL(url)
		if err != nil {
			log.Println("Visit the URL below to get a code.",
				" This program will pause until the site is visted.")
		} else {
			log.Println("Your browser has been opened to an authorization URL.",
				" This program will resume once authorization has been provided.")
		}
		// fmt.Println(url)

		// Wait for the web server to get the code.
		code := <-codeCh

		// This code caches the authorization code on the local
		// filesystem, if necessary, as long as the TokenCache
		// attribute in the config is set.
		token, err = transport.Exchange(code)
		if err != nil {
			return nil, err
		}
	}

	transport.Token = token
	return transport.Client(), nil
}
<|endoftext|>


<commit_before>package ogdat

import (
	"encoding/csv"
	"io"
	"log"
	"os"
	"strconv"
)

/*	Version10 = "OGD Austria Metadata 1.0" // Version 1.0: 24.10.2011
	Version11 = "OGD Austria Metadata 1.1" // Version 1.1: 12.03.2012
	Version20 = "OGD Austria Metadata 2.0" // Version 2.0: 10.10.2012
	Version21 = "OGD Austria Metadata 2.1" // Version 2.1: 15.10.2012
*/
type OGDSet map[int]*Beschreibung

var specification = make(map[string]OGDSet)

type Occurrence int

const (
	OccUndef Occurrence = iota
	OccRequired
	OccOptional
)

func (desc *Beschreibung) Version() string {
	return desc.version
}

func (desc *Beschreibung) Occurrence() Occurrence {
	return desc.occurrence
}

type Beschreibung struct {
	ID            int
	Bezeichner    string
	OGD_Kurzname  string
	CKAN_Feld     string
	Anzahl        byte
	Definition_DE string
	Erlauterung   string
	Beispiel      string
	ONA2270       string
	ISO19115      string
	RDFProperty   string
	Definition_EN string
	occurrence    Occurrence
	version       string
}

func NewBeschreibung(ID int, occur Occurrence, ver string) *Beschreibung {
	return &Beschreibung{ID: ID, occurrence: occur, version: ver}
}

func (set OGDSet) GetSpecForID(id int) *Beschreibung {
	if set != nil {
		if spec, ok := set[id]; ok {
			return spec
		}
	}
	return nil
}

func Register(version, specfile string) {
	specmap, _ := Loadogdatspec(version, specfile)
	specification[version] = specmap
}

func Loadogdatspec(version, filename string) (OGDSet, error) {
	reader, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer reader.Close()
	spec := make(OGDSet)
	csvreader := csv.NewReader(reader)
	csvreader.Comma = '|'
	csvreader.LazyQuotes = true

	// skip the first line as it contains the field description
	record, err := csvreader.Read()

	for record, err = csvreader.Read(); err != io.EOF; record, err = csvreader.Read() {
		id, _ := strconv.Atoi(record[0])
		var occ Occurrence
		switch record[12][0] {
		case 'R':
			occ = OccRequired
		case 'O':
			occ = OccOptional
		}
		descrecord := NewBeschreibung(id, occ, version)

		descrecord.Bezeichner = record[1]
		descrecord.OGD_Kurzname = record[2]
		descrecord.CKAN_Feld = record[3]
		descrecord.Anzahl = byte(record[4][0])
		descrecord.Definition_DE = record[5]
		descrecord.Erlauterung = record[6]
		descrecord.Beispiel = record[7]
		descrecord.ONA2270 = record[8]
		descrecord.ISO19115 = record[9]
		descrecord.RDFProperty = record[10]
		descrecord.Definition_EN = record[11]

		spec[id] = descrecord
	}
	log.Printf("Info: Read %d %s specifiaction records", len(spec), version)

	return spec, nil
}
<commit_msg>change the container type keeping an OGD-AT Beschreibung from a map to an ordered slice<commit_after>package ogdat

import (
	"encoding/csv"
	"io"
	"log"
	"os"
	"strconv"
)

/*	Version10 = "OGD Austria Metadata 1.0" // Version 1.0: 24.10.2011
	Version11 = "OGD Austria Metadata 1.1" // Version 1.1: 12.03.2012
	Version20 = "OGD Austria Metadata 2.0" // Version 2.0: 10.10.2012
	Version21 = "OGD Austria Metadata 2.1" // Version 2.1: 15.10.2012
*/
type OGDSet []*Beschreibung

var specification = make(map[string]OGDSet)

type Occurrence int

const (
	OccUndef Occurrence = iota
	OccRequired
	OccOptional
)

func (desc *Beschreibung) Version() string {
	return desc.version
}

func (desc *Beschreibung) Occurrence() Occurrence {
	return desc.occurrence
}

type Beschreibung struct {
	ID            int
	Bezeichner    string
	OGD_Kurzname  string
	CKAN_Feld     string
	Anzahl        byte
	Definition_DE string
	Erlauterung   string
	Beispiel      string
	ONA2270       string
	ISO19115      string
	RDFProperty   string
	Definition_EN string
	occurrence    Occurrence
	version       string
}

func NewBeschreibung(ID int, occur Occurrence, ver string) *Beschreibung {
	return &Beschreibung{ID: ID, occurrence: occur, version: ver}
}

func (set OGDSet) GetSpecForID(id int) *Beschreibung {
	if set != nil {
		for idx, elm := range set {
			if elm.ID == id {
				return set[idx]
			}
		}
	}
	return nil
}

func Register(version, specfile string) {
	specmap, _ := Loadogdatspec(version, specfile)
	specification[version] = specmap
}

func Loadogdatspec(version, filename string) (OGDSet, error) {
	reader, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer reader.Close()
	spec := make(OGDSet, 0)
	csvreader := csv.NewReader(reader)
	csvreader.Comma = '|'
	csvreader.LazyQuotes = true

	// skip the first line as it contains the field description
	record, err := csvreader.Read()

	for record, err = csvreader.Read(); err != io.EOF; record, err = csvreader.Read() {
		id, _ := strconv.Atoi(record[0])
		var occ Occurrence
		switch record[12][0] {
		case 'R':
			occ = OccRequired
		case 'O':
			occ = OccOptional
		}
		descrecord := NewBeschreibung(id, occ, version)

		descrecord.Bezeichner = record[1]
		descrecord.OGD_Kurzname = record[2]
		descrecord.CKAN_Feld = record[3]
		descrecord.Anzahl = byte(record[4][0])
		descrecord.Definition_DE = record[5]
		descrecord.Erlauterung = record[6]
		descrecord.Beispiel = record[7]
		descrecord.ONA2270 = record[8]
		descrecord.ISO19115 = record[9]
		descrecord.RDFProperty = record[10]
		descrecord.Definition_EN = record[11]

		spec = append(spec, descrecord)
	}
	log.Printf("Info: Read %d %s specifiaction records", len(spec), version)

	return spec, nil
}
<|endoftext|>


<commit_before>package ogdat

import (
	"reflect"
	"strconv"
	"strings"
)

/*	Version10 = "OGD Austria Metadata 1.0" // Version 1.0: 24.10.2011
	Version11 = "OGD Austria Metadata 1.1" // Version 1.1: 12.03.2012
	Version20 = "OGD Austria Metadata 2.0" // Version 2.0: 10.10.2012
	Version21 = "OGD Austria Metadata 2.1" // Version 2.1: 15.10.2012
*/

var specification = make(map[string]*OGDSet)

type Occurrence int

const (
	OccUndef Occurrence = iota
	OccRequired
	OccOptional
)

type Beschreibung struct {
	ID            int
	Bezeichner    string
	OGD_Kurzname  string
	CKAN_Feld     string
	Anzahl        string
	Definition_DE string
	Erlauterung   string
	Beispiel      string
	ONA2270       string
	ISO19115      string
	RDFProperty   string
	Definition_EN string
	occurrence    Occurrence
	version       string
}

func NewBeschreibung(ID int, occur Occurrence, ver string) *Beschreibung {
	return &Beschreibung{ID: ID, occurrence: occur, version: ver}
}

func (desc *Beschreibung) Version() string {
	return desc.version
}

func (desc *Beschreibung) Occurrence() Occurrence {
	return desc.occurrence
}

func (desc *Beschreibung) IsRequired() bool {
	return desc.occurrence == OccRequired
}

type OGDSet struct {
	Label        []string
	Beschreibung []*Beschreibung
}

func (set *OGDSet) GetBeschreibungForID(id int) (*Beschreibung, string) {
	if set != nil {
		for idx, elm := range set.Beschreibung {
			if elm.ID == id {
				return set.Beschreibung[idx], set.Label[idx]
			}
		}
	}
	return nil, ""
}

func RegisterFromCSVFile(version, specfile string) *OGDSet {
	set, _ := Loadogdatspec(version, specfile)
	specification[version] = set
	return set
}

func Register(version string, set *OGDSet) *OGDSet {
	specification[version] = set
	return set
}

func GetOGDSetForVersion(version string) *OGDSet {
	return specification[version]
}

func GetIDFromMetaDataStructField(val reflect.StructField) int {
	ids := val.Tag.Get("ogdat")
	if idx := strings.Index(ids, "ID"); idx > -1 {
		ids = ids[idx+len("ID")+1:]
		if idx = strings.IndexRune(ids, ','); idx > -1 {
			ids = ids[:idx]
		}
		if i, err := strconv.Atoi(ids); err == nil {
			return i
		}
	}
	return -1
}

// Return if a value is nil. Will panic if the value is not a pointer
func MetaDataStructFieldIsNil(val interface{}) bool {
	v := reflect.ValueOf(val)
	if v.Kind() != reflect.Ptr {
		panic("Struct field is not a pointer")
	}
	return v.IsNil()
}
<commit_msg>* rename MetaDataStructFieldIsNil --> IsNil * IsNil returns false, if value is not a pointer * GetBeschreibungForID: return struct and corresponding OGD_Kurzname<commit_after>package ogdat

import (
	"reflect"
	"strconv"
	"strings"
)

/*	Version10 = "OGD Austria Metadata 1.0" // Version 1.0: 24.10.2011
	Version11 = "OGD Austria Metadata 1.1" // Version 1.1: 12.03.2012
	Version20 = "OGD Austria Metadata 2.0" // Version 2.0: 10.10.2012
	Version21 = "OGD Austria Metadata 2.1" // Version 2.1: 15.10.2012
*/

var specification = make(map[string]*OGDSet)

type Occurrence int

const (
	OccUndef Occurrence = iota
	OccRequired
	OccOptional
)

type Beschreibung struct {
	ID            int
	Bezeichner    string
	OGD_Kurzname  string
	CKAN_Feld     string
	Anzahl        string
	Definition_DE string
	Erlauterung   string
	Beispiel      string
	ONA2270       string
	ISO19115      string
	RDFProperty   string
	Definition_EN string
	occurrence    Occurrence
	version       string
}

func NewBeschreibung(ID int, occur Occurrence, ver string) *Beschreibung {
	return &Beschreibung{ID: ID, occurrence: occur, version: ver}
}

func (desc *Beschreibung) Version() string {
	return desc.version
}

func (desc *Beschreibung) Occurrence() Occurrence {
	return desc.occurrence
}

func (desc *Beschreibung) IsRequired() bool {
	return desc.occurrence == OccRequired
}

type OGDSet struct {
	Label        []string
	Beschreibung []*Beschreibung
}

func (set *OGDSet) GetBeschreibungForID(id int) (*Beschreibung, string) {
	if set != nil {
		for idx, elm := range set.Beschreibung {
			if elm.ID == id {
				return set.Beschreibung[idx], set.Beschreibung[idx].OGD_Kurzname
			}
		}
	}
	return nil, ""
}

func RegisterFromCSVFile(version, specfile string) *OGDSet {
	set, _ := Loadogdatspec(version, specfile)
	specification[version] = set
	return set
}

func Register(version string, set *OGDSet) *OGDSet {
	specification[version] = set
	return set
}

func GetOGDSetForVersion(version string) *OGDSet {
	return specification[version]
}

func GetIDFromMetaDataStructField(val reflect.StructField) int {
	ids := val.Tag.Get("ogdat")
	if idx := strings.Index(ids, "ID"); idx > -1 {
		ids = ids[idx+len("ID")+1:]
		if idx = strings.IndexRune(ids, ','); idx > -1 {
			ids = ids[:idx]
		}
		if i, err := strconv.Atoi(ids); err == nil {
			return i
		}
	}
	return -1
}

// Return if a value is nil. If value is nor a pointer, return will be false
func IsNil(val interface{}) bool {
	v := reflect.ValueOf(val)
	if v.Kind() != reflect.Ptr {
		return false
	}
	return v.IsNil()
}
<|endoftext|>


<commit_before>// Olive - a lightweight simple Golang web application framework .
/*
	// Example
	package main

	import ( "github.com/alash3al/olive-go"; "net/http" )

	func main(){
		app := olive.NewApp()

		// create new route
		// Path = "*" --> any path
		// Method = "*" --> any method
		// Host = "*" --> any host
		// "*" -> is the default value for each property
		// Exclusive =  true, "true is the default"
		// 				it means that once it matches the current request,
		//				stop and don't run similar routes with the same request properties .

		app.Factory().SetPath("/tst").SetHost("*").SetMethod("*").SetFunc(func(c *olive.Context){
			c.Res.Write([]byte("tst"))
		})

		app.Factory().SetPath(`/page/([^/]+)`).SetHost("*").SetMethod("*").SetFunc(func(c *olive.Context){
			c.Res.Write([]byte("current-page: " + c.Args[0]))
		})

		app.Factory().SetPath("*").SetHost("cdn.mysite.com").SetHandler(http.FileServer(http.Dir(`/root/cdn/`)))

		app.Add(
			olive.NewRoute().SetPath("/new"), // ... and so on, multiple routes are supported
		)

		app.ListenAndServe(":80")
		// or
		// app.ListenAndServeTLS(":433", ........)
	}
*/
package olive

// Our Requirements
import (
	"net/http"
	"regexp"
	"strings"
)

// A Context is the a request + response + <some properties>
type Context struct {
	Req  *http.Request
	Res  http.ResponseWriter
	Args []string
}

// A Route is a request middleware
type Route struct {
	method    string
	host      string
	path      *regexp.Regexp
	exclusive bool
	callback  func(*Context)
}

// Construct a new Route instance
func NewRoute() *Route {
	r := &Route{}
	r.SetPath("*").SetMethod("*").SetHost("*").SetFunc(func(c *Context) {
		http.NotFound(c.Res, c.Req)
	})
	return r
}

// set the "method" of the route
// `*` means any request method
func (this *Route) SetMethod(m string) *Route {
	this.method = strings.TrimSpace(strings.ToUpper(m))
	return this
}

// set the host of the router
// `*` means any host
func (this *Route) SetHost(v string) *Route {
	this.host = strings.TrimSpace(v)
	return this
}

// set the "path" of the route
// `*` means any path
func (this *Route) SetPath(p string) *Route {
	if p != "*" {
		p = regexp.MustCompilePOSIX(`/+`).ReplaceAllString((`/` + strings.TrimSpace(p) + `/`), `/`)
		this.path = regexp.MustCompilePOSIX(`^` + (p) + `$`)
	} else {
		this.path = regexp.MustCompilePOSIX(`(.*?)?`)
	}
	return this
}

// Just stop when the current request matches this route and don't run other similar routes ?
func (this *Route) SetExclusive(s bool) *Route {
	this.exclusive = s
	return this
}

// set the "func" of the route
func (this *Route) SetFunc(fn func(*Context)) *Route {
	this.callback = fn
	return this
}

// set the "http.Handler" of the route
func (this *Route) SetHandler(h http.Handler) *Route {
	return this.SetFunc(func(c *Context) { h.ServeHTTP(c.Res, c.Req) })
}

// Main middlewares container
type App struct {
	routes []*Route
}

// Create a new instance
func NewApp() *App {
	this := new(App)
	this.routes = []*Route{}
	return this
}

// Returns a new Route
func (this *App) Factory() *Route {
	r := NewRoute()
	this.routes = append(this.routes, r)
	return r
}

// Add a previously created route
func (this *App) Add(routes ...*Route) *App {
	this.routes = append(this.routes, routes...)
	return this
}

// Clear all routes
func (this *App) Clear() *App {
	this.routes = []*Route{}
	return this
}

// Dispatch all registered routes
func (this *App) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	method := strings.ToUpper(r.Method)
	host := strings.SplitN(r.Host, `:`, 2)[0]
	path := regexp.MustCompilePOSIX(`/+`).ReplaceAllString(`/`+r.URL.Path+`/`, `/`)
	for _, route := range this.routes {
		if route.path.MatchString(path) {
			if (route.method == `*`) || (regexp.MustCompilePOSIX(`^` + (route.method) + `$`).MatchString(method)) {
				if (route.host == `*`) || (regexp.MustCompilePOSIX(`^` + (route.host) + `$`).MatchString(host)) {
					args := []string{}
					if route.host != `*` {
						args = append(args, regexp.MustCompilePOSIX(`^`+(route.host)+`$`).FindAllStringSubmatch(host, -1)[0][1:]...)
					}
					args = append(args, route.path.FindAllStringSubmatch(path, -1)[0][1:]...)
					route.callback(&Context{r, w, args})
					if route.exclusive {
						break
					}
				}
			}
		}
	}
}

// serving HTTP traffic
func (this *App) ListenAndServe(addr string) error {
	return http.ListenAndServe(addr, this)
}

// serving HTTPS traffic
func (this *App) ListenAndServeTLS(addr string, certFile string, keyFile string) error {
	return http.ListenAndServeTLS(addr, certFile, keyFile, this)
}
<commit_msg>Delete olive.go<commit_after><|endoftext|>


<commit_before>package main

import (
	"fmt"
	"math/rand"
	"net/http"
	"net/http/httptest"
	"net/url"
	"os"
	"reflect"
	"testing"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/boltdb/bolt"
)

const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
const (
	letterIdxBits = 6                    // 6 bits to represent a letter index
	letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
	letterIdxMax  = 63 / letterIdxBits   // # of letter indices fitting in 63 bits
)

const testingDatabaseName = "test.db" // very original

// Client structure to be injected into functions to perform HTTP calls
type Client struct {
	HTTPClient *http.Client
}

func expect(t *testing.T, a interface{}, b interface{}) {
	if a != b {
		t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
	}
}

func refute(t *testing.T, a interface{}, b interface{}) {
	if a == b {
		t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
	}
}

// TestDB - holds connection to database during tests
var TestDB *bolt.DB

func testTools(code int, body string) (*httptest.Server, *DBClient) {

	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(code)
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, body)
	}))

	tr := &http.Transport{
		Proxy: func(req *http.Request) (*url.URL, error) {
			return url.Parse(server.URL)
		},
	}
	// creating random buckets for everyone!
	bucket := GetRandomName(10)
	cache := Cache{db: TestDB, requestsBucket: bucket}

	cfg := InitSettings()
	// preparing client
	dbClient := &DBClient{
		http:  &http.Client{Transport: tr},
		cache: cache,
		cfg:   cfg,
	}
	return server, dbClient
}

var src = rand.NewSource(time.Now().UnixNano())

// GetRandomName - provides random name for buckets. Each test case gets it's own bucket
func GetRandomName(n int) []byte {
	b := make([]byte, n)
	for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
		if remain == 0 {
			cache, remain = src.Int63(), letterIdxMax
		}
		if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
			b[i] = letterBytes[idx]
			i--
		}
		cache >>= letterIdxBits
		remain--
	}

	return b
}

func setup() {
	// we don't really want to see what's happening
	log.SetLevel(log.FatalLevel)
	db := getDB(testingDatabaseName)
	TestDB = db
}

// teardown does some cleanup after tests
func teardown() {
	TestDB.Close()
	os.Remove(testingDatabaseName)
}
<commit_msg>adding counter to test tools<commit_after>package main

import (
	"fmt"
	"math/rand"
	"net/http"
	"net/http/httptest"
	"net/url"
	"os"
	"reflect"
	"testing"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/boltdb/bolt"
)

const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
const (
	letterIdxBits = 6                    // 6 bits to represent a letter index
	letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
	letterIdxMax  = 63 / letterIdxBits   // # of letter indices fitting in 63 bits
)

const testingDatabaseName = "test.db" // very original

// Client structure to be injected into functions to perform HTTP calls
type Client struct {
	HTTPClient *http.Client
}

func expect(t *testing.T, a interface{}, b interface{}) {
	if a != b {
		t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
	}
}

func refute(t *testing.T, a interface{}, b interface{}) {
	if a == b {
		t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
	}
}

// TestDB - holds connection to database during tests
var TestDB *bolt.DB

func testTools(code int, body string) (*httptest.Server, *DBClient) {

	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(code)
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, body)
	}))

	tr := &http.Transport{
		Proxy: func(req *http.Request) (*url.URL, error) {
			return url.Parse(server.URL)
		},
	}
	// creating random buckets for everyone!
	bucket := GetRandomName(10)
	cache := Cache{db: TestDB, requestsBucket: bucket}

	cfg := InitSettings()
	counter := NewModeCounter()
	// preparing client
	dbClient := &DBClient{
		http:    &http.Client{Transport: tr},
		cache:   cache,
		cfg:     cfg,
		counter: counter,
	}
	return server, dbClient
}

var src = rand.NewSource(time.Now().UnixNano())

// GetRandomName - provides random name for buckets. Each test case gets it's own bucket
func GetRandomName(n int) []byte {
	b := make([]byte, n)
	for i, cache, remain := n-1, src.Int63(), letterIdxMax; i >= 0; {
		if remain == 0 {
			cache, remain = src.Int63(), letterIdxMax
		}
		if idx := int(cache & letterIdxMask); idx < len(letterBytes) {
			b[i] = letterBytes[idx]
			i--
		}
		cache >>= letterIdxBits
		remain--
	}

	return b
}

func setup() {
	// we don't really want to see what's happening
	log.SetLevel(log.FatalLevel)
	db := getDB(testingDatabaseName)
	TestDB = db
}

// teardown does some cleanup after tests
func teardown() {
	TestDB.Close()
	os.Remove(testingDatabaseName)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"errors"
	"testing"
	"time"

	"github.com/AlexanderThaller/logger"
	"github.com/juju/errgo"
)

const (
	Project      = "Test1"
	TestDataPath = "testdata"
)

var (
	StartTime = time.Time{}
	EndTime   = time.Time{}
)

func testCommand(action string) (*Command, *bytes.Buffer) {
	buffer := bytes.NewBufferString("")
	command := NewCommand(buffer)

	command.DataPath = TestDataPath
	command.EndTime = time.Now()
	command.StartTime = time.Time{}
	command.Action = action

	return command, buffer
}

func testCommandRunOutput(t *testing.T, l logger.Logger, action, expected string) {
	command, buffer := testCommand(action)

	err := command.Run()
	got := buffer.String()

	testerr_output(t, l, err, got, expected)
}

func compareRecord(t *testing.T, l logger.Logger, err error, newrecord, record Record) {
	if record == nil {
		l.Alert("record is nil")
		t.Fail()
		return
	}
	if newrecord == nil {
		l.Alert("newrecord is nil")
		t.Fail()
		return
	}

	{
		message := "Newrecord action is not the same with record action"
		got := newrecord.GetAction()
		expected := record.GetAction()
		testerr(t, l, message, err, got, expected)
	}

	{
		message := "Newrecord project is not the same with record project"
		got := newrecord.GetProject()
		expected := record.GetProject()
		testerr(t, l, message, err, got, expected)
	}

	{
		message := "Newrecord timestamp is not the same with record timestamp"
		got := newrecord.GetTimeStamp()
		expected := record.GetTimeStamp()
		testerr(t, l, message, err, got, expected)
	}

	{
		message := "Newrecord value is not the same with record value"
		got := newrecord.GetValue()
		expected := record.GetValue()
		testerr(t, l, message, err, got, expected)
	}
}

func test_output(t *testing.T, l logger.Logger, got, expected interface{}) {
	message := "Did not get the expected output"
	test(t, l, message, got, expected)
}

func test(t *testing.T, l logger.Logger, message string, got, expected interface{}) {
	testerr(t, l, message, errors.New("no error"), got, expected)
}

func testerr_output(t *testing.T, l logger.Logger, err error, got, expected interface{}) {
	message := "Did not get the expected output"
	testerr(t, l, message, err, got, expected)
}

func testerr(t *testing.T, l logger.Logger, message string, err error, got, expected interface{}) {
	if got == expected {
		return
	}

	l.Error("MESSAGE : ", message)
	if err != nil {
		l.Notice("ERROR: ", errgo.Details(err))
	}
	l.Notice("GOT: ", got)
	l.Notice("EXPECTED: ", expected)
	t.Fail()
}
<commit_msg>will now print differences if testing failes and the type is a string.<commit_after>package main

import (
	"bytes"
	"errors"
	"fmt"
	"reflect"
	"testing"
	"time"

	"github.com/AlexanderThaller/logger"
	"github.com/juju/errgo"
	"github.com/sergi/go-diff/diffmatchpatch"
)

const (
	Project      = "Test1"
	TestDataPath = "testdata"
)

var (
	StartTime = time.Time{}
	EndTime   = time.Time{}
)

func testCommand(action string) (*Command, *bytes.Buffer) {
	buffer := bytes.NewBufferString("")
	command := NewCommand(buffer)

	command.DataPath = TestDataPath
	command.EndTime = time.Now()
	command.StartTime = time.Time{}
	command.Action = action

	return command, buffer
}

func testCommandRunOutput(t *testing.T, l logger.Logger, action, expected string) {
	command, buffer := testCommand(action)

	err := command.Run()
	got := buffer.String()

	testerr_output(t, l, err, got, expected)
}

func compareRecord(t *testing.T, l logger.Logger, err error, newrecord, record Record) {
	if record == nil {
		l.Alert("record is nil")
		t.Fail()
		return
	}
	if newrecord == nil {
		l.Alert("newrecord is nil")
		t.Fail()
		return
	}

	{
		message := "Newrecord action is not the same with record action"
		got := newrecord.GetAction()
		expected := record.GetAction()
		testerr(t, l, message, err, got, expected)
	}

	{
		message := "Newrecord project is not the same with record project"
		got := newrecord.GetProject()
		expected := record.GetProject()
		testerr(t, l, message, err, got, expected)
	}

	{
		message := "Newrecord timestamp is not the same with record timestamp"
		got := newrecord.GetTimeStamp()
		expected := record.GetTimeStamp()
		testerr(t, l, message, err, got, expected)
	}

	{
		message := "Newrecord value is not the same with record value"
		got := newrecord.GetValue()
		expected := record.GetValue()
		testerr(t, l, message, err, got, expected)
	}
}

func test_output(t *testing.T, l logger.Logger, got, expected interface{}) {
	message := "Did not get the expected output"
	test(t, l, message, got, expected)
}

func test(t *testing.T, l logger.Logger, message string, got, expected interface{}) {
	testerr(t, l, message, errors.New("no error"), got, expected)
}

func testerr_output(t *testing.T, l logger.Logger, err error, got, expected interface{}) {
	message := "Did not get the expected output"
	testerr(t, l, message, err, got, expected)
}

func testerr(t *testing.T, l logger.Logger, message string, err error, got, expected interface{}) {
	if got == expected {
		return
	}

	l.Error("MESSAGE : ", message)
	if err != nil {
		l.Notice("ERROR: ", errgo.Details(err))
	}
	l.Notice("GOT:\n", got)
	l.Notice("EXPECTED:\n", expected)

	if reflect.TypeOf(got).Name() == "string" {
		differ := diffmatchpatch.New()
		diff := differ.DiffMain(expected.(string), got.(string), true)

		l.Notice("DIFF:")
		for _, line := range diff {
			switch line.Type {
			case diffmatchpatch.DiffDelete:
				fmt.Print("\033[32m" + line.Text + "\033[0m")
			case diffmatchpatch.DiffInsert:
				fmt.Print("\033[31m" + line.Text + "\033[0m")
			default:
				fmt.Print(line.Text)
			}
		}
	}

	t.Fail()
}
<|endoftext|>


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

/*
TODO(krzysied): This measurement should replace api_responsiveness.go.
*/

package slos

import (
	"fmt"
	"math"
	"sort"
	"strconv"
	"time"

	"github.com/prometheus/common/model"
	"k8s.io/apimachinery/pkg/util/sets"
	clientset "k8s.io/client-go/kubernetes"
	"k8s.io/klog"
	"k8s.io/perf-tests/clusterloader2/pkg/errors"
	"k8s.io/perf-tests/clusterloader2/pkg/measurement"
	measurementutil "k8s.io/perf-tests/clusterloader2/pkg/measurement/util"
	"k8s.io/perf-tests/clusterloader2/pkg/util"
)

const (
	apiResponsivenessPrometheusMeasurementName = "APIResponsivenessPrometheus"

	// latencyQuery %v should be replaced with query window size.
	latencyQuery = "quantile_over_time(0.99, apiserver:apiserver_request_latency:histogram_quantile[%v])"
	// countQuery %v should be replaced with query window size.
	countQuery = "sum(increase(apiserver_request_duration_seconds_count[%v])) by (resource, subresource, scope, verb)"

	latencyWindowSize = 5 * time.Minute
)

func init() {
	measurement.Register(apiResponsivenessPrometheusMeasurementName, createAPIResponsivenessPrometheusMeasurement)
}

func createAPIResponsivenessPrometheusMeasurement() measurement.Measurement {
	return &apiResponsivenessMeasurementPrometheus{}
}

type apiResponsivenessMeasurementPrometheus struct {
	startTime time.Time
	apiCalls  map[string]*apiCall
}

func (a *apiResponsivenessMeasurementPrometheus) Execute(config *measurement.MeasurementConfig) ([]measurement.Summary, error) {
	var summaries []measurement.Summary

	if config.PrometheusFramework == nil {
		klog.Errorf("%s: prometheus framework is not provided!")
		// TODO(#498): for the testing purpose metric is not returning error.
		return summaries, nil
	}

	action, err := util.GetString(config.Params, "action")
	if err != nil {
		return summaries, err
	}

	switch action {
	case "start":
		a.start()
	case "gather":
		summary, err := a.gather(config.PrometheusFramework.GetClientSets().GetClient())
		if err == nil || errors.IsMetricViolationError(err) {
			summaries = append(summaries, summary)
		}
		return summaries, err
	default:
		return summaries, fmt.Errorf("unknown action %v", action)
	}

	return summaries, nil
}

// Dispose cleans up after the measurement.
func (a *apiResponsivenessMeasurementPrometheus) Dispose() {}

// String returns string representation of this measurement.
func (*apiResponsivenessMeasurementPrometheus) String() string {
	return apiResponsivenessPrometheusMeasurementName
}

func (a *apiResponsivenessMeasurementPrometheus) start() {
	klog.Infof("%s: starting latency metrics in apiserver...", a)
	a.startTime = time.Now()
}

func (a *apiResponsivenessMeasurementPrometheus) gather(c clientset.Interface) (measurement.Summary, error) {
	apiCalls, err := a.gatherApiCalls(c)
	if err != nil {
		klog.Errorf("%s: samples gathering error: %v", a, err)
	}

	metrics := &apiResponsiveness{ApiCalls: apiCalls}
	sort.Sort(sort.Reverse(metrics))
	var badMetrics []string
	top := 5
	for i := range metrics.ApiCalls {
		isBad := false
		latencyThreshold := getLatencyThreshold(&metrics.ApiCalls[i])
		if metrics.ApiCalls[i].Latency.Perc99 > latencyThreshold {
			isBad = true
			badMetrics = append(badMetrics, fmt.Sprintf("got: %+v; expected perc99 <= %v", metrics.ApiCalls[i], latencyThreshold))
		}
		if top > 0 || isBad {
			top--
			prefix := ""
			if isBad {
				prefix = "WARNING "
			}
			klog.Infof("%s: %vTop latency metric: %+v; threshold: %v", a, prefix, metrics.ApiCalls[i], latencyThreshold)
		}
	}
	// TODO(#498): For testing purpose this metric will never return metric violation error.
	// The code below should be
	// if len(badMetrics) > 0 {
	// 	return &apiResponsivenessPrometheus{metrics}, errors.NewMetricViolationError("top latency metric", fmt.Sprintf("there should be no high-latency requests, but: %v", badMetrics))
	// }
	return &apiResponsivenessPrometheus{metrics}, nil
}

func (a *apiResponsivenessMeasurementPrometheus) gatherApiCalls(c clientset.Interface) ([]apiCall, error) {
	measurementEnd := time.Now()
	measurementDuration := measurementEnd.Sub(a.startTime)
	// Latency measurement is based on 5m window aggregation,
	// therefore first 5 minutes of the test should be skipped.
	latencyMeasurementDuration := measurementDuration - latencyWindowSize
	if latencyMeasurementDuration < time.Minute {
		latencyMeasurementDuration = time.Minute
	}
	timeBoundedLatencyQuery := fmt.Sprintf(latencyQuery, measurementutil.ToPrometheusTime(latencyMeasurementDuration))
	latencySamples, err := measurementutil.ExecutePrometheusQuery(c, timeBoundedLatencyQuery, measurementEnd)
	if err != nil {
		return nil, err
	}
	timeBoundedCountQuery := fmt.Sprintf(countQuery, measurementutil.ToPrometheusTime(measurementDuration))
	countSamples, err := measurementutil.ExecutePrometheusQuery(c, timeBoundedCountQuery, measurementEnd)
	if err != nil {
		return nil, err
	}
	return a.convertToApiCalls(latencySamples, countSamples)
}

func (a *apiResponsivenessMeasurementPrometheus) convertToApiCalls(latencySamples, countSamples []*model.Sample) ([]apiCall, error) {
	apiCalls := make(map[string]*apiCall)
	ignoredResources := sets.NewString("events")
	// TODO(krzysied): figure out why we're getting non-capitalized proxy and fix this.
	ignoredVerbs := sets.NewString("WATCH", "WATCHLIST", "PROXY", "proxy", "CONNECT")

	for _, sample := range latencySamples {
		resource := string(sample.Metric["resource"])
		subresource := string(sample.Metric["subresource"])
		verb := string(sample.Metric["verb"])
		scope := string(sample.Metric["scope"])
		quantile, err := strconv.ParseFloat(string(sample.Metric["quantile"]), 64)
		if err != nil {
			return nil, err
		}
		if ignoredResources.Has(resource) || ignoredVerbs.Has(verb) {
			continue
		}

		latency := time.Duration(float64(sample.Value) * float64(time.Second))
		addLatency(apiCalls, resource, subresource, verb, scope, quantile, latency)
	}

	for _, sample := range countSamples {
		resource := string(sample.Metric["resource"])
		subresource := string(sample.Metric["subresource"])
		verb := string(sample.Metric["verb"])
		scope := string(sample.Metric["scope"])
		if ignoredResources.Has(resource) || ignoredVerbs.Has(verb) {
			continue
		}

		count := int(math.Round(float64(sample.Value)))
		addCount(apiCalls, resource, subresource, verb, scope, count)
	}

	var result []apiCall
	for _, call := range apiCalls {
		result = append(result, *call)
	}
	return result, nil
}

func getApiCall(apiCalls map[string]*apiCall, resource, subresource, verb, scope string) *apiCall {
	key := getMetricKey(resource, subresource, verb, scope)
	call, exists := apiCalls[key]
	if !exists {
		call = &apiCall{
			Resource:    resource,
			Subresource: subresource,
			Verb:        verb,
			Scope:       scope,
		}
		apiCalls[key] = call
	}
	return call
}

func addLatency(apiCalls map[string]*apiCall, resource, subresource, verb, scope string, quantile float64, latency time.Duration) {
	call := getApiCall(apiCalls, resource, subresource, verb, scope)
	call.Latency.SetQuantile(quantile, latency)
}

func addCount(apiCalls map[string]*apiCall, resource, subresource, verb, scope string, count int) {
	if count == 0 {
		return
	}
	call := getApiCall(apiCalls, resource, subresource, verb, scope)
	call.Count = count
}

func getMetricKey(resource, subresource, verb, scope string) string {
	return fmt.Sprintf("%s|%s|%s|%s", resource, subresource, verb, scope)
}

func getLatencyThreshold(call *apiCall) time.Duration {
	isListCall := (call.Verb == "LIST")
	isClusterScopedCall := (call.Scope == "cluster")
	latencyThreshold := apiCallLatencyThreshold
	if isListCall {
		latencyThreshold = apiListCallLatencyThreshold
		if isClusterScopedCall {
			latencyThreshold = apiClusterScopeListCallThreshold
		}
	}
	return latencyThreshold
}

type apiResponsivenessPrometheus struct {
	metric *apiResponsiveness
}

// SummaryName returns name of the summary.
func (*apiResponsivenessPrometheus) SummaryName() string {
	return apiResponsivenessPrometheusMeasurementName
}

// SummaryTime returns time when summary was created.
func (a *apiResponsivenessPrometheus) SummaryTime() time.Time {
	return time.Now()
}

// PrintSummary returns summary as a string.
func (a *apiResponsivenessPrometheus) PrintSummary() (string, error) {
	return a.metric.PrintSummary()
}
<commit_msg>fixing api responsiveness prometheus log<commit_after>/*
Copyright 2018 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.
*/

/*
TODO(krzysied): This measurement should replace api_responsiveness.go.
*/

package slos

import (
	"fmt"
	"math"
	"sort"
	"strconv"
	"time"

	"github.com/prometheus/common/model"
	"k8s.io/apimachinery/pkg/util/sets"
	clientset "k8s.io/client-go/kubernetes"
	"k8s.io/klog"
	"k8s.io/perf-tests/clusterloader2/pkg/errors"
	"k8s.io/perf-tests/clusterloader2/pkg/measurement"
	measurementutil "k8s.io/perf-tests/clusterloader2/pkg/measurement/util"
	"k8s.io/perf-tests/clusterloader2/pkg/util"
)

const (
	apiResponsivenessPrometheusMeasurementName = "APIResponsivenessPrometheus"

	// latencyQuery %v should be replaced with query window size.
	latencyQuery = "quantile_over_time(0.99, apiserver:apiserver_request_latency:histogram_quantile[%v])"
	// countQuery %v should be replaced with query window size.
	countQuery = "sum(increase(apiserver_request_duration_seconds_count[%v])) by (resource, subresource, scope, verb)"

	latencyWindowSize = 5 * time.Minute
)

func init() {
	measurement.Register(apiResponsivenessPrometheusMeasurementName, createAPIResponsivenessPrometheusMeasurement)
}

func createAPIResponsivenessPrometheusMeasurement() measurement.Measurement {
	return &apiResponsivenessMeasurementPrometheus{}
}

type apiResponsivenessMeasurementPrometheus struct {
	startTime time.Time
	apiCalls  map[string]*apiCall
}

// Execute supports two actions:
// - start - Stores the measurement starting time.
// - gather - Gathers and prints current api server latency data based on data collected by prometheus server.
func (a *apiResponsivenessMeasurementPrometheus) Execute(config *measurement.MeasurementConfig) ([]measurement.Summary, error) {
	var summaries []measurement.Summary

	if config.PrometheusFramework == nil {
		klog.Warning("%s: Prometheus is disabled, skipping the measurement!", a)
		// TODO(#498): for the testing purpose metric is not returning error.
		return summaries, nil
	}

	action, err := util.GetString(config.Params, "action")
	if err != nil {
		return summaries, err
	}

	switch action {
	case "start":
		a.start()
	case "gather":
		summary, err := a.gather(config.PrometheusFramework.GetClientSets().GetClient())
		if err == nil || errors.IsMetricViolationError(err) {
			summaries = append(summaries, summary)
		}
		return summaries, err
	default:
		return summaries, fmt.Errorf("unknown action %v", action)
	}

	return summaries, nil
}

// Dispose cleans up after the measurement.
func (a *apiResponsivenessMeasurementPrometheus) Dispose() {}

// String returns string representation of this measurement.
func (*apiResponsivenessMeasurementPrometheus) String() string {
	return apiResponsivenessPrometheusMeasurementName
}

func (a *apiResponsivenessMeasurementPrometheus) start() {
	klog.Infof("%s: starting latency metrics in apiserver...", a)
	a.startTime = time.Now()
}

func (a *apiResponsivenessMeasurementPrometheus) gather(c clientset.Interface) (measurement.Summary, error) {
	apiCalls, err := a.gatherApiCalls(c)
	if err != nil {
		klog.Errorf("%s: samples gathering error: %v", a, err)
	}

	metrics := &apiResponsiveness{ApiCalls: apiCalls}
	sort.Sort(sort.Reverse(metrics))
	var badMetrics []string
	top := 5
	for i := range metrics.ApiCalls {
		isBad := false
		latencyThreshold := getLatencyThreshold(&metrics.ApiCalls[i])
		if metrics.ApiCalls[i].Latency.Perc99 > latencyThreshold {
			isBad = true
			badMetrics = append(badMetrics, fmt.Sprintf("got: %+v; expected perc99 <= %v", metrics.ApiCalls[i], latencyThreshold))
		}
		if top > 0 || isBad {
			top--
			prefix := ""
			if isBad {
				prefix = "WARNING "
			}
			klog.Infof("%s: %vTop latency metric: %+v; threshold: %v", a, prefix, metrics.ApiCalls[i], latencyThreshold)
		}
	}
	// TODO(#498): For testing purpose this metric will never return metric violation error.
	// The code below should be
	// if len(badMetrics) > 0 {
	// 	return &apiResponsivenessPrometheus{metrics}, errors.NewMetricViolationError("top latency metric", fmt.Sprintf("there should be no high-latency requests, but: %v", badMetrics))
	// }
	return &apiResponsivenessPrometheus{metrics}, nil
}

func (a *apiResponsivenessMeasurementPrometheus) gatherApiCalls(c clientset.Interface) ([]apiCall, error) {
	measurementEnd := time.Now()
	measurementDuration := measurementEnd.Sub(a.startTime)
	// Latency measurement is based on 5m window aggregation,
	// therefore first 5 minutes of the test should be skipped.
	latencyMeasurementDuration := measurementDuration - latencyWindowSize
	if latencyMeasurementDuration < time.Minute {
		latencyMeasurementDuration = time.Minute
	}
	timeBoundedLatencyQuery := fmt.Sprintf(latencyQuery, measurementutil.ToPrometheusTime(latencyMeasurementDuration))
	latencySamples, err := measurementutil.ExecutePrometheusQuery(c, timeBoundedLatencyQuery, measurementEnd)
	if err != nil {
		return nil, err
	}
	timeBoundedCountQuery := fmt.Sprintf(countQuery, measurementutil.ToPrometheusTime(measurementDuration))
	countSamples, err := measurementutil.ExecutePrometheusQuery(c, timeBoundedCountQuery, measurementEnd)
	if err != nil {
		return nil, err
	}
	return a.convertToApiCalls(latencySamples, countSamples)
}

func (a *apiResponsivenessMeasurementPrometheus) convertToApiCalls(latencySamples, countSamples []*model.Sample) ([]apiCall, error) {
	apiCalls := make(map[string]*apiCall)
	ignoredResources := sets.NewString("events")
	// TODO(krzysied): figure out why we're getting non-capitalized proxy and fix this.
	ignoredVerbs := sets.NewString("WATCH", "WATCHLIST", "PROXY", "proxy", "CONNECT")

	for _, sample := range latencySamples {
		resource := string(sample.Metric["resource"])
		subresource := string(sample.Metric["subresource"])
		verb := string(sample.Metric["verb"])
		scope := string(sample.Metric["scope"])
		quantile, err := strconv.ParseFloat(string(sample.Metric["quantile"]), 64)
		if err != nil {
			return nil, err
		}
		if ignoredResources.Has(resource) || ignoredVerbs.Has(verb) {
			continue
		}

		latency := time.Duration(float64(sample.Value) * float64(time.Second))
		addLatency(apiCalls, resource, subresource, verb, scope, quantile, latency)
	}

	for _, sample := range countSamples {
		resource := string(sample.Metric["resource"])
		subresource := string(sample.Metric["subresource"])
		verb := string(sample.Metric["verb"])
		scope := string(sample.Metric["scope"])
		if ignoredResources.Has(resource) || ignoredVerbs.Has(verb) {
			continue
		}

		count := int(math.Round(float64(sample.Value)))
		addCount(apiCalls, resource, subresource, verb, scope, count)
	}

	var result []apiCall
	for _, call := range apiCalls {
		result = append(result, *call)
	}
	return result, nil
}

func getApiCall(apiCalls map[string]*apiCall, resource, subresource, verb, scope string) *apiCall {
	key := getMetricKey(resource, subresource, verb, scope)
	call, exists := apiCalls[key]
	if !exists {
		call = &apiCall{
			Resource:    resource,
			Subresource: subresource,
			Verb:        verb,
			Scope:       scope,
		}
		apiCalls[key] = call
	}
	return call
}

func addLatency(apiCalls map[string]*apiCall, resource, subresource, verb, scope string, quantile float64, latency time.Duration) {
	call := getApiCall(apiCalls, resource, subresource, verb, scope)
	call.Latency.SetQuantile(quantile, latency)
}

func addCount(apiCalls map[string]*apiCall, resource, subresource, verb, scope string, count int) {
	if count == 0 {
		return
	}
	call := getApiCall(apiCalls, resource, subresource, verb, scope)
	call.Count = count
}

func getMetricKey(resource, subresource, verb, scope string) string {
	return fmt.Sprintf("%s|%s|%s|%s", resource, subresource, verb, scope)
}

func getLatencyThreshold(call *apiCall) time.Duration {
	isListCall := (call.Verb == "LIST")
	isClusterScopedCall := (call.Scope == "cluster")
	latencyThreshold := apiCallLatencyThreshold
	if isListCall {
		latencyThreshold = apiListCallLatencyThreshold
		if isClusterScopedCall {
			latencyThreshold = apiClusterScopeListCallThreshold
		}
	}
	return latencyThreshold
}

type apiResponsivenessPrometheus struct {
	metric *apiResponsiveness
}

// SummaryName returns name of the summary.
func (*apiResponsivenessPrometheus) SummaryName() string {
	return apiResponsivenessPrometheusMeasurementName
}

// SummaryTime returns time when summary was created.
func (a *apiResponsivenessPrometheus) SummaryTime() time.Time {
	return time.Now()
}

// PrintSummary returns summary as a string.
func (a *apiResponsivenessPrometheus) PrintSummary() (string, error) {
	return a.metric.PrintSummary()
}
<|endoftext|>


<commit_before>package limiter

import (
	"sync"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/uber/tchannel-go/testutils"
)

func TestSerial(t *testing.T) {
	run := New(1000 /* maxRequests */, 100000 /* rps */, time.Second)
	for i := 0; i < 1000; i++ {
		assert.True(t, run.More(), "Request %v should succeed", i)
	}
	for i := 0; i < 1000; i++ {
		assert.False(t, run.More(), "Request %v should fail", i)
	}
}

func TestRateLimited(t *testing.T) {
	run := New(1000 /* maxRequests */, 100 /* rps */, time.Second)
	assert.True(t, run.More(), "First request should succeed")
	started := time.Now()
	assert.True(t, run.More(), "Second request should succeed")
	elapsed := time.Since(started)

	// Since RPS is 100, we should only execute one call every 10ms.
	// Because of timing + call overhead, we make a safe asseertion for > 5ms
	// but < 15ms.
	assert.True(t, elapsed > 5*time.Millisecond && elapsed < 15*time.Millisecond,
		"Second More elapsed is unexpected, expected 5ms < %v < 15ms", elapsed)
}

func TestParallel(t *testing.T) {
	run := New(1000 /* maxRequests */, 100000 /* rps */, time.Second)

	var wg sync.WaitGroup
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			for i := 0; i < 100; i++ {
				assert.True(t, run.More(), "First 100 requests in each goroutine should succeed, failed at %v", i)
			}
		}()
	}

	wg.Wait()
	assert.False(t, run.More(), "Requests should fail after 1000 parallel requests")
}

func TestStop(t *testing.T) {
	run := New(1000 /* maxRequests */, 1000000 /* rps */, time.Millisecond)

	for i := 0; i < 100; i++ {
		assert.True(t, run.More(), "Before Stop() should succeed", i)
	}
	run.Stop()
	for i := 0; i < 1000; i++ {
		assert.False(t, run.More(), "After Stop() should fail")
	}
}

func TestTimeout(t *testing.T) {
	run := New(1000 /* maxRequests */, 1000 /* rps */, time.Millisecond)
	assert.True(t, run.More(), "Succeed within the timeout")
	time.Sleep(5 * time.Millisecond)
	assert.False(t, run.More(), "Fail after the timeout")
}

func TestUnlimitedRequests(t *testing.T) {
	timeout := testutils.Timeout(100 * time.Millisecond)
	run := New(0 /* maxRequests */, 1000 /* rps */, timeout)
	for i := 0; i < 5; i++ {
		assert.True(t, run.More(), "Unlimited should suceed till timeout")
	}
	time.Sleep(timeout)
	assert.False(t, run.More(), "Fail after the timeout")
}

func TestUnlimitedStop(t *testing.T) {
	run := New(0 /* maxRequests */, 0 /* rps */, 0 /* maxDuration */)
	for i := 0; i < 5; i++ {
		assert.True(t, run.More(), "Unlimited should suceed till Stop")
	}
	run.Stop()
	time.Sleep(5 * time.Millisecond)
	assert.False(t, run.More(), "Fail after the timeout")
}
<commit_msg>Fix flaky limiter test (#284)<commit_after>package limiter

import (
	"sync"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/uber/tchannel-go/testutils"
)

func TestSerial(t *testing.T) {
	run := New(1000 /* maxRequests */, 100000 /* rps */, time.Second)
	for i := 0; i < 1000; i++ {
		assert.True(t, run.More(), "Request %v should succeed", i)
	}
	for i := 0; i < 1000; i++ {
		assert.False(t, run.More(), "Request %v should fail", i)
	}
}

func TestRateLimited(t *testing.T) {
	run := New(1000 /* maxRequests */, 100 /* rps */, time.Second)
	assert.True(t, run.More(), "First request should succeed")
	started := time.Now()
	assert.True(t, run.More(), "Second request should succeed")
	elapsed := time.Since(started)

	// Since RPS is 100, we should only execute one call every 10ms.
	// Because of timing + call overhead, we make a safe asseertion for > 5ms
	// but < 15ms.
	assert.True(t, elapsed > 5*time.Millisecond && elapsed < 15*time.Millisecond,
		"Second More elapsed is unexpected, expected 5ms < %v < 15ms", elapsed)
}

func TestParallel(t *testing.T) {
	run := New(1000 /* maxRequests */, 100000 /* rps */, time.Second)

	var wg sync.WaitGroup
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			for i := 0; i < 100; i++ {
				assert.True(t, run.More(), "First 100 requests in each goroutine should succeed, failed at %v", i)
			}
		}()
	}

	wg.Wait()
	assert.False(t, run.More(), "Requests should fail after 1000 parallel requests")
}

func TestStop(t *testing.T) {
	run := New(0 /* maxRequests */, 0 /* rps */, 0 /* maxDuration */)

	for i := 0; i < 100; i++ {
		assert.True(t, run.More(), "Before Stop() should succeed, iteration %v", i)
	}
	run.Stop()
	for i := 0; i < 1000; i++ {
		assert.False(t, run.More(), "After Stop() should fail")
	}

	// Make sure we can stop multiple times
	run.Stop()
	run.Stop()
	assert.False(t, run.More(), "After Stop() should fail")
}

func TestTimeout(t *testing.T) {
	run := New(1000 /* maxRequests */, 1000 /* rps */, time.Millisecond)
	assert.True(t, run.More(), "Succeed within the timeout")
	time.Sleep(5 * time.Millisecond)
	assert.False(t, run.More(), "Fail after the timeout")
}

func TestUnlimitedRequests(t *testing.T) {
	timeout := testutils.Timeout(100 * time.Millisecond)
	run := New(0 /* maxRequests */, 1000 /* rps */, timeout)
	for i := 0; i < 5; i++ {
		assert.True(t, run.More(), "Unlimited should suceed till timeout")
	}
	time.Sleep(timeout)
	assert.False(t, run.More(), "Fail after the timeout")
}

func TestUnlimitedStop(t *testing.T) {
	run := New(0 /* maxRequests */, 0 /* rps */, 0 /* maxDuration */)
	for i := 0; i < 5; i++ {
		assert.True(t, run.More(), "Unlimited should suceed till Stop")
	}
	run.Stop()
	time.Sleep(5 * time.Millisecond)
	assert.False(t, run.More(), "Fail after the timeout")
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"time"
	//"github.com/kidoman/embd"
	"github.com/stianeikeland/go-rpio"
)

var (
	ledRed = rpio.Pin(4)
	ledYellow = rpio.Pin(17)
	ledGreen = rpio.Pin(27)
)

func main() {
	fmt.Println("Parsing parameters")
	num := flag.Int("num", 0, "number of blinks")
	flag.Parse()

	fmt.Println("Number of blinks: ", *num)

	fmt.Println("Opening rpio access")

	var err = rpio.Open()

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	defer rpio.Close()

	fmt.Println("Pin as output")
	ledRed.Output()
	ledYellow.Output()
	ledGreen.Output()

	for i := 0; i < *num; i++ {
		if i % 3 == 0 {
			fmt.Println("Toggle RED")
			ledRed.Toggle()
		} else if i % 3 == 1 {
			fmt.Println("Toggle YELLOW")
			ledYellow.Toggle()
		} else {
			fmt.Println("Toggle GREEN")
			ledGreen.Toggle()
		}
		time.Sleep(time.Second)
	}
}
<commit_msg>Refactored led toggle<commit_after>package main

import (
	"flag"
	"fmt"
	"os"
	"time"
	//"github.com/kidoman/embd"
	"github.com/stianeikeland/go-rpio"
)

var (
	ledRed = rpio.Pin(4)
	ledYellow = rpio.Pin(17)
	ledGreen = rpio.Pin(27)
)

func toggleLED(pin rpio.Pin, string color)  {
	fmt.Println("Toggle ", color)
	pin.Toggle()
}

func main() {
	fmt.Println("Parsing parameters")
	num := flag.Int("num", 0, "number of blinks")
	flag.Parse()

	fmt.Println("Number of blinks: ", *num)

	fmt.Println("Opening rpio access")

	var err = rpio.Open()

	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	defer rpio.Close()

	fmt.Println("Pin as output")
	ledRed.Output()
	ledYellow.Output()
	ledGreen.Output()

	for i := 0; i < *num; i++ {
		if i % 3 == 0 {
			toggleLED(ledRed, "red")
		} else if i % 3 == 1 {
			toggleLED(ledYellow, "yellow")
		} else {
			toggleLED(ledGreen, "green")
		}
		time.Sleep(time.Second)
	}
}
<|endoftext|>


<commit_before>package ebay

type GetOrdersRequest struct {
	Xmlns string `xml:"xmlns,attr"`

	RequesterCredentials RequesterCredentials `xml:"RequesterCredentials"`

	CreateTimeFrom       string
	CreateTimeTo         string
	IncludeFinalValueFee string
	//  ListingType          string
	//  ModTimeFrom string
	//	ModTimeTo            string
	//	NumberOfDays         string
	OrderRole   string
	OrderStatus string
	//	SortingOrder         string
	DetailLevel string
	//	ErrorLanguage        string
	//	MessageID            string
	//	OutputSelector       string
	Version string
	//	WarningLevel         string
	//	Pagination
	//	OrderIDArray
}

type GetOrdersRequestResponse struct {
	Xmlns                    string `xml:"xmlns,attr"`
	Timestamp                string
	Ack                      string
	Build                    string
	Errors                   Errors
	HasMoreOrders            bool
	ReturnedOrderCountActual int
	CorrelationID            string
	HardExpirationWarning    string

	Pagination
	OrderArray OrderArray
}

type Pagination struct {
	EntriesPerPage       string
	OrdersPerPage        string
	PageNumber           string
	TotalNumberOfEntries int
	TotalNumberOfPages   int
}

type OrderIDArray struct {
	OrderID     string
	BuyerUserID string
}

type OrderArray struct {
	Order Order
}

type Order struct {
	BuyerCheckoutMessage string
	AmountSaved          string
	BuyerPackageEnclosure
	BuyerTaxIdentifier
	BuyerUserID string
	CancelDetail
	CancelReasonDetails string
	CancelStatus        string
	CheckoutStatus
}

type BuyerPackageEnclosure struct {
	BuyerPackageEnclosureType string
}
type BuyerTaxIdentifier struct{}

type CancelDetail struct {
	CancelCompleteDate  string
	CancelIntiationDate string
	CancelIntiator      string
	CancelReason        string
	CancelReasonDetails string
}

type CheckoutStatus struct{}

func (p *Pagination) Setpagination(entriesperpage, pagenumber string) {
	p.EntriesPerPage = entriesperpage
	p.PageNumber = pagenumber
}

func (o *OrderIDArray) GetOrderId(orderid string) {
	o.OrderID = orderid

}
<commit_msg>added struct fields<commit_after>package ebay

type GetOrdersRequest struct {
	Xmlns string `xml:"xmlns,attr"`

	RequesterCredentials RequesterCredentials `xml:"RequesterCredentials"`

	CreateTimeFrom       string
	CreateTimeTo         string
	IncludeFinalValueFee string
	//  ListingType          string
	//  ModTimeFrom string
	//	ModTimeTo            string
	//	NumberOfDays         string
	OrderRole   string
	OrderStatus string
	//	SortingOrder         string
	DetailLevel string
	//	ErrorLanguage        string
	//	MessageID            string
	//	OutputSelector       string
	Version string
	//	WarningLevel         string
	//	Pagination
	//	OrderIDArray
}

type GetOrdersRequestResponse struct {
	Xmlns                    string `xml:"xmlns,attr"`
	Timestamp                string
	Ack                      string
	Build                    string
	Errors                   Errors
	HasMoreOrders            bool
	ReturnedOrderCountActual int
	CorrelationID            string
	HardExpirationWarning    string

	Pagination
	OrderArray OrderArray
}

type Pagination struct {
	EntriesPerPage       string
	OrdersPerPage        string
	PageNumber           string
	TotalNumberOfEntries int
	TotalNumberOfPages   int
}

type OrderIDArray struct {
	OrderID     string
	BuyerUserID string
}

type OrderArray struct {
	Order Order
}

type Order struct {
	BuyerCheckoutMessage string
	AmountSaved          string
	BuyerPackageEnclosure
	BuyerTaxIdentifier
	BuyerUserID string
	CancelDetail
	CancelReasonDetails string
	CancelStatus        string
	CheckoutStatus
}

type BuyerPackageEnclosure struct {
	BuyerPackageEnclosureType string
}
type BuyerTaxIdentifier struct {
	Attribute string
	ID        string
	Type      string
}

type CancelDetail struct {
	CancelCompleteDate  string
	CancelIntiationDate string
	CancelIntiator      string
	CancelReason        string
	CancelReasonDetails string
}

type CheckoutStatus struct{}

func (p *Pagination) Setpagination(entriesperpage, pagenumber string) {
	p.EntriesPerPage = entriesperpage
	p.PageNumber = pagenumber
}

func (o *OrderIDArray) GetOrderId(orderid string) {
	o.OrderID = orderid

}
<|endoftext|>